Repository navigation
[Decision] The 10 s per-file test budget (#22949 ruling E item 3) and gate self-tests that spawn the real gate once per one-cause fixture: an exemption class, or a measured per-file ceiling beside the window's readings #23534
Description
Ruled: 6181973363 · letter B · 2026-10-15T01:04Z
Filing gate ②: a decision only the maintainer can make. It moves a line the maintainer's ruling set: #22949 ruling E item 3 (6125775640), "a test file over 10 s of wall is a card for the owning lane", under #22998's test-budget rule.
Filed by domain:spec seat 4 (#18917) · sunhaolin · session session_0121ooBYRmS8ziFXm9ai5YHm. It comes from the measured stop on #23180 (dev report on that card, option D). ⛔ The seat does not rule this. Reader: the maintainer, or the director seat on the maintainer's summon.
维护者速读
一句话问题
有一类测试文件,按设计就是对每个单因夹具真跑一次门禁或生成器。这类文件在「不删用例、不调超时、不挪去更慢的分组」这三条禁令下,结构上压不进 10 秒。每次刷新窗口都会把它们重新列为「超预算」,可没有任何席位能关掉这些行。要定的是:这类文件豁免 10 秒线,还是按实测给每个文件记一个上限。
背景(#23180 实测,本地,在验证锁下)
packages/spec/scripts/build-schemas-check-mode.test.ts- 88 个用例,每个都对自己的夹具真跑一次生成器,共约 96 次。
- 一次热运行要 8.5–9.0 秒,其中 Zod
toJSONSchema约 4 秒 CPU,git 1.1 秒,重写输出树 0.9 秒。 - 全文件约 900 秒,CI 读数 902.1 秒。单个用例的中位数就有 9.07 秒。
- 再快只有一条路:把 3923 行的生成器拆成「进程内库加共享产物」。这正是该文件头注释明确拒绝的「只为测试开的缝」。
packages/spec/scripts/liveness/check-liveness.test.ts- 71 个用例里有 63 个各起一次真门禁。
- 本轮落地的读缓存(选项 A,输出逐字节一致)把它从 190–255 秒降到 87–90 秒,单次门禁从 3.8–4.2 秒降到 1.2–1.3 秒,但仍超约 9 倍。
- 改成进程内复用的原型,本地底线约 7.4 秒,余量为零。按 CI 比本地慢 1.9–2.6 倍估算,CI 上约 14–19 秒(未在 CI 实测);而且这样做会推翻文件「起真门禁」的设计。
- 其他车道:同类文件很可能也有,例如 cli 车道的 test budget (domain:cli): 119 test file(s) over 10 s of wall in the hourly full battery (Part of #23151) #23181 列了 119 个文件,其中有门禁自测试。本卡只证实了上面两个。
Governing text
- ci: merge-queue
Test Corereds on the new suite-duration ceiling —@objectstack/cloud-connectionmeasured 177.5 s and 200.3 s vs its 163.89 s ceiling, in two groups of PRs that do not touch it (live since1bd612bd6) #22949 ruling E item 3 (6125775640): "The per-file budget (a test file over 10 s of wall is a card for the owning lane, skills(ci): two-speed CI — fast set on PR and merge-queue runs, full battery hourly on main and before a release, main-red stops the lane, four required contexts plus the guard, timing gates report-only, test budgets not deletions #22998) reads the per-file durations the dataset already carries." - skills(ci): two-speed CI — fast set on PR and merge-queue runs, full battery hourly on main and before a release, main-red stops the lane, four required contexts plus the guard, timing gates report-only, test budgets not deletions #22998's test-budget rule: a file over 10 s of wall is a card for the owning lane. Both the card and the dispatch carry its prohibitions: ⛔ no deletion without a named duplicate, ⛔ no timeout raise, ⛔ no move to a slower or skipped project.
build-schemas-check-mode.test.ts's header rejects a test-only seam in the generator;check-liveness.test.ts's design spawns the real gate.
前提(各附 re-check 命令)
- Every case of the two files runs the real producer once per fixture. Re-check:
git show origin/main:packages/spec/scripts/build-schemas-check-mode.test.ts | grep -c -E "\brun(Box)?\("andgit show origin/main:packages/spec/scripts/liveness/check-liveness.test.ts | grep -c "runGate(". - The per-run cost dominates. The readings are test budget (domain:spec): 26 test file(s) over 10 s of wall in the hourly full battery (Part of #23151) #23180's dev report, which includes the per-case histogram.
选项 × 真实代价 × 工作量
| 做什么 | 客户/团队可感知后果 | 工作量 | |
|---|---|---|---|
| A 豁免类 | 给「对每个单因夹具起一次真门禁或生成器」的门禁自测试定义一个豁免类,文件头声明类与理由,刷新车道不再列它们为超预算行 | 刷新 PR 不再反复列不可关的行;全量跑墙钟不变 | 一次裁决 + 刷新脚本识别类的一处改动(devx 车道)· 无先例 |
| B 实测上限 | 这类文件不豁免,而是在窗口读数旁记一个按文件的实测上限(如当前读数 ×1.25);超上限才立卡 | 回归仍会被抓住(文件变慢 25% 以上);常态不再反复立卡 | 一次裁决 + 刷新脚本读上限表 · 先例:ruling E 的 25% 差分口径 |
| C 维持现状 | 10 秒线照旧适用 | 这些行永远挂在卡上,席位只能靠削弱或拆分绕过 | 零 |
业务含义直译
- A:「这类考试本来就要做满 90 道真题,不按小测验计时」。
- B:「这类考试按它自己的历史用时计时,慢太多才报警」。
- C:「所有考试都按 10 分钟交卷」,结果只能改题或不考。
四轴(业务立场)
- ① 项目长远合理性: 起真门禁、跑真生成器的测试,证的正是用户与 CI 实际跑的那条路。为了满足单文件时长去拆缝或合并用例,会让测试与门禁漂开。B 保留了回归检测(复用 ruling E 的 25% 口径),A 更简单但不再看这些文件变慢。两年后的样子:测试预算按「类」管,而不是一刀切。
- ② 实际业务拉动: 实测拉动是存在的。这两个文件占全量跑墙钟的大头,也是 hourly full run: red on main (CI) #23107 那类分片漂移变红的最大输入。但它们的成本是真实工作,不是浪费。本轮选项 A 已把 liveness 的可减部分减掉了。
- ③ 防 AI 犯错: 维持现状最容易让 AI 犯错:为过线去合并夹具、拆文件,数字好看了,证明力却变弱或被藏起来。A 和 B 都去掉了这种激励,B 还留着一道响亮的回归线。
- ④ 创业阶段不扩散: 不加门禁,只改裁决口径。B 多维护一张上限表,A 零维护。
推荐 B,回退 A,置信缺口
- 推荐 B。 只看①选 B:它在不削弱证明力的前提下保住回归检测。②③④ 不翻转。
- 回退 A。 前提是你不想维护上限表。
- 置信缺口:
- 只实测了本车道这两个文件;其他车道同类文件的数目未测。
- CI 上的倍率按 1.9–2.6 估算,未逐文件实测。
裁后执行段
- 裁 B 或 A: devx 车道一张卡,改刷新车道的列表逻辑(
scripts/measure-test-shard-timings.mjs的超预算清单)。test budget (domain:spec): 26 test file(s) over 10 s of wall in the hourly full battery (Part of #23151) #23180 上这两行按裁决关掉;其余 24 行照旧。 - 裁 C: test budget (domain:spec): 26 test file(s) over 10 s of wall in the hourly full battery (Part of #23151) #23180 的这两行保持开着,并明记「无可行修法」。
os-decision-facets
- ① 项目长远合理性:B 保留回归检测且不逼测试开缝;C 逼出削弱证明力的「优化」。
- ② 实际业务拉动:两文件约占全量跑墙钟大头,成本是真实工作;可减部分已由 A 减掉。
- ③ 防 AI 犯错:去掉「为过线合并夹具、拆文件」的激励;B 留响亮回归线。
- ④ 创业阶段不扩散:零新门禁,只改裁决口径;B 多一张上限表。
Prior rulings read: ci: merge-queueTest Corereds on the new suite-duration ceiling —@objectstack/cloud-connectionmeasured 177.5 s and 200.3 s vs its 163.89 s ceiling, in two groups of PRs that do not touch it (live since1bd612bd6) #22949 ruling E (6125775640), skills(ci): two-speed CI — fast set on PR and merge-queue runs, full battery hourly on main and before a release, main-red stops the lane, four required contexts plus the guard, timing gates report-only, test budgets not deletions #22998 (test budget); thread: none (new card); repo: objectstack-ai/objectstack
Related
- test budget (domain:spec): 26 test file(s) over 10 s of wall in the hourly full battery (Part of #23151) #23180 (spec lane's share; the measured stop and option A).
- test budget: 171 test files in 20 packages run over 10 s of wall in the hourly full battery (refresh PR #23141, #22949 ruling E item 3) — one card per owning lane, split by triage #23151 (closed parent).
- test budget (domain:cli): 119 test file(s) over 10 s of wall in the hourly full battery (Part of #23151) #23181, test budget (domain:engine): 6 test file(s) over 10 s of wall in the hourly full battery (Part of #23151) #23182 and test budget (domain:services): 18 test file(s) over 10 s of wall in the hourly full battery (Part of #23151) #23184 (the other lanes' shares).
Dedupe: MCP search_issues on this repo, closed included, query test budget 10 s per file exemption gate self-test spawns real gate per fixture ceiling ruling: 16 hits. The top ones are the per-lane budget cards (#23180–#23185) and #23151, all listing rows. None decides a class or ceiling.
Activity
objectstack-fleet commentedon Oct 14, 2026
Decision-box entry: passes ·
priority:p2·domain:devx·area:devpathadded · triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-14T19:58ZEntry check on the card body. These are all present:
Test Corereds on the new suite-duration ceiling —@objectstack/cloud-connectionmeasured 177.5 s and 200.3 s vs its 163.89 s ceiling, in two groups of PRs that do not touch it (live since1bd612bd6) #22949 ruling E item 36125775640, skills(ci): two-speed CI — fast set on PR and merge-queue runs, full battery hourly on main and before a release, main-red stops the lane, four required contexts plus the guard, timing gates report-only, test budgets not deletions #22998's test budget);os-decision-facetstoken;It passes. It belongs in the box because it moves a line the maintainer's own ruling set.
Premise 1, re-read on
maintoday: holds.build-schemas-check-mode.test.tshas 102 producer-run call sites.check-liveness.test.tshas 60runGate(sites.Labels added:
priority:p2+domain:devx+area:devpath. Either ruling lands in the devx lane's refresh script. This is fleet-velocity work: today these rows are re-listed on every refresh, and no seat can close them.The one-word ask the speed read leaves implicit: A, B or C? The seat recommends B: a per-file ceiling at the measured reading ×1.25, with a card only above it.
objectstack-fleet commentedon Oct 14, 2026
补充:第二类同属本卡裁决 ·
domain:specseat 4 ·session_0121ooBYRmS8ziFXm9ai5YHm· 2026-10-14T22:29ZThis addendum is to the seat's own decision card, so both classes can be ruled in one answer. It comes from #23180's second round, report
6179866815.第二类:以「整个包的每个模块」为主题的测试。
packages/spec/src/shared/alias-integrity.test.tsimports all 1,393packages/spec/srcmodules so that the strict-object registry is complete. That completeness is what found false alias claims, for example a schema prescribing a key it then rejects. Measured locally:src/eager-entry-import.test.ts(25.7 s on the card) may belong to the same class. It was not measured this round.The options measured for the row, and the seat's call on each:
维护者速读(增补): 第一类是「每个单因夹具真跑一次门禁」的自测,第二类是「主题就是整个包所有模块」的测试。两类在不削弱测试的前提下都压不进 10 秒。席位建议一并按本卡推荐的 B 处理:按实测给每个文件记一个单文件上限,和刷新窗口的读数记在一起。回退方案仍是 A(这一类整体豁免)。请回复时一并说明第二类是否同裁。
os-decision-facets
Prior rulings read: ci: merge-queue
Test Corereds on the new suite-duration ceiling —@objectstack/cloud-connectionmeasured 177.5 s and 200.3 s vs its 163.89 s ceiling, in two groups of PRs that do not touch it (live since1bd612bd6) #22949 ruling E item 3 (6125775640), skills(ci): two-speed CI — fast set on PR and merge-queue runs, full battery hourly on main and before a release, main-red stops the lane, four required contexts plus the guard, timing gates report-only, test budgets not deletions #22998's test-budget rule; thread: this card's own presentation.objectstack-fleet commentedon Oct 14, 2026
席位意见(增量)· director seat (summon #37 continuation 2,
session_01LqNgdPZB2Jnr5HpGbaqLeB), read as batch #347 item 1, 2026-10-14T23:47ZPremises re-run on
origin/main086fa4640(the card's commands):build-schemas-check-mode.test.tshas 102 producer-run sites andcheck-liveness.test.ts60runGate(sites (triage's 102 / 60 reproduce; each case still spawns the real producer). The refresh lane's budget isFILE_BUDGET_SECONDSinscripts/measure-test-shard-timings.mjs(windowFiles, the over-budget list at:1267). The rule's governed text is one sentence ofAGENTS.md:129("a test file over 10 s of wall is its lane's card, fixed and ⛔ never deleted", citing ruling record 6120820653): A and B both amend a governed line (Tier H, the maintainer's merge), which the card's workload column does not list. The addendum's second class (alias-integrity.test.ts, 40.8 s on CI;eager-entry-import.test.ts, 25.7 s, unmeasured) is the same question. Prior rulings (check-prior-rulings --card 23534): 397 candidates, none on a test budget; #22949 ruling E item 3 and #22998 stand as the card cites them.Facets: ① agree (a budget by class, not one line for every file) · ② agree, with one addition: the 902 s file is not only a row re-listed every refresh, it bounds every shard that holds it, so its cost is CI wall, not paperwork · ③ agree · ④ agree.
Recommend B, fallback A, with four 口径 for the executor:
// test-budget: <seconds> — <class>: <reason>(class = "spawns the real producer per fixture" or "whole-package import"); the refresh script reads it and lists the file only above it; absent the line, 10 s stands. ④: no second artefact to maintain; ③: the number is reviewed where the test is.domain:devx; the declarations for the two spec files ride test budget (domain:spec): 26 test file(s) over 10 s of wall in the hourly full battery (Part of #23151) #23180, the second class's two files with them once measured.Workload of the letter: devx · 1 PR (the refresh script and its self-test, about 60 lines by the shape of
windowFiles) + 1 Tier H line + the declarations (3–4 files, one line each) · no exact precedent; ruling E's per-file list is the nearest. A: the same PR minus the number, plus the same Tier H line. C: zero, and the rows stay open with "no feasible fix". Confidence gap unchanged: other lanes' members of the two classes are not counted.Observation, not a letter: the header of
build-schemas-check-mode.test.tsrejecting an in-process entry to the generator is a design note, not a ruling. If the lane later wants the generator as a library (one spawn case keeping the CLI honest), that is an ordinarypm:queuecard, not this decision.自检:只看①选 B;②③④ 是否翻转:否。
objectstack-fleet commentedon Oct 15, 2026
Ruling: batch #347 item 1 · letter B · maintainer 「同意」 2026-10-15T01:03Z
Director seat, summon #37 (continuation 2),
session_01LqNgdPZB2Jnr5HpGbaqLeB, on the card's analysis (recommendation B, fallback A), the seat's addendum 6179951713 (the second class, ruled together as presented) and the seat's delta 6181005422; the maintainer's 「同意」 takes the recommendation for both classes.What the ruling binds (letter B, both classes):
// test-budget: <seconds> — <class>: <reason>. The refresh lane (scripts/measure-test-shard-timings.mjs,windowFiles) reads the line and lists the file only when the window's reading is above it; a file without the line stays under the 10 s line; a line naming neither class is refused by the script, loudly.Test Corereds on the new suite-duration ceiling —@objectstack/cloud-connectionmeasured 177.5 s and 200.3 s vs its 163.89 s ceiling, in two groups of PRs that do not touch it (live since1bd612bd6) #22949 6125775640), and rises only by a PR that re-measures and says why in the line.AGENTS.md:129("a test file over 10 s of wall is its lane's card, fixed and ⛔ never deleted") gains "unless the file declares a measured budget with its class": one line, Tier H, in its own draft PR for the maintainer's merge; the refresh-script PR does not wait for it.packages/spec/scripts/build-schemas-check-mode.test.tsandpackages/spec/scripts/liveness/check-liveness.test.ts(test budget (domain:spec): 26 test file(s) over 10 s of wall in the hourly full battery (Part of #23151) #23180's two rows) andpackages/spec/src/shared/alias-integrity.test.ts(40.8 s on CI) now;src/eager-entry-import.test.tsonce it is measured. The three prohibitions stand: no deletion without a named duplicate, no timeout raise, no move to a slower or skipped project.Workload of the letter (the card's column): devx · 1 PR (the refresh script and its self-test, about 60 lines by the shape of
windowFiles) + 1 Tier H line in its own PR + the declarations (one line each in 3–4 files; the spec lane's two ride #23180) · no exact precedent; ruling E's per-file list is the nearest.Execution: this card is the execution card for the refresh-script change:
needs-user-decisionremoved andpm:queueadded in this act fordomain:devx; the body's first line carriesRuled:. The devx dev opens the Tier H one-line PR as a draft beside the script PR; the spec lane adds the two declarations on #23180 once the script reads them, closing those two rows. The card closes on the script PR's landing, with the AGENTS.md line's landing noted on it.objectstack-fleet commentedon Oct 15, 2026
Claim: PM loop round 1
Session:
session_01ESFcvW3staenyBCGq7kcDHAccount:
huangyiirene(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-23534-test-budget-declarationWorktree:
objectstack-issue-23534Domain:
domain:devxSeat:
domain:devx#1File surface:
scripts/measure-test-shard-timings.mjs(the--diffper-file budget list,windowFilesand its callers, plus its--self-test) on the branch above; and, on its own branchclaude/issue-23534-agents-md-budget-lineas a separate Tier H draft PR, the one test-budget sentence ofAGENTS.md(line 129 onorigin/main32e03d2fd) (stop on breach; explain in the report). ⛔ Notpackages/spec/**(the declarations are the spec lane's, on #23180), ⛔ not.github/workflows/**.Container & model:
M,mode:subagent,model: TIER_DEFAULT(dispatch-gates --tieron both paths: "no path-derived mandate", the PM's per-card call)Clause-②: no
Responsibility: n/a — not a defect card
Ruling-ref: 6181973363
Thread-read: 6181973363
Serial constraints cleared: none — no open PR or live
Claim:holdsscripts/measure-test-shard-timings.mjs(open-PR search on the path: 0 hits);AGENTS.mdis shared prose, not aSINGLE_CLAIM_PATHSentry; #23180 (the spec lane's consumer of this script) is unclaimed and depends on this card, not the reverse.Generated by Claude Code
objectstack-fleet commentedon Oct 15, 2026
os-dev-report
{
"issue": 23534,
"status": "done",
"branch": "claude/issue-23534-test-budget-declaration",
"pr": "#23595",
"session": "session_01ESFcvW3staenyBCGq7kcDH",
"premise_still_valid": true,
"summary": "Script PR #23595 (draft, Fixes #23534, Clause-② no, skip-changeset, assignee huangyiirene):
--diffnow reads one header line// test-budget: SECONDS — CLASS: REASONfrom each test file its window read over 10 s and lists the file only above that budget. CLASS is one of the ruling's two phrases verbatim, SECONDS is a multiple of 10 above 10, and REASON is non-empty. A malformed, duplicate or below-header declaration refuses the diff (exit 1, names path:line); a file no longer in the tree stays under the 10 s line and is named. Tier H PR #23596 #23596 (draft, Refs #23534, Clause-② no, skip-changeset, assignee huangyiirene) adds the ruled phrase plus(ruling record 6181973363)to AGENTS.md line 129. It is +1 line, socheck:pm-skill-ratchetis RED: AGENTS.md is 1117 lines against a ceiling of 1116. That raise is outside the claimed file surface and is the maintainer's call; see open_questions[0]. PM assumptions: A1, A2, A3 and A5 hold. A4 is false as stated: there are 5 batteries, not 1. Counts measured on 70d4c06 were 56/11/14/14/22, all at their pins; this PR adds a sixth battery pinned at 14 and moves the floor from 5 to 6. A3 additionally found the annotation's self-test clause already false on main (the self-test indexes every package manifest); both halves are rewritten truthfully, and the derivation is unchanged (32 commands).","tests": "All on #23595 head 40215f6. (1)
node scripts/measure-test-shard-timings.mjs --self-testprintedmeasure-test-shard-timings: self-test OK, exit 0. An instrumented copy counted 56/11/14/14/22/14 registered cases against pins 56/11/14/14/22/14. (2) Real CLI on the real tree, synthetic captures: exit 0.packages/spec/scripts/build-schemas-check-mode.test.tsresolved and read (no declaration, so it is listed at 902.10 against 10 s). The missingsrc/nope-renamed.test.tswas namedno file at packages/spec/src/nope-renamed.test.ts in this checkout, and an unknown package was named. (3) Replica tree (symlinked scripts, --preserve-symlinks-main), spec files declared 1130 and 620: exit 0. build-schemas was held (902.10 s of its 1130 s) and not listed; check-liveness was listed at640.00 (declared 620). The same replica with the classwhole-packge importexited 1 with no body, stderrError: packages/spec/src/shared/alias-integrity.test.ts:2: the class \"whole-packge import\" is neither class the ruling names.(4) Ablation through scripts/ablation-replace.mjs: deleted the class-check line (anchor 1 -> 0, blob e224fd82 -> 0ea2558b). The self-test went RED, exit 1,budget: a class naming neither read as null. Restored withgit checkout HEAD --: blob e224fd82 matches HEAD,git diff HEADempty, self-test OK. No dist or build is involved (a plain .mjs). (5)pnpm exec eslint --no-inline-config scripts/measure-test-shard-timings.mjsexit 0 (--print-configresolves for the path).","gates": "#23595 at 40215f6:
dispatch-gates --commands --repo objectstack-ai/objectstackderived 32 commands off merge base 70d4c06, the same 32 as the dispatch lead. All ran, each exit captured before any pipe, and all 32 exited 0.pnpm check:pm-dispatch-gatesran detached (nohup, PID 6391, read after exit): EXIT=0,dispatch-gates self-test (fast tier): 1841 cases pass.--ran:32 derived famil(ies) accounted for — 32 run, 0 NOT-MEASURED (a DERIVED zero …). #23596 at e5de5ac: 15 derived off merge base 744b73f. 14 exited 0;pnpm check:pm-skill-ratchetexited 1:✗ check-skill-line-ratchet: AGENTS.md is 1117 lines; the ratchet ceiling is 1116.--ran:15 run, 0 NOT-MEASURED. CI check-runs at report time. #23595: success for Governed Surface Queue Guard, Check Changeset, Lint · repo & tooling gates, Type Check · workspace/source gates/debt ledger, Test Core 2-6/6, Dogfood Regression Gate, and Regenerate the shard-timings dataset (the refresh pull_request dry run, every step success; the --diff step's own exit is NOT MEASURED because its job log blob host is unreachable from this container). in_progress for Lint · ESLint/PM dispatch-gates/docs & code guards/CI, release & engine gates/scoped x3, Test Core 1/6 and Type Check · consumer gates. #23596: success for Governed Surface Queue Guard, Check Changeset, Test Core, Lint · PM dispatch-gates and scoped x3, Type Check · workspace/debt ledger; in_progress for Lint · repo & tooling gates (expected RED: it runs check:pm-skill-ratchet), ESLint, docs & code guards, CI/release/engine gates, and Type Check · source/consumer gates.","line_budget": {
"#23595": {
"additions": 358,
"deletions": 27,
"files": 1,
"note": "vs the ruling's ~60 estimate: self-test 180 (158 code, 22 comment; 14 cases); outside it 178 (118 code, 60 comment: grammar docblock, rewritten annotation, two section headers)"
},
"#23596": {
"additions": 2,
"deletions": 1,
"files": 1,
"note": "net +1 line; AGENTS.md 1116 -> 1117 against ceiling 1116"
}
},
"files_changed": [
"scripts/measure-test-shard-timings.mjs (#23595)",
"AGENTS.md (#23596)"
],
"deviations": [
"AGENTS.md PR is RED on check:pm-skill-ratchet (+1 line at headroom 0). Measured: a greedy rewrap at 96/97/100 bytes needs 4 lines for the 343-byte tail where 256 bytes took 3, and the ruled phrase cannot be shortened. Not fixed here: the ceiling lives in scripts/pm/check-skill-line-ratchet.mjs, outside the claimed surface, and a raise needs a maintainer ruling (open_questions[0]).",
"The rewritten dispatch-gates annotation also corrects its pre-existing false self-test clause ("reads no tracked file"; the self-test indexes the workspace manifests). This is the same line A3 ordered rewritten.",
"Two existing self-test assertions moved with the rendered text: the NOT MEASURED heading substring, and
{ packageDir: () => null }added to the existing CLI round trip so it stays off the tracked tree.","Commit trailers use AGENTS.md's model-free pair (
Claude-Session+Co-authored-by: Claude), not the harness reminder's model-named Co-Authored-By. PR bodies end with AGENTS.md's session-URL footer, not the harness footer. Both follow AGENTS.md precedence.","No env var value printed: existence only, via the
${X+x}form."],
"mcp_calls": "0 — no MCP GitHub tool called",
"api_writes": "5 — each one relay stroke (POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]): (1) pr_create -> POST /repos/objectstack-ai/objectstack/pulls (#23595, draft) + POST /repos//issues/23595/assignees; (2) pr_create -> POST /pulls (#23596, draft) + POST /issues/23596/assignees; (3) label-write -> POST /repos//issues/23595/labels [skip-changeset]; (4) label-write -> POST /issues/23596/labels [skip-changeset]; (5) comment -> POST /repos//issues/23534/comments (this os-dev-report). Read-backs: both bodies identical, byte for byte; both label sets match their targets. Also 4 git pushes, which are not REST writes.",
"open_questions": [
{
"question": "AGENTS.md has 0 line headroom (ceiling 1116), and ruling item 4's phrase cannot fit without +1 line. How does #23596 go green?",
"options": [
"A — The maintainer rules a raise of AGENTS.md's ceiling from 1116 to 1117 for this one sentence, quoting ruling 6181973363 item 4 ("one line, Tier H"). A seat then adds that one-row edit to scripts/pm/check-skill-line-ratchet.mjs CEILINGS on #23596's branch, with the reply quoted, per the ratchet's own "raise requires a maintainer ruling quoted in the PR" exit. Cost: 1 line, one more maintainer word, no new surface.",
"B — Pay with a one-line deletion of other AGENTS.md content in the same PR. Cost: a second, unrelated governed edit that the ruling never authorised; no candidate line in this paragraph is deletable without changing ruled text.",
"C — Leave #23596 red. Cost: a required check (Lint & Repo Gates) blocks the merge, and AGENTS.md keeps telling agents the 10 s line binds files the script already exempts."
],
"recommendation": "A. Business need: the ruling ordered this sentence, and the overflow is measured, not chosen. Long-term soundness: the ratchet prices a raise as a quoted ruling, as its four prior AGENTS.md raises were. AI error-proofing: a rule file that disagrees with the script invites agents to "fix" over-10 s declared files by weakening them, the very incentive the ruling removed. Startup focus: +1 line, nothing else. The #23596 body already asks the maintainer this in 你要做的."
},
{
"question": "SETTLED (no answer needed unless you disagree): the class spellings.",
"options": [
"A — The ruling's two phrases verbatim: "spawns the real producer once per single-cause fixture", "whole-package import".",
"B — Short slugs such as producer-per-fixture."
],
"recommendation": "A, done. The declaration reads as the ruling, so a reviewer checks it against the ruling text, not a mapping. The refusal prints both phrases, so a typo carries its own remedy. It adds no second vocabulary."
},
{
"question": "SETTLED: the granularity of a refusal. A malformed declaration refuses the whole --diff (exit 1, and the workflow quotes the stderr in place of the regression section) rather than only the per-file half.",
"options": [
"A — Whole refusal, the file's existing refusal convention and the path the dispatch's A5 named.",
"B — Per-file NOT MEASURED with the rises kept, exit 0."
],
"recommendation": "A, done: the loudest form, one refusal path, least code. Its cost, stated: one bad header line in any test file the window has over 10 s blanks that week's rise readings too. The refusal names path:line, so the fix card is one line in the owning lane. Only over-10 s files are read, so a malformed line in a fast file never fires."
},
{
"question": "SETTLED: a captured file that is no longer at its path, or an unknown package. The 10 s line holds, the file is listed if over it, and the body names it under "No budget declaration could be read".",
"options": [
"A — The 10 s line holds, and the file is named.",
"B — Refuse the diff.",
"C — Skip the file."
],
"recommendation": "A, done. B would cost the whole week's readings for a rename between window and refresh. C would be the silent exemption the dispatch forbids."
}
],
"out_of_scope_findings": [
"carrier: none · noted in #23595 Acceptance notes, not filed: shard-timings-refresh.yml header prose (lines 178-181, 190-191) still says "every test file over 10 s of wall"; it is a description only, and a governed .github/workflows/** edit; dedupe words: shard-timings-refresh header, per-file budget prose, test-budget declaration, 10 s line",
"carrier: none · noted, not filed: the measure-test-shard-timings.mjs self-test docblock says "This file declares ONE battery" (stale since earlier batteries; now six)",
"carrier: none · noted, not filed: scripts/ci/select-shard-timings-run.mjs --self-test spawns the real --diff with fixture package @objectstack/a, which now reads the workspace index to find no declaration (assertions unchanged, passed)",
"carrier: none · noted, not filed: a declaration is parsed only by the weekly refresh (no PR-time parse; no new gate by default); #23595 gives the spec lane a local one-liner around the exported readTestBudget"
]
}
objectstack-fleet commentedon Oct 15, 2026
Review pointers ·
domain:devxseat 1 ·session_01ESFcvW3staenyBCGq7kcDH· 2026-10-15T03:18Z (report6183503537)Test Core (1/6)concludes on head40215f6c).AGENTS.mdsentence, ruling item 4; draft,needs-user-decision, reviews requested fromos-zhuangandhotlong). It is red oncheck:pm-skill-ratchet(AGENTS.md1117 lines against a ceiling of 1116), and its landing waits on the maintainer's word on that ceiling plus an authorized approval. Per the ruling, this card closes on PR feat(scripts): a test file of either ruled class is listed over its own declared budget, not the 10 s line #23595 and theAGENTS.mdline's landing is noted here when it happens.Generated by Claude Code
feat(scripts): a test file of either ruled class is listed over its o…
objectstack-fleet commentedon Oct 15, 2026
Landed: PR #23595 →
16abea884(Fixes #23534) ·domain:devxseat 1 ·session_01ESFcvW3staenyBCGq7kcDH· 2026-10-15T03:33ZGET /pulls/23595merged: trueat 03:32:06Z,merge_commit_sha16abea884git ls-remote origin refs/heads/gh-readonly-queue/main/pr-23595*origin/maingit merge-base --is-ancestor 16abea884 origin/mainexport function readTestBudgetis inscripts/measure-test-shard-timings.mjsthere (1 hit)GET /issues/23534closed/completedat 03:32:07Z, on the mergeopen, so no card was closed by mistakeState change: this act removes
pm:dispatched.Still open from this ruling: the
AGENTS.mdsentence (item 4) is PR #23596, Tier H, draft. It is red oncheck:pm-skill-ratchetat the 1116-line ceiling and waits on the maintainer's word on that ceiling plus an authorized approval (seat record6183585588). Its landing will be noted here.Next reader: the spec lane on #23180 (item 5). The script now reads the declarations, so the cross-lane note goes there.
Generated by Claude Code
objectstack-fleet commentedon Oct 15, 2026
File-surface addendum to claim
6183044862·domain:devxseat 1 ·session_01ESFcvW3staenyBCGq7kcDH· 2026-10-15T03:58Zclaude/issue-23534-agents-md-budget-line) also takes one row inscripts/pm/check-skill-line-ratchet.mjs. The change isCEILINGS['AGENTS.md', 1116]→1117, with its comment block.6184004601.domain:skillssurface, so the cross-lane note goes on the skills seat post with the push.Generated by Claude Code
objectstack-fleet commentedon Oct 15, 2026
os-dev-report
{
"issue": 23534,
"status": "done",
"branch": "claude/issue-23534-agents-md-budget-line",
"pr": "#23596",
"session": "session_01ESFcvW3staenyBCGq7kcDH",
"premise_still_valid": true,
"summary": "Patch round on PR #23596 only. The CEILINGS line-count row
['AGENTS.md', 1116]in scripts/pm/check-skill-line-ratchet.mjs is now 1117, with a comment block in the map's own convention above it. The block names card #23534 and PR #23596, says the sentence was bought by CONTENT and that the rewrap was measured, and quotes 「A 上限抬到 1117 (Recommended)」 verbatim, recorded at PR #23596 comment 6184004601. The width row['AGENTS.md', 768]is untouched. New head 93709a2 (commit 93709a2), pushed plain on top of e5de5ac; no merge of main was needed (GitHub: mergeable true, mergeable_state clean). Not touched: the PR body, the draft flag, reviewers and auto-merge. No claim posted: the newestClaim:on #23534 is still 6183044862, and the seat declares the file-surface addendum.","tests": "
pnpm check:pm-skill-ratchetexit 0 at 93709a2 (it runs --self-test then the scan):✓ check-skill-line-ratchet self-test: 157 cases pass.and✓ check-skill-line-ratchet: AGENTS.md is 1117 lines (ceiling 1117; headroom 0).Before this push, e5de5ac exited 1 withAGENTS.md is 1117 lines; the ratchet ceiling is 1116.pnpm check:pm-skill-id-lintexit 0:✓ check-skill-id-lint self-test: 23 cases pass./87 file(s) clean.pnpm check:nul-bytesexit 0:75 assertions/no raw ASCII control bytes. A manual control-byte grep of the edited file found nothing.","gates": "
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackon the branch derived 35 commands from 2 paths (AGENTS.md, scripts/pm/check-skill-line-ratchet.mjs; +10/-2) off merge base 744b73f. It warned of a STALE TREE: 6 commits behind origin/main, and the stale file was scripts/measure-test-shard-timings.mjs. Re-deriving the same 2 paths in a detached worktree at origin/main 16abea8 gave an identical 35-line list (diff exit 0). All 35 ran at 93709a2 with exits captured before any pipe, and all 35 exited 0.pnpm check:pm-dispatch-gatesran detached (PID 5902, waited on with tail --pid): EXIT=0,1841 cases pass.--ran:✓ dispatch-gates --ran: 35 derived famil(ies) accounted for — 35 run, 0 NOT-MEASURED (a DERIVED zero …). CI on 93709a2 at report time, all success: Lint & Repo Gates, TypeScript Type Check, Test Core, Governed Surface Queue Guard, every Lint · lane (repo & tooling gates included), Type Check · workspace/source/consumer/debt ledger, Test Core 1-6/6, and Dogfood Regression Gate.","line_budget": {
"#23596": {
"additions": 10,
"deletions": 2,
"files": 2,
"note": "this round +8/-1 in scripts/pm/check-skill-line-ratchet.mjs; the earlier AGENTS.md commit +2/-1"
}
},
"files_changed": [
"scripts/pm/check-skill-line-ratchet.mjs (#23596, this round)",
"AGENTS.md (#23596, earlier round)"
],
"deviations": [
"The recorded worktree had been removed after round 1 (cleanup rule). It was recreated from origin/claude/issue-23534-agents-md-budget-line at e5de5ac, the remote head, and removed again after the gates.",
"The commit message body quotes the ruling and names PR #23596 comment 6184004601. Its trailers are the model-free pair only, with no card trailer."
],
"mcp_calls": "0 — no MCP GitHub tool called",
"api_writes": "1 — relay stroke (POST /repos/objectstack-ai/objectstack/dispatches as objectstack-fleet[bot]) -> comment: POST /repos//issues/23534/comments (this os-dev-report). Also 1 plain git push e5de5ac..93709a2, which is not a REST write.",
"open_questions": [],
"out_of_scope_findings": []
}
objectstack-fleet commentedon Oct 15, 2026
Landed: the
AGENTS.mdsentence, PR #23596 →8d05456cb(ruling item 4) ·domain:devxseat 1 ·session_01ESFcvW3staenyBCGq7kcDH· 2026-10-15T04:17ZGET /pulls/23596merged: trueat 04:16:44Z,merge_commit_sha8d05456cbgit ls-remote origin refs/heads/gh-readonly-queue/main/pr-23596*origin/maingit merge-base --is-ancestor 8d05456cb origin/mainAGENTS.mdcarries "unless the file declares a …" (1 hit) at 1117 lines; the ratchet's['AGENTS.md', 1117](1 hit)os-zhuangreview5527773337; ceiling ruling 「A 上限抬到 1117 (Recommended)」 at PR #23596 comment6184004601, quoted in the PR bodyRefs, no closing keyword); #23606 stays open in the decision boxState change: this act removes
needs-user-decisionfrom PR #23596; it was approved and has merged.Ruling
6181973363status:main: the script in PR feat(scripts): a test file of either ruled class is listed over its own declared budget, not the 10 s line #23595, the sentence in PR docs(agents): a test file that declares a measured budget with its class is held to that budget, not the 10 s line #23596.6183798001).Generated by Claude Code