pub struct Log;Expand description
The store’s chronological log: a thin handle for the append-only timeline.
All methods take the Store so they resolve the active log.md and the
log/ archives under the store root.
Implementations§
Source§impl Log
impl Log
Sourcepub fn append(store: &Store, entry: &LogEntry) -> Result<()>
pub fn append(store: &Store, entry: &LogEntry) -> Result<()>
Atomically append entry to the active log.md, creating it (with
type: log frontmatter) if absent. If the active log holds entries
from a prior month, roll those older months into log/<YYYY-MM>.md
first (atomic move), keeping the active file to the current month.
Sourcepub fn tail(store: &Store, n: usize) -> Result<Vec<LogEntry>>
pub fn tail(store: &Store, n: usize) -> Result<Vec<LogEntry>>
The n most-recent entries by timestamp, returned oldest→newest.
Out-of-order safety (mirrors Log::since). The log is append-only
but not guaranteed to be in non-decreasing timestamp order on disk: a
corrective entry is appended below the entry it corrects, a
backdated/clock-skewed write lands physically after newer entries, and a
merge=union clone merge interleaves both sides until a later agent
reorders. Out-of-order is only a LOG_OUT_OF_ORDER warning, never
rejected. So the last n physical entries are not the n newest
by time — taking them would omit a genuinely-recent entry that sits
physically before an older one, and the documented curator warm-up
(dbmd log tail 20) would report a stale picture of what was done lately.
We therefore feed every entry of each file we touch through a bounded
newest-by-timestamp window and let it select the true top n.
Bounded cost: the active log.md is kept to the current month by
rotation, so a full read of it is cheap and is not a whole-store walk.
Across archives we can prune: each log/<YYYY-MM>.md holds only entries
from that month (rotation buckets by the entry’s own year-month), so once
the window is full, an archive whose month is strictly before the
window-minimum’s month cannot contain any entry newer than the current
nth-newest. We cross archives newest-month-first and stop at the first
such archive.
Sourcepub fn since(
store: &Store,
time: DateTime<FixedOffset>,
) -> Result<Vec<LogEntry>>
pub fn since( store: &Store, time: DateTime<FixedOffset>, ) -> Result<Vec<LogEntry>>
Entries strictly newer than time, reverse-scanning active → archives.
No within-file early stop. The log is append-only but not
guaranteed to be in non-decreasing timestamp order on disk: a corrective
entry is appended below the entry it corrects (SPEC: “if a finding is
wrong, append a corrective entry below it”), a backdated/clock-skewed
write lands physically after newer entries, and a merge=union clone
merge interleaves both sides until a later agent reorders. Out-of-order
is only a LOG_OUT_OF_ORDER warning, never rejected. So a newer entry
can sit physically before an older one; stopping at the first
older-than-time entry would silently drop those — the documented
curator warm-up (dbmd log since <ts>) would miss real recent work.
We therefore read every entry of each file we touch.
Bounded cost: the active log.md is kept to the current month by
rotation, so a full read of it is cheap (the same read tail does for a
large n) and is not a whole-store walk. Across archives we can stop:
each log/<YYYY-MM>.md holds only entries from that month (rotation
buckets by the entry’s own year-month), so an archive whose month is
strictly before time’s month cannot contain any entry newer than
time. We cross archives newest-month-first and stop at the first whose
month is entirely at or before time’s.
Sourcepub fn last_validate_at(store: &Store) -> Result<Option<DateTime<FixedOffset>>>
pub fn last_validate_at(store: &Store) -> Result<Option<DateTime<FixedOffset>>>
The timestamp of the most recent validate entry — the default since
window for working-set validation (crate::validate::validate_working_set).
Sourcepub fn parse_header(
line: &str,
) -> Option<(DateTime<FixedOffset>, LogKind, Option<String>)>
pub fn parse_header( line: &str, ) -> Option<(DateTime<FixedOffset>, LogKind, Option<String>)>
Parse a single entry header (## [YYYY-MM-DD HH:MM] <kind> | <object>)
into its timestamp, kind, and object. Returns None if the line isn’t a
well-formed entry header.