diff --git a/.claude/skills/pm-dispatch/references/platform-readings.md b/.claude/skills/pm-dispatch/references/platform-readings.md index 5953c762e3..fff965f2a9 100644 --- a/.claude/skills/pm-dispatch/references/platform-readings.md +++ b/.claude/skills/pm-dispatch/references/platform-readings.md @@ -376,9 +376,11 @@ - 强制档不得因不可用而降档 —— 那正是降档保险丝要拒的替换。 - 本车道强制多是过宽的回忆:`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`。 +- ⭐ 本表的 `mustName` 不要求排他 ⇒ 第七个加注册行不会让本表变红。 +- ⇒ ⛔ 门绿不是本行已对的读数:计数行只能手跟改。 - `in_progress` 不是过;advisory 门禁红进 main 是共享损伤,照样止血立单。 - ⛔ 聚合命令同样不作判定:`check:type-check-debt` 可在包级 typecheck 绿时红。 - `check:i18n` 以 PREREQUISITE NOT MET(workspace CLI 未 build)退 3,不是漂移。 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 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) => 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],