Files
OwnCord/Server/coverage-floor.json
T
J3vbandClaude Fable 5 7da2a2b9ad feat(b3-6): coverage floor — script, floors and CI gate on the ubuntu leg (S-06) (#1453)
* feat(b3-6): coverage floor — script, floors and CI step (S-06)

scripts/coverage-floor.sh reads a Go coverage profile and fails when the
aggregate, or one of the core packages (ws, service, permissions, auth, db),
is below the figure recorded in coverage-floor.json. Statement counts come
from the profile's block lines, not `go tool cover -func`, so the per-package
figures are exact; percentages are truncated to one decimal and compared in
tenths. Exclusions (generated db/dbgen, cmd/) live in the floor file.

Measured with the CI command on this branch's base (origin/dev 75d64dd4):
aggregate 79.1 (11241/14194), auth 90.8, db 79.4, permissions 100.0,
service 67.8, ws 84.5. The plan's starting aggregate was 74.6 (B0 baseline at
an older SHA); the ratchet applies to this PR too, so the floor lands at the
measured figure.

Wired into ci.yml right after the race/coverage test step, on the Linux leg
only: OS-tagged files swap in and out of the build and several tests skip on
Windows, so one leg keeps the figure deterministic. The ratchet rule is in
Server/CLAUDE.md.

--floor <file> and OWNCORD_COVERAGE_FLOOR override the committed floors, so
the negative control needs no edit of the tracked JSON.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KmiqjgTuov1stBTB6uGkvo

* docs(b3-6): evidence block for item 1 (coverage floor)

Numbers, RED/GREEN commands and the Linux-leg decision, appended to the
B3-6 section per the item's exit criteria.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KmiqjgTuov1stBTB6uGkvo

* fix(b3-6): coverage floor — fail closed on JSON shape, honour --floor anywhere, LC_ALL=C, gate after the last test step

Review findings on item 1.

The floor-file parser now fails closed instead of silently reading less than
the file says. A Prettier-wrapped "exclude" array used to yield zero
exclusions and misreport as a coverage drop; an "exclude" key with no parsed
entries is now exit 2 naming the one-line-array rule. A package entry sharing
a line with the closing brace ("ws": 99.0 }) used to be dropped, so that floor
stopped being enforced; the block now closes after the line is parsed, and an
entry on the "packages": { line is parsed too. Two entries on one line are
exit 2 rather than one silently ignored. All three rules are in the header
comment.

--floor is parsed in any argument position, so `coverage-floor.sh coverage.out
--floor red.json` no longer silently uses the committed floors; an unknown
flag or a second positional argument is a usage message and exit 2.

LC_ALL=C is exported for mawk's locale-dependent decimal handling.

The ci.yml step moves after the deadlock and tag-gated test steps — it still
reads the profile the race step wrote, and still runs only on the ubuntu leg,
but a floor miss no longer hides those steps' results.

Server/CLAUDE.md gains the no-trailing-slash rule for exclusions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KmiqjgTuov1stBTB6uGkvo

* fix(b3-6): coverage floor — every package entry must parse, and the five core packages must all be present (Codex P2 on #1453)

A package entry whose value did not match the numeric regex — valid JSON such
as "auth": "90.8" — was silently ignored, and the only completeness check was
"at least one package parsed", so a malformed value quietly removed a floor.
That contradicts the script's own fail-closed contract.

Inside the "packages" block, any line that is not a well-formed
"name": <number> entry (or the block's closing brace) is now exit 2, naming the
line number, the line, and the shape rule. The entry match is anchored, so it
also subsumes the previous "two entries on one line" heuristic.

The five core packages — ws, service, permissions, auth, db — must each have a
parsed floor; a missing one is exit 2 naming it. Extra packages beyond the core
set stay allowed.

Header comment and the plan's evidence block record both rules.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KmiqjgTuov1stBTB6uGkvo

* fix(b3-6): coverage floor — floors set from the Linux leg (CI run 33302062524)

The floors were first measured locally on Windows; the gate runs on the ubuntu
leg, and the first CI run of #1453 showed the two legs differ. Each floor is
now the Linux value truncated to one decimal, measured by the gate itself on
the leg that enforces it: aggregate 79.9 (11344/14191), auth 90.8 (418/460),
db 79.3 (1738/2189), permissions 100.0 (94/94), service 67.8 (1204/1775),
ws 86.9 (3271/3763).

The deltas are the ones the pre-merge analysis predicted. ws is higher on Linux
because three EnsureLiveKitBinary tests and one harvest_s5 case skip on Windows,
and that lifts the aggregate with it; db is one statement larger on Linux
(lockfile_unix.go has 11 statements where lockfile_windows.go has 10), which
costs it a tenth. auth, permissions and service carry no OS-conditional code and
are identical on both legs.

The evidence block now carries both columns, cites the run id, and keeps the
74.6 note. Running the new floors against the local Windows profile fails on
aggregate and ws by exactly those deltas, which is expected and is why the gate
is Linux-only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KmiqjgTuov1stBTB6uGkvo

* fix(b3-6): coverage floor — a tenth of headroom where the Linux leg varied run-to-run (ws, aggregate; runs 33302062524 and 33302732286)

Run 33302062524 measured ws at 3271/3763 (86.9); run 33302732286, same commit,
measured 3267/3763 (86.8) and failed the floor set from the first. Four
statements of run-to-run variance in ws under -race — timing-dependent branches
— which moves the aggregate with it (11344 -> 11340). The reviewer's
zero-headroom concern is now evidence rather than a prediction.

Floors are therefore the lowest observed Linux figure, truncated to 0.1, minus
0.1 where the package varied between runs: ws 86.9 -> 86.7, aggregate
79.9 -> 79.8. auth 90.8, db 79.3, permissions 100.0 and service 67.8 are
unchanged — their statement counts are identical in both runs, so they take no
headroom.

Server/CLAUDE.md states that rule next to the ratchet, and notes that a Windows
run reports aggregate and ws under floor by design. The evidence block carries
both runs' covered/total per package, which varied, and the resulting floors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KmiqjgTuov1stBTB6uGkvo

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 11:48:02 +00:00

13 lines
315 B
JSON

{
"_doc": "Coverage floors enforced by scripts/coverage-floor.sh, measured on the Linux CI leg. Ratchet rule and shape: Server/CLAUDE.md.",
"aggregate": 79.8,
"exclude": ["db/dbgen", "cmd"],
"packages": {
"auth": 90.8,
"db": 79.3,
"permissions": 100.0,
"service": 67.8,
"ws": 86.7
}
}