Read the audit log
Merge the operator-side and on-host JSONL logs to see every state-changing op yoink performed, including deploys whose containers no longer exist.
yoink history reads container labels — once a container is docker rm'd, that line is gone. The audit log is yoink's durable record. Two files, one merged read path:
- Operator side (
$XDG_STATE_HOME/yoink/audit/events.jsonl, defaults to~/.local/state/yoink/audit/) — fleet-wide events:RunStarted,RunFinished, validation/build failures that never reach a host. - Host side (
/var/lib/yoink/audit/events.jsonlon each managed host) — per-host events:LockAcquired,LockReleased,ContainerStarted,ContainerCreated,DeployFailed, …
Each line carries an event_id (UUIDv7) so the merge view dedupes safely, and an origin field ("operator" or "host") so a glance at the table shows where each line came from.
Read everything from the last week
yoink audit logDefault window is 7d, default limit is 100 rows, sorted newest-first. The output:
ts origin host deploy_id event details
2026-05-01T15:42:01.317Z operator — 0190f0c7-c5b1-7c98-… RunFinished up ok
2026-05-01T15:42:01.299Z host cax11.example.com 0190f0c7-c5b1-7c98-… LockReleased
2026-05-01T15:41:58.612Z host cax11.example.com 0190f0c7-c5b1-7c98-… ContainerCreated docs docs-3fdc075b tag=sha-3fdc075
2026-05-01T15:41:42.005Z host cax11.example.com 0190f0c7-c5b1-7c98-… LockAcquired
2026-05-01T15:41:42.005Z operator — 0190f0c7-c5b1-7c98-… RunStarted up services=[docs]deploy_id is a UUIDv7 — one per yoink up invocation. Lexicographic sort orders runs by start time.
Filter by side
yoink audit log --origin operator # only the local file
yoink audit log --origin host # only the on-host SSH fetchesUse --origin host together with --host <ADDR> to focus on one host's local view of a deploy.
Reconstruct one run
yoink audit log --deploy-id 0190f0c7-c5b1-7c98-aa92-1d77b8e91f10
# or, since the prefix is unique:
yoink audit run 0190f0c7Returns every event tagged with that run, across every host, ordered by timestamp. Use it after a deploy to confirm what actually happened, or when triaging a failure.
Filter by host, service, or event type
yoink audit log --host docs.example.com
yoink audit log --service api --event ContainerCreated --event DeployFailed
yoink audit log --since 30m --format json | jq 'select(.event == "DeployFailed")'--format json emits one event per line (raw JSONL — no pretty-printing) so it pipes cleanly into jq, vector, or whatever else.
Find failed deploys
yoink audit log --event DeployFailed --since 30dDeployFailed events carry the failed container's last log lines under log_tail, captured at the moment yoink gave up. The container is usually long gone from docker ps; the audit log is the only thing that still has the diagnosis.
Retention and rotation
Both the operator-side and per-host active files rotate at 5 MiB — renamed to events-<UTC-timestamp>.jsonl while a fresh one starts. yoink audit log reads both the active and rotated files when --since reaches further back than 24 hours.
To prune rotated files past a retention window:
yoink audit gc --keep 90d # default retention
yoink audit gc --keep 30d --dry-run # preview before deleting
yoink audit gc --keep 30d --host docs.example.comThe active file is never touched. Schedule yoink audit gc from cron / a deploy hook if you have a strict retention requirement.
What's recorded vs. not
Recorded (every state-changing op):
RunStarted/RunFinishedenvelope on everyyoink up,rollback,prune,secrets rotate.LockAcquired/LockReleasedper host — the gap between them is your hold time.ContainerCreated/ContainerRemovedper replica — the forensic record of swaps.DeployFailedwithlog_tailwhen a healthcheck never passes.HookFinishedwith the exit code.- Progress events (
PullStarted,NetworkReady,HealthcheckHealthy, …) for richer triage.
Not recorded:
- Read commands (
status,history,doctor,diff,tui,audit logitself,secrets show,secrets env). They emit nothing — youraudit loginvocation does not show up in its own output. - Operator identity beyond
$USER@$HOSTNAME. There's no central identity provider; the field is informational only. - Secret values. Event payloads carry names (
SecretsRotated.new_recipient), never values.
In the TUI
yoink tui opens to the dashboard; press a (or 7) to open the Audit pane. Same merged-and-deduped view, plus:
↑↓/jk— select rowEnter— toggle a detail panel below the table (fullevent_id,deploy_id, actor + git SHA, and the failed-deploylog_tailwhen applicable)/— substring filter across host, event name, summary,deploy_id, and actor;Entercommits,Esccancels editingr— re-fetch (parallel SSH per host plus one local read for the operator log)Esc— clears the active filter on first press, returns to Dashboard on second
yoink tui --mode audit jumps straight there.
Schema
See Audit event schema for the per-variant fields and JSON shape. The schema is versioned via the per-event v field; older readers can refuse newer lines instead of misreading them.
See also
- Audit event schema — every event variant and its payload.
- CLI reference:
yoink audit— every flag. - Sealed secrets workflow —
secrets rotateshows up in the audit log too.