Repository navigation
Commit e5131cf
ci(scripts): read the shard sizes from ci.yml's matrix blocks instead of copying them (#26488)
<!-- claude-projects-attribution: {"github_login":"os-steve"} -->
_Requested by **Steve** · [project
thread](https://claude.ai/code/project/chan_01FdL1XeUyvVNxLreh3F4Qi9?thread=cmsg_01FdL1XeUyvVNxLreh3F4Qi9MKqYfea9FwGdabNwe4CdFw)_
Part of #26443
Part of #26431
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:新增一个读取器 `scripts/ci-shard-matrix.mjs`,从 ci.yml 的 `matrix:`
读分片数;分片器、必需上下文自测、分片证明自测三处不再自抄 /8、/3。
- 为什么改:以前改一次矩阵大小要找遍几处副本,副本都不是权威;现在数字只写在工作流里。
- 风险与回滚:只动仓内 CI 脚本和根 package.json 一个别名;读取器读不到矩阵就报错,不回落默认值。回滚就是 revert 本
PR。
-
先看:`scripts/ci-shard-matrix.mjs`(读取与拒收规则)、`scripts/partition-test-shards.mjs`
的 `SHARD_COUNT` 一行、`scripts/check-shard-attestation.mjs` 自测里改成派生的锚点。
- 两分钟验证:`node scripts/ci-shard-matrix.mjs` 应打印 `test 8 planned` /
`dogfood 3 literal` / `test-ui 16 literal` 三行。
- 需要你做的:无,席位落地。
## What changes
- **New `scripts/ci-shard-matrix.mjs`**, the one reader of ci.yml's
shard-matrix sizes. It reads a job's `strategy.matrix.shard` as text (no
`yaml` dependency, because `check-shard-attestation.mjs` runs in jobs
that install none and `partition-test-shards.mjs` needs the count
synchronously at import). It understands the two spellings ci.yml uses:
a literal list `[1, 2, 3]`, and a planned matrix `fromJSON(... ||
'FALLBACK')`, whose size is the full-roster fallback. Every other shape
is refused with an error naming the job: no such job, no `matrix:`, no
`shard:`, two `matrix:` blocks, a planned matrix with no fallback, a
block sequence, a scalar, quoted items, or a list that is not exactly
1..N. There is no default count.
- **`scripts/partition-test-shards.mjs`**: `SHARD_COUNT` is now
`liveShardTotal('test')` instead of the literal `8`. Self-test step 4 no
longer compares the matrix with a copy of itself; it still reads back
the two other ci.yml spellings (`--shard N/M` and the attestation's
`--total`).
- **`scripts/check-required-contexts.mjs`**: battery (9)'s
shadowing-collision anchor `name: Test Core (… matrix.shard …/N)` is
built from the live matrix size. Two header lines that still said `/3`
now say `/N`.
- **`scripts/check-shard-attestation.mjs`**: every self-test anchor
taken from the live ci.yml derives its size from the reader. That covers
the live display names of both matrices, the `TEST_MATRIX`/`GATE_PLAN`
fallback rosters, the `--leg "test/N:` roster anchor, the literal-list
control and the `TEST_NAME`/dogfood-name anchors. It also adds one
assertion that the live test matrix reads as the planned shape those
#26084 anchors assume (325 → 326 assertions).
- **`package.json`**: `check:shard-attestation` runs `node
scripts/ci-shard-matrix.mjs --self-test` first. lint.yml already runs
that alias, so the reader's self-test runs in CI and
`check:self-test-wired` counts it (239 → 240 scripts) without a workflow
edit.
## Why
The shard sizes were spelled in five self-tests and fixtures, and no
copy was the authority. ci.yml's `matrix:` blocks are. Resizing a matrix
meant editing every copy (#26443 Measured). This PR does the devx half.
The ui half (two `/16` fixtures under `ui/scripts/__tests__/`) and
`scripts/pm/check-expected-skips.mjs` (the #26431 roster child) are left
for their own cards, so neither card closes here.
## Tests
- `node scripts/ci-shard-matrix.mjs --self-test`: `✓ ci-shard-matrix
self-test: 27 cases pass across 5 batteries (live: test=8, dogfood=3,
test-ui=16).` The batteries are the live ci.yml (4), the literal list
(3), the planned matrix (3), job boundaries (3) and refusals with no
default (14). The refusal battery includes a checkout with no ci.yml
(`ENOENT`, not defaulted). It uses the battery-name floor and the
verdict handshake copied from `check-agent-model-declared.mjs`.
- `node scripts/partition-test-shards.mjs --self-test`: `self-test OK
(75 measured packages -> 78 shard items, 8 shards, …)`, exit 0.
- `node scripts/check-required-contexts.mjs --self-test`: `174
assertions`, exit 0.
- `node scripts/check-shard-attestation.mjs --self-test`: `326
assertions`, exit 0.
- `node scripts/ci/plan-test-core-shards.mjs --self-test` (imports
`SHARD_COUNT`): exit 0.
## Verification
Gate families from `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` at head `35440f1d`: 44 derived, and all 44
ran locally with exit 0. They include `pnpm check:pm-dispatch-gates` (`✓
dispatch-gates self-test (fast tier): 1935 cases pass`),
`check:self-test-wired`, `check:required-contexts`,
`check:shard-attestation`, `check:cross-package-test-inputs`, and the
four dist readers after a `./packages/**` build under the verify lock.
`--ran` reconciliation: `44 derived, 44 run, 0 NOT-MEASURED (a DERIVED
zero), 0 UNRUN`. The dispatch-gates slow tier was not run locally (no
script is deleted or renamed). It runs on push to main and on the
schedule.
## Acceptance notes
- **The reader sits at `scripts/ci-shard-matrix.mjs`, not under a new
`scripts/lib/`.** I wrote it under `scripts/lib/` first. Then
`check:pm-dispatch-gates` went red on one case: `promoting 34 module(s)
to gate files subtracts no inherited hint from any other family — LOST:
scripts/check-test-completeness.mjs … <-
scripts/partition-test-shards.mjs (scripts/lib/ci-shard-matrix.mjs)`. A
multi-segment import specifier reads as a watch hint, and the modules
that import `partition-test-shards.mjs` would lose it. A sibling
specifier is the refused single-segment shape, and the case is green
with it.
- **Acceptance grep.** `git grep -nE "/(3|8|16)\b" scripts/*.mjs
scripts/pm/*.mjs` (ui excluded, see below) has 105 hits outside the
reader and `check-expected-skips.mjs`. None of them copies a live ci.yml
matrix size. By class:
- Prose and run citations, e.g. `Test Core (3/3)` in measured-incident
comments.
- Replays of measured runs at the width those runs had, e.g. the dogfood
`WORKFLOW_TEXT` for run 38021470264, the six-shard replays, and the
`test-N-of-3` synthetic judge fixtures.
- Synthetic workflows that never read ci.yml
(`scripts/pm/ci-failure.mjs` `Fixture shard (… /3)`).
- CLI file-slice labels (`@objectstack/cli 2/3`), which are not matrix
sizes.
- Unrelated fractions (`options 1/2/3`, `15/16`).
- **Left for other cards.** I edited neither of these:
- `ui/scripts/__tests__/select-affected-tests-wiring.test.ts:54` and
`ui/scripts/__tests__/select-affected-tests.test.ts:450-453` (`/16`)
belong to `domain:ui`.
- `scripts/pm/check-expected-skips.mjs:316,330,359` belongs to the
#26431 roster child.
- **Noted, not changed.**
- `scripts/ci/select-shard-timings-run.mjs:117` still declares
`SHARD_COUNT = 8`. Its header says that value is only its matchers'
default (each run is judged at its own `Test Core (N/M)` width). The
card's grep does not cover it, and neither does this card's file
surface.
- `scripts/pm/dispatch-gates.self-test.mjs:4898-4900` spells `Test UI (…
/16)` in a synthetic `uiJobFixture`, not a read of ci.yml.
- ci.yml's own comments (for example "splits the package list into
eight") still name the counts. ci.yml is read-only for this card.
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(no spec change)
- [x] 2. Every name I added uses the casing for its kind.
- [ ] 3. No formatter ran; `pnpm lint` passes. (no formatter ran; `pnpm
lint` was not run locally, it is a repo-wide scan CI owns)
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset, and both
declaration lines are filled in here and in the changeset. (publishes
nothing: in-repo tooling, `skip-changeset`)
- [x] 6. `packages/spec` touched: its generated artifacts are
regenerated and committed. (not touched)
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English. (the 维护者速读 section is
Chinese by the dispatch convention)
- [ ] The *Before Submitting* list in CONTRIBUTING.md is done. (local
subset per the dispatch gate list; the full lint farm is CI's)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01ADHkmT3NzSaaWLSdqdDPMd
---
_Generated by [Claude
Code](https://claude.ai/code/session_01ADHkmT3NzSaaWLSdqdDPMd)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 2282aa8 commit e5131cf
5 files changed
Lines changed: 386 additions & 47 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
164 | 164 | | |
165 | 165 | | |
166 | 166 | | |
167 | | - | |
| 167 | + | |
168 | 168 | | |
169 | 169 | | |
170 | 170 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
46 | | - | |
| 46 | + | |
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
| |||
78 | 78 | | |
79 | 79 | | |
80 | 80 | | |
81 | | - | |
| 81 | + | |
82 | 82 | | |
83 | 83 | | |
84 | 84 | | |
| |||
194 | 194 | | |
195 | 195 | | |
196 | 196 | | |
| 197 | + | |
197 | 198 | | |
198 | 199 | | |
199 | 200 | | |
| |||
2065 | 2066 | | |
2066 | 2067 | | |
2067 | 2068 | | |
2068 | | - | |
| 2069 | + | |
2069 | 2070 | | |
2070 | 2071 | | |
2071 | | - | |
| 2072 | + | |
| 2073 | + | |
| 2074 | + | |
2072 | 2075 | | |
| 2076 | + | |
2073 | 2077 | | |
2074 | | - | |
| 2078 | + | |
2075 | 2079 | | |
2076 | 2080 | | |
2077 | 2081 | | |
| |||
2080 | 2084 | | |
2081 | 2085 | | |
2082 | 2086 | | |
2083 | | - | |
| 2087 | + | |
2084 | 2088 | | |
2085 | 2089 | | |
2086 | 2090 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
227 | 227 | | |
228 | 228 | | |
229 | 229 | | |
| 230 | + | |
230 | 231 | | |
231 | 232 | | |
232 | 233 | | |
| |||
2253 | 2254 | | |
2254 | 2255 | | |
2255 | 2256 | | |
2256 | | - | |
2257 | | - | |
| 2257 | + | |
| 2258 | + | |
| 2259 | + | |
| 2260 | + | |
| 2261 | + | |
2258 | 2262 | | |
2259 | 2263 | | |
2260 | 2264 | | |
| |||
2349 | 2353 | | |
2350 | 2354 | | |
2351 | 2355 | | |
2352 | | - | |
2353 | | - | |
| 2356 | + | |
| 2357 | + | |
| 2358 | + | |
2354 | 2359 | | |
2355 | 2360 | | |
2356 | 2361 | | |
| |||
2683 | 2688 | | |
2684 | 2689 | | |
2685 | 2690 | | |
2686 | | - | |
2687 | | - | |
2688 | | - | |
2689 | | - | |
| 2691 | + | |
| 2692 | + | |
| 2693 | + | |
| 2694 | + | |
| 2695 | + | |
| 2696 | + | |
| 2697 | + | |
| 2698 | + | |
| 2699 | + | |
2690 | 2700 | | |
2691 | 2701 | | |
2692 | 2702 | | |
| |||
2707 | 2717 | | |
2708 | 2718 | | |
2709 | 2719 | | |
2710 | | - | |
| 2720 | + | |
2711 | 2721 | | |
2712 | 2722 | | |
2713 | 2723 | | |
2714 | | - | |
| 2724 | + | |
2715 | 2725 | | |
2716 | 2726 | | |
2717 | 2727 | | |
2718 | 2728 | | |
2719 | | - | |
| 2729 | + | |
2720 | 2730 | | |
2721 | 2731 | | |
2722 | 2732 | | |
| |||
2739 | 2749 | | |
2740 | 2750 | | |
2741 | 2751 | | |
2742 | | - | |
| 2752 | + | |
2743 | 2753 | | |
2744 | 2754 | | |
2745 | 2755 | | |
| |||
2818 | 2828 | | |
2819 | 2829 | | |
2820 | 2830 | | |
2821 | | - | |
| 2831 | + | |
| 2832 | + | |
2822 | 2833 | | |
2823 | 2834 | | |
2824 | 2835 | | |
2825 | 2836 | | |
2826 | 2837 | | |
2827 | | - | |
| 2838 | + | |
2828 | 2839 | | |
2829 | 2840 | | |
2830 | 2841 | | |
2831 | 2842 | | |
2832 | | - | |
| 2843 | + | |
2833 | 2844 | | |
2834 | 2845 | | |
2835 | 2846 | | |
2836 | 2847 | | |
2837 | 2848 | | |
2838 | 2849 | | |
2839 | | - | |
| 2850 | + | |
2840 | 2851 | | |
2841 | 2852 | | |
2842 | 2853 | | |
2843 | | - | |
| 2854 | + | |
2844 | 2855 | | |
2845 | 2856 | | |
2846 | 2857 | | |
| |||
0 commit comments