Composition
A minimal stack for a request-serving service
The shape
HTTP or RPC in, a database and a few dependencies behind, deployed continuously.
The stack
One row per doubt. No two rows do the same job.
| Doubt | Sensor | Why this one |
|---|---|---|
| not internally consistent | Type Checker Structural | Milliseconds, definitive, and the diagnostic names both sides. |
| unasserted execution | Mutation Testing Test Effectiveness | The only closer. Run it on the modules that bill or authorize. |
| emergent failure | Integration Tests Behavioral | Against the real database, before merge; a canary sees it too late. |
| does not run where deployed | Smoke Tests Behavioral | Four requests against the fresh deploy, before real traffic arrives. |
| falls over with a dependency | Fault Injection Adversarial | In staging, at realistic magnitude; live chaos is the same technique later. |
| unjudged observation, wrong logic | Business Invariants Invariants | Says whether the 200 was the right answer, in the domain's terms. |
| untested conditions, unintended change | Canary Analysis Change | Two doubts, one sensor, on traffic you already have. |
| reveals late effects | Error-Budget Impact Change | Retrospective, but it charges the burn to the deploy that caused it. |
Left open, on purpose
-
Until there is a load number to aim at. A load test run at a concurrency the service already serves asks nothing.
-
Only review closes it, and review is a practice you run rather than a thing you install.
-
Same closer, independent review. The canary compares the new version against the old one, so a bug both versions share reads green; review is where that gets caught.
What this stack is mistaken for proving
8 sensors close 9 of 19 doubts and reveal 1 more after the fact. It says nothing about unspecified property, missing behavior, unreached by tests, nobody knows where the coupling is, nobody knows where the risk sits, nobody can find out why. A green board from this stack is not evidence against any of those.
Install the merge gates first: the type checker and the integration suite are an afternoon each. The canary and the business invariants both read from the same observability events, so those two arrive together once the events exist. Fault injection comes last, because its verdict is only as good as the invariants it checks against, and until then a passing run proves nothing.