Repository navigation
Commit d348707
pm-dispatch: governed is an approval tier, the lane follows the subject — rule text to skills, workflow wiring to devx (#27082)
Fixes #26997
Clause-②: no
Metadata-protocol: none
Ruling-ref: 6458715764
## 维护者速读
- 改了什么:`.claude/skills/pm-dispatch/SKILL.md` 域车道表两行 +
〈路径分叉〉一行,全部就地改、不加行(319/319)。`domain:skills` 行从「governed
面全量」改为规则文本清单(`AGENTS.md`、`CLAUDE.md`、`.claude/**`、`skills/**`、`docs/adr/**`、`docs/NORTH-STAR.md`);`domain:devx`
行把 `.github/workflows/**`(接线、CI 性能)收归本域;〈路径分叉〉的 governed 面定义保持原集合,加一句「定
Tier,非车道」。
- 为什么改:同一批文件(CI 工作流、AGENTS.md)在车道表里有两到三个归属,同一张卡可被两个席位认领、或无人认领;维护者已裁 B ——
governed 是批准等级,车道按主题。本 PR 只改「哪个席位可以认领哪类卡」:工作流/CI 性能卡留在 devx,规则文本卡归
skills。
- 风险与回滚:不放松任何批准 —— Tier H / Tier S 仍按路径判(〈路径分叉〉现在明说这一点);风险只在车道读法,回滚 =
revert 本 PR 的单个 commit。
- 先看:`.claude/skills/pm-dispatch/SKILL.md` L161(devx 行:工作流改归本域;spec
目的地按同格的「归 skills」拼法改拼作 bare `spec`,是裁决点名的信心缺口,见 Acceptance notes)→
L183(governed 面定义:去掉「统一定义」与 `(全量)` 两处注解换一句「定 Tier,非车道」)→ L162(skills
行:规则文本清单)。
- 两分钟验证:`pnpm check:pm-skill-ratchet && pnpm check:pm-governed-prose` ——
预期 `SKILL.md is 319 lines (ceiling 319)`、`widest table row is 341 bytes
(pin 341)`、`name all 13 registered governed surfaces … and claim no
others`。
- 需要你做的:无 —— `.claude/**` 是 Tier S,席位做契约复核(达档)后落地;裁决已在案(ruling record
6458715764)。
## What changes
One file, three lines, in place; the line count stays 319 / 319 and the
widest table row stays 341 / 341 (L160, not touched).
| Line | Row / bullet | Bytes before | Bytes after | Cap |
|:--|:--|--:|--:|--:|
| L161 | `domain:devx` row | 339 | 339 | 341 (table-row pin) |
| L162 | `domain:skills` row | 300 | 329 | 341 (table-row pin) |
| L183 | 〈路径分叉〉 governed-set definition | 120 | 120 | 120 (prose line) |
| L184 | 〈路径分叉〉 `AGENTS.md`+`CLAUDE.md` line | 120 | 120 (unchanged) |
120 (prose line) |
L161 before:
```text
| `domain:devx` | `sdui-parser`、`packages/qa`、`content/docs`、`apps/docs`、`docs/qa`、`.githooks`、`docker/README.md`、`examples/**` 仅测试基建面;`packages/lint`、`scripts`(门禁类)、`.github/workflows`(接线)三者按锚定规则归 `domain:spec`,门禁按 SUBJECT:governed 面归 skills,代码/文档质量归本域 |
```
L161 after:
```text
| `domain:devx` | `sdui-parser`、`packages/qa`、`content/docs`、`apps/docs`、`docs/qa`、`.githooks`、`.github/workflows/**`(接线、CI 性能)、`docker/README.md`、`examples/**` 仅测试基建面;`packages/lint`、`scripts`(门禁类)按锚定规则归 spec,门禁按 SUBJECT:governed 面归 skills,代码/文档质量归本域 |
```
L162 before:
```text
| `domain:skills` | governed 面全量(含本文件;统一定义见「governed 面统一定义」行);非门禁的 `scripts/pm/**`(PM 循环工具);governed 面的治理执行文件:`.github/CODEOWNERS` + SUBJECT 是 governed 面本身的门禁/审计(现为 `scripts/pm/check-governed-merges.mjs`) |
```
L162 after:
```text
| `domain:skills` | 规则文本:`AGENTS.md`+`CLAUDE.md`+`.claude/**`(含本文件)+`skills/**`+`docs/adr/**`+`docs/NORTH-STAR.md`;非门禁的 `scripts/pm/**`(PM 循环工具);governed 面的治理执行文件:`.github/CODEOWNERS` + SUBJECT 是 governed 面本身的门禁/审计(现为 `scripts/pm/check-governed-merges.mjs`) |
```
L183 before:
```text
- governed 面统一定义:`docs/adr/**`+`.claude/**`(全量)+`skills/**`+`docs/NORTH-STAR.md`+`.github/workflows/**`。
```
L183 after:
```text
- governed 面(定 Tier,非车道):`docs/adr/**`+`.claude/**`+`skills/**`+`docs/NORTH-STAR.md`+`.github/workflows/**`。
```
L184 (unchanged, 120 / 120 bytes):
```text
- governed 面同含 `AGENTS.md`+`CLAUDE.md`;`GOVERNED_REPOS` 同治理、行可限仓,执行席恒随落地仓车道。
```
What each edit does, against the ruling (letter B, ruling record
6458715764):
- **`domain:skills` row (L162)** — "governed 面全量(含本文件;统一定义见「governed
面统一定义」行)" becomes the rule-text list in the ruling's order:
`AGENTS.md`+`CLAUDE.md`+`.claude/**`(含本文件)+`skills/**`+`docs/adr/**`+`docs/NORTH-STAR.md`.
`.github/workflows/**` is deliberately absent from it. The rest of the
row (non-gate `scripts/pm/**`; CODEOWNERS + the governed-subject
gate/audit) is byte-identical.
- **`domain:devx` row (L161)** — the "三者…归 `domain:spec`" clause loses
its `.github/workflows`(接线) member, and `.github/workflows/**`(接线、CI 性能)
joins the row's own surface list (after `.githooks`, before
`docker/README.md`), so the workflows are the lane's own with CI
performance named as the ruling names it. The gates-by-SUBJECT clause
("门禁按 SUBJECT:governed 面归 skills,代码/文档质量归本域") is unchanged. The count
word 三者 is dropped rather than rewritten as 两者: with two members it
carried no information, and the row pin had no room for it.
- **〈路径分叉〉 (L183–L184)** — the governed set is kept with the same five
globs on L183 and `AGENTS.md`+`CLAUDE.md` on L184 (L184 unchanged); L183
now says in one clause what the set is for: "(定 Tier,非车道)" — it sets the
approval tier, not the lane. Tier H for workflows is therefore carried
here (path → Tier) rather than restated in the devx row, which had no
bytes left for "(仍 Tier H)".
The anchor rule's destination for `packages/lint` and `scripts`(门禁类) is
unchanged in substance — they still go to spec by the anchor rule — but
its spelling moved from `` `domain:spec` `` to bare `spec`, the same
bare form the cell already uses for "归 skills". This is the ruling's
named confidence gap being touched for a byte reason only: the 341-byte
table-row pin (L160 sits at 341, headroom 0) left the row 7 bytes short
with the literal label kept, and the only other way to fit was to drop
"CI 性能", which the ruling names explicitly. No restatement of the
scripts→spec rule is made or implied.
Two glosses left L183 to pay for the clause at the 120-byte line cap:
the word 统一定义 (the phrase 「governed 面统一定义」 was referenced only by L162,
which this PR rewrites; `git grep` finds no script or reference pinning
it) and `(全量)` after `.claude/**` (the glob is the whole tree by
construction, and L204 — "受管面两层:Tier S = `.claude/**` 全树" — keeps the
whole-tree emphasis in words). The PM's suggested spelling for the
clause (「governed 面只定批准档(Tier),⛔ 不定车道;车道按主题见域车道表」, appended to L184)
measures 202 bytes on L184 and 159 on L183; L184 is at 120 / 120 with no
gloss to remove, so the clause lands on L183 in the shortest spelling
that still names both halves (Tier, not lane).
`origin/main` was merged before opening (merge commit on top of the
edit; `origin/main` had moved by one unrelated dogfood-test commit,
`5cba8fc2`). At the moment of opening it had moved two commits further
(`cd609a49`: an ADR status batch and a ui change), neither touching this
file or any ratcheted file, so the branch is left at its merge point
rather than re-merged. PR #26749, which edits the `domain:cloud` row of
the same table, had **not** landed at the time of opening (state open,
`mergeable_state: blocked`); its row is four lines below this PR's rows
and the regions are disjoint.
## Tests
No package is touched, so no build closure (①) and no package
test/typecheck (②) is owed; the diff is `.claude/**` only, which
publishes nothing (`skip-changeset` declared on the create). No tested
behaviour changed, so no ablation.
Readings taken on the final head `0b1ae9b8` (edit commit `dd558521`,
merged with `origin/main` `5cba8fc2`). Every exit code was captured
before any pipe (`cmd > LOG 2>&1; EXIT=$?`).
<details><summary>Ratchet and governed-prose verdict lines</summary>
```text
✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/SKILL.md: widest table row is 341 bytes (pin 341; headroom 0).
✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/SKILL.md is 319 lines (ceiling 319; headroom 0).
✓ check-governed-prose self-test: 31 cases pass.
✓ check-governed-prose: 2 instruction surface(s) name all 13 registered governed surfaces that govern objectstack (docs/adr/** · .claude/** · skills/** · AGENTS.md · CLAUDE.md · docs/NORTH-STAR.md · .github/workflows/** · ui/docs/adr/** · ui/.claude/** · ui/skills/** · ui/AGENTS.md · ui/CLAUDE.md · ui/.github/workflows/**) and claim no others.
✓ check-skill-id-lint: 104 file(s) clean (pattern /#[0-9]{3,}/g).
check-skill-frame-sync: 4 axes: business-need → long-term-soundness → ai-authoring-safety → startup-scope-discipline; binding sentence present; 107 markdown files scanned for undeclared copies.
✓ check-skill-frame-freshness: the decision frame in this tree is current with origin/main (fetched just now).
```
</details>
<details><summary>Per-line byte measurement (python, utf-8)</summary>
```text
lines: 319
L161 bytes=339
L162 bytes=329
L183 bytes=120
L184 bytes=120
widest row bytes: 341 at L160
control-character scan over the file: 0 hits
```
</details>
## Acceptance notes
Lines that still tie a lane to governed-ness and are **not** edited here
(the ruling names only L161 / L162 / L183–L184; listed for the seat to
file or rule consistent):
- SKILL.md L164, the `domain:ui` row: 「…协议恒归 `domain:spec`,受管面归
`domain:skills`;详见 `references/lanes/ui.md`」 — under letter B,
`ui/.github/workflows/**` is workflow wiring inside ui's governed set,
and this row still routes every ui governed path to skills.
- `references/cross-repo-coordination.md` L11: 「objectui 仓已并入本仓 `ui/`:UI
卡住本仓,`ui/**` 代码归 `domain:ui`,受管面归 `domain:skills`。」 — the same tie as
the ui row, for the same path family.
- SKILL.md L184: 「…执行席恒随落地仓车道」 — the repo lane (which repository's seat
executes), not the domain lane; consistent with B, listed because it
sits in the same two-line definition.
- SKILL.md L204: 「受管面两层:Tier S = `.claude/**` 全树,余皆 Tier H 等人批;…」 —
approval axis only; consistent with B and now the home of the whole-tree
emphasis that `(全量)` used to carry on L183.
- `references/lanes/devx.md` L7: 「边界:守护 skills 的门禁脚本在 `scripts/`
下时归本席,判据是被改文件的路径。」 — a by-PATH rule for gate scripts that guard skills,
while SKILL.md L161 (unchanged clause) and L162 route gates by SUBJECT
(governed-surface gates → skills). Pre-existing tension outside this
card's question; the ruling says gates stay by SUBJECT as today.
- `references/lanes/director.md` L86: 「改 skill、指令或治理文本归 skills 席」 — rule
text → skills; consistent with B.
Mechanism hypotheses from the dispatch, as measured: ① held (rule-text
list fits the row at 329 bytes). ② held in substance; the count word is
dropped, not rewritten, and the spec label's spelling had to move to
bare `spec` to fit the 341-byte pin (named above as the confidence gap).
③ falsified on placement: L184 is at 120 / 120 and cannot take a clause;
the clause lands on L183 after two glosses leave it. ④ the list above. ⑤
held: `check:pm-governed-prose` stays green (the register and PD 14 are
untouched; the five globs on L183 are intact and no new `**`-shaped span
was added); `check:pm-skill-id-lint`, `check:skill-frame-sync`,
`check:skill-frame-freshness` all green.
## Verification
Local gate subset (derived with `node scripts/pm/dispatch-gates.mjs
--commands --repo objectstack-ai/objectstack`, no paths, from the
worktree after the final commit: 20 commands — 12 matched by path, 8
declared whole-tree), each exit captured before any pipe; `--ran`
reconciliation: `20 derived, 20 run, 0 NOT-MEASURED, 0 UNRUN`, with
`pnpm check:pm-settings-deny-roster` and `pnpm
check:skill-frame-freshness` recorded as outside the derivation.
<details><summary>Exit codes</summary>
```text
pnpm check:pm-skill-ratchet :: exit 0
pnpm check:pm-governed-prose :: exit 0
pnpm check:pm-skill-id-lint :: exit 0
pnpm check:skill-frame-sync :: exit 0
pnpm check:pm-governed-merges :: exit 0
pnpm check:pm-expected-skips :: exit 0
node scripts/pm/check-governed-queue-guard.mjs --self-test :: exit 0
node scripts/pm/check-harness-current.mjs --self-test :: exit 0
pnpm check:nul-bytes :: exit 0
node scripts/check-closing-keyword-parity.mjs :: exit 0
node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0
node scripts/check-comment-mask-corpus.mjs :: exit 0
pnpm --filter @objectstack/lint run check:doc-formula-expressions :: exit 0 (first run exit 3 = PREREQUISITE NOT MET, @objectstack/formula and @objectstack/lint not built — nothing measured; built under the verify lock, VERDICT command-exit 0, rerun exit 0)
pnpm check:agent-test-spelling :: exit 0
pnpm check:cross-package-test-inputs :: exit 0
pnpm check:doc-authoring :: exit 0
pnpm check:driver-memory-census :: exit 0
pnpm check:gitlink-declared :: exit 0
pnpm check:refd-timer-probe :: exit 0
pnpm check:watch-hint-literal :: exit 0
outside the derivation: pnpm check:skill-frame-freshness :: exit 0 (local-only family) · pnpm check:pm-settings-deny-roster :: exit 0 (roster under .claude, run and read)
```
</details>
CI-measured only (matched by path, no local invocation): `node
scripts/pm/check-governed-queue-guard.mjs` and its `--toolchain-needed`
form (`governed-surface-guard.yml`) — read from the PR's `Governed
Surface Queue Guard` check-run; a draft Tier S PR with no
contract-review record is expected to be held by it until the seat's
record exists. Every other family CI runs on this PR (`Lint & Repo
Gates` and the rest of the required set) is read from the PR's
check-runs by the seat, not re-run here.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01QSeKYmhU5KEj1nukYhp1Tg)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent d63f24a commit d348707
1 file changed
Lines changed: 3 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
158 | 158 | | |
159 | 159 | | |
160 | 160 | | |
161 | | - | |
162 | | - | |
| 161 | + | |
| 162 | + | |
163 | 163 | | |
164 | 164 | | |
165 | 165 | | |
| |||
180 | 180 | | |
181 | 181 | | |
182 | 182 | | |
183 | | - | |
| 183 | + | |
184 | 184 | | |
185 | 185 | | |
186 | 186 | | |
| |||
0 commit comments