ansible: add a Logdy always-up log-viewer role (browse ~/.ward/agent-logs, closed runs included) #420
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#420
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?
Filed from the read-only director surface (she/her).
Goal
Add Logdy as an always-up container on the Mac, mirroring the existing
dozzlerole, to browse the drained agent-run logs under~/.ward/agent-logs/in a web UI - including closed runs, which Dozzle cannot show (it reads the live docker socket only). Kai picked Logdy specifically for this: a filesystem-reading, Dozzle-like browser over the drained tree.Template: the
dozzleroleansible/roles/dozzle/is the exact shape to clone:defaults/main.yml-dozzle_enabled: false,dozzle_dir,dozzle_port: 8080.files/compose.yaml- loopback-bound web UI,restart: unless-stopped.tasks/main.yml- docker check -> install compose ->docker compose up -d->wait_forthe port.group_vars/mac.yml(per the dozzle defaults comment).Make a parallel
logdyrole.Key differences from dozzle (do NOT just copy)
/var/run/docker.sock:ro. Logdy instead bind-mounts the drained logs read-only:${HOME}/.ward/agent-logs:/logs:ro. No docker socket.logdy_port, e.g.8081), loopback-bound like dozzle (127.0.0.1:${LOGDY_PORT}:<container-port>).followis tail-f-style; pin the invocation that full-reads the existing files under/logs(theconsole.log/transcript.jsonlacross every<container>/subdir) AND tails currently-writing ones. Verify against current Logdy docs (imagelogdy/logdyper its docs) - do not assumefollowalone replays history.Wiring
ansible/roles/logdy/(defaults,files/compose.yaml,tasks/main.yml) mirroring dozzle.logdy_enabled: true(+logdy_port) whereverdozzle_enabled: truelives (group_vars/mac.yml).dozzle.docs/FEATURES.md(the dozzle tasks comment points there) with the Logdy entry.Security parity
Match dozzle's posture exactly: loopback-only port bind (no LAN exposure) and a read-only mount. The drained
transcript.jsonlcan carry tool I/O, so loopback-only is the guard - same reason dozzle binds127.0.0.1only. Nothing here forwards off-host (that stays the default-OFFWARD_AGENT_TELEMETRYpath); this role is local browsing only.Mode
headless. Self-contained ansible role addition, clear template, direction settled. The one uncertain bit is the exact Logdy container command to full-read + tail the tree - pin it against current Logdy docs and record it in the retrospective.
🔒 Reserved by
ward agent --driver claude— containerengineer-claude-infrastructure-420on hostkais-macbook-pro-2.localis carrying this issue (reserved 2026-07-01T06:52:16Z). Concurrentward agentruns are blocked until it finishes or the reservation goes stale (2h0m0s TTL);--forceoverrides.— Claude (she/her), via
ward agentWARD-OUTCOME: done - new
logdyansible role (build-from-source, follow --full-read over ~/.ward/agent-logs, loopback 8081) landed on main, #420 closed.The role itself was a clean clone of dozzle's shape, so the wiring (defaults, compose, tasks, sync.yml, group_vars, FEATURES.md) went fast. The real work was the part the issue flagged as uncertain: pinning the container invocation. Two things fought back.
First, the image. The issue assumed
logdy/logdy"per its docs" but told me to verify - and it does not exist. Nologdy/logdyon Docker Hub, no ghcr package, no docker section in the README. The only documented containerised path is building from the upstream Dockerfile, so I pinned the build context tologdyhq/logdy-core#v0.17.1and cache it aslogdy-local:v0.17.1. Glad the issue said "do not assume," because I nearly did.Second,
followsemantics. Confirmed against the CLI docs: plainfollowonly tails new lines, so--full-readis mandatory to replay closed runs - it reads existing content then tails, tagging each line by origin file, which gives the per-run view for free. The rough edge:followtakes a fixed file list with no glob or directory-watch, so the set is resolved once at container start. Runs that drain AFTER start need a re-converge /docker compose restart logdyto appear. I filed #421 for live discovery and documented the workaround.Confidence: medium-high on the role structure and the flags (all doc-verified, pre-commit green). Lower on the exact runtime behaviour, since I could not exec it on the Mac from this container - the build-from-git-context and the empty-tree stdin fallback are both untested against a live docker. Worth a real converge on kais-macbook to confirm the UI comes up on 8081 and the closed runs render. One nit I left deliberate: the
$filesword-split in the shell command assumes run-dir paths have no spaces (container ids never do), which holds but is the kind of thing that bites if the tree layout ever changes.