← Corpus / corpora-builder / reminder
The Sidecar Port Is Adopted, Not Owned
Tauri probes 8787 and uses whatever answers. A stray dev sidecar becomes the app's backend, silently, and the app looks fine.
- Path
- reminders/The-Sidecar-Port-Is-Adopted-Not-Owned.md
- Authors
- Michael Staton
- Augmented with
- Claude Code on Claude Opus 5 (1M context)
- Tags
- Reminder · Corpora-Builder · Tauri · Agent-Discipline
The Sidecar Port Is Adopted, Not Owned
What happened
An agent started a sidecar on 127.0.0.1:8787 against a synthetic test
corpus while working. The operator then launched the desktop app. The app came
up, listed sources, and showed focus chips reading Ocean Energy and
Automation — fixtures from the agent’s scratch directory, rendered as though
they were the client’s corpus.
Nothing errored. Nothing looked broken. The app was simply pointed at the wrong corpus.
Separately, the agent’s vite dev held 1420, so tauri dev died with
Port 1420 is already in use — the loud half of the same mistake, and the only
half that announced itself.
Why
src-tauri/src/lib.rs::ensure_sidecar opens with:
// Probe first, always. A tracked handle proves nothing about a live process.
if healthz_ok().await {
return Ok(());
}
That probe is right, and it exists for a good reason — a handle the Rust side is
holding proves nothing about whether the process is alive. But its converse is
that any process answering /healthz on 8787 is adopted as the backend, with
no check that it is the one this app would have spawned. /healthz reports a
label; nobody compares it to anything.
The rule
An agent must not leave a sidecar or dev server on the app’s ports.
8787— the sidecar. Occupying it silently redirects the desktop app.1420—vite dev, andtauri.conf.jsonuses--strictPort, so it fails outright rather than moving.
When a running instance is needed for verification, use different ports and point the frontend at the other one:
uv run python -m src.cli --local <corpus> serve --port 8788
cd app && VITE_CORPORA_API=http://127.0.0.1:8788 bunx vite dev --port 1421
VITE_CORPORA_API exists for exactly this. The packaged app never sets it, so
8787 stays the contract.
And before killing anything on 8787, look at what it is. curl -s localhost:8787/healthz reports the label. A sidecar reading Reach Edu is the
operator’s session, not litter — killing it takes their app’s backend out from
under them.
Still open
The adoption is unverified. ensure_sidecar could compare /healthz’s label
against the workspace it is about to serve, and spawn its own on a mismatch
rather than adopting a stranger. Not built; this reminder is the mitigation.
Related
app/src-tauri/src/lib.rs—ensure_sidecarcontext-v/specs/Browse-Corpus.md—/healthzand the CORS origin contract- [[../contracts/Autonomy-Gates]] — what an agent may do unattended