wal

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 4, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package wal is a durable, file-based write-ahead log of edit intents. Each Append fsyncs one JSON-encoded record (one line) to <dir>/wal.log; Replay reads every record back in order. There is no SQLite or external store: the log is a plain append-only file so a crash mid-edit can be reconciled on restart by replaying the recorded intents.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Append

func Append(dir string, in Intent) error

Append durably records one intent. It creates dir if needed, then opens <dir>/wal.log in append mode, writes the JSON encoding of in as a single line, and fsyncs the file before returning so the record survives a crash.

Types

type Intent

type Intent struct {
	// ID uniquely identifies this intent.
	ID string `json:"id"`
	// Edits are the byte-range replacements this intent will apply.
	Edits []locator.FileEdit `json:"edits"`
	// Originals maps each affected file path to its pre-edit raw bytes.
	Originals map[string][]byte `json:"originals"`
	// ExpectedRawHash maps each file path to its expected raw content hash.
	ExpectedRawHash map[string]string `json:"expected_raw_hash"`
	// ExpectedNormHash maps each file path to its expected normalized hash.
	ExpectedNormHash map[string]string `json:"expected_norm_hash"`
	// Creates lists the paths this intent is creating from non-existence. On
	// crash recovery or rollback each path is unlinked, undoing a half-created
	// file. Nil for edit-only intents (ADR-0004).
	Creates []string `json:"creates,omitempty"`
	// Deletes lists the paths this intent is removing. It is the inverse of
	// Creates: a delete's undo is a content RESTORE, so each deleted path's FULL
	// prior bytes are captured in Originals before the unlink, and a crash or
	// rollback restores them from there on recovery (ADR-0004). Nil for non-delete
	// intents; the `omitempty` tag keeps older records (written before Deletes
	// existed) decoding cleanly so Replay over a mixed log keeps working.
	Deletes []string `json:"deletes,omitempty"`
	// Moves lists the {From,To} relocations this intent is performing. A move is a
	// DELETE(From)+CREATE(To) as one atomic-on-recovery unit (ADR-0004): the source
	// bytes are captured in Originals[From] BEFORE the destination is claimed and
	// the source unlinked, so a crash converges to fully-moved or fully-original
	// and the source bytes are never lost. Nil for non-move intents; the
	// `omitempty` tag keeps older records (written before Moves existed) decoding
	// cleanly so Replay over a mixed log keeps working.
	Moves []Move `json:"moves,omitempty"`
	// Batch marks a UNIFIED BATCH intent (Session.ApplyBatch, ADR-0004 §10.1): a
	// heterogeneous []Op applied as ONE all-or-nothing change. Its recovery model
	// is INTERNALLY ONE-DIRECTIONAL — Recover converges a batch intent fully
	// BACKWARD (to the pre-batch state), so a Move inside a batch is UNDONE
	// (restore Originals[From] at From, remove To) in the same backward direction
	// as the batch's edits/deletes/creates, never converged forward. A single-op
	// MoveFile leaves this false and keeps its own FORWARD-converge semantics, so a
	// batch can never produce the half-applied state where the move completes while
	// the other ops roll back. The `omitempty` tag keeps older records decoding
	// cleanly (absent key => false => single-op semantics).
	Batch bool `json:"batch,omitempty"`
}

Intent is one durably-recorded edit intent. It captures the edits to apply, the original bytes of each affected file (for restore-on-failure), and the expected raw and normalized content hashes per file (for drift detection) so a recovering process has everything needed to reapply or roll back.

The Creates field is an ADDITIVE extension for file-lifecycle create ops (ADR-0004): it records the paths a create intent is bringing into existence so a crash or rollback can UNLINK each half-created file (create's undo is unlink, not a content restore). It is the zero value (nil) for edit-only intents, and because the field carries `omitempty` an old edit-only record written before Creates existed still unmarshals cleanly (the absent key decodes to nil), so Replay over a mixed log keeps working.

func Replay

func Replay(dir string) ([]Intent, error)

Replay reads every recorded intent from <dir>/wal.log in append order. A missing directory or log file is treated as an empty log: it returns an empty slice and no error.

type Move added in v0.2.0

type Move struct {
	// From is the source path the move removes.
	From string `json:"from"`
	// To is the destination path the move creates with the source bytes.
	To string `json:"to"`
}

Move is one source->destination relocation recorded in an Intent. From is the source path being removed; To is the destination path being created with the source's bytes (captured in Intent.Originals[From]). Recover uses the pair to converge a crashed move (ADR-0004).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL