Repository navigation
[finding] AGENTS.md states the merge queue's required set as six contexts and calls the rest advisory — it is seven, and no gate reds on the stale sentence #17798
Description
Filed unassigned and ungraded by the os-dev seat implementing #15233 (branch claude/issue-15233-required-contexts-seventh-row). domain:*, priority: and type deliberately unset — triage's call. Out of scope for #15233 and deliberately not fixed there: that card's dispatch puts AGENTS.md explicitly off-limits.
What AGENTS.md says
AGENTS.md, the merge-queue paragraph (lines 505-510):
And the queue enforces only the required set — six contexts block:
Lint & Repo Gates(allcheck:*gates),TypeScript Type Check,Test Core,Dogfood Regression Gate,Build CoreandTemporal Conformance (live PG + MySQL). A check outside those six is advisory and rides through … treat those six names as contract.
What the live ruleset says
NODE_OPTIONS=--use-env-proxy node scripts/check-required-contexts.mjs --verify-required-set, run 2026-09-12 against the live ruleset (main, id 12119582, active), exit 0:
required-set sweep: 7 live required context(s) on main, 0 registered-but-not-required, 0 required-but-unpinned.
required: TypeScript Type Check
required: Test Core
required: Dogfood Regression Gate
required: Build Core
required: Temporal Conformance (live PG + MySQL)
required: Lint & Repo Gates
required: Governed Surface Queue Guard
Seven, not six. The seventh is Governed Surface Queue Guard, enrolled in Settings on 2026-08-27 per #12427 (closed completed 2026-08-27T07:51Z on the maintainer's confirmation).
Why this is worth a card, not a nit
The false half is not the number, it is the sentence that follows it: "A check outside those six is advisory and rides through." A seat that reads this and sees Governed Surface Queue Guard red or pending concludes it is advisory and arms anyway — and that is verbatim the #12427 incident shape, a zero-review governed PR riding through because the guard's refusal was read as advisory. The paragraph is operative prose a review seat acts on, not description.
There is direct precedent that this exact misclassification is a ruled defect. The #9677 ruling (2026-08-18) widened this same surface from two names to six for the same reason, recorded in scripts/check-required-contexts.mjs:
the sentence had named two and called the other four advisory-and-rides-through, which is the misclassification that puts a PR into the queue to be ejected.
⇒ The set has since grown by one and the sentence has not followed.
⚠️ No gate reds on this — the same trap #15233 is itself an instance of
AGENTS.md is an INSTRUCTION_SURFACES entry carrying mustName for the six names. mustName does not require exclusivity, so:
- adding the seventh
REQUIRED_CONTEXTSrow (what [finding]Governed Surface Queue Guardis required onmainbut pinned by no REQUIRED_CONTEXTS row — renaming its job detaches the governed-surface gate silently #15233 lands) does not red this surface; - the six names it does list are all still real, so the scan stays green;
- nothing anywhere counts the surface's names against the registry's length.
⇒ ⛔ "Every gate is green" is not a reading that this paragraph is right. #15233's triage (comment 5586769327) flagged exactly this for the pm-dispatch readings ledger and had it hand-followed in that PR. This is the second surface with the same defect, and it was not in that card's scope.
Suggested remedy (not a ruling — the lane's to make)
Either hand-follow the sentence six → seven the way #15233 hand-followed the readings ledger, or decide that mustName growing is what should have reddened here and make exclusivity checkable, so the next enrolment cannot leave this sentence behind a third time.
Dedup
Scanned all 137 open issues carrying tooling or domain:devx (73 + 125, deduped; domain:devx paged to exhaustion — page 3 empty) for agents.md, required set, those six, six contexts, advisory and rides, queue enforces only. Nearest neighbours are #17673 (Console Pin Gate absent on packages/** changes — a different AGENTS.md rule and a different instrument) and #16696 (docs-drift row precision). No open twin. Note: MCP search_issues was rate-limited for this session and the REST /search/* path answers 403 for repository-bound sessions, so this is a repo-scoped list plus local grep, whose blind spot is minute-fresh cards.
Generated by Claude Code
Activity
claude commentedon Sep 13, 2026
pm:queue→pm:blocked(this stroke),Blocked-by: #15233written as the first body line — skills seat, sessionsession_01DAcomhvR9kKizeYgg89Vo8(GitHubos-project-manager), 2026-09-13T07:15Z.Why this card cannot be built on today's tree. Its acceptance (triage 5651027386) makes item 2 the substance: 「让
mustName的排他性可检 —— 即某处必须把该面列出的名字数对上注册表的长度,使得下一次入列若不更新这句话就变红」, with item 1 hand-followingAGENTS.mdto the live set (seven, namingGoverned Surface Queue Guard). Onorigin/main84e6b05the registryREQUIRED_CONTEXTSinscripts/check-required-contexts.mjsstill has SIX rows: the seventh row is devx PR #17803 (Closes #15233, draft, awaiting a human merge — it is a governed diff because it also touches.claude/skills/pm-dispatch/references/platform-readings.md). An exclusivity check that compares AGENTS.md's seven names against a six-row registry reds by construction, and acceptance 4 forbids this card from touching the registry (「⛔ 不动REQUIRED_CONTEXTS注册表本身(那是 #15233 的面)」). Same file, too: PR #17803 editsscripts/check-required-contexts.mjs, so this card is same-file serial behind it either way.Unlock. #15233 closes when PR #17803 merges; the unlock scan puts this card back to
pm:queue, and the dispatch then re-verifies on the merged ref that the registry has seven rows and thatAGENTS.md:505–:510 still says six. Known pit for that dispatch, recorded now: PR #17803's body reportscheck:required-contexts --self-testRED on its branch for a pre-existingbranches: [main]filter ongoverned-surface-guard.yml— if that residual is still red after #17803 lands, the exclusivity self-test this card adds must be measured against that known red, not blamed on it.State read back:
priority:p2·pm:blocked·domain:skills· Bug · no assignee.Generated by Claude Code
claude commentedon Sep 15, 2026
pm:blocked→pm:queue— unlock scan at seating, skills seat, sessionsession_01HZfg2AwVX191qCizp88gQr, 2026-09-15T02:07Z.Blocked-by: #15233is satisfied: #15233 is CLOSED completed (PR #17803 merged 2026-09-13T14:26Z). Re-verified onorigin/mainb3b43b6(fetched 2026-09-15T01:51Z):scripts/check-required-contexts.mjsREQUIRED_CONTEXTScarries SEVEN rows, the seventhGoverned Surface Queue Guardat :436;AGENTS.md:505 still reads 「six contexts block」 — the premise of items 1 and 2 stands. The body's first lineBlocked-by: #15233is removed in this act; no new blocker derived (the registry row the exclusivity check compares against is onmain). Known pit carried from the hold note 5651882793: PR #17803 reportedcheck:required-contexts --self-testred on a pre-existingbranches: [main]filter — the dispatch measures the exclusivity self-test against that known red rather than blaming it. Labels read back after the write.Generated by Claude Code
claude commentedon Sep 15, 2026
Claim: PM loop round 1
Session:
session_01HZfg2AwVX191qCizp88gQr(skills seat; claimed at 2026-09-15T02:13Z)Branch:
claude/issue-17798-required-set-seven-exclusivityWorktree:
objectstack-issue-17798Domain:
domain:skillsFile surface:
AGENTS.md(the merge-queue paragraph :505–:510 only — a REGION claim; PR #18227 holds :1026+, the second to land mergesorigin/mainfirst) +scripts/check-required-contexts.mjs(INSTRUCTION_SURFACESand--self-test; ⛔ not theREQUIRED_CONTEXTSregistry) (stop on breach; explain in the report)Container & model:
M,mode:subagent,model: default judgment tier (opus) — dispatch-gates --tier on b3b43b6: no path-derived mandate for AGENTS.md + scripts/; the seat reviews at the contract-review tierClause-②: no
Thread-read: 5673580944
Serial constraints cleared:
PR #18227 (ready, devx) touches AGENTS.md at :1026+ — a disjoint region, declared above; no open PR touches scripts/check-required-contexts.mjs (8 open PRs' file lists read at 2026-09-15T02:09Z); #15233 / PR #17803 landed, so the seventh registry row is on main; verify lock free; H17 index ∩ this face: none; batch 3, devs in flight 1 before this claimGenerated by Claude Code
claude commentedon Sep 15, 2026
os-dev-report
{
"issue": 17798,
"status": "done",
"branch": "claude/issue-17798-required-set-seven-exclusivity",
"pr": "#18244",
"premise_still_valid": true,
"head_sha": "78959ab",
"files_changed": [
"AGENTS.md",
"scripts/check-required-contexts.mjs"
],
"summary": "Item 1: AGENTS.md :505-:510 hand-followed six to seven, inserting
Governed Surface Queue Guardand moving all three count words, equal-line at the 1075 ceiling. Item 2: INSTRUCTION_SURFACES gains a declaredstatesTheSetflag — an entry that declares it must name REQUIRED_CONTEXTS exactly (membership and count), so the next enrolment reds on the PR that adds the registry row; the declaration cannot be dropped to buy the exemption (a full list without it reds), and ablating every declaration reds rather than ticking. review-checklist.md is classified the other way and keeps its two-name floor: it names the two required jobs a seat confirms by hand, not the set, so the set growing must not red it. Acceptance 4 honoured: the REQUIRED_CONTEXTS block is byte-identical to origin/main (md5 fae2c1f44520bde2f96f6aa7a988c35e on both b3b43b6 and HEAD).","self_test_baseline": "B2 MEASURED AND FALSIFIED. On origin/main b3b43b6, in a clean worktree, BEFORE any edit:
node scripts/check-required-contexts.mjs --self-testexit 0 (159 assertions) and the pin exit 0 (7 contexts across 3 workflows). The known pit from hold note 5651882793 — PR #17803 reporting the self-test red on a pre-existingbranches: [main]filter on governed-surface-guard.yml — is NOT red on main today. All work below is measured against a green baseline, not against a standing red.","tests": "AFTER (78959ab): check-required-contexts --self-test exit 0, 169 assertions (159 + 10 new); the pin exit 0. ABLATIONS, each from the COMMITTED implementation, each mutation proved on disk before reading the result, each restored and proved byte-identical by git hash-object vs the HEAD blob with git diff HEAD empty: (A) drop the seventh name from the AGENTS.md entry mustName — grep 2 to 1, numstat 0/1 — RED exit 1, diagnostic "declares statesTheSet: true, so its mustName must be the required set EXACTLY — it lists 6 name(s) against a registry of 7, missing (the seventh literal)"; self-test also exit 1. (B) rot only the NUMERAL back (seven contexts block to six) with all seven literals still listed — numstat 1/1 — GREEN exit 0, reported as measured and not as expected: the scan pins literals, never the word introducing them; recorded as a residual in the script header. (B2) delete the seventh literal from the paragraph — grep 1 to 0, numstat 1/1 — RED exit 1, "AGENTS.md no longer names the required context". (floor control) battery floor 41 to 42 — RED exit 1 naming the exact count, "registered 41 case(s), below its pinned floor of 42", so the floor binds at headroom 0 and 41 is measured, not a number below the real one. No ablation left anything behind: every restore leg verified by blob hash. No dist/build step exists for this path (the gate reads its own source; no package resolves it through dist), so the rebuild leg is inapplicable and the on-disk mutation proof stands in its place.",
"gates": {
"derived": "37 command(s) from
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackwith NO paths, change set derived by the tool itself (2 committed paths, 0 working-tree, 0 untracked) at 78959ab","ran": "37 of 37, each exit captured by redirecting the command output to a file and reading the status variable immediately, before any pipe",
"green": "37 of 37 exit 0",
"not_measured": "none",
"unrun": "none",
"reconciliation": "node scripts/pm/dispatch-gates.mjs --ran RECORD_FILE --repo objectstack-ai/objectstack gives exit 0,
Run reconciliation — 37 derived, 37 run, 0 NOT-MEASURED, 0 UNRUNand37 derived famil(ies) accounted for — 37 run, 0 NOT-MEASURED (a DERIVED zero — all 37 recorded an exit code and none of them is 3)","caveat": "ONE of the 37 exit codes is read from the gate printed verdict line rather than captured:
pnpm check:pm-dispatch-gates(scripts/pm/check-dispatch-gates.mjs) runs past this container foreground ceiling — cap-killed twice at 400s and 560s — so it was finished on a detached run whose code this shell could not wait on. Its own final line isdispatch-gates self-test: 1723 cases pass.with no failure lines in 1724 lines of output. The process was confirmed gone before this report; nothing I started outlives this round.","beyond_derivation": "This card edits a gate script, so check:required-contexts and its --self-test are owed beyond the derivation — both green above.
git grepover test-shaped paths finds no .test. naming check-required-contexts.mjs, so that script has no separate suite to owe.","lint": "Narrowed with the three readings that make a narrowing a measurement: (1) covered population read from eslint own config —
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), and eslint.config.mjs declares no markdown population at all, so AGENTS.md is outside the lint verdict in either direction; (2) file count read from --format json: 1 file, 0 errors, 0 warnings, exit 0; (3) invariance: this repo runs one eslint.config.mjs which never enables type-aware linting for ANY file (no parserOptions.project, no typed rules — eslint.config.mjs :326-:329, with its own positive control recorded there), so this diff cannot move any untouched file verdict. The repo-widepnpm lintscan is CI run.","changeset": "skip-changeset, measured not asserted: both paths lie outside every package directory, and of the 70 non-private packages none has a files[] entry escaping its own directory (0 entries starting with ../ or /). Nothing published moves. Label POSTed by the additive endpoint and read back."
},
"line_budget": {
"AGENTS.md": {
"before": 1075,
"after": 1075,
"ceiling": 1075,
"widest_table_row_pin": "768, untouched — this edit adds no table row"
},
"scripts/check-required-contexts.mjs": "not under any ratchet (the pm line ratchet covers .md instruction surfaces only)"
},
"deviations": [
"The triage grading comment 5651027386, which the dispatch says to read verbatim on the card, answers HTTP 404 and is not on #17798 (the card carries exactly 3 comments: 5651882793, 5673580944, 5673630071). Its acceptance items 1, 2 and 4 were read from the verbatim quotations inside hold note 5651882793 and from this dispatch own text. Recorded as NOT MEASURED against the primary source, never as no-flags.",
"The PR body records
pnpm check:pm-dispatch-gatesas NOT MEASURED, because it was still cap-killed at the moment the body was written. It finished GREEN afterwards (see gates.caveat). The body was NOT patched: the write budget is four writes and a PATCH is outside it. The correction is here and the direction of the error is conservative — the body under-claims coverage, it does not claim a green it did not have.","One self-test battery floor was RAISED (instruction surfaces #9491: 31 to 41). The roster comment calls the counts a floor that adding cases must not red, so raising is not required; it was raised deliberately so the ten cases this card adds cannot stop registering silently, and the raise is proved binding by the floor control above.",
"Process lesson worth carrying, not a rule change: an ablation trap spelled a trap on EXIT that runs
git checkout HEAD -- PATHfired on a file whose fix was still UNCOMMITTED and wiped the whole implementation with exit 0 and no output — the failure shape the standing rulecommit the fix before any ablationexists for. Detected by the next derivation reporting a 1-path change set instead of 2; the patch scripts were re-applied and everything after that point ran from a committed tree."],
"mcp_calls": "0 — no MCP GitHub tool was called, read or write. All GitHub traffic went through the REST proxy with curl and GITHUB_TOKEN.",
"api_writes": "3 REST writes (plus 2 git pushes): POST /repos/objectstack-ai/objectstack/pulls (draft #18244); POST /repos//issues/18244/labels (skip-changeset, read back — readback [size/m, skip-changeset], union(read,target) present, nothing stripped; size/m is the size-labeler and not mine to correct); POST /repos//issues/17798/comments (this report). No PATCH of any body. PR body read back in full after creation: byte-identical to what was sent, exactly one footer, session-URL form.",
"open_questions": [],
"out_of_scope_findings": [
"to file (class b — contradicts a declared contract once this lands; dedupe words: platform-readings, mustName exclusivity, count line hand-followed, statesTheSet, required contexts roster): .claude/skills/pm-dispatch/references/platform-readings.md :385-:386 becomes FALSE the moment this PR lands. Those two lines state that this table mustName does not require exclusivity, so a seventh registry row cannot red it, and conclude that a green gate is not a reading that the count line is right — the count line can only be hand-followed. After this PR that entry declares statesTheSet: true and the registry growing DOES red it. Not fixed in place: the file is outside this card declared REGION claim, and the gate own header records .claude/skills/pm-dispatch/** as a surface a dev seat may not edit (the reason the checklist half of #9325 was its own card). Successor named: the domain:skills seat, in its own lane.",
"noted, not filed: the count WORD in a set-stating surface stays hand-followed — ablation leg B above is green. Recorded as a residual in the script header beside the paraphrase-drift and shortening-rename residuals, and bounded rather than covered: the census forces every enrolled literal INTO the prose, so a stale numeral sits next to a complete list, not a short one. Closing it needs the arbitrary-literal recognition the header already measured as out of reach. Successor: none — this is the recorded boundary of the mechanism, not a defect anyone else will hit in a file.",
"noted, not filed: comment 5651027386 is 404 (see deviations). Successor: none — nothing in the tree depends on it; the acceptance it carried survives verbatim in 5651882793."
]
}
Generated by Claude Code
claude commentedon Sep 15, 2026
ACCEPT — skills seat, session
session_01HZfg2AwVX191qCizp88gQr, 2026-09-15T03:10Z. Report 5674064155 read in full; PR #18244 (head78959ab) reviewed in-seat at the contract-review tier:## Contract reviewPASS, record 5674090825 on the PR; 速读终稿 posted there. Checklist: draft, basemain, first lineFixes #17798, no other closing keyword beside a card number; changed files = the claim's file surface exactly (AGENTS.md:505–:510 REGION +scripts/check-required-contexts.mjs);REQUIRED_CONTEXTSbyte-identical to main (acceptance 4);skip-changesetread back withsize/m;mcp_calls0, three REST writes + two pushes inside theWrites:budget; gates 37 / 37 / 0 / 0. Seat-measured on the head: ratchet ✓ 1075/1075, governed-prose ✓,--pair 18244exit 0,check-governed-merges --test→ governed (AGENTS.md); the gate's own reading on the head is on the record (a fresh worktree lacks the gate'syamlimport, so the seat linked a sibling install — see the record's ① line). Acceptance: item 1 (six → seven, namingGoverned Surface Queue Guard) landed equal-line; item 2 (exclusivity checkable — a set-stating surface reds when the registry grows without it) landed as the declaredstatesTheSetcensus with its anti-exemption branch; item 4 honoured. Deviations (4) accepted on the record; the triage comment 5651027386 is 404 (the suspended triage account's) — its acceptance survives verbatim in 5651882793. Out-of-scope class (b): platform-readings :385–:386 (「本表的 mustName 不要求排他 ⇒ 第七个加注册行不会让本表变红」 / 「计数行只能手跟改」) become false the moment this lands — filed by the seat as its own card in this lane,pm:blockedon this card until the PR merges. Landing: governed rules layer ⇒needs-user-decisionon PR #18244, reviews requested from the two authorized approvers, then ruling C by this seat after an authorized approval; the card stayspm:dispatched+ assigned until MERGED.Generated by Claude Code
claude commentedon Sep 15, 2026
Landed — skills seat, session
session_01HZfg2AwVX191qCizp88gQr, 2026-09-15T06:40Z. PR #18244 (head78959ab) merged by the queue as1297178e968bbfa0bed51de24ed3d596d63dd0dd(single-parent squash pergit rev-list --parents) at 2026-09-15T06:32Z — themerged_atinstant, carried identically by themergedandremoved_from_merge_queuetimeline events (the squash commit's own date, 06:06Z, is the ENQUEUE instant, not the landing — #18274). Two readings at 2026-09-15T06:37Z:git log origin/maincarries(#18244), and the queue'sremoved_from_merge_queueevent is on the timeline (the queue refs are not served through this proxy, so the event is the second reading). Ruling-C landing: os-zhuang's APPROVED review 5206125508 on that head; review of record 5674090825, ACCEPT 5674091300, ruling-C provenance 5675577896; the approver flipped it ready and enqueued it at 2026-09-15T06:06Z. Now onorigin/main:scripts/check-required-contexts.mjsstates the merge queue's required set as seven contexts and treats every set-stating surface as a census (statesTheSet: true), with AGENTS.md :505–:510 following. Residue (pm:dispatched, assignee) stripped throughlabel-write.mjsand read back; #18248 (Blocked-by: #17798) is unblocked →pm:queue.Generated by Claude Code
fix(devx): pin `Governed Surface Queue Guard` as the seventh REQUIRED…
fix(agents,gates): the merge queue blocks on seven contexts, and a se…