Follow-ups on the salvaged bounded-teardown fix:
- Replace the source-grep regression test (backend-lifecycle.test.ts asserted
main.ts source text) with behavior-contract tests against the extracted
createPoolStopper(): handle retention until bounded exit, stop dedup,
stopAll completeness, and the respawn-awaits-dying-backend gate.
- Gate the registry-local spawn path on the in-flight stop too (sibling site
the original PR predates).
- Route teardownPoolBackendAndWait through the shared stopper so profile
delete/rename teardown covers both local pool keys with the same bounded
semantics.