internal/server/api is the weakest package on both mutation axes
open by a73x
Labels: backlog
[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.