Self-cleaning ephemeral verify harness
Problem
Verifying a change locally — say an integration import — means bringing up the sandbox infra and the NestJS services, running the checks, and then remembering to tear it all down. Today the bring-up is a single idempotent skill (local-stack-up), but teardown is manual (/kill-service-ports + bewith sandbox down) and easy to forget. The result is stray services and containers left running after a verify, eating ports and memory, and occasionally confusing the next verify run.
There is no orchestrator that runs the whole loop end-to-end and cleans up after itself — and, critically, cleans up only what it started, so it never kills a stack the developer already had up for their own work.
Proposal
A self-cleaning, ephemeral verification harness: one entry point that snapshots the current state, brings up only what is missing, runs the verification (preferring the bounded, audited infra-MCP tools for DB/cache checks), and then tears down only the parts it brought up — leaving anything that was already running untouched. If state is ambiguous, it errs on the side of leaving things running (never kill what you are not certain you started).
The primitives already exist; the missing piece is the orchestration + the "kill only what I started" bookkeeping.
Why now / Why us
The bring-up half (local-stack-up) and the verify half (verify-integration-local) are landing now in backend-services PR #2784, and this proposal arose directly from that work (Ariel: "a mechanism that automatically runs the app, checks against infra-MCP what's needed, and at the end kills the service because it no longer needs them"). It also composes cleanly with bewith-docs PR #220 (route DB/cache work onto the infra-MCP) — the harness is exactly the place to make "check via the infra-MCP" the default verification path. We own all the pieces; this is glue, not new infrastructure.
Sketch of approach
- Snapshot before-state. Is the sandbox infra up (
bewith sandbox status)? Are the gateways already listening (internal8082/ external8083)? Record both. - Bring up only what is missing. Reuse
local-stack-upas-is — it is already idempotent and writeslogs/local-services.pidsfor the services it spawns. - Verify. Run the relevant checks, preferring the infra-MCP tools (
mysqlRunSelect/mongoRunFind/redisRead) for DB/cache assertions; fall back to the scripteddocker exec … <cli>checks when the infra-MCP is not registered in the session. - Teardown — only what step 1 found missing. If the harness started the services, kill exactly those PIDs (
logs/local-services.pids); if it started infra,bewith sandbox down; if either was already up, leave it. Default to "leave running" on ambiguity. - Likely shape: an
--ephemeralmode onlocal-stack-up(it already owns bring-up and a "Stop" section), rather than a new top-level skill — the bring-up/teardown state lives there. A thin orchestrator skill that composeslocal-stack-up+ verify + teardown is the alternative. - Where it is implemented: the repo-specific launcher (
scripts/start-local-services.mjs, parses.vscode/launch.json+ the NestJS compound) lives inbackend-services; the bewith-docs platform carries the pattern (snapshot → up → verify → teardown-only-what-started) and the runbook in thelocal-stack-upskill. - Agent-drivable per
agent-drivable-cli: non-interactive, machine-readable, exits non-zero on a failed verify.
Open questions
- Fold into the open PR #2784, or a follow-up? Recommendation: follow-up. #2784 is
OPEN+MERGEABLEbutCHANGES_REQUESTED(CodeRabbit nitpicks only — a localhost-port clarification + a.vscode/launch.jsonanalysis note) and stale ~3 days. Adding a ~150-line orchestrator would balloon a near-done PR and reset its review, against the small-reviewable-PR discipline. Land #2784 first (address the nits), then a focused follow-up PR extendslocal-stack-up. - Project-level infra-MCP registration (adjacent, not part of the harness). #2784's new
.mcp.jsonregisters only the Playwright MCP;backend-servicescurrently gets the infra-MCP only via the user-level~/.claude.json. Adding the sandbox infra-MCP server to the project.mcp.jsonwould make "use the infra-MCP" reliable for everybackend-servicessession — the project-level half of the PR #220 "infra-MCP availability" follow-up. Verify first how theinfra-mcp-devcontainer is meant to be connected (stdio command vs HTTP) before wiring. - Should teardown be opt-in (
--ephemeral) or the default for a verify run, with--keepto retain? Default-keep is safer; default-teardown matches the "self-cleaning" intent. Lean opt-in to start.
Related
backend-servicesPR #2784 —verify-integration-local+ thestart-local-services.mjslauncher (the verify half + the repo-specific script).bewith-docsPR #220 — route DB/cache work onto the infra-MCP (the "check via infra-MCP" half).local-stack-up— the platform skill this proposal would extend with an--ephemeralmode (local-runwas consolidated into it).
Triage notes
Filled in during triage. Empty until then.