gleamunison/store_log
The store’s own record of what happened to it.
Two append-only logs beside the store file, each keyed by a monotonic
sequence number: content (what entered the store) and exec (what was
run, and how it ended). They are separate from the store because the store
is content-addressed and immutable, while a log is time-ordered: writing a
changing fact into the store would put it behind a hash that cannot change.
The logs are store-owned. Any command that admits or executes a definition writes to them, so the record does not depend on which CLI path ran.
Types
pub type ContentEntry {
ContentEntry(ref_hex: String, kind: String, at: Int)
}
Constructors
-
ContentEntry(ref_hex: String, kind: String, at: Int)
pub type ExecEntry {
ExecEntry(
ref_hex: String,
outcome: String,
reason: String,
caller: String,
at: Int,
)
}
Constructors
-
ExecEntry( ref_hex: String, outcome: String, reason: String, caller: String, at: Int, )
One row of the merged view: either kind of entry, in chronological order.
pub type MergedEntry {
MergedEntry(
kind: String,
ref_hex: String,
label: String,
detail: String,
at: Int,
)
}
Constructors
-
MergedEntry( kind: String, ref_hex: String, label: String, detail: String, at: Int, )
Values
pub fn content_tail(
dir: String,
n: Int,
) -> Result(List(ContentEntry), String)
pub fn merged_tail(
dir: String,
n: Int,
) -> Result(List(MergedEntry), String)
Both logs as one chronological view. Every row carries its kind, so a reader can tell an admission from an execution without consulting two commands.
pub fn record_content(
dir: String,
ref_hex: String,
kind: String,
) -> Result(Nil, String)
Record that a definition entered the store. Failure is returned, never swallowed: a store that cannot say what it holds is a store you cannot audit.
pub fn record_exec(
dir: String,
ref_hex: String,
outcome: String,
reason: String,
caller: String,
) -> Result(Nil, String)
Record one execution attempt: outcome is “ok” or “refused”, reason names why when it is not “ok”.