docs(pm-dispatch): six protocol-line repairs, line-neutral on both governed text surfaces - #16339
Conversation
- reading 3 counts `pm:dispatched` u `pm:queue` and a branch push (a push is a claim and owes the comment), paid by folding the cross-seat/readings pair - the dispatch names `dispatch-gates.mjs --commands`, exits captured before any pipe, `--ran` reconciling; the human-readable form is never scraped - the dispatch tells the dev it posts no second claim, per AGENTS.md - the producer-side fence made executable: fix and report, no notify-then-act - a `Clause-<2>: yes` claim hangs the gate on the card in the same write and reads `--pair N` before requesting review, paid by folding the tier pair - core-rules digest gains the `Governing text:` + protocol-baseline line, paid by folding the two recommendation-order lines SKILL.md 811/811, table pin 342 untouched; core-rules.md 150/150. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox
…ill-protocol-lines
|
ACCEPT — contract-tier review of PR #16339, head Implemented-by: Verified in a detached compare worktree at the PR head, not from the report:
Ruling on the open question — A. SKILL.md's 「家族派发的折叠认领:共享分支按链首卡命名;每张成员卡各留认领评论并点名该分支」 sits in the PM's atomic-pair block (its neighbours are 「派发前按序执行原子对」 and 「② 认领评论(英文)」) and orders the PM's folded claim per member card — exactly what this flight's six claims are. It states nothing AGENTS.md contradicts and is not copied into dispatch orders, so it is not the defect #16064 measured; no edit, and no follow-up card for a subject marker — the block's subject is explicit two lines above. Collision, recorded for the approvers: the devx seat's draft PR #16271 (the #14944 depth-hold rules) edits the same two files; Landing regime: governed ( Generated by Claude Code |
维护者速读事情:只改两份 PM 协议文本(SKILL.md 与核心条款摘要),不动代码、不动行为。改的是六条实测把派发跑错的规则行,两份文件严格行数不变——新增的每一行都由同段落一次合并偿还,没有抬任何天花板。 最贵的一条是「第二条认领」:协议原来要求每份派发令命令 dev 再发一条认领评论,而仓库根 AGENTS.md 明令 dev 不得再发。跨两仓两车道五个 dev 撞上这条矛盾指令,四个拒绝、一个照做。现在协议改成 AGENTS.md 的读法:PM 那条认领就是 dev 的身份,dev 只核对最新一条点名自己的分支。 门禁清单不再靠人读输出:派发令原来让 dev 抓工具「给人看」的输出,一个 dev 的正则静默丢了五个门禁、退出码仍是 0。现在点名机器可读形式,逐条跑、退出码先落盘、再用 两处让证据失效的机制补上:开轮互斥的第三个读数原来只看已派发的卡,有人在排队卡的分支上干活时它读不到——现在分支推送本身即认领;契约复审标签原来可以只挂 PR 不挂卡,日后合法清除就留下「被剥离」的假签名——现在挂标同笔挂卡,PR 开出即对账。另两条是收口:「先报备再动手」改成一次性 dev 能闭合的形式;决策框架的两条新规则补进摘要。 要请您留意的:摘要里少了「防错轴打破余下平局」这半句,规则本体在 SKILL.md 四轴段完整保留(席位逐句核过),只是摘要不再重复。另外 devx 席的 PR #16271 改同一段落,两份草案互相冲突,后合的一方补一轮合并,不影响本 PR。 席位意见:建议合并。四张卡由本 PR 关闭(#16004 · #16064 · #15897 · #15961),#15975 与 #14768 的另一半在 flight B 的 os-dev.md 里。 Generated by Claude Code |
Fixes #16004
Fixes #16064
Fixes #15897
Fixes #15961
Refs #15975
Refs #14768
Six protocol-line repairs on the two governed
pm-dispatchtext surfaces. No code, nobehaviour: these files are read in full by every seat session, and each repaired line was
measured to be producing wrong runs.
Both files are LINE-NEUTRAL — every added line is paid by a fold inside the same
section, never by a ceiling raise:
.claude/skills/pm-dispatch/SKILL.md.claude/skills/pm-dispatch/references/core-rules.mdEvery added line is ≤ 119 bytes against the 120-byte rule. The four-axis decision-frame
block in SKILL.md is untouched, and
check:skill-frame-syncconfirms the two copies arestill structurally isomorphic.
What changed, per card
#16064 — SKILL.md:538 ordered every dispatch to demand a second claim comment
AGENTS.md:400binds a dispatched executor to post no second claim;SKILL.md:538ordered the PM to demand one. The skill's own tiebreak makes
AGENTS.mdthe winner, so:538 was the defective line. Five devs across two repos hit it; four refused, one complied
— identical orders, opposite outcomes.
Rewritten in place, 1:1, to the
AGENTS.mdreading: the dispatch states the dev posts nosecond claim, the PM's
Claim:is its identity, and the dev verifies the newest one namesits branch and stops with a report on a mismatch.
SKILL.md:479(家族派发的折叠认领) as a second site ordering a claim per member card. Reading that line in
its block (467–485), its subject is the PM's atomic pair, not the dev — it describes the
PM's own folded claims across member cards, which is what this flight's own claims are. It
therefore does not carry the same defect and is left untouched. Flagging the reading rather
than acting on it, since it differs from the triage note.
#15897 — the dispatch asked for the human-readable gate list and got it scraped
The old line named a bare
dispatch-gates.mjsrun, whose prose output has to bescraped; a dev's regex silently dropped the whole convention-triggered section at exit 0,
five gates with it, and CI went red on
check:i18n.Rewritten in place, 1:1, to name the machine form: take the list from
dispatch-gates.mjs --commands, run each command, land the exit code before any pipe, andreconcile with
--ran; never scrape the human-readable output. The reconciliation is whatnow mechanically guarantees no family is missed, so it carries that guarantee instead of
prose (rules-only register).
#16004 — the seat mutex's reading 3 was blind to a queued card's branch
Reading 3 filtered on
pm:dispatchedonly, so a session pushing to apm:queuecard'sclaude/issue-N-*branch produced no reading at all; one collision was found by hand, offthe branch tip, not by the mutex.
Widened to two lines: the card set becomes
pm:dispatched∪pm:queue, and a branch pushsince the last shift-end brief counts as a claim in its own right (one
git ls-remotepercard) — a push is a claim, and owes the comment reading 3 counts.
Paid by folding the cross-seat-handwriting line and the readings-only-add-a-yield line into
one, inside the same block.
#15975 (Refs) — a single-carrier gate hang makes a clear indistinguishable from a strip
The clause-② gate is a dual carrier; hung on one side only, the eventual legitimate clear
can only ever produce the one-removal strip signature. The defect is committed at hang
time and only surfaces at landing.
One line added beside the existing carrier rule: a
Clause-②: yesclaim hangs the gate onthe card in the same write as the claim, and when the delivering PR opens the seat reads
check-clause2-carriers --pair Nat exit 0 before requesting any review — so a split isrepaired at hang time, never at landing.
Paid by folding the
--tierhint line and the enqueue-refusal line into one, inside thesame 复核 block. The other half of this card (the os-dev.md line) rides its own flight, so
this PR only refs it.
#14768 (Refs) — the unexecutable "report, then act" fence
SKILL.md:543carried 「报备后」 — report for the record, then fix — which presupposes amid-run channel a one-shot dev does not have, and so hands it the whole three-way choice the
author thought they had fenced. This is the census's hit 3, in the allow-with-trace class.
Rewritten in place, 1:1, to the executable form: fix on the producer side and report the
landing point; never patch on the consumer side. Only the SKILL.md hit is in scope here —
the census's other three hits ride flight B.
#15961 — the core-rules digest owed the two decision-frame rules
One digest line added to the 升级与决策 block, in the digest's plain-language register: every
decision card and director presentation carries
Governing text:, and the protocol is thebaseline — a spec-vs-code mismatch defaults to changing the code, and a protocol change is
its own card rather than an option on a defect card.
Paid by folding the two recommendation-order lines into one.⚠️ The fold drops two clauses
that are derivable rather than independent — 「其余投不翻它」 (a consequence of the ≥50% weight
stated in the same line) and 「防错轴打破余下平局」. The second is a genuine rule and it is
not lost from the corpus: SKILL.md keeps it. It leaves the digest only, which is what a
fold in a digest costs.
Verification
Gate union run at
d88c29c76a, this PR's head, after the final commit.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 16commands from the tree (never from a hand-written path list). Every one was run with its
exit code captured before any pipe, then reconciled:
16 of 16 green. One needed a build first and is worth naming, because its first exit was not
a finding:
pnpm --filter @objectstack/lint run check:doc-formula-expressionsfirst returned exit3 — the gate's own PREREQUISITE-NOT-MET code, in its words "Nothing was measured … It is
NOT a finding". After
turbo run build --filter=@objectstack/formula --filter=@objectstack/lintit re-ran at exit 0.
The dispatch-named gates, quoted from their own verdict lines rather than from a bare
$?:check-governed-merges --teston this PR's real paths returns exit 3 — GOVERNED, asexpected for
.claude/**:Whole-repo
pnpm lint(eslint . --no-inline-config) ran in full throughscripts/pm/os-verify-lock.sh(slotissue-16004) and returned:No narrowing was taken, so no narrowing needs declaring.
H-row check. Each of the 10 sentences this diff removes was grepped over
scripts/and.claude/hooks: 0 hits, with a positive control proving the grep reaches that corpus(
scripts/pm/check-half-states.mjsdoes quote SKILL.md-register phrases, just not these).No patrol row pins a sentence this PR rewrites.
维护者速读(草稿)
一、这次动的是什么。 只改两份 PM 协议文本,不动任何代码、不动任何行为。改的是六条把
派发跑错的规则行:每条要么在实测中直接产生了错误的运行,要么让一次合法操作变得无法自证。
两份文件都严格行数不变——新增的每一行都由同一段落里的一次合并偿还,没有抬任何天花板。
二、最贵的一条是"第二条认领"。 协议要求每份派发令命令 dev 再发一条认领评论,而仓库根
的 AGENTS.md 明令 dev 不得再发。两处相互矛盾,而 AGENTS.md 按规则获胜。代价是实测出来的:
跨两个仓、两条车道,五个 dev 撞上同一条矛盾指令,四个拒绝执行、一个照做——同样的命令,相反
的结果。真正的成本不是那四次拒绝,而是那些默默挑一边、没人看见的运行。
三、门禁清单被当成散文抓取。 派发令原来让 dev 跑工具的"给人看"的那种输出,再用正则去
抓。一个 dev 的正则静默丢掉了整整一段(五个门禁),退出码仍是 0,读起来像跑完了,直到 CI 变
红。现在派发令点名机器可读形式,并要求逐条跑、退出码先落盘、再用工具自己的对账模式核。
四、两处让"证据"失效的机制。 其一,开轮互斥的第三个读数只看已派发的卡,于是有人在排队
卡的分支上干活时它一个读数都产生不了——实测撞过一次车,是靠人读分支尖端发现的,不是靠互斥。
现在分支推送本身即认领。其二,契约复审的门禁标签本该同时挂在卡和 PR 两处,只挂一处时,日后
那次合法的清除只会留下"被剥离"的签名——缺陷在挂标那一刻就已铸成,却要到落地才暴露。现在挂
标即同笔挂卡,并在 PR 开出时先对账。
五、剩下两条是收口。 一条把"先报备、再动手"这种一次性 dev 根本没有通道执行的围栏,改成
本轮内能闭合的形式;一条把决策框架的两条新规则补进核心条款摘要,让摘要和主协议不再各说各话。
需要维护者留意的是第六条的合并代价:摘要里少了一句"防错轴打破余下平局"——该规则在主协议
SKILL.md 中完整保留,只是不再在摘要中重复。
席位意见:
🤖 Generated with Claude Code
Generated by Claude Code
Generated by Claude Code