Skip to content

docs(os-dev, pm-dispatch): a breaking PR runs the full dogfood battery on its final head; the review checklist reads the field before arming - #24917

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-24890-breaking-dogfood-battery
Oct 21, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-24890-breaking-dogfood-battery

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #24890

Clause-②: no

Summary

A dispatched breaking change — a ! in the PR title, or a (narrowing) arm on the Clause-②: line — now owes the full dogfood battery on its final head, records the result in a new dogfood_battery report field, and the review checklist reads that field before ready / auto-merge / queue. The rule is stated once, in .claude/agents/os-dev.md, by extending the clause that already said 「dogfood 只在终 head 跑一次」; the checklist line reads it. No CI, workflow, gate or script changes; two governed .claude/** files, both at their line ceilings before and after (404/404, 77/77).

Where the rule landed, and why there (H2, H5)

  • .claude/agents/os-dev.md L279 read 「PR 开出后合 main 只因冲突、main 致 CI 红、出队,后只跑 §10 复检;dogfood 只在终 head 跑一次。」 Commit b8762c089 introduced that clause together with AGENTS.md §10's "dogfood once, on the final head"; the parent tree's only other "dogfood" in AGENTS.md is §7's full-battery enumeration ("main's hourly and push runs carry the full battery — dogfood, e2e, …"). So the word there names the Dogfood Regression Gate suite, with no trigger and no command. The clause is split off L279 and extended in place into three rule lines (trigger · command · red disposition), so the rule stays stated once. AGENTS.md §10 itself is Tier H and outside the file surface; it keeps its trigger-less sentence, and the role file now carries the trigger.
  • The report field dogfood_battery is added to the JSON template in the same file (SKILL.md 〈报告契约〉: 「终报 JSON 形状住 .claude/agents/os-dev.md,⛔ 不抄第二份」). The report-marker readers in scripts/pm/check-half-states.mjs read only the marker line and open_questions, so an added key is additive.
  • The reader is references/review-checklist.md 〈测试与门禁证据〉, whose last block is already the seat's pre-arm read (「翻 ready、挂 auto-merge 或入队前…」, 「每个门禁读数先钉到 PR 当前 head」, 「dev 本地并集钉 head」). The new line sits at its end. landing-operations.md 〈入队与落地〉 decides the 条款② gate and the queue mechanics, not the dev-evidence read, and its ratchet is 101/101 — no line goes there, no second home. execution-duties.md and dispatch-runbook.md are untouched: the standing clause is unconditional, and os-dev.md 〈标准条款住在这里〉 says unconditional clauses live in the role file, not in the dispatch brief.

The trigger spelling (H1 — a correction to the card)

The card writes the declaration as Clause-②: yes (narrowing); the dispatch brief's hypothesis names Clause-②: no (narrowing). Both are legal spellings, and neither is the trigger by itself:

  • scripts/pm/clause2-line.mjs (the fleet's one reader) closes the value set at yes | no and the arm set at (widening) | (narrowing), and documents the four combinations: yes (narrowing) = "a diff that widens one surface and narrows another. Both facts are true and both are read"; no (narrowing) = "NOT a widening, but breaking. This is the whole point of the arm"; no (widening) = malformed.
  • scripts/pm/record-recognisers.mjs reads the narrowing face from "A narrowing arm on ANY of them ⇒ the narrowing face (yes (narrowing) included)".
  • AGENTS.md step 3: "(narrowing) is BREAKING".
  • The tree at head carries both: .changeset/24583-7b3-organizationless-counter-retired.md (yes (narrowing)), .changeset/24765-team-sessions-related-list.md and .changeset/24813-adopt-orphans-readonly-package.md (no (narrowing)).

So the rule is written against the ARM, value-agnostic: 「Clause-②: 带 (narrowing) 臂(yes/no 皆算)」. The card's yes (narrowing) is one of the two spellings, not the only one; no third spelling was introduced. Related observation (no change here): references/contract-review.md L12 spells only no (narrowing) for the tier derivation while the recogniser reads either value — noted under Acceptance notes.

The command (H4)

  • packages/qa/dogfood/package.json: "test": "vitest run". vitest.config.ts: shard: process.env.OS_TEST_SHARD is the only shard mechanism; two projects (shared-showcase, isolated), OS_CLOUD_URL: 'off' and OS_REGISTRY_LOG: 'warn' set per project inside the config.
  • ci.yml dogfood job (Dogfood Regression Gate (n/3)): builds the closure with pnpm turbo run build --filter=@objectstack/dogfood, then runs OS_TEST_SHARD=n/3 pnpm turbo run test --filter=@objectstack/dogfood — the same test script, sharded only by that variable — and grades the log with scripts/check-test-completeness.mjs.
  • Measured at a8b44d407 in packages/qa/dogfood: npx vitest list --filesOnly prints 287 files; find -name '*.test.ts' counts 287 (265 of them *.dogfood.test.ts). The plain pnpm --filter @objectstack/dogfood test with no OS_TEST_SHARD therefore runs the whole set — the union of the three CI shards — so the card's command IS the full battery, provided the closure is built first and nothing shards or narrows it. The rule says so: 「命令同 CI:按 ① 建闭包,锁下 pnpm --filter @objectstack/dogfood test;⛔ 无 OS_TEST_SHARD、无路径」 (① = the closure-build rule in 〈本地验证范围〉).
  • Beyond the ~10-minute foreground cap: L88 is generalised from the one check:pm-dispatch-gates case to 「超前台上限者(check:pm-dispatch-gates、全量 dogfood):nohup … > LOG 2>&1 & 后 tail --pid」. The verify lock still applies (rule 1 of 〈资源纪律〉 — the battery is a heavy run), so the backgrounded command is the lock wrapper itself, and the lock's VERDICT line goes into the report field.
  • NOT MEASURED: the battery's local wall time. ci.yml's own comment reads "the ~7½-minute dogfood suite" (a CI runner, sharded); this PR is not a !/narrowing change, so it owes no run, and a 287-file boot battery on the shared box was not spent on a reading the rule does not depend on.

Paying the ratchets (H3)

Both files sat at zero headroom. Every added line is paid by deleting a line that states no rule, each named with where its content still lives. No re-wrap was used as payment; the four added prose lines measure 119 / 120 / 119 / 118 bytes against the 120-byte cap, and the JSON line sits in a fence, which the cap exempts.

.claude/agents/os-dev.md — 404 → 404 (+3 rule lines, +1 JSON template line, −4; L88 and L279 rewritten in place):

  • deleted 「陷阱在 shell 用法里,不可机械化;⛔ 别等机械强制。」 — a meta statement; the file's own L20 already says it carries only 「钩子无法机械强制的条款」.
  • deleted 「⛔ 不把这类结果写进报告当作一次失败的测量。」 — restates L176 「两类跑了却没测到,都读作 NOT MEASURED,不读作绿也不读作红」 for class ②.
  • deleted 「消融本就为证明新门禁能失败时,这份假绿读作门禁没触发,于是有人去弱化一条好门禁。」 — the story behind the asymmetry; the rule stays in the asymmetry line above it and in the three leg lines below it (build each leg, prove it reached dist/).
  • deleted 「例:反向验证方向反转、前提死了、某个产物在此无意义;按模板硬造比留白更糟。」 — an example list; each case is a rule elsewhere (「报告你实际观察到的方向」, premise_still_valid: false, 「报告模板是工具,不是真相」).
  • L88 「测试电池 pnpm check:pm-dispatch-gates 亦属 check:*:不走锁,…」 → 「超前台上限者(check:pm-dispatch-gates、全量 dogfood):…」 — the check:* / no-lock classification is L87's, by name; the nohup + tail form is generalised rather than stated twice.

.claude/skills/pm-dispatch/references/review-checklist.md — 77 → 77 (+1, −1):

  • deleted 「这是合并前唯一的人工关口,⛔ 不只信报告;合并后那一读见 landing-operations.md。」 — the rule lives in execution-duties.md 〈复核〉 「你是记录在案的复核人:对 GitHub 核验,⛔ 不对报告的自述核验」 and the pointer in its preamble 「落地窗口另读 landing-operations.md」; the first clause is narrative.

Verification

Local union, run after the final commit on bd8baf269 (working tree clean, git status --porcelain empty), every exit code captured before any pipe:

family (as dispatch-gates --commands printed it) exit the gate's own verdict line
node scripts/check-closing-keyword-parity.mjs 0 OK (3 parsers agree on all 9 keywords …)
node scripts/check-closing-keyword-parity.mjs --self-test 0 40 assertions, 5 mutations each driven to red
node scripts/check-comment-mask-corpus.mjs 0 9691 files, 0 disagree, 0 unparseable
node scripts/pm/check-governed-queue-guard.mjs --self-test 0 322 cases pass
node scripts/pm/check-harness-current.mjs --self-test 0 all 26 cases passed
pnpm --filter @objectstack/lint run check:doc-formula-expressions 0 23 record-scoped formula example(s) across 476 files judged clean (first attempt exit 3, PREREQUISITE NOT MET: @objectstack/formula / @objectstack/lint unbuilt — built under the verify lock, VERDICT command-exit 0, held 2s, then re-run)
pnpm check:agent-model-declared 0 1 agent definition(s) under .claude/agents/ all declare a model
pnpm check:agent-test-spelling 0 0 violations — 599 file(s) · 14 separator(s) JUDGED
pnpm check:commit-card-trailers 0 self-test 81 cases pass
pnpm check:cross-package-test-inputs 0 31 package(s) read outside themselves, all declared
pnpm check:doc-authoring 0 53 published skill files clean; 19144 customer-facing string(s) clean
pnpm check:driver-memory-census 0 every declaration is ledgered, every ledger entry is live
pnpm check:gitlink-declared 0 OK (11488 index entries — 0 gitlink(s))
pnpm check:nul-bytes 0 OK (scanned 11479 text file(s) … no raw ASCII control bytes)
pnpm check:pm-governed-merges 0 self-test 500 assertions
pnpm check:pm-skill-id-lint 0 87 file(s) clean (pattern /#[0-9]{3,}/g)
pnpm check:pm-skill-ratchet 0 .claude/agents/os-dev.md is 404 lines (ceiling 404; headroom 0) · review-checklist.md is 77 lines (ceiling 77; headroom 0)
pnpm check:refd-timer-probe 0 9685 source file(s) swept
pnpm check:required-contexts 0 5 required context name(s) pinned across 3 workflow(s)
pnpm check:skill-frame-sync 0 the one declared copy of the decision frame is internally coherent
pnpm check:watch-hint-literal 0 76 declaration(s) across 4 rostered name(s)

node scripts/pm/dispatch-gates.mjs --ran ran.list --repo objectstack-ai/objectstack → exit 0: "Run reconciliation — 21 derived, 21 run, 0 NOT-MEASURED, 0 UNRUN."

  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack with no paths derived the same 21 commands the dispatch brief listed; --ran reconciliation below.
  • No package is touched ⇒ no ① closure build and no ② package test/typecheck; test:repo and every CI family are read from this PR's check-runs by the seat, not re-run here.
  • No test-pinned behaviour changed ⇒ no ablation.
  • skip-changeset is declared on this PR: .claude/** is on the fast lane, nothing published moves.

Acceptance notes

  • references/contract-review.md L12 names only Clause-②: no (narrowing) as the narrowing spelling that lifts the tier, while record-recognisers.mjs lifts it on the arm whatever the value (yes (narrowing) included). Prose narrower than its reader; a governed reference outside this card's surface. Observation — carrier: none.
  • os-dev.md 「证据已销毁(评论、卡或 PR 答 404)的复核项记 NOT MEASURED…」 and review-checklist.md 「复核项证据已销毁(…)⇒ 记 NOT MEASURED…」 state one rule on both sides; each has its own reader (dev / seat), so neither was spent here. Observation — carrier: none.
  • vitest list --filesOnly prints 287 under OS_TEST_SHARD=1/3, 2/3 and 3/3 alike: listing is not sharded, only run is. Not a defect; a reason the rule counts files from the plain list.
  • ci.yml's "~7½-minute dogfood suite" comment predates the three-shard job and was not re-measured. Observation — carrier: none.

维护者速读(草稿)

改了什么:给开发 agent 的角色文件加了一条规则:PR 标题带 !、或 changeset 的 Clause-②: 行带 (narrowing) 臂(yes/no 皆算)的卡,在最终 head 上跑一次全量 dogfood(与 CI 同一条命令、不分片不缩范围),结果写进终报的新字段 dogfood_battery;复核清单在翻 ready / 挂 auto-merge / 入队前核这个字段。红的处置照卡:是本改动自己的后果(陈旧 fixture)就同 PR 修,否则照实报,永不跳过或收窄。两个文件各删了等量不含规则的文字抵账,行数不变。

为什么改:推送 CI 和合并队列只测被改到的包,带 ! 的破坏性改动会让没被改到的包里的 dogfood 测试在合并后的整点全量跑才变红(18.x 已发生两次,#24780 与 #24879)。维护者问「如何避免类似的问题」并「立卡」;卡上的「Done when」是裁决,本 PR 照它落地。卡上写的触发拼写 yes (narrowing) 只是两种合法拼写之一,规则按「臂」写,两种都算。

风险与代价(含回滚):纯流程文字,不动 CI、workflow、门禁或脚本。代价是带 ! 或收窄声明的卡多一次锁下的全量 dogfood 运行(CI 分片跑约 7 分半,本地单机预计超过十分钟),其它卡零成本。回滚 = revert 本 PR 的一个 commit,无数据与发布影响。

席位意见:

你要做的:本 PR 只碰 .claude/**,属 Tier S:席位达档复核 PASS 后由席位入队,无需你动手。如对触发条件(按臂算、不按值算)或字段名 dogfood_battery 有异议,在卡上回一句即可。


Generated by Claude Code

…y on its final head and reports it; the checklist reads the field before arming

os-dev.md: the trigger-less "dogfood once on the final head" clause gains its
trigger (a `!` title or a `(narrowing)` arm on the Clause-② line, either
value), the CI-equivalent command (closure build, then the unsharded
`pnpm --filter @objectstack/dogfood test` under the verify lock), the red
disposition (own stale fixture fixed in the same PR, anything else reported,
never skipped or narrowed), a `dogfood_battery` report field, and the
nohup/tail --pid form generalised to every run longer than the foreground
cap. Four non-rule lines pay for the four added lines. review-checklist.md
reads the field before ready/arm/queue; one pointer line whose rule lives in
execution-duties.md pays for it. Both ratchets stay at 404/404 and 77/77.

Claude-Session: https://claude.ai/code/session_01M82feuetLzrCiBz41BJb7L
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 20, 2026
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation labels Oct 20, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: bd8baf26940f540a2886bd4155ba5d923e6ad99f
Local-runs: none
Scope: .claude/agents/os-dev.md, .claude/skills/pm-dispatch/references/review-checklist.md + .claude/skills/pm-dispatch/references/execution-duties.md (L3, L177), .claude/skills/pm-dispatch/references/landing-operations.md (L8-13, L61, L73-75), .claude/skills/pm-dispatch/references/contract-review.md (L12), .claude/skills/pm-dispatch/SKILL.md (L280), .claude/skills/pm-dispatch/references/lanes/skills.md (L20, L29), AGENTS.md (L11-14, L236-237, L339-340, L531-533, L586, L1088), scripts/pm/clause2-line.mjs, scripts/pm/record-recognisers.mjs, scripts/check-changeset-no-major.mjs, scripts/check-adr-0087-registration.mjs, scripts/pm/check-half-states.mjs (the H52 reader), scripts/pm/check-settings-deny-roster.mjs (header), scripts/pm/check-skill-line-ratchet.mjs (ceilings), scripts/pm/check-governed-merges.mjs (register), .github/workflows/ci.yml (the dogfood job), .github/workflows/pr-automation.yml (the Check Changeset job), packages/qa/dogfood/package.json, packages/qa/dogfood/vitest.config.ts, .changeset/24583-7a3-sharing-null-readers.md, .changeset/24583-7b3-organizationless-counter-retired.md, .changeset/24765-team-sessions-related-list.md, .changeset/24813-adopt-orphans-readonly-package.md

Inputs: card #24890 body and both comments (the claim and the os-dev-report), PR #24917 body, file list (2 files, +7/−7) and net diff against main, and the check-runs on the head. The branch is one commit off merge-base a8b44d4; head repo = base repo (not a fork); the PR is draft with no auto-merge. The two hits are the whole diff, so there is no lane remainder. Line numbers below are the HEAD file's.

Check-runs on the head, read 2026-10-21T00:42Z (identical to the first reading on 2026-10-20): all 40 completed, none in progress, none failed. The required five: Lint & Repo Gates success · TypeScript Type Check success · Test Core success · Governed Surface Queue Guard success · Build Core skipped (path-filtered by the filter job: no package touched). The rest: Check Changeset success (its second, label-fast-path instance skipped) · Check PR Size success · Check Documentation Links success · the four claim/card guards success · Lint · ESLint, docs & code guards, repo & tooling gates, CI release & engine gates, PM dispatch-gates and the three scoped jobs success · Type Check · workspace, source gates, consumer gates, debt ledger success · Dogfood Regression Gate (aggregator) success with its three shards and Dogfood Verify CLI skipped · Auto Label success · Console Pin Gate, Temporal Conformance, Build Docs and the opt-in harnesses skipped.

① Derived judgments

The diff changes rules text, not a schema: its accept set is what a dev and the landing seat are now told to do and not do. Each changed rule, judged against its readers and the cited code:

  1. Trigger — os-dev.md L277 「全量 dogfood 只在终 head 跑一次,仅当标题带 ! 或 Clause-②: 带 (narrowing) 臂(yes/no 皆算)」: RIGHT. The arm, not the value, marks breaking, in every reader of that line: clause2-line.mjs L89-101 reads yes (narrowing) and no (narrowing) as declared narrowings and refuses only no (widening); record-recognisers.mjs L187-188 and L238 put the narrowing face on the arm "whatever the value", and its self-test L1628 pins yes (narrowing); check-adr-0087-registration.mjs L683-684 adds the clause-②-narrowing breaking signal on the arm alone, both spellings pinned at L2463-2464; check-changeset-no-major.mjs (the Check Changeset job's reader, pr-automation.yml L1127) L1662-1675 reports the arm beside either value and L1689 names no (narrowing) as carrying the axis; AGENTS.md L1088 says (narrowing) is BREAKING. Both spellings are EMITTED on the tree: yes (narrowing) in .changeset/24583-7b3 and 24583-7a3 (the latter with trailing reasoning, which readArmToken keeps), no (narrowing) in 24765 and 24813. The card's yes (narrowing)-only spelling would have missed two of those four; the arm-based rule is the reading that honours the card's intent (breaking ⇒ battery), and the dev declared the correction in the PR body (H1) and in the report, the public correction review-checklist.md L68 asks for. The gap the rule closes is real at the head: ci.yml L2037 runs the dogfood shards only when the event is neither pull_request nor merge_group, so neither PR CI nor the queue ever runs the battery (AGENTS.md L531-533, the two speeds); the card's premise holds. Note, not a finding: no reader in the tree reads ! off a PR TITLE — check-adr-0087-registration.mjs L677-678 reads the conventional-commit bang off the changeset summary line — so the title half is a seat and dev read, exactly as the card wrote it; 「标题带 !」 is to be read at the conventional-commit position (type(scope)!:), not as any exclamation mark.

  2. Command — L278 「命令同 CI:按 ① 建闭包,锁下 pnpm --filter @objectstack/dogfood test;⛔ 无 OS_TEST_SHARD、无路径」: RIGHT as the CI equivalent. packages/qa/dogfood/package.json test is vitest run; vitest.config.ts L168 shard: process.env.OS_TEST_SHARD is the only shard mechanism (L128-136); ci.yml L2146-2157 builds the closure with pnpm turbo run build --filter=@objectstack/dogfood, then L2202-2205 runs the same test script with OS_TEST_SHARD=k/3. The plain command with no shard variable is the union of the three CI shards. One imprecision, named for the lane: 「按 ① 建闭包」 points at 〈本地验证范围〉 ① (L133), whose closure is the TOUCHED package's dependency closure; the closure the battery needs is @objectstack/dogfood's (ci.yml L2162: "the step above builds everything the tests need"). The 「命令同 CI」 anchor and L188 「判断任何事之前先 build」 resolve it, and a dependency left unbuilt fails loud at import (the L178-179 class), never green — so it does not move the verdict; it is the one line to tighten when the file next moves (「按 ① 为 dogfood 建闭包」 or equivalent).

  3. Red disposition — L279 「红 = 本改动的后果(陈旧 fixture)同 PR 修,余照报;⛔ 永不跳过或收窄;计数记 dogfood_battery」: RIGHT, verbatim the card's Done-when.

  4. L88 rewrite 「超前台上限者(check:pm-dispatch-gates、全量 dogfood):nohup 重定向后 tail --pid」: RIGHT. The lock classification it no longer states is L87's by name (check:* 门禁 … 不走它) and L278's for the battery (锁下 — the backgrounded command is the lock wrapper itself); it composes with L344 (the one anti-polling foreground wait is tail --pid) and L345 (a run longer than the turn is read from its log at report time).

  5. L276 split: RIGHT. The merge-main rule keeps its line; the dogfood clause moves to L277 with its trigger. Commit b8762c0 (verified in history) introduced that clause together with AGENTS.md L586 "dogfood once, on the final head"; AGENTS.md at the head mentions dogfood only there and at L532 (the full battery). The role file adds a trigger and a command to a sentence that states neither; the once-on-the-final-head direction is unchanged on both sides, so nothing conflicts with the file that wins on conflict.

  6. Report field dogfood_battery (JSON template L373): RIGHT, additive. The report's mechanical readers are check-half-states.mjs H52 (the marker line and open_questions, L11796-11816) and the mcp_calls roster rule check-settings-deny-roster.mjs documents; neither reads another key. SKILL.md L280 keeps the shape in os-dev.md alone — honoured, no second copy. The n/a — … spelling is what the dev's own report on this PR already carries.

  7. review-checklist.md L50 「! 或 (narrowing):入队前核 dogfood_battery 钉 head、全量、红已修/已报;缺或收窄 ⇒ REWORK」: RIGHT. Named reader (lanes/skills.md L29) = the dispatch seat at the pre-arm read; it sits in the block that already pins every reading to the head (L42-49) and reads the same trigger as L277. landing-operations.md L8-13 remain the 条款② gate and L61 the Tier S landing — no second home needed, no line owed there.

  8. The five deleted lines, each checked for survival (lanes/skills.md L20 「被砍内容若在别处无家,砍掉就是丢规则」): no rule dropped.

    • os-dev.md 「陷阱在 shell 用法里,不可机械化;⛔ 别等机械强制。」 → lives in L20 (the file carries 钩子无法机械强制的条款) and L186-187 (条款无论 prompt 提没提都生效,沉默不是许可); AGENTS.md states the same ordering twice (the rule outranks the hook, L236-237 and L339-340). A meta line.
    • os-dev.md 「⛔ 不把这类结果写进报告当作一次失败的测量。」 → L175 「两类跑了却没测到,都读作 NOT MEASURED,不读作绿也不读作红」 covers class ② (the 两类 are the ① and ② that follow it), and L102 fixes the spelling (NOT MEASURED, the family, the reason).
    • os-dev.md 「消融本就为证明新门禁能失败时,这份假绿读作门禁没触发,于是有人去弱化一条好门禁。」 → the consequence narrative of L248-249 (the asymmetry; a false green endorsing an assertion that may never fail), whose operative rule is L250-252 (build each leg, prove it reached dist/). AGENTS.md L11-14: a rule carries no incident narrative.
    • os-dev.md 「例:反向验证方向反转、前提死了、某个产物在此无意义;按模板硬造比留白更糟。」 → each example is a rule elsewhere: L242 (报告你实际观察到的方向;永不硬套模板的预设), L384 (premise_still_valid: false), L385 (报告模板是工具,不是真相 … 直说).
    • review-checklist.md 「这是合并前唯一的人工关口,⛔ 不只信报告;合并后那一读见 landing-operations.md。」 → the rule is execution-duties.md L177 「对 GitHub 核验,⛔ 不对报告的自述核验」; the pointer is its L3 「落地窗口另读 landing-operations.md」; the post-merge read itself stands at landing-operations.md L73 and L75 (closed_by_pull_requests; cards that left open unexpectedly). 「唯一的人工关口」 is narrative.
  9. Ratchets: RIGHT. The head blobs measure 404 lines (os-dev.md, ceiling 404 at check-skill-line-ratchet.mjs L1455) and 77 (review-checklist.md, ceiling 77 at L1165); every payment is a whole-line deletion, no re-wrap; the added prose lines measure 112 / 87 / 119 / 120 / 119 / 118 bytes and the template line sits in a fence. Lint · PM dispatch-gates and Lint & Repo Gates are success on the head.

  10. Landing tier and shape: RIGHT. Both paths under .claude/ ⇒ Tier S (check-governed-merges.mjs L1178; landing-operations.md L61); Governed Surface Queue Guard success on the head; no CI, workflow, gate or script change, as the card's ⛔ orders; dispatch-runbook.md and execution-duties.md untouched is right (os-dev.md L186: 无条件条款住这里). Fixes #24890 on the first line is right: the whole Done-when is delivered. The 维护者速读 section is present with its five parts (L288-289); the body ends in the session-URL footer; the head commit carries the model-free trailer pair.

② Semver level

skip-changeset: RIGHT. The diff is .claude/** only — the fast lane os-dev.md L300 names; nothing in any package's files[] moves, and no .changeset/*.md is edited. The label was applied in the pr_create stroke and is on the PR; Check Changeset is success on the head. Clause-②: no on the PR body (L3) is the claim's line copied verbatim (os-dev.md L280): no accept set widens and no published surface narrows. No (narrowing) arm and no ! in the title ⇒ this PR owes no battery; the report's dogfood_battery: "n/a — …" is the field's own first correct use.

③ Boundary flags

open_questions: empty — nothing to answer. Each deviations entry: (1) branch off a8b44d4 after the brief's lead at fcb40ad — merge-base verified a8b44d4, same 21 derived families: answered. (2) doc-formula-expressions exit 3 PREREQUISITE NOT MET, then 0 after the prerequisite build — honest, and Lint · docs & code guards is success on the head: answered. (3) battery wall time NOT MEASURED — not owed on this PR; accepted (the 速读's 预计超过十分钟 is stated as an estimate, not a reading). (4) vitest list ignores the shard variable — vitest.config.ts L168 confirms the shard applies to run only: answered. (5) the model-named trailer declined — the head commit carries Claude-Session: and a model-free Co-authored-by line, verified from the object: answered. (6) label read-back via a REST read — skip-changeset present in the PR's labels: answered.

out_of_scope_findings and the Acceptance notes: (a) contract-review.md L12 spells only no (narrowing) as the tier-lifting spelling while the reader lifts on the arm with either value — CONFIRMED, and wider than the dev noted: record-recognisers.mjs's own prose (L131, the REVIEW_FACES words at L156, the --template help at L1053-1054) names the one spelling too, while its code (L238) and self-test (L1628) read yes (narrowing). Not a class a/b/c finding; ESCALATED to the domain:skills lane as a one-line follow-up on contract-review.md L12 with the record-recognisers.mjs prose rider (same lane: scripts/pm/** and .claude/skills/**), carried on the lane's next governed PR together with this review's own ①.2 note on the closure wording. (b) the NOT MEASURED-on-destroyed-evidence rule stated on the dev side (os-dev.md L176) and the seat side (review-checklist.md L36) — two readers, by design; no action. (c) ci.yml L627 and L2027 "~7½-minute" comments predate the three-shard job — observation; no action; carrier none accepted.

Implemented-by: claude/issue-24890-breaking-dogfood-battery
Reviewed-by: session_01M82feuetLzrCiBz41BJb7L

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对

ACCEPT · domain:skills seat 1 (seat post #7623) · session_01M82feuetLzrCiBz41BJb7L · head bd8baf26940f540a2886bd4155ba5d923e6ad99f · 2026-10-21T00:45Z

  1. Form. The PR is a draft against main, and the body's first line is Fixes #24890. Assignee huangyiirene equals the card's. Files: .claude/agents/os-dev.md and .claude/skills/pm-dispatch/references/review-checklist.md only (+7/−7), the declared surface. check-governed-merges.mjs --pr 24917: Tier S, 14 changed lines. skip-changeset is right: no package is touched.
  2. Premises measured.
    • The seat read the whole diff: the trigger, the command, the red disposition, the dogfood_battery report field and the checklist line that reads it.
    • Each of the five deleted lines was traced, by the seat and by the review, to where its content still lives (review ①.8).
    • The trigger reads the (narrowing) arm with either value. The tree's readers (clause2-line.mjs, record-recognisers.mjs, check-adr-0087-registration.mjs, check-changeset-no-major.mjs) all do the same, and both spellings occur in .changeset/* on main. This corrects the card's yes (narrowing)-only spelling (dev H1).
  3. Gate check-runs, pinned to this head (2026-10-21T00:42Z, per the review): 40 completed, 0 failures. Lint & Repo Gates, TypeScript Type Check, Test Core, Governed Surface Queue Guard and every Lint · and Type Check · lane are success. check-expected-skips.mjs --pr 24917, from a checkout pinned to origin/main 62bc12930: roster: identical to … main's tip, then OK — 14 skipped check-run(s), every one in main's roster (exit 0). The contract review of record is comment 6305134343 (Served-tier: CONTRACT_REVIEW_TIER, this head, Local-runs: none, PASS), rendered by an isolated subagent at that tier and adopted by this seat.
  4. Accepted deviations.
    • The branch is off a8b44d407, not the dispatch's fcb40ad67; the same 21 families were derived.
    • The battery's wall time is NOT MEASURED. This PR owes no run, and its own dogfood_battery is n/a.
    • The model-free commit trailers follow AGENTS.md.
  5. Out-of-scope findings and review notes. None is a class a, b or c finding; each goes to the seat post's carried pointers.
    • contract-review.md L12, and the prose of record-recognisers.mjs, spell only no (narrowing) as the tier-lifting declaration, while the code lifts on the arm with either value (review ③ (a)). The tree's reader is right, and a wrong seat tier is refused loudly by it, so nothing goes through silently. The prose is tightened at the next edit of either file, paid by compression.
    • os-dev.md L278's 「按 ① 建闭包」 should name the dogfood package's closure (review ①.2). It is tightened at the file's next edit.
    • The NOT MEASURED-on-destroyed-evidence rule appears on both sides, dev and seat, by design. No action.
    • The ci.yml "~7½-minute" comments predate the three-shard job. Observation only.
  6. Landing. Tier S with an at-tier PASS on this head and every check green: the seat flips it ready, arms auto-merge once mergeable_state settles, follows it to MERGED, then closes out pm-dispatch: a dispatched ! (breaking) change carries a full dogfood battery run in its dev report before it is armed — push CI and the merge queue test only touched packages; two 18.x steps reddened the hourly battery (#24780, #24879) #24890.

Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Director record · governed landing recognised · summon #45 continuation 3, session_01Lg6GQ4xjqmvEzYv78d6H7i · 2026-10-21T05:04Z

Audit window --since-ref objectstack=e4d604efd39f (tip eddffc3390cf): this PR landed on the Tier S surface .claude/** (×2, +7/−7: .claude/agents/os-dev.md and .claude/skills/pm-dispatch/references/review-checklist.md) at be1fd311b, merged by objectstack-fleet[bot] from the queue, with the at-tier contract review PASS 6305134343 (Served-tier: CONTRACT_REVIEW_TIER, head bd8baf2694) and the domain:skills seat ACCEPT 6305152302 on the same head, and no APPROVED review by a GOVERNED_APPROVERS account — one of the three rows this window puts to the maintainer under the rule of #24241.

Put to the maintainer in this session's chat beside batch #381, with one line on what changed: a dispatched breaking PR (a ! in its title, or a (narrowing) arm on its Clause-②: line) now owes the full dogfood battery on its final head and records the result in a new dogfood_battery report field, and the review checklist reads that field before ready, auto-merge or queue; no CI, workflow, gate or script changes. The maintainer answered 「其他同意」 — recognised. Nothing is owed on this PR; the ledger block on #12708 carries the row.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants