Skip to content

Durable per-job run history + logs (read model for the panel) - #14

Merged
edgehero merged 5 commits into
mainfrom
plan-exec/2026-07-18-run-history-logs
Jul 21, 2026
Merged

Durable per-job run history + logs (read model for the panel)#14
edgehero merged 5 commits into
mainfrom
plan-exec/2026-07-18-run-history-logs

Conversation

@edgehero

Copy link
Copy Markdown
Owner

Durable per-job run history + logs — the read-model layer a future admin panel reads (issue #4). Each job reaching a terminal state now persists a PII-free, id-keyed status record (logs/<jobId>.json) via a synchronous write that beats the shutdown race; when PI_CAPTURE_JOB_LOGS=1 (opt-in, off by default) the container's raw output is also tee'd to logs/<jobId>.log. No new database — a flat node:fs sidecar keyed by job id, with a boot-time age sweep (PI_LOG_RETENTION_DAYS) for retention. All host-side, never mounted into the container; the raw log is gitignored.

The record captures what BullMQ's retained job cannot: exitCode, turns (parsed from the runner's exit stdout line), and budgetReserved — for every terminal outcome (completed / policy / infra-failure). The log/record path is money-path-adjacent, so it is fault-isolated end-to-end: a throwing or rejecting sink/writer can neither hang nor crash the run and never changes the throw-vs-return retry classification (proven by the load-bearing acceptance tests) — no double-spend, no lost retry. {code, aborted} and the reserve-before-container order are byte-identical.

New specs: REQ-DURABLE-RUN-HISTORY, INT-RUN-HISTORY-FILE-CONTRACT, DES-RUN-HISTORY-FLAT-FILES-NO-DB, and OQ-007 (periodic-sweep retention, left OPEN).

Verification

Check Baseline Final
test (node --test, whole workspace) 311 pass / 0 fail / 15 skipped 375 pass / 0 fail / 15 skipped (+64 tests)
lint / typecheck none configured (0) none configured (0)
Legacy/dead-code sweep PASS (no add-alongside; every export consumed)
Container Smoke (image) PASS — image built (multi-arch); pi pinned exact 0.80.7; runner tests 58/58 incl. new turns contract test
Webhook (receiver) N/A (receiver untouched)
Queue Verification (worker) PASS — offline deterministic matrix (drain path untouched); 93/93; money-path invariants confirmed
Spec drift exit 0 exit 0 (no new drift)

Container one-job E2E was skipped (no provider key in the runner environment — optional per the plan).

Closes #4

🤖 Generated with Claude Code

edgehero and others added 5 commits July 18, 2026 10:43
…guration" passed gates

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NGgfho2J6YfRSQN1bSDhj6
…un-history module" passed gates

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NGgfho2J6YfRSQN1bSDhj6
…iner output capture" passed gates

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NGgfho2J6YfRSQN1bSDhj6
…s record assembly + wiring" passed gates

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NGgfho2J6YfRSQN1bSDhj6
…, contract test, docs, deploy notes" passed gates

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NGgfho2J6YfRSQN1bSDhj6
@edgehero
edgehero merged commit cdab35c into main Jul 21, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Durable per-job run history + logs (read model for the panel)

1 participant