Files
command-center/agent/managed-skills/e2e-port-squat-triage/SKILL.md
T
Frank 8af40c402b chore(agent): commit the machine tier and the doctrine text the checkout was already running
Landing blocker for #61 and #63: the deployment checkout is 12 commits behind and
`merge --ff-only` refuses while tracked paths are dirty. Discard is not available here
(workspace policy: no `checkout`/`stash` on shared state), so the dirt is committed.

- `agent/APPEND_SYSTEM.md`: the point-of-use / one-work-log / PR-link doctrine, already
  byte-identical to `origin/main` (`cmp` against the trunk blob: no difference). No new
  prose — the commit exists so the trunk merge can proceed.
- `agent/config.yml` and `agent/managed-skills/**`: the machine-live tier the heartbeat
  owns (AGENTS.md § Live-sync tiers).

`ALLOW_SECRETS=1` was used, deliberately and after auditing the staged diff by hand: the
only credential-shaped strings in it are two copies of `AKIA0000000000000EXAMPLE` — the
inert all-zero AWS example id — and they appear inside the two skill pages that teach
that exact placeholder shape. This checkout is still running the pre-#61 hook; the merged
gate (value-scoped placeholder filter, `71601f7`) exempts this value, so the refusal
dies with this landing. No `--no-verify` was used: the gate ran and its verdict is
recorded here.

Refs #61
2026-10-21 01:44:51 -07:00

2.1 KiB

name, description
name description
e2e-port-squat-triage When an e2e seam on a fixed port fails weirdly (404s on routes that exist, stale behavior, health probe passes but app seems ancient), audit for leftover dev/debug servers squatting the port before believing any red or green.

E2E fixed-port squat triage

Symptom classes (all seen with a stale server squatting the seam's fixed port)

  • Routes that exist in current dist/source return 404 ("Cannot POST /api/...") while unit tests through the same app factory pass.
  • A seam that is green but exercises old code: its setup curls http://host:PORT/health and gets a response from whoever owns the port — a leftover server, not the one it just spawned (the spawned one dies or idles with EADDRINUSE, sometimes still showing in pgrep).
  • Behavior matches an older build (missing mounts/guards) despite a fresh build step.

Triage recipe (before touching code)

  1. Who owns the port:
    ss -tlnp 2>/dev/null | grep :PORT
    
  2. List every server process with start times:
    for p in $(pgrep -f "path/to/server-entry"); do ps -o pid,lstart,cmd -p $p --no-headers; done
    
  3. Compare start times against the build artifact timestamps (ls -la dist/...). A server older than the dist you just built is a liar — its in-memory modules predate the code under test.
  4. Kill all leftovers, then re-check: pgrep -f "server-entry" || echo all-dead.
  5. Rerun the seam. Only now is red/red and green/green meaningful.

Why it happens

  • kill %1 in non-interactive bash fails silently (no job control) — use explicit PIDs or pkill -f <pattern>.
  • Seam setups that "wait for health" cannot distinguish their own server from a squatter on the same port; a pre-flight "port must be free" assertion is the permanent fix (assert before spawn).

Hardening (if you own the seam)

Add to setup, before spawning: fail fast if the port is already listening — turns the silent liar into a loud error:

ss -tln "sport = :PORT" | grep -q LISTEN && { echo "port PORT busy — kill leftovers first" >&2; return 1; }