pub struct ChioKernel { /* private fields */ }Expand description
The Chio Runtime Kernel.
This is the central component of the Chio protocol. It validates capabilities, runs guards, dispatches tool calls, and signs receipts.
The kernel is designed to be the sole trusted mediator. It never exposes its signing key, address, or internal state to the agent.
Implementations§
Source§impl ChioKernel
impl ChioKernel
pub fn admit_governed_active_response( &self, request: &GovernedActiveResponseRequest, ) -> Result<GovernedActiveResponseAdmission, KernelError>
pub fn commit_governed_active_response_dispatch( &self, admission: &mut GovernedActiveResponseAdmission, ) -> Result<GovernedActiveResponseDispatchCommit, KernelError>
pub fn cancel_governed_active_response( &self, admission: &GovernedActiveResponseAdmission, ) -> Result<(), KernelError>
Source§impl ChioKernel
impl ChioKernel
Sourcepub fn verdict_for_provider_invocation(
&self,
invocation: &ToolInvocation,
capability: CapabilityToken,
agent_id: AgentId,
server_id: ServerId,
) -> Result<VerdictResult, KernelError>
pub fn verdict_for_provider_invocation( &self, invocation: &ToolInvocation, capability: CapabilityToken, agent_id: AgentId, server_id: ServerId, ) -> Result<VerdictResult, KernelError>
Compute a fabric VerdictResult for a provider-native tool
invocation by routing through the existing MCP verdict path.
The shim builds a ToolCallRequest from the supplied invocation
plus the surrounding capability context, calls
crate::ChioKernel::evaluate_tool_call_blocking, and lowers the
kernel response into a fabric verdict via
verdict_result_from_response.
The kernel-side fabric integration point. Adapters call this method with an invocation already lifted from the upstream wire format and a capability token resolved from their authentication path.
Source§impl ChioKernel
impl ChioKernel
pub fn reconcile_durable_admission_receipt_projections( &self, ) -> Result<usize, KernelError>
pub fn reconcile_durable_admission_startup(&self) -> Result<usize, KernelError>
pub fn reconcile_recoverable_admissions(&self) -> Result<usize, KernelError>
Source§impl ChioKernel
impl ChioKernel
Sourcepub fn with_hybrid_signing_backend(
&mut self,
hybrid: &HybridSigningConfig,
self_quote_bytes: &[u8],
verifier: &dyn KernelSelfQuoteVerifier,
) -> Result<Box<dyn SigningBackend>, KernelBootError>
pub fn with_hybrid_signing_backend( &mut self, hybrid: &HybridSigningConfig, self_quote_bytes: &[u8], verifier: &dyn KernelSelfQuoteVerifier, ) -> Result<Box<dyn SigningBackend>, KernelBootError>
Construct the hybrid signing backend the kernel would use under
hybrid’s configured floor and PQ key material after the kernel
self-quote gate has run.
Threads the kernel’s classical Ed25519 keypair into a
chio_core::crypto::Ed25519Backend under
KernelCryptoFloor::AllowClassical, or composes it with an
[chio_core::crypto::MlDsa65Backend] derived from hybrid.pq_signing_seed
into a [chio_core::crypto::HybridBackend] under
KernelCryptoFloor::AllowHybrid or KernelCryptoFloor::PqRequired,
but only after crate::boot::load_kernel_signing_backend_after_self_quote
accepts self_quote_bytes.
Receipt body construction continues to flow through the existing
inline path (build_and_sign_receipt); callers that opt in to
hybrid signing pass the returned backend through
crate::sign_receipt_body_with_backend (along with the canonical
content preimage the body’s content_hash was derived from) before
persistence, so the hybrid path recomputes content_hash inside the
trust boundary and is WYSIWYS fail-closed just like the inline
classical path.
§Errors
Returns crate::boot::KernelBootError::SelfQuoteRejected when the
self-quote verifier rejects a non-classical floor, or
crate::boot::KernelBootError::SigningBackend when the configured
floor needs a PQ key but hybrid.pq_signing_seed is None. Mirrors
the policy-level check in chio_policy::CryptoFloor::validate_with_pq_key
so the boot path catches the misconfiguration even when the policy crate
is bypassed.
Source§impl ChioKernel
impl ChioKernel
Sourcepub fn try_new(config: KernelConfig) -> Result<Self, KernelBuildError>
pub fn try_new(config: KernelConfig) -> Result<Self, KernelBuildError>
Fallible constructor that runs fail-closed validation of the hot-path
deadline config before building. This is the documented entrypoint for
hosts that set [deadlines]. new stays infallible for existing
callers; the append bound is additionally floor-clamped at read time so
even a host that bypasses this path can never run an unbounded append.
Sourcepub fn flush_receipt_writes_with_timeout(
&self,
timeout: Duration,
) -> Result<Option<ReceiptFlushReport>, KernelError>
pub fn flush_receipt_writes_with_timeout( &self, timeout: Duration, ) -> Result<Option<ReceiptFlushReport>, KernelError>
Flush any queued receipt writes to durable storage, bounded by timeout.
A shutdown drain calls this to prove the commit-actor queue is empty
before the process exits. Ok(None) means no receipt store is
configured; a configured store’s flush error is surfaced rather than
swallowed, so a drain can exit non-zero when a receipt might not be
durable.
pub fn new(config: KernelConfig) -> Self
Sourcepub fn spawn_receipt_writer_watchdog(self: &Arc<Self>)
pub fn spawn_receipt_writer_watchdog(self: &Arc<Self>)
Start the receipt-writer liveness watchdog. Opt-in: the hosting edge calls this in an async context. It polls the store’s liveness on the configured cadence and publishes the verdict the pre-dispatch gate reads.
Sourcepub fn set_revocation_view(&mut self, view: Arc<RevocationView>)
pub fn set_revocation_view(&mut self, view: Arc<RevocationView>)
Install (or replace) the recursive-delegation oracle handle.
Default deployments leave this None and rely on the compatibility
per-row RevocationStore lookup. Installing a
chio_kernel_core::RevocationView here causes the verifier to
consult it on every delegated dispatch.
The handle is Arc-shared so federation gossip can install
monotone snapshot updates without holding a kernel mutex.
Sourcepub fn revocation_view(&self) -> Option<&Arc<RevocationView>>
pub fn revocation_view(&self) -> Option<&Arc<RevocationView>>
Borrow the currently-installed revocation view, if any.
Sourcepub async fn sign_receipt_via_channel(
&self,
body: ChioReceiptBody,
canonical_content: Vec<u8>,
) -> Result<ChioReceipt, KernelError>
pub async fn sign_receipt_via_channel( &self, body: ChioReceiptBody, canonical_content: Vec<u8>, ) -> Result<ChioReceipt, KernelError>
Sign a ChioReceiptBody off the kernel critical path via the
mpsc-backed signing task.
Producers .await on bounded backpressure rather than on a
receipt-log mutex. Returns
Err(KernelError::ReceiptSigningFailed) if the signing step
itself rejected the body (e.g. the body’s kernel_key does not
match the kernel’s signing public key) and
Err(KernelError::Internal) if the signing task is no longer
running.
This method is async because it .awaits on the channel send
(backpressure) and on the oneshot reply. The caller must run
inside a tokio runtime; every kernel-internal call site already
does (the ToolEvaluator trait methods are async, and so is
the public evaluate_tool_call entrypoint).
canonical_content is the exact byte preimage body.content_hash was
derived from. The signing task recomputes sha256_hex(canonical_content)
inside the trust boundary and refuses to sign on mismatch (WYSIWYS,
), so this channel path is as fail-closed as the inline
build_and_sign_receipt path.
Sourcepub async fn shutdown(&self)
pub async fn shutdown(&self)
Drain the in-flight signing-task queue and join the task. After this
call, every signing request that successfully .send().await-ed before
shutdown has been signed and replied to; new sends surface
KernelError::Internal.
Idempotent: safe to call more than once. Safe to call on a kernel whose signing task was never spawned (no signing happened); in that case shutdown is a no-op.
Note: shutdown does NOT mark the kernel as terminally stopped
for other paths (capability validation, guard pipeline, store
lookups). Operators that want a hard stop should call
Self::emergency_stop in addition.
pub fn set_receipt_store( &mut self, receipt_store: Box<dyn ReceiptStore>, ) -> Result<(), KernelError>
pub fn configure_durable_admission( &mut self, mode: DurableAdmissionMode, unsafe_development: bool, ) -> Result<(), AdmissionOperationError>
pub fn durable_admission_mode(&self) -> DurableAdmissionMode
pub fn set_durable_admission_store( &mut self, store: Arc<dyn QualifiedAdmissionProjectionStore>, outcome_store: Arc<dyn QualifiedToolOutcomeStore>, fence: StoreMutationFence, ) -> Result<(), AdmissionOperationError>
Sourcepub fn enable_unsafe_ephemeral_financial_dispatch_for_development(&mut self)
pub fn enable_unsafe_ephemeral_financial_dispatch_for_development(&mut self)
Enable legacy financial dispatch without durable admission recovery.
This is an unsafe development compatibility switch. Ambiguous connector outcomes can retain budget or rail holds permanently because no recovery operation survives restart. Production deployments should install a qualified durable admission store instead.
pub fn set_receipt_store_handle( &mut self, receipt_store: Arc<dyn ReceiptStore>, ) -> Result<(), KernelError>
pub fn try_set_receipt_store_handle( &mut self, receipt_store: Arc<dyn ReceiptStore>, ) -> Result<(), KernelError>
pub fn set_payment_adapter(&mut self, payment_adapter: Box<dyn PaymentAdapter>)
pub fn set_price_oracle(&mut self, price_oracle: Box<dyn PriceOracle>)
pub fn set_attestation_trust_policy( &mut self, attestation_trust_policy: AttestationTrustPolicy, )
Sourcepub fn opt_in_ephemeral_revocation_store(&mut self)
pub fn opt_in_ephemeral_revocation_store(&mut self)
Accept the default in-memory revocation store instead of requiring a durable one. A locally-run kernel with no durable or remote revocation backend keeps its revocation set in memory, so the durability gate would otherwise deny every dispatch. Opting in here relaxes the gate only while the store is genuinely ephemeral: installing a durable store (or a revocation view) satisfies the gate on its own regardless of this flag. Intended for local, interactive runtimes; deployments that must survive restart should wire a durable store instead of calling this.
pub fn set_revocation_store( &mut self, revocation_store: Box<dyn RevocationStore>, )
pub fn set_revocation_store_handle( &mut self, revocation_store: Arc<dyn RevocationStore>, )
pub fn set_budget_store(&mut self, budget_store: Box<dyn BudgetStore>)
pub fn set_budget_store_handle(&mut self, budget_store: Arc<dyn BudgetStore>)
pub fn set_post_invocation_pipeline(&mut self, pipeline: PostInvocationPipeline)
pub fn add_post_invocation_hook(&mut self, hook: Box<dyn PostInvocationHook>)
Sourcepub fn set_settlement_observer_runtime(
&mut self,
hook: Arc<dyn SettlementHook>,
outcome_store: Arc<dyn SettlementOutcomeStore>,
retry_policy: RetryPolicy,
) -> Result<(), KernelError>
pub fn set_settlement_observer_runtime( &mut self, hook: Arc<dyn SettlementHook>, outcome_store: Arc<dyn SettlementOutcomeStore>, retry_policy: RetryPolicy, ) -> Result<(), KernelError>
Install a settlement hook with its durable outcome store and retry policy.
Before dispatch, the kernel requires a receipt store that can atomically seed pending settlement work within the configured receipt-append deadline. The store and runtime may be configured in either order; attaching an incompatible store fails without replacing the active one.
The returned error must not be discarded: swallowing it leaves the kernel
dispatching charges with settlement uninstalled. Embedders porting from
set_settlement_observer should read
docs/migrations/kernel-embedder-surface.md, which lists the receipt-store
capabilities this requires and the configuration failure modes.
Sourcepub fn settlement_observer(&self) -> Option<Arc<dyn SettlementHook>>
pub fn settlement_observer(&self) -> Option<Arc<dyn SettlementHook>>
Return the active settlement hook without exposing routing internals.
Sourcepub fn run_settlement_observer(
&self,
receipt: &ChioReceipt,
idempotency_key: &SettlementIdempotencyKey,
) -> SettlementObserverStatus
pub fn run_settlement_observer( &self, receipt: &ChioReceipt, idempotency_key: &SettlementIdempotencyKey, ) -> SettlementObserverStatus
Invoke the registered settlement hook against a freshly signed receipt. The receipt is observer-only relative to this call: callers MUST pass a receipt that has already been signed and stored, and the returned status NEVER feeds back into the dispatch path.
Sourcepub fn set_memory_provenance_store(
&mut self,
store: Arc<dyn MemoryProvenanceStore>,
)
pub fn set_memory_provenance_store( &mut self, store: Arc<dyn MemoryProvenanceStore>, )
Install a memory-provenance chain.
Once installed, every governed MemoryWrite-shaped tool call
appends an entry to the chain after the allow receipt is
signed. A chain-store failure on that path is fatal: the call
surfaces KernelError::Internal(...) so operators can detect
and repair the drift rather than silently shipping a write
without provenance evidence.
Every MemoryRead-shaped tool call looks the entry up by
(store, key) and attaches the result to the receipt as
memory_provenance evidence metadata. Reads with no chain
entry or with a tampered chain surface as
crate::memory_provenance::ProvenanceVerification::Unverified
so the receipt unambiguously records the gap.
Sourcepub fn memory_provenance_store(&self) -> Option<Arc<dyn MemoryProvenanceStore>>
pub fn memory_provenance_store(&self) -> Option<Arc<dyn MemoryProvenanceStore>>
Return a clone of the active memory-provenance store handle,
or None when no provenance chain has been installed.
Useful for integration tests that want to assert on the chain
state directly after driving evaluate_tool_call.
Sourcepub fn with_federation_peers(self, peers: Vec<FederationPeer>) -> Self
pub fn with_federation_peers(self, peers: Vec<FederationPeer>) -> Self
Install a set of chio_federation::trust_establishment::FederationPeers
this kernel trusts for bilateral co-signing. Overwrites any
previously declared set. Callers typically obtain these peers
from chio_federation::trust_establishment::KernelTrustExchange::accept_envelope
after a successful mTLS handshake.
Builder-style so deployments can chain .with_federation_peers(...)
onto ChioKernel::new(config).
Sourcepub fn with_capability_trust_roots(
self,
roots: Vec<(PublicKey, ScopeHash)>,
) -> Self
pub fn with_capability_trust_roots( self, roots: Vec<(PublicKey, ScopeHash)>, ) -> Self
Builder-style so deployments can chain
.with_capability_trust_roots(...) onto ChioKernel::new(config).
Sourcepub fn set_capability_trust_root(
&self,
issuer: PublicKey,
root: ScopeHash,
) -> Option<ScopeHash>
pub fn set_capability_trust_root( &self, issuer: PublicKey, root: ScopeHash, ) -> Option<ScopeHash>
Install or update a single capability trust-root entry without requiring builder-style construction. Returns the previous root hash for that issuer, if any.
Sourcepub fn capability_trust_roots_snapshot(&self) -> HashMap<String, ScopeHash>
pub fn capability_trust_roots_snapshot(&self) -> HashMap<String, ScopeHash>
Snapshot the currently registered capability trust-root registry.
Hot-path callers should prefer the resolver returned by
capability_trust_root_resolver_snapshot.
Sourcepub fn set_federation_cosigner(
&mut self,
cosigner: Arc<dyn BilateralCoSigningProtocol>,
)
pub fn set_federation_cosigner( &mut self, cosigner: Arc<dyn BilateralCoSigningProtocol>, )
Install the bilateral cosigner responsible for
contacting a peer kernel to obtain a co-signature. Production
deployments plug in an mTLS-backed RPC client; tests can use
chio_federation::bilateral::InProcessCoSigner.
Sourcepub fn set_federation_artifact_store(
&mut self,
store: Arc<dyn FederationArtifactStore>,
)
pub fn set_federation_artifact_store( &mut self, store: Arc<dyn FederationArtifactStore>, )
Install a durable crate::federation_artifact_store::FederationArtifactStore
for bilateral co-sign artifacts.
When set, Self::apply_federation_cosign writes each
DualSignedReceipt / DsseEnvelope through to the store BEFORE inserting
it into the bounded in-memory caches, and Self::dual_signed_receipt /
Self::federation_dsse_envelope fall back to the store on a cache miss.
This closes the evidence-loss window where a federated deployment
producing more than federation_cache_capacity receipts would drop
evicted co-sign artifacts while the durable receipt store keeps only the
base receipt. Without a store installed, evicted co-sign artifacts are
lossy by policy (the bounded caches drop-oldest at capacity).
A deployment requiring durable bilateral evidence installs a
database-backed impl; the bundled
crate::federation_artifact_store::InMemoryFederationArtifactStore is a
capped, idle-swept reference impl and test double.
Sourcepub fn set_federation_local_kernel_id(&self, kernel_id: impl Into<String>)
pub fn set_federation_local_kernel_id(&self, kernel_id: impl Into<String>)
Advertise this kernel’s stable identifier as seen by remote federation peers. When unset, the hex encoding of the signing public key is used. Setting this is recommended in production so receipts reference DNS names rather than raw keys.
Sourcepub fn federation_peer(
&self,
remote_kernel_id: &str,
now: u64,
) -> Option<FederationPeer>
pub fn federation_peer( &self, remote_kernel_id: &str, now: u64, ) -> Option<FederationPeer>
Resolve the active federation peer for
remote_kernel_id, refusing stale pins fail-closed.
Sourcepub fn federation_peers_snapshot(&self) -> Vec<FederationPeer>
pub fn federation_peers_snapshot(&self) -> Vec<FederationPeer>
Snapshot the currently-pinned federation peer set.
Sourcepub fn dual_signed_receipt(&self, receipt_id: &str) -> Option<DualSignedReceipt>
pub fn dual_signed_receipt(&self, receipt_id: &str) -> Option<DualSignedReceipt>
Look up a dual-signed receipt by the underlying
chio_core::receipt::body::ChioReceipt id. Returns None when the
receipt did not cross a federation boundary or when the
co-signing hook has not yet produced a dual-signed artifact
for it.
pub fn federation_dsse_envelope(&self, receipt_id: &str) -> Option<DsseEnvelope>
Sourcepub fn federation_local_kernel_id(&self) -> String
pub fn federation_local_kernel_id(&self) -> String
Local kernel identifier used in bilateral co-signing. Falls back to the hex encoding of the signing public key.
Sourcepub fn emergency_stop(&self, reason: &str) -> Result<(), KernelError>
pub fn emergency_stop(&self, reason: &str) -> Result<(), KernelError>
Engage the emergency kill switch.
After this call, every evaluate_tool_call* path returns a signed
deny receipt with reason "kernel emergency stop active" before
touching capability validation or the guard pipeline. The kernel
remains running so orchestrators and health probes see a live
process; it is inert.
The active capability set is NOT purged from the revocation store:
the current RevocationStore trait has no bulk revoke API and
capability expiration plus the kill-switch flag together
cover this surface. When a future revision adds revoke_all,
this method should call it; until then, capability revocation is
delegated to natural expiration.
Sourcepub fn emergency_resume(&self) -> Result<(), KernelError>
pub fn emergency_resume(&self) -> Result<(), KernelError>
Disengage the emergency kill switch and resume normal operation.
Subsequent evaluate_tool_call* calls follow the full validation
pipeline again. Capabilities that naturally expired while the
kernel was stopped remain expired; the kill switch does not
retroactively grant anything.
Sourcepub fn is_emergency_stopped(&self) -> bool
pub fn is_emergency_stopped(&self) -> bool
Return true when the emergency kill switch is engaged.
Sourcepub fn is_rss_shedding(&self) -> bool
pub fn is_rss_shedding(&self) -> bool
Return true when the RSS soft-ceiling sampler has flagged that process
RSS crossed memory_budget.rss_soft_limit_bytes. A single relaxed atomic
load on the admission fast path.
Sourcepub fn bounded_structure_gauges(&self) -> Vec<(&'static str, usize)>
pub fn bounded_structure_gauges(&self) -> Vec<(&'static str, usize)>
Enumerate each long-lived bounded structure’s telemetry label and its current live entry count. This is the registry the size-metric convention and the soak harness read; adding a new long-lived collection without a gauge here fails the registry test.
Sourcepub fn emergency_stopped_since(&self) -> Option<u64>
pub fn emergency_stopped_since(&self) -> Option<u64>
Return the unix timestamp (seconds) at which the kill switch was
engaged, or None when the kernel is currently running normally.
Sourcepub fn emergency_stop_reason(&self) -> Option<String>
pub fn emergency_stop_reason(&self) -> Option<String>
Return the operator-supplied reason for the current emergency stop,
or None when the kernel is running normally.
Sourcepub fn set_dpop_store(
&mut self,
nonce_store: DpopNonceStore,
config: DpopConfig,
)
pub fn set_dpop_store( &mut self, nonce_store: DpopNonceStore, config: DpopConfig, )
Install a DPoP nonce replay store and verification config.
Once installed, any invocation whose matched grant has dpop_required == Some(true)
must carry a valid DpopProof on the ToolCallRequest. Requests that lack a proof
or whose proof fails verification are denied fail-closed.
Sourcepub fn set_execution_nonce_store(
&mut self,
config: ExecutionNonceConfig,
store: Box<dyn ExecutionNonceStore>,
)
pub fn set_execution_nonce_store( &mut self, config: ExecutionNonceConfig, store: Box<dyn ExecutionNonceStore>, )
Install an execution-nonce config and replay store.
Once installed, every Verdict::Allow carries a short-lived signed
nonce on ToolCallResponse::execution_nonce. Tool servers re-present
that nonce via ToolCallRequest::execution_nonce and the kernel’s
verify_presented_execution_nonce helper (or directly via the
free-standing verify_execution_nonce function) before executing.
Set config.require_nonce = true to put the kernel into strict mode:
any call that reaches require_presented_execution_nonce without a
nonce is denied. When require_nonce == false the feature is opt-in
per tool server and non-nonce callers continue to work (backward
compatibility).
Sourcepub fn execution_nonce_required(&self) -> bool
pub fn execution_nonce_required(&self) -> bool
Returns true when execution-nonce strict mode is active.
Strict mode requires every presented tool call to carry a fresh,
valid, single-use nonce. When false the kernel is either not
minting nonces at all (no config installed) or is in opt-in mode
where tool servers can verify presented nonces but non-nonce calls
are not outright rejected.
Sourcepub fn verify_presented_execution_nonce(
&self,
presented: &SignedExecutionNonce,
expected: &NonceBinding,
) -> Result<(), ExecutionNonceError>
pub fn verify_presented_execution_nonce( &self, presented: &SignedExecutionNonce, expected: &NonceBinding, ) -> Result<(), ExecutionNonceError>
Verify a caller-presented execution nonce against the expected binding, consuming it in the replay store on success.
Returns Ok(()) when the nonce is fresh, correctly bound, signed
by this kernel, and has not been consumed. Returns an error
wrapping ExecutionNonceError on any failure (expired, tampered,
replayed, binding mismatch, store unreachable).
Sourcepub fn require_presented_execution_nonce(
&self,
request: &ToolCallRequest,
cap: &CapabilityToken,
) -> Result<(), KernelError>
pub fn require_presented_execution_nonce( &self, request: &ToolCallRequest, cap: &CapabilityToken, ) -> Result<(), KernelError>
Execution-nonce dispatch gate.
Denies fail-closed when strict mode is configured and the request lacks a nonce. When strict mode is disabled, a request with no nonce remains backward-compatible. Any presented nonce is still verified and consumed so opt-in callers cannot bypass binding, expiry, signature, or replay checks.
Returns Ok(()) when:
- no nonce is required and none was presented, OR
- a nonce is presented, signed by this kernel, correctly bound, non-expired, and has not been consumed.
Returns Err(KernelError::Internal(...)) fail-closed otherwise.
pub fn requires_web3_evidence(&self) -> bool
pub fn validate_web3_evidence_prerequisites(&self) -> Result<(), KernelError>
Sourcepub fn add_guard(&mut self, guard: Box<dyn Guard>)
pub fn add_guard(&mut self, guard: Box<dyn Guard>)
Register a policy guard. Guards are evaluated in registration order. If any guard denies, the request is denied.
Sourcepub fn set_runtime_admission_hook(
&mut self,
hook: Arc<dyn RuntimeAdmissionHook>,
)
pub fn set_runtime_admission_hook( &mut self, hook: Arc<dyn RuntimeAdmissionHook>, )
Install a product-specific runtime admission hook. The hook runs after core authorization checks and guards, but before tool dispatch.
pub fn set_threshold_approval_requirement_resolver( &mut self, resolver: Arc<dyn ThresholdApprovalRequirementResolver>, )
Sourcepub fn set_supplemental_quota_verifier(
&mut self,
verifier: Arc<dyn SupplementalQuotaVerifier>,
binding: SupplementalQuotaVerifierBinding,
) -> Result<(), SupplementalQuotaError>
pub fn set_supplemental_quota_verifier( &mut self, verifier: Arc<dyn SupplementalQuotaVerifier>, binding: SupplementalQuotaVerifierBinding, ) -> Result<(), SupplementalQuotaError>
Install the sole trusted parser and verifier for opaque supplemental authorization artifacts.
Sourcepub fn clear_runtime_admission_hook(&mut self)
pub fn clear_runtime_admission_hook(&mut self)
Remove the product-specific runtime admission hook.
Sourcepub fn register_tool_server(
&mut self,
connection: Box<dyn ToolServerConnection>,
)
pub fn register_tool_server( &mut self, connection: Box<dyn ToolServerConnection>, )
Register a tool server connection.
Sourcepub fn register_resource_provider(
&mut self,
provider: Box<dyn ResourceProvider>,
)
pub fn register_resource_provider( &mut self, provider: Box<dyn ResourceProvider>, )
Register a resource provider.
Sourcepub fn register_prompt_provider(&mut self, provider: Box<dyn PromptProvider>)
pub fn register_prompt_provider(&mut self, provider: Box<dyn PromptProvider>)
Register a prompt provider.
Source§impl ChioKernel
impl ChioKernel
Sourcepub async fn evaluate_tool_call(
&self,
request: &ToolCallRequest,
) -> Result<ToolCallResponse, KernelError>
pub async fn evaluate_tool_call( &self, request: &ToolCallRequest, ) -> Result<ToolCallResponse, KernelError>
Evaluate a tool call request.
This is the kernel’s main entry point. It performs the full validation pipeline:
- Verify capability signature against known CA public keys.
- Check time bounds (not expired, not-before satisfied).
- Check revocation status of the capability and its delegation chain.
- Verify the requested tool is within the capability’s scope.
- Check and decrement invocation budget.
- Run all registered guards.
- If all pass: forward to tool server, sign allow receipt.
- If any fail: sign deny receipt.
Every call – whether allowed or denied – produces exactly one signed receipt.
pub async fn evaluate_tool_call_with_metadata( &self, request: &ToolCallRequest, extra_metadata: Option<Value>, ) -> Result<ToolCallResponse, KernelError>
pub fn sign_planned_deny_response( &self, request: &ToolCallRequest, reason: &str, extra_metadata: Option<Value>, ) -> Result<ToolCallResponse, KernelError>
Sourcepub async fn evaluate_plan(
&self,
req: PlanEvaluationRequest,
) -> PlanEvaluationResponse
pub async fn evaluate_plan( &self, req: PlanEvaluationRequest, ) -> PlanEvaluationResponse
Plan-level evaluation.
Takes an ordered list of planned tool calls under a single capability token and evaluates every step INDEPENDENTLY against the pre-invocation portion of the evaluation pipeline: capability signature / time-bound / revocation / subject binding, the request-matching pass (scope + constraints + model constraint), and the registered guard pipeline. No tool-server dispatch, no budget mutation, no receipt emission, and no cross-step state propagation take place: this is a stateless pre-flight check.
Dependencies between planned steps are advisory metadata only in v1: the kernel does not topologically sort the graph, refuse on cycles, or short-circuit downstream steps when an earlier step denies. Callers are expected to make that decision themselves once they have the per-step verdict list.
Guards that require post-invocation output (response-shaping,
streaming sanitizers, etc.) are inherently skipped because no
tool output exists; every registered guard is
invoked against the synthesised pre-flight request, matching the
set of guards that run in evaluate_tool_call before dispatch.
Plan evaluation does not emit receipts. The kernel emits structured trace spans for the plan and every per-step verdict so operators can correlate plan evaluations with subsequent tool-call receipts.
Sourcepub fn evaluate_plan_blocking(
&self,
req: &PlanEvaluationRequest,
) -> PlanEvaluationResponse
pub fn evaluate_plan_blocking( &self, req: &PlanEvaluationRequest, ) -> PlanEvaluationResponse
Synchronous variant of Self::evaluate_plan for substrate
adapters that do not run on an async runtime.
Plan evaluation never touches the network, so the async method is a thin wrapper over this blocking implementation.
Source§impl ChioKernel
impl ChioKernel
pub fn evaluate_tool_call_blocking( &self, request: &ToolCallRequest, ) -> Result<ToolCallResponse, KernelError>
pub fn evaluate_tool_call_blocking_with_metadata( &self, request: &ToolCallRequest, extra_metadata: Option<Value>, ) -> Result<ToolCallResponse, KernelError>
Pre-execution authorization gate for callers that execute the tool
themselves (the sidecar mediated /v1/evaluate route).
Runs the full pre-dispatch verification pipeline (capability, DPoP,
governed intent, approval token, guards, runtime admission), reserves
the pre-execution budget hold and KEEPS IT OPEN, and mints a fresh
execution nonce. It never dispatches a tool server, never consumes a
presented nonce, and never signs a completed or settled spend. The
returned receipt is intentionally non-authoritative: the hold is
reserved, not reconciled, so is_authoritative_spend_receipt rejects it.
The reserved open hold is what enforces max_total_cost against
concurrent authorizations: a second authorization for a grant whose
budget is already fully reserved is denied. The caller presents the
minted nonce to the real tool server, which verifies and consumes it and
reconciles the reserved hold at the execution site.
The request MUST NOT carry a presented execution nonce: this entry point
mints nonces, it does not settle them. The invariant is enforced here
fail-closed: a request with a presented nonce is rejected with
KernelError::ReservingAuthorizationRejectsPresentedNonce rather than
silently skipping the reserve path (a presented nonce makes
execution_nonce_preflight_required return false) and falling through to
dispatch, which is the opposite of the documented reserve behavior.
Source§impl ChioKernel
impl ChioKernel
Sourcepub fn issue_capability(
&self,
subject: &PublicKey,
scope: ChioScope,
ttl_seconds: u64,
) -> Result<CapabilityToken, KernelError>
pub fn issue_capability( &self, subject: &PublicKey, scope: ChioScope, ttl_seconds: u64, ) -> Result<CapabilityToken, KernelError>
Issue a new capability for an agent.
The kernel delegates issuance to the configured capability authority.
Sourcepub fn revoke_capability(
&self,
capability_id: &CapabilityId,
) -> Result<(), KernelError>
pub fn revoke_capability( &self, capability_id: &CapabilityId, ) -> Result<(), KernelError>
Revoke a capability and all descendants in its delegation subtree.
When a root capability is revoked, every capability whose
delegation_chain contains the revoked ID will also be rejected
on presentation (the kernel checks all chain entries against the
revocation store).
Sourcepub fn is_capability_revoked(
&self,
capability_id: &str,
) -> Result<bool, KernelError>
pub fn is_capability_revoked( &self, capability_id: &str, ) -> Result<bool, KernelError>
Whether a capability id is present in the installed revocation store.
Callers that authorize a token minted outside the kernel (an HTTP authority projecting a presented capability, for example) use this to check the caller’s token against revocations, since the kernel’s own revocation check runs against the internal capability it evaluates.
Sourcepub fn receipt_log(&self) -> ReceiptLog
pub fn receipt_log(&self) -> ReceiptLog
Read-only access to the receipt log.
pub fn child_receipt_log(&self) -> ChildReceiptLog
pub fn guard_count(&self) -> usize
pub fn post_invocation_hook_count(&self) -> usize
pub async fn drain_tool_server_events_async( &self, ) -> Result<Vec<ToolServerEvent>, KernelError>
pub fn try_drain_tool_server_events( &self, ) -> Result<Vec<ToolServerEvent>, KernelError>
pub fn drain_tool_server_events(&self) -> Vec<ToolServerEvent>
pub fn register_session_pending_url_elicitation( &self, session_id: &SessionId, elicitation_id: impl Into<String>, related_task_id: Option<String>, ) -> Result<(), KernelError>
pub fn register_session_required_url_elicitations( &self, session_id: &SessionId, elicitations: &[CreateElicitationOperation], related_task_id: Option<&str>, ) -> Result<(), KernelError>
pub fn queue_session_elicitation_completion( &self, session_id: &SessionId, elicitation_id: &str, ) -> Result<(), KernelError>
pub fn queue_session_late_event( &self, session_id: &SessionId, event: LateSessionEvent, ) -> Result<(), KernelError>
pub fn queue_session_tool_server_event( &self, session_id: &SessionId, event: ToolServerEvent, ) -> Result<(), KernelError>
pub fn queue_session_tool_server_events( &self, session_id: &SessionId, ) -> Result<(), KernelError>
pub async fn queue_session_tool_server_events_async( &self, session_id: &SessionId, ) -> Result<(), KernelError>
pub fn drain_session_late_events( &self, session_id: &SessionId, ) -> Result<Vec<LateSessionEvent>, KernelError>
pub fn ca_count(&self) -> usize
pub fn public_key(&self) -> PublicKey
Sourcepub fn set_capability_crypto_floor(&mut self, floor: KernelCryptoFloor)
pub fn set_capability_crypto_floor(&mut self, floor: KernelCryptoFloor)
Set the configured capability-token crypto floor.
Boot paths that load policy.crypto_floor must call this before
accepting traffic when they do not use Self::with_hybrid_signing_backend.
pub fn capability_issuer_is_trusted(&self, issuer: &PublicKey) -> bool
pub fn arm_restart_reserved_hold_gate(&self) -> Result<(), KernelError>
Sourcepub fn evaluate_portable_verdict<'a>(
&self,
capability: &'a CapabilityToken,
request: &PortableToolCallRequest,
guards: &'a [&'a dyn Guard],
clock: &'a dyn Clock,
session_filesystem_roots: Option<&'a [String]>,
) -> EvaluationVerdict
pub fn evaluate_portable_verdict<'a>( &self, capability: &'a CapabilityToken, request: &PortableToolCallRequest, guards: &'a [&'a dyn Guard], clock: &'a dyn Clock, session_filesystem_roots: Option<&'a [String]>, ) -> EvaluationVerdict
Run the portable pure-compute verdict path provided by
chio-kernel-core.
This exposes the same synchronous checks the core kernel performs
(capability signature, issuer trust, time bounds, subject binding,
scope match, sync guard pipeline) in isolation from the
chio-kernel-only concerns (budget mutation, revocation lookup,
governed-transaction evaluation, tool dispatch, receipt
persistence).
Adapters that run the kernel on constrained platforms (wasm32,
edge workers, mobile via FFI) should prefer this entry point –
it does not require a tokio runtime, a sqlite database, or any
IO adapter. The full evaluate_tool_call_* API remains the
authoritative path for the desktop sidecar.
Verified-core boundary note:
formal/proof-manifest.toml treats this shell method as the one
chio-kernel entrypoint inside the current bounded verified core,
because it delegates directly to chio_kernel_core::evaluate after
supplying trusted issuers and portable guard/context wiring.
pub fn register_budget_parent( &self, parent_token_id: String, parent_share_bps: u16, ) -> Result<(), BudgetSplitError>
pub fn evict_budget_parent(&self, parent_token_id: &str)
Source§impl ChioKernel
impl ChioKernel
Sourcepub fn reap_expired_reserved_budget_holds(
&self,
now_unix_secs: i64,
) -> Result<usize, KernelError>
pub fn reap_expired_reserved_budget_holds( &self, now_unix_secs: i64, ) -> Result<usize, KernelError>
Settle every expired, unreconciled reserved budget hold at its reserved worst-case, forfeiting the reserved amount to realized spend. In the two-phase reserve/reconcile flow the only evidence a spend occurred is the caller’s reconcile; an expired-and-unreconciled hold may correspond to a call that executed and spent, so releasing it would under-count real spend and fail open for a cumulative spend cap. Self-healing and fail-closed: a still-valid reserved hold and any reconciled/reversed/released hold are never touched, and a settled hold is idempotent under repeated reaps. Returns the number of holds settled. The sidecar drives this on a timer (startup wiring is a later task); this method is the reachable primitive.
Reconcile the reserved budget hold named by a presented execution nonce at its measured realized cost, producing an authoritative mediated-spend receipt. Fail-closed at every step.
Order of checks:
- The presented
argumentsmust hash to the nonce’s bound parameter hash (the caller must have executed the exact call the nonce authorizes). - The nonce must name a reserved hold (
reserved_hold_id). - The realized currency must equal the currency the grant/hold was authorized in. This is checked BEFORE the nonce is consumed, so a mismatch is rejected fail-closed without burning the nonce or settling, and an unchecked caller-supplied currency never reaches a signed receipt.
- The nonce is VERIFIED (schema, expiry, signature under the kernel key, and that it has not already been consumed) but is NOT yet marked consumed. A forged or tampered nonce fails the signature check; an already-settled nonce fails the replay check; neither is ever marked.
- The named hold must still be open. A missing or already-closed hold is rejected. This open-to-closed settle is the mutual-exclusion point: two concurrent presentations of the same nonce cannot both settle because the store closes the hold atomically (the second finds it closed and is rejected here), so deferring the nonce mark opens no double-settle window.
- The hold is settled at
min(realized_cost, reserved)– realized cost is CLAMPED to the reserved worst-case, since the payer never authorized more than the reserved envelope. A realized cost of zero settles the hold at zero, releasing the entire reserved amount back to the grant. - The nonce is marked consumed (single-use replay) ONLY after the settle succeeds. A transient store error at step 6 therefore leaves the nonce unconsumed, so the caller can re-present the same signed nonce and settle at realized cost instead of forfeiting the reservation. Once the hold is closed a replay is already rejected at step 5, so marking after settlement is safe.
- A completed allow receipt is signed with the reconciled hold lineage
and the nonce id, so
is_authoritative_spend_receiptaccepts it.
Source§impl ChioKernel
impl ChioKernel
Sourcepub fn verify_dpop_for_permission_preview(
&self,
proof: &DpopProof,
cap: &CapabilityToken,
expected_tool_server: &str,
expected_tool_name: &str,
arguments: &Value,
) -> Result<(), KernelError>
pub fn verify_dpop_for_permission_preview( &self, proof: &DpopProof, cap: &CapabilityToken, expected_tool_server: &str, expected_tool_name: &str, arguments: &Value, ) -> Result<(), KernelError>
Verify a DPoP proof for non-mutating permission preview.
This mirrors invocation DPoP policy and checks that the nonce store and config are installed, but deliberately avoids inserting the nonce so a later authoritative invocation can still spend it.
Source§impl ChioKernel
impl ChioKernel
pub fn open_session( &self, agent_id: AgentId, issued_capabilities: Vec<CapabilityToken>, ) -> Result<SessionId, KernelError>
pub fn open_session_with_id( &self, session_id: SessionId, agent_id: AgentId, issued_capabilities: Vec<CapabilityToken>, ) -> Result<SessionId, KernelError>
Sourcepub fn activate_session(
&self,
session_id: &SessionId,
) -> Result<(), KernelError>
pub fn activate_session( &self, session_id: &SessionId, ) -> Result<(), KernelError>
Transition a session into the ready state once setup is complete.
Sourcepub fn set_session_auth_context(
&self,
session_id: &SessionId,
auth_context: SessionAuthContext,
) -> Result<(), KernelError>
pub fn set_session_auth_context( &self, session_id: &SessionId, auth_context: SessionAuthContext, ) -> Result<(), KernelError>
Persist transport/session authentication context for a session.
Sourcepub fn set_session_peer_capabilities(
&self,
session_id: &SessionId,
peer_capabilities: PeerCapabilities,
) -> Result<(), KernelError>
pub fn set_session_peer_capabilities( &self, session_id: &SessionId, peer_capabilities: PeerCapabilities, ) -> Result<(), KernelError>
Persist peer capabilities negotiated at the edge for a session.
Sourcepub fn replace_session_roots(
&self,
session_id: &SessionId,
roots: Vec<RootDefinition>,
) -> Result<(), KernelError>
pub fn replace_session_roots( &self, session_id: &SessionId, roots: Vec<RootDefinition>, ) -> Result<(), KernelError>
Replace the session’s current root snapshot.
Sourcepub fn normalized_session_roots(
&self,
session_id: &SessionId,
) -> Result<Vec<NormalizedRoot>, KernelError>
pub fn normalized_session_roots( &self, session_id: &SessionId, ) -> Result<Vec<NormalizedRoot>, KernelError>
Return the runtime’s normalized root view for a session.
Sourcepub fn enforceable_filesystem_root_paths(
&self,
session_id: &SessionId,
) -> Result<Vec<String>, KernelError>
pub fn enforceable_filesystem_root_paths( &self, session_id: &SessionId, ) -> Result<Vec<String>, KernelError>
Return only the enforceable filesystem root paths for a session.
Sourcepub fn subscribe_session_resource(
&self,
session_id: &SessionId,
capability: &CapabilityToken,
agent_id: &str,
uri: &str,
) -> Result<(), KernelError>
pub fn subscribe_session_resource( &self, session_id: &SessionId, capability: &CapabilityToken, agent_id: &str, uri: &str, ) -> Result<(), KernelError>
Subscribe the session to update notifications for a concrete resource URI.
Sourcepub fn unsubscribe_session_resource(
&self,
session_id: &SessionId,
uri: &str,
) -> Result<(), KernelError>
pub fn unsubscribe_session_resource( &self, session_id: &SessionId, uri: &str, ) -> Result<(), KernelError>
Remove a session-scoped resource subscription. Missing subscriptions are ignored.
Sourcepub fn session_has_resource_subscription(
&self,
session_id: &SessionId,
uri: &str,
) -> Result<bool, KernelError>
pub fn session_has_resource_subscription( &self, session_id: &SessionId, uri: &str, ) -> Result<bool, KernelError>
Check whether a session currently holds a resource subscription.
Sourcepub fn begin_draining_session(
&self,
session_id: &SessionId,
) -> Result<(), KernelError>
pub fn begin_draining_session( &self, session_id: &SessionId, ) -> Result<(), KernelError>
Mark a session as draining. New tool calls are rejected after this point.
Sourcepub fn close_session(&self, session_id: &SessionId) -> Result<(), KernelError>
pub fn close_session(&self, session_id: &SessionId) -> Result<(), KernelError>
Close a session and clear transient session-scoped state.
pub fn session_count(&self) -> usize
pub fn resource_provider_count(&self) -> usize
pub fn prompt_provider_count(&self) -> usize
Sourcepub fn begin_session_request(
&self,
context: &OperationContext,
operation_kind: OperationKind,
cancellable: bool,
) -> Result<(), KernelError>
pub fn begin_session_request( &self, context: &OperationContext, operation_kind: OperationKind, cancellable: bool, ) -> Result<(), KernelError>
Validate a session-scoped operation and register it as in flight.
Sourcepub fn begin_child_request(
&self,
parent_context: &OperationContext,
request_id: RequestId,
operation_kind: OperationKind,
progress_token: Option<ProgressToken>,
cancellable: bool,
) -> Result<OperationContext, KernelError>
pub fn begin_child_request( &self, parent_context: &OperationContext, request_id: RequestId, operation_kind: OperationKind, progress_token: Option<ProgressToken>, cancellable: bool, ) -> Result<OperationContext, KernelError>
Construct and register a child request under an existing parent request.
Sourcepub fn complete_session_request(
&self,
session_id: &SessionId,
request_id: &RequestId,
) -> Result<(), KernelError>
pub fn complete_session_request( &self, session_id: &SessionId, request_id: &RequestId, ) -> Result<(), KernelError>
Complete an in-flight session request.
Sourcepub fn complete_session_request_with_terminal_state(
&self,
session_id: &SessionId,
request_id: &RequestId,
terminal_state: OperationTerminalState,
) -> Result<(), KernelError>
pub fn complete_session_request_with_terminal_state( &self, session_id: &SessionId, request_id: &RequestId, terminal_state: OperationTerminalState, ) -> Result<(), KernelError>
Complete an in-flight session request with an explicit terminal state.
Sourcepub fn request_session_cancellation(
&self,
session_id: &SessionId,
request_id: &RequestId,
) -> Result<(), KernelError>
pub fn request_session_cancellation( &self, session_id: &SessionId, request_id: &RequestId, ) -> Result<(), KernelError>
Mark an in-flight session request as cancelled.
Sourcepub fn validate_sampling_request(
&self,
context: &OperationContext,
operation: &CreateMessageOperation,
) -> Result<(), KernelError>
pub fn validate_sampling_request( &self, context: &OperationContext, operation: &CreateMessageOperation, ) -> Result<(), KernelError>
Validate whether a sampling child request is allowed for this session.
Sourcepub fn validate_elicitation_request(
&self,
context: &OperationContext,
operation: &CreateElicitationOperation,
) -> Result<(), KernelError>
pub fn validate_elicitation_request( &self, context: &OperationContext, operation: &CreateElicitationOperation, ) -> Result<(), KernelError>
Validate whether an elicitation child request is allowed for this session.
Sourcepub fn evaluate_tool_call_operation_with_nested_flow_client<C: NestedFlowClient>(
&self,
context: &OperationContext,
operation: &ToolCallOperation,
client: &mut C,
) -> Result<ToolCallResponse, KernelError>
pub fn evaluate_tool_call_operation_with_nested_flow_client<C: NestedFlowClient>( &self, context: &OperationContext, operation: &ToolCallOperation, client: &mut C, ) -> Result<ToolCallResponse, KernelError>
Evaluate a session-scoped tool call while allowing the target tool server to proxy negotiated nested flows back through a client transport owned by the edge.
Sourcepub async fn evaluate_tool_call_operation_with_nested_flow_client_async<C: NestedFlowClient>(
&self,
context: &OperationContext,
operation: &ToolCallOperation,
client: &mut C,
) -> Result<ToolCallResponse, KernelError>
pub async fn evaluate_tool_call_operation_with_nested_flow_client_async<C: NestedFlowClient>( &self, context: &OperationContext, operation: &ToolCallOperation, client: &mut C, ) -> Result<ToolCallResponse, KernelError>
Async-native variant for hosts that already run inside a Tokio runtime.
This path avoids the synchronous dispatch bridge, so current-thread runtimes do not convert nested-flow tool calls into bridge errors. The synchronous entrypoint remains for blocking edges and still fails before side effects when a current-thread runtime is entered.
Sourcepub fn evaluate_session_operation(
&self,
context: &OperationContext,
operation: &SessionOperation,
) -> Result<SessionOperationResponse, KernelError>
pub fn evaluate_session_operation( &self, context: &OperationContext, operation: &SessionOperation, ) -> Result<SessionOperationResponse, KernelError>
Evaluate a normalized operation against a specific session.
This is the higher-level entry point that future JSON-RPC or MCP edges should target. The current stdio loop normalizes raw frames into these operations before invoking the kernel.
Auto Trait Implementations§
impl !Freeze for ChioKernel
impl !RefUnwindSafe for ChioKernel
impl !UnwindSafe for ChioKernel
impl Send for ChioKernel
impl Sync for ChioKernel
impl Unpin for ChioKernel
impl UnsafeUnpin for ChioKernel
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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