Skip to main content

ProviderSession

Trait ProviderSession 

Source
pub trait ProviderSession: Send + Sync {
    // Required methods
    fn attestation(&self) -> &CapabilityAttestation;
    fn execute<'life0, 'async_trait>(
        &'life0 self,
        call: BoundActionCall,
        cancel: Option<CancellationToken>,
    ) -> Pin<Box<dyn Future<Output = Result<ActionOutcome, ProviderError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn observe<'life0, 'async_trait>(
        &'life0 self,
        req: ObserveRequest,
        cancel: Option<CancellationToken>,
    ) -> Pin<Box<dyn Future<Output = Result<Observation, ProviderError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn ui_snapshot<'life0, 'life1, 'async_trait>(
        &'life0 self,
        observation_id: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<UiSnapshotOutcome, ProviderError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn reconcile<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        call_id: &'life1 str,
        issuing: &'life2 EventCursor,
    ) -> Pin<Box<dyn Future<Output = Result<ReconcileResult, ProviderError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;
    fn fetch_evidence<'life0, 'life1, 'async_trait>(
        &'life0 self,
        asset: &'life1 AssetRef,
    ) -> Pin<Box<dyn Future<Output = Result<EvidenceStream, ProviderError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn record_verdict<'life0, 'async_trait>(
        &'life0 self,
        verdict: VerdictWrite,
    ) -> Pin<Box<dyn Future<Output = Result<(), ProviderError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn current_cursor<'life0, 'async_trait>(
        &'life0 self,
    ) -> Pin<Box<dyn Future<Output = Result<EventCursor, ProviderError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn health<'life0, 'async_trait>(
        &'life0 self,
    ) -> Pin<Box<dyn Future<Output = Result<SessionHealth, ProviderError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn end<'life0, 'async_trait>(
        &'life0 self,
        outcome: SessionOutcome,
        reason: Option<String>,
    ) -> Pin<Box<dyn Future<Output = Result<(), ProviderError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
}
Expand description

An open provider session (spine §4.2 ProviderSession). One session owns one underlying client connection exclusively. In the broken state every method except health (which reports { ok: false }) fails with a transport_lost-class error (04 §2.1).

Required Methods§

Source

fn attestation(&self) -> &CapabilityAttestation

The attestation result (already verified inside open_session), exposed for Evidence and reports.

Source

fn execute<'life0, 'async_trait>( &'life0 self, call: BoundActionCall, cancel: Option<CancellationToken>, ) -> Pin<Box<dyn Future<Output = Result<ActionOutcome, ProviderError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Executes an action (devicerail: device.execute). The four-way terminal outcome is returned unfolded and untranslated — failed, cancelled and timedOut are Ok values, not errors. Err means “no terminal could be obtained” (transport rupture, envelope timeout, abort undeliverable); the runner records the attempt as hanging and goes through reconcile (04 §3).

Preconditions the conformance suite enforces: call.call_id is used verbatim as the substrate action id; a repeated call_id is rejected (a retry is a new call_id + new WAL intent); an unattested action_name is rejected with capability_drift before any wire request.

Source

fn observe<'life0, 'async_trait>( &'life0 self, req: ObserveRequest, cancel: Option<CancellationToken>, ) -> Pin<Box<dyn Future<Output = Result<Observation, ProviderError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Takes an explicit observation (devicerail: device.observe). Omissions are data, not errors: a wanted-but-missing part comes back as a typed omission reason on the Observation (04 §4.1).

Source

fn ui_snapshot<'life0, 'life1, 'async_trait>( &'life0 self, observation_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<UiSnapshotOutcome, ProviderError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Dereferences an observation’s normalized UI tree (devicerail: ui.snapshot.get { observationId }; feature observation.uiSnapshot.v1). Protocol hard limit: readable only while the issuing session is active → the runner localizes immediately during observing (04 §4.2).

Source

fn reconcile<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, call_id: &'life1 str, issuing: &'life2 EventCursor, ) -> Pin<Box<dyn Future<Output = Result<ReconcileResult, ProviderError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Effect reconciliation of a pending intent (spine §6.7-B, 04 §5). issuing is the credential of the session generation that dispatched the intent (2026-07-18 incorporation: explicit parameter — pendingIntent issuing state, falling back to the checkpoint binding cursor). The implementation must consult the ISSUING session’s log: when issuing.sessionId is not this session and the old log is unreachable, the honest answer is logUnavailable — never a scan of the current session’s log (a reachable-but-wrong log can fabricate neverDispatched).

Source

fn fetch_evidence<'life0, 'life1, 'async_trait>( &'life0 self, asset: &'life1 AssetRef, ) -> Pin<Box<dyn Future<Output = Result<EvidenceStream, ProviderError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Fetches evidence bytes by AssetRef.uri for the local content-addressed store. When asset.sha256 is present the provider must verify while reading and fail on mismatch — evidence integrity is non-negotiable (04 §4.3).

Source

fn record_verdict<'life0, 'async_trait>( &'life0 self, verdict: VerdictWrite, ) -> Pin<Box<dyn Future<Output = Result<(), ProviderError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Writes back a Pointlock-computed verdict (devicerail: verdict.record; feature verdict.record.v1). Wire hard caps (VERDICT_SUMMARY_MAX_CHARS, VERDICT_EVIDENCE_MAX_ENTRIES): the provider fails closed on oversize input with a bind_arguments_invalid-class error (04 §5).

Source

fn current_cursor<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<EventCursor, ProviderError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

The checkpoint event-cursor watermark: the highest sequence the provider has delivered to the runner (ack-after-persist), not the highest the daemon has produced (04 §5).

Source

fn health<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<SessionHealth, ProviderError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Lightweight, side-effect-free health probe. Must not fail on a broken session — it reports { ok: false } instead (04 §2.1).

Source

fn end<'life0, 'async_trait>( &'life0 self, outcome: SessionOutcome, reason: Option<String>, ) -> Pin<Box<dyn Future<Output = Result<(), ProviderError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Ends the session (devicerail: session.end). Idempotent: calling it on an already ended/broken session is a no-op; best-effort — it must not fail and block the runner’s teardown when the transport is already gone (04 §2.1).

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§