Skip to content

docs(pm-dispatch): release is an explicit act — clear the assignee and post a Release: line whenever a card leaves a session's hands (#15846) - #15848

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-15846-release-is-an-explicit-act
Sep 5, 2026
Merged

docs(pm-dispatch): release is an explicit act — clear the assignee and post a Release: line whenever a card leaves a session's hands (#15846)#15848
os-zhuang merged 1 commit into
mainfrom
claude/issue-15846-release-is-an-explicit-act

Conversation

@claude

@claude claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Fixes #15846

What

Ownership had an explicit entry (assign + Claim:) and no explicit exit. Under the maintainer's 2026-09-05 design ruling (R3, recorded on the ownership-contradiction card by the skills seat: the assignee field stays a presence bit under one shared identity — 「暂时不区分」 — and a presence bit is only truthful if its exit is written down), release is an explicit act: whoever moves a card out of a session's ownership — re-route, hand-back on premise_still_valid: false, an abandoned flight with no takeover, a cross-lane hand-off — clears the assignee and posts a line beginning Release: (session ID, which of the four reasons, destination = the new label state or lane) in the same write; the next owner claims afresh. Two definitional readings follow: a pm:queue card never carries an assignee; a pm:dispatched card always does (what H1 and H24 read).

Line-neutral on both files, both at headroom 0. Every new fact is folded into an existing line or takes the place of a line whose content survives in its neighbour; no ceiling moves and the ratchet script is untouched.

.claude/skills/pm-dispatch/SKILL.md — 811 → 811 lines, widest table row 342 → 342 bytes

State-model table (状态模型):

  • open + 队列标签 + 无 assignee row, 85 → 128 bytes: adds 「pm:queue 卡恒无 assignee,有即半态」.
  • assignee 已设 row, 63 → 216 bytes: adds 「离手恒走释放 —— 四因 = 改路由、前提证伪、弃飞无接管、跨车道移交,去向 = 新标签态或车道;⛔ 不静默摘 assignee」.
  • pm:dispatched row, 106 → 122 bytes: adds 「恒带 assignee」.

认领 family (beside 「assignee 字段归 PM」, which is unchanged):

  • New line, 118 bytes: 「释放是显式动作:让卡离手者同笔清 assignee + Release: 行(会话/因/去向);下一任重新认领。」
  • Paid for by folding 「选中的单派发前按序执行一个原子对。」 into the ① line, now 「派发前按序执行原子对:① Assign @me,并把 pm:dispatched 与摘 pm:queue 放进同一次标签写入。」 (119 bytes). Nothing dropped.
  • Dead-claim reclamation line, 113 bytes: 「摘 assignee(注明原因)回队」 → 「释放回队(Release: 行载因)」. Reclamation is the abandoned-flight reason of this same rule; left as it was, the file would spell the same exit two ways.

.claude/skills/pm-dispatch/references/state-machine.md — 42 → 42 lines

  • New line after 摘标者, 119 bytes: 「释放者 = 让卡离手的席位:行首 Release:(会话/因/去向)与清 assignee 同笔;下一任重新认领。」
  • Paid for by folding 「awaiting 卡在在飞视图里计停放库存。」 into the retriage-authority line, now 「retriage 原定级在改判前仍是权威;awaiting 卡在在飞视图里计停放库存。」 (93 bytes). The only phrase dropped is 「挂/摘分属两方」, which the 挂标者 / 摘标者 lines directly beneath already state.

Byte widths (LC_ALL=C awk, bytes)

  • SKILL.md widest non-table prose line: line 98 at 120 (pre-existing, unchanged). Widest table row: line 250 at 342 (the domain:engine row, pre-existing, unchanged). Line 810 at 172 bytes sits inside the claim template's code fence (pre-existing, fence-exempt). No line this PR writes exceeds 120 bytes; the widest new line is 119.
  • state-machine.md widest line: line 18 at 120 (pre-existing, unchanged); the new line is 119.

Where the four reasons and the destination live — the dev's call inside the ruling

The 120-byte cap on a 认领 line cannot hold the act, the four reasons and the three fields at once; the assignee 已设 row has ~240 bytes of room under the 342-byte pin. So the act and the fresh claim sit in the 认领 line and in state-machine.md (the 行契约: 行首 Release: with its three fields, same write as the clear), while the four reasons, the destination definition and the ⛔ on silent clearing sit in the assignee row of the state model, and the two definitional readings sit in the pm:queue / pm:dispatched rows they define.

