Skip to content

[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

Description

@os-zhuang

Filed by the triage seat, on origin/main 0e45ee8c, 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:

line what it says
:206 scripts/pm/** 等住 objectstack 的全板工具链单写手恒为 objectstack 侧席」
:248 domain:devx row: 「scripts/(门禁类;与 domain:skills 的分界按门禁的 SUBJECT:治理 agent 指令面/governed 面的归 skills,治理代码/文档质量的归本域)」
:249 domain:skills row: 「governed 面的治理执行文件:.github/CODEOWNERS + SUBJECT 是 governed 面本身的门禁/审计(现为 scripts/pm/check-governed-merges.mjs)」
:628 「纯代码面(scripts/pm/ 工具.claude/ hooks/workflows/settings、非 md 产物)⇒ skills 席自审

: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:

:241  唯一例外 `packages/lint` 等与 spec 相交的 devx 面:围着 spec 契约转的归 `domain:spec`,余留 devx。

The word doing the work is 「等」. A scripts/ gate whose SUBJECT is the spec contract is domain:spec only 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:

:609  governed 面统一定义:`docs/adr/**` + `.claude/**`(全量,含 agents/hooks/settings)+ `skills/**`。

But the domain:skills row (: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.

What it has already cost (measured, this session)

  1. [finding] check-widening-tells counts a file it structurally cannot judge as "read" — so exit 0 reads as corroboration for every published surface outside packages/spec #17112 was laned domain:services, with no triage audit comment. Its landing site is scripts/pm/check-widening-tells.mjs; domain:services fits no reading of the table. The lane was taken from the card's filing seat (「Filed by the domain:services PM seat」), which is what a reader falls back on when the table does not answer. Corrected on that card today.
  2. [finding] check-widening-tells' CLI cannot be told the repo, so its declared objectui mirror row is unreachable — every objectui diff reads clean, including one that DOES add a key to packages/types/src/zod/** #17217 (its sub-issue) could be routed only by carrying :241's 「等」 across two rows — a reader stopping at :248's two-way split lands domain:devx, and parent and child would then sit in different lanes on what is one fix to one output line.
  3. 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 · /pm-dispatch triage

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions