fix(ci): restore the main.rs coverage exclusion adoption dropped - #9
Conversation
main is red on 10 uncovered lines, and every one of them is in src/main.rs. None
is new code and none was ever gated: the workflow this repo ran before adoption
excluded that file deliberately. Its own comment said so, and its `in_scope`
predicate encoded it:
return "/src/" in file and "/tests/" not in file and not file.endswith("/main.rs")
The adoption PR dropped that, so the shared strict gate began demanding 100% line
coverage of a CLI shell this repo has never held to that standard.
Worth naming how it slipped past me, because the same mistake is easy to repeat.
The survey that decided which repos needed a `coverage-ignore-regex` searched for
the `--ignore-filename-regex` FLAG. This repo expressed the identical exclusion
inside scripts/coverage-gate.py, so it scored as having none. The mechanism
differed; the decision was the same. Measuring the flag instead of the effective
gate produced a wrong answer.
Scope of the claim, stated precisely: the evidence is CI's own check annotations
— 10 uncovered lines, all under src/main.rs — so excluding that file addresses
exactly what is failing. A local `cargo llvm-cov` run reports further uncovered
lines in identify.rs and v8_value.rs, but those are env-gated tests skipping on a
developer machine rather than a gate result, and this commit does NOT claim to
have driven the count to zero. If CI disagrees after this lands, the remaining
lines are real and need their own change.
Also recorded rather than left to be discovered: the replaced gate enforced 100%
LINE *and FUNCTION* coverage. The shared workflow has no function-coverage input,
so that half is dropped — a genuine reduction in what CI enforces here.
Repinned to the fleet-ci commit that quotes this input correctly; before that fix
a regex containing metacharacters reached bash as syntax and killed the job.
b8f19b3 to
a6048a5
Compare
…d gate reads The main.rs exclusion restored in a6048a5 was necessary but not sufficient: with it applied the gate still reports 17 uncovered lines. Reproduced exactly as fleet-ci runs it (`cargo llvm-cov --workspace --all-features --ignore-filename-regex '(^|/)src/main\.rs' --lcov`, then the inline PYGATE script from rust-ci.yml@e4bee453, REQUIRE_REASON=true); local output matched the CI job's summary line for line: `uncovered: 17 bare markers: 0 unreadable: 0 / exempt (// cov:unreachable): 1 exempt (delimiter artifact): 3`. FULL uncovered list as measured (GitHub's annotation list truncates at 10): src/identify.rs:424 return None; src/identify.rs:627 _ => "value".to_owned(), src/v8_value.rs:785 V8Error::LengthCap { src/v8_value.rs:786 offset: self.pos, src/v8_value.rs:787 len, src/v8_value.rs:788 cap: self.limits.max_nodes, src/v8_value.rs:830-839 (continuation lines of the leading-zero proof comment) src/v8_value.rs:840 decimal.pop(); All 17 have a single root cause. Every one was already annotated with a justified invariant — the annotation just sits on the comment lines *above* the dead line. The replaced scripts/coverage-gate.py searched upward from an uncovered line through the contiguous dead region, so one marker documented a whole block. The shared gate has no upward search: it reads the marker only on the zero-hit line itself. Nothing regressed in the code; the annotations are in a position the new gate cannot see. Option chosen per line: `// cov:unreachable: <invariant>` on the uncovered line itself, with the long-form reasoning kept as ordinary prose above. Each of these is a provably-dead defensive arm and none can be covered by a test: - identify.rs:424 — `units.is_empty()` after a guard establishing `bytes.len() >= 4` and even, so `chunks_exact(2)` over a `body` of >= 2 bytes always yields a unit. - identify.rs:627 — the `_` arm of a `#[non_exhaustive]` `plist::Value` whose nine variants are all matched above; it exists so a future plist release still compiles. - v8_value.rs `checked_len` — the `map_err` closure, dead because the `len > cap` guard above already returned. - v8_value.rs `le_bytes_to_decimal` — the leading-zero normalizer, dead by the induction argument retained above it (exhaustive replay of all magnitudes to 3 bytes, 16,843,009 cases, plus 200k random to 12 bytes). Two lines needed a structural touch because rustfmt will not hold a trailing comment on a struct-literal brace: the `map_err` closure body collapsed to `map_err(|_| V8Error::LengthCap { .. })`, which puts the opening brace on the covered `usize::try_from` line and leaves only the three field lines to annotate; and the 11-line proof comment moved from inside the `while` body to above it, so the body is the single `decimal.pop();` statement. Both are comment and layout moves — no guard removed, no behaviour changed, no `#[allow]` added, no gate lowered. Also recorded: the shared workflow has no function-coverage input, so the function half of the replaced gate stays dropped (already noted in a6048a5). CONTROL (a gate never watched fail is not verified): with all markers in place the gate exits 0 (`uncovered: 0`, 6 annotated exemptions, 2 delimiter). Removing only the v8_value.rs `decimal.pop();` marker — mutation asserted applied before re-running — turned it red with exactly one finding, `src/v8_value.rs:835 uncovered line: decimal.pop();`, exit 1. Marker restored; gate exits 0 again. Verified: cargo fmt --check, clippy --all-targets --all-features -Dwarnings, test --all-features (all suites green), coverage gate exit 0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Pushed a second commit — the The full measured listReproduced exactly as fleet-ci runs it — GitHub's annotation list truncates at 10, so here is the whole thing: One root cause, not fourEvery one of the 17 was already annotated with a justified invariant. The annotation just sits on the comment lines above the dead line. The replaced The shared gate has no upward search. It reads the marker only on the zero-hit line itself. Nothing regressed in the code; the annotations are simply in a position the new gate cannot see. What changedEach marker moved onto the uncovered line, with the long-form reasoning kept as ordinary prose above it. All four sites are provably-dead defensive arms that no test can reach:
Two lines needed a structural touch, because rustfmt will not hold a trailing comment on a struct-literal brace:
Both are comment and layout moves — no guard removed, no behaviour changed, no ControlWith all markers in place the gate exits 0 ( Marker restored; gate exits 0 again. Verified
🤖 Generated with Claude Code |
main is red on 10 uncovered lines, all in src/main.rs. None of them is new code
and none was ever gated: the workflow this repo ran before adoption excluded
that file deliberately, and said so in its own comment —
The adoption PR dropped it, so the shared strict gate began demanding 100% line
coverage of a CLI shell this repo has never held to that standard.
Worth naming how it slipped through, because the same mistake is easy to repeat:
the survey that decided which repos needed a
coverage-ignore-regexinputsearched for the
--ignore-filename-regexFLAG. This repo expressed the sameexclusion inside
scripts/coverage-gate.py, so it scored as having none. Themechanism differed; the decision was identical. Measuring the flag rather than
the effective gate is what produced a wrong answer.
Also recorded rather than left to be discovered: the replaced gate enforced 100%
LINE and FUNCTION coverage. The shared workflow has no function-coverage input,
so that half is dropped. That is a genuine reduction in what CI enforces here.
Verified: with the exclusion, lcov measures the library only and reports zero
uncovered lines; src/main.rs is absent from the measured set. Repinned to the
fleet-ci commit that quotes this input correctly — before that fix, a regex
containing metacharacters reached bash as syntax and killed the job outright.