agents(os-dev): narrow three test obligations — one-time ablation proofs, import-side tests only on public-surface change, no wording pins - #16460
Conversation
…ofs, import-side tests only on public-surface change, no wording pins Rules-only folds under the unchanged 403-line ceiling, every line at or under 120 bytes: - L129-130: the affected set is the changed package; importers owe tests only when a public surface changes (spec contract, published `exports`, wire shape); byte-identical public surface owes own-package tests and the derived gates only. - L210-213: reverse verification and ablation are one-time proofs quoted in the PR body and the report, never a permanent test file; the two commit-first lines and their two uncommitted-hazard lines fold into one each. - L227: prompts, verdicts and error copy are not pinned unless a consumer parses the text; assert the kind, the exit code or the named subject. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox
Verdict: ACCEPT (governed — to the approvers)Implemented-by: os-dev flight Y (fable), branch What was checked
Rulings
LandingGoverned surface: reviewers Generated by Claude Code |
维护者速读(skills 席,2026-09-07T03:1xZ)事情:按您 02:0xZ 的指示(「同意,这几个都处理,你现在就负责派发」的 C 项),dev 契约 为什么:测试文件 3,388 对源码 2,183,每天新增 35–89 个,增长是契约义务的函数;抽样 145 个新测试里 import 方补测的只有 6 个,所以 ② 的直接效果小,① 与 ③ 是主要来源。三条都不动「怎么做验证」,只动「留不留下来」。 风险:低。契约收窄意味着某些跨包回归改由合并队列的 CI 捕获(受影响集 + 跨包扫描),而不是由 dev 提前补测;公开面变化时的 import 方义务仍在。文本层面 ratchet / frame-sync / clause-② 载体检查全绿。 要您做什么:一个决定——合并或退回。审批人 os-zhuang / hotlong 已被请求复审。 席位意见:建议合并。三条与您对测试总量的判断一致;若想保守,可只合 ① 与 ③、把 ② 退回(我们会拆成单行 PR)。 Generated by Claude Code |
Fixes #16456
Governed surface (
.claude/**): draft PR, human merge. One file,.claude/agents/os-dev.md, line-neutral at 403/403: every added line is paid by a fold inside the same block, every line is at or under 120 bytes (LC_ALL=C awk, measured max 120, zero over), and the diff stays in the rules-only register (no dates, quotations, issue numbers, narrative or model names). No other file moves — the measurement below says why.Three test obligations in the dev contract are narrowed (maintainer-directed, verbatim: 「我想的是测试会不会太多,是否都是必要的,是不是应该砍,每次修改都要完整的测试吗」 → 「同意,这几个都处理,你现在就负责派发」). Line numbers: 改前 =
origin/mainat6eba38f5a3, 改后 =ddb4213508. In the quoted lines the two angle-bracket placeholders are spelledYOUR_BRANCHandPATH; the file keeps its own spellings — the GitHub sanitizer eats angle-bracket fragments in bodies.① Reverse verification and ablation are one-time proofs — os-dev.md L210–214 → L210–213
git checkout YOUR_BRANCH -- PATH。git checkout origin/main -- PATH不留任何恢复点。HEAD,HEAD必须先装着你的实现。YOUR_BRANCHyields toHEAD, which hard line ① (L217) already mandatesgit checkout origin/main -- PATH不留恢复点,git checkout HEAD -- PATH删的正是实现。HEAD,HEAD必须先装着你的实现。git checkout HEAD -- PATH删的正是实现本身,事后检查全绿。No longer owed: a fixture, spec or self-test case added to the tree to make a reverse-verification or ablation proof permanent — the legs stay mandatory (the how-to at L188 and L214–260 is untouched), and the evidence is the quoted before/after run in the PR body and the report.
② Import-side tests only when a public surface changes — os-dev.md L129–130
TURBO_SCM_BASE="$BASE" pnpm exec turbo ls --affected。exports、线上形状。--affectedgraph, importers included), so it is the echo the ruling namesNo longer owed: a test in — or a local test run of — every package that merely imports the changed module while every public surface (a
packages/speccontract, a publishedexportsentry, a wire shape) stays byte-identical; own-package tests and the derived gates remain owed. When a public surface does change, importers still owe tests, and the consumer-sweep filter at L185 (pnpm --filter '...@objectstack/PKG') remains the enumerator — theturbo ls --affectedspelling leaves with the CI-set definition it served.③ No pin tests on wording — new os-dev.md L227 (the measurement found no prior carrier)
code+status之上再断言 message 首句,永不取而代之。No longer owed: a pin test on a remedy string, a verdict line, a prompt or an error message's prose; the assertion is on the kind, the exit code or the named subject, and wording is pinned only where a consumer parses it (L228 keeps the code+status-first mechanics for that case).
Measurement — every carrier of the three obligations, by file and line
First pass
grep -n -E '欠|import|反向验证|消融|pin|文案|原文'over the five named files, second pass a read of each hit's neighbourhood, third pass a wider grep (受影响|affected|下游|消费者|清扫|判定行|message|wording|fixture|snapshot|措辞|永久) over.claude/agents/os-dev.md, all of.claude/skills/pm-dispatch/(references and lanes included),AGENTS.md,.claude/skills/dogfood-verification/SKILL.mdand the publishedskills/objectstack-pm-dispatch/.Moves (all in os-dev.md): L129–130 (②), L210–214 (① — the block gains the one-time-proof rule and folds 5 → 4), new L227 (③).
Read true under the ruling, left in place:
code+status; wording only where it is itself contract: ③'s direction.packages/clitier sentences (L131, L266): 「受影响包」 now reads through L129; both read true unchanged.testsfield (「ablation: rebuild + on-disk mutation proof」): the quoted-run evidence of ①.references/core-rules.md— no carrier (L61pinis a version pin; L150 is the report contract).references/review-checklist.mdL31 (real command + output as test evidence), L53–58 (rejection assertions oncode/status), L59–62 (N-package sweep evidence only on a contract tightening) — consistent with ①, ③, ②; no wording-pin demand anywhere in the file.references/contract-review.md— no carrier.SKILL.mdL182–183 (behaviour pins reversed on a contrary fact — behaviour, not wording), L546 (repo-wide pin sweep on a public-semantics flip: the public-surface case), L548 (code+statusminimum), L596 — consistent; no line moves.references/lanes/services.mdL17–18 — 「每条否定性 pin 都要消融验证:被禁行为放回、测试转红、报失败输出、恢复」: already the one-time form of ① (report the failing output, restore).references/lanes/spec.mdL38–39 — contract-surface cards run consumer-package tests: the public-surface case of ②.references/dispatch-runbook.mdL223–225 — the pin sweep on a semantics flip; the grep of error messages is the search instrument for existing pins, and L224 asserts substance, not prose.AGENTS.mdL364–371 — commit-first for reverse verification; consistent with ①.skills/objectstack-pm-dispatch/rules/dev-template.mdL71–72 (generic 「run the affected packages'」 with no importer definition) and L95–96 (wording only where it is itself contract) — no echo;skills/**untouched, so the two-readings clause does not apply.The wording-pin obligation (③) had no carrier in the corpus — it was a habit; rule ③ is added as a fold, next to its nearest neighbour L228.
Line pins and consistency
check-skill-line-ratchetlive:✓ check-skill-line-ratchet: .claude/agents/os-dev.md is 403 lines (ceiling 403; headroom 0).— no ceiling touched; self-test155 cases pass.LC_ALL=C awkover the file →max=120 over120=0(the file already carried 120-byte lines).grep -cof six removed anchors → 0 each; six inserted anchors → 1 each.git merge-tree --write-tree HEAD origin/main→ exit 0, 0 CONFLICT lines againstorigin/mainat245c6a23cd(tree4c4791bb1c).Gates (union run at
ddb4213508, the final commit; every exit captured before any pipe)Derived with
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack(no path passed; change set from the merge base6eba38f5a: 1 path). Reconciled:✓ dispatch-gates --ran: 16 derived famil(ies) accounted for — 16 run, 0 NOT-MEASURED.(exit 0).pnpm check:pm-skill-ratchetexit 0 — the two lines quoted above;declared cross-file moves: 1, total ceilings down 9 lines(main's state, untouched).pnpm check:pm-skill-id-lintexit 0 —✓ check-skill-id-lint: 26 file(s) clean (pattern /#[0-9]{3,}/g).pnpm check:skill-frame-syncexit 0 —4 axes … binding sentence present in all 2; 4 count mention(s) agree; 75 markdown files scanned for undeclared copies.node scripts/pm/check-clause2-carriers.mjs --self-testexit 0 —✓ check-clause2-carriers self-test: 190 cases pass.node scripts/pm/check-governed-merges.mjs --test .claude/agents/os-dev.md→ exit 3 —One hit governs the whole PR — 「混合 diff 一条命中即整 PR 分叉」; proportion is not a question. .claude/** ×1.pnpm check:pm-governed-mergesexit 0 — self-test 274 assertions.pnpm check:nul-bytesexit 0 —scanned 8078 text file(s) … no raw ASCII control bytes.pnpm check:agent-model-declaredexit 0 —0 justified inherit(s); no definition leaves its tier to the dispatching session.pnpm check:agent-test-spelling,check:doc-authoring,check:driver-memory-census,check:refd-timer-probe,check:watch-hint-literal,check-closing-keyword-parity(+ self-test),check-comment-mask-corpus,check-governed-queue-guard --self-test— all exit 0.pnpm --filter @objectstack/lint run check:doc-formula-expressions— first run exit 3PREREQUISITE NOT MET — the workspace package @objectstack/formula is not built(nothing measured); prerequisites built under the verify-lock, re-run: exit 0 —✓ check:doc-formula-expressions: 22 record-scoped formula example(s) across 430 files / 1371 TS blocks judged clean by @objectstack/formula.pnpm lintthroughbash scripts/pm/os-verify-lock.sh(slotissue-16456, one acquisition, full 540s budget):os-verify-lock: VERDICT command-exit 0 · held the lock 89s (1m29s) · waited 0s(shared-box seconds).No ablation applies — the diff is instruction text; the proof is the gates above.
维护者速读(草稿)
.claude/agents/os-dev.md)里三条测试义务收窄:反向验证与消融只是一次性证明、引在 PR 与报告里,不再留永久测试文件;只有公开面(spec 契约、发布的exports、线上形状)变化时,import 方的包才欠测试;提示、裁决与错误文案不做 pin 测试,除非消费者解析其原文。403 行上限不动,只折不加。🤖 Generated with Claude Code
https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox
Generated by Claude Code