docs(pm-dispatch): land the maintainer's filing/merging directive — items 1 2 3 4 5 8 — as in-place charter deltas, net 0 per ratcheted file - #19449
Conversation
…tems 1 2 3 4 5 8 — as in-place charter deltas Filing threshold inverted (three classes qualified: reachable today, named producer; observation/dormant/zero-pull findings not filed, no digest, no quota); devs do not file — report entries carry `class: a|b|c` + evidence or `carrier:`, the seat disposes each entry in one ACCEPT line; triage merges at first grading (same file + same mechanism), same family is linked and batched, in-flight never merged, execution seats raise `pm:retriage` with the reading; same-assignee duplicates closed by the holding seat; an escalated card names which half it carries; a ruled card re-enters the decision box only with `Prior rulings on this card:`; the director presents the first batch after the first five same-family cards, class-1 screening per batch, cheap-scan ordering, verifiable criterion. Net 0 lines in every ratcheted file: each new rule paid by retiring a second pointer to the same reference file or a line restated verbatim in a sibling. Every line at or under 120 bytes. state-machine.md untouched (no `needs-user-decision` section; the intake duty's home is SKILL.md). Claude-Session: https://claude.ai/code/session_017ETYWqMQD4qMtZzAGovWNi Co-authored-by: Claude <noreply@anthropic.com>
Contract reviewServed-tier: ① Derived judgments
② Semver levelNone — nothing published ( ③ Boundary flagsTwo Implemented-by: VERDICT: PASS Generated by Claude Code |
Fixes #19340
Clause-②: no
Lands the DELTA between the six adopted items of the director's record (comment 5750077963 on #19340 — the maintainer's verbatim answer 「1 2 3 4 5 6 8」, 2026-09-20T13:24Z, items 1 2 3 4 5 6 8 adopted, 7 and 9 not) and the charter as it stood on
origin/main23f1de0. Item 6 is carried by #19344 (out of scope here; #19344 remains open). Items 7 and 9 were not adopted and nothing here re-proposes them.Every ratcheted file lands at net 0 — each new rule is paid by retiring a second pointer to the same reference file or a line restated verbatim in a sibling (the pointer-retirement pattern of the last two director-charter PRs) — and every landed line is at or under 120 bytes (widest: 120 B).
state-machine.mdis untouched (reasons below). Diff: 4 files, +24 / −24.Per item — the line that stood, the line that lands, what was already in place
origin/main23f1de0)a2665ce)SKILL.md:347–:351 named the three classes and 「其余进 PR## Acceptance notes,⛔ 不立卡」 but said nothing about reachability today, a named producer, dormant / zero-pull findings, digests or quotasSKILL.md:351 (new) 「(a) 须今天可达,(c) 须具名生产者;观察、休眠、零拉动 ⛔ 不立卡、不进汇总卡、无配额」 ·os-dev.md:45 「(a) 须今天可达,…」, :46 「…须具名生产者…」, :48 adds 休眠、零拉动 to the not-filed list ·core-rules.md:87 twin (今日可达可复现缺陷 · 具名生产者陷阱)SKILL.md:347–:350 (three classes, (a)/(c) boundaries), :352–:354 (承接者:无), :376 (三类外关 not planned);os-dev.md:41–:44, :47SKILL.md:778 「只列三类立卡与noted, not filed;立卡附查重词、归挂、立在修复仓」 and :779 「席位在 ACCEPT 读 … 由席位补立」 named noclass:/carrier:field and no per-entry disposition;os-dev.md:49–:50 spelled entries asnoted, not filed: …; :60–:61 and :65 still read as the dev filing (「立成它的 sub-issue」「独立立单」「无 assignee 立单」)SKILL.md:777 (every entryclass: a|b|c+ evidence, orcarrier:= 承接者; neither ⇒ Acceptance notes), :778 (dev 不立卡; ACCEPT disposes each entry in one linefiled #N/Acceptance notes/dropped — reason; the seat files the three-class ones in the fix repo), :779 (seat reads Acceptance notes, files the true three-class ones with 归挂 + 查重词; out-of-class cards already filed are closed not planned) ·os-dev.md:49–:50 (the two fields;carrier:defined; neither ⇒ Acceptance notes only), :60–:61, :65 (the REPORT names the sub-issue /Blocked-by:anchor; the seat files), :376 (report template) ·core-rules.md:151 twinos-dev.md:55 「dev 不POST /issues」 already said devs do not file; :51 (3–5 dedupe words); :53 (four-write budget)issue_writeandsub_issue_writeare insettings.jsonpermissions.deny, pinned bycheck-settings-deny-roster.mjsSKILL.md:367 「同文件同缺陷 = 同一发现,不分车道:证据搬到先卡,后卡关duplicate_of,⛔ 不并排派发」 and :368 「其余在飞 ⇒Blocked-by:不派;open 未认领 ⇒ 先并成一个派发入口;已完成 ⇒ 卡可能过期」 — a label-pass rule with no first-touch timing, no same-family rule and no execution-seat routeSKILL.md:368 「同文件同机制 = 同一发现,不分车道,首触定级即并:证据搬先卡,后卡关duplicate_of」, :369 「同族异缺陷 ⛔ 不并:互链排同批;在飞(assignee/open PR)永不并,Blocked-by:不派;完工查过期」, :370 「执行席 ⛔ 不并卡,疑重复挂pm:retriage写明哪两张同文件同机制;…」SKILL.md:223 (分诊唯一生产duplicate_of), :224 (执行席误标 ⇒pm:retriage), :366 (查重先按文件/机制);core-rules.md:137 (去重并卡 = 记账不升级) — no core-rules line states the merge rule itself, so no twinSKILL.md:454–:455 (在飞卡衍生三分 / sub-issue) and :471 (Release:行点名已落项与余项去向) never required the new card's face to say which half it carriesSKILL.md:458 (new) 「自在飞派发升级出的卡首行一句:本卡承哪一半、父卡留哪一半;缺此行不入队不入箱」SKILL.md:456–:457 (sub-issue inherits domain / priority; the one dispatch bypass), :471Prior rulings on this card:SKILL.md:357 「决策箱勤务:落卡入箱时校验/补全四棱块与速读;…」 checked the 速读 and four-facet block only; no intake refusal existed anywhereSKILL.md:357 (intake also checks thePrior rulings on this card:line), :358 (new) 「线程有Ruling:/RULED 的卡再入箱,该行逐 id 各一句变化;缺行 ⇒ 拒入,pm:retriage回立卡者」SKILL.md:340 (Prior rulings read:line at classification), :733 (出决策箱须引裁决 id);decision-analysis.md:45;dispatch-runbook.md:84 (Ruling-ref:);state-machine.md:40–:41 (who hangs and who removespm:retriage)director.md:40 「第一步:逐卡过一类自裁三判据;全立者录裁转工作态、只入收班追认表,⛔ 不呈批」 — read as 「screen the whole inbox, then present」director.md:40 「首批读完前 ≤5 张同族卡即呈;一类自裁按批过,⛔ 不先扫全箱,自裁者由下一候选补位」, :41 「取下五张只用便宜扫描:标签、assignee、PR 引用、速读首行;全文只读手上五张」, :42 「判据:开场标记→首批 ≤ 读五张;全立者录裁转工作态、只入收班追认表,⛔ 不呈批」 (the old :40 tail kept verbatim)director.md:44 「一次只开一批」 (pacing, not the pre-read); :23 (每批 5 张)SKILL.md:223 「分诊座位唯一生产:…duplicate_of」 with no exception anywhereSKILL.md:370 tail 「同 assignee 者自关后卡」 — the holding seat closes the later card asduplicate_ofitself, nopm:retriageround tripPaid for by retiring five second pointers and two restated lines — net 0 per file
SKILL.md:321 「since读法与成本对价见references/dispatch-runbook.md」dispatch-runbook.md, still pointed at from :384, :532, :588, :729SKILL.md:560 「云卡四课与接手协议增量见references/dispatch-runbook.md」dispatch-runbook.md:115 「## 云卡(mode:cloud)四课」, :143 「## 接手中断的 dev」; pointed at from :532SKILL.md:650 「os-regen 的陷阱与锚点禁令见 landing-operations A」references/landing-operations.md」;os-dev.md:197–:198 carry the trapSKILL.md:657 「首次入队 flip 定点、MERGED 两读数、关键 PR 订阅与退订/归档细则见 landing-operations B」SKILL.md:771 「总监席不占domain:*,永不认领 backlog、永不写码;章程见references/lanes/director.md」director.md:19 (the rule);SKILL.md:57 and :675 (the pointer)director.md:42 「一行回批即全链执行,裁后四件原子执行不再请示」decision-analysis.md:14 (⛔ 不为它另起请示轮),SKILL.md:728 (四件同笔);director.md:46 points at decision-analysisdirector.md:51 「代裁通道的置信门与人工地板见 SKILL.md 分诊座位职责,⛔ 不另抄」SKILL.md:392–:399 (人工地板, 置信门), :770 (总监席是唯一裁决者)Clauses compressed inside a rewritten line, and where each now lives:
SKILL.md:357 「语言按不变量」「子轮」SKILL.md:367 「⛔ 不并排派发」Blocked-by:不派」 + :370 (execution seat raisespm:retriage): two same-finding cards can no longer be dispatched side by sideSKILL.md:368 「open 未认领 ⇒ 先并成一个派发入口」SKILL.md:368 「已完成 ⇒ 卡可能过期」os-dev.md:46 「由写它的人以外的人」→「他人」 · :48 「文档 nit」→「nit」os-dev.md:49 「席位 ACCEPT 读」SKILL.md:778–:779 (the seat's ACCEPT disposition)core-rules.md:87 「先发修复指令再跳过,不可派发」→「发修复指令不派」SKILL.md:355 (the full rule)core-rules.md:151 「核验对读同轮报告」→「对读同轮」SKILL.md:780 (unchanged)Ceilings before / after (
node scripts/pm/check-skill-line-ratchet.mjs, green before and after).claude/skills/pm-dispatch/SKILL.md.claude/agents/os-dev.md.claude/skills/pm-dispatch/references/core-rules.md.claude/skills/pm-dispatch/references/lanes/director.md.claude/skills/pm-dispatch/references/state-machine.mdNo ceiling raised, no cross-file move declared. Twin rule: a rule changed in
SKILL.mdthat has acore-rules.mdtwin changed there in this PR (:87 for item 1, :151 for item 2); items 3, 4, 5, 8 have no core-rules twin line, so none was added.Item 2's lock — measured, not written
.claude/settings.jsonpermissions.denyholds 17mcp__github__*write tools, includingissue_writeandsub_issue_write— the MCP half of 「devs do not file」 is already mechanical (lock 1;check-settings-deny-roster.mjspins the roster).permissions.allowpre-approvescurl -sS -X POST …/issues/*/labels(labels) and noPOST …/issues(create): the REST create is neither allowed nor denied — it falls to the session's permission mode, not to a rule.guard-main-checkout-bash.shmentionscurl, as a write-redirection shape, not a URL.references/rest-channel.md:41 declaresPOST …/issuesa ✓ seat channel (「建卡带标签POST .../issues」) and the seats file cards through it; a dev subagent runs inside the seat's session under the samesettings.json. A Bash deny rule onPOST …/issueswould refuse the seat's own filing — exactly the conflict the claim anticipated — so no rule is added. The report'sopen_questionscarries the two mechanisms that could bind the dev without the seat (an agent-scoped PreToolUse hook declared inos-dev.mdfrontmatter; a guard branch keyed on a subagent signal in the hook payload), both needing a measurement of what the harness hands a subagent's hook, and both on the human floor (新增必需 hook).Why
state-machine.mdis untouchedThe claim listed it for item 4(ii). It is 42 / 42 on the ratchet (mechanism assumption 4: the row exists), has no
needs-user-decisionsection, and itspm:retriagesection already governs the refusal's mechanics — :40 (挂标者 = 提出异议的席位, evidence + the ask in one stroke) and :41 (摘标者 = 分诊 Routine, next fire). The intake duty the card itself names (「落卡入箱时校验/补全」) lives atSKILL.md:357, so 4(ii) lands there. Nothing instate-machine.mdis a second pointer or a restated line worth retiring to add a twin.Mechanism assumptions — each verified
dispatch-gates --tier --repo objectstack-ai/objectstackon the five paths → MANDATORY, path-derived fromSKILL.mdandos-dev.md; the register (check-governed-merges.mjsrowclaude-tree) puts.claude/**in Tier S.node scripts/pm/check-governed-merges.mjs --pr Nruns after this PR opens; its reading is in the report comment on finding(skills/pm-dispatch): the director charter's step order reads as 「screen the whole inbox before the first batch」 — summon #25 presented batch #192 only after reading all 51 cards; and ruled cards re-enter the decision box without citing the ruling on their own thread #19340 (GOVERNED, exit 3, Tier S expected)..claude/settings.json, which this PR does not.origin/mainmoved by one commit since the branch point (57ceb9d,scripts/only, no.claude/path) — nothing to merge..claude/**:scripts/check-skills-token-ratchet.mjsprices the publishedskills/**only;.claude/**is priced in lines bycheck-skill-line-ratchet.mjs. Ceilings not raised.state-machine.mdrow. Present at 42 — see above.Verification (head
a2665ce)Derived union —
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack(no paths; change set 4 paths vs merge base23f1de0, 48 changed lines vs the 5000 threshold: under) → 23 commands, each exit captured before any pipe, reconciled with--ran: 「23 derived famil(ies) accounted for — 23 run, 0 NOT-MEASURED (a DERIVED zero — all 23 recorded an exit code and none of them is 3)」.check:doc-formula-expressionsfirst exited 3 (PREREQUISITE NOT MET —@objectstack/formulaand@objectstack/lintunbuilt; not a measurement); both were built underbash scripts/pm/os-verify-lock.sh(VERDICT command-exit 0, 4 tasks, cached) and the gate re-ran to exit 0. The three named gates pluscheck-nul-bytesandcheck-agent-model-declaredwere also run directly vianodeon the working tree before the commit, exit 0 each.pnpm check:pm-dispatch-gates(not in the derived union) runs detached with its exit captured to a log; at PR open it stood at 1715 cases ✓ / 0 ✗ and still running — its final exit is in the report comment.四维分析 — 每处措辞的取舍
finding积压超过运行手册 15 张告警线(第 1、2 项)。措辞只写机制与判据,不写故事;判据可核验(开场标记→首批 ≤ 读五张;线程有Ruling:而卡面缺行 ⇒ 拒入)。SKILL.md:357 的决策箱勤务行,并卡规则在查重三行,总监节奏在章程 :40–:42),不另起一节。第 2 项的锁没有落:实测无规则拒POST …/issues,而settings.jsondeny 会一并锁住席位自己的立卡通道 —— 加一条会破坏立卡的规则是「workaround」,故按裁决意图只落报告契约半边,机制半边作为待决问题带四轴上报。noted, not filed: …)改成两个具名字段(class: a|b|c+ 证据 /carrier:),缺字段的条目有确定去向(Acceptance notes),席位处置是三选一的固定拼写;入箱拒入是机械判据(线程有Ruling:/RULED 而卡面缺行),不靠席位记得去读线程 —— 这正是本场 5 张重入卡的失效形态。state-machine.md不为一个已有归宿的规则新增一节。维护者速读(草稿)
改了什么 — 把您 2026-09-20 对立卡与并卡流程的裁定(「1 2 3 4 5 6 8」,总监席记录 5750077963)中的六项(第 6 项由 #19344 另落)逐条落进章程:立卡门槛反转(只立三类,且缺陷须今天可达、元数据陷阱须具名生产者;观察类 / 休眠 / 零拉动 不立卡、不进汇总卡、不设配额);dev 不立卡,报告每条带
class:+ 证据或carrier:,席位在 ACCEPT 逐条一行处置;分诊首触定级即并同文件同机制的卡,同族异缺陷互链排同批、在飞永不并,执行席只挂pm:retriage;同 assignee 的重复由持有席自关;从在飞派发升级出的卡首行写明承哪一半;线程已有裁决的卡再入决策箱必须带Prior rulings on this card:行,否则拒入;总监席读完前五张同族卡即呈首批,一类自裁按批过,排序只用便宜扫描。四个受棘轮文件全部净 0 行(813 / 403 / 151 / 72),每条新规则以退掉一条重复指针或一条他处已原样陈述的行付账;state-machine.md未动。为什么改 — 章程原文与已生效裁定相反或缺失:
director.md:40 仍写「第一步:逐卡过一类自裁」(本场总监席因此读完 51 张卡才呈第一批);SKILL.md没有「首触即并」「同持有自关」「Prior rulings on this card」任何一句;os-dev.md的报告契约没有class:/carrier:字段,且三行仍把「立单」写成 dev 的动作。每个席位每次 fire 都读这些文件,错一句就整队照错。风险与代价(含回滚) — 纯文本改动,零代码、零工作流、零 settings;派生门禁 23 / 23 绿。代价是为了净 0 而退掉的 7 行(5 条第二指针、2 条他处原样陈述的规则)与重写行里压缩掉的几个短语,每一条都在上方表格里点名了现在住在哪一行;若您认为任一条不该退,恢复它是一行 revert,但要同时退另一行才能过棘轮。第 2 项的机械锁没有落:实测今天没有任何规则拒绝 dev 会话的 REST
POST /issues(MCPissue_write已 deny;REST 建卡既不在 allow 也不在 deny),而在settings.json加 deny 会同时锁住席位自己的立卡通道,故作为待决问题上报而不硬加。席位意见 —(留空,由席位定稿)
你要做的 — 本 PR 走 Tier S 席内复核落地,不需要您点击。唯一待您一字的是第 2 项机械锁的形态(报告
open_questions):A 以os-dev.mdfrontmatter 的 agent 级 PreToolUse hook 只锁 dev 会话 / B 暂不加锁、只靠报告契约与 ACCEPT 处置 / C 其它。Acceptance notes
Prior rulings read:(tool-printed bycheck-prior-rulings.mjs, ids only;decision-analysis.md:45) and the ruledPrior rulings on this card:(hand-written, id + one sentence each) are now two spellings for one fact on a card face; the tool could print a stub of the second. 承接者: the skills seat (this lane), when a card asks for it — no PR heads forcheck-prior-rulings.mjstoday.SKILL.md:223 still reads 「分诊座位唯一生产 …duplicate_of」 with the item-8 exception only at :370; no 120-byte spelling of the exception fits on :223 (four variants measured 125–153 B). 承接者: the next PR that touches :223.os-dev.md:48 keeps 「未演练漂移」 while the seat-side list (SKILL.md:351) says 「休眠」 — same class, two words. 承接者:无..claude/**is the superseded boundary; PR fix(pm): repair two carriers still spelling the superseded references-tier boundary #19379 repairs the two carriers still spelling it (out of scope here; fix(pm): repair two carriers still spelling the superseded references-tier boundary #19379 remains open).Generated by Claude Code