Trait SopRunStore
pub trait SopRunStore: Send + Sync {
Show 25 methods
// Required methods
fn save_run(&self, run: &PersistedRun) -> Result<(), StoreError>;
fn save_run_with_event(
&self,
run: &PersistedRun,
ev: &SopEventRecord,
) -> Result<u64, StoreError>;
fn finish_run(
&self,
run_id: &str,
terminal: &PersistedRun,
) -> Result<(), StoreError>;
fn finish_run_with_event(
&self,
run_id: &str,
terminal: &PersistedRun,
ev: &SopEventRecord,
) -> Result<u64, StoreError>;
fn load_active_runs(&self) -> Result<Vec<PersistedRun>, StoreError>;
fn load_terminal_runs(
&self,
limit: usize,
) -> Result<Vec<PersistedRun>, StoreError>;
fn load_run(&self, run_id: &str) -> Result<Option<PersistedRun>, StoreError>;
fn last_terminal_completed_at(
&self,
sop_name: &str,
) -> Result<Option<String>, StoreError>;
fn try_claim_run(
&self,
run_id: &str,
sop_name: &str,
per_sop_cap: usize,
global_cap: usize,
) -> Result<Option<ClaimToken>, StoreError>;
fn renew_claim_for_restore(
&self,
run_id: &str,
sop_name: &str,
) -> Result<ClaimToken, StoreError>;
fn claim_counts(&self, sop_name: &str) -> Result<(usize, usize), StoreError>;
fn heartbeat_claim(&self, token: &ClaimToken) -> Result<(), StoreError>;
fn release_claim(&self, token: &ClaimToken) -> Result<(), StoreError>;
fn expired_claims(
&self,
now_iso: &str,
) -> Result<Vec<ClaimToken>, StoreError>;
fn append_event(&self, ev: &SopEventRecord) -> Result<u64, StoreError>;
fn list_events(
&self,
run_id: &str,
) -> Result<Vec<SopEventRecord>, StoreError>;
fn save_proposal(&self, p: &ProposalRecord) -> Result<(), StoreError>;
fn load_proposal(
&self,
id: &str,
) -> Result<Option<ProposalRecord>, StoreError>;
fn list_proposals(
&self,
status: Option<ProposalStatus>,
) -> Result<Vec<ProposalRecord>, StoreError>;
fn prune(&self, policy: &RetentionPolicy) -> Result<usize, StoreError>;
fn health_check(&self) -> bool;
fn backend(&self) -> &'static str;
// Provided methods
fn save_run_with_pending_capacity(
&self,
run: &PersistedRun,
max_pending: usize,
) -> Result<bool, StoreError> { ... }
fn mark_claim_retained_after_terminal_rollback(
&self,
_run_id: &str,
) -> Result<(), StoreError> { ... }
fn has_retained_terminal_rollback_claim(
&self,
_run_id: &str,
) -> Result<bool, StoreError> { ... }
}Required Methods§
Sourcefn save_run(&self, run: &PersistedRun) -> Result<(), StoreError>
fn save_run(&self, run: &PersistedRun) -> Result<(), StoreError>
Persist-before-mutate. Revision-guarded: a strictly-older revision is
rejected as StaleRevision; an equal revision is accepted only as a
byte-identical idempotent retry, else RevisionConflict; a newer
revision wins.
Sourcefn save_run_with_event(
&self,
run: &PersistedRun,
ev: &SopEventRecord,
) -> Result<u64, StoreError>
fn save_run_with_event( &self, run: &PersistedRun, ev: &SopEventRecord, ) -> Result<u64, StoreError>
Persist an active run transition and append its audit event as one store
outcome. Implementations must make both writes visible together or neither
visible at all; callers use this for approval gate resolution so a durable
gate_resolved row cannot exist without the run transition it authorizes.
Sourcefn finish_run(
&self,
run_id: &str,
terminal: &PersistedRun,
) -> Result<(), StoreError>
fn finish_run( &self, run_id: &str, terminal: &PersistedRun, ) -> Result<(), StoreError>
Move a run to terminal state (kept as a terminal record, not deleted) and
release any live claim. Revision-guarded exactly like save_run, so a
stale or divergent terminal write cannot clobber newer state or release a
live claim.
Sourcefn finish_run_with_event(
&self,
run_id: &str,
terminal: &PersistedRun,
ev: &SopEventRecord,
) -> Result<u64, StoreError>
fn finish_run_with_event( &self, run_id: &str, terminal: &PersistedRun, ev: &SopEventRecord, ) -> Result<u64, StoreError>
Move a run to terminal state and append its audit event as one store outcome. Claim release is part of the terminal transition and must be in the same atomic boundary as the audit append.
Sourcefn load_active_runs(&self) -> Result<Vec<PersistedRun>, StoreError>
fn load_active_runs(&self) -> Result<Vec<PersistedRun>, StoreError>
Boot-rehydrate source: every non-terminal run (latest revision per id).
Sourcefn load_terminal_runs(
&self,
limit: usize,
) -> Result<Vec<PersistedRun>, StoreError>
fn load_terminal_runs( &self, limit: usize, ) -> Result<Vec<PersistedRun>, StoreError>
Boot-rehydrate source for the display retention window: terminal runs,
newest-first by started_at, truncated to limit (0 = unbounded). The
engine seeds finished_runs from this so completed/failed/cancelled runs
survive a restart in the Runs surface, matching max_finished_runs.
Sourcefn load_run(&self, run_id: &str) -> Result<Option<PersistedRun>, StoreError>
fn load_run(&self, run_id: &str) -> Result<Option<PersistedRun>, StoreError>
Single run by id (latest revision), terminal or not.
Sourcefn last_terminal_completed_at(
&self,
sop_name: &str,
) -> Result<Option<String>, StoreError>
fn last_terminal_completed_at( &self, sop_name: &str, ) -> Result<Option<String>, StoreError>
completed_at of the most recently successful terminal run for sop_name,
or None if that SOP has no completed run with a recorded completion.
Drives the cooldown check off the shared store so every engine holder
observes the same success marker (not just the engine that ran the SOP).
fn try_claim_run( &self, run_id: &str, sop_name: &str, per_sop_cap: usize, global_cap: usize, ) -> Result<Option<ClaimToken>, StoreError>
fn renew_claim_for_restore( &self, run_id: &str, sop_name: &str, ) -> Result<ClaimToken, StoreError>
Sourcefn claim_counts(&self, sop_name: &str) -> Result<(usize, usize), StoreError>
fn claim_counts(&self, sop_name: &str) -> Result<(usize, usize), StoreError>
Live claim counts as (for_sop, total), used by read-only admission
checks so status surfaces observe the same concurrency source as CAS.
Sourcefn heartbeat_claim(&self, token: &ClaimToken) -> Result<(), StoreError>
fn heartbeat_claim(&self, token: &ClaimToken) -> Result<(), StoreError>
Renew a claim’s lease (tick liveness). No-op if the claim is gone.
Sourcefn release_claim(&self, token: &ClaimToken) -> Result<(), StoreError>
fn release_claim(&self, token: &ClaimToken) -> Result<(), StoreError>
Release a claim (finish/cancel), freeing the slot for admission.
Sourcefn expired_claims(&self, now_iso: &str) -> Result<Vec<ClaimToken>, StoreError>
fn expired_claims(&self, now_iso: &str) -> Result<Vec<ClaimToken>, StoreError>
Reaper source: claims whose lease expired at/<= now_iso.
Sourcefn append_event(&self, ev: &SopEventRecord) -> Result<u64, StoreError>
fn append_event(&self, ev: &SopEventRecord) -> Result<u64, StoreError>
Append-only, monotonic-seq, never-overwrite. Returns the assigned seq.
Sourcefn list_events(&self, run_id: &str) -> Result<Vec<SopEventRecord>, StoreError>
fn list_events(&self, run_id: &str) -> Result<Vec<SopEventRecord>, StoreError>
Ordered event history for a run.
fn save_proposal(&self, p: &ProposalRecord) -> Result<(), StoreError>
fn load_proposal(&self, id: &str) -> Result<Option<ProposalRecord>, StoreError>
fn list_proposals( &self, status: Option<ProposalStatus>, ) -> Result<Vec<ProposalRecord>, StoreError>
Sourcefn prune(&self, policy: &RetentionPolicy) -> Result<usize, StoreError>
fn prune(&self, policy: &RetentionPolicy) -> Result<usize, StoreError>
Drop terminal runs beyond the retention policy. Returns the count dropped.
fn health_check(&self) -> bool
Provided Methods§
Sourcefn save_run_with_pending_capacity(
&self,
run: &PersistedRun,
max_pending: usize,
) -> Result<bool, StoreError>
fn save_run_with_pending_capacity( &self, run: &PersistedRun, max_pending: usize, ) -> Result<bool, StoreError>
Persist a parked approval/checkpoint run only if this SOP still has room
in its pending pool. Returns Ok(false) without saving when the pool is
full. Store implementations should make the count and save one atomic
critical section; the default preserves compatibility for test wrappers.
Sourcefn mark_claim_retained_after_terminal_rollback(
&self,
_run_id: &str,
) -> Result<(), StoreError>
fn mark_claim_retained_after_terminal_rollback( &self, _run_id: &str, ) -> Result<(), StoreError>
Mark an existing live claim as intentionally retained while a failed terminal checkpoint decision is retried. No-op if the claim is already gone; the caller is already failing closed on the original transition.
Sourcefn has_retained_terminal_rollback_claim(
&self,
_run_id: &str,
) -> Result<bool, StoreError>
fn has_retained_terminal_rollback_claim( &self, _run_id: &str, ) -> Result<bool, StoreError>
Whether the live claim for run_id is an intentional terminal-rollback
retention marker rather than a stale parked claim from old behavior.