Skip to content

Commit 436d4a2

Browse files
marius-bughiuclaude
andcommitted
fix(dashboard): require the primary item count in the coverage guard
The report-backed check accepted a BCL+Celerity pair at any of a collection's item counts, but a grid card's chart is always `seriesFor(..., primaryN)` — the ratio text falls back to the smaller count, the sparkline does not. So a collection with data only at 1k rendered "awaiting data" while the guard passed. Check the primary count alone, which is what decides the card. Also condense the two new CHANGELOG entries to the documented "a few sentences" budget, since release.yml lifts the whole section into the GitHub Release body. Both raised in review on #327. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 0d543bd commit 436d4a2

2 files changed

Lines changed: 11 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ All notable changes to Celerity are documented here. This project follows [Keep
1717

1818
### Fixed
1919

20-
- **The `EnumMap` and `EnumSet` cards on the benchmark dashboard rendered empty.** The page required an `(ItemCount: N)` suffix on every result name, and those two benchmarks deliberately declare no item-count sweep — the enum universe is bounded — so their measurements were published to `gh-pages` and then discarded at render time. Both cards now chart their real numbers, on the grid and on their detail pages, and unparameterized benchmarks are excluded from the headline speedup stats rather than bucketed at zero items. Closes [#301](https://github.com/marius-bughiu/Celerity/issues/301).
21-
- A blank dashboard card is now a red CI check instead of a silent gap. `scripts/check_dashboard_coverage.js` asserts that the two `COLLECTIONS` arrays agree, that every charted collection is registered in the CI benchmark suite, and — against the merged benchmark report — that every published result name parses and every card resolves to both a BCL and a Celerity measurement. It runs on every PR in `ci.yml` and, in full, in the aggregate job of `benchmarks.yml`. Closes [#301](https://github.com/marius-bughiu/Celerity/issues/301).
20+
- **The `EnumMap` and `EnumSet` cards on the benchmark dashboard rendered empty.** The page required an `(ItemCount: N)` suffix on every result name, and both benchmarks deliberately declare no item-count sweep, so their measurements were published and then discarded at render time. Both cards now chart their real numbers, and unparameterized benchmarks are excluded from the headline speedup stats. Closes [#301](https://github.com/marius-bughiu/Celerity/issues/301).
21+
- A blank dashboard card is now a red CI check rather than a silent gap: `scripts/check_dashboard_coverage.js` fails when a published result name is unparseable, when a card has no measurements behind it, or when a charted collection is missing from either `COLLECTIONS` array or from the CI benchmark suite. Closes [#301](https://github.com/marius-bughiu/Celerity/issues/301).
2222
- **The coverage gate measured only one of the six shipped packages.** Coverlet's assembly filter is exact-match, so `Celerity.Hashing`, `Celerity.Primitives`, and the three showcase packages had been outside the gate since the 2.0.0 package split — any of them could have dropped to 0% with CI green. All six are now measured, the gaps that exposed are backfilled to **100% line and branch** coverage, and the floor is raised from 95%/90% to match. Closes [#314](https://github.com/marius-bughiu/Celerity/issues/314).
2323

2424
## [2.4.0] - 2026-07-26

scripts/check_dashboard_coverage.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -167,15 +167,17 @@ function main() {
167167
}
168168

169169
for (const col of index.COLLECTIONS) {
170+
// The primary count, exactly as index.html picks it: a card's ratio text may fall
171+
// back to the smaller count, but its chart is always seriesFor(..., primaryN), and
172+
// that is what decides between a sparkline and "awaiting data". So the primary
173+
// count is the one that has to resolve.
170174
const items = col.items || [1000, 100000];
175+
const primaryN = items[items.length - 1];
171176
for (const op of col.ops) {
172-
const resolved = items.some((n) => {
173-
const pair = idx[index.idxKey(col.key, op, n)];
174-
return pair && pair.bcl && pair.celerity;
175-
});
176-
if (!resolved) {
177-
const at = items.map((n) => (n == null ? 'no sweep' : n)).join(' / ');
178-
problems.push(`${col.key}.${op} has no BCL+Celerity pair at ${at} — that card renders empty.`);
177+
const pair = idx[index.idxKey(col.key, op, primaryN)];
178+
if (!pair || !pair.bcl || !pair.celerity) {
179+
const at = primaryN == null ? 'no sweep' : primaryN;
180+
problems.push(`${col.key}.${op} has no BCL+Celerity pair at ${at} — that card renders "awaiting data".`);
179181
}
180182
}
181183
}

0 commit comments

Comments
 (0)