Skip to main content

Host

Struct Host 

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

Registers in-process, stdio, and HTTP providers behind one handle and fans queries out across them.

Implementations§

Source§

impl Host

Source

pub fn new() -> Self

A host with no providers and the default per-provider timeout.

Source

pub fn with_timeout(per_provider_timeout: Duration) -> Self

A host with a custom per-provider timeout.

Source

pub fn register(&mut self, provider: Box<dyn ContextProvider>)

Register an in-process provider (a built-in, e.g. the code graph).

Source

pub async fn add_stdio( &mut self, id: impl Into<String>, program: &str, args: &[String], ) -> Result<(), HostError>

Spawn and register a child-process provider over stdio, completing the handshake (SPEC.md §3).

Source

pub async fn add_http( &mut self, id: impl Into<String>, url: impl Into<String>, credential: Option<Credential>, ) -> Result<(), HostError>

Connect and register a remote HTTP provider, completing the handshake.

credential is an optional bearer Credential attached to every request; pass None for an unauthenticated provider. A plaintext (http://) transport to a non-loopback provider is refused before any bytes leave the host (HostError::InsecureTransport, C7), and the credential is never logged (C8).

Record legacy boolean consent for a provider, unlocking an egress provider that declares no scopes for querying (§3.5).

Source

pub fn record_receipt(&mut self, receipt: ConsentReceipt)

Append a scope-level ConsentReceipt to the audit ledger, authorizing one egress scope for one provider (docs/context-reuse.md §3). A provider that declares off-machine egress scopes stays gated until every such scope has a receipt.

Source

pub fn consent(&self) -> &ConsentStore

The consent store (read-only), e.g. to persist decisions.

Source

pub fn trust_key(&mut self, provider_id: impl Into<String>, key: TrustedKey)

Trust key for provider_id’s provenance attestations (ADR 0016).

The operator is the trust root: there is no discovery and no trust-on-first-use, so a key is here because a person put it here, from the same material as the provider’s own configuration. A host with a UI shows TrustedKey::fingerprint beside the consent prompt, so “I consent to this provider” and “I trust this key” are one decision.

A host that calls this for nobody verifies nothing and loses nothing: every signed frame reads as NoTrustedKey and is still served (SPEC.md F9).

Source

pub fn trust(&self) -> &TrustStore

The trust store (read-only), e.g. to persist it beside the consent ledger or to render what an operator has trusted.

Source

pub fn set_trust_store(&mut self, trust: TrustStore)

Replace the whole trust store — for a host restoring one it persisted.

Source

pub fn provider_ids(&self) -> Vec<&str>

The ids of every registered provider, in registration order.

Source

pub fn provider(&self, id: &str) -> Option<&dyn ContextProvider>

Borrow a registered provider by id, e.g. to read its cached capabilities.

Source

pub fn len(&self) -> usize

How many providers are registered.

Source

pub fn is_empty(&self) -> bool

Source

pub async fn verify_frames(&self, held: &[FrameId]) -> VerifyOutcome

Revalidate frames this host already holds, so unchanged context can be reused without re-querying it (docs/context-reuse.md §4).

Identities are grouped by provider and each capable provider is asked once. The rule is default-deny: a frame is retained only on an explicit Verdict::Valid, and every other outcome — a negative verdict, a missing digest, a provider that doesn’t support verify, an unregistered provider, a failed request — drops the frame with a reason (requirement V2). Reasons that warrant a re-query tell the host which dropped frames are worth fetching again.

This method holds no state: it neither caches frames nor tracks turn boundaries. When to re-verify is the host’s policy (§4 gives informative guidance); the protocol’s job is only to answer the question when asked. No frame body travels in either direction.

Source

pub async fn query_provider( &self, id: &str, query: &ContextQuery, ) -> Result<ContextQueryResult, HostError>

Query a single provider by id, honoring the consent gate and the per-provider timeout. Querying an unconsented egress provider is HostError::ConsentRequired (legacy boolean) or HostError::ConsentScopeRequired (an off-machine scope with no receipt, §3), and the payload is never transmitted (§3.5).

Source

pub async fn query_provider_attested( &self, id: &str, query: &ContextQuery, ) -> Result<(ContextQueryResult, Vec<FrameAttestationOutcome>), HostError>

query_provider, plus what the host found when it checked the provider’s attestations against its TrustStore (SPEC.md §6.5, ADR 0016).

Returns the result exactly as the provider served it and one FrameAttestationOutcome per frame in it — including the frames no attestation covered. No frame is ever withheld for failing the check (SPEC.md F9): the outcomes are a fact recorded beside the evidence, not a filter over it.

Source

pub async fn query_all(&self, query: &ContextQuery) -> FanOut

Fan a query out to every capability-matching provider concurrently, collecting a per-provider outcome. Each provider is consent-gated, timed out, and budget-audited independently — the crash-consistency contract means one provider’s failure never affects another (task deliverables 3 + 5).

Source

pub async fn query_all_budgeted( &self, template: &ContextQuery, global_budget: u32, ) -> FanOut

Fan a query out under a global token budget, splitting it into a per-provider max_tokens share before building each provider’s query (issue #15). Where query_all hands the same max_tokens to every provider — so N honest providers can each spend the whole budget and the honest total is N× the intended prompt budget — this gives each capability-matching provider a slice of global_budget, so the honest legs sum to <= global_budget.

template supplies every field of the query except max_tokens, which is overwritten per provider with its share from compose::budget_split — an equal split by default, documented there as swappable for a weighted one. Only capability-matching providers (the same filter query_all applies) count toward the split and receive a query. Each leg is still consent-gated, timed out, and budget-audited exactly as in query_all, so a provider that overspends its share is dropped with a report by the existing B2 audit — the split composes with per-leg honesty rather than replacing it.

query_all stays the un-budgeted legacy path.

Source

pub async fn shutdown(self) -> Vec<(String, Result<(), HostError>)>

Shut every provider down cleanly, consuming the host so its stdio children are reaped as they drop. Returns each provider’s shutdown result so a caller can log stragglers.

Trait Implementations§

Source§

impl Default for Host

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl !RefUnwindSafe for Host

§

impl !UnwindSafe for Host

§

impl Freeze for Host

§

impl Send for Host

§

impl Sync for Host

§

impl Unpin for Host

§

impl UnsafeUnpin for Host

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> 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> 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 = !

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

fn try_from(value: U) -> Result<T, !>

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