You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ci(test-shards): Test Core's two slowest shards set every core PR's wall clock at ~28 min (5.6 min dependency build + ~20 min tests) while the other six finish in 7–17 — re-derive the cli slicing and shard balance on post-merge readings #25870
Ruled: 6439314592 · letter A (re-ruled from B, 6435350063) · 2026-10-27T10:22Z
Filing gate ③ (maintainer-directed). Maintainer, 2026-10-26 01:45Z, in the project thread that measured post-merge CI speed: 「创建issue」 (asked after reading the ranked fix list; this is item 5, the largest wall-clock lever).
谁付代价(业务筛): every PR that touches a core package waits for the slowest Test Core shard, and so does every core merge-queue entry. The ui/ merge did not change this (core PRs were 28–29 min before and ~31 min after), but it is now the floor that every core PR and queue entry pays.
Measured (pull_request runs, 2026-10-25/26)
run
slowest shards
other shards
40211990811
5/8 27.6 min, 4/8 18.2
8.4–17.0
40211391950
4/8 28.1, 5/8 27.4
7.7–17.1
40219925686
5/8 27.8, 4/8 27.3, 3/8 25.3
7.5–16.8
40248884869
4/8 29.6, 5/8 23.4
7.3–17.8
On the long shards, "Build this shard's dependencies" takes 5.3–5.8 min and "Run this shard's tests" 20–22 min. On the short ones the build is 0.3–0.9 min.
The merged timing table from run 40248884869: @objectstack/cli 2542 s summed over its 3 slices (pinned 2899 s), and the slowest files are all cli integration files (data-commands.absent-database.integration.test.ts 364 s, stack-conversion-record-door.test.ts 330 s, …). Many other packages run at 0.35–0.6× their pinned weight (objectql 0.35×, metadata-protocol 0.52×), so the dataset over-weights them and under-fills other legs.
Wanted
Find out what makes 3/8–5/8 long: the cli slices, the dependency closure they build (5.6 min against <1 min elsewhere), or stale weights.
Then do the cheapest of: refresh the weights, re-derive the cli slice count, or pre-build the shared closure once.
⛔ No test skipped or quarantined, and no timeout raised to make it fit.
Acceptance
Slowest Test Core shard ≤ ~20 min on 3 consecutive pull_request runs that touch packages/spec. Readings go on the card.
Expected saving: ~8 min wall clock per core PR and per core queue entry. Size: M. Clause-②: no. Metadata-protocol: none.
Dedupe
search_issues 2026-10-26 01:50Z 「Test Core shard long pole 4/8 5/8 rebalance shard timings wall clock」: 11 hits, all closed. Earlier rounds of the same shape: #22075, #25376 (6→8 shards), #25390 (cli slice refresh), #21758, #16173. Nothing open. New.
{
"issue": 25870,
"status": "done",
"branch": "claude/project-thread-lbjl7f",
"pr": "https://github.com/objectstack-ai/objectstack/pull/26186",
"session": "session_01CLvWYcHLpbpu8X8PvozD7F (card thread, retry after the #26077 revert)",
"premise_still_valid": true,
"summary": "Implements the replayed lowest-risk candidate and nothing more: plain-sum placement unchanged, the 2026-10-26 dataset (byte-identical to f36f6190), cli x4 with PREVIOUS_FILE_SHARDED_PACKAGES {cli:3}, and self-test pin 3d (WHOLE_LEG_CAP_SECONDS = 1868, the heaviest whole leg the queue ran green; LOAD_SENSITIVE_APART = objectql + plugin-security). planRun() on the full turbo ls list: whole-package shards 1499/1501/1501/1500s (main: 1866-1868s), slice shards 826-827s whole + 674s slice (wall-model step 959s vs 1276s), objectql 7/8 and plugin-security 6/8. Part of #25870: the card closes only on the after-landing reading (10 full merge-queue Test Core builds, no load-shaped red).",
"tests": "partition-test-shards --self-test OK (bins 1499-1501s, whole legs 1499/1501/826/827/826/826/1501/1500s within 1868s, cli x4). Ablation 1: #25968 load-based partition() restored + pin 2 disabled -> pin 3d reds: shards 5-8/8 at 2141/2139/2141/2142s past 1868s, and objectql + plugin-security share 7/8; file restored, cmp clean. Ablation 2: cli x3 on the refreshed dataset -> pin 3c reds (899s > 871s, Raise it to 4); restored, cmp clean. Sibling self-tests green: measure-test-shard-timings, check-test-completeness, ci/select-shard-timings-run, ci/select-shard-packages.selftest.sh (32 cases).",
"gates": "dispatch-gates --commands at merge base 365fe5ec: 35 families, all exit 0; --ran: 35 derived, 35 run, 0 NOT-MEASURED. check-commit-card-trailers --range origin/main..HEAD pass. Serial: none of the 36 other open PRs touches scripts/partition-test-shards.mjs or scripts/test-shard-timings.json (git diff --name-only per pull head). CI families: read from PR #26186 check-runs.",
"dogfood_battery": "n/a - no ! in the PR title and no (narrowing) arm",
"mcp_calls": "read-only: issue_read x1, list_pull_requests x1, pull_request_read x1; 0 writes",
"api_writes": "2 relay strokes: pr_create (#26186, assignee os-elon-musk, label skip-changeset); this comment + pr_request_reviewers (os-elon-musk)",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none - ci.yml Test Core comments still say 3 slices; Tier H, left (PR Acceptance notes)",
"carrier: none - pin 3d grades the full list only; partial-list runs can still co-locate the pair on lighter shards, as on the green layout (PR Acceptance notes)"
]
}
After-landing reading for #26186: 10 full Test Core queue builds, 0 red
#26186 merged at 2026-10-26 18:02Z. I read it at 00:45Z over REST: every merge_group run of ci.yml created from 17:43Z on, which is the run for #26186's own group and everything queued on top of it.
All queue builds: 96 completed runs, 96 green. No job in any of them failed, no run was re-attempted, and no entry was ejected by Test Core. Two more were still in progress at read time.
The first 10 full builds
A build counts as full here when two things hold. First, at least 6 of its 8 Test Core shards ran 10 minutes or more. Second, the aggregator's suite list shows objectql, plugin-security and all 4 cli slices executed. The ratios below are each suite's measured wall against its suite-duration ceiling, from the aggregator's report-only check.
One standing over-ceiling reading, which is report-only:@objectstack/service-package reads 33–77 s against a 32.90 s ceiling (1.1–2.3x) on 26 of the 29 heavy builds. It was already over on the old layout before this PR: 47.89 s on 40325660507 and 46.97 s on 40327508710 (about 1.45x). Its suite gained a hydration test file in feat(install): a declared dependency co-owns its parent's namespace, and both boot hydrates sort by it (ADR-0141 D5) #26054 at 10:42Z, and its ceiling is the 10-26 refresh's figure. The check reports and does not fail. I'm noting it here and not filing it.
Slowest spec-touching pull_request shard (for information, not the gate)
The slowest spec-PR shard is 23.9–25.4 min on 8 of these 10 runs. The outliers are 20.7 and 29.2. Before #25968 the range was 25.7–28.8, so this is about 2–4 min faster. It does not reach the original ≤ ~20 min goal. The slowest shard is always a CLI-slice shard: setup, then the cold DTS closure (~6 min), then ~5 min of whole packages, then a slice. The step model's prediction of 959 s plus the closure and setup gives about 23.5 min, which is what these runs read. #26138's earlier run 40377181895 was red on cli slices 4/8 and 6/8. That red was a real assertion in that PR's own CLI change (audit-mail-bodies.archive.integration.test.ts › "a declared archive this boot cannot connect is NOT reported clean", 1 ms, not a timeout), and the PR's next run was green.
For the seat: the acceptance gate (no load-shaped red in the queue) holds. The speed goal is still open. What is left on a slice shard is the DTS closure plus the slice, which brings option B (DTS only on the slice that reads .d.ts, Tier H, ci.yml) or option C (weight-balanced CLI slices) from the earlier report back on the table. Choosing between them is the seat's or the maintainer's call. I have not taken either.
Release: session_01LKHDniRQSWjRJyDtacwpEd (devx seat 1) · seat signs off on the maintainer's word 「当前任务处理完,合并后就下班」 (2026-10-27 01:20Z) · next: needs-user-decision, close or follow-up B/C
PR #26186 landed on 2026-10-26 18:02Z. Its acceptance is met: 96/96 queue CI runs were green, and the first 10 full builds had no load-shaped red (reading 6430866969). The card's original speed goal is not met. The slowest spec-PR shard runs 23.9–25.4 min against the ≤ ~20 min goal; what remains is the cold DTS closure (~6 min) plus a CLI slice.
Question for the maintainer (the seat recommends option 1):
Close this card as completed, and re-file it if the spec-PR wall becomes a problem.
Option C: rebalance the CLI slices by weight. Measure first. No ci.yml edit, not Tier H.
Option B: build DTS only on the slice that reads .d.ts. This edits ci.yml, so it is Tier H and needs a governed approver.
Director seat, summon #51 continuation (ledger objectstack#12708). Presented to the maintainer in batch #408 as item 4 of 5 — the devx seat's question in 6433447870 after PR #26186 landed. Seat increment (re-read 2026-10-27T04:45Z; the after-landing reading 6430866969 is not restated):
Acceptance half met: 96/96 queue Test Core builds green since landing, no load-shaped red. Speed goal unmet: the slowest spec-PR shard reads 23.9–25.4 min on 8 of 10 runs against the ≤ ~20 min goal; what remains on a slice shard is the cold DTS closure (~6 min) plus a CLI slice; the slices themselves are balanced (826–827 s each).
Half-state: needs-user-decision alone; the ruling's stroke closes the card (1) or returns it to pm:queue (B/C).
Facets (seat's reading): ① the lever is known and specific (one build step that every slice pays but only one slice reads); ② every core PR and queue entry pays ~6 min of it, dozens a day; ③ B changes a build step, not a test — a mistake reds loudly at build; ④ B is a ci.yml edit (Tier H), not a gate; C is measurement with no ci.yml edit.
Ruling: batch #408 item 4 · letter B · maintainer 「批 #408 同意」 2026-10-27T06:26Z
Recorded by the director seat (summon #51 continuation, session_01KrKXQVvgYk2AJ4VkqMobyb, ledger objectstack#12708). The maintainer answered batch #408 with 「批 #408 同意」 — every seat letter. Brief 6433979362; the devx release 6433447870 asked the question. Letter B: the cold DTS closure is built only on the CLI slice that reads .d.ts; the other slices skip it. C's measurement (the per-slice before/after wall and the suite ratios) rides the same PR body as the reading; the card closes on three consecutive spec-touching pull_request runs with the slowest Test Core shard ≤ ~20 min, as the card's acceptance says, or on the maintainer's word that the measured saving is enough. Not 1 (the goal is unmet and the lever is known) and not C alone (the slices are balanced at 826–827 s; the ~6 min is the closure).
Workload: devx · 1 Tier H PR (.github/workflows/ci.yml, lands by the maintainer's approval) · S; ⛔ no test skipped or quarantined, no timeout raised (the card's own line).
Execution: needs-user-decision → pm:queue in this act (domain:devx, p2). Ruling-ref: names this comment. Clause-②: no, Metadata-protocol: none.
Claim: PM loop round 11 · 2026-10-27T07:25Z
Session: session_01Q4MDXRbEJCNdPAP4SiXwp9 (devx seat 2) · card thread cmsg_01FdL1XeUyvVNxLreh3F4Qi97ymecxbJozWc9XMZjBfknn
Account: os-steve
Branch: claude/project-thread-o6kgnu (the harness-pinned branch of the card thread; it names no issue, so this claim is the identity record; amended on spawn)
Worktree: objectstack-issue-25870
Domain: domain:devx
Seat: domain:devx#2 (seat post #20163)
File surface: .github/workflows/ci.yml, the Test Core job only: the "Declarations skipped" step (DTS_READERS / OS_SKIP_DTS) and, if the slice must be named there, the closure build step. Per ruling B the cold DTS closure is built only on the CLI slice whose tests read .d.ts; every other slice, CLI slices included, sets OS_SKIP_DTS=1. scripts/partition-test-shards.mjs and its self-test only if the slice that reads .d.ts cannot be named from the workflow alone. ⛔ No test skipped or quarantined, no timeout raised, no shard count or weight change. ⛔ No other job of ci.yml. The PR is Tier H (.github/workflows/**): draft until a GOVERNED_APPROVERS approval
Container & model: M, mode:thread, model: default tier (TIER_DEFAULT, from dispatch-gates --tier: no path-derived mandate), effort: medium
Clause-②: no
Metadata-protocol: none
Ruling-ref: 6435350063
Responsibility: n/a — maintainer-directed filing (「创建issue」, 2026-10-26); ruled B at 6435350063
Thread-read: 6435350063
Premise: on origin/main, every Test Core shard that carries any @objectstack/cli slice builds the DTS closure (DTS_READERS='@objectstack/cli @objectstack/metadata'), and only one CLI slice's tests read .d.ts (the dev confirms which, on origin/main, before changing anything)
Serial constraints cleared: no open PR edits .github/workflows/ci.yml (read 07:30Z over the 21 open PRs); #26529 (this seat) edits test-nightly-tiers.yml and shard-timings-refresh.yml only
{
"issue": 25870,
"status": "needs_decision",
"branch": "claude/project-thread-o6kgnu",
"pr": null,
"session": "session_01ADHkmPfbyqbnLkfPfz7Uan (card thread V, dispatched by devx seat 2 session_01Q4MDXRbEJCNdPAP4SiXwp9)",
"premise_still_valid": false,
"summary": "Premise false on origin/main f486e9c1: every one of the 4 CLI slices holds a test that reads built .d.ts, so ruling B as worded (DTS closure only on the one CLI slice that reads .d.ts) has no slice to drop DTS from and saves 0 min. Measured: the whole cli suite on an OS_SKIP_DTS=1 closure goes red in exactly 5 of 514 files, all declaration-caused (TS7016 on @objectstack/spec/* dist, ENOENT on cli dist/*.d.ts): published-subpath-console.pin, scaffold-test-script-passes (slice 1/4), create-in-repo-scaffold-typechecks (2/4, not in the ci.yml 830a63a list), scaffold-emission-typechecks (3/4), published-subpath-hook-body.pin (4/4). Slice membership is vitest's own BaseSequencer.shard (sha1 of the relative path, equal-count ranges) run on packages/cli's real config, so any added or removed cli test file moves the cut points: a static 'cli k/4' name in ci.yml is wrong by construction. No file changed, no PR opened; the decision on how to reach ruling B's intent is the seat's (open_questions).",
"tests": "f486e9c1. (1) OS_SKIP_DTS=1 turbo build --filter=@objectstack/cli --filter=@objectstack/metadata: 61/61 tasks, 1m43s, 0 .d.ts under packages/spec/dist and packages/cli/dist. (2) Whole cli suite on that closure (vitest run, unit+integration, maxWorkers=3, under os-verify-lock): VERDICT command-exit 1; Test Files 5 failed | 508 passed | 1 skipped (514); Tests 25 failed | 6379 passed | 9 skipped (6413). The 5 files and their first error lines are in the summary. (3) Control leg, same tree with declarations: turbo build --filter=@objectstack/cli 61/61 tasks 7m04s (shared box), then the same 5 files: VERDICT command-exit 0, Test Files 5 passed (5), Tests 56 passed (56). (4) Slice map: vitest createVitest + config.sequence.sequencer.shard() over globTestSpecifications() in packages/cli with OS_TEST_SHARD=k/4: 129/129/128/128 of 514 files; readers 1/4: 2 files, 2/4: 1, 3/4: 1, 4/4: 1. (5) Shard map, full turbo ls list replayed through partition-test-shards.mjs --shard k/8 --exclude @objectstack/dogfood: cli 1/4..4/4 on shards 3..6, @objectstack/metadata on 7, so 5 of 8 shards keep DTS. CI agrees: pull_request run 40423632426 (spec-touching, PR #26343) 'Build this shard's dependency closure' 4.2/4.4/5.8/5.3/5.5 min on shards 3-7 against 0.5-0.9 on 1, 2, 8; slowest Test Core (5/8) = cli 3/4, 25.1 min.",
"gates": "No diff, so no derived family: dispatch-gates --commands not run (it derives from the changed set, which is empty). NOT MEASURED: every CI family, reason: no PR.",
"dogfood_battery": "n/a - no PR",
"mcp_calls": "5 - read only: issue_read x3 (get, get_comments x2), actions_list x1 (list_workflow_jobs 40423632426), get_job_logs x1 (job 121924032523); 0 writes",
"api_writes": "1 - this os-dev-report comment (post-stamped, relay)",
"open_questions": [
{
"question": "Ruling B's wording has no slice to act on (all 4 CLI slices read .d.ts). Which route carries its intent, the cold DTS closure on one CLI slice only?",
"options": [
"A Pin the declaration readers to one fixed slice: a sequencer in packages/cli/vitest.config.ts sends a declared reader list to slice 1/n and sha1-splits the rest; ci.yml keeps DTS only for '@objectstack/cli 1/4' (plus metadata); partition-test-shards charges that slice the closure cost (~4.5 min) so its shard carries less whole-package work. Facets (brief 6433979362): (1) lever specific, 3 slice shards drop ~4.5 min of closure each; (2) every spec PR and queue entry; (3) a reader missing from the list reds loudly with TS7016 on a skipping slice, as today; (4) Tier H (ci.yml) and widens the file surface to packages/cli/vitest.config.ts and partition-test-shards.mjs + self-test. Without the partition charge the reader shard stays ~23-25 min and the slowest shard does not move. Risk: the other 509 cli files re-split, so load-sensitive neighbours shift (the #25968 revert); read the queue red rate after landing. Size M.",
"B Implement the ruling literally: decide per slice in ci.yml from vitest's own shard of the reader list. Saves 0 min today (every slice holds a reader). Not worth a Tier H PR.",
"C Move the 5 cli readers and metadata's typescript-serializer-annotation to a job that already builds declarations (Build Core), and set OS_SKIP_DTS=1 on every Test Core shard: 5 shards drop ~4.5 min, slowest ~20-21 min with no partition change. It takes tests out of the required Test Core context, which the card's no-skip/no-quarantine line forbids without the maintainer's word, and edits a second ci.yml job.",
"D Close on the current reading (slowest spec-PR shard 23.9-25.4 min) by the maintainer's word, as the ruling allows."
],
"recommendation": "A, because it is the only route that keeps every test in Test Core and still gives the intent of B: declarations on exactly one CLI slice, by a membership the package declares instead of a sha1 accident. The partition charge is what makes it reach ~20 min. Measure the readers' slice weight before landing."
}
],
"out_of_scope_findings": [
"carrier: #25870 - the ci.yml 'Choose this shard's declaration build' comment lists the cli DTS readers measured on 830a63a; it misses create-in-repo-scaffold-typechecks, which now also reds without declarations. Fix rides whichever route is chosen (Tier H text)."
]
}
Seat domain:devx#2 (#20163) · session_01Q4MDXRbEJCNdPAP4SiXwp9. Thread-read: 6436965718. The card thread measured on f486e9c1 (report 6436965718) and opened no PR.
Every CLI slice has a reader. On a closure built with OS_SKIP_DTS=1, the whole cli suite reds in exactly 5 of 514 files, all for missing declarations. The control leg with declarations is 5/5 files, 56/56 tests green. Using vitest's own sequencer.shard on the real packages/cli config, the five readers land in all four slices (1/4: 2, 2/4: 1, 3/4: 1, 4/4: 1).
So ruling B as worded saves 0 minutes. There is no CLI slice that could skip the closure. The cut points are sha1 ranges, so any added or removed cli test file moves them; a static cli k/4 in ci.yml would be wrong by construction.
CI agrees: on run 40423632426 (spec-touching), the closure build takes 4.2–5.8 min on shards 3–7 (cli 1/4–4/4 and metadata) against 0.5–0.9 min on 1, 2 and 8. The slowest shard, 5/8 (cli 3/4), took 25.1 min.
Ways to reach the ruling's goal. Each is the maintainer's call, because each goes past what B ruled:
A (seat's recommendation): add a sequencer to packages/cli/vitest.config.ts that pins the five reader files into slice 1/n. ci.yml then keeps the closure only for cli 1/n and metadata, and partition-test-shards counts the ~4.5 min closure into that slice's weight. Three shards stop building the closure; the slowest shard should come down toward ~20 min (to be measured on the PR). The surface widens to the cli vitest config (cli is domain:server's package) and the partition script; still one Tier H PR.
B as worded: saves nothing.
C: move the five reader tests out of Test Core. This changes where tests run and needs the maintainer.
D: close the card on this reading.
The card is marked needs-user-decision and stays claimed; the thread waits for the answer.
Release: session_01Q4MDXRbEJCNdPAP4SiXwp9 (devx seat 2) · seat signs off on the maintainer's word 「devx 车道当前任务处理完就下班」 (2026-10-27 08:42Z) · next: needs-user-decision on 6436991767 (A / C / D; the seat recommends A)
The card thread measured that ruling B's premise is false: the five .d.ts readers sit in all four CLI slices, so B as worded saves 0 minutes (report 6436965718). No PR was opened. The thread branch claude/project-thread-o6kgnu holds no changes. A dispatch after the ruling starts from 6436991767.
Director seat, summon #51 continuation (ledger objectstack#12708). Presented to the maintainer in batch #411 as item 3 of 3 — a re-ruling: ruling B (6435350063, batch #408) has no slice to act on. Seat increment (the dev report 6436965718 and the seat reading 6436991767 are not restated):
The premise the seat's B rested on ("only one CLI slice reads .d.ts") is false on origin/mainf486e9c1: five cli test files read built declarations and vitest's sha1 sharding scatters them across all four slices (1/4: 2, 2/4: 1, 3/4: 1, 4/4: 1); with OS_SKIP_DTS=1 exactly those 5 of 514 files go red, all declaration-caused. B as worded saves 0 min. The seat's recommendation in batch Fix duplicate property in logger config object #408 was wrong on this fact; the dev measured it before changing anything, as the claim ordered.
The intent of B (declarations on exactly one CLI slice) is reachable by the dev's A: a sequencer in packages/cli/vitest.config.ts pins the declared reader files into slice 1/n, ci.yml keeps the closure for cli 1/n and metadata only, and partition-test-shards charges that slice the ~4.5 min closure so its shard carries less whole-package work. Three shards drop the closure; expected slowest shard toward ~20 min, measured on the PR. Surface: ci.yml (Tier H) + the cli vitest config (domain:server's package) + the partition script and self-test. Risk named by the dev: the other 509 cli files re-split, so load-sensitive neighbours move (the ci(test-shards): place Test Core bins by predicted wall, and cut the CLI into 4 slices on the refreshed dataset #25968 class) — the PR's after-landing reading must repeat 6430866969's 10-build check.
C moves the five reader tests into Build Core and skips declarations on every Test Core shard: ~20–21 min with no partition change, but it takes tests out of the required Test Core context, which the card's own ⛔ line forbids without the maintainer's word. D closes the card on the current reading (23.9–25.4 min).
Half-state: needs-user-decision with the thread's claim still held (pm:dispatched was lifted by the seat's release 6438053721 → the card shows needs-user-decision alone).
Facets (seat's reading): ① A keeps every test in Test Core and makes reader membership a declared fact of the package instead of a sha1 accident; ② every spec-touching PR and queue entry pays the closure on three shards today; ③ a reader missing from the declared list reds loudly (TS7016) on a skipping slice; ④ Tier H plus two more files, no gate.
Ruling: batch #411 item 3 · re-ruled B → A · maintainer 「26583 A 25870 A」 2026-10-27T10:20Z
Recorded by the director seat (summon #51 continuation, session_01KrKXQVvgYk2AJ4VkqMobyb, ledger objectstack#12708). The maintainer answered batch #411 with 「26583 A 25870 A」. Brief 6439158762; the card thread's measurement 6436965718 and the seat reading 6436991767 showed ruling B (6435350063) had no slice to act on — the five .d.ts readers sit in all four CLI slices by vitest's sha1 sharding, so B as worded saved 0 min. Letter A, as the dev specified: a sequencer in packages/cli/vitest.config.ts pins the declared reader files (the five measured on f486e9c1, plus any the dev finds) into slice 1/n; ci.yml keeps the cold DTS closure for cli 1/n and metadata only, every other slice sets OS_SKIP_DTS=1; scripts/partition-test-shards.mjs charges that slice the ~4.5 min closure so its shard carries less whole-package work; the "Choose this shard's declaration build" comment in ci.yml is corrected (it misses create-in-repo-scaffold-typechecks). ⛔ No test skipped or quarantined, no timeout raised, no test moved out of Test Core (not C), no shard-count change. Not D: the lever is known and measured.
Workload: devx + server (the cli vitest config is domain:server's package) · 1 Tier H PR (.github/workflows/ci.yml, lands by the maintainer's approval) · M. Acceptance stays the card's: the slowest Test Core shard ≤ ~20 min on three consecutive spec-touching pull_request runs, measured on the PR; after landing, the 10-full-queue-build reading of 6430866969 is repeated before the card closes, because the other 509 cli files re-split and load-sensitive neighbours move (the #25968 / #26077 class).
Execution: needs-user-decision → pm:queue in this act (domain:devx, p2); the devx seat re-dispatches from 6436991767's A. Ruling-ref: names this comment; 6435350063 is superseded. Clause-②: no, Metadata-protocol: none.
Claim: PM loop round 5 · 2026-10-27T13:14Z
Session: session_01JQwxbaFpnMwgpCgneKe2qS
Account: os-warren (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/project-thread-ervpst (platform exception: this seat's container pushes only its own claude/project-thread-* branch). The dev builds in its own worktree off origin/main now and pushes only after the branch's open #26586 PR has merged
Worktree: objectstack-issue-25870
Domain: domain:devx
Seat: domain:devx#1
File surface: ruling A (6439314592) as the dev specified it in 6436991767: a sequencer in packages/cli/vitest.config.ts (a domain:server package, named in the ruling's workload) that pins the declaration-reading test files into slice 1/n; .github/workflows/ci.yml, the Test Core job's declaration-build choice only (closure kept for cli 1/n and metadata, OS_SKIP_DTS=1 elsewhere) plus the "Choose this shard's declaration build" comment; scripts/partition-test-shards.mjs and its self-test, charging that slice the closure. ⛔ No test skipped or quarantined, no timeout raised, no test moved out of Test Core, no shard-count change, no other ci.yml job (stop on breach)
Landing: Tier H (.github/workflows/**). ⛔ No pr_create until the contract review and the seat's ACCEPT are both on record, because the relay's pr_create requests GOVERNED_APPROVERS on a Tier H diff at once (#26617). The ceiling tier is out of quota here, so the contract review waits for the director seat. Then the PR is draft until a GOVERNED_APPROVERS approval
Container & model: M, mode:subagent (in-seat and serial instead of a card thread: the account's 7-day usage reads allowed_warning, so the seat opens no new card thread, coordinator.md §六), model: default (no path-derived mandate, default opus; quota exemption), effort: high
Clause-②: no
Metadata-protocol: none
Ruling-ref: 6439314592
Responsibility: n/a — maintainer-directed filing (「创建issue」, 2026-10-26); re-ruled B → A at 6439314592 (「26583 A 25870 A」)
Thread-read: 6439314592
Premise: holds by the paths (no commit to ci.yml, packages/cli/vitest.config.ts or scripts/partition-test-shards.mjs on origin/main since the ruling, read at 4b7dbc4); the dev re-measures the reader files on main before any edit, because the ruling allows "plus any the dev finds"
Serial constraints cleared: none (no open PR touches ci.yml, packages/cli/vitest.config.ts, scripts/partition-test-shards.mjs or scripts/test-shard-timings.json, read over all open PRs' full file lists); this seat's #26586 PR goes first on the shared branch
Built on ruling A, pushed, no PR yet: a contract review is owed first · domain:devx#1 · 2026-10-27T16:02Z
The in-seat dev built ruling A (6439314592). The branch claude/project-thread-ervpst is at 7e64f7c1d, one commit on base 437310316. It touches 3 files: .github/workflows/ci.yml (+26/−9, the Test Core "Choose this shard's declaration build" step and its comment only), packages/cli/vitest.config.ts (+103/−1) and scripts/partition-test-shards.mjs (+351/−12). Compare: main...claude/project-thread-ervpst
Readers, re-measured on 4373103: the same 5 of 515 cli queue files go red on an OS_SKIP_DTS=1 closure (TS7016 / ENOENT): create-in-repo-scaffold-typechecks, published-subpath-console.pin, published-subpath-hook-body.pin, scaffold-emission-typechecks, scaffold-test-script-passes.
Shape:
DeclarationReaderSequencer puts the readers first in vitest's own sha1 order and cuts that order into vitest's own equal-count ranges, giving 129/129/129/128 files. All 5 readers land in 1/4, and only 9 files change slice. The config refuses to load if a listed reader is missing from the queue population.
ci.yml keeps declarations only for a whole reader or for slice 1/*.
The partitioner charges that slice 270 s × 2.9 of packing weight and seats @objectstack/metadata on its shard.
The partitioner self-test reads the index back from all three places it is spelled.
Predicted walls (planRun): the slowest Test Core shard goes from 23.0 to 19.1 min, and 1 shard builds .d.ts instead of 5. The dev expects about 20–21 min in CI, because the model reads 1–2 min low. All whole legs stay within 1868 s, with objectql and plugin-security on different shards.
Measured locally:
slices 2–4/4 on a no-declarations build: green;
slice 1/4 with declarations: green;
ablation dropping one reader from the list: that file reds on its new slice;
each of the four partitioner ablations: reds;
dispatch-gates --commands: 86 derived gates, all 86 exit 0.
actionlint: NOT MEASURED, because no binary is available here.
Seat's read: the ci.yml keep-rule uses KEEP only for its log line. The sequencer applies only when shard is set. Seating metadata on the reader slice's shard is how the ruling's "closure for cli 1/n and metadata only" becomes a single shard. Without it, metadata kept a second shard on declarations, and the slowest shard stayed at 23.6 min.
Why there is no PR: this diff is Tier H (.github/workflows/**, a governed surface), so it owes a CONTRACT_REVIEW_TIER review before the queue. That tier is the director seat's, and it is out of quota for this account. The relay pr_create also requests GOVERNED_APPROVERS on a Tier H draft at once (#26617, on hold), and the maintainer ruled on 2026-10-27 that a Tier H PR must not reach approvers before the contract review and the seat's ACCEPT. So the seat opens the PR only after a PASS on this head. The PR body draft is ready (Part of #25870). After landing, the ruling's 10-full-queue-build reading is repeated before the card closes.
Release · domain:devx#1 · session_01JQwxbaFpnMwgpCgneKe2qS · 2026-10-27T22:49Z · ⛔ not a claim
Claim 6442808845 is released. The seat stands down on the maintainer's word (「当前任务处理完,合并后就下班」), and devx seat 2 takes the queue next. The card goes back to pm:queue with no assignee.
Resume from:claude/project-thread-ervpst@7e64f7c1d3. It holds ruling A (6439314592) built as one commit: packages/cli/vitest.config.ts, scripts/partition-test-shards.mjs and a third file, +480/−22. The branch is 107 commits behind main today. Cut a fresh branch from main, bring this commit across, and re-run the gates named in 6446912662.
Claim: PM loop round 1 · 2026-10-27T23:28Z
Session: session_01QSeKYmTYfaPbLQD4BJfomW
Account: os-justin (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-25870-cli-reader-sequencer
Worktree: objectstack-issue-25870
Domain: domain:devx
Seat: domain:devx#2
File surface: ruling A (6439314592) as specified in 6436991767. packages/cli/vitest.config.ts, a sequencer that pins the declaration-reading test files into slice 1/n (cli is domain:server's package; the ruling names it in the workload, declared here as the cross-lane face). .github/workflows/ci.yml: the Test Core "Choose this shard's declaration build" step and its comment only. scripts/partition-test-shards.mjs and its self-test, charging that slice the closure. ⛔ No test skipped or quarantined, no timeout raised, no test moved out of Test Core, no shard-count change, no other ci.yml job. Tier H (stop on breach; explain in the report)
Container & model: M, mode:subagent, model: TIER_DEFAULT (dispatch-gates --tier on the surface: "no path-derived mandate"), effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card
Ruling-ref: 6439314592
Thread-read: 6455523371
Premise: holds. Seat 1's build of ruling A is commit 7e64f7c1d3 on claude/project-thread-ervpst (git ls-remote reads it), 107 commits behind main per 6455523371. No commit on origin/main touches packages/cli/vitest.config.ts or scripts/partition-test-shards.mjs within this shallow clone's window.
Resume-from: claude/project-thread-ervpst@7e64f7c1d3
Serial constraints cleared: open PR #26854 (draft, Tier H) edits ci.yml L117–130 and L4237+, other regions. #25452's change (c), in flight this round with this seat, edits ci.yml cache steps in other regions. Whichever lands second merges main. Landing: Tier H, so the contract review and the seat's ACCEPT go on record before any relay pr_create, which requests GOVERNED_APPROVERS on a Tier H diff.
{
"issue": 25870,
"status": "done",
"branch": "claude/issue-25870-cli-reader-sequencer",
"pr": null,
"session": "session_01QSeKYmTYfaPbLQD4BJfomW (mode:subagent; the PM seat's session)",
"premise_still_valid": true,
"summary": "Ruling A (6439314592) as specified in 6436991767. I cut the branch from origin/main 912076f885, cherry-picked seat 1's 7e64f7c1d3 cleanly (no main commit had touched the 3 files since its base 43731031), re-read every hunk, and kept them. I added one fix: refineToCap() could move the whole reader that rides with the reader slice (@objectstack/metadata) off its shard. That would put declarations back on a second shard, so riders are now fixed in place like slices, and a self-test fixture plus an ablation cover it. Final head c5a59dfe5f is a clean merge of origin/main, including #26854 and #25452's cache steps (disjoint regions). The diff vs main is 3 files, +509/-24: ci.yml (Test Core 'Choose this shard's declaration build' step and comment only), packages/cli/vitest.config.ts, scripts/partition-test-shards.mjs. Readers re-derived (at 9d1cfdbf63 = 912076f885 + this diff; packages/cli is unchanged across both merges): the same 5 of 520 cli files, no new one. Placement on the full turbo ls list: 1 shard builds declarations instead of 5 (cli 1/4 + metadata on shard 1). Wall model: slowest shard ~22.0 to ~18.8 min; the model reads ~2 min low against CI, so expect ~20-21 min. The card's acceptance (≤ ~20 min on 3 spec-touching pull_request runs) is NOT MEASURED, CI-only. No PR, per the dispatch's landing rule (Tier H; contract review and seat ACCEPT first). Compare: https://github.com/objectstack-ai/objectstack/compare/main...claude/issue-25870-cli-reader-sequencer. The PR body draft is at /tmp/claude-0/-home-user-objectstack/abda50f5-0303-5b44-858d-90377f8109e0/scratchpad/issue-25870/pr-body.md. Suggested title: 'ci(test-core): build declarations on one CLI slice only — pin the CLI's declaration readers into slice 1/n'. Labels: skip-changeset (cli files[] = dist, README.md, CHANGELOG.md; 0 hits for DeclarationReaderSequencer/DECLARATION_READER_FILES there, positive control hook-body under dist hits).",
"tests": "Shared 4-core box. (1) OS_SKIP_DTS=1 turbo build --filter=@objectstack/cli --filter=@objectstack/metadata: 61/61 tasks, 0 .d.ts under packages/spec/dist and packages/cli/dist. (2) Whole cli suite on that closure (vitest run --maxWorkers=3, under os-verify-lock): VERDICT command-exit 1; Test Files 5 failed | 514 passed | 1 skipped (520); Tests 25 failed | 6432 passed | 9 skipped (6466). The red files are exactly create-in-repo-scaffold-typechecks (TS7016), published-subpath-console.pin (TS7016 + ENOENT dist/console.d.ts), published-subpath-hook-body.pin (TS7016 + ENOENT dist/hook-body.d.ts), scaffold-emission-typechecks (TS7016/TS2307), scaffold-test-script-passes (TS7016). (3) Control leg, rebuilt with declarations (243 .d.ts), OS_TEST_SHARD=1/4: VERDICT command-exit 0; Test Files 129 passed | 1 skipped (130); Tests 1750 passed | 2 skipped. The 5 readers ran there green, 56/56 tests, and the 130 files equal the new slice 1 map. (4) Slice map from vitest's own context (createVitest + config.sequence.sequencer vs BaseSequencer): before 130/130/130/130 with readers 2/1/1/1; after 130/130/130/130 with readers 5/0/0/0; union 520, 0 duplicates, 9 files moved. Summed per-file seconds per slice: before 301/602/833/401, after 313/595/827/401. The readers sum to 47 s, on the lightest slice. (5) partition-test-shards --self-test OK; whole legs 143/1597/1597/925/924/923/1599/1597s within 1868s. (6) Ablations through ablation-replace.mjs (anchor 1 to 0 each time, restored blob == HEAD, git diff HEAD empty): rider fix reverted -> exit 1 'the cap repair moved the whole reader off the reader slice's shard'; closure wall 0 -> exit 1 (826s vs [826,827,826]s); rider misplaced -> exit 1 (metadata on shard 2); ci.yml DTS_READER_SLICE='2' -> exit 1; sequencer removed -> exit 1; reader dropped from the list -> it moves to slice 2/4 (declaration-less). My first reader-drop attempt was refused by the tool (replacement text not unique) and restored, so it was a no-op; the second attempt used a unique marker. (7) pnpm --filter @objectstack/cli typecheck (compiles vitest.config.ts via tsconfig.test.json): VERDICT command-exit 0, check:test-typecheck OK. A first run was red in ../objectql/src/picklist-resolution.ts on a metadata-core dist that was stale after the merge; it went green after rebuilding.",
"gates": "At c5a59dfe5f: dispatch-gates --commands --repo objectstack-ai/objectstack derived 86 families, all 86 exit 0 (each captured before any pipe). --ran: '86 derived, 86 run, 0 NOT-MEASURED, 0 UNRUN' (a derived zero). On the earlier head 849642eb8c, check:dts-closure exit 1 and check:dual-build-cjs-loads exit 3 (PREREQUISITE NOT MET) came from a run that overlapped my own closure rebuild; re-run on the settled tree, both exited 0, and both are 0 again on the final head. check:nul-bytes exit 0. The ci.yml step's shell was exercised on 6 shard-file fixtures: cli 1/4 + metadata, cli whole, and metadata keep declarations; cli 2/4, cli 4/4 and cli 11/12 skip them. YAML parses. NOT MEASURED: actionlint and shellcheck (no binary here); every CI family (no PR yet, per the landing rule); slices 2-4/4 not re-run as slices (declared narrowing: the whole-suite no-declarations run covers all their files green, and the slice map shows 0 readers in them).",
"dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
"mcp_calls": "0",
"api_writes": "1 — this os-dev-report comment (POST /repos/objectstack-ai/objectstack/issues/25870/comments via scripts/pm/post-stamped.mjs). Not REST: 5 git pushes to claude/issue-25870-cli-reader-sequencer (empty branch, cherry-pick, fix, two merges of main).",
"open_questions": [
{
"question": "The dispatch says the PR body carries `Fixes #25870`. Ruling 6439314592 says the card closes only after the 10-full-queue-build reading is repeated after landing, and the card's acceptance needs 3 spec-touching PR runs. The os-dev DoD says to use `Part of` when the merge should not close the card. Which line goes in the body?",
"options": [
"A `Part of #25870` (the draft uses this, as seat 1's draft did): merge leaves the card open for the readings",
"B `Fixes #25870` as dispatched: merge closes the card before the ruling's after-landing reading"
],
"recommendation": "A, because the ruling ties closing the card to the after-landing reading, and a merge-time close would hide the open speed check from the inbox."
}
],
"out_of_scope_findings": [
"carrier: #25870 (seat) · noted, not filed: the real cli slices are not equal-weight. Summed per-file seconds are 313/595/827/401, and cli 3/4 is the heaviest, the same slice as main's slowest shard 5/8. This PR removes that shard's closure but does not rebalance (option C, not ruled). It is the next lever if the CI reading misses ~20 min.",
"carrier: none · noted in PR Acceptance notes: partitioner bin totals printed as 'Ns predicted' now include the reader slice's 783 s packing charge. driftReport() reads per-package timings, not bin totals, so the drift verdict is unaffected."
]
}
devx seat 2 · answer to the dev's open question (os-dev-report 6458117958) · 2026-10-28T01:24Z
The PR body carries Part of #25870, not Fixes. Ruling 6439314592 closes the card only after the 10-full-queue-build reading is repeated after landing, and the card's acceptance (slowest Test Core shard ≤ ~20 min on three spec-touching pull_request runs) is read in CI after the PR exists. The dispatch order's Fixes line was the seat's error. Branch claude/issue-25870-cli-reader-sequencer @ c5a59dfe5f is now in contract review at CONTRACT_REVIEW_TIER. The seat opens the draft PR through the relay once the review and its ACCEPT are on record (Tier H).
Served-tier: CONTRACT_REVIEW_TIER
Head-sha: c5a59dfe5fc24489c4caaa78d87c8f7a81959a78
Local-runs: none
Scope: .github/workflows/ci.yml + packages/cli/vitest.config.ts, scripts/partition-test-shards.mjs (its self-test is the same file), .github/workflows/test-nightly-tiers.yml, scripts/ci/plan-test-core-shards.mjs, packages/cli/package.json, packages/cli/tsconfig.build.json, turbo.json, scripts/nightly-tiers.mjs, and vitest 4.1.12's own BaseSequencer.ts and pool.ts (the private math the config cites; read from the tag the lockfile pins, since this checkout carries no node_modules)
Reviewed on the card, not a PR: by the seat's Tier H landing rule the review precedes pr_create. Net diff origin/main...c5a59dfe is 3 files, +509/−24, four commits (seat 1's build cherry-picked, the rider fix, two merges of main). Inputs: the card body and all 22 comments, the diff and whole files at the head, nothing else.
① Derived judgments
Check-runs: NONE exist for this head, because there is no PR. Every derived gate family is answered here only by the dev's local reading (86 derived, 86 exit 0 at c5a59df, report 6458117958); actionlint/shellcheck NOT MEASURED there either. The PR's CI is the seat's to read after pr_create; nothing below counts as green until it does.
Accept-set and surface changes the diff implies, each judged on the tree:
A Test Core shard carrying @objectstack/cli k/n with k≠1 now sets OS_SKIP_DTS=1: its dependency closure and its own cli#build (test dependsOn: build, the cli build script honours the flag) emit no .d.ts. Right, conditional on the reader list being complete: the config pins exactly five files into slice 1, the five the two measurements (f486e9c, 4373103/9d1cfdbf) found red under OS_SKIP_DTS=1, and all five exist at the head under packages/cli/test/.
A shard carrying @objectstack/cli 1/n, the CLI whole, or @objectstack/metadata keeps declarations as before. Right (ci.yml case ''|"$DTS_READER_SLICE"/*).
In a run where the CLI is sliced and metadata is present, metadata is seated on the reader slice's shard; where the CLI is whole or absent, placement is byte-identical to main. Right (expandSlices sets rideWith only when an anchor exists; partition places riders straight after their anchor; self-test pins both directions).
The reader slice is charged 270 s × 2.9 = 783 s of packing weight; whole legs re-balance around it; pin 3d (wholeLegProblems) and pin 3c (serialFloorOf, sliceCountProblems) still read weight, never the charge. Right.
The nightly document (sliceAcrossShards) is expanded with NO_DECLARATION_READERS; test-nightly-tiers.yml sets no OS_SKIP_DTS anywhere, so nothing is skipped there and the sequencer, running with readers = [] in nightly mode, reproduces vitest's own split exactly. Right.
vitest split: readers first (name order), the rest in vitest's own sha1 order, cut by vitest's own equal-count ranges. Right against vitest 4.1.12 source: calculateShardRange is the config's shardRange line for line; the key is fullPath.slice(config.root.length), i.e. /test/..., which is the config's /${relative}; pool.ts:63-78 builds ONE sequencer from the root config.sequence.sequencer and calls shard() once over all projects' specs, so "read by the root context only" is a fact, and extends: true on both projects changes nothing.
Public surface: none. packages/clifiles[] = dist, README.md, CHANGELOG.md; tsconfig.build.json includes src only, so vitest.config.ts and its two new exports never reach dist.
Self-test: the new battery declares 16 and the section holds exactly 16 check() calls (4 on the committed dataset/live tree, 7 spellings, 3 placement, 1 cap repair, 1 planRun); SELF_TEST_BATTERY_FLOOR 16 → 17 with one new roster entry. Right.
scripts/ci/plan-test-core-shards.mjs reads bins through planRun(), so the plan job and each shard's "Compute this shard's package set" see the same charged/ridden placement and the digest cannot disagree with it. Right.
② Semver level
skip-changeset is right: the diff publishes nothing from any released package (workflow, a script under scripts/, and a vitest config outside the cli build's include). Claim 6456145005's Clause-②: no and Metadata-protocol: none hold: no spec key, value, type, default or meaning changes; no export of a published entry changes. No changeset owed, no BREAKING banner, no ADR-0087 disposition.
③ Boundary flags
Part of #25870, not Fixes. Ruling 6439314592 closes the card only after the 10-full-queue-build reading of 6430866969 is repeated after landing, and the card's own acceptance is three consecutive spec-touching pull_request runs at ≤ ~20 min, both after-landing readings. A merge-time close would hide both. The seat's answer stands; the draft body already says it.
Out-of-scope note 1 (slices not equal-weight, 313/595/827/401 s, cli 3/4 heaviest): stays on the card as the next lever. It is option C, which the ruling did not take ("not C alone"); nothing in this diff makes it worse (the sha1 split was 301/602/833/401), and the ruling's acceptance is measured on the PR. Not a blocker; the seat records it when the CI reading comes in.
Out-of-scope note 2 (the shard log's Ns predicted / all bins now include the 783 s charge on one bin): see ④ should-fix S1. driftReport() is untouched and reads per-package timings, so the drift verdict is unaffected; judged on the code, not the report.
The dev's declared narrowing (slices 2–4/4 not re-run as slices locally; the whole-suite OS_SKIP_DTS=1 run covers every one of their files green and the slice map shows 0 readers in them) is a sound reading of the tree; CI runs them for real on the PR.
Nothing to escalate.
④ Design judgment
Against ruling 6439314592 (letter A as specified in 6436991767): a sequencer in packages/cli/vitest.config.ts pins the declared readers (the five measured, plus any found: re-measured twice, none found) into slice 1/n; ci.yml keeps the closure for cli 1/n and metadata only, every other slice sets OS_SKIP_DTS=1; the partitioner charges that slice the closure and seats metadata with it so exactly one shard builds declarations; the "Choose this shard's declaration build" comment now lists create-in-repo-scaffold-typechecks. All four parts are in the tree. The ⛔ list holds: no test skipped, quarantined or moved (no skip/todo/only, no tier change, nothing leaves Test Core); no timeout raised (no timeout token in the diff); SHARD_COUNT and FILE_SHARDED_PACKAGES (cli: 4) untouched; the ci.yml hunks are at lines 913–960 only, inside the test: job's one step and its comment, no other job touched.
Breaking it, each in turn:
Can a declaration-reading file land on a slice/shard that builds with OS_SKIP_DTS=1? Not a listed one. The five are placed first in ordered, slice 1's range starts at 0, and a reader count past the slice's own range (readers.length over end − start) is refused at load, so they are in slice 1 for any n the partitioner can emit; ci.yml keeps declarations for 1/*, for an unsliced cli, and for metadata; the three spellings of the index (ci.yml DTS_READER_SLICE='1', config DECLARATION_READER_SLICE = 1, partitioner DECLARATION_READER_SLICES) are read back against each other by the self-test in code position, and a fourth pin reds when a sliced reader package has no reader slice at all. Metadata's own reader (typescript-serializer-annotation) rides to the reader shard or, when the cli is whole/absent, keeps its own shard's declarations as today. The nightly never skips. The only hole is an UNLISTED new reader, which is the ruling's accepted facet ③: on slices 2–4 (three in four by sha1) it reds its own PR deterministically with TS7016/ENOENT; on slice 1 it passes until a later population change moves the cut past it (S2 below).
Does the slice cut still match vitest's own --shard range math? Yes, verified against vitest 4.1.12 (BaseSequencer.calculateShardRange and the sha1 key, above). And the pin's correctness does not even depend on the match: every index cuts the same ordered sequence with the same function, so the union is the whole population and the slices are disjoint whatever vitest's private math becomes on an upgrade. Ties are impossible (distinct paths, sha1 hex compare), so the order is total and deterministic across slices.
Does the ci.yml case keep and skip the right lines?@objectstack/cli alone → SLICE empty → '' arm → kept. @objectstack/metadata → kept. @objectstack/cli 1/4 → 1/* → kept. cli 2/4, cli 4/4 → skipped. cli 11/12 → 11/12 does not match 1/* (the glob needs 1/ as prefix) → skipped. A quoted expansion inside a case pattern is literal in bash, which is the run: shell. An empty shard file → KEEP empty → OS_SKIP_DTS=1, harmless. The failure direction, were the partitioner to co-locate cli 2/4 with metadata, is the safe one (metadata keeps declarations for both).
When the cli population changes? A file added or removed re-splits the other 515 files along vitest's order while the readers stay first in slice 1 — by design, and the reason the ruling orders the 10-build queue reading after landing. A listed reader renamed, deleted or moved to a nightly tier refuses the config at load in queue mode (which is also the local default, OS_TEST_TIERS unset), naming the file; so a rename must carry the list. A nightly-mode load skips the population check and the sequencer sees no readers, so the nightly's 2-way CLI slicing is byte-identical to main's.
Does the rider fix hold in refineToCap()? Yes. fixed = every slice plus every item whose rideWith names a present item; give and take both require movable, so metadata can neither be moved off the reader bin nor swapped into another; the fixture (bin 800 s over a 600 s cap where moving m would strictly lower it) pins the rule. The reader bin's total keeps the 783 s charge while weightOf reads plain weight, which is consistent with partition()'s put and is what makes the repair push whole packages OFF that bin (the intent). The withinCap arm cannot flip the CLI back to whole over the charge: the cap is the whole-package LPT max of the dataset, which holds the CLI whole at 2697 s, so it is ≥ 2697 s against a reader bin of 783 + 674 + 143 ≈ 1600 s.
Expected effect, judged on the dataset rather than the report: cli 2697.45 s / 4 = 674 s per slice, metadata 142.75 s; the reader shard carries 143 s of whole packages against ~925 s on the other slice shards (the self-test's ROOM_SECONDS pin holds 300 s of that gap as a literal), and 1 shard builds declarations instead of 5. Whether that reaches ≤ ~20 min is the PR's CI reading, not this record's.
Findings:
S1 (should-fix, may ride a follow-up): the shard log line shard k/8: ... Ns predicted (all bins: .../...s ...) and balanceOf()'s max/mean now carry the 783 s packing charge on the reader slice's bin without saying so; a reader of a slice shard's log will read ~1600 s as test seconds. One word in that line (or printing the charge beside the bin) closes it. Pin 2's ratio is graded on the same packed totals, which is the intended packing shape, so no verdict changes.
S2 (should-fix, no code owed on this PR): record in the PR body's Acceptance notes the one direction the design cannot see: a new reader that sha1 lands in slice 1 passes until a later population change moves the cut past it and then reds an unrelated PR. The ruling accepted this shape; the note is so the next red of that shape is read as "add the file to DECLARATION_READER_FILES", not as a flake.
Draft PR #27018 opened through the relay from claude/issue-25870-cli-reader-sequencer @ c5a59dfe5f, after contract review 6458259422 (PASS). Its body is the dev's draft plus the review's two should-fix notes in Acceptance notes. Part of #25870. Tier H: GOVERNED_APPROVERS were requested on open. The seat writes its ## 席位核对 once the PR's CI has read the card's acceptance.
Landed (partial): ruling A built, via PR #27018, merged as 6d9e5a1874 · 2026-10-28T02:24Z
Release: session_01QSeKYmTYfaPbLQD4BJfomW (domain:devx#2) · partial landing · landed: the cli's five declaration-reading test files are pinned into slice 1/n, only cli 1/n + metadata build declarations, and the partitioner charges that slice the closure · remaining: the card's acceptance readings, which only time and CI runs can answer · state: pm:dispatched → pm:on-hold, assignee cleared
The merged diff matches the reviewed head c5a59dfe5f (sorted +/− lines hash-identical). Seat record → PR #27018 comment 6458499735. Two independent contract reviews at CONTRACT_REVIEW_TIER, both PASS: 6458259422 (on this card) and 6458668091 (on the PR). Landing regime: Tier H by the maintainer's hand. os-zhuang, a GOVERNED_APPROVERS account, readied, armed and enqueued it; check-governed-merges --pr 27018 reads "the maintainer's hand, or an authorized APPROVED review".
Restart-when: three pull_request CI runs whose diff touches packages/spec/** have completed on heads based at or after 6d9e5a1874; read the slowest Test Core (k/8) job wall time on each (acceptance: ≤ ~20 min on all three), then repeat the 10-full-queue-build reading of 6430866969 (ruling 6439314592); close the card if both hold, or reopen work on the next lever (the uneven cli slices 313/595/827/401 s, unruled option C) if they do not.
Data point so far, not an acceptance reading: on the PR's own run (no packages/spec change), the slowest shard was 5/8 at 12 min 08 s.
Activity
ci(test-shards): revert Test Core to the plain-sum layout and the 202…
objectstack-fleet commentedon Oct 26, 2026
os-dev-report
{ "issue": 25870, "status": "done", "branch": "claude/project-thread-lbjl7f", "pr": "https://github.com/objectstack-ai/objectstack/pull/26186", "session": "session_01CLvWYcHLpbpu8X8PvozD7F (card thread, retry after the #26077 revert)", "premise_still_valid": true, "summary": "Implements the replayed lowest-risk candidate and nothing more: plain-sum placement unchanged, the 2026-10-26 dataset (byte-identical to f36f6190), cli x4 with PREVIOUS_FILE_SHARDED_PACKAGES {cli:3}, and self-test pin 3d (WHOLE_LEG_CAP_SECONDS = 1868, the heaviest whole leg the queue ran green; LOAD_SENSITIVE_APART = objectql + plugin-security). planRun() on the full turbo ls list: whole-package shards 1499/1501/1501/1500s (main: 1866-1868s), slice shards 826-827s whole + 674s slice (wall-model step 959s vs 1276s), objectql 7/8 and plugin-security 6/8. Part of #25870: the card closes only on the after-landing reading (10 full merge-queue Test Core builds, no load-shaped red).", "tests": "partition-test-shards --self-test OK (bins 1499-1501s, whole legs 1499/1501/826/827/826/826/1501/1500s within 1868s, cli x4). Ablation 1: #25968 load-based partition() restored + pin 2 disabled -> pin 3d reds: shards 5-8/8 at 2141/2139/2141/2142s past 1868s, and objectql + plugin-security share 7/8; file restored, cmp clean. Ablation 2: cli x3 on the refreshed dataset -> pin 3c reds (899s > 871s, Raise it to 4); restored, cmp clean. Sibling self-tests green: measure-test-shard-timings, check-test-completeness, ci/select-shard-timings-run, ci/select-shard-packages.selftest.sh (32 cases).", "gates": "dispatch-gates --commands at merge base 365fe5ec: 35 families, all exit 0; --ran: 35 derived, 35 run, 0 NOT-MEASURED. check-commit-card-trailers --range origin/main..HEAD pass. Serial: none of the 36 other open PRs touches scripts/partition-test-shards.mjs or scripts/test-shard-timings.json (git diff --name-only per pull head). CI families: read from PR #26186 check-runs.", "dogfood_battery": "n/a - no ! in the PR title and no (narrowing) arm", "mcp_calls": "read-only: issue_read x1, list_pull_requests x1, pull_request_read x1; 0 writes", "api_writes": "2 relay strokes: pr_create (#26186, assignee os-elon-musk, label skip-changeset); this comment + pr_request_reviewers (os-elon-musk)", "open_questions": [], "out_of_scope_findings": [ "carrier: none - ci.yml Test Core comments still say 3 slices; Tier H, left (PR Acceptance notes)", "carrier: none - pin 3d grades the full list only; partial-list runs can still co-locate the pair on lighter shards, as on the green layout (PR Acceptance notes)" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
After-landing reading for #26186: 10 full Test Core queue builds, 0 red
#26186 merged at 2026-10-26 18:02Z. I read it at 00:45Z over REST: every
merge_grouprun ofci.ymlcreated from 17:43Z on, which is the run for #26186's own group and everything queued on top of it.All queue builds: 96 completed runs, 96 green. No job in any of them failed, no run was re-attempted, and no entry was ejected by Test Core. Two more were still in progress at read time.
The first 10 full builds
A build counts as full here when two things hold. First, at least 6 of its 8 Test Core shards ran 10 minutes or more. Second, the aggregator's suite list shows objectql, plugin-security and all 4 cli slices executed. The ratios below are each suite's measured wall against its suite-duration ceiling, from the aggregator's report-only check.
(#26264 was built twice because its first group was rebuilt after an entry ahead of it changed. Both builds were green.)
hook-run-as, plugin-securityshipped-sets-identity-default-row-scope, and clihook-timeout-override-refusal.@objectstack/service-packagereads 33–77 s against a 32.90 s ceiling (1.1–2.3x) on 26 of the 29 heavy builds. It was already over on the old layout before this PR: 47.89 s on 40325660507 and 46.97 s on 40327508710 (about 1.45x). Its suite gained a hydration test file in feat(install): a declared dependency co-owns its parent's namespace, and both boot hydrates sort by it (ADR-0141 D5) #26054 at 10:42Z, and its ceiling is the 10-26 refresh's figure. The check reports and does not fail. I'm noting it here and not filing it.Slowest spec-touching
pull_requestshard (for information, not the gate)There have been 9 spec-touching PRs since landing (#26138 #26159 #26271 #26305 #26320 #26342 #26343 #26355 #26361). Their completed Test Core runs:
The slowest spec-PR shard is 23.9–25.4 min on 8 of these 10 runs. The outliers are 20.7 and 29.2. Before #25968 the range was 25.7–28.8, so this is about 2–4 min faster. It does not reach the original ≤ ~20 min goal. The slowest shard is always a CLI-slice shard: setup, then the cold DTS closure (~6 min), then ~5 min of whole packages, then a slice. The step model's prediction of 959 s plus the closure and setup gives about 23.5 min, which is what these runs read. #26138's earlier run 40377181895 was red on cli slices 4/8 and 6/8. That red was a real assertion in that PR's own CLI change (
audit-mail-bodies.archive.integration.test.ts› "a declared archive this boot cannot connect is NOT reported clean", 1 ms, not a timeout), and the PR's next run was green.For the seat: the acceptance gate (no load-shaped red in the queue) holds. The speed goal is still open. What is left on a slice shard is the DTS closure plus the slice, which brings option B (DTS only on the slice that reads
.d.ts, Tier H, ci.yml) or option C (weight-balanced CLI slices) from the earlier report back on the table. Choosing between them is the seat's or the maintainer's call. I have not taken either.Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Release:
session_01LKHDniRQSWjRJyDtacwpEd(devx seat 1) · seat signs off on the maintainer's word 「当前任务处理完,合并后就下班」 (2026-10-27 01:20Z) · next:needs-user-decision, close or follow-up B/CPR #26186 landed on 2026-10-26 18:02Z. Its acceptance is met: 96/96 queue CI runs were green, and the first 10 full builds had no load-shaped red (reading 6430866969). The card's original speed goal is not met. The slowest spec-PR shard runs 23.9–25.4 min against the ≤ ~20 min goal; what remains is the cold DTS closure (~6 min) plus a CLI slice.
Question for the maintainer (the seat recommends option 1):
ci.ymledit, not Tier H..d.ts. This editsci.yml, so it is Tier H and needs a governed approver.Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Brief-claimed-by: session_01KrKXQVvgYk2AJ4VkqMobyb · batch #408 · 2026-10-27T04:45Z
Director seat, summon #51 continuation (ledger objectstack#12708). Presented to the maintainer in batch #408 as item 4 of 5 — the devx seat's question in 6433447870 after PR #26186 landed. Seat increment (re-read 2026-10-27T04:45Z; the after-landing reading 6430866969 is not restated):
needs-user-decisionalone; the ruling's stroke closes the card (1) or returns it topm:queue(B/C).ci.ymledit (Tier H), not a gate; C is measurement with noci.ymledit..d.ts; C's measurement rides the same PR body as the before/after reading. Not 1 (the goal is unmet and the remedy is known), not C alone (the slices are already balanced; the 6 min is the closure). Workload: devx · 1 Tier H PR · S; precedent PR ci(test-shards): refresh the Test Core dataset and cut the CLI into 4 slices on plain-sum placement, and pin the whole-package leg #26186 (+/− not re-measured here) on the same shard tooling.Prior rulings read: shard balance · cli slices → ci(test-shards): widen Test Core from 6 to 8 shards once
@objectstack/specis file-sharded — the "6 is enough" arithmetic predates the cli slices (full-battery slowest shard ≈ 1937 s → ≈ 1452 s) #25376, ci(test-shards): the cli slices ran 1132 s against 735 s predicted (×1.54) on Test Core 3/6 — refreshscripts/test-shard-timings.json(dated 2026-10-13) and re-derive the cli slice count under pin 3c #25390, ci(test-shards): place Test Core bins by predicted wall, and cut the CLI into 4 slices on the refreshed dataset #25968 (reverted by ci(test-shards): revert Test Core to the plain-sum layout and the 2026-10-23 dataset (undo #25968) #26077), ci(test-shards): refresh the Test Core dataset and cut the CLI into 4 slices on plain-sum placement, and pin the whole-package leg #26186; thread: 6433447870.objectstack-fleet commentedon Oct 27, 2026
Ruling: batch #408 item 4 · letter B · maintainer 「批 #408 同意」 2026-10-27T06:26Z
Recorded by the director seat (summon #51 continuation,
session_01KrKXQVvgYk2AJ4VkqMobyb, ledger objectstack#12708). The maintainer answered batch #408 with 「批 #408 同意」 — every seat letter. Brief 6433979362; the devx release 6433447870 asked the question. Letter B: the cold DTS closure is built only on the CLI slice that reads.d.ts; the other slices skip it. C's measurement (the per-slice before/after wall and the suite ratios) rides the same PR body as the reading; the card closes on three consecutive spec-touchingpull_requestruns with the slowest Test Core shard ≤ ~20 min, as the card's acceptance says, or on the maintainer's word that the measured saving is enough. Not 1 (the goal is unmet and the lever is known) and not C alone (the slices are balanced at 826–827 s; the ~6 min is the closure).Workload: devx · 1 Tier H PR (
.github/workflows/ci.yml, lands by the maintainer's approval) · S; ⛔ no test skipped or quarantined, no timeout raised (the card's own line).Execution:
needs-user-decision→pm:queuein this act (domain:devx, p2).Ruling-ref:names this comment.Clause-②: no,Metadata-protocol: none.objectstack-fleet commentedon Oct 27, 2026
Claim: PM loop round 11 · 2026-10-27T07:25Z
Session:
session_01Q4MDXRbEJCNdPAP4SiXwp9(devx seat 2) · card threadcmsg_01FdL1XeUyvVNxLreh3F4Qi97ymecxbJozWc9XMZjBfknnAccount:
os-steveBranch:
claude/project-thread-o6kgnu(the harness-pinned branch of the card thread; it names no issue, so this claim is the identity record; amended on spawn)Worktree:
objectstack-issue-25870Domain:
domain:devxSeat:
domain:devx#2(seat post #20163)File surface:
.github/workflows/ci.yml, the Test Core job only: the "Declarations skipped" step (DTS_READERS/OS_SKIP_DTS) and, if the slice must be named there, the closure build step. Per ruling B the cold DTS closure is built only on the CLI slice whose tests read.d.ts; every other slice, CLI slices included, setsOS_SKIP_DTS=1.scripts/partition-test-shards.mjsand its self-test only if the slice that reads.d.tscannot be named from the workflow alone. ⛔ No test skipped or quarantined, no timeout raised, no shard count or weight change. ⛔ No other job ofci.yml. The PR is Tier H (.github/workflows/**): draft until a GOVERNED_APPROVERS approvalContainer & model: M,
mode:thread,model: default tier (TIER_DEFAULT, from dispatch-gates --tier: no path-derived mandate),effort: mediumClause-②: no
Metadata-protocol: none
Ruling-ref: 6435350063
Responsibility: n/a — maintainer-directed filing (「创建issue」, 2026-10-26); ruled B at 6435350063
Thread-read: 6435350063
Premise: on
origin/main, every Test Core shard that carries any@objectstack/clislice builds the DTS closure (DTS_READERS='@objectstack/cli @objectstack/metadata'), and only one CLI slice's tests read.d.ts(the dev confirms which, onorigin/main, before changing anything)Serial constraints cleared: no open PR edits
.github/workflows/ci.yml(read 07:30Z over the 21 open PRs); #26529 (this seat) editstest-nightly-tiers.ymlandshard-timings-refresh.ymlonlyGenerated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
os-dev-report
{ "issue": 25870, "status": "needs_decision", "branch": "claude/project-thread-o6kgnu", "pr": null, "session": "session_01ADHkmPfbyqbnLkfPfz7Uan (card thread V, dispatched by devx seat 2 session_01Q4MDXRbEJCNdPAP4SiXwp9)", "premise_still_valid": false, "summary": "Premise false on origin/main f486e9c1: every one of the 4 CLI slices holds a test that reads built .d.ts, so ruling B as worded (DTS closure only on the one CLI slice that reads .d.ts) has no slice to drop DTS from and saves 0 min. Measured: the whole cli suite on an OS_SKIP_DTS=1 closure goes red in exactly 5 of 514 files, all declaration-caused (TS7016 on @objectstack/spec/* dist, ENOENT on cli dist/*.d.ts): published-subpath-console.pin, scaffold-test-script-passes (slice 1/4), create-in-repo-scaffold-typechecks (2/4, not in the ci.yml 830a63a list), scaffold-emission-typechecks (3/4), published-subpath-hook-body.pin (4/4). Slice membership is vitest's own BaseSequencer.shard (sha1 of the relative path, equal-count ranges) run on packages/cli's real config, so any added or removed cli test file moves the cut points: a static 'cli k/4' name in ci.yml is wrong by construction. No file changed, no PR opened; the decision on how to reach ruling B's intent is the seat's (open_questions).", "tests": "f486e9c1. (1) OS_SKIP_DTS=1 turbo build --filter=@objectstack/cli --filter=@objectstack/metadata: 61/61 tasks, 1m43s, 0 .d.ts under packages/spec/dist and packages/cli/dist. (2) Whole cli suite on that closure (vitest run, unit+integration, maxWorkers=3, under os-verify-lock): VERDICT command-exit 1; Test Files 5 failed | 508 passed | 1 skipped (514); Tests 25 failed | 6379 passed | 9 skipped (6413). The 5 files and their first error lines are in the summary. (3) Control leg, same tree with declarations: turbo build --filter=@objectstack/cli 61/61 tasks 7m04s (shared box), then the same 5 files: VERDICT command-exit 0, Test Files 5 passed (5), Tests 56 passed (56). (4) Slice map: vitest createVitest + config.sequence.sequencer.shard() over globTestSpecifications() in packages/cli with OS_TEST_SHARD=k/4: 129/129/128/128 of 514 files; readers 1/4: 2 files, 2/4: 1, 3/4: 1, 4/4: 1. (5) Shard map, full turbo ls list replayed through partition-test-shards.mjs --shard k/8 --exclude @objectstack/dogfood: cli 1/4..4/4 on shards 3..6, @objectstack/metadata on 7, so 5 of 8 shards keep DTS. CI agrees: pull_request run 40423632426 (spec-touching, PR #26343) 'Build this shard's dependency closure' 4.2/4.4/5.8/5.3/5.5 min on shards 3-7 against 0.5-0.9 on 1, 2, 8; slowest Test Core (5/8) = cli 3/4, 25.1 min.", "gates": "No diff, so no derived family: dispatch-gates --commands not run (it derives from the changed set, which is empty). NOT MEASURED: every CI family, reason: no PR.", "dogfood_battery": "n/a - no PR", "mcp_calls": "5 - read only: issue_read x3 (get, get_comments x2), actions_list x1 (list_workflow_jobs 40423632426), get_job_logs x1 (job 121924032523); 0 writes", "api_writes": "1 - this os-dev-report comment (post-stamped, relay)", "open_questions": [ { "question": "Ruling B's wording has no slice to act on (all 4 CLI slices read .d.ts). Which route carries its intent, the cold DTS closure on one CLI slice only?", "options": [ "A Pin the declaration readers to one fixed slice: a sequencer in packages/cli/vitest.config.ts sends a declared reader list to slice 1/n and sha1-splits the rest; ci.yml keeps DTS only for '@objectstack/cli 1/4' (plus metadata); partition-test-shards charges that slice the closure cost (~4.5 min) so its shard carries less whole-package work. Facets (brief 6433979362): (1) lever specific, 3 slice shards drop ~4.5 min of closure each; (2) every spec PR and queue entry; (3) a reader missing from the list reds loudly with TS7016 on a skipping slice, as today; (4) Tier H (ci.yml) and widens the file surface to packages/cli/vitest.config.ts and partition-test-shards.mjs + self-test. Without the partition charge the reader shard stays ~23-25 min and the slowest shard does not move. Risk: the other 509 cli files re-split, so load-sensitive neighbours shift (the #25968 revert); read the queue red rate after landing. Size M.", "B Implement the ruling literally: decide per slice in ci.yml from vitest's own shard of the reader list. Saves 0 min today (every slice holds a reader). Not worth a Tier H PR.", "C Move the 5 cli readers and metadata's typescript-serializer-annotation to a job that already builds declarations (Build Core), and set OS_SKIP_DTS=1 on every Test Core shard: 5 shards drop ~4.5 min, slowest ~20-21 min with no partition change. It takes tests out of the required Test Core context, which the card's no-skip/no-quarantine line forbids without the maintainer's word, and edits a second ci.yml job.", "D Close on the current reading (slowest spec-PR shard 23.9-25.4 min) by the maintainer's word, as the ruling allows." ], "recommendation": "A, because it is the only route that keeps every test in Test Core and still gives the intent of B: declarations on exactly one CLI slice, by a membership the package declares instead of a sha1 accident. The partition charge is what makes it reach ~20 min. Measure the readers' slice weight before landing." } ], "out_of_scope_findings": [ "carrier: #25870 - the ci.yml 'Choose this shard's declaration build' comment lists the cli DTS readers measured on 830a63a; it misses create-in-repo-scaffold-typechecks, which now also reds without declarations. Fix rides whichever route is chosen (Tier H text)." ] }Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Seat reading · ruling B's premise is false · devx seat 2 · 2026-10-27T08:17Z
Seat
domain:devx#2(#20163) ·session_01Q4MDXRbEJCNdPAP4SiXwp9. Thread-read: 6436965718. The card thread measured onf486e9c1(report 6436965718) and opened no PR.OS_SKIP_DTS=1, the whole cli suite reds in exactly 5 of 514 files, all for missing declarations. The control leg with declarations is 5/5 files, 56/56 tests green. Using vitest's ownsequencer.shardon the realpackages/cliconfig, the five readers land in all four slices (1/4: 2, 2/4: 1, 3/4: 1, 4/4: 1).cli k/4inci.ymlwould be wrong by construction.Ways to reach the ruling's goal. Each is the maintainer's call, because each goes past what B ruled:
packages/cli/vitest.config.tsthat pins the five reader files into slice 1/n.ci.ymlthen keeps the closure only for cli 1/n and metadata, andpartition-test-shardscounts the ~4.5 min closure into that slice's weight. Three shards stop building the closure; the slowest shard should come down toward ~20 min (to be measured on the PR). The surface widens to the cli vitest config (cli isdomain:server's package) and the partition script; still one Tier H PR.The card is marked
needs-user-decisionand stays claimed; the thread waits for the answer.Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Release:
session_01Q4MDXRbEJCNdPAP4SiXwp9(devx seat 2) · seat signs off on the maintainer's word 「devx 车道当前任务处理完就下班」 (2026-10-27 08:42Z) · next:needs-user-decisionon 6436991767 (A / C / D; the seat recommends A)The card thread measured that ruling B's premise is false: the five
.d.tsreaders sit in all four CLI slices, so B as worded saves 0 minutes (report 6436965718). No PR was opened. The thread branchclaude/project-thread-o6kgnuholds no changes. A dispatch after the ruling starts from 6436991767.Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Brief-claimed-by: session_01KrKXQVvgYk2AJ4VkqMobyb · batch #411 · 2026-10-27T10:11Z
Director seat, summon #51 continuation (ledger objectstack#12708). Presented to the maintainer in batch #411 as item 3 of 3 — a re-ruling: ruling B (6435350063, batch #408) has no slice to act on. Seat increment (the dev report 6436965718 and the seat reading 6436991767 are not restated):
.d.ts") is false onorigin/mainf486e9c1: five cli test files read built declarations and vitest's sha1 sharding scatters them across all four slices (1/4: 2, 2/4: 1, 3/4: 1, 4/4: 1); withOS_SKIP_DTS=1exactly those 5 of 514 files go red, all declaration-caused. B as worded saves 0 min. The seat's recommendation in batch Fix duplicate property in logger config object #408 was wrong on this fact; the dev measured it before changing anything, as the claim ordered.packages/cli/vitest.config.tspins the declared reader files into slice 1/n,ci.ymlkeeps the closure for cli 1/n and metadata only, andpartition-test-shardscharges that slice the ~4.5 min closure so its shard carries less whole-package work. Three shards drop the closure; expected slowest shard toward ~20 min, measured on the PR. Surface:ci.yml(Tier H) + the cli vitest config (domain:server's package) + the partition script and self-test. Risk named by the dev: the other 509 cli files re-split, so load-sensitive neighbours move (the ci(test-shards): place Test Core bins by predicted wall, and cut the CLI into 4 slices on the refreshed dataset #25968 class) — the PR's after-landing reading must repeat 6430866969's 10-build check.Test Corecontext, which the card's own ⛔ line forbids without the maintainer's word. D closes the card on the current reading (23.9–25.4 min).needs-user-decisionwith the thread's claim still held (pm:dispatchedwas lifted by the seat's release 6438053721 → the card showsneeds-user-decisionalone).Test Coreand makes reader membership a declared fact of the package instead of a sha1 accident; ② every spec-touching PR and queue entry pays the closure on three shards today; ③ a reader missing from the declared list reds loudly (TS7016) on a skipping slice; ④ Tier H plus two more files, no gate.Prior rulings read: 6435350063 (B), 6430866969 (after-landing reading), ci(test-shards): place Test Core bins by predicted wall, and cut the CLI into 4 slices on the refreshed dataset #25968 / ci(test-shards): revert Test Core to the plain-sum layout and the 2026-10-23 dataset (undo #25968) #26077 (the revert), ci(test-shards): refresh the Test Core dataset and cut the CLI into 4 slices on plain-sum placement, and pin the whole-package leg #26186; thread: 6436991767.
objectstack-fleet commentedon Oct 27, 2026
Ruling: batch #411 item 3 · re-ruled B → A · maintainer 「26583 A 25870 A」 2026-10-27T10:20Z
Recorded by the director seat (summon #51 continuation,
session_01KrKXQVvgYk2AJ4VkqMobyb, ledger objectstack#12708). The maintainer answered batch #411 with 「26583 A 25870 A」. Brief 6439158762; the card thread's measurement 6436965718 and the seat reading 6436991767 showed ruling B (6435350063) had no slice to act on — the five.d.tsreaders sit in all four CLI slices by vitest's sha1 sharding, so B as worded saved 0 min. Letter A, as the dev specified: a sequencer inpackages/cli/vitest.config.tspins the declared reader files (the five measured onf486e9c1, plus any the dev finds) into slice 1/n;ci.ymlkeeps the cold DTS closure for cli 1/n and metadata only, every other slice setsOS_SKIP_DTS=1;scripts/partition-test-shards.mjscharges that slice the ~4.5 min closure so its shard carries less whole-package work; the "Choose this shard's declaration build" comment inci.ymlis corrected (it missescreate-in-repo-scaffold-typechecks). ⛔ No test skipped or quarantined, no timeout raised, no test moved out ofTest Core(not C), no shard-count change. Not D: the lever is known and measured.Workload: devx + server (the cli vitest config is
domain:server's package) · 1 Tier H PR (.github/workflows/ci.yml, lands by the maintainer's approval) · M. Acceptance stays the card's: the slowest Test Core shard ≤ ~20 min on three consecutive spec-touchingpull_requestruns, measured on the PR; after landing, the 10-full-queue-build reading of 6430866969 is repeated before the card closes, because the other 509 cli files re-split and load-sensitive neighbours move (the #25968 / #26077 class).Execution:
needs-user-decision→pm:queuein this act (domain:devx, p2); the devx seat re-dispatches from 6436991767's A.Ruling-ref:names this comment; 6435350063 is superseded.Clause-②: no,Metadata-protocol: none.objectstack-fleet commentedon Oct 27, 2026
Claim: PM loop round 5 · 2026-10-27T13:14Z
Session:
session_01JQwxbaFpnMwgpCgneKe2qSAccount:
os-warren(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/project-thread-ervpst(platform exception: this seat's container pushes only its ownclaude/project-thread-*branch). The dev builds in its own worktree offorigin/mainnow and pushes only after the branch's open #26586 PR has mergedWorktree:
objectstack-issue-25870Domain:
domain:devxSeat:
domain:devx#1File surface: ruling A (6439314592) as the dev specified it in 6436991767: a sequencer in
packages/cli/vitest.config.ts(adomain:serverpackage, named in the ruling's workload) that pins the declaration-reading test files into slice 1/n;.github/workflows/ci.yml, the Test Core job's declaration-build choice only (closure kept for cli 1/n and metadata,OS_SKIP_DTS=1elsewhere) plus the "Choose this shard's declaration build" comment;scripts/partition-test-shards.mjsand its self-test, charging that slice the closure. ⛔ No test skipped or quarantined, no timeout raised, no test moved out of Test Core, no shard-count change, no otherci.ymljob (stop on breach)Landing: Tier H (
.github/workflows/**). ⛔ Nopr_createuntil the contract review and the seat's ACCEPT are both on record, because the relay'spr_createrequestsGOVERNED_APPROVERSon a Tier H diff at once (#26617). The ceiling tier is out of quota here, so the contract review waits for the director seat. Then the PR is draft until aGOVERNED_APPROVERSapprovalContainer & model: M,
mode:subagent(in-seat and serial instead of a card thread: the account's 7-day usage readsallowed_warning, so the seat opens no new card thread, coordinator.md §六),model: default(no path-derived mandate, default opus; quota exemption),effort: highClause-②: no
Metadata-protocol: none
Ruling-ref: 6439314592
Responsibility: n/a — maintainer-directed filing (「创建issue」, 2026-10-26); re-ruled B → A at 6439314592 (「26583 A 25870 A」)
Thread-read: 6439314592
Premise: holds by the paths (no commit to
ci.yml,packages/cli/vitest.config.tsorscripts/partition-test-shards.mjson origin/main since the ruling, read at 4b7dbc4); the dev re-measures the reader files on main before any edit, because the ruling allows "plus any the dev finds"Serial constraints cleared: none (no open PR touches
ci.yml,packages/cli/vitest.config.ts,scripts/partition-test-shards.mjsorscripts/test-shard-timings.json, read over all open PRs' full file lists); this seat's #26586 PR goes first on the shared branchGenerated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Built on ruling A, pushed, no PR yet: a contract review is owed first ·
domain:devx#1· 2026-10-27T16:02ZThe in-seat dev built ruling A (6439314592). The branch
claude/project-thread-ervpstis at7e64f7c1d, one commit on base437310316. It touches 3 files:.github/workflows/ci.yml(+26/−9, the Test Core "Choose this shard's declaration build" step and its comment only),packages/cli/vitest.config.ts(+103/−1) andscripts/partition-test-shards.mjs(+351/−12). Compare: main...claude/project-thread-ervpstOS_SKIP_DTS=1closure (TS7016 / ENOENT):create-in-repo-scaffold-typechecks,published-subpath-console.pin,published-subpath-hook-body.pin,scaffold-emission-typechecks,scaffold-test-script-passes.DeclarationReaderSequencerputs the readers first in vitest's own sha1 order and cuts that order into vitest's own equal-count ranges, giving 129/129/129/128 files. All 5 readers land in 1/4, and only 9 files change slice. The config refuses to load if a listed reader is missing from the queue population.ci.ymlkeeps declarations only for a whole reader or for slice1/*.@objectstack/metadataon its shard.planRun): the slowest Test Core shard goes from 23.0 to 19.1 min, and 1 shard builds.d.tsinstead of 5. The dev expects about 20–21 min in CI, because the model reads 1–2 min low. All whole legs stay within 1868 s, with objectql and plugin-security on different shards.dispatch-gates --commands: 86 derived gates, all 86 exit 0.ci.ymlkeep-rule usesKEEPonly for its log line. The sequencer applies only whenshardis set. Seating metadata on the reader slice's shard is how the ruling's "closure for cli 1/n and metadata only" becomes a single shard. Without it, metadata kept a second shard on declarations, and the slowest shard stayed at 23.6 min.Why there is no PR: this diff is Tier H (
.github/workflows/**, a governed surface), so it owes aCONTRACT_REVIEW_TIERreview before the queue. That tier is the director seat's, and it is out of quota for this account. The relaypr_createalso requestsGOVERNED_APPROVERSon a Tier H draft at once (#26617, on hold), and the maintainer ruled on 2026-10-27 that a Tier H PR must not reach approvers before the contract review and the seat's ACCEPT. So the seat opens the PR only after a PASS on this head. The PR body draft is ready (Part of #25870). After landing, the ruling's 10-full-queue-build reading is repeated before the card closes.Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Release ·
domain:devx#1·session_01JQwxbaFpnMwgpCgneKe2qS· 2026-10-27T22:49Z · ⛔ not a claimClaim 6442808845 is released. The seat stands down on the maintainer's word (「当前任务处理完,合并后就下班」), and devx seat 2 takes the queue next. The card goes back to
pm:queuewith no assignee.claude/project-thread-ervpst@7e64f7c1d3. It holds ruling A (6439314592) built as one commit:packages/cli/vitest.config.ts,scripts/partition-test-shards.mjsand a third file, +480/−22. The branch is 107 commits behind main today. Cut a fresh branch from main, bring this commit across, and re-run the gates named in 6446912662.cisurface). A director-seat contract review is owed before any relaypr_create(fleet-write: relay pr_create asks the governed approvers to review a Tier H draft before any contract review exists, so an approver can approve and merge it unreviewed (#26566, #26570) #26617). The PR body draft is/mnt/project-files/pm-devx-seat/pr-25870-body.md. No director reviewed it during this seat's shift, so it is a tail, not work in flight.objectstack-fleet commentedon Oct 27, 2026
Claim: PM loop round 1 · 2026-10-27T23:28Z
Session:
session_01QSeKYmTYfaPbLQD4BJfomWAccount:
os-justin(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-25870-cli-reader-sequencerWorktree:
objectstack-issue-25870Domain:
domain:devxSeat:
domain:devx#2File surface: ruling A (6439314592) as specified in 6436991767.
packages/cli/vitest.config.ts, a sequencer that pins the declaration-reading test files into slice 1/n (cli isdomain:server's package; the ruling names it in the workload, declared here as the cross-lane face)..github/workflows/ci.yml: the Test Core "Choose this shard's declaration build" step and its comment only.scripts/partition-test-shards.mjsand its self-test, charging that slice the closure. ⛔ No test skipped or quarantined, no timeout raised, no test moved out of Test Core, no shard-count change, no otherci.ymljob. Tier H (stop on breach; explain in the report)Container & model: M,
mode:subagent,model: TIER_DEFAULT(dispatch-gates --tieron the surface: "no path-derived mandate"),effort: highClause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card
Ruling-ref: 6439314592
Thread-read: 6455523371
Premise: holds. Seat 1's build of ruling A is commit
7e64f7c1d3onclaude/project-thread-ervpst(git ls-remotereads it), 107 commits behind main per 6455523371. No commit onorigin/maintouchespackages/cli/vitest.config.tsorscripts/partition-test-shards.mjswithin this shallow clone's window.Resume-from:
claude/project-thread-ervpst@7e64f7c1d3Serial constraints cleared: open PR #26854 (draft, Tier H) edits
ci.ymlL117–130 and L4237+, other regions. #25452's change (c), in flight this round with this seat, editsci.ymlcache steps in other regions. Whichever lands second mergesmain. Landing: Tier H, so the contract review and the seat's ACCEPT go on record before any relaypr_create, which requestsGOVERNED_APPROVERSon a Tier H diff.Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
os-dev-report
{ "issue": 25870, "status": "done", "branch": "claude/issue-25870-cli-reader-sequencer", "pr": null, "session": "session_01QSeKYmTYfaPbLQD4BJfomW (mode:subagent; the PM seat's session)", "premise_still_valid": true, "summary": "Ruling A (6439314592) as specified in 6436991767. I cut the branch from origin/main 912076f885, cherry-picked seat 1's 7e64f7c1d3 cleanly (no main commit had touched the 3 files since its base 43731031), re-read every hunk, and kept them. I added one fix: refineToCap() could move the whole reader that rides with the reader slice (@objectstack/metadata) off its shard. That would put declarations back on a second shard, so riders are now fixed in place like slices, and a self-test fixture plus an ablation cover it. Final head c5a59dfe5f is a clean merge of origin/main, including #26854 and #25452's cache steps (disjoint regions). The diff vs main is 3 files, +509/-24: ci.yml (Test Core 'Choose this shard's declaration build' step and comment only), packages/cli/vitest.config.ts, scripts/partition-test-shards.mjs. Readers re-derived (at 9d1cfdbf63 = 912076f885 + this diff; packages/cli is unchanged across both merges): the same 5 of 520 cli files, no new one. Placement on the full turbo ls list: 1 shard builds declarations instead of 5 (cli 1/4 + metadata on shard 1). Wall model: slowest shard ~22.0 to ~18.8 min; the model reads ~2 min low against CI, so expect ~20-21 min. The card's acceptance (≤ ~20 min on 3 spec-touching pull_request runs) is NOT MEASURED, CI-only. No PR, per the dispatch's landing rule (Tier H; contract review and seat ACCEPT first). Compare: https://github.com/objectstack-ai/objectstack/compare/main...claude/issue-25870-cli-reader-sequencer. The PR body draft is at /tmp/claude-0/-home-user-objectstack/abda50f5-0303-5b44-858d-90377f8109e0/scratchpad/issue-25870/pr-body.md. Suggested title: 'ci(test-core): build declarations on one CLI slice only — pin the CLI's declaration readers into slice 1/n'. Labels: skip-changeset (cli files[] = dist, README.md, CHANGELOG.md; 0 hits for DeclarationReaderSequencer/DECLARATION_READER_FILES there, positive control hook-body under dist hits).", "tests": "Shared 4-core box. (1) OS_SKIP_DTS=1 turbo build --filter=@objectstack/cli --filter=@objectstack/metadata: 61/61 tasks, 0 .d.ts under packages/spec/dist and packages/cli/dist. (2) Whole cli suite on that closure (vitest run --maxWorkers=3, under os-verify-lock): VERDICT command-exit 1; Test Files 5 failed | 514 passed | 1 skipped (520); Tests 25 failed | 6432 passed | 9 skipped (6466). The red files are exactly create-in-repo-scaffold-typechecks (TS7016), published-subpath-console.pin (TS7016 + ENOENT dist/console.d.ts), published-subpath-hook-body.pin (TS7016 + ENOENT dist/hook-body.d.ts), scaffold-emission-typechecks (TS7016/TS2307), scaffold-test-script-passes (TS7016). (3) Control leg, rebuilt with declarations (243 .d.ts), OS_TEST_SHARD=1/4: VERDICT command-exit 0; Test Files 129 passed | 1 skipped (130); Tests 1750 passed | 2 skipped. The 5 readers ran there green, 56/56 tests, and the 130 files equal the new slice 1 map. (4) Slice map from vitest's own context (createVitest + config.sequence.sequencer vs BaseSequencer): before 130/130/130/130 with readers 2/1/1/1; after 130/130/130/130 with readers 5/0/0/0; union 520, 0 duplicates, 9 files moved. Summed per-file seconds per slice: before 301/602/833/401, after 313/595/827/401. The readers sum to 47 s, on the lightest slice. (5) partition-test-shards --self-test OK; whole legs 143/1597/1597/925/924/923/1599/1597s within 1868s. (6) Ablations through ablation-replace.mjs (anchor 1 to 0 each time, restored blob == HEAD, git diff HEAD empty): rider fix reverted -> exit 1 'the cap repair moved the whole reader off the reader slice's shard'; closure wall 0 -> exit 1 (826s vs [826,827,826]s); rider misplaced -> exit 1 (metadata on shard 2); ci.yml DTS_READER_SLICE='2' -> exit 1; sequencer removed -> exit 1; reader dropped from the list -> it moves to slice 2/4 (declaration-less). My first reader-drop attempt was refused by the tool (replacement text not unique) and restored, so it was a no-op; the second attempt used a unique marker. (7) pnpm --filter @objectstack/cli typecheck (compiles vitest.config.ts via tsconfig.test.json): VERDICT command-exit 0, check:test-typecheck OK. A first run was red in ../objectql/src/picklist-resolution.ts on a metadata-core dist that was stale after the merge; it went green after rebuilding.", "gates": "At c5a59dfe5f: dispatch-gates --commands --repo objectstack-ai/objectstack derived 86 families, all 86 exit 0 (each captured before any pipe). --ran: '86 derived, 86 run, 0 NOT-MEASURED, 0 UNRUN' (a derived zero). On the earlier head 849642eb8c, check:dts-closure exit 1 and check:dual-build-cjs-loads exit 3 (PREREQUISITE NOT MET) came from a run that overlapped my own closure rebuild; re-run on the settled tree, both exited 0, and both are 0 again on the final head. check:nul-bytes exit 0. The ci.yml step's shell was exercised on 6 shard-file fixtures: cli 1/4 + metadata, cli whole, and metadata keep declarations; cli 2/4, cli 4/4 and cli 11/12 skip them. YAML parses. NOT MEASURED: actionlint and shellcheck (no binary here); every CI family (no PR yet, per the landing rule); slices 2-4/4 not re-run as slices (declared narrowing: the whole-suite no-declarations run covers all their files green, and the slice map shows 0 readers in them).", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "0", "api_writes": "1 — this os-dev-report comment (POST /repos/objectstack-ai/objectstack/issues/25870/comments via scripts/pm/post-stamped.mjs). Not REST: 5 git pushes to claude/issue-25870-cli-reader-sequencer (empty branch, cherry-pick, fix, two merges of main).", "open_questions": [ { "question": "The dispatch says the PR body carries `Fixes #25870`. Ruling 6439314592 says the card closes only after the 10-full-queue-build reading is repeated after landing, and the card's acceptance needs 3 spec-touching PR runs. The os-dev DoD says to use `Part of` when the merge should not close the card. Which line goes in the body?", "options": [ "A `Part of #25870` (the draft uses this, as seat 1's draft did): merge leaves the card open for the readings", "B `Fixes #25870` as dispatched: merge closes the card before the ruling's after-landing reading" ], "recommendation": "A, because the ruling ties closing the card to the after-landing reading, and a merge-time close would hide the open speed check from the inbox." } ], "out_of_scope_findings": [ "carrier: #25870 (seat) · noted, not filed: the real cli slices are not equal-weight. Summed per-file seconds are 313/595/827/401, and cli 3/4 is the heaviest, the same slice as main's slowest shard 5/8. This PR removes that shard's closure but does not rebalance (option C, not ruled). It is the next lever if the CI reading misses ~20 min.", "carrier: none · noted in PR Acceptance notes: partitioner bin totals printed as 'Ns predicted' now include the reader slice's 783 s packing charge. driftReport() reads per-package timings, not bin totals, so the drift verdict is unaffected." ] }Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
devx seat 2 · answer to the dev's open question (os-dev-report 6458117958) · 2026-10-28T01:24Z
The PR body carries
Part of #25870, notFixes. Ruling 6439314592 closes the card only after the 10-full-queue-build reading is repeated after landing, and the card's acceptance (slowest Test Core shard ≤ ~20 min on three spec-touchingpull_requestruns) is read in CI after the PR exists. The dispatch order'sFixesline was the seat's error. Branchclaude/issue-25870-cli-reader-sequencer@c5a59dfe5fis now in contract review atCONTRACT_REVIEW_TIER. The seat opens the draft PR through the relay once the review and its ACCEPT are on record (Tier H).Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
Contract review
Served-tier:
CONTRACT_REVIEW_TIERHead-sha:
c5a59dfe5fc24489c4caaa78d87c8f7a81959a78Local-runs: none
Scope: .github/workflows/ci.yml + packages/cli/vitest.config.ts, scripts/partition-test-shards.mjs (its self-test is the same file), .github/workflows/test-nightly-tiers.yml, scripts/ci/plan-test-core-shards.mjs, packages/cli/package.json, packages/cli/tsconfig.build.json, turbo.json, scripts/nightly-tiers.mjs, and vitest 4.1.12's own
BaseSequencer.tsandpool.ts(the private math the config cites; read from the tag the lockfile pins, since this checkout carries no node_modules)Reviewed on the card, not a PR: by the seat's Tier H landing rule the review precedes
pr_create. Net difforigin/main...c5a59dfeis 3 files, +509/−24, four commits (seat 1's build cherry-picked, the rider fix, two merges of main). Inputs: the card body and all 22 comments, the diff and whole files at the head, nothing else.① Derived judgments
Check-runs: NONE exist for this head, because there is no PR. Every derived gate family is answered here only by the dev's local reading (86 derived, 86 exit 0 at c5a59df, report 6458117958); actionlint/shellcheck NOT MEASURED there either. The PR's CI is the seat's to read after
pr_create; nothing below counts as green until it does.Accept-set and surface changes the diff implies, each judged on the tree:
@objectstack/cli k/nwith k≠1 now setsOS_SKIP_DTS=1: its dependency closure and its owncli#build(testdependsOn: build, the cli build script honours the flag) emit no.d.ts. Right, conditional on the reader list being complete: the config pins exactly five files into slice 1, the five the two measurements (f486e9c, 4373103/9d1cfdbf) found red underOS_SKIP_DTS=1, and all five exist at the head underpackages/cli/test/.@objectstack/cli 1/n, the CLI whole, or@objectstack/metadatakeeps declarations as before. Right (ci.ymlcase ''|"$DTS_READER_SLICE"/*).expandSlicessetsrideWithonly when an anchor exists;partitionplaces riders straight after their anchor; self-test pins both directions).wholeLegProblems) and pin 3c (serialFloorOf,sliceCountProblems) still readweight, never the charge. Right.sliceAcrossShards) is expanded withNO_DECLARATION_READERS; test-nightly-tiers.yml sets noOS_SKIP_DTSanywhere, so nothing is skipped there and the sequencer, running with readers = [] in nightly mode, reproduces vitest's own split exactly. Right.calculateShardRangeis the config'sshardRangeline for line; the key isfullPath.slice(config.root.length), i.e./test/..., which is the config's/${relative};pool.ts:63-78builds ONE sequencer from the rootconfig.sequence.sequencerand callsshard()once over all projects' specs, so "read by the root context only" is a fact, andextends: trueon both projects changes nothing.packages/clifiles[]= dist, README.md, CHANGELOG.md;tsconfig.build.jsonincludessrconly, sovitest.config.tsand its two new exports never reachdist.check()calls (4 on the committed dataset/live tree, 7 spellings, 3 placement, 1 cap repair, 1 planRun);SELF_TEST_BATTERY_FLOOR16 → 17 with one new roster entry. Right.scripts/ci/plan-test-core-shards.mjsreads bins throughplanRun(), so the plan job and each shard's "Compute this shard's package set" see the same charged/ridden placement and the digest cannot disagree with it. Right.② Semver level
skip-changesetis right: the diff publishes nothing from any released package (workflow, a script underscripts/, and a vitest config outside the cli build'sinclude). Claim 6456145005'sClause-②: noandMetadata-protocol: nonehold: no spec key, value, type, default or meaning changes; no export of a published entry changes. No changeset owed, no BREAKING banner, no ADR-0087 disposition.③ Boundary flags
Part of #25870, notFixes. Ruling 6439314592 closes the card only after the 10-full-queue-build reading of 6430866969 is repeated after landing, and the card's own acceptance is three consecutive spec-touchingpull_requestruns at ≤ ~20 min, both after-landing readings. A merge-time close would hide both. The seat's answer stands; the draft body already says it.Ns predicted/all binsnow include the 783 s charge on one bin): see ④ should-fix S1.driftReport()is untouched and reads per-package timings, so the drift verdict is unaffected; judged on the code, not the report.OS_SKIP_DTS=1run covers every one of their files green and the slice map shows 0 readers in them) is a sound reading of the tree; CI runs them for real on the PR.④ Design judgment
Against ruling 6439314592 (letter A as specified in 6436991767): a sequencer in
packages/cli/vitest.config.tspins the declared readers (the five measured, plus any found: re-measured twice, none found) into slice 1/n; ci.yml keeps the closure for cli 1/n and metadata only, every other slice setsOS_SKIP_DTS=1; the partitioner charges that slice the closure and seats metadata with it so exactly one shard builds declarations; the "Choose this shard's declaration build" comment now listscreate-in-repo-scaffold-typechecks. All four parts are in the tree. The ⛔ list holds: no test skipped, quarantined or moved (noskip/todo/only, no tier change, nothing leaves Test Core); no timeout raised (notimeouttoken in the diff);SHARD_COUNTandFILE_SHARDED_PACKAGES(cli: 4) untouched; the ci.yml hunks are at lines 913–960 only, inside thetest:job's one step and its comment, no other job touched.Breaking it, each in turn:
OS_SKIP_DTS=1? Not a listed one. The five are placed first inordered, slice 1's range starts at 0, and a reader count past the slice's own range (readers.lengthoverend − start) is refused at load, so they are in slice 1 for any n the partitioner can emit; ci.yml keeps declarations for1/*, for an unsliced cli, and for metadata; the three spellings of the index (ci.ymlDTS_READER_SLICE='1', configDECLARATION_READER_SLICE = 1, partitionerDECLARATION_READER_SLICES) are read back against each other by the self-test in code position, and a fourth pin reds when a sliced reader package has no reader slice at all. Metadata's own reader (typescript-serializer-annotation) rides to the reader shard or, when the cli is whole/absent, keeps its own shard's declarations as today. The nightly never skips. The only hole is an UNLISTED new reader, which is the ruling's accepted facet ③: on slices 2–4 (three in four by sha1) it reds its own PR deterministically with TS7016/ENOENT; on slice 1 it passes until a later population change moves the cut past it (S2 below).--shardrange math? Yes, verified against vitest 4.1.12 (BaseSequencer.calculateShardRangeand the sha1 key, above). And the pin's correctness does not even depend on the match: every index cuts the sameorderedsequence with the same function, so the union is the whole population and the slices are disjoint whatever vitest's private math becomes on an upgrade. Ties are impossible (distinct paths, sha1 hex compare), so the order is total and deterministic across slices.casekeep and skip the right lines?@objectstack/clialone → SLICE empty →''arm → kept.@objectstack/metadata→ kept.@objectstack/cli 1/4→1/*→ kept.cli 2/4,cli 4/4→ skipped.cli 11/12→11/12does not match1/*(the glob needs1/as prefix) → skipped. A quoted expansion inside acasepattern is literal in bash, which is therun:shell. An empty shard file → KEEP empty →OS_SKIP_DTS=1, harmless. The failure direction, were the partitioner to co-locatecli 2/4with metadata, is the safe one (metadata keeps declarations for both).OS_TEST_TIERSunset), naming the file; so a rename must carry the list. A nightly-mode load skips the population check and the sequencer sees no readers, so the nightly's 2-way CLI slicing is byte-identical to main's.refineToCap()? Yes.fixed= every slice plus every item whoserideWithnames a present item;giveandtakeboth requiremovable, so metadata can neither be moved off the reader bin nor swapped into another; the fixture (bin 800 s over a 600 s cap where movingmwould strictly lower it) pins the rule. The reader bin'stotalkeeps the 783 s charge whileweightOfreads plainweight, which is consistent withpartition()'sputand is what makes the repair push whole packages OFF that bin (the intent). ThewithinCaparm cannot flip the CLI back to whole over the charge: the cap is the whole-package LPT max of the dataset, which holds the CLI whole at 2697 s, so it is ≥ 2697 s against a reader bin of 783 + 674 + 143 ≈ 1600 s.ROOM_SECONDSpin holds 300 s of that gap as a literal), and 1 shard builds declarations instead of 5. Whether that reaches ≤ ~20 min is the PR's CI reading, not this record's.Findings:
shard k/8: ... Ns predicted (all bins: .../...s ...)andbalanceOf()'s max/mean now carry the 783 s packing charge on the reader slice's bin without saying so; a reader of a slice shard's log will read ~1600 s as test seconds. One word in that line (or printing the charge beside the bin) closes it. Pin 2's ratio is graded on the same packed totals, which is the intended packing shape, so no verdict changes.No must-fix.
Implemented-by:
claude/issue-25870-cli-reader-sequencerReviewed-by:
session_01QSeKYmTYfaPbLQD4BJfomWVERDICT: PASS
objectstack-fleet commentedon Oct 28, 2026
devx seat 2 · PR opened · 2026-10-28T01:34Z
Draft PR #27018 opened through the relay from
claude/issue-25870-cli-reader-sequencer@c5a59dfe5f, after contract review 6458259422 (PASS). Its body is the dev's draft plus the review's two should-fix notes in Acceptance notes.Part of #25870. Tier H:GOVERNED_APPROVERSwere requested on open. The seat writes its## 席位核对once the PR's CI has read the card's acceptance.Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
Landed (partial): ruling A built, via PR #27018, merged as
6d9e5a1874· 2026-10-28T02:24ZRelease:
session_01QSeKYmTYfaPbLQD4BJfomW(domain:devx#2) · partial landing · landed: the cli's five declaration-reading test files are pinned into slice 1/n, only cli 1/n + metadata build declarations, and the partitioner charges that slice the closure · remaining: the card's acceptance readings, which only time and CI runs can answer · state:pm:dispatched→pm:on-hold, assignee clearedThe merged diff matches the reviewed head
c5a59dfe5f(sorted +/− lines hash-identical). Seat record → PR #27018 comment 6458499735. Two independent contract reviews atCONTRACT_REVIEW_TIER, both PASS: 6458259422 (on this card) and 6458668091 (on the PR). Landing regime: Tier H by the maintainer's hand. os-zhuang, aGOVERNED_APPROVERSaccount, readied, armed and enqueued it;check-governed-merges --pr 27018reads "the maintainer's hand, or an authorized APPROVED review".Restart-when: three
pull_requestCI runs whose diff touchespackages/spec/**have completed on heads based at or after6d9e5a1874; read the slowestTest Core (k/8)job wall time on each (acceptance: ≤ ~20 min on all three), then repeat the 10-full-queue-build reading of 6430866969 (ruling 6439314592); close the card if both hold, or reopen work on the next lever (the uneven cli slices 313/595/827/401 s, unruled option C) if they do not.Data point so far, not an acceptance reading: on the PR's own run (no
packages/specchange), the slowest shard was 5/8 at 12 min 08 s.Generated by Claude Code