Skip to main content

Module wal

Module wal 

Source
Expand description

G114 — Write-Ahead Log (WAL) sidecar for crash recovery (v0.1.12). G114 — Write-Ahead Log (WAL) sidecar for crash-safe atomic writes.

§Problem

The atomic_write pipeline has 13 steps. If the process is killed (SIGKILL, OOM, power loss) between any two steps, the target file may be left in a partially-written, truncated, or otherwise inconsistent state. The variant AtomwriteError::CopyBackBlake3Failed (exit 92) indicates a partial WriteStrategy::CopyBack failure, but offers no recovery mechanism.

§Solution

Before performing any write, append a JSON journal entry to a sidecar file .atomwrite.journal.<target>.json that records:

  • The operation type (write / replace / edit)
  • The target path (relative to workspace)
  • The BLAKE3 checksum of the previous content (if any)
  • The BLAKE3 checksum of the new content (precomputed)
  • The PID and start timestamp
  • A 16-byte random op_id for idempotency

After the atomic rename succeeds, append a committed entry with the same op_id. On startup, the recover_orphan_journals function scans for .atomwrite.journal.*.json files whose last entry is not committed, and emits a structured NDJSON event wal_recovery per orphan, listing the original target, the pre-computed expected_new_checksum, and the recorded op_id for the caller to decide whether to replay or abort.

§Causa x Efeito

  • Causa: atomic_write é uma sequência de 13 passos; crash entre qualquer par pode deixar o arquivo em estado inconsistente.
  • Efeito: Sem WAL, recovery exige intervenção manual via git checkout, cp do backup mais recente, ou heurística ad-hoc.
  • Solução: Sidecar journal append-only + recovery idempotente via op_id; recovery é puramente consultivo (não toca o filesystem).
  • Benefício: Operador recebe wal_recovery NDJSON estruturado com target, expected_new_checksum, op_id para replay manual ou script de recovery.

Modules§

heuristics
Heuristics for deciding whether a Committed sidecar should be kept past the immediate Drop-guard removal (G119 L4).

Structs§

AutoHealReport
Result of an auto-heal pass on startup (G119 L3).
JournalGuard
RAII guard that removes the sidecar journal on normal drop (G119 L2).
OrphanJournalReport
Per-sidecar recovery report emitted by recover_orphan_journals. Populated for every sidecar whose last entry is Started (a real orphan that needs operator attention) and for sidecars whose last entry is Committed or Aborted (informational; safe to clean).
WalDirEntry
Count of journals in a single directory.
WalStateBreakdown
Breakdown of journals by terminal state.
WalStats
Snapshot of journal state for wal-stats (G119 L5 telemetry).

Enums§

JournalEntry
A single entry in the append-only WAL journal.
JournalOp
Operation type recorded in the journal.
WalPolicy
Policy governing WHEN a WAL sidecar is created (G119 L1 prevention).

Constants§

L1_LARGE_FILE_BYTES
Threshold above which a target file is considered “large” for the L1 prevention heuristic. Files smaller than this on a routine write do not generate a WAL sidecar in WalPolicy::Auto mode.

Functions§

auto_heal_on_startup
Auto-heal stale terminal journals on startup (G119 L3).
compute_wal_stats
Compute a snapshot of the current journal state. Read-only and safe to call from any context. Used by the wal-stats subcommand (G119 L5).
generate_op_id
Generate a 16-hex-char op ID from random bytes.
heuristics_should_preserve
Compose all 5 L4 heuristics into a single decision. Returns true when AT LEAST ONE heuristic votes to PRESERVE the sidecar.
journal_aborted
Append an Aborted entry to the journal for target.
journal_committed
Append a Committed entry to the journal for target.
journal_path
Compute the sidecar path used as the WAL journal for target.
journal_started
Append a Started entry to the journal for target.
journal_started_with_guard
Wrap a Started journal write in a Drop guard. On normal scope exit (the caller did not call keep()), the sidecar is removed — the Committed entry is the last useful record and the file is deleted to keep the working tree clean (G119 R1 fix).
recover_orphan_journals
Scan dir (non-recursive) for .atomwrite.journal.*.json sidecars and emit a recovery report for each orphan.
should_create_sidecar
Decide whether a sidecar should be created for target given the operation kind and the active policy (G119 L1).
walk_journal_paths
Recursively walk a directory and yield all *.atomwrite.journal.json sidecar paths. Returns an empty Vec if the workspace does not exist.