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
impl Store
Sourcepub fn open(root: impl AsRef<Path>) -> Result<Self, StoreError>
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.
Sourcepub fn begin_run(&mut self, new_run: NewRun) -> Result<String, StoreError>
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.
Sourcepub fn append_event(
&mut self,
run_id: &str,
at_ms: u64,
run_path: &RunPath,
payload: &RunLogPayload,
) -> Result<u64, StoreError>
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.
Sourcepub 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>
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.
Sourcepub fn submit_human_response(
&mut self,
run_id: &str,
request_id: &str,
actor: &str,
at_ms: u64,
response: Value,
) -> Result<u64, StoreError>
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):
- The request must exist (
humanRequestedwith this id). - First response wins: a request with a paired final response
is closed. A supervision
suspendanswer is non-final (spine §6.9) — it is recorded but keeps the request open for a later proceed/abort ruling. at_msmust not exceed the request’sdeadlineAtMs(supervision requests carry none and never expire).- The request must still be pending (a lazily-settled step no longer accepts responses).
- 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.
Sourcepub fn rebuild_checkpoint(
&self,
run_id: &str,
) -> Result<CheckpointView, StoreError>
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.
Sourcepub fn verify_checkpoint(
&self,
run_id: &str,
) -> Result<CheckpointView, StoreError>
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.
Sourcepub fn put_evidence(
&mut self,
bytes: &[u8],
media_type: &str,
) -> Result<EvidencePut, StoreError>
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).
Sourcepub fn link_evidence(
&mut self,
run_id: &str,
seq: u64,
asset_id: &str,
sha256: &str,
) -> Result<(), StoreError>
pub fn link_evidence( &mut self, run_id: &str, seq: u64, asset_id: &str, sha256: &str, ) -> Result<(), StoreError>
Links a RunLog event to a localized evidence entry
(evidence_ref row; idempotent). foreign_keys=ON rejects links
to evidence that was never put.
Sourcepub fn run_meta(&self, run_id: &str) -> Result<RunMeta, StoreError>
pub fn run_meta(&self, run_id: &str) -> Result<RunMeta, StoreError>
Reads the run’s metadata row (the fold input).
Sourcepub fn run_status(&self, run_id: &str) -> Result<RunStatus, StoreError>
pub fn run_status(&self, run_id: &str) -> Result<RunStatus, StoreError>
Reads the run’s current lifecycle status.
Sourcepub fn revision(&self, run_id: &str) -> Result<u64, StoreError>
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.
Sourcepub fn global_revision(&self) -> Result<u64, StoreError>
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.
Sourcepub fn evidence_meta(
&self,
sha256: &str,
) -> Result<Option<EvidenceMeta>, StoreError>
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).
Sourcepub fn list_runs(&self) -> Result<Vec<RunListEntry>, StoreError>
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).
Sourcepub fn events(&self, run_id: &str) -> Result<Vec<RunLogEvent>, StoreError>
pub fn events(&self, run_id: &str) -> Result<Vec<RunLogEvent>, StoreError>
Reads the run’s full ordered event log.
Sourcepub fn materialized_checkpoint(
&self,
run_id: &str,
) -> Result<Option<(u64, CheckpointView)>, StoreError>
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.