Four agents each merged green work into one branch of my API. Booting it and calling about 40 routes once found two routes nobody had written and four crashes.
Four agents each merged green work into one branch of my API. Booting it and calling about 40 routes once found two routes nobody had written and four crashes.
In early September 2026 I merged a wave of agent work into one branch of the API behind my latest ecommerce product. One agent wrote a shared contract. Then four agents built slices on top of it in parallel, each in its own worktree. Every slice arrived green, and the merged branch compiled and passed its suites.
Then I booted it against a real Postgres and called about 40 routes, once each. Two routes did not exist. Four more returned a 500.
None of the six showed up in the type check, the unit tests, or the integration tests that already ran against a real database. Each of those checks was honest about what it looked at. None of them looked at the wiring between the slices, and in a parallel wave the wiring is the one part nobody owns.
The missing routes show it most plainly. The database methods behind them already existed. No slice wrote the handler that calls them, so the framework answered with its own "Cannot GET".
Each one was about a five-minute fix, once one HTTP call had pointed at it.
Against a real, throwaway database, not the one a sibling agent is using.
The framework logs every route it mapped at boot. A handler nobody wrote is simply missing from that log, so I compare it with the frontend's API client, which is the contract.
A script now calls every route the router mapped and fails on any 500. It prints every route it skipped, with the reason. Comparing its list with the frontend client, and checking the shape of other errors, is still by hand.
This is part of the merge, not a proof step for later. I budget one fix commit for it. The same reconcile also added a test that checks the module graph offline, which would have caught one of that day's wiring gaps as a red test instead of a live 500.
One call per route proves the route exists and survives that call. It does not prove the feature works. The same day, driving the feature end to end found more gaps of the same kind, such as tasks that were created and never started.
The script calls read routes by default. Writes need a flag, and should only run against a throwaway database, because a smoke test that writes changes what it measures. The two constraint failures were writes, so a read-only run would have missed them.
It also never tests shutdown. One call per route says nothing about whether the process exits when it is told to. That story is in my NestJS deploy notes.
These are notes from one wave on one API, and "about 40" is as exact as the record gets.
After merging parallel work, typecheck and tests are not the gate for a running service. Boot the merged app against a real, throwaway database. Take the route list from the router's boot log or the frontend's API client, never from memory. Call every route once. Fail on any 500, any unknown route, and any error that is not the API's shaped error. Do this as part of the merge, and budget one fix commit for it.