skills(pm-dispatch): the lane table routes a scripts/ gate three ways by pointer and names every row-less path - #17226
Conversation
… by pointer and names every row-less path Half A: the `domain:devx` row's `scripts/` clause no longer presents a two-way split (devx vs skills by SUBJECT); `packages/lint`, `scripts/` and `.github/workflows/` share one pointer to the anchoring exception (spec-contract subject ⇒ `domain:spec`, the spec row's tool-chain clause), then the SUBJECT split between skills and devx follows. The landing-path line under the ACCEPT fork says in its own words that it names the REVIEW seat, not the lane. Half B: the `domain:skills` row cites the governed-surface definition instead of re-enumerating a subset of it (so `docs/adr/**` and `.claude/**` in full have a row); `docs/audits/**` joins the no-fixed-home row as a stated non-assignment; `.github/workflows/` is spelled in the devx row as the devx lane description already states it; `packages/qa` is spelled as the path in the cli row. Line-neutral at 812/812; every edited row stays under the 342-byte table-row pin; the edited landing-path line is 119 of 120 bytes. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MoTv7pn338AZ71owsp19gQ
维护者速读改了什么 — 只改 PM 派发技能的主文件 为什么改 — 分诊席实测:同一个目录 风险与代价(含回滚) — 纯指针改动:不动任何门禁脚本、不动锚定规则本身、不改任何既有归属;行数上限与表格行宽上限都没抬,相关门禁本席在该提交上复跑全绿;与另一张等你合并的 PR #17220 在同一文件的不同区域,两种合并顺序都干净。唯一需要你过目的判断: 席位意见 — 通过。dev 对派发裁决的这一处偏离本席接受,理由如上;其余四处逐行核过,与卡上的再检查命令一致。 你要做的 — 确认 Generated by Claude Code |
Fixes #17222
One governed file, both halves of the card, under the card's own discipline (quoted on #16993 and #17222): 「同一概念两份真理」 is the failure mode — one statement, pointers to it. ⛔ Not a routing dispute: no lane assignment changes. Every edit is a pointer or a data row; no rule text is added, none is restated. Line-neutral:
.claude/skills/pm-dispatch/SKILL.mdstays at 812/812, every edited table row stays under the 342-byte pin, and the one edited prose line is 119 of 120 bytes.Half A — a
scripts/gate resolves from the row a reader lands ondomain:devxrow (:248) — 311 → 330 bytes (pin 342)before:
after:
(inline code spans inside the row are shown without their backticks so the quote stays one line)
scripts/clause no longer presents a two-way split.packages/lint,scripts/(门禁类) and.github/workflows/(门禁接线) share one pointer — 「三者与 spec 相交的面按锚定规则的例外归domain:spec」 — to the anchoring exception at :241 (「围着 spec 契约转的归domain:spec,余留 devx」) and, through thedomain:speclabel, to the spec row's tool-chain clause at :250 (「按锚定规则的例外归本域的工具链」). The three-way answer (spec / skills / devx) is now reachable from this row without carrying :241's 「等」 across two rows.domain:skills的分界按门禁的 SUBJECT」).:628, the ACCEPT path-fork line — 113 → 119 bytes (cap 120)
before:
after:
scripts/pmno longer reads it as a lane attribution. The two surface spans (scripts/pm/,.claude/) are byte-identical. The word 工具 afterscripts/pm/was dropped to pay for 复核席为 under the 120-byte line cap — the path names the same thing.check-governed-prosepinned region (:607–:633, from**ACCEPT 之后的路径分叉to本段只适用本循环派发的 dev PR); the region still names all five registered surfaces and no**-shaped span was added, so the gate stays green (verdict quoted below). :609/:610 (the governed-surface definition) are untouched.Half B — every path has a row or a stated non-assignment
domain:skillsrow (:249) — 253 → 254 bytesbefore:
after:
docs/adr/**+.claude/**(全量,含 agents/hooks/settings)+skills/**」, :610 forAGENTS.md+CLAUDE.md) instead of re-enumerating a subset of it. An ADR edit, and any.claude/**file, now has a row — through the definition, which stays the single statement. The pointer names :609's literal phrase so a grep finds it in one hop.grep -n docs/adron SKILL.md still lands on :609 only — by design, the row points rather than re-spells.(无固定归属,按落点分诊)row (:252) — 184 → 203 bytesdocs/audits/**joins as a stated non-assignment. No lane invented: nothing under.claude/**or inAGENTS.mdassigns it (the only mentions are tooling paths inscripts/).domain:clirow (:251) — 262 → 271 bytesqa→packages/qa, so the grep speaks. The row already named it; not a routing change..github/workflows/— in thedomain:devxrow (see the deviation below)Deviation from dispatch ruling 3(b), declared
The ruling placed⚠️ makes the same argument for
.github/workflows/**in the no-fixed-home row as a stated non-assignment, on the premise that no lane statement covers it. Measured onorigin/mainbccf3111:.claude/skills/pm-dispatch/references/lanes/devx.md:8— the devx lane's own job description — already states 「scripts/(门禁类)、.github/workflows/(门禁接线)」 as devx scope. A no-fixed-home entry would contradict that maintainer-merged line, which is the 「两份真理」 the card's discipline forbids (the card's owndocs/adr/**against :609). So the devx row mirrors devx.md:8 byte-for-byte into its gate clause instead. This is not a new lane assignment: it is the existing one, made visible where the reader lands, under the same SUBJECT split ascripts/gate gets — which is the reading the ruling itself anticipated a triage seat would apply, and that per-card SUBJECT call stays triage's. If the seat rules otherwise, the swap is one line: drop 、.github/workflows/(门禁接线) from :248 (row would read 「三者」 → 「二者」, 289 bytes) and append 、.github/workflows/**to :252 (228 bytes).Ceilings and pins (
check-skill-line-ratchet, before → after, both on this branch)paid_by.domain:enginerow :246, untouched); pin 342 unchanged, headroom 0 before and after.cdefa340(row :246 widened by one ASCII byte to 343, on-disk anchorgrep -c= 1):✗ check-skill-line-ratchet: .claude/skills/pm-dispatch/SKILL.md has a 343-byte table row at L246; the max-table-row-bytes pin is 342.— exit 1; probe worktree removed, main worktreegit status --porcelainempty.Re-check (the card's block, on
cdefa340)grep -c "domain:spec"→ 5 (was 4: the devx row now namesdomain:specas its pointer)grep -c ".github/workflows"→ 1 (:248) ·grep -c "docs/audits"→ 1 (:252) ·grep -c "packages/qa"→ 1 (:251)grep -n "docs/adr"→ :609 only (the skills row points at it; see above)grep -n "scripts/pm"→ :206 (single writer, untouched) · :249 (the skills row's named governed-surface gate) · :628 (now the review seat, in its own words) · the rest are command spellings and the 机械守卫索引 tableGates (every family
dispatch-gates.mjsderives for this file, plus the dispatch-named ones; all atcdefa340)pnpm check:pm-skill-ratchet—✓ check-skill-line-ratchet self-test: 157 cases pass.·✓ … SKILL.md: widest table row is 342 bytes (pin 342; headroom 0).·✓ … SKILL.md is 812 lines (ceiling 812; headroom 0).pnpm check:pm-governed-prose—✓ check-governed-prose self-test: 28 cases pass.·✓ check-governed-prose: 2 instruction surface(s) name all 5 registered governed surfaces (docs/adr/** · .claude/** · skills/** · AGENTS.md · CLAUDE.md) and claim no others.pnpm check:pm-skill-id-lint—✓ check-skill-id-lint: 26 file(s) clean (pattern /#[0-9]{3,}/g).pnpm check:skill-frame-sync—✓ check-skill-frame-sync: 2 copies of the decision frame are structurally isomorphic across 2 filespnpm check:skill-frame-freshness—✓ … the decision frame in this tree is current with origin/main (fetched just now).pnpm check:pm-half-states—✓ check-half-states self-test: 3019 cases pass.·pnpm check:pm-clause2-carriers—✓ check-clause2-carriers self-test: 319 cases pass (…)·pnpm check:pm-widening-tells—✓ check-widening-tells self-test: 173 cases pass (…)— assumption D holds: no edited line is a pinned string in any of the three (grep of every edited phrase overscripts/returns nothing).pnpm check:pm-dispatch-gates(run detached, over the 600 s cap) —✓ dispatch-gates self-test: 1624 cases pass.pnpm check:agent-test-spelling,pnpm check:doc-authoring,pnpm check:pm-governed-merges,node scripts/pm/check-governed-queue-guard.mjs --self-test,pnpm --filter @objectstack/lint run check:doc-formula-expressions(after building@objectstack/formula+@objectstack/lintunder the verify lock — the gate refuses on an unbuilt dist),pnpm check:nul-bytes,node scripts/check-closing-keyword-parity.mjs --self-testand the gate,node scripts/check-comment-mask-corpus.mjs,pnpm check:watch-hint-literal,pnpm check:refd-timer-probe,pnpm check:driver-memory-census— all exit 0.✓ dispatch-gates --ran: 16 derived famil(ies) accounted for — 16 run, 0 NOT-MEASURED.(change set derived from the merge basebccf3111: the one file).node scripts/pm/check-governed-queue-guard.mjs(the gate itself) is CI-measured only — it reads the workflow event payload.core-rules.md twin
references/core-rules.md〈域车道〉 (:64–:65) carries only the anchoring rule with a pointer to SKILL.md's exception; no sentence changed here has a twin there (each edited phrase grepped overreferences/— nothing). Left untouched, as ruling 5 requires.PR #17220 regions and merge order
PR #17220 (
origin/claude/issue-17017-awaiting-maintainer-carrierataf85c612) touches SKILL.md at :108, :128 and :707–:711; this PR touches :248, :249, :251, :252 and :628 — disjoint, not touched. Both merge orders are clean (HEADcdefa340,origin/mainbccf3111):git merge-tree --write-tree origin/main HEAD→ exit 0, tree6463089164df2920162298ab3670d9aa139b6da2git merge-tree --write-tree origin/claude/issue-17017-awaiting-maintainer-carrier HEAD→ exit 0, treed3800a96a05da4381eec04aa133ec6d37ab3617dChangeset
skip-changeset:.claude/**publishes nothing (a governed, repo-internal agent playbook; no packagefiles[]reaches it). No gate demanded a changeset.Acceptance notes
scripts/clause covers gates only — a non-gatescripts/**script has no row,scripts/pm/**is stated only inreferences/lanes/skills.md, and three devx.md:8 paths have none — the successor gap to #17222 #17225: the table'sscripts/clause covers gates only — a non-gatescripts/**script still has no row,scripts/pm/**is stated only inreferences/lanes/skills.md:7, and three pathslanes/devx.md:8states (.githooks/,docker/README.md,examples/**测试基建面) have none. Same class as this card, outside its rulings; routing is triage's, so it is a card, not a rider here.runtime,verify,types) grep 0 aspackages/…too; the ruling spelled onlyqaand that is what landed. 承接者: the skills seat, next time it edits the table.references/lanes/skills.md:6–9andlanes/devx.md:8–11are lane-file summaries of the table that both say the table is the 全量判据; after this PR they are consistent with it for the paths the card measured. 承接者: the skills seat (it owns both files).维护者速读(草稿)
改了什么:只改一个文件
.claude/skills/pm-dispatch/SKILL.md,五行原地改写、行数不变(812/812)。域车道表里:devx 行的scripts/条从「devx 与 skills 二选一」改成指向锚定规则例外的一句(与 spec 契约相关的门禁归 spec,其余按 SUBJECT 分 skills/devx),并把.github/workflows/照 devx 车道岗位说明原样列入;skills 行改为引用「governed 面统一定义」那一行,不再自抄一份子集(于是 ADR 与整棵.claude/都有了归属);「无固定归属」行加上docs/audits/**;cli 行把qa写全成packages/qa。复核段的「纯代码面 ⇒ skills 席自审」一行加上「复核席为」三字,说明它讲的是谁复核、不是归哪个车道。为什么改:分诊席实测,同一目录
scripts/pm/在文件里有四处说法互不衔接,而docs/adr/**等路径在表里根本没有行;已经造成一张卡分错车道、一张险些分错。修法遵守上一张同类卡定下的纪律:一处陈述、其他地方只做指针,不再多抄一份规则。风险与代价(含回滚):纯文档指针改动,不动任何门禁脚本、不动锚定规则本身、不改任何既有归属;所有相关门禁本地全绿,行数上限与表格行宽度上限都没抬。唯一需要维护者过目的判断:
.github/workflows/我按 devx 车道岗位说明列进了 devx 行,而不是派发裁决建议的「无固定归属」行,理由是岗位说明已经这样写了,两处说法不一才是这张卡要消灭的东西;不同意时只需把它从 devx 行挪到「无固定归属」行,一行的事。回滚 = revert 这一个提交。席位意见:
你要做的:确认
.github/workflows/的放行位置后,人工合并本 PR。Generated by Claude Code