internal/server/api is the weakest package on both mutation axes #106

Open
opened 2026-08-23 14:53:15 +00:00 by a73x · 0 comments
a73x commented 2026-08-23 14:53:15 +00:00 (Migrated from git.a73x.sh)

[claude 2026-08-23] Falls out of the 2026-08-23 re-baseline (see the mutation baseline issue). internal/server/api is now the worst package in the tree on both axes at once — 38 surviving mutants and 41 unreached — and it holds that position without having got worse. Everything around it improved; it did not move.

That combination is what makes it worth a cycle. A package that is weak on efficacy has tests that execute the code without asserting on it. A package that is weak on coverage has code no test reaches. This package is both, and it is the HTTP surface: every authorization decision, every tenant-scoping check, and every refusal the control plane makes lives here.

Scale of the problem, for planning: 21 non-test files, ~3900 lines, with api.go alone at 1070.

Not a rewrite

The tests here are not absent — the package has 27 test files. The deficit is what they assert, not whether they run. Treat this the way the comment audit was run: let the mutants name the specific claims nothing holds, fix those, and leave the rest alone. Do not refactor the package to make it testable; that trades a measured problem for an unmeasured one.

Sequence

  1. Get the per-mutant survivor list (make mutate PKG=./internal/server/api) and group survivors by file.
  2. Split the security-relevant survivors — anything in auth.go, principal.go, ratelimit.go, tokens.go, sshcert.go, usercas.go, trustedcas.go — from the rest. An unasserted authorization branch is a different severity from an unasserted response field.
  3. Kill the security group first, each with a test named for the claim it holds.
  4. Judge the unreached 41 separately. Some will be genuinely dead code worth deleting rather than testing — that is a real outcome, not a failure to cover.

Caveat on the numbers

38/41 come from a run made while the machine was under concurrent load, which inflated timeouts tree-wide. Timed-out mutants are unresolved rather than alive, so the true survivor count could be somewhat higher once they resolve. Re-measure on an idle box before treating any figure here as the target to drive to zero.


Migrated from git-collab issue 011250a275418e8297e2efe7d84e78089691cd70.

Original author: a73x dev@a73x.sh.

[claude 2026-08-23] Falls out of the 2026-08-23 re-baseline (see the mutation baseline issue). `internal/server/api` is now the worst package in the tree on **both** axes at once — 38 surviving mutants and 41 unreached — and it holds that position without having got worse. Everything around it improved; it did not move. That combination is what makes it worth a cycle. A package that is weak on efficacy has tests that execute the code without asserting on it. A package that is weak on coverage has code no test reaches. This package is both, and it is the HTTP surface: every authorization decision, every tenant-scoping check, and every refusal the control plane makes lives here. Scale of the problem, for planning: 21 non-test files, ~3900 lines, with `api.go` alone at 1070. ## Not a rewrite The tests here are not absent — the package has 27 test files. The deficit is what they assert, not whether they run. Treat this the way the comment audit was run: let the mutants name the specific claims nothing holds, fix those, and leave the rest alone. Do not refactor the package to make it testable; that trades a measured problem for an unmeasured one. ## Sequence 1. Get the per-mutant survivor list (`make mutate PKG=./internal/server/api`) and group survivors by file. 2. Split the security-relevant survivors — anything in `auth.go`, `principal.go`, `ratelimit.go`, `tokens.go`, `sshcert.go`, `usercas.go`, `trustedcas.go` — from the rest. An unasserted authorization branch is a different severity from an unasserted response field. 3. Kill the security group first, each with a test named for the claim it holds. 4. Judge the unreached 41 separately. Some will be genuinely dead code worth deleting rather than testing — that is a real outcome, not a failure to cover. ## Caveat on the numbers 38/41 come from a run made while the machine was under concurrent load, which inflated timeouts tree-wide. Timed-out mutants are unresolved rather than alive, so the true survivor count could be somewhat higher once they resolve. Re-measure on an idle box before treating any figure here as the target to drive to zero. --- Migrated from git-collab issue `011250a275418e8297e2efe7d84e78089691cd70`. Original author: a73x <dev@a73x.sh>.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
a73x/eitri#106
No description provided.