Global revision counter and per-durability-level change tracking.
The revision is a monotonically increasing integer representing a version of the world. It increments every time any input changes. Durability tracking enables skipping validation of subgraphs rooted in high-durability inputs (see D6).
Durability levels
Durability classifies how often an input changes:
:high— almost never (standard library, language definitions):medium— occasionally (project source files not being edited):low— constantly (the file currently open in the editor)
During validation, if a query's entire dependency subgraph has minimum
durability :high and last_changed(rev, :high) < query.verified_at,
the query can skip graph traversal entirely.
Concurrency
All operations are lock-free. advance/2 uses :atomics.add_get/3 for
the global counter and :atomics.put/3 for durability tracking.
last_changed_at_or_above/2 reads multiple atomics slots without
cross-slot atomicity — the worst case is a spurious validation
(conservative, not incorrect).
Summary
Functions
Increments the global revision counter and records which durability level changed. Returns the new revision number.
Reads the current global revision. Lock-free.
Returns the revision at which the given durability level last had an input change. Returns 0 if no input at that level has ever changed.
Returns the maximum revision across all durability levels at or above the given level. Used for the durability optimization during validation.
Creates a new revision tracker. Initial revision is 0 (no inputs set yet).
Restores atomics state from a snapshot produced by snapshot/1.
Captures the current state of all atomics for manifest persistence.
Types
@type durability() :: :high | :medium | :low
@type revision() :: non_neg_integer()
@type t() :: %Roux.Revision{ counter: :atomics.atomics_ref(), durability: :atomics.atomics_ref() }
Functions
@spec advance(t(), durability()) :: revision()
Increments the global revision counter and records which durability level changed. Returns the new revision number.
Called when an input is set or modified.
Reads the current global revision. Lock-free.
@spec last_changed(t(), durability()) :: revision()
Returns the revision at which the given durability level last had an input change. Returns 0 if no input at that level has ever changed.
Used during validation to skip subgraphs.
@spec last_changed_at_or_above(t(), durability()) :: revision()
Returns the maximum revision across all durability levels at or above the given level. Used for the durability optimization during validation.
Higher durability means more stable (changes less often):
:lowincludes:low+:medium+:highchanges (all levels).:mediumincludes:medium+:highchanges.:highincludes only:highchanges.
@spec new() :: t()
Creates a new revision tracker. Initial revision is 0 (no inputs set yet).
@spec restore(t(), %{ counter: revision(), high: revision(), medium: revision(), low: revision() }) :: :ok
Restores atomics state from a snapshot produced by snapshot/1.
Used during manifest loading to resume the revision timeline across VM restarts.
@spec snapshot(t()) :: %{ counter: revision(), high: revision(), medium: revision(), low: revision() }
Captures the current state of all atomics for manifest persistence.
Returns a plain map that can be serialized with :erlang.term_to_binary/1.