Four-axis note. 实际业务需求: measured, not speculative — H1/H24 report residue as live half-states and a seat's list view shows taken cards that are free; all four exits already exist in the protocol (改路由 in the pm:retriage row, premise_still_valid: false in 收集 / 报告契约, 死认领回收, 跨车道 接手). 项目长远合理性: the exit is written where the entry is written — the state model and the 认领 section — not as a patrol heuristic. 防 AI 犯错: the definitional readings turn the field into a checkable invariant, and 「⛔ 不静默摘 assignee」 forbids the tolerant path. 创业阶段不扩散: no new label, field, comment marker or gate row; the patrol row for a Release: newer than the last Claim: stays the declared follow-up.

Not changed

The claim's first-line spelling Claim: (ruled 2026-08-11); CLAIM_COMMENT_MARKER; the H1/H24 code in scripts/pm/check-half-states.mjs (its prose is a follow-up once this lands); the two declared frame-block copies; the ratchet script's CEILINGS and pins.

Verification — all at ec0a7f8d8c, the PR head

Family derived by node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack on the two files (16 commands: 9 by path, 7 whole-tree), cross-checked by the no-path derivation from the merge-base (same 16), every command run with the exit code captured before any pipe, then reconciled: ✓ dispatch-gates --ran: 16 derived famil(ies) accounted for — 16 run, 0 NOT-MEASURED.

  • ✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/SKILL.md: widest table row is 342 bytes (pin 342; headroom 0).
  • ✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/SKILL.md is 811 lines (ceiling 811; headroom 0).
  • ✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/state-machine.md is 42 lines (ceiling 42; headroom 0). (widest table row 0, pin 0)
  • ✓ check-skill-line-ratchet self-test: 155 cases pass.
  • ✓ check-skill-id-lint: 24 file(s) clean (pattern /#[0-9]{3,}/g). (+ self-test 14 cases)
  • ✓ check-skill-frame-sync: 2 copies of the decision frame are structurally isomorphic across 2 files
  • ✓ check-half-states self-test: 2267 cases pass. — no H-row prose pin fired on the edited sentences.
  • ✓ check-skills-token-ratchet: 36 authored bundle file(s) within their ceilings; 10 generator-owned file(s) measured, not ratcheted.
  • ✓ check-governed-prose: 2 instruction surface(s) name all 5 registered governed surfaces … and claim no others.; check-governed-merges --self-test: 274 assertions; check-governed-queue-guard self-test: 144 cases pass; check-closing-keyword-parity --self-test: 24 assertions; comment-mask corpus sweep: 5998 files, 0 disagree; check-agent-test-spelling: 0 violations; doc authoring guard: 46 published skill files clean; check-nul-bytes --self-test: 75 assertions; check-refd-timer-probe self-test: 11 cases pass; check-watch-hint-literal: 61 declaration(s) across 4 rostered name(s); check:driver-memory-census exit 0.
  • check:doc-formula-expressions: first run PREREQUISITE NOT MET (exit 3: @objectstack/formula, then @objectstack/lint, not built — NOT MEASURED, not a finding); after turbo run build --filter=@objectstack/lint through the lock: ✓ check:doc-formula-expressions self-test: 58 cases passed and ✓ check:doc-formula-expressions: 22 record-scoped formula example(s) across 428 files / 1370 TS blocks judged clean by @objectstack/formula.
  • Whole-repo pnpm lint (eslint . --no-inline-config) through scripts/pm/os-verify-lock.sh (slot issue-15846): os-verify-lock: VERDICT command-exit 0 · held the lock 67s (1m07s) · waited 65s (1m05s).
  • Control-character self-scan of both files (grep -naP over the C0/DEL range): no hits.

Negative control on the ratchet, run from the committed state: one line appended to each file → ✗ … SKILL.md is 812 lines; the ratchet ceiling is 811 and ✗ … state-machine.md is 43 lines; the ratchet ceiling is 42 (exit 1); restored with git checkout HEAD -- …, proven by git hash-object equal to the HEAD blob on both paths (a32af80219…, b3b537e59a…) and git diff HEAD empty.

check-governed-merges --test on the two paths: exit 3 (.claude/**, governed) ⇒ draft PR, in-seat contract-tier review, human merge, skip-changeset (no package publishes anything from this diff).

Generated by Claude Code

🤖 Generated with Claude Code

https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox


Generated by Claude Code

…d post a `Release:` line whenever a card leaves a session's hands (#15846)

Ownership had an explicit entry (assign + `Claim:`) and no explicit exit.
Under the maintainer's 2026-09-05 design ruling (R3), whoever moves a card
out of a session's ownership — re-route, hand-back on a falsified premise,
an abandoned flight with no takeover, a cross-lane hand-off — clears the
assignee and posts a line beginning `Release:` (session, reason,
destination) in the same write; the next owner claims afresh. The two
definitional readings follow: a `pm:queue` card never carries an assignee,
a `pm:dispatched` card always does.

Line-neutral on both files, both at headroom 0 (SKILL.md 811/811, table
pin 342; state-machine.md 42/42): every new fact is folded into an existing
line or takes the place of a line whose content survives in its neighbour.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox

os-steve commented Sep 5, 2026

Copy link
Copy Markdown
Collaborator

ACCEPT — contract-tier in-seat review of PR #15848, head ec0a7f8d8 (skills seat, 2026-09-05T11:3xZ).

Implemented-by: claude/issue-15846-release-is-an-explicit-act (os-dev subagent)
Reviewed-by: session_019RfFHiRCSs3JXLK4cwcfox (skills seat)

Verified in a detached compare worktree at the PR head, three-dot against origin/main (d701e657d), not from the report: two files, +8 / −8, line-neutral — SKILL.md 811 / 811 with the widest table row still line 250 at 342 bytes, state-machine.md 42 / 42. The rule lands where ruled: the 认领 family gains 「释放是显式动作:让卡离手者同笔清 assignee + Release: 行(会话/因/去向);下一任重新认领。」, paid for by folding the 原子对 header into its ① line with nothing dropped; the state-model rows carry the two definitional readings (pm:queue 卡恒无 assignee,有即半态 / pm:dispatched 恒带 assignee) and the assignee 已设 row carries the four exits, the destination and ⛔ 不静默摘 assignee — the dev's placement of the four reasons in the row rather than the 120-byte prose line is the right call inside the ruling; the dead-claim reclamation line now routes through 释放回队 with the Release: line carrying the reason; state-machine.md gains the releaser line beside the applier and remover, paid for by folding the awaiting-inventory line into the retriage-authority line (only the redundant 挂/摘分属两方 dropped). No issue number in any changed line; no model names in the diff or the PR body; the Claim: spelling, CLAIM_COMMENT_MARKER, the H1/H24 code and the frame copies untouched. Governed on both paths (check-governed-merges --test exit 3); tier read MANDATORY from the SKILL.md path, met.

Seat gate runs on this head in the compare worktree: skill-line-ratchet exit 0 (both files at headroom 0, as ruled), skill-id-lint 24 files clean, half-states self-test 2267 (no H-row prose pin fired), governed exit 3. The dev's evidence beyond that: 16 derived families all exit 0 and reconciled 16 of 16, frame-sync green (two declared copies), the formula-expressions gate green after building its prerequisites (its one-build-short refusal filed as #15850 for devx), whole-repo lint through the lock, the negative control (+1 line on each file reds the ratchet, restore proven by blob hash), widest line this PR writes 119 bytes; CI on ec0a7f8d8: 29 check runs completed, 16 success, 13 skipped by the path filter, none failing (seat's read at 11:3xZ).

Landing regime: governed surface ⇒ this PR stays a draft; reviewers os-zhuang and hotlong requested by the seat; the human merge is the review record; no seat flips it ready, enqueues it, or arms auto-merge. Fixes #15846 closes the card on merge. A check-half-states H1/H24 prose follow-up is the seat's to file once this lands.


Generated by Claude Code

os-steve commented Sep 5, 2026

Copy link
Copy Markdown
Collaborator

Tally correction to the ACCEPT above (skills seat, 2026-09-05T11:2xZ): the seat's REST read of the check runs on ec0a7f8d8 at 11:27Z gives 29 completed — 17 success, 12 skipped, none failing (the verdict's 16 / 13 was read while the last run was still in progress). The verdict stands.


Generated by Claude Code

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

Labels

documentation Improvements or additions to documentation size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants