Description
The wave-1 install is a bare binary at /usr/local/bin/codingagent2otel driven by a systemd unit. Rob’s standing rule for camden is that every app deploys as a container under /opt, following /opt/CLAUDE.md, and never as a hand-placed binary, so that install is the wrong shape regardless of it passing its own checks. camden’s layout law puts the compose project at /opt/compose/
Two things do not carry across from the systemd unit. The unit granted CAP_DAC_READ_SEARCH as an ambient capability so the unprivileged service user could read files whose synced POSIX ACL carries an effective mask of —; Docker’s cap_add places a capability in the bounding and permitted sets but not the effective set for a non-root uid, and the image hardcodes USER 65532. And the binary has no environment-variable configuration at all, so the container must be given a bind-mounted YAML file.
Acceptance Criteria
- #1 A compose project at /opt/compose/codingagent2otel/compose.yml declares name: codingagent2otel, runs ghcr.io/rknightion/codingagent2otel:main, and carries com.centurylinklabs.watchtower.scope=fastlane so the 5-minute watchtower-fast instance picks up rolling builds
- #2 Config and checkpoint state live under /opt/codingagent2otel/ and are referenced from the compose file by absolute path; no application state lives under /opt/compose
- #3 The transcript tree is bind-mounted read-only and a write attempt from inside the running container fails
- #4 The container reads a file written by the archive sync after the container started, despite the ACL effective mask; the mechanism that makes this work is recorded with the discriminating check that proved it rather than assumed from the systemd unit
- #5 OTLP reaches camden’s Alloy from inside the container and the image’s own -healthcheck probe reports the container healthy
- #6 Live verification after cutover: one named metric, one named log record and one named span are each confirmed present in the m7kni stack, quoted with the query used
- #7 The systemd install is fully decommissioned: unit stopped, disabled and its file removed, /usr/local/bin/codingagent2otel removed, and /var/lib/codingagent2otel removed only after the checkpoint is migrated and the container is proven ingesting
- #8 agent-session-archive.timer, agent-session-index.timer and agent-session-metrics.timer are still active after the cutover
- #9 The production compose file and its config are committed under deploy/ and the installed copies match them by hash
Definition of Done
- #1 just check passes: fmt-check, lint, build, test-short, probe-ci, dashboard-check and docs-links all clean