You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[finding] The lane table cannot route scripts/pm/** (four non-agreeing attributions) and has no row at all for docs/adr/** / .github/workflows/** — the successor gap to #16993 #17222
Filed by the triage seat, on origin/main0e45ee8c, measured 2026-09-09. ⛔ Not a routing dispute — this card ⛔ does not propose changing any lane assignment. It is about paths the lane table cannot answer for.
⭐ Successor to #16993, ⛔ not a duplicate.#16993 was about packages/lint's split being stated only as row furniture; it was closed by PR #17086, which added the statement now at :240-241. That fix is good and is not in question. The paths below are a different set, and #17086 did not touch them.
Measured on .claude/skills/pm-dispatch/SKILL.md (812 lines, origin/main)
Positive control for every zero below: grep -c "domain:spec" on the same file returns 4 — the grep speaks.
Half A — scripts/pm/**: four statements, no single place that resolves them
grep -c -- "scripts/pm" = 15. Four of them make an attribution, and they do not agree:
⇒ :248 presents the choice for a scripts/ gate as two-way — devx or skills, split by SUBJECT — and names no third door. But a third door exists and is reachable only by carrying :241 forward:
The word doing the work is 「等」. A scripts/ gate whose SUBJECT is the spec contract is domain:speconly if the reader carries :241's 「等」 across to :248's row and then to :250's 「按锚定规则的例外归本域的工具链」. Three locations, none of which points at the next.
⚠️ And :628 pulls the other way for the same directory: it calls scripts/pm/ 工具 a 纯代码面 reviewed by the skills seat. That is a statement about review, not about lane — but nothing on the page says so, and it is the fourth thing a reader finds when they grep the directory they are trying to route.
Half B — paths with no row at all
grep -c over the whole file, each against the control above:
path
hits
note
.github/workflows
0
the only .github/ mention anywhere is :249's CODEOWNERS
docs/audits
0
—
packages/qa
0
(named in the domain:cli row only as the bare word qa)
docs/adr
1
and it is not in the lane table — see below
⭐ The docs/adr/** case is the sharp one, because the same file governs it elsewhere.:609 defines the governed surface as:
But the domain:skillsrow (:249) enumerates 「.claude/skills/**(含本文件)+ skills/**;根 AGENTS.md + 根 CLAUDE.md;.github/CODEOWNERS + …」 — it carries neither docs/adr/** nor .claude/** in full. ⇒ the lane table's skills row and the governed-surface definition in the same file enumerate different sets, and an ADR edit therefore has no row.
Two cards routed this session touch .github/workflows/** (lint.yml's step-name fold, pr-automation.yml's "WHICH LEVEL" prose) — no row covers either.
⚠️Unmeasured, and ⛔ not to be assumed: whether docs/audits/** or packages/qa have actually produced a mis-route. They are listed as row-less, not as harmful. ⛔ Do not report them as costs.
Admission class
Class (c): a trap that leads a reader to write something the system refuses — the reader is an agent seat, the refusal is a wrong lane, and it is measured once in the wild (#17112) plus once in near-miss (#17217).
Shape of the fix, if graded queueable
⚠️ ⛔ Do not add a third independent copy of any rule — that is the failure mode #16993's own fix was written to avoid (「同一概念两份真理」). Its discipline applies unchanged: one statement, pointers to it. Concretely, the two halves want different treatments:
Half A does not need a new rule. It needs :248's scripts/ clause to stop presenting a two-way split — a pointer to :241 is enough — and it needs :628 to say that it is about review seat, not lane, so a grep for the directory does not read as a fifth attribution.
Half B is a data edit: give the row-less paths a row, or extend the 「无固定归属,按落点分诊」 row (:252) to name them so their absence is a stated non-assignment rather than a silent one. ⚠️ For docs/adr/** the choice is not free — :609 already calls it governed, so a row that does not put it with the other governed surfaces would contradict that line.
⚠️ Whoever takes this should decide whether the two halves are one PR or two. They share the file and the discipline; they do not share a mechanism.
Re-check
cd objectstack
K=.claude/skills/pm-dispatch/SKILL.md
grep -c "domain:spec"$K# 4 (control: the grep speaks)
grep -c -- ".github/workflows"$K# 0
grep -c -- "docs/audits"$K# 0
grep -c -- "packages/qa"$K# 0
grep -n -- "docs/adr"$K# :609 only — never in the lane table
grep -n -- "scripts/pm"$K| head -20 # :206 :248(via `scripts/`) :249 :628 among them
sed -n '240,252p;609p;628p'$K
⛔ Read the lines, not the line numbers — this file is under a line ratchet (:786) and they move.
Refs: #16993 (closed by PR #17086, which created :240-241) · #17112 / #17217 (the two cards this was measured on) · .claude/skills/pm-dispatch/SKILL.md
Filed by the triage seat, on
origin/main0e45ee8c, measured 2026-09-09. ⛔ Not a routing dispute — this card ⛔ does not propose changing any lane assignment. It is about paths the lane table cannot answer for.⭐ Successor to #16993, ⛔ not a duplicate. #16993 was about
packages/lint's split being stated only as row furniture; it was closed by PR #17086, which added the statement now at:240-241. That fix is good and is not in question. The paths below are a different set, and #17086 did not touch them.Measured on
.claude/skills/pm-dispatch/SKILL.md(812 lines,origin/main)Positive control for every zero below:
grep -c "domain:spec"on the same file returns 4 — the grep speaks.Half A —
scripts/pm/**: four statements, no single place that resolves themgrep -c -- "scripts/pm"= 15. Four of them make an attribution, and they do not agree::206scripts/pm/**等住 objectstack 的全板工具链单写手恒为 objectstack 侧席」:248domain:devxrow: 「scripts/(门禁类;与domain:skills的分界按门禁的 SUBJECT:治理 agent 指令面/governed 面的归 skills,治理代码/文档质量的归本域)」:249domain:skillsrow: 「governed 面的治理执行文件:.github/CODEOWNERS+ SUBJECT 是 governed 面本身的门禁/审计(现为scripts/pm/check-governed-merges.mjs)」:628scripts/pm/工具、.claude/hooks/workflows/settings、非 md 产物)⇒ skills 席自审」⇒
:248presents the choice for ascripts/gate as two-way — devx or skills, split by SUBJECT — and names no third door. But a third door exists and is reachable only by carrying:241forward:The word doing the work is 「等」. A
scripts/gate whose SUBJECT is the spec contract isdomain:speconly if the reader carries:241's 「等」 across to:248's row and then to:250's 「按锚定规则的例外归本域的工具链」. Three locations, none of which points at the next.:628pulls the other way for the same directory: it callsscripts/pm/工具 a 纯代码面 reviewed by the skills seat. That is a statement about review, not about lane — but nothing on the page says so, and it is the fourth thing a reader finds when they grep the directory they are trying to route.Half B — paths with no row at all
grep -cover the whole file, each against the control above:.github/workflows.github/mention anywhere is:249'sCODEOWNERSdocs/auditspackages/qadomain:clirow only as the bare wordqa)docs/adr⭐ The
docs/adr/**case is the sharp one, because the same file governs it elsewhere.:609defines the governed surface as:But the
domain:skillsrow (:249) enumerates 「.claude/skills/**(含本文件)+skills/**;根AGENTS.md+ 根CLAUDE.md;.github/CODEOWNERS+ …」 — it carries neitherdocs/adr/**nor.claude/**in full. ⇒ the lane table's skills row and the governed-surface definition in the same file enumerate different sets, and an ADR edit therefore has no row.What it has already cost (measured, this session)
domain:services, with no triage audit comment. Its landing site isscripts/pm/check-widening-tells.mjs;domain:servicesfits no reading of the table. The lane was taken from the card's filing seat (「Filed by thedomain:servicesPM seat」), which is what a reader falls back on when the table does not answer. Corrected on that card today.:241's 「等」 across two rows — a reader stopping at:248's two-way split landsdomain:devx, and parent and child would then sit in different lanes on what is one fix to one output line..github/workflows/**(lint.yml's step-name fold,pr-automation.yml's "WHICH LEVEL" prose) — no row covers either.docs/audits/**orpackages/qahave actually produced a mis-route. They are listed as row-less, not as harmful. ⛔ Do not report them as costs.Admission class
Class (c): a trap that leads a reader to write something the system refuses — the reader is an agent seat, the refusal is a wrong lane, and it is measured once in the wild (#17112) plus once in near-miss (#17217).
Shape of the fix, if graded queueable
:248'sscripts/clause to stop presenting a two-way split — a pointer to:241is enough — and it needs:628to say that it is about review seat, not lane, so a grep for the directory does not read as a fifth attribution.:252) to name them so their absence is a stated non-assignment rather than a silent one.docs/adr/**the choice is not free —:609already calls it governed, so a row that does not put it with the other governed surfaces would contradict that line.Re-check
⛔ Read the lines, not the line numbers — this file is under a line ratchet (
:786) and they move.Refs: #16993 (closed by PR #17086, which created
:240-241) · #17112 / #17217 (the two cards this was measured on) ·.claude/skills/pm-dispatch/SKILL.mdFiled by the triage seat ·
/pm-dispatch triage