fix(agents,gates): the merge queue blocks on seven contexts, and a set-stating surface is now a census - #18244
Conversation
…rface that states the set is now a census AGENTS.md's merge-queue paragraph named six required contexts and called everything else advisory-and-rides-through. The live ruleset has seven -- `Governed Surface Queue Guard`, enrolled 2026-08-27 -- so the sentence a review seat acts on classified the one gate that refuses a zero-review governed PR as advisory. That is verbatim the incident shape the guard exists to prevent. Nothing reddened on it, and that is the half worth fixing. `mustName` is a FLOOR: it reds when a listed literal goes stale and is blind to one going MISSING, so growing the registry left every surface's list legal and every gate green. The same misclassification has now landed twice (2->6, then 6->7). - AGENTS.md :505-:510: six -> seven, the seventh name inserted, equal-line at the 1075 ceiling; each literal kept whole on one line, since the scan matches them contiguously. - INSTRUCTION_SURFACES gains `statesTheSet`. An entry that declares it must name the registry EXACTLY -- count and membership -- so the next enrolment reds on the PR that adds the row. `review-checklist.md` is classified the other way and keeps its two-name floor: it names the two jobs a seat confirms by hand, not the set. - The declaration cannot be dropped to buy the exemption (a full list with no `statesTheSet` reds), and ablating every declaration reds rather than ticking. - Ten self-test cases, battery floor 31 -> 41: the 6-of-7 omission, its restore-leg ablation, the eighth-row enrolment end to end and its hand-off from the census red to the naming floor, the padded-duplicate count, the undeclared full list, and the no-declaration floor. The `REQUIRED_CONTEXTS` registry itself is untouched. Claude-Session: https://claude.ai/code/session_01HZfg2AwVX191qCizp88gQr Co-authored-by: Claude <[email protected]>
Ablating AGENTS.md's numeral back to "six" while all seven literals stay listed runs GREEN: this scan pins literals, never the word that introduces them. The census bounds it rather than covering it -- every enrolled literal is forced into the prose, so a stale numeral sits next to a complete list -- and pinning the numeral needs the arbitrary-literal recognition the header already measured as out of reach. Claude-Session: https://claude.ai/code/session_01HZfg2AwVX191qCizp88gQr Co-authored-by: Claude <[email protected]>
Contract reviewServed-tier: Reviewing seat: ① Derived judgments
② Semver levelNot applicable — nothing published moves; ③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
维护者速读(终稿)改了什么:两处。一、 为什么改:那句话是审核席翻 ready / 挂 auto-merge / 入队前照着做的操作指令,它把治理面守卫说成 advisory,而那个守卫的职责恰恰是拒掉零审查的治理 PR。上一次入列(#15233 加第七行)时门禁全绿、没有任何东西提示句子已过期——同一漏洞发生了两次。这次不只手跟数字,而是让「谁陈述了整个集合」可查:下一次(第八个)入列时,加注册行的那个 PR 自己会红。 风险与代价(含回滚):风险低。新规则只对显式声明 席位意见:建议批准。本席核过:AGENTS.md hunk 恰为认领区域;棘轮 1075/1075、governed-prose 绿;排他/反豁免/零声明三个分支读法与报告一致;dev 在改动前先证伪了「主干自测本就红」的假设(基线绿),四组消融方向与报告一致。本席自跑该门禁的读数见 PR 上的复核记录;CI 你要做的(一个动作):approve 本 PR。approve 后本席翻 ready + 入队,你不必再点合并。 Generated by Claude Code |
|
Ruling-C landing provenance — skills seat, session Generated by Claude Code |
Fixes #17798
AGENTS.md's merge-queue paragraph named SIX required contexts and called everything else "advisory and rides through". The live ruleset has SEVEN —Governed Surface Queue Guard, enrolled 2026-08-27 (#12427) and pinned inREQUIRED_CONTEXTSby #15233. The sentence a review seat acts on therefore classified the one gate that refuses a zero-review governed PR as advisory, which is verbatim the incident shape that guard exists to prevent.Nothing reddened on it, and that is the half worth fixing.
mustNameis a FLOOR: it reds when a listed literal goes stale and is blind to one going MISSING. So the registry grew, every surface's list stayed legal, every gate stayed green, and the sentence stayed behind. The same misclassification has now landed twice — 2 to 6 by the #9677 ruling, 6 to 7 here.维护者速读(草稿)
改了什么。 两处。一、
AGENTS.md的合并队列段落从「六个必需上下文」改成七个,把第七个Governed Surface Queue Guard写进名单(等行数改写,1075 行没动)。二、scripts/check-required-contexts.mjs的INSTRUCTION_SURFACES增加一个statesTheSet声明:声明了它的文件,其名单必须与注册表逐个且等长地对上。注册表本身(REQUIRED_CONTEXTS)一行未动,那是 #15233 的面。为什么改。 这句话不是描述,是审核席翻 ready / 挂 auto-merge / 入队前照着做的操作指令。它把治理面守卫说成 advisory,而那个守卫的职责恰恰是拒掉零审查的治理 PR —— #12427 的事故形态。更关键的是:上一次入列(#15233 加第七行)时,全部门禁是绿的,没有任何东西提示这句话已经过期。同一个漏洞已经发生两次,所以这次不只是手跟一遍数字,而是把「谁陈述了整个集合」变成机器可查的:下一次(第八个)入列时,加注册行的那个 PR 自己会变红。
风险与代价(含回滚)。 风险低。新规则只对显式声明
statesTheSet: true的条目生效,今天是两个文件(AGENTS.md与 pm-dispatch 的platform-readings.md);review-checklist.md被明确归类为不陈述集合(它点名的是审核席亲手确认的两个 job,不是集合),保留它原有的两名下限,集合变大不会误伤它。声明也不能被悄悄摘掉换取豁免:名单已覆盖整个集合却没声明的条目同样变红。代价:每次入列多一处必须同 PR 跟进的数组。回滚 =git revert,两个文件都是纯文本,没有生成物、没有发布面、没有数据迁移。席位意见。
你要做的。 确认一件事:第七个上下文
Governed Surface Queue Guard今天确实在 Settings 的必需集合里(卡面 2026-09-12 的实测读数是七个,本 PR 不改 Settings)。其余不需要你操作。本 PR 触及受管面AGENTS.md,按 Prime Directive #14 走人工合并或已批准的队列路径。What changed
1.
AGENTS.md:505-:510 — six to seven. The seventh name inserted, "six" to "seven" in all three places, equal-line at the 1075 ceiling (before 1075 / after 1075 / ceiling 1075). Each context literal is kept whole on one line: the scan matches them contiguously, and a wrap that splitTypeScript Type Checkacross a line break made the surface red. That is a real trap for the next hand-follow, so it is recorded here rather than only avoided.2.
INSTRUCTION_SURFACESgainsstatesTheSet. An entry that declares it must name the registry EXACTLY — membership and count:review-checklist.mdis classified the other way and keeps its two-name floor: it names the two required jobs a seat confirms by hand — its own next line sends the seat totrue-green.mdfor the rest — so it never claimed to enumerate the set, and the set growing must not red it.3. Ten self-test cases, battery floor 31 to 41. The 6-of-7 omission and its restore-leg ablation; the eighth-row enrolment end to end, plus the hand-off where following the ARRAYS clears the census red and leaves the naming floor demanding the PROSE; the padded duplicate; the undeclared full list; the no-declaration floor; and the two classification pins (which surfaces state the set, by NAME never by count; and the checklist's partial list staying legal).
Evidence
Baseline first, on
origin/mainb3b43b6in a clean worktree, BEFORE any edit — the known pit from hold note 5651882793 (PR #17803 reported--self-testred on a pre-existingbranches: [main]filter ongoverned-surface-guard.yml):The known pit is NOT red on
maintoday. The residual named in the hold note is gone; the work below is measured against a green baseline, not against a standing red.After (
78959ab):--self-testexit 0, 169 assertions; the pin exit 0.Reverse verification, both legs from the committed implementation, each with its on-disk mutation proved and each restored byte-identical (
git hash-objectvs the HEAD blob,git diff HEADempty):'Governed Surface Queue Guard'from theAGENTS.mdentry'smustName(grep 2 to 1;git diff --numstat0/1)seven contexts blocktosix contexts blockinAGENTS.md, all seven literals still listed (numstat 1/1)and `Governed Surface Queue Guard`from the paragraph (grep 1 to 0; numstat 1/1)Leg B is the honest finding of this PR: the census forces every enrolled literal INTO the prose, so a stale numeral now sits next to a complete list rather than a short one. Bounded, not covered; pinning the numeral needs the arbitrary-literal recognition the script header already measured as out of reach.
Derived gate union, run after the final commit, on
78959ab(git rev-parse --short HEAD), each exit captured by redirect before any pipe:36 of 37 exit 0. The one not measured:
pnpm check:pm-dispatch-gates(scripts/pm/check-dispatch-gates.mjs) runs past this session's foreground ceiling — it was still printing passing cases at 560s. NOT MEASURED, reason: runtime exceeds the foreground cap; CI owns it. Its subject matter — theROOT_FILE_WATCH_HINTSdeclaration this file carries — is separately green underpnpm check:watch-hint-literal(exit 0) and under this script's ownthe dispatch-gates declaration (#9979)battery (6 assertions).--ranreconciliation is reported in the dev report; the beyond-derivation families this card owes because it edits a gate script —check:required-contextsand its--self-test— are the two green readings above.git grepfinds no*.test.*namingcheck-required-contexts.mjs, so that script has no separate test suite to owe.Lint, narrowed with the three readings that make a narrowing a measurement:
npx eslint --print-config scripts/check-required-contexts.mjsreports exactly 2 rules enabled for this path (no-restricted-imports,comment-swallow/no-code-inside-block-comment);eslint.config.mjsdeclares no markdown population at all, soAGENTS.mdis outside the lint verdict in either direction;--format json: 1 file, 0 errors, 0 warnings;eslint.config.mjswhich never enables type-aware linting for any file (noparserOptions.project, no typed rules —eslint.config.mjs:326-:329, with its own positive-control measurement recorded there), so this diff cannot move any untouched file's verdict.The repo-wide
pnpm lintscan is CI's run.skip-changeset, measured rather than asserted: both paths lie outside every package directory, and of the 70 published packages none has afiles[]entry escaping its own directory (0 entries starting with../or/). Nothing published moves.Acceptance notes
Out of scope, noted, not filed:
.claude/skills/pm-dispatch/references/platform-readings.md:385-:386 becomes FALSE when this lands. It reads 「⭐ 本表的mustName不要求排他 ⇒ 第七个加注册行不会让本表变红」 and 「⇒ ⛔ 门绿不是本行已对的读数:计数行只能手跟改」. After this PR that entry declaresstatesTheSet: trueand the registry growing DOES red it, so a seat reading those two lines would keep hand-following a line the gate now holds. Not fixed here: the file is outside this card's declared REGION claim (AGENTS.md:505-:510 plus this script), and the script's own header records.claude/skills/pm-dispatch/**as a surface a dev seat may not edit — the reason the checklist half of TheESLintrequired context carries ~54check:*gates, so every one of their failures mis-routes its own diagnosis — and the rename needs a Settings change no agent seat can make #9325 was its own card. Successor: thedomain:skillsseat, in its own lane. Dedupe words:platform-readings,mustName 不要求排他,计数行只能手跟改,statesTheSet,required contexts 的名单.Nothing else was touched.
REQUIRED_CONTEXTSis byte-identical toorigin/main.Generated by Claude Code