Skip to content

Commit f76423d

Browse files
os-warrenclaude
andauthored
ci(pm): pin the governed-surface prose enumerations to GOVERNED_SURFACES (#9525) (#9841)
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 59b6e99 commit f76423d

4 files changed

Lines changed: 323 additions & 1 deletion

File tree

‎.github/workflows/lint.yml‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,25 @@ jobs:
293293
- name: Governed-merges audit self-test
294294
run: pnpm check:pm-governed-merges
295295

296+
# Governed-surface PROSE pin (#9525) — the other half of the step above.
297+
# `GOVERNED_SURFACES` is machine-read on every path decision, but the
298+
# sentences that TELL a seat which surfaces are governed are prose,
299+
# duplicated out of the register by hand, in AGENTS.md Prime Directive
300+
# #14 and the PM skill's ACCEPT path-fork. That duplicate went stale
301+
# twice in two days (#9395, #9511) and a human — not a gate — caught it
302+
# both times: #9525 re-ran the whole derived gate union against the stale
303+
# directive and every check came back green, with a positive control
304+
# proving the file IS scanned. This step asserts both directions: the
305+
# prose names every registered surface, and claims no surface the
306+
# register lacks (the direction that manufactures enforcement nobody
307+
# has). Unlike the audit next door it is a real gate, not only a
308+
# self-test — it reads the shipped files — so it runs both, and it is
309+
# deliberately UNCONDITIONAL: no `if:`, no paths filter, because the
310+
# staleness it catches arrives via an edit to the REGISTER, in a PR that
311+
# need not touch either prose file at all.
312+
- name: Governed-surface prose pin
313+
run: pnpm check:pm-governed-prose
314+
296315
# Release-rehearsal clone preflight self-test (#9555). A local
297316
# `pnpm run version` rehearsal — the prescribed verification route for
298317
# every release-machinery change — HANGS FOREVER in an agent container:

‎AGENTS.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ Other scripts: `objectui:bump` (pull only), `objectui:build`, `objectui:clean`.
181181
182182
> **`docs/adr/**` + `.claude/**`(含 agents/hooks/settings,不只 skills)+ `skills/**` + `AGENTS.md` + `CLAUDE.md`。混合 diff 照现行规则一条命中即整 PR 分叉** (2026-08-18)
183183
184-
**Which surfaces — and where that list actually lives.** The 2026-08-18 quotation above *is* the definition, and it is wider than ADRs and wider than skills: the two repo-root instruction files are on it, so **the file you are reading is itself a governed surface**, and so is `.claude/` entire — agents, hooks and settings, not only `.claude/skills/`. ⚠️ Even so, treat that quotation as a reading aid rather than the register: the set has grown three times in two days. The register is the `GOVERNED_SURFACES` table in `scripts/pm/check-governed-merges.mjs`, and adding a surface is an edit *there*, never here. Print today's set rather than trusting this paragraph: `node -e "import('./scripts/pm/check-governed-merges.mjs').then(m=>console.log(m.GOVERNED_SURFACES.map(s=>s.glob).join(' · ')))"`
184+
**Which surfaces — and where that list actually lives.** The 2026-08-18 quotation above *is* the definition, and it is wider than ADRs and wider than skills: the two repo-root instruction files are on it, so **the file you are reading is itself a governed surface**, and so is `.claude/` entire — agents, hooks and settings, not only `.claude/skills/`. ⚠️ Even so, treat that quotation as a reading aid rather than the register: the set has grown three times in two days. The register is the `GOVERNED_SURFACES` table in `scripts/pm/check-governed-merges.mjs`, and adding a surface is an edit *there*, never here. This directive no longer drifts from it in silence: `pnpm check:pm-governed-prose` reds per-PR when the surfaces named here are fewer than the register's — or more, the direction that manufactures enforcement nobody has. ⚠️ When it reds, name the surface **in this paragraph**; ⛔ never edit the quotation above to satisfy a gate — a verbatim ruling rewritten is a ruling rewritten. Print today's set rather than trusting this paragraph: `node -e "import('./scripts/pm/check-governed-merges.mjs').then(m=>console.log(m.GOVERNED_SURFACES.map(s=>s.glob).join(' · ')))"`
185185

186186
**Authoring stays open to every seat** — drafting the ADR, the skill or the instruction edit, pushing the branch, opening the PR, revising it under review. What is reserved is the **landing**: on any PR whose diff touches a governed surface, ⛔ never merge it, ⛔ never add it to the merge queue, ⛔ never call `enable_pr_auto_merge`, ⛔ never flip it out of draft to make any of those possible. Judge it on the PR's **file list**, not on its description, and a **mixed diff is not a proportion question** — one path hit is enough; if the rest needs to land, split the governed files into their own PR. **Reviewed + approved + fully green does not override this.** Under #13 an accepted ADR *is* the decision, so merging one is the act of adopting a governance position — the one class of change about which "CI is green" carries no information at all (a thorough, fully-green ADR draft has been closed by the maintainer on demand grounds no gate could evaluate). The other surfaces are reserved for a reason of the same shape: the agent instruction tree and these two root files are the operating protocol every *later* dispatch reads, and the published catalog lands in codebases this repo cannot see, so a bad merge propagates into work nobody has started yet — and green says nothing about whether it should propagate.
187187

‎package.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
"check:pm-dispatch-gates": "node scripts/pm/check-dispatch-gates.mjs",
5555
"check:pm-half-states": "node scripts/pm/check-half-states.mjs --self-test",
5656
"check:pm-governed-merges": "node scripts/pm/check-governed-merges.mjs --self-test",
57+
"check:pm-governed-prose": "node scripts/pm/check-governed-prose.mjs --self-test && node scripts/pm/check-governed-prose.mjs",
5758
"check:partof-closing-keyword": "node scripts/check-partof-closing-keyword.mjs --self-test",
5859
"check:single-claim-paths": "node scripts/check-single-claim-paths.mjs --self-test",
5960
"check:adr-anchors": "node scripts/check-adr-anchors.mjs --self-test && node scripts/check-adr-anchors.mjs",

0 commit comments

Comments
 (0)