Once the port is published on 192.168.20.13 the host no longer listens on
127.0.0.1:8096, so wait_healthy(), do_status() and the rollback path would all
get connection-refused and every deploy would roll back. They now probe
$PUBLISH_IP (RESUME_PUBLISH_IP, default 192.168.20.13). assert_shape() asserts
the published host IP is that address instead of loopback; the mem_limit ==
memswap_limit checks are unchanged. check_port stays address-agnostic on
`sport = :8096`.
Records the amendment in reference/stack.md (ports table + the bind rule) and
docs/phase-3-deploy.md (§3.2 bullet, flow diagram, DoD line), citing Sam's
decision of 2026-10-26, interaction 54aeb1a2. AGENTS.md is Sam's to change and
is untouched.
Two failures from the first real deploy, both repo-side:
1. The container logged "exec /usr/bin/resume-server: no such file or
directory" and restarted until the health gate failed. The build host has
cgo enabled, so the binary carried the nix glibc interpreter, and the
distroless/static image has no dynamic loader. Every SQLite path already
uses pure-Go modernc.org/sqlite, so build with CGO_ENABLED=0 and ship a
static binary.
2. Compose warned about orphan containers ai-resume-backend-1 and
ai-resume-db-1: /home/sam/deployment/ai-resume on .13 already owns the
`ai-resume` compose project (on the ai-mesh network). Sharing the name makes
each stack visible as orphans to the other, so a `compose down
--remove-orphans` in either could stop the other. Run the site as project
`ai-resume-site`; the image tag stays ai-resume:local and the port binding,
mem_limit and memswap_limit are untouched.
The release directory under /home/sam/deployment/resume is the rollback unit;
deploy.sh stages releases/<timestamp>-<sha>/, flips `current` atomically,
builds the image from that directory and gates on /healthz, restoring the
previous release on any failure.
The rehearsal recipe in the header is kept as comments only; the pasted spec
lost the comment prefixes on the multi-line printf, which would have made the
script exit 1 on startup. It now uses \n escapes on one commented line.