pub struct Journal { /* private fields */ }Expand description
Append-only event log with a project-authoritative path and a best-effort global mirror.
Implementations§
Source§impl Journal
impl Journal
Sourcepub fn new(
project_path: ProjectJournalPath,
global_path: GlobalJournalPath,
) -> Self
pub fn new( project_path: ProjectJournalPath, global_path: GlobalJournalPath, ) -> Self
Create a Journal. Paths are injected via newtypes (F9) to prevent silent
positional swap of the two same-type PathBuf arguments.
The runtime never hard-codes ~/.fno/. The driver CLI wires the real
paths (task 1.2). Tests use tempdir paths.
Sourcepub fn new_raw(project_path: PathBuf, global_path: PathBuf) -> Self
pub fn new_raw(project_path: PathBuf, global_path: PathBuf) -> Self
Convenience constructor accepting plain PathBufs directly. Intended for
tests where importing the newtype wrappers would add noise. Production
callers should prefer Journal::new (which enforces distinct types).
Sourcepub fn append(&self, event_type: &str, data: Value) -> Result<(), LoopError>
pub fn append(&self, event_type: &str, data: Value) -> Result<(), LoopError>
Append one event line to the project journal (fatal on failure) and mirror it to the global file (best-effort).
The envelope shape is:
{"ts":"YYYY-MM-DDTHH:MM:SSZ","type":"<kind>","source":"loop","data":{...}}
Method name is append (NOT emit/emit_fields) so the
daemon-stream parity scanner in lib.rs (which greps for .emit()
does not require these kinds to be registered in KNOWN_EVENT_KINDS.
These are loop-stream events, not daemon-stream events.
Sourcepub fn find_termination(
&self,
session_key: &str,
) -> Result<Option<Evidence>, LoopError>
pub fn find_termination( &self, session_key: &str, ) -> Result<Option<Evidence>, LoopError>
Scan journals for the LAST termination event matching session_key.
§Search order (ab-7303e5d7: cross-cwd delivery via global mirror)
- Scan the project journal first (authoritative for single-cwd target walks).
- When no match is found AND the global path differs from the project path,
scan the global journal (
~/.fno/events.jsonl).
Rationale: worker sessions dispatched by the megawalk walker run /target
in their OWN conductor worktrees, so their termination events land in the
WORKTREE’s events.jsonl. loopcheck’s emit_to_both also mirrors them to
~/.fno/events.jsonl (the global path). The walker’s project journal
lives at the walker’s cwd; only the global mirror is shared across cwds.
Returns None if not found in either journal or on read errors (fail
tolerant: unreadable journal = no pre-existing termination).
Uses BufReader + .lines() to stream files rather than loading them
entirely; the journal rotates at 8 MB but can grow to that before
rotation, so streaming avoids a large allocation on hot paths.
Unknown reason strings are treated as no-match (warn to stderr).
Unreadable lines (I/O errors from .lines()) are skipped silently.
Auto Trait Implementations§
impl Freeze for Journal
impl RefUnwindSafe for Journal
impl Send for Journal
impl Sync for Journal
impl Unpin for Journal
impl UnsafeUnpin for Journal
impl UnwindSafe for Journal
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.