Skip to main content
🗓️ Schedule discussionOpens Google Calendar — add attendees there.

Self-cleaning ephemeral verify harness

OpenAuthor: @relbnsOwner: openEffort: M

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 (internal 8082 / external 8083)? Record both.
  • Bring up only what is missing. Reuse local-stack-up as-is — it is already idempotent and writes logs/local-services.pids for 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 scripted docker 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 --ephemeral mode on local-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 composes local-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 in backend-services; the bewith-docs platform carries the pattern (snapshot → up → verify → teardown-only-what-started) and the runbook in the local-stack-up skill.
  • 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 + MERGEABLE but CHANGES_REQUESTED (CodeRabbit nitpicks only — a localhost-port clarification + a .vscode/launch.json analysis 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 extends local-stack-up.
  • Project-level infra-MCP registration (adjacent, not part of the harness). #2784's new .mcp.json registers only the Playwright MCP; backend-services currently gets the infra-MCP only via the user-level ~/.claude.json. Adding the sandbox infra-MCP server to the project .mcp.json would make "use the infra-MCP" reliable for every backend-services session — the project-level half of the PR #220 "infra-MCP availability" follow-up. Verify first how the infra-mcp-dev container 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 --keep to retain? Default-keep is safer; default-teardown matches the "self-cleaning" intent. Lean opt-in to start.
  • backend-services PR #2784 — verify-integration-local + the start-local-services.mjs launcher (the verify half + the repo-specific script).
  • bewith-docs PR #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 --ephemeral mode (local-run was consolidated into it).

Triage notes

Filled in during triage. Empty until then.