Four bugs under a green suite
The last report closed with two gates and a coverage number. This one is about what the coverage number was for. Chasing uncovered blocks across ten Go backends turned up a panic that takes the server down, a validator that never trimmed, a validator that was never called at all, and an endpoint that was never registered — half an API, unreachable, under a suite that had been green for a week. Coverage is not a metric. It is a bug detector, and everything it found was hiding in the same place: a branch the spec never named.
The law that predicted all four
Yesterday's report established it and today it held nine times out of nine:
Coverage is a mirror of the spec's list of test names. The model writes every test that is named and not one that is not. The hole is exactly the shape of what the spec forgot to say.
Which makes it predictive. Before measuring taskflow I could say where the hole would be: the spec named one project test, so the project half would be dark. It was. And in every dark branch, something was waiting.
1. A panic, reachable from any HTTP request
The service package sat at 48.6%. I pulled the uncovered blocks and
wrote the test the spec had implied — "bounds checks, never panics" — and
it crashed:
panic: runtime error: slice bounds out of range [-1:]
paginate had no offset < 0 clamp. Any request carrying
?offset=-1 slices items[-1:] and takes the process down.
The spec itself said "never panic." The model had written that
guard correctly in one run and dropped it in another — in three backends, all
three shipped without it, all three green.
An untested branch is not merely unverified. It is a branch where the model's output is a coin flip — and the coin has been flipping in production.
2. A validator that never trimmed
tasks-api was the suite's lowest at 56.5%. Validate() — the contract
every other layer trusts — had never been executed directly. Writing the
test the spec implied:
func (t Task) Validate() error {
if t.Title == "" { // the spec says: "when the TRIMMED Title is empty"
A title of " " was accepted. The API stored tasks that look blank to
every client. The spec was right; the code was wrong; nothing ever asked.
3. A validator that was never called
The same file, one layer up. PUT /tasks/{id} was registered, shipped,
and had never been called once — so nobody had noticed that
Update does not validate. Nor does Create.
Validate() was dead code.
The spec said "map ErrInvalidTask to 400 with errors.Is" — and the model wrote that mapping faithfully, while never calling the one thing that produces the error.
Mapping an error that nothing returns is a dead branch. And an uncalled method is legal Go: it builds, it vets, and there is no sentence for a gate to hear. The only thing that notices is a test.
4. And the quiet one: a door that was never there
taskflow's router wired three project endpoints:
mux.HandleFunc("GET /projects", projectHandler.List)
mux.HandleFunc("GET /projects/{id}", projectHandler.Get)
mux.HandleFunc("DELETE /projects/{id}", projectHandler.Delete)
// and no POST /projects.
A project could never be created. Every project endpoint answered 405. Half
the API was unreachable — and the suite was green, because no test had ever
tried to create a project. The spec said POST/GET /projects. The model
dropped the POST.
The mirror law at its most expensive: an untested mirror can be missing more than its branches. It can be missing its door.
What actually fixes these
Not a gate. Three of the four are invisible to the compiler — an unregistered route, an uncalled method, a missing clamp all build clean and vet clean. There is no sentence for a gate to listen for. What fixes them is the spec, and specifically two devices that earned their keep today:
Show, don't describe. "Bounds checks, never panics" produced a
panic. Three named guards written out as code produced the guards, in three
backends out of three. "Map ErrInvalidTask to 400" produced a mapping with nothing
behind it; if err := t.Validate(); err != nil, written out, produced
the call.
Make it countable. The model drops what it cannot count. "Nine
routes, and the one that goes missing is POST /projects" produced nine routes.
"THREE declarations, count them" stopped an Event struct from
vanishing. "Eleven top-level declarations: the helper and ten tests" stopped the
helper from vanishing. Three for three.
The honest floor
The gate audit reported one artifact stuck — the gates could not move it at all — and for a moment that reads as a broken gate chain. It was not. The artifact's defect is the missing route, and a missing route is legal Go. So the audit now says what STUCK actually means, because it was three different things wearing one label:
a gate that stopped firing → a REGRESSION (fix it) a defect class never seen → a BACKLOG item (build it) a defect the compiler cannot name → the HONEST FLOOR (leave it)
The third is real, and it is not a failure. It is the boundary between what determinism can repair and what only a specification can prevent.
Numbers
service workapi 54.2% → 100.0%
service taskapipro 48.6% → 94.3%
api taskapi 64.6% → 93.0%
api taskapipro 64.5% → 86.4%
taskflow 65.7% → 79.7% // projects List 0% → 100%, Delete 0% → 85.7%
tasks-api 56.5% → 70.6% // Validate 0% → 100%, Update 0% → 72.2%
10 / 10 specs green. Nothing traded for it.
green by the gates alone, no model: 10. suite: 290.
"Green" means the tests that exist pass. It does not mean the code that exists works — and which tests exist is decided by the spec's list of names. That is the whole of it. Four bugs shipped under a green suite, and every one of them was sitting in a branch nobody had thought to name: an unnamed guard, an unnamed rule, an unnamed call, an unnamed route. Coverage did not measure the work. It found the work.