Skip to main content

TransactionStore

Struct TransactionStore 

Source
pub struct TransactionStore { /* private fields */ }

Implementations§

Source§

impl TransactionStore

Source

pub fn open_read_only( path: impl AsRef<Path>, ) -> Result<Self, TransactionStoreError>

Open the store with no audit chain key. Inserts will fail with AuditChainMissing — only suitable for read-only callers (e.g. sysknife audit verify which loads the key separately).

Source

pub fn open(path: impl AsRef<Path>) -> Result<Self, TransactionStoreError>

Open the store and bind it to an audit chain key. Every insert computes a forward Ed25519-signed chain hash linked to the previous row.

The key path defaults to <db_dir>/audit-key so dev/test runs with per-tempdir databases are fully isolated. Production deployments override with SYSKNIFE_AUDIT_KEY_PATH=/etc/sysknife/audit-key.

Source

pub fn open_with_key( path: impl AsRef<Path>, audit_key: Arc<AuditKey>, ) -> Result<Self, TransactionStoreError>

Open the store with an explicit audit key. Used by tests and by production code paths that want to inject a key from a specific path.

Source

pub fn record( &self, transaction: NewTransaction, ) -> Result<TransactionRecord, TransactionStoreError>

Source

pub fn record_previewed( &self, transaction: NewTransaction, preview: PreviewEnvelope, ) -> Result<RecordedPreviewedTransaction, TransactionStoreError>

Source

pub fn get( &self, transaction_id: &str, ) -> Result<Option<TransactionRecord>, TransactionStoreError>

Source

pub fn get_preview( &self, transaction_id: &str, ) -> Result<Option<PreviewEnvelope>, TransactionStoreError>

Source

pub fn update_status( &self, transaction_id: &str, new_status: JobState, ) -> Result<(), TransactionStoreError>

Source

pub fn approve_transaction( &self, transaction_id: &str, ) -> Result<Option<String>, TransactionStoreError>

Attach one immutable approval receipt digest to a fresh queued preview.

Source

pub fn revoke_unconsumed_approval( &self, transaction_id: &str, ) -> Result<bool, TransactionStoreError>

Remove an approval that was persisted but could not be delivered to the caller. Consumed receipts are never revocable.

Source

pub fn claim_approved_for_execution( &self, transaction_id: &str, receipt_digest: &str, ) -> Result<bool, TransactionStoreError>

Atomically consume an approved receipt and transition Queued to Running.

Source

pub fn cleanup_stale_queued(&self) -> Result<u64, TransactionStoreError>

Cancel all Queued transactions whose created_at timestamp is older than the 15-minute TTL window. Returns the number of rows affected.

State-machine safety: the WHERE clause pins status = Queued before applying Queued → Canceled, which is the only legal transition reachable from Queued other than Running. A row that has progressed to Running (or any terminal state) in between the TTL match and our UPDATE is skipped because the predicate no longer matches it. This makes the bulk SQL semantically equivalent to fetching each candidate, building a JobStateMachine, and calling cancel() on it — but in a single statement so we don’t race ourselves when many rows expire at once. The cleanup_stale_queued_does_not_clobber_running_rows regression test in tests/coverage_gaps.rs pins this guarantee.

Source

pub fn cancel_queued( &self, transaction_id: &str, ) -> Result<bool, TransactionStoreError>

Cancel one still-Queued transaction (Queued → Canceled). Returns true iff a queued row was transitioned.

Option A semantics: the status = ?3 (Queued) guard means a Running transaction — one whose privileged action is already executing — is never cancelled, so we never leave a half-applied root mutation behind a Canceled record. Missing or already-terminal transactions return false.

Source

pub fn list_transactions( &self, limit: u32, status_filter: Option<&str>, action_filter: Option<&str>, since_hours: Option<u32>, ) -> Result<Vec<TransactionRecord>, TransactionStoreError>

List transactions with optional filters, ordered by newest first.

  • limit: max number of rows (capped at 100)
  • status_filter: if set, only return rows matching this status (must be a valid JobState variant: "succeeded", "failed", "queued", "running", "canceled", "rolled_back", "needs_reboot")
  • action_filter: if set, only return rows with this exact action name
  • since_hours: if set, only return rows created within the last N hours
Source

pub fn list_history( &self, limit: u32, status_filter: Option<&str>, action_filter: Option<&str>, since_hours: Option<u32>, ) -> Result<Vec<JobHistoryEntry>, TransactionStoreError>

Structured history for programmatic clients (the MCP sysknife_history tool). Unlike list_transactions it selects created_at and returns JobHistoryEntry so risk_level and created_at reach the caller typed, without text re-parsing.

Source

pub fn fetch_chain_rows(&self) -> Result<Vec<ChainRow>, TransactionStoreError>

Return all rows in seq order with the chain fields needed for verify.

Source

pub fn fetch_event_rows(&self) -> Result<Vec<EventRow>, TransactionStoreError>

Return every approval event in seq order.

Source

pub fn verify_audit_chain( &self, key: &AuditKey, ) -> Result<VerifyOutcome, TransactionStoreError>

Walk the audit chain with key and report integrity status.

Source

pub fn verify_event_chain( &self, key: &AuditKey, ) -> Result<VerifyOutcome, TransactionStoreError>

Walk the approval-event chain with key.

Source

pub fn verify_event_binding( &self, ) -> Result<BindingOutcome, TransactionStoreError>

Check that every event tip committed by a transaction row is still present in the event chain. See audit_chain::verify_event_binding.

Source

pub fn verify_audit_chain_with_pubkey( &self, verifying_key_hex: &str, ) -> Result<VerifyOutcome, TransactionStoreError>

Verify the chain with only the hex-encoded Ed25519 public key. The auditor path: proves the chain without the private key and cannot forge.

Source

pub fn fetch_chain_row( &self, transaction_id: &str, ) -> Result<Option<ChainRow>, TransactionStoreError>

Fetch a single row’s chain metadata by transaction_id. Used by the audit-log forwarder to construct an AuditEvent after insert.

Trait Implementations§

Source§

impl Clone for TransactionStore

Source§

fn clone(&self) -> TransactionStore

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for TransactionStore

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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