agent-proxy role skips rebuild when a container is already running - new upstream builds never auto-pulled (trigger gate, plus no_log hides build errors) #434
Labels
No labels
burndown-2026-06
coherence-core
consult
headless
interactive
P0
P1
P2
P3
P4
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
coilyco-flight-deck/infrastructure#434
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
The
agent-proxyrole does not auto-pull a new upstream build on converge, which is the behaviour expected of it. #431 changed the up-step todocker compose up -d --build --pull always --force-recreate, but left the trigger gate untouched:So the rebuild only fires when the compose.yaml file content changed or no container is currently running. A healthy container running an older image, with an unchanged compose file, means the step is skipped and a new commit on
agent-proxy#mainis never pulled.ward exec ansible-syncthen reports "ok/unchanged" while the host keeps running stale code. This is the same "upstream fixes never reach the host" failure #431 set out to fix - #431 fixed the command, not the trigger.Two diagnosability traps in the same step (fix while here)
no_log: trueon the up-step (added to hide the tower URL) also swallows all stdout/stderr, so a faileddocker compose buildsurfaces as an opaque failed task with no error. Keep the tower URL out of the log without blinding the build - e.g. passPROXY_TOWER_BASE_URLvia an env/.envfile the copy step writes, and dropno_logfrom the shell task, or split the sensitive assignment from the visible build.dockerCLI is absent from ansible's PATH, the whole "Converge" block is skipped viawhen: agent_proxy_docker.rc == 0with no warning - it reads as a clean converge. Emit adebug/fail(or at least a warning) when docker is missing on a host whereagent_proxy_enabled.Wanted behaviour
agent-proxy#main(docker's git-context clone re-fetches, and layer cache keeps a no-op cheap), and only recreates the container when the built image actually changed - not a forced restart on every sync. A clean pattern:docker compose build --pullunconditionally, thendocker compose up -dwithout--force-recreate(compose recreates only on image change).Acceptance
agent-proxy#mainis picked up on the nextward exec ansible-sync(new image built, container recreated).Refs
--build --pullbut not the trigger) and #430.🔒 Reserved by
ward agent --driver claude— containerengineer-claude-infrastructure-434on hostkais-macbook-pro-2.localis carrying this issue (reserved 2026-07-02T08:43:58Z). Concurrentward agentruns are blocked until it finishes or the reservation goes stale (2h0m0s TTL);--forceoverrides.— Claude (she/her), via
ward agentWARD-OUTCOME: done - agent-proxy now rebuilds from agent-proxy.git#main every converge and recreates only on a real image/config change.
The fix itself was small once the shape was clear. The real work was untangling three things the old step conflated. The trigger gate was doing the compose-changed / no-container dance to avoid churn, but that same guard is exactly what froze the image on a healthy host. Splitting build (unconditional
docker compose build --pull) from up (plaindocker compose up -d, let compose decide whether to recreate) makes each concern honest, and compose's own image-diff logic gives the no-op-is-cheap property for free without any hand-rolleddocker psbookkeeping.What fought back: the
no_logwas load-bearing for the wrong reason. Untangling it meant moving the tower URL into a 0600.envthat compose auto-loads, which happens to read cleaner than the inlineenvironment:block anyway. Small surprise on the way out - the repo's own code-comments hook rejects inline YAML comments below the header line, so all my rationale had to move into docs/agent-proxy.md instead of living next to the tasks. Good discipline, mildly annoying mid-flow.Confidence: high on the logic, which mirrors the pattern the issue itself proposed. The one thing I could not exercise here is a real converge on a mac with docker (this container has no docker daemon and the role is mac-gated), so the
changed_whenstderr-matching onup -doutput is reasoned, not observed. Worth a glance on the next realansible-sync; if the ok/changed reporting reads off, it is a one-line tweak to the match strings, not a design issue. No follow-ups worth filing.