Repository navigation
ci(test-core): build declarations on one CLI slice only — pin the CLI's declaration readers into slice 1/n - #27018
Conversation
…'s declaration readers into slice 1/n The five CLI test files that compile against built .d.ts sat in all four CLI slices by vitest's sha1 split, so five Test Core shards built the declaration closure (~4.5 min) for one or two files each. A sequencer in packages/cli/vitest.config.ts now puts them first in vitest's own order, so they land in slice 1/n; ci.yml keeps declarations for a whole reader or slice 1/* only; the partitioner charges that slice the closure (270 s x 2.9 of packing weight) and seats @objectstack/metadata beside it, so one shard builds declarations instead of five. Claude-Session: https://claude.ai/code/session_01JQwxbaFpnMwgpCgneKe2qS Co-authored-by: Claude <noreply@anthropic.com>
…th the reader slice out of the cap repair refineToCap() moved any whole package off the densest bin, the rider included, which would put declarations on a second shard. The rider now stays with its slice like the slice itself; the self-test gains the fixture where only that rule keeps it there. Claude-Session: https://claude.ai/code/session_01QSeKYmTYfaPbLQD4BJfomW Co-authored-by: Claude <noreply@anthropic.com>
…i-reader-sequencer
…i-reader-sequencer
📓 Docs Drift Check5 anchor(s) derived from 1 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run. What this run could not see
Coarse fallback — 32 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin d7d6b5547a5caa1e0eed0254ecd6ce653502bfcd && git checkout d7d6b5547a5caa1e0eed0254ecd6ce653502bfcd
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 7eb613c39fb85cc1e4d0b658c9ecea4e45949c99 c5a59dfe5fc24489c4caaa78d87c8f7a81959a78 && git checkout -B drift-repro 7eb613c39fb85cc1e4d0b658c9ecea4e45949c99 && git merge --no-ff c5a59dfe5fc24489c4caaa78d87c8f7a81959a78
node scripts/docs-audit/affected-docs.mjs --json 7eb613c39fb85cc1e4d0b658c9ecea4e45949c99 |
席位核对 — ACCEPT · domain:devx#2 · head
|
Contract reviewServed-tier: Reviewed on PR #27018, adversarially against the dev report 6458117958, the seat's earlier record 6458259422 and the seat's ACCEPT 6458499735. Inputs: the card body and all 23 comments; the PR body, file list and the net diff ① Derived judgmentsGate verdicts on the head: 56 success, 11 skipped (opt-in and path-filtered jobs), 0 failure, 0 pending. Test Core 8/8 success, Plan Test Core shards success, Test completeness guard success on every shard, Build Core, Check Changeset, Governed Surface Queue Guard, PR-body guards, Lint (all nine), Type Check (all five) success. Accept-set and surface changes the diff implies, each judged on the tree:
② Semver level
③ Boundary flags
No must-fix. Implemented-by: VERDICT: PASS Generated by Claude Code |
Part of #25870
Ruling-ref: 6439314592
Clause-②: no
Metadata-protocol: none
维护者速读
.d.ts。现在 vitest 把它们固定排进第 1 片(sequencer 在packages/cli/vitest.config.ts)。Test Core 只在带 cli 1/4 的那个分片构建声明,metadata 也被排到同一分片;其余分片都设OS_SKIP_DTS=1。.github/workflows/ci.yml里 "Choose this shard's declaration build" 一步的case判断;packages/cli/vitest.config.ts的DeclarationReaderSequencer.shard();scripts/partition-test-shards.mjs的partition()/refineToCap()对rideWith的处理。node scripts/partition-test-shards.mjs --self-test,应看到self-test OK和whole legs 143/1597/1597/925/924/923/1599/1597s,其中第 1 分片只放 cli 1/4 和 metadata。GOVERNED_APPROVERS身份审阅并批准这个 Tier H PR(.github/workflows/ci.yml)。What changes
Ruling A (6439314592), as specified in 6436991767, built on seat 1's commit
7e64f7c1d3(cherry-picked onto currentmain, every hunk re-read and re-verified here) plus one fix:packages/cli/vitest.config.ts.DECLARATION_READER_FILESlists the 5 files that compile against built declarations.DeclarationReaderSequenceroverrides onlyshard(). It puts the readers first and the remaining files in vitest's own sha1 order (key/+ root-relative path, the same asBaseSequencer), then cuts that sequence with vitest's own equal-count ranges. The readers land in slice 1/n, and every other file moves at most 5 places along vitest's order. The config refuses to load when a listed reader is missing from the queue population. It also refuses when the readers do not fit in slice 1/n. With no shard set, or in a nightly-tier run (no readers in the population), the order is vitest's own..github/workflows/ci.yml, the Test Core "Choose this shard's declaration build" step and its comment only.DTS_READER_SLICE='1': a shard keeps declarations when it carries a whole reader package or slice1/*of one. Every other shard setsOS_SKIP_DTS=1. The comment now listscreate-in-repo-scaffold-typechecks, which the earlier list missed.scripts/partition-test-shards.mjs.serialFloorOf()are unchanged.DECLARATION_READER_PACKAGES(@objectstack/metadata) rides into the reader slice's bin, so one shard builds declarations, not two.refineToCap()could move the riding whole reader off the reader slice's shard. That would put declarations back on a second shard. Riders are now fixed in place like slices. The self-test gains the fixture where only that rule keeps the rider in place.⛔ Unchanged: no test is skipped or quarantined, no timeout is raised, no test leaves Test Core, the shard count stays 8, and no other
ci.ymljob is touched.Tests
All readings are local, on a shared 4-core box, so wall-clock figures are shared-box seconds.
Reader set re-derived on current main (merge base 912076f)
OS_SKIP_DTS=1 turbo run build --filter=@objectstack/cli --filter=@objectstack/metadata: 61/61 tasks, and 0.d.tsfiles underpackages/spec/distandpackages/cli/dist.vitest run --maxWorkers=3, under the verify lock) gaveVERDICT command-exit 1, withTest Files 5 failed | 514 passed | 1 skipped (520)andTests 25 failed | 6432 passed | 9 skipped (6466). The red files are exactly the 5 listed inDECLARATION_READER_FILES, and every one fails for missing declarations:create-in-repo-scaffold-typechecks: TS7016published-subpath-console.pin: TS7016, ENOENT ondist/console.d.tspublished-subpath-hook-body.pin: TS7016, ENOENT ondist/hook-body.d.tsscaffold-emission-typechecks: TS7016 / TS2307scaffold-test-script-passes: TS7016.d.ts), runningOS_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.Slice map, from vitest's own context on the real config
createVitest+globTestSpecifications()+config.sequence.sequenceragainstBaseSequencer, forOS_TEST_SHARD=k/4:BaseSequencer)DeclarationReaderSequencer)Placement and wall model, full `turbo ls` list (129 packages, dogfood excluded)
Partitioner self-test and ablations
node scripts/partition-test-shards.mjs --self-test:self-test OK (75 measured packages -> 78 shard items, 8 shards, max/mean 1.00x ..., whole legs 143/1597/1597/925/924/923/1599/1597s within 1868s, file-level slices: @objectstack/cli x4).scripts/ablation-replace.mjs:the cap repair moved the whole reader off the reader slice's shard.git diff HEADis empty.c5a59dfe5f. Each went throughablation-replace.mjswith the anchor going 1 to 0, and each was restored to blob == HEAD with an emptygit diff HEAD:cli 1/4's shard carries 826s of whole packages against [826, 827, 826]s ... not 300s less;@objectstack/metadata is on shard 2, not with @objectstack/cli 1/4 on shard 1;DTS_READER_SLICE='2': exit 1,DECLARATION_READER_SLICES says slice 1, ci.yml DTS_READER_SLICE says 2;its vitest config does not install DeclarationReaderSequencer;DECLARATION_READER_FILES(slice map re-read through vitest's context):scaffold-test-script-passesmoves to slice 2/4, a declaration-less slice, where the run above shows it red with TS7016. My first attempt at this one was refused by the tool, because the replacement text was not unique. It was restored, and the second attempt used a unique marker.Acceptance notes
Acceptance is NOT MEASURED here: the card asks for the slowest Test Core shard ≤ ~20 min on 3 consecutive spec-touching
pull_requestruns. That can only be read on this PR in CI. After landing, the ruling repeats the 10-full-queue-build reading of 6430866969 before the card closes, so this PR saysPart of, notFixes.Real slices are not equal-weight. The summed per-file seconds above make cli 3/4 the heaviest slice, which is the same slice as the slowest shard on main (5/8). This PR removes that shard's closure. It does not rebalance the slices (option C, not ruled).
The partitioner's per-shard "Ns predicted" bin totals now include the reader slice's 783 s packing charge (closure, never test weight).
driftReport()reads per-package timings, not bin totals, so the drift verdict is unaffected.Changeset:
skip-changeset.@objectstack/clishipsfiles: ["dist", "README.md", "CHANGELOG.md"].DeclarationReaderSequencer/DECLARATION_READER_FILEShave 0 hits under those paths, and the positive control (hook-bodyunderdist/) hits.scripts/and.github/are not published.Contract review (seat, before this PR opened): card comment 6458259422,
CONTRACT_REVIEW_TIER, PASS onc5a59dfe5f, no must-fix. Its two should-fix notes:DECLARATION_READER_FILESpasses as long as vitest's sha1 cut happens to put it in slice 1 (about one chance in four). A later population change that moves the cut then reds an unrelated PR. That red means "add the file toDECLARATION_READER_FILES", not a flake. A listed reader that is renamed or deleted already refuses the config at load.Ns predicted (all bins: ...)line andbalanceOf()now include the reader slice's 783 s packing charge without saying so.driftReport()is untouched, so no verdict changes. The wording fix rides a follow-up.Verification
Final head
c5a59dfe5f. It is a clean merge oforigin/mainthat includes #26854 and the #25452 cache steps, in regions disjoint from this diff.packages/cliis unchanged across both merges. The reader and slice readings above were taken at9d1cfdbf63, which is merge base912076f885plus this diff.Derived gates at c5a59df
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 86 families. All 86 exited 0, each exit captured before any pipe.--ranreported:86 derived, 86 run, 0 NOT-MEASURED, 0 UNRUN(a derived zero: all 86 recorded an exit code).849642eb8c,check:dts-closureandcheck:dual-build-cjs-loadsfirst exited 1 and 3. That run overlapped my own rebuild of the closure, which hadtsupcleaning dists. Re-run on the settled tree, both exited 0:233/233 declared declaration file(s) presentand112 published require entry point(s) across 69 package(s) load. Both are 0 again on the final head.pnpm --filter @objectstack/cli typecheck, which compilesvitest.config.tsthroughtsconfig.test.json, gaveVERDICT command-exit 0andcheck:test-typecheck: OK. A first run went red in../objectql/src/picklist-resolution.tsbecausemetadata-core's dist was stale after the merge. It went green after rebuilding the closure.cli 1/4+ metadata,cliwhole, andmetadataalone keep declarations;cli 2/4+ metadata-core, client-react +cli 4/4, andcli 11/12setOS_SKIP_DTS=1.Generated by Claude Code