use std::sync::Arc;
use chio_appraisal::VerifiedRuntimeAttestationRecord;
use chio_core::receipt::metadata::GuardEvidence;
use dashmap::DashMap;
use crate::budget_store::BudgetCommitMetadata;
use crate::*;
#[path = "admission_coordinator.rs"]
mod admission_coordinator;
mod error;
mod kernel_drop_guard;
mod kernel_scopes;
mod kernel_struct;
pub use construction::KernelBuildError;
pub use error::{
HotPathStage, KernelError, OverloadResource, SettlementRuntimeConfigError,
StructuredErrorReport,
};
pub use kernel_struct::{
ChioKernel, HotPathDeadlineConfig, HybridSigningConfig, KernelConfig, MemoryBudgetConfig,
DEFAULT_CHECKPOINT_BATCH_SIZE, DEFAULT_MAX_SIZE_BYTES, DEFAULT_MAX_STREAM_DURATION_SECS,
DEFAULT_MAX_STREAM_TOTAL_BYTES, DEFAULT_RECEIPT_APPEND_BUDGET_MS,
DEFAULT_RECEIPT_WRITER_POLL_MS, DEFAULT_RECEIPT_WRITER_STALL_MS, DEFAULT_RETENTION_DAYS,
MIN_RECEIPT_APPEND_BUDGET_MS,
};
pub(crate) use admission_coordinator::{
DurableAdmissionRuntime, DurableToolAdmission, DurableToolReturnInput,
};
pub(crate) use kernel_drop_guard::{PostAdmissionDropGuard, PostAdmissionReceiptContext};
pub(crate) use kernel_scopes::{
current_scoped_receipt_federation_admission, current_scoped_receipt_tenant_id,
extract_tenant_id_from_auth_context, scope_receipt_federation_admission,
scope_receipt_tenant_id, ReceiptFederationAdmission, ScopedKernelReceiptFederationAdmission,
ScopedKernelReceiptTenantId,
};
pub(crate) use kernel_struct::{
capability_crypto_floor, receipt_crypto_floor, ReservedSiblingShare, RestartReservedHoldGate,
};
pub type AgentId = String;
pub type CapabilityId = String;
pub type ServerId = String;
pub const EMERGENCY_STOP_DENY_REASON: &str = "kernel emergency stop active";
pub struct RuntimeAdmissionContext<'a> {
pub request: &'a ToolCallRequest,
pub extra_metadata: Option<&'a serde_json::Value>,
pub now_unix_secs: u64,
pub now_unix_ms: u64,
pub matched_grant_index: Option<usize>,
pub local_kernel_id: String,
}
#[derive(Debug, Clone, PartialEq)]
pub struct RuntimeAdmissionDecision {
pub allowed: bool,
pub reason: Option<String>,
pub metadata: Option<serde_json::Value>,
}
impl RuntimeAdmissionDecision {
#[must_use]
pub fn allow(metadata: Option<serde_json::Value>) -> Self {
Self {
allowed: true,
reason: None,
metadata,
}
}
#[must_use]
pub fn deny(reason: impl Into<String>, metadata: Option<serde_json::Value>) -> Self {
Self {
allowed: false,
reason: Some(reason.into()),
metadata,
}
}
}
pub trait RuntimeAdmissionHook: Send + Sync {
fn name(&self) -> &str;
fn evaluate(
&self,
context: &RuntimeAdmissionContext<'_>,
) -> Result<RuntimeAdmissionDecision, KernelError>;
fn release_reserved(&self, _metadata: &serde_json::Value) -> Result<(), KernelError> {
Ok(())
}
}
#[derive(Debug, serde::Deserialize)]
#[serde(deny_unknown_fields)]
struct KernelFederationTreatyDsseMetadata {
capability_lease_ref: chio_federation::bilateral_dsse::CapabilityLeaseRef,
policy_evaluation_summary: chio_federation::bilateral_dsse::PolicyEvaluationSummary,
#[serde(default)]
governance_receipt_ref: Option<chio_federation::bilateral_dsse::GovernanceReceiptRef>,
#[serde(default)]
consistency_anchor: Option<String>,
#[serde(default)]
consistency_model: Option<String>,
#[serde(default)]
cross_org_visibility: Option<String>,
treaty_binding_ref: chio_federation::bilateral_dsse::TreatyBindingRef,
}
#[derive(Debug)]
pub(crate) struct ReceiptContent {
pub(crate) content_hash: String,
pub(crate) metadata: Option<serde_json::Value>,
pub(crate) canonical_content: Vec<u8>,
}
#[derive(Debug, Clone, Default)]
pub(crate) struct ValidatedGovernedCallChainProof {
upstream_proof: Option<chio_core::capability::governance::GovernedUpstreamCallChainProof>,
continuation_token_id: Option<String>,
session_anchor_id: Option<String>,
}
#[derive(Debug, Clone, Default)]
pub(crate) struct ValidatedGovernedAdmission {
call_chain_proof: Option<ValidatedGovernedCallChainProof>,
verified_runtime_attestation: Option<VerifiedRuntimeAttestationRecord>,
verified_payee_binding: Option<VerifiedGovernedPayeeBinding>,
approval_intent_hash: String,
approval_reservation: Option<VerifiedApprovalReservation>,
}
#[derive(Debug, Clone)]
pub(crate) struct VerifiedApprovalReservation {
pub(crate) threshold_proposal_hash: String,
pub(crate) approval_set_hash: String,
pub(crate) threshold_replay: Option<ThresholdApprovalReplayReservationV1>,
}
#[derive(Debug)]
pub(crate) struct VerifiedThresholdApprovalSet {
pub(crate) requirement: chio_core::capability::threshold_approval::ThresholdApprovalRequirement,
pub(crate) body: chio_core::capability::governance::VerifiedApprovalSetBody,
pub(crate) replay: ThresholdApprovalReplayReservationV1,
}
pub(crate) enum BudgetAdmissionOutcome {
Authorized {
grant_index: usize,
mutation: Box<PreExecutionBudgetMutation>,
},
PendingApproval {
grant_index: usize,
proposal: Box<chio_core::capability::governance::ThresholdApprovalProposal>,
},
}
#[cfg(test)]
impl BudgetAdmissionOutcome {
pub(crate) fn into_authorized(
self,
) -> Result<(usize, PreExecutionBudgetMutation), KernelError> {
match self {
Self::Authorized {
grant_index,
mutation,
} => Ok((grant_index, *mutation)),
Self::PendingApproval { .. } => Err(KernelError::Internal(
"budget admission remained pending approval".to_owned(),
)),
}
}
}
pub(crate) struct GovernedValidationContext<'a> {
parent_context: Option<&'a OperationContext>,
now: u64,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct VerifiedGovernedPayeeBinding {
beneficiary_id: String,
settlement_destination_ref: String,
payee_binding_digest: String,
economic_intent_digest: String,
pre_action_authority_digest: String,
}
impl VerifiedGovernedPayeeBinding {
pub(in crate::kernel) fn new(
beneficiary_id: String,
settlement_destination_ref: String,
economic_intent_digest: String,
pre_action_authority_digest: String,
) -> Result<Self, chio_credit::obligation::ObligationError> {
let payee_binding_digest = chio_credit::obligation::derive_obligation_payee_binding_digest(
&beneficiary_id,
&settlement_destination_ref,
)?;
Ok(Self {
beneficiary_id,
settlement_destination_ref,
payee_binding_digest,
economic_intent_digest,
pre_action_authority_digest,
})
}
#[cfg(test)]
pub(crate) fn for_test(
beneficiary_id: &str,
settlement_destination_ref: &str,
economic_intent_digest: &str,
pre_action_authority_digest: &str,
) -> Result<Self, chio_credit::obligation::ObligationError> {
Self::new(
beneficiary_id.to_owned(),
settlement_destination_ref.to_owned(),
economic_intent_digest.to_owned(),
pre_action_authority_digest.to_owned(),
)
}
#[must_use]
pub(crate) fn beneficiary_id(&self) -> &str {
&self.beneficiary_id
}
#[must_use]
pub(crate) fn settlement_destination_ref(&self) -> &str {
&self.settlement_destination_ref
}
#[must_use]
pub(crate) fn payee_binding_digest(&self) -> &str {
&self.payee_binding_digest
}
#[must_use]
pub(crate) fn economic_intent_digest(&self) -> &str {
&self.economic_intent_digest
}
#[must_use]
pub(crate) fn pre_action_authority_digest(&self) -> &str {
&self.pre_action_authority_digest
}
}
#[derive(Debug, Clone)]
pub(crate) enum LocalReceiptArtifact {
Tool(Box<chio_core::receipt::body::ChioReceipt>),
Child(Box<chio_core::receipt::lineage::ChildRequestReceipt>),
}
impl LocalReceiptArtifact {
fn verify_signature_with_floor(
&self,
floor: chio_core::receipt::crypto_floor::ReceiptCryptoFloor,
) -> Result<bool, KernelError> {
match self {
Self::Tool(receipt) => receipt.verify_signature_with_floor(floor).map_err(|error| {
KernelError::GovernedTransactionDenied(format!(
"governed call_chain parent receipt failed signature verification: {error}"
))
}),
Self::Child(receipt) => receipt.verify_signature_with_floor(floor).map_err(|error| {
KernelError::GovernedTransactionDenied(format!(
"governed call_chain parent receipt failed signature verification: {error}"
))
}),
}
}
fn artifact_hash(&self) -> Result<String, KernelError> {
let canonical = match self {
Self::Tool(receipt) => canonical_json_bytes(receipt),
Self::Child(receipt) => canonical_json_bytes(receipt),
}
.map_err(|error| {
KernelError::GovernedTransactionDenied(format!(
"failed to hash governed call_chain parent receipt: {error}"
))
})?;
Ok(sha256_hex(&canonical))
}
fn session_anchor_reference(&self) -> Option<chio_core::session::SessionAnchorReference> {
let metadata = match self {
Self::Tool(receipt) => receipt.metadata.as_ref(),
Self::Child(receipt) => receipt.metadata.as_ref(),
};
extract_session_anchor_reference_from_metadata(metadata)
}
}
fn block_on_async_tool_dispatch<F, T>(future: F) -> Result<T, KernelError>
where
F: std::future::Future<Output = Result<T, KernelError>>,
{
match tokio::runtime::Handle::try_current() {
Ok(handle) if handle.runtime_flavor() == tokio::runtime::RuntimeFlavor::MultiThread => {
tokio::task::block_in_place(|| handle.block_on(future))
}
Ok(_handle) => {
Err(KernelError::SyncBridgeIncompatibleWithCurrentThreadRuntime)
}
Err(_) => {
futures::executor::block_on(future)
}
}
}
fn extract_session_anchor_reference_from_metadata(
metadata: Option<&serde_json::Value>,
) -> Option<chio_core::session::SessionAnchorReference> {
let metadata = metadata?;
let candidates = [
metadata
.get("governed_transaction")
.and_then(|value| value.get("call_chain")),
metadata.get("lineageReferences"),
];
for candidate in candidates.into_iter().flatten() {
let Some(session_anchor_id) = candidate
.get("sessionAnchorId")
.and_then(serde_json::Value::as_str)
.filter(|value| !value.trim().is_empty())
else {
continue;
};
let Some(session_anchor_hash) = candidate
.get("sessionAnchorHash")
.and_then(serde_json::Value::as_str)
.filter(|value| !value.trim().is_empty())
else {
continue;
};
return Some(chio_core::session::SessionAnchorReference::new(
session_anchor_id,
session_anchor_hash,
));
}
None
}
#[derive(Debug, Clone)]
pub struct GuardDecision {
pub verdict: Verdict,
pub evidence: Vec<GuardEvidence>,
}
impl GuardDecision {
#[must_use]
pub fn allow() -> Self {
Self {
verdict: Verdict::Allow,
evidence: Vec::new(),
}
}
#[must_use]
pub fn allow_with_evidence(evidence: Vec<GuardEvidence>) -> Self {
Self {
verdict: Verdict::Allow,
evidence,
}
}
#[must_use]
pub fn deny(evidence: Vec<GuardEvidence>) -> Self {
Self {
verdict: Verdict::Deny,
evidence,
}
}
#[must_use]
pub fn pending_approval(evidence: Vec<GuardEvidence>) -> Self {
Self {
verdict: Verdict::PendingApproval,
evidence,
}
}
#[must_use]
pub fn from_verdict(verdict: Verdict) -> Self {
match verdict {
Verdict::Allow => Self::allow(),
Verdict::Deny => Self::deny(Vec::new()),
Verdict::PendingApproval => Self::pending_approval(Vec::new()),
}
}
}
impl PartialEq<Verdict> for GuardDecision {
fn eq(&self, other: &Verdict) -> bool {
self.verdict == *other
}
}
impl PartialEq<GuardDecision> for Verdict {
fn eq(&self, other: &GuardDecision) -> bool {
*self == other.verdict
}
}
pub trait Guard: Send + Sync {
fn name(&self) -> &str;
fn evaluate(&self, ctx: &GuardContext) -> Result<GuardDecision, KernelError>;
}
pub struct GuardContext<'a> {
pub request: &'a ToolCallRequest,
pub scope: &'a ChioScope,
pub agent_id: &'a AgentId,
pub server_id: &'a ServerId,
pub session_filesystem_roots: Option<&'a [String]>,
pub matched_grant_index: Option<usize>,
}
pub trait ResourceProvider: Send + Sync {
fn list_resources(&self) -> Vec<ResourceDefinition>;
fn list_resource_templates(&self) -> Vec<ResourceTemplateDefinition> {
vec![]
}
fn read_resource(&self, uri: &str) -> Result<Option<Vec<ResourceContent>>, KernelError>;
fn complete_resource_argument(
&self,
_uri: &str,
_argument_name: &str,
_value: &str,
_context: &serde_json::Value,
) -> Result<Option<CompletionResult>, KernelError> {
Ok(None)
}
}
pub trait PromptProvider: Send + Sync {
fn list_prompts(&self) -> Vec<PromptDefinition>;
fn get_prompt(
&self,
name: &str,
arguments: serde_json::Value,
) -> Result<Option<PromptResult>, KernelError>;
fn complete_prompt_argument(
&self,
_name: &str,
_argument_name: &str,
_value: &str,
_context: &serde_json::Value,
) -> Result<Option<CompletionResult>, KernelError> {
Ok(None)
}
}
const DEFAULT_RECEIPT_MIRROR_CAPACITY: usize = 4096;
#[derive(Clone)]
pub struct ReceiptLog {
ring: chio_bounded::Ring<ChioReceipt>,
}
impl ReceiptLog {
pub fn new() -> Self {
Self::with_capacity(
DEFAULT_RECEIPT_MIRROR_CAPACITY,
chio_bounded::SizeGauge::new(),
)
}
pub fn with_capacity(capacity: usize, gauge: chio_bounded::SizeGauge) -> Self {
Self {
ring: chio_bounded::Ring::with_capacity(capacity, gauge),
}
}
pub fn append(&mut self, receipt: ChioReceipt) {
let _evicted = self.ring.push(receipt);
}
pub fn len(&self) -> usize {
self.ring.len()
}
pub fn is_empty(&self) -> bool {
self.ring.is_empty()
}
pub fn iter(&self) -> impl Iterator<Item = &ChioReceipt> {
self.ring.iter()
}
pub fn receipts(&self) -> Vec<ChioReceipt> {
self.ring.iter().cloned().collect()
}
pub fn get(&self, index: usize) -> Option<&ChioReceipt> {
self.ring.iter().nth(index)
}
}
impl Default for ReceiptLog {
fn default() -> Self {
Self::new()
}
}
#[derive(Clone)]
pub struct ChildReceiptLog {
ring: chio_bounded::Ring<ChildRequestReceipt>,
}
impl ChildReceiptLog {
pub fn new() -> Self {
Self::with_capacity(
DEFAULT_RECEIPT_MIRROR_CAPACITY,
chio_bounded::SizeGauge::new(),
)
}
pub fn with_capacity(capacity: usize, gauge: chio_bounded::SizeGauge) -> Self {
Self {
ring: chio_bounded::Ring::with_capacity(capacity, gauge),
}
}
pub fn append(&mut self, receipt: ChildRequestReceipt) {
let _evicted = self.ring.push(receipt);
}
pub fn len(&self) -> usize {
self.ring.len()
}
pub fn is_empty(&self) -> bool {
self.ring.is_empty()
}
pub fn iter(&self) -> impl Iterator<Item = &ChildRequestReceipt> {
self.ring.iter()
}
pub fn receipts(&self) -> Vec<ChildRequestReceipt> {
self.ring.iter().cloned().collect()
}
pub fn get(&self, index: usize) -> Option<&ChildRequestReceipt> {
self.ring.iter().nth(index)
}
}
impl Default for ChildReceiptLog {
fn default() -> Self {
Self::new()
}
}
#[derive(Clone, Copy)]
pub(crate) struct MatchingGrant<'a> {
pub(crate) index: usize,
pub(crate) grant: &'a ToolGrant,
pub(crate) specificity: (u8, u8, usize),
}
pub(crate) struct BudgetChargeResult {
grant_index: usize,
cost_charged: u64,
currency: String,
budget_total: u64,
new_committed_cost_units: u64,
budget_hold_id: String,
authorize_metadata: BudgetCommitMetadata,
invocation_capture: Option<Box<crate::budget_store::BudgetHoldMutationDecision>>,
}
impl BudgetChargeResult {
fn reverse_event_id(&self) -> String {
let authorize_event_id = self
.authorize_metadata
.event_id
.as_deref()
.unwrap_or(&self.budget_hold_id);
let authorize_commit_index = self.authorize_metadata.budget_commit_index.unwrap_or(0);
format!("{authorize_event_id}:rollback:{authorize_commit_index}")
}
fn capture_invocation_event_id(&self) -> String {
let authorize_commit_index = self.authorize_metadata.budget_commit_index.unwrap_or(0);
format!(
"{}:capture-invocation:{authorize_commit_index}",
self.budget_hold_id
)
}
fn cancel_captured_before_dispatch_event_id(&self) -> String {
self.reverse_event_id()
}
fn reconcile_event_id(&self) -> String {
format!("{}:reconcile", self.budget_hold_id)
}
}
pub(crate) enum PreExecutionBudgetMutation {
None,
Invocation { grant_index: usize },
InvocationHold(BudgetChargeResult),
Charge(BudgetChargeResult),
}
impl PreExecutionBudgetMutation {
fn charge_result(&self) -> Option<&BudgetChargeResult> {
match self {
Self::Charge(charge) => Some(charge),
Self::None | Self::Invocation { .. } | Self::InvocationHold(_) => None,
}
}
fn durable_hold_result(&self) -> Option<&BudgetChargeResult> {
match self {
Self::Charge(charge) | Self::InvocationHold(charge) => Some(charge),
Self::None | Self::Invocation { .. } => None,
}
}
fn durable_hold_result_mut(&mut self) -> Option<&mut BudgetChargeResult> {
match self {
Self::Charge(charge) | Self::InvocationHold(charge) => Some(charge),
Self::Invocation { .. } | Self::None => None,
}
}
fn into_charge_result(self) -> Option<BudgetChargeResult> {
match self {
Self::Charge(charge) => Some(charge),
Self::None | Self::Invocation { .. } | Self::InvocationHold(_) => None,
}
}
}
struct SessionNestedFlowBridge<'a, C> {
sessions: &'a DashMap<SessionId, Arc<Session>>,
child_receipts: &'a mut Vec<ChildRequestReceipt>,
parent_context: &'a OperationContext,
allow_sampling: bool,
allow_sampling_tool_use: bool,
allow_elicitation: bool,
policy_hash: &'a str,
kernel_keypair: &'a Keypair,
client: &'a mut C,
}
impl<C> SessionNestedFlowBridge<'_, C> {
fn complete_child_request_with_receipt<T: serde::Serialize>(
&mut self,
child_context: &OperationContext,
operation_kind: OperationKind,
result: &Result<T, KernelError>,
) -> Result<(), KernelError> {
let terminal_state = child_terminal_state(&child_context.request_id, result);
complete_session_request_with_terminal_state_in_sessions(
self.sessions,
&child_context.session_id,
&child_context.request_id,
terminal_state.clone(),
)?;
let receipt = build_child_request_receipt(
self.policy_hash,
self.kernel_keypair,
child_context,
operation_kind,
terminal_state,
child_outcome_payload(result)?,
)?;
self.child_receipts.push(receipt);
Ok(())
}
}
impl<C: NestedFlowClient> NestedFlowBridge for SessionNestedFlowBridge<'_, C> {
fn parent_request_id(&self) -> &RequestId {
&self.parent_context.request_id
}
fn poll_parent_cancellation(&mut self) -> Result<(), KernelError> {
self.client.poll_parent_cancellation(self.parent_context)
}
fn list_roots(&mut self) -> Result<Vec<RootDefinition>, KernelError> {
let (child_context, _start) = begin_child_request_in_sessions(
self.sessions,
self.parent_context,
nested_child_request_id(&self.parent_context.request_id, "roots"),
OperationKind::ListRoots,
None,
false,
)?;
let result = (|| {
let session = session_from_map(self.sessions, &child_context.session_id)?;
session.validate_context(&child_context)?;
session.ensure_operation_allowed(OperationKind::ListRoots)?;
if !session.peer_capabilities().supports_roots {
return Err(KernelError::RootsNotNegotiated);
}
let roots = self
.client
.list_roots(self.parent_context, &child_context)?;
session_from_map(self.sessions, &child_context.session_id)?
.replace_roots(roots.clone());
Ok(roots)
})();
if matches!(
&result,
Err(KernelError::RequestCancelled { request_id, .. })
if request_id == &child_context.request_id
) {
session_from_map(self.sessions, &child_context.session_id)?
.request_cancellation(&child_context.request_id)?;
}
self.complete_child_request_with_receipt(
&child_context,
OperationKind::ListRoots,
&result,
)?;
result
}
fn create_message(
&mut self,
operation: CreateMessageOperation,
) -> Result<CreateMessageResult, KernelError> {
let (child_context, _start) = begin_child_request_in_sessions(
self.sessions,
self.parent_context,
nested_child_request_id(&self.parent_context.request_id, "sample"),
OperationKind::CreateMessage,
None,
true,
)?;
let result = (|| {
validate_sampling_request_in_sessions(
self.sessions,
self.allow_sampling,
self.allow_sampling_tool_use,
&child_context,
&operation,
)?;
self.client
.create_message(self.parent_context, &child_context, &operation)
})();
if matches!(
&result,
Err(KernelError::RequestCancelled { request_id, .. })
if request_id == &child_context.request_id
) {
session_from_map(self.sessions, &child_context.session_id)?
.request_cancellation(&child_context.request_id)?;
}
self.complete_child_request_with_receipt(
&child_context,
OperationKind::CreateMessage,
&result,
)?;
result
}
fn create_elicitation(
&mut self,
operation: CreateElicitationOperation,
) -> Result<CreateElicitationResult, KernelError> {
let (child_context, _start) = begin_child_request_in_sessions(
self.sessions,
self.parent_context,
nested_child_request_id(&self.parent_context.request_id, "elicit"),
OperationKind::CreateElicitation,
None,
true,
)?;
let result = (|| {
validate_elicitation_request_in_sessions(
self.sessions,
self.allow_elicitation,
&child_context,
&operation,
)?;
self.client
.create_elicitation(self.parent_context, &child_context, &operation)
})();
if matches!(
&result,
Err(KernelError::RequestCancelled { request_id, .. })
if request_id == &child_context.request_id
) {
session_from_map(self.sessions, &child_context.session_id)?
.request_cancellation(&child_context.request_id)?;
}
self.complete_child_request_with_receipt(
&child_context,
OperationKind::CreateElicitation,
&result,
)?;
result
}
fn notify_elicitation_completed(&mut self, elicitation_id: &str) -> Result<(), KernelError> {
let session = session_from_map(self.sessions, &self.parent_context.session_id)?;
session.validate_context(self.parent_context)?;
session.ensure_operation_allowed(OperationKind::ToolCall)?;
self.client
.notify_elicitation_completed(self.parent_context, elicitation_id)
}
fn notify_resource_updated(&mut self, uri: &str) -> Result<(), KernelError> {
let session = session_from_map(self.sessions, &self.parent_context.session_id)?;
session.validate_context(self.parent_context)?;
session.ensure_operation_allowed(OperationKind::ToolCall)?;
if !session.is_resource_subscribed(uri) {
return Ok(());
}
self.client
.notify_resource_updated(self.parent_context, uri)
}
fn notify_resources_list_changed(&mut self) -> Result<(), KernelError> {
let session = session_from_map(self.sessions, &self.parent_context.session_id)?;
session.validate_context(self.parent_context)?;
session.ensure_operation_allowed(OperationKind::ToolCall)?;
self.client
.notify_resources_list_changed(self.parent_context)
}
}
fn extract_guard_name(message: &str) -> Option<String> {
let start_marker = "guard \"";
let start = message.find(start_marker)? + start_marker.len();
let rest = &message[start..];
let end = rest.find('"')?;
Some(rest[..end].to_string())
}
fn scope_from_capability_snapshot(
snapshot: &crate::capability_lineage::CapabilitySnapshot,
) -> Result<ChioScope, KernelError> {
serde_json::from_str(&snapshot.grants_json).map_err(|error| {
KernelError::Internal(format!(
"invalid capability snapshot scope for {}: {error}",
snapshot.capability_id
))
})
}
fn validate_delegation_scope_step(
parent_capability_id: &str,
child_capability_id: &str,
parent_scope: &ChioScope,
child_scope: &ChioScope,
child_expires_at: u64,
link: &chio_core::capability::attenuation::DelegationLink,
) -> Result<(), KernelError> {
validate_delegatable_subset(
parent_capability_id,
child_capability_id,
parent_scope,
child_scope,
)?;
validate_declared_attenuations(child_capability_id, child_scope, child_expires_at, link)?;
Ok(())
}
fn validate_delegatable_subset(
parent_capability_id: &str,
child_capability_id: &str,
parent_scope: &ChioScope,
child_scope: &ChioScope,
) -> Result<(), KernelError> {
for child_grant in &child_scope.grants {
let allowed = parent_scope.grants.iter().any(|parent_grant| {
parent_grant.operations.contains(&Operation::Delegate)
&& child_grant.is_subset_of(parent_grant)
});
if !allowed {
return Err(KernelError::DelegationInvalid(format!(
"parent capability {} does not authorize delegated tool grant {}/{} on child capability {}",
parent_capability_id,
child_grant.server_id,
child_grant.tool_name,
child_capability_id
)));
}
}
for child_grant in &child_scope.resource_grants {
let allowed = parent_scope.resource_grants.iter().any(|parent_grant| {
parent_grant.operations.contains(&Operation::Delegate)
&& child_grant.is_subset_of(parent_grant)
});
if !allowed {
return Err(KernelError::DelegationInvalid(format!(
"parent capability {} does not authorize delegated resource grant {} on child capability {}",
parent_capability_id, child_grant.uri_pattern, child_capability_id
)));
}
}
for child_grant in &child_scope.prompt_grants {
let allowed = parent_scope.prompt_grants.iter().any(|parent_grant| {
parent_grant.operations.contains(&Operation::Delegate)
&& child_grant.is_subset_of(parent_grant)
});
if !allowed {
return Err(KernelError::DelegationInvalid(format!(
"parent capability {} does not authorize delegated prompt grant {} on child capability {}",
parent_capability_id, child_grant.prompt_name, child_capability_id
)));
}
}
Ok(())
}
fn validate_declared_attenuations(
child_capability_id: &str,
child_scope: &ChioScope,
child_expires_at: u64,
link: &chio_core::capability::attenuation::DelegationLink,
) -> Result<(), KernelError> {
for attenuation in &link.attenuations {
match attenuation {
chio_core::capability::attenuation::Attenuation::RemoveTool {
server_id,
tool_name,
} => {
if child_scope
.grants
.iter()
.any(|grant| tool_grant_covers_target(grant, server_id, tool_name))
{
return Err(KernelError::DelegationInvalid(format!(
"child capability {} still grants removed tool {}/{}",
child_capability_id, server_id, tool_name
)));
}
}
chio_core::capability::attenuation::Attenuation::RemoveOperation {
server_id,
tool_name,
operation,
} => {
if child_scope.grants.iter().any(|grant| {
tool_grant_covers_target(grant, server_id, tool_name)
&& grant.operations.contains(operation)
}) {
return Err(KernelError::DelegationInvalid(format!(
"child capability {} still grants removed operation {:?} on {}/{}",
child_capability_id, operation, server_id, tool_name
)));
}
}
chio_core::capability::attenuation::Attenuation::AddConstraint {
server_id,
tool_name,
constraint,
} => {
if child_scope.grants.iter().any(|grant| {
tool_grant_covers_target(grant, server_id, tool_name)
&& !grant.constraints.contains(constraint)
}) {
return Err(KernelError::DelegationInvalid(format!(
"child capability {} is missing declared constraint on {}/{}",
child_capability_id, server_id, tool_name
)));
}
}
chio_core::capability::attenuation::Attenuation::ReduceBudget {
server_id,
tool_name,
max_invocations,
} => {
if child_scope.grants.iter().any(|grant| {
tool_grant_covers_target(grant, server_id, tool_name)
&& grant
.max_invocations
.is_none_or(|value| value > *max_invocations)
}) {
return Err(KernelError::DelegationInvalid(format!(
"child capability {} exceeds declared invocation budget on {}/{}",
child_capability_id, server_id, tool_name
)));
}
}
chio_core::capability::attenuation::Attenuation::ShortenExpiry { new_expires_at } => {
if child_expires_at > *new_expires_at {
return Err(KernelError::DelegationInvalid(format!(
"child capability {} expires after declared shortened expiry {}",
child_capability_id, new_expires_at
)));
}
}
chio_core::capability::attenuation::Attenuation::ReduceCostPerInvocation {
server_id,
tool_name,
max_cost_per_invocation,
} => {
if child_scope.grants.iter().any(|grant| {
tool_grant_covers_target(grant, server_id, tool_name)
&& grant.max_cost_per_invocation.as_ref().is_none_or(|value| {
value.currency != max_cost_per_invocation.currency
|| value.units > max_cost_per_invocation.units
})
}) {
return Err(KernelError::DelegationInvalid(format!(
"child capability {} exceeds declared per-invocation cost ceiling on {}/{}",
child_capability_id, server_id, tool_name
)));
}
}
chio_core::capability::attenuation::Attenuation::ReduceTotalCost {
server_id,
tool_name,
max_total_cost,
} => {
if child_scope.grants.iter().any(|grant| {
tool_grant_covers_target(grant, server_id, tool_name)
&& grant.max_total_cost.as_ref().is_none_or(|value| {
value.currency != max_total_cost.currency
|| value.units > max_total_cost.units
})
}) {
return Err(KernelError::DelegationInvalid(format!(
"child capability {} exceeds declared total-cost ceiling on {}/{}",
child_capability_id, server_id, tool_name
)));
}
}
}
}
Ok(())
}
fn tool_grant_covers_target(grant: &ToolGrant, server_id: &str, tool_name: &str) -> bool {
(grant.server_id == "*" || grant.server_id == server_id)
&& (grant.tool_name == "*" || grant.tool_name == tool_name)
}
pub(crate) struct ReceiptParams<'a> {
request_id: Option<&'a str>,
capability_id: &'a str,
tool_name: &'a str,
server_id: &'a str,
decision: Decision,
action: ToolCallAction,
content_hash: String,
canonical_content: Vec<u8>,
metadata: Option<serde_json::Value>,
timestamp: u64,
trust_level: chio_core::receipt::kinds::TrustLevel,
tenant_id: Option<String>,
}
pub(crate) fn current_unix_timestamp() -> u64 {
if let Some(now) = fixed_runtime_unix_secs_for_current_thread() {
return now;
}
SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.as_secs())
.unwrap_or(0)
}
pub(crate) fn current_unix_timestamp_ms() -> u64 {
if let Some(now) = fixed_runtime_unix_secs_for_current_thread() {
return now.saturating_mul(1000);
}
SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|duration| u64::try_from(duration.as_millis()).unwrap_or(u64::MAX))
.unwrap_or(0)
}
#[cfg(feature = "delegation")]
#[path = "delegation.rs"]
pub(crate) mod delegation;
#[path = "construction.rs"]
mod construction;
mod evaluation;
#[path = "validation.rs"]
mod validation;
#[path = "reconciliation.rs"]
mod reconciliation;
#[path = "governed_validation.rs"]
mod governed_validation;
#[path = "dispatch.rs"]
mod dispatch;
#[path = "evaluator.rs"]
pub mod evaluator;
mod responses;
#[path = "session_ops.rs"]
mod session_ops;
#[path = "settlement_observer.rs"]
pub mod settlement_observer;
#[path = "signing_task.rs"]
pub(crate) mod signing_task;
#[path = "receipt_writer_watchdog.rs"]
mod receipt_writer_watchdog;
#[cfg(test)]
#[path = "tests.rs"]
mod tests;