4.6 KiB
Retained execution journal - 2.1.0rc9
What is recorded
The worker captures only projected public Core metadata: job/run/sequence, source UTC time and receipt time, stage, opaque play/task IDs, approved/withheld labels, reviewed logical hosts, result/changed/ignored flags, supported retry/poll information, fixed diagnostic hints and recap counters. Unknown additive payloads, legacy duplicate progress in detail mode, raw stdout/stderr, debug bodies, credential frames and final report data are not journal entries.
Core labels remain withheld when Core withholds them. A missing host stays null; no inference from a nearby event. A task result can arrive interleaved with another host/task: use IDs, not last-arriving names. The result event records only that it was observed; the final response establishes the authoritative result and retained report.
The normal final Core result, targets and existing lifecycle/audit metadata remain separate. A journal does not become a second execution engine or replay operation.
Browser-independent capture
Capture starts in the execution child after review/claim checks. An open page is not required. A 2,048-entry nonblocking queue feeds batches of up to 128 events with a normal 250 ms flush target. SQLite synchronous FULL transactions publish the event rows, bounded checkpoint and durable cursor together. The writer's busy timeout is 250 ms. Closing tries to drain within 2.5 seconds and waits up to 3 seconds for its thread.
Those are bounded scheduling/lock budgets, not a guarantee against slow storage or physical failure. A crash can lose queued/uncommitted events. Queue or write failures increment a loss counter on the next possible commit. Persistent storage failure or a killed writer leaves an unclosed capture, shown as interrupted when the job ends. Metadata loss does not establish a task failure or success and never triggers re-execution. If the database cannot persist the final result, the normal workflow cannot certify success from a prior event.
Retention and display windows
[journal]
max_events = 20000
max_bytes = 8388608
The newest tail is retained. Older event rows are removed in the same commit when either limit is exceeded; a visible omission count/range remains. A bounded checkpoint retains last stage/play/task, observed task-start count, up to64 recent task contexts, and up to500 latest logical-host observations. Final Core facts do not depend on journal coverage. Limits are validated in Settings; the byte budget may be64KiB..64MiB and the event budget100..200000.
The initial page loads200 tail events; API pages allow1..500. The browser keeps at most2,000 displayed records, with a link to the paged timeline. Display pagination never changes retained counts. Large streams are rendered at most once per animation frame. Only the console's scrollTop changes; manual upward scrolling pauses Follow output.
Job deletion cascades through the journal. No terminal/Core-wide history collection and no shadow archive. Database/backup files stay in existing private storage; deletion is not secure physical erasure or deletion of prior backups. There is no silent age-pruning policy.
Reopen, reconnect and authorization
GET the snapshot/tail, then connect SSE strictly after the committed high-water cursor. Last-Event-ID takes precedence over the initial after query on reconnection. A per-job local cursor and unique(job, Core run, Core sequence) suppress duplicates. Filtered legacy events produce ordinary Core-sequence gaps, not automatic loss claims. Retention gaps are explicit.
Every read uses existing owner-or-admin job authorization. Every streaming iteration rechecks live session, password-change state and job access. A cursor is not permission. Deleted/inaccessible jobs end the feed and request clearing the view. Two devices read the same committed rows and never directly attach to the executor process.
When the job ends, SSE drains through the available committed cursor and ends; history remains readable. Worker/service interruption does not resume Ansible. Closing a page does not cancel a job or resend a credential.
Progress means last observed activity, not a total task graph. There is no invented percentage, ETA, list of future tasks or proof of stall from silence. Host observations are not final per-host outcomes. The displayed time is localized while stored values remain UTC.
Historical jobs
Schema migration does not fabricate progress for old jobs. They retain lifecycle and final facts but show detailed history unavailable. No terminal import or automatic rerun fills gaps. A new queued job may show waiting for capture until the execution child starts.