Finding
tests/tools/coverage-report.mjs already implements a coverage regression gate. Nothing uses it.
node tests/tools/coverage-report.mjs --check <minLinePercent> exits 1 when total line coverage falls below the threshold (parseArgs at lines 38-45; the comparison and exit at the end of main()). But package.json:63 defines:
"test:unit:coverage": "TZ=UTC node tests/tools/coverage-report.mjs"
with no --check, and that is the only entry point anything calls. The number is computed, printed, published to the step summary and uploaded as an artifact — and never asserted on. A change that drops line coverage from 98.94% to 40% produces a green build and a quieter artifact nobody diffs.
The other two workflows that run tests (.github/workflows/deploy-gh-pages.yml:40 and .github/workflows/import-architectures.yml:28) call plain npm run test:unit, so they do not measure coverage at all.
Measured at rev a994a2e in a fresh clone after npm ci, npm run -s test:unit:coverage on node v26.8.2 reports all files | 98.94.
This is the package.json half of the fix. Wiring CI to it is tracked separately, because the quality lane cannot push changes under .github/workflows/.
Recommendation
Add a gated sibling script that pins a floor below the current figure, leaving enough headroom that ordinary churn does not flap the gate:
"test:unit:coverage:check": "TZ=UTC node tests/tools/coverage-report.mjs --check 97"
Priority
- Impact: medium — on its own it changes nothing, but it is what makes the CI change a one-line edit
- Effort: low — one line in
package.json
Filed by quality agent (hold-gated mode)
🐝 Hive Agent: quality | Instance: hosted-available-lke648397-260827-5n31 | SHA: unknown
— hive: agent=quality backend=copilot model=claude-opus-5 copilot=1.0.88
Finding
tests/tools/coverage-report.mjsalready implements a coverage regression gate. Nothing uses it.node tests/tools/coverage-report.mjs --check <minLinePercent>exits 1 when total line coverage falls below the threshold (parseArgsat lines 38-45; the comparison and exit at the end ofmain()). Butpackage.json:63defines:with no
--check, and that is the only entry point anything calls. The number is computed, printed, published to the step summary and uploaded as an artifact — and never asserted on. A change that drops line coverage from 98.94% to 40% produces a green build and a quieter artifact nobody diffs.The other two workflows that run tests (
.github/workflows/deploy-gh-pages.yml:40and.github/workflows/import-architectures.yml:28) call plainnpm run test:unit, so they do not measure coverage at all.Measured at rev
a994a2ein a fresh clone afternpm ci,npm run -s test:unit:coverageon node v26.8.2 reportsall files | 98.94.This is the package.json half of the fix. Wiring CI to it is tracked separately, because the quality lane cannot push changes under
.github/workflows/.Recommendation
Add a gated sibling script that pins a floor below the current figure, leaving enough headroom that ordinary churn does not flap the gate:
npm run test:unit:coverage:checkexists and exits 0 at current coveragePriority
package.jsonFiled by quality agent (hold-gated mode)
🐝 Hive Agent:
quality| Instance:hosted-available-lke648397-260827-5n31| SHA:unknown— hive: agent=quality backend=copilot model=claude-opus-5 copilot=1.0.88