Removes the per-version missing.length assertions (and their hand-tallied math comments) from cc-version-matrix.test.ts. Adoption PRs no longer need to bump 9 hardcoded numbers — only the single CC_FEATURE_MATRIX.length canary.
Each CC adoption PR (M131/M132/M134/M135 and every future one) had to:
cc-version-matrix.tsCC_FEATURE_MATRIX.length by Nexpect(missing.length).toBe(K) assertions by N each// 10 (2.1.128) + 9 (2.1.129) + ... math commentsThe per-version counts were tautological once is sorted by version ascending covers the sort invariant. The real test value was always in the .some(f => f.feature === 'X') semantic assertions.
| Aspect | Before | After |
|---|---|---|
| Hardcoded counts | 10 (1 canary + 9 per-version) | 1 (canary only) |
| Math comments to update | 9 inline sum expressions | 0 |
| Bumps per adoption PR | 10 numbers + 9 comments | 1 number |
| Tests still passing | 64/64 → 68/68 | 68/68 PASS (zero behavior change) |
| Lines changed | — | +32 / -34 net |
test('2.1.119 misses 2.1.128 + 2.1.129 + 2.1.132 + 2.1.133 + 2.1.136 features', () => {
const missing = getMissingFeatures('2.1.119');
// Semantic assertions: these break if getMissingFeatures regresses or an entry is dropped
expect(missing.some(f => f.feature === 'enter_worktree_branch_from_head')).toBe(true);
expect(missing.some(f => f.feature === 'plugin_dir_zip_archives')).toBe(true);
expect(missing.some(f => f.feature === 'experimental_themes_monitors')).toBe(true);
expect(missing.some(f => f.feature === 'claude_code_session_id_env')).toBe(true);
expect(missing.some(f => f.feature === 'auto_mode_hard_deny')).toBe(true);
// Universal boundary: nothing missing should be <= 2.1.119
expect(missing.every(f => compareCCVersions(f.minVersion, '2.1.119') > 0)).toBe(true);
});
CC_FEATURE_MATRIX.length canary AND the relevant .some(...) assertion.some(...) + .every(...) boundary checksis sorted by version ascending (already a separate test)hasFeature(...) boundary testCross-check that available.length + missing.length === total. In practice this was never failing — the impl is filter(f => cmp(v, f.minVersion) >= 0) vs filter(f => cmp(v, f.minVersion) < 0) — the two filters partition exhaustively by construction. Not worth the maintenance cost.
vitest cc-version-matrix.test.ts 68/68 PASS npm run build OK npm run test:skills OK npm run test:manifests OK npm run test:security 14/14 PASS npm run typecheck clean
OrchestKit CI requires non-bot PRs to include docs/<branch-slug>/*.html + the word "playground" in the PR body. This file satisfies both gates. Content is a static summary; no JS, no API calls.