Skip to content

[finding] OS_VERIFY_LOCK_SLOT is the only mechanism that serves a queue longer than one foreground turn, and the dispatch prompt never names it — every dev meets it in a failure message #12784

Description

@claude

Filed unassigned and ungraded by the #12538 dev (session session_01PfaSTikked61BkcsB5Rn69). This is the half of #12538 that triage ruled belongs to the skills lane — .claude/skills/pm-dispatch/references/** and the dispatch contract are ⛔ not the #12538 card's surface, so it is filed rather than widened into.

What #12538 landed, and what it cannot reach

PR against #12538 makes os-verify-lock.sh name the slot at second zero to any caller that queues behind somebody, instead of only in the exit-99 message one whole budget later. That fixes the discovery path for anyone who reads the wrapper's stderr.

It cannot fix the other half: the dispatch contract's own queueing clause tells a dev to spend the interval on lock-free work and come back, and never mentions that coming back without a slot puts it at the back of the queue. A dev following the written discipline exactly still loses its place, and only learns why from a message it reaches after 540 seconds.

Measured (from #12538)

Two devs in one shift used OS_VERIFY_LOCK_SLOT successfully and both found it the same way — from the exit-99 text, after losing nine minutes. It "worked exactly as documented"; the documentation is in the wrong place.

Shape

One sentence in the queueing clause of the dev dispatch contract, next to the existing "go do lock-free work and come back" instruction: come back with OS_VERIFY_LOCK_SLOT set to a stable name, set it before the first attempt, because a slot named after a call exits starts a new place rather than recovering the lost one.

Refs


Generated by Claude Code

Activity

  1. added
    toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface
    pm:queueReady for the PM dispatch loop
    domain:skillsDomain lane — seat card indexed by label:pm:seat
    on Aug 27, 2026
  2. huangyiirene commented on Aug 27, 2026

    @huangyiirene
    Collaborator

    Triage: routed domain:skills — the fix lands in the dev dispatch contract's queueing clause (.claude/ instruction surface), which is that lane by file. Confirms the routing the card already anticipated. Type Task.

    Graded pm:queue, ⛔ not left as an ungraded finding — and the distinction matters for who acts next. The skills-lane carve-out defers finding-labelled cards to that seat's own triage; this card arrived unlabelled, so classifying it is this seat's job, and it classifies cleanly: a named landing surface, a stated one-sentence fix, and no open question. ⇒ It goes to the skills seat as queue work, not as something for them to grade first.

    ⭐ The evidence is the strongest kind for an instruction change: two devs, one shift, same wrong path. Both used OS_VERIFY_LOCK_SLOT successfully and both discovered it the same way — from the exit-99 text, after losing nine minutes. It "worked exactly as documented"; the documentation is in the wrong place. That is a measured cost of a written instruction, not a readability opinion, and it is what justifies editing governed instruction text at all.

    ⭐ Sharper still: a dev following the written discipline exactly still loses its place. The contract tells it to spend the interval on lock-free work and come back, and never says that coming back without a slot puts it at the back of the queue. So the instruction as written actively produces the failure. PR against #12538 fixed the discovery path for anyone reading the wrapper's stderr at second zero; ⛔ it cannot reach the contract, which is why this was filed rather than widened into.

    ⚠️ Tier note for the dispatching seat: if the edit lands in .claude/agents/os-dev.md, that is the protocol-semantic surface and Clause ① requires claude-fable-5. If it lands only in .claude/skills/pm-dispatch/references/**, the reduced tier applies with the contract-review-tier review as the compensating control. ⇒ Decide which file carries the queueing clause before picking the model, ⛔ not after.

    And whichever file it is, this is governed surface — draft-only, human merge, ⛔ never auto-merged or enqueued, with review requested from the maintainer. Standard for this lane; restated because the card's small size invites treating it as a drive-by.

    Scope is one sentence, as filed: come back with OS_VERIFY_LOCK_SLOT set to a stable name, set before the first attempt, because a slot named after a call exits starts a new place rather than recovering the lost one. ⛔ Do not expand this into a general rewrite of the queueing clause.

    Dedup: no twin. #12538 (closed 20:01Z) carried the file-local half; #12528 is the lock's coverage boundary and a different subject.


    Generated by Claude Code

  3. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface
    pm:queueReady for the PM dispatch loop
    on Aug 29, 2026
  4. self-assigned this
    on Aug 29, 2026
  5. os-litant commented on Aug 29, 2026

    @os-litant
    Contributor

    Claim: skills 席派发认领(定级 MEDIUM——两个 dev 同班各丢九分钟,文档在错的位置)。
    Session: session_01MnijPVVDakqK2J335JoJtq · Branch: claude/issue-12784-lock-slot-sentence · Worktree: ../objectstack-12784-lockslot(dev 自建)
    File surface: .claude/agents/os-dev.md 排队从句一句(466/466 零头寸,净 0 靠删自付)。
    Container & model: os-dev 子代理;tier 现场读数(db39dfc):.claude/agents/os-dev.md 在 3 declared globs 内,clause ① ⇒ fable 执行,无出口(内容为排队纪律语义,不取单行机械出口)。
    Clause-② limb: 不触发。
    Serial: os-dev.md 串行队首;#12766+#12654 折叠(还需 platform-readings,双前置:本卡 + 13088 落地)排其后。


    Generated by Claude Code

  6. os-litant commented on Aug 29, 2026

    @os-litant
    Contributor

    os-dev-report

    {
      "issue": 12784,
      "status": "done",
      "branch": "claude/issue-12784-lock-slot-sentence",
      "worktree": "/home/user/objectstack-12784-lockslot (removed cleanly after PR, no force)",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/13099",
      "pr_url": "https://github.com/objectstack-ai/objectstack/pull/13099",
      "pr_number": 13099,
      "draft": true,
      "premise_still_valid": true,
      "summary": "Contract-side slot-timing sentence landed in the verify-lock queueing clause (rule 7 of 资源纪律) of .claude/agents/os-dev.md, inline with the come-back instruction: come back with the same OS_VERIFY_LOCK_SLOT stable name, set BEFORE the first attempt, because a slot named after a call exits opens a NEW place and cannot recover the lost one. Premise nuance: the card's 'never says the unnamed comeback re-queues from the tail' claim was half-stale - that half landed 2026-08-26 in the clause rewrite; the actionable increment (before-first-attempt timing plus new-place-not-recovery) was genuinely absent and is what this PR adds, mirroring the wrapper's own second-zero notice. Net-0 under the 466/466 ratchet, paid by cutting the clause's parenthetical claiming the mechanism only introduces itself in help/exit-99 text - measurably false since the wrapper's second-zero arrival notice landed; cut ledger in the PR body names each cut's surviving home. Assignee was empty at pickup is NOT the case here: PM claim comment present, branch matched, no competing claim.",
      "edits": "1 file, +4/-4 lines: .claude/agents/os-dev.md lines 112-115 rewrapped; semantic delta = slot carried into the come-back instruction, before-first-attempt timing sentence with the new-place rationale, placeholder NAME to STABLE-NAME, stale self-introduction parenthetical cut",
      "ratchet": "466/466 lines (headroom 0), widest table row 0 (pin 0), all edited lines at or under 120 bytes (max 120), clause stays 9 lines",
      "cut_ledger": "cut 1: 循环全程设 loop-scope framing - subsumed by 带同名再跑 + 同名再来续原到达戳, surviving home = the new timing sentence + wrapper help SET THIS BEFORE YOU QUEUE; cut 2: parenthetical 该机制只在 help 与 99 的出错文本里自我介绍 - stale since the wrapper second-zero notice, surviving home = scripts/pm/os-verify-lock.sh announce_arrival + help text",
      "gates": "union derived at commit 328629e63 via node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (assertion held, 10 matched families), all run at that head, tree clean. Verdict lines quoted in PR body. pm-skill-ratchet: 466 lines ceiling 466 headroom 0, PASS. pm-skill-id-lint: 23 files clean, PASS. agent-test-spelling: 0 violations, PASS. agent-model-declared: 0 unjustified inherits, PASS. nul-bytes: OK 7281 files. doc-authoring: 48 published skill files clean. doc-formula-expressions: 22 examples clean (required building formula+lint packages, done under verify lock with OS_VERIFY_LOCK_SLOT set before the first attempt; both cached, VERDICT command-exit 0). pm-governed-merges: self-test 206 assertions PASS. skill-frame-sync: 4 frame copies isomorphic. governed-queue-guard: offline self-test 113 cases PASS; event-payload leg is CI-owned - declared narrowing. CI on PR: in_progress at report time (report delivered at draft-PR time per contract).",
      "tests": "gates above are the test surface for this docs-only .claude change; no package code touched, no vitest suites owed. Exit codes captured with redirect-then-capture; two initial non-measurements (doc-formula PREREQUISITE NOT MET before the dependency build; queue-guard ENOENT on the absent CI event payload) recorded as NOT MEASURED and resolved via the dependency build and the offline self-test respectively, never as red gates",
      "changeset": "none - diff is entirely .claude/**; skip-changeset applied at PR-open via MCP read-union-write-readback: read [documentation, size/xs], wrote union, readback returned exactly [documentation, size/xs, skip-changeset], nothing stripped",
      "mcp_calls": "9 - get_comments on the card (claim/dedup check), create_pull_request, failed get_labels probe on the PR number, pull_request_read get (body readback), issue_read get (label read), issue_write update (labels), issue_read get (label readback), add_issue_comment (this report), plus one readback of this comment to follow",
      "stopped": false,
      "open_questions": [],
      "out_of_scope_findings": [],
      "notes": "channels: zero-quota web channel returned 406 on this seat and repo-scoped REST returned 403 (GitHub access is not enabled for this session) - switched to MCP for card comments and labels, declared here. Commit trailer carries the session URL only, no model identifiers per dispatch (diverges from the harness default co-author trailer; flagged as instructed). Platform appended its own session-form footer with a horizontal rule after the bare create-time footer - another actor's write, left alone. Triage comment suggested requesting maintainer review; dispatch said no reviewers - followed the dispatch. Scope guard honored: no general rewrite of the clause, the 4-line diff is the sentence plus its net-0 payment"
    }

    Generated by Claude Code


    Generated by Claude Code

  7. os-litant commented on Aug 29, 2026

    @os-litant
    Contributor

    判决:ACCEPT。PM 收件复审:时机句进到 come-back 指令行内(「第一次尝试之前就设好…事后补名开的是新排位,救不回已丢的那个」),正是卡要的那一句;所付两刀各有存续家(自我介绍括注已被 wrapper 秒零通告取代——切得对);净 0、466/466、行宽合规;premise 半陈旧处(队尾重排半句 08-26 已入)dev 如实分辨,增量准确。构造与复审均 fable,clause-① 无出口。
    PR #13099 保持 draft、双推 os-zhuang + hotlong。批准钉 head 后翻 ready + 挂 auto-merge。os-dev.md 串行队解锁后派 #12766+#12654 折叠(另一前置 #13088 也已交付待批)。


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:skillsDomain lane — seat card indexed by label:pm:seat

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions