From c8ec00b159201cd4bbd24ad2c46a837682aaa1f9 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 12 Sep 2026 05:55:00 +0000 Subject: [PATCH 1/3] fix(devx): pin `Governed Surface Queue Guard` as the seventh REQUIRED_CONTEXTS row The guard has been a live required context on `main` since 2026-08-27 and no registry row named it, so nothing made its check-run name load-bearing in a machine-checked way -- `--verify-required-set` read it as `direction B` every day since. Direction B is not #12427's direction A: that card fixed the guard running ADVISORY; this pins the NAME it is required under. Adding the row also makes the registry judge the workflow that publishes it, and that surfaced a live defect the row exists to surface: the guard's `pull_request:` trigger carries `branches: [main]`, the base-filter shape #16482 retired from `ci.yml` and `lint.yml`. A base-filtered trigger publishes no check run on a PR based on a feature branch -- an absence, not a skip -- so the one gate that governs the governed surface reports nothing there. That half is NOT fixed here; see the PR body. Carried with the row, because the registry derives both from it: - the readings ledger's `mustName` gains the seventh name (`--self-test` asserts it names every required context, so the count line alone is not what makes the seat's copy non-optional); - the self-test's workflow corpus is derived from the registry instead of a hand-listed pair, so a registered file can no longer go unread and report "never read" (#4690) through every fixture. Claude-Session: https://claude.ai/code/session_012GKcPZbMoGq7WPzKLfRBTU Co-authored-by: Claude --- .../references/platform-readings.md | 7 ++-- scripts/check-required-contexts.mjs | 36 ++++++++++++++++--- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/.claude/skills/pm-dispatch/references/platform-readings.md b/.claude/skills/pm-dispatch/references/platform-readings.md index 276786c4d0..1910db045c 100644 --- a/.claude/skills/pm-dispatch/references/platform-readings.md +++ b/.claude/skills/pm-dispatch/references/platform-readings.md @@ -376,9 +376,12 @@ - 强制档不得因不可用而降档 —— 那正是降档保险丝要拒的替换。 - 本车道强制多是过宽的回忆:`dispatch-gates.mjs --tier PATH` 逐路径现推,路径线是下限非放行。 - 该脚本只答自己那棵树:姊妹仓路径回 absent from this tree,姊妹仓的档位与条款②只能手推。 -- required checks 的名单是每仓事实,objectstack 六个: +- required checks 的名单是每仓事实,objectstack 七个: `TypeScript Type Check` · `Lint & Repo Gates` · `Test Core` · `Dogfood Regression Gate` · - `Build Core` · `Temporal Conformance (live PG + MySQL)`。 + `Build Core` · `Temporal Conformance (live PG + MySQL)` · `Governed Surface Queue Guard`。 +- 第七个 2026-08-27 入集(#12427),而注册表到 #15233 才钉住它。 +- ⭐ 本表的 `mustName` 不要求排他 ⇒ 第七个加注册行不会让本表变红。 +- ⇒ ⛔ 门绿不是本行已对的读数:计数行只能手跟改。 - `in_progress` 不是过;advisory 门禁红进 main 是共享损伤,照样止血立单。 - ⛔ 聚合命令同样不作判定:`check:type-check-debt` 可在包级 typecheck 绿时红。 - `check:i18n` 以 PREREQUISITE NOT MET(workspace CLI 未 build)退 3,不是漂移。 diff --git a/scripts/check-required-contexts.mjs b/scripts/check-required-contexts.mjs index 005a2d58bc..33a88e427d 100644 --- a/scripts/check-required-contexts.mjs +++ b/scripts/check-required-contexts.mjs @@ -423,6 +423,22 @@ export const REQUIRED_CONTEXTS = [ '2026-08-18 read, so it was applied somewhere between the two — no attestation names the day', carries: 'the live-server datetime conformance axis (#3912/#3942)', }, + { + workflow: 'governed-surface-guard.yml', + job: 'governed-surface-guard', + // The one gate that governs the governed surface, and until this row the + // one live required context nothing pinned — `--verify-required-set` read + // it as `direction B` (required, pinned by NO registry row) from the day + // the enrolment landed until this row (#15233). Direction B is not + // direction A: #12427 fixed the guard running ADVISORY (not required at + // all); this pins the NAME it is required under. Neither implies the + // other, and the sweep counts them separately. + context: 'Governed Surface Queue Guard', + authorized: + '#12427 maintainer confirmation, closed `completed` 2026-08-27T07:51Z on the verbatim 「Governed Surface Queue Guard 已添加」 (comment 5436049459); ' + + 'read back live in the ruleset sweep of 2026-09-10 that carries the director ruling enrolling this row (#15233)', + carries: 'the governed-surface refusal — the `merge_group` leg that refuses a governed diff carrying no ruled approval', + }, ]; /** @@ -548,6 +564,11 @@ export const INSTRUCTION_SURFACES = [ 'Dogfood Regression Gate', 'Build Core', 'Temporal Conformance (live PG + MySQL)', + // The seventh, enrolled 2026-08-27 (#12427) and pinned here by #15233. + // The ledger's own count line is hand-followed prose, so it is this + // array — asserted against REQUIRED_CONTEXTS.length in `--self-test` — + // that makes the seat's copy of the required set non-optional. + 'Governed Surface Queue Guard', ], }, { @@ -1703,10 +1724,17 @@ async function selfTest() { const root = scriptRepoRoot(); const { parse } = await requireDependency('yaml', () => import('yaml'), import.meta.url); - const sources = { - 'lint.yml': readFileSync(join(root, '.github', 'workflows', 'lint.yml'), 'utf8'), - 'ci.yml': readFileSync(join(root, '.github', 'workflows', 'ci.yml'), 'utf8'), - }; + // Every workflow the registry names, read from disk. A registered file left + // out here is not simply unexercised: `judge` reports it as never read + // (#4690), so EVERY fixture below inherits that finding and asserts against + // the wrong problem list. Derived from the registry so enrolling an eighth + // context cannot silently skip this step. + const sources = Object.fromEntries( + [...new Set(REQUIRED_CONTEXTS.map((e) => e.workflow))].map((file) => [ + file, + readFileSync(join(root, '.github', 'workflows', file), 'utf8'), + ]), + ); /** Judge the real workflows with one file's text replaced by `source`. */ const withSource = (file, source) => From 2e8006da0bc796daa909e297f4246f793ba50ce1 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 13 Sep 2026 12:37:16 +0000 Subject: [PATCH 2/3] fix(devx): pay the seventh-row readings increment under the standing exception The required-contexts increment landed platform-readings.md at 452 against a ceiling of 449, and the raise was never recorded. Re-measured on the merged head and taken under the standing one-file exception in pm-dispatch SKILL.md rather than a fresh decision card: ceiling 449 -> 451, with a matching `ruledRaises` record quoting that ruling. The increment is +2, not the +3 it was drafted at. Its third line carried the seventh context's entry date and the two card numbers behind it -- provenance narrative, which `check-skill-id-lint` refuses outright (2 issue-ID citations) and which the 2026-08-12 ruling keeps out of the scanned corpus. Its one operative residue, that the registry can lag the real required set, is already what the corollary line beside it says, so the line is deleted rather than bought. Claude-Session: https://claude.ai/code/session_01NFSv55L8jzmE9yvi9UwZug Co-authored-by: Claude --- .../references/platform-readings.md | 1 - scripts/pm/check-skill-line-ratchet.mjs | 47 ++++++++++++++++++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/.claude/skills/pm-dispatch/references/platform-readings.md b/.claude/skills/pm-dispatch/references/platform-readings.md index 994c9bac8e..fff965f2a9 100644 --- a/.claude/skills/pm-dispatch/references/platform-readings.md +++ b/.claude/skills/pm-dispatch/references/platform-readings.md @@ -379,7 +379,6 @@ - required checks 的名单是每仓事实,objectstack 七个: `TypeScript Type Check` · `Lint & Repo Gates` · `Test Core` · `Dogfood Regression Gate` · `Build Core` · `Temporal Conformance (live PG + MySQL)` · `Governed Surface Queue Guard`。 -- 第七个 2026-08-27 入集(#12427),而注册表到 #15233 才钉住它。 - ⭐ 本表的 `mustName` 不要求排他 ⇒ 第七个加注册行不会让本表变红。 - ⇒ ⛔ 门绿不是本行已对的读数:计数行只能手跟改。 - `in_progress` 不是过;advisory 门禁红进 main 是共享损伤,照样止血立单。 diff --git a/scripts/pm/check-skill-line-ratchet.mjs b/scripts/pm/check-skill-line-ratchet.mjs index a61ae58b64..e87301649c 100644 --- a/scripts/pm/check-skill-line-ratchet.mjs +++ b/scripts/pm/check-skill-line-ratchet.mjs @@ -846,7 +846,35 @@ export const CEILINGS = new Map([ // line-neutral folds among this file's adjacent rule pairs, and re-wrap funding // is refused per the 2026-08-17 rule in any case. Landed count, headroom 0, // same convention. - ['.claude/skills/pm-dispatch/references/platform-readings.md', 449], + // Raised 449 → 451 by the TWELFTH readings increment, again under the STANDING + // one-file exception quoted above rather than a fresh decision card, and again + // recorded as a `ruledRaises` record citing it. Spent at ONE line per + // deduplicated reading, each written in this file's voice: this table's own + // `mustName` does not require exclusivity, so pinning a seventh registry row + // cannot turn the table red (+1); and its corollary — a green gate is + // therefore NOT a reading that the count row beside it is current, which is + // exactly what leaves that row hand-maintained (+1) = +2 exactly. + // + // ONE correction is paid in place and buys nothing: the required-checks row + // and its wrapped continuation, which said six and named six. The new count + // and the seventh name land inside the two lines that row already occupied. + // + // ⚠️ ONE candidate was REFUSED rather than trimmed, and the refusal is this + // corpus's own standard doing the work. The seventh context's entry date and + // the card that pinned it were drafted as a third line; that is provenance + // narrative carrying a date and two issue numbers, which `check-skill-id-lint` + // refuses outright and which the 2026-08-12 ruling keeps out of the scanned + // corpus altogether. Its one operative residue — that the registry can lag the + // real required set — is already what the corollary line above says, so the + // line was DELETED rather than bought, and this increment is +2 and not the +3 + // it was drafted at. Candidates 3 / landed 2 readings / already present 0 / + // refused 1. + // + // Nothing else was paid in place: the fourth increment MEASURED zero + // line-neutral folds among this file's adjacent rule pairs, and re-wrap funding + // is refused per the 2026-08-17 rule in any case. Landed count, headroom 0, + // same convention. + ['.claude/skills/pm-dispatch/references/platform-readings.md', 451], // Per-operation REST/GraphQL/git channel mapping — which fleet operation has // a REST twin (each row executed in a real session, provenance date carried // per row), the handful that are GraphQL-only, and the queue-routing @@ -1450,6 +1478,23 @@ export const CROSS_FILE_MOVES = new Map([ date: '2026-09-12', delta: 24, }, + { + // The TWELFTH increment, under the same STANDING exception — the same + // words again, for the same reason: a record that quotes no ruling is + // RED and each record stands alone. The +2 is accounted for line by + // line beside this entry's ceiling above, and the exception's own + // conditions (per-item verification and the candidate / landed / + // already-present / refused counts) are carried by the raising PR's + // dedup table and the seat's ACCEPT. + ruling: + 'the standing one-file exception for' + + ' `.claude/skills/pm-dispatch/references/platform-readings.md` — pm-dispatch' + + ' SKILL.md, verbatim and untranslated: 「唯一例外:`platform-readings.md`' + + ' 增量抬上限到落地行数,免决策卡,记 `ruledRaises` 引常设裁决。条件:席位验收评论' + + '逐条核实、去重计数(候选/落地/已有/拒收)、一事一行、不计重排」', + date: '2026-09-13', + delta: 2, + }, ], sources: [ ['.claude/skills/pm-dispatch/references/lanes/cli.md', 35], From ce1f42e6d0e7e756152de80184573c8673a3a422 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 13 Sep 2026 13:23:30 +0000 Subject: [PATCH 3/3] fix(ci): drop the base filter wedging the newly-required governed-surface check Pinning `Governed Surface Queue Guard` as the seventh required context brought governed-surface-guard.yml under the required-contexts registry's assertion 7c, and it still carried `pull_request: branches: [main]` -- the same defect that was cleared from ci.yml and lint.yml before this workflow was registered. A base-filtered trigger does not start at all on a PR whose base is a feature branch, so the check publishes no check run there. That is an ABSENCE, which branch protection holds as permanently pending rather than as a skip, so a required context must report for ANY base. Gate was red in both limbs (6 self-test failures plus the live judgement); both are green with the filter gone. The `types:` list and the deliberate absence of a `paths:` filter are untouched. Claude-Session: https://claude.ai/code/session_01NFSv55L8jzmE9yvi9UwZug Co-authored-by: Claude --- .github/workflows/governed-surface-guard.yml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/governed-surface-guard.yml b/.github/workflows/governed-surface-guard.yml index d7089e4a41..723c581cf5 100644 --- a/.github/workflows/governed-surface-guard.yml +++ b/.github/workflows/governed-surface-guard.yml @@ -19,8 +19,17 @@ on: # regime's healthy end state, and a check that reddens on the healthy case is # the permanently-red gate the 2026-08-18 ruling retired. pull_request: - branches: - - main + # ⛔ NO `branches:` filter either — the same permanent-pending wedge as the + # `paths:` note below, reached through the other axis of this same trigger: + # `paths:` decides which CHANGES start the workflow, `branches:` decides + # which BASE branches do. A `branches: [main]` filter means a PR based on a + # feature branch does not start this workflow at all, so `Governed Surface + # Queue Guard` publishes NO check run there — an ABSENCE, which branch + # protection holds as permanently pending rather than as a skip. A required + # context must report for ANY base, and this one is required: enrolling it + # in `scripts/check-required-contexts.mjs` brought this file under that + # registry's assertion 7c, which is the same defect #16482 cleared from + # `ci.yml` and `lint.yml` before this workflow was registered. # Naming `types:` REPLACES GitHub's default set rather than extending it, # so all three defaults are restated here (#8304). `ready_for_review` is # the addition and it is the point: flipping a governed draft to ready is