Skip to content

ci: enforce the coverage floor per package, and keep the fuzz corpus - #257

Merged
Jaro-c merged 3 commits into
developfrom
ci/adopt-per-package-gate-and-fuzz-corpus
Jul 28, 2026
Merged

ci: enforce the coverage floor per package, and keep the fuzz corpus#257
Jaro-c merged 3 commits into
developfrom
ci/adopt-per-package-gate-and-fuzz-corpus

Conversation

@Jaro-c

@Jaro-c Jaro-c commented Jul 28, 2026

Copy link
Copy Markdown
Member

Closes #218. Closes #225. Adopts both halves of Glyndor/.github#106, and is the consumer that proves them before that repository gets a tag.

Per-package coverage floor

This module ran at 91% against a gate of 90 while auth/oauth sat at 87.7% and internal/keymanager at 85.7%. The two with the most attack surface were the two thinnest, and internal/clock at 100% was paying for them.

Every package clears 90 today, which is exactly when a floor is cheapest to adopt — it locks in a state that already holds rather than demanding new work:

package coverage
auth/oauth 90.2%
auth/email 91.9%
internal/keymanager 92.0%
auth/apikey 94.6%
auth/jwt 95.0%
auth/password 95.8%
auth/username 97.5%
authcore 98.1%
internal/clock 100.0%

The measurement that made this decidable: comparing isolated profiles against -coverpkg=./... moves those packages by +0.5 and +0.0, so the per-package numbers are honest rather than an artefact of helpers being exercised from a sibling package.

The fuzz corpus survives between runs

It never did. setup-go restores GOCACHE — where Go keeps the corpus — but on a cache hit does not save it again, so every discovery died with the runner and the next week re-explored the same ground from the seeds.

Measured here before changing anything: a cold 60s run of FuzzParseJWK finds 219 new interesting inputs, 300s finds 293. A single run saturates well before its budget, so the budget was never the constraint — starting from zero every week was. fuzztime is deliberately unchanged.

The compounding will not be visible in this pull request; the first scheduled run after it merges seeds the cache, and the one after that is the first to start warm.

Pinned by SHA

Glyndor/.github is only tagged once a consumer has proved a workflow green, and this is that consumer. The pin moves to the release tag afterwards.

Adopts both halves of Glyndor/.github#106.

The coverage floor now has to hold in every package rather than on
average. This module ran at 91% against a gate of 90 while auth/oauth sat
at 87.7% and internal/keymanager at 85.7% — the two with the most attack
surface were the two thinnest, and internal/clock at 100% was paying for
them. Every package clears 90 today, which is exactly when a floor is
cheapest to adopt: it locks in a state that already holds instead of
demanding new work.

The fuzz corpus now survives between runs. It never did: setup-go restores
GOCACHE but does not save it again on a cache hit, so each week started
from the seed corpus and re-explored the same ground. Measured here, a
cold 60s run of FuzzParseJWK finds 219 new interesting inputs and 300s
finds 293 — a single run saturates well before its budget, so the budget
was never the constraint. Starting from zero was.

Pinned by SHA rather than tag: Glyndor/.github is only tagged once a
consumer has proved a workflow green, and this is that consumer.

Closes #218. Closes #225.

Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
@Jaro-c Jaro-c added type:ci CI/CD and automation prio:P2 Medium priority status:review In review effort:S Small area:meta Subsystem: meta labels Jul 28, 2026
Jaro-c added 2 commits July 27, 2026 22:24
Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
The gate names every package under the floor with a ::error:: annotation
and fails the job, verified at 96 where six packages are under it. Back to
90, which every package clears.

Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
@Jaro-c

Jaro-c commented Jul 28, 2026

Copy link
Copy Markdown
Member Author

Proved the gate can fail before trusting it, since a gate nobody has seen fail is decoration.

Temporarily raised the floor to 96 on this branch (f1323f4) and the job went red, naming each package individually:

::error::github.com/Glyndor/authcore/auth/oauth is at 90.2%, under the 96% floor
::error::github.com/Glyndor/authcore/auth/email is at 91.9%, under the 96% floor
::error::github.com/Glyndor/authcore/internal/keymanager is at 92.0%, under the 96% floor
::error::github.com/Glyndor/authcore/auth/apikey is at 94.6%, under the 96% floor
::error::github.com/Glyndor/authcore/auth/jwt is at 95.0%, under the 96% floor

Reverted to 90 in 382807a, and the job is green again with Every package clears 90%. So the wiring propagates the exit status, the if: condition fires, and the annotation points at the offender rather than just failing.

This is the same discipline the sweep in #229 was about: the failing direction is the one worth checking.

@Jaro-c
Jaro-c merged commit a712d70 into develop Jul 28, 2026
14 checks passed
@Jaro-c
Jaro-c deleted the ci/adopt-per-package-gate-and-fuzz-corpus branch July 28, 2026 03:26
Jaro-c added a commit that referenced this pull request Jul 28, 2026
Seven callers were spread across three versions:

| caller | was | now |
|---|---|---|
| `ci.yml`, `fuzz.yml` | raw commit, no version comment | `# v1.12.0` |
| `schedule-freshness.yml` | v1.11.0 | v1.12.0 |
| `dco.yml`, `go-audit.yml`, `line-limit.yml`, `main-guard.yml` |
v1.10.1 | v1.12.0 |

`ci` and `fuzz` were pinned bare on purpose — Glyndor/.github#106 was
waiting for a consumer to prove it green before being tagged, and #257
was that consumer. Now that v1.12.0 exists they get their comment back.

That comment is not decoration. Without a version beside the SHA,
Dependabot has nothing to compare against, never proposes a bump, and
the pin rots — which is exactly how four of these ended up two releases
behind while nobody noticed.

Supersedes #250, #251, #252 and #254, which each moved one caller to
v1.11.0.

Verified with `actionlint` across all seven workflows.

Signed-off-by: Jaro-c <75870284+Jaro-c@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:meta Subsystem: meta effort:S Small prio:P2 Medium priority status:review In review type:ci CI/CD and automation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant