Skip to main content

Store

Struct Store 

Source
pub struct Store { /* private fields */ }
Expand description

The single-writer store handle (see the module docs for the durability rules and the single-writer discipline).

Implementations§

Source§

impl Store

Source

pub fn open(root: impl AsRef<Path>) -> Result<Self, StoreError>

Opens (creating if needed) the store rooted at root: the SQLite database at <root>/pointlock.db and the evidence area at <root>/evidence/. Sets journal_mode=WAL, synchronous=FULL (the actionIntent fsync semantics depend on FULL) and foreign_keys=ON, and applies the DDL.

Source

pub fn root(&self) -> &Path

The store’s root directory.

Source

pub fn begin_run(&mut self, new_run: NewRun) -> Result<String, StoreError>

Creates the run row (status running) and returns the run id.

The caller is expected to append the runStarted event next — the row only seeds the fold input (RunMeta); it is not a log entry.

Source

pub fn append_event( &mut self, run_id: &str, at_ms: u64, run_path: &RunPath, payload: &RunLogPayload, ) -> Result<u64, StoreError>

Appends one event and returns its allocated seq.

One IMMEDIATE transaction covers: seq := MAX(seq)+1 allocation, the run_log insert, the checkpoint re-materialization, and the run.status transition. The materialization folds incrementally through the per-run single-writer fold cache; any seq discontinuity falls back to the full refold, and the persisted view is identical either way. Atomicity means an event whose fold fails is refused — the log can never outrun the materialized view.

Source

pub fn write_action_intent( &mut self, run_id: &str, at_ms: u64, run_path: &RunPath, call_id: &str, args_snapshot: Value, dispatch: Option<IntentDispatch>, ) -> Result<u64, StoreError>

Appends the actionIntent WAL entry in its own transaction and returns its seq.

Dispatch discipline (07 §3.3 rule 1): under WAL + synchronous=FULL, this method returning Ok means the intent is durably on disk — that is the “fsync before dispatch” of spine §6.2. Callers MUST invoke this and observe the Ok before calling provider.execute; on crash, reconcile(callId) finds the intent regardless of whether the dispatch left the process.

Source

pub fn submit_human_response( &mut self, run_id: &str, request_id: &str, actor: &str, at_ms: u64, response: Value, ) -> Result<u64, StoreError>

The single-writer arbitration of a human response (06 §4.3; R13): validates the response against the pending request read back from the ledger and — only when every rule passes — appends the humanResponded event, returning its seq.

at_ms is the store-receipt clock, the only timeout judge (06 §4.3 rule 2): a response received after the request’s deadlineAtMs is refused with HumanResponseRejection::DeadlineExpired and no event is written — the lazy settlement of the expired request itself stays the runner’s job on resume (06 §5.3).

Arbitration rules, in order (all rejections are typed StoreError::HumanResponseRejected and side-effect free — bad data never enters the ledger):

  1. The request must exist (humanRequested with this id).
  2. First response wins: a request with a paired final response is closed. A supervision suspend answer is non-final (spine §6.9) — it is recorded but keeps the request open for a later proceed/abort ruling.
  3. at_ms must not exceed the request’s deadlineAtMs (supervision requests carry none and never expire).
  4. The request must still be pending (a lazily-settled step no longer accepts responses).
  5. The payload must match the shape the request’s purpose/mode demands (06 §2.1 union as adjudicated): confirm {decision ∈ decisions, note?}, judge {status ∈ pass|fail|unknown, note?}, provideInput {input (validated against outputSchema), note?}, repairWorld {decision ∈ the request's declared decisions, else done|cannotRepair (06 §2.1), note?}, supervision {decision ∈ proceed|abort|suspend, note?}.

Single-writer discipline makes check-then-append race-free: this Store owns the only write connection.

Source

pub fn rebuild_checkpoint( &self, run_id: &str, ) -> Result<CheckpointView, StoreError>

Rebuilds the CheckpointView by folding the run’s full log (07 §3.3 rebuild channel). Read-only; does not touch the materialized row.

Source

pub fn verify_checkpoint( &self, run_id: &str, ) -> Result<CheckpointView, StoreError>

I1’s runtime self-check (backs pointlock inspect --rebuild-checkpoint): asserts materialized == rebuilt.

Verifies that (a) the checkpoint row exists and its log_seq is the log head, (b) the stored view equals the full-log refold, and (c) run.status equals the folded status. Any inequality is a store-layer bug surfaced as a typed error. Returns the verified view.

Source

pub fn put_evidence( &mut self, bytes: &[u8], media_type: &str, ) -> Result<EvidencePut, StoreError>

Localizes evidence bytes into the content-addressed area and indexes them, idempotently. Layout: <root>/evidence/sha256/<hex[0..2]>/<hex[2..4]>/<digest>.

file-before-row (07 §3.3 rule 3): bytes are written to a temp file, fsynced, renamed into place (and the directory fsynced) before the evidence row is inserted; the caller appends the referencing RunLog event only after this returns. Re-putting identical bytes is a no-op dedup (deduplicated: true).

Links a RunLog event to a localized evidence entry (evidence_ref row; idempotent). foreign_keys=ON rejects links to evidence that was never put.

Source

pub fn run_meta(&self, run_id: &str) -> Result<RunMeta, StoreError>

Reads the run’s metadata row (the fold input).

Source

pub fn run_status(&self, run_id: &str) -> Result<RunStatus, StoreError>

Reads the run’s current lifecycle status.

Source

pub fn revision(&self, run_id: &str) -> Result<u64, StoreError>

The run’s current revision = its max ledger seq (0 before the first event) — the SSE invalidation currency (08 §5). Cheap by design: the pollers behind --serve call this a few times a second.

Source

pub fn global_revision(&self) -> Result<u64, StoreError>

A store-wide monotonic revision (= sum of every run’s head seq): the inbox stream’s invalidation currency — any append anywhere moves it.

Source

pub fn evidence_meta( &self, sha256: &str, ) -> Result<Option<EvidenceMeta>, StoreError>

Resolves one content-addressed evidence entry to its media type and absolute path (the /evidence/:sha256 byte route — 08 §4.3 dereference side; the address is the only key, never a path).

Source

pub fn list_runs(&self) -> Result<Vec<RunListEntry>, StoreError>

Lists every run, in creation order (projection read side: the cross-run inbox and the flow run index consume this).

Source

pub fn events(&self, run_id: &str) -> Result<Vec<RunLogEvent>, StoreError>

Reads the run’s full ordered event log.

Source

pub fn materialized_checkpoint( &self, run_id: &str, ) -> Result<Option<(u64, CheckpointView)>, StoreError>

Reads the materialized checkpoint row, if any: (log_seq, view). None until the first event is appended.

Auto Trait Implementations§

§

impl !Freeze for Store

§

impl !RefUnwindSafe for Store

§

impl !Sync for Store

§

impl !UnwindSafe for Store

§

impl Send for Store

§

impl Unpin for Store

§

impl UnsafeUnpin for Store

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more