Bypass resistance
See which paths can construct a kernel or dispatch a call, and how the build fails when a new one appears.
On this page
Every kernel construction and dispatch call that Chio's scanner finds in the source tree is named in a checked inventory, and an unlisted site fails the build.
The result covers the five scanned directories and excludes test-only code. Dispatch contracts and behavior tests cover what a static scan cannot see, and feature negotiation fixes which invocation semantics each session carries.
A new construction or dispatch site fails the build
A kernel constructor or dispatch call that the inventory does not already name fails as unclassified. Its author classifies the owner, entrypoint, and effect boundary before the build passes.
A control holds only when every path to its effect passes the kernel
A check can be correct and still ineffective if the application has another way to perform the same action. A coding host may expose one file through a native tool, a protocol adapter, and a shell; an SDK wrapper may enforce a rule while a lower-level connector stays callable; a new adapter may keep the ordinary request fields and drop a security extension that changes admission. Constructors choose which authorities and stores exist, transports choose which commitments survive serialization, and dispatch sites choose which executor reaches the resource.
Every route from the agent to the repository crosses the kernel, so admission is mandatory.
In Rust · lib.rs:25913 lines
/// Invoke a bridged tool. A dispatcher is required so the kernel cannot
/// sign successful receipts for simulated side effects.
pub fn invoke_tool(&self, tool_name: &str, arguments: Value) -> Result<Value, BridgeError> {
// …
if let Some(dispatcher) = &self.dispatcher {
// … egress contract checks
let response = dispatcher(&binding.method, &url, &arguments)?;
// …
} else {
Err(BridgeError::Kernel(
"OpenAPI bridge requires a dispatcher for live tool invocation".to_string(),
))
}
Chio's consumer boundary ledger sorts every accepted way to reach the kernel into six profiles, by who dispatches the effect:
- Trusted native host. The embedding host's own process, through the kernel's native construction path.
- Mediated protocol. The configured kernel, behind an authenticated MCP, A2A, or ACP-Client edge.
- Ordinary kernel host. The kernel, built by a factory that installs no active defense.
- Caller transport. The caller-side executor, once the kernel commits dispatch; Caller delivery covers its reservation, start, and report calls.
- Portable verification. No one; a portable evaluator decides and never dispatches.
- Harness. A synthetic or local connector, never a production path.
These are consumer profiles. The six security profiles are a separate vocabulary that sorts execution boundaries by what each controls.
The inventory names 31 constructor sites and 91 dispatch sites
formal/adapter-source-inventory.toml (schema chio.adapter-source-inventory.v1) names every place the workspace may build a kernel and every place a built kernel may evaluate or authorize a tool call, decide a provider invocation, or reserve, start, or reconcile a caller delivery. Dispatch sites cluster where the trust boundary is highest: 42 in chio-kernel, 12 in chio-mcp-edge, 8 in chio-control-plane, and 4 in chio-api-protect, with small counts across the other adapters, tooling, and examples. Each entry records a path, a symbol, a target, and a reference count, grouped by source location.
The check rescans crates, examples, integrations, bench, and sdks for the constructor calls its FACTORIES list names, for direct ChioKernel::new and ChioKernel::default calls (21 of the 31 constructor sites), and for the dispatch calls its prefix list names. Its CALL_CONTRACTS table also requires named protocol-adapter, kernel-validation, and runtime-admission functions to call a named validation or dispatch target a minimum number of times, so an entry point cannot quietly stop checking peer capabilities. Every Chio release passes the adapter-no-bypass gate before it is tagged. chio release verify --evidence qualification shows its result for the release you run.
An unclassified live site or a stale entry fails the check. When you add a constructor or dispatch path, classify its owner, entrypoint, and effect boundary in the inventory, keep that classification through aliases and generated callsites, and extend the scanner for syntax it does not cover. The contributor qualification page runs the check against a source tree.
Test-only code sits outside the scan, and an import alias, a kernel type alias, or a macro-hidden reference fails the check. The checker supplements dispatch contracts and behavior tests and performs no Rust type checking or macro expansion, so a new constructor alias or macro-hidden construction needs a scanner extension. The inventory is a completeness gate over named sites, not a semantic proof that no other path exists.
Source locations
validate_invocation_features is defined at chio-core-types/src/capability/features.rs:106. The FACTORIES list at xtask/src/adapter_no_bypass/constructors.rs:24, and CALL_CONTRACTS at xtask/src/adapter_no_bypass.rs:198.
Negotiation fixes the semantics a session carries before admission begins
CapabilityNegotiation::validate_invocation_features checks a request's aggregate budget, cumulative approval, threshold-governed approval, governed active-response, and opaque supplemental extensions against the profile the peer negotiated, before any signature or admission check. A request that uses an extension its session never negotiated is refused, and an adapter that drops a negotiated required field is refused instead of downgraded. Success establishes semantic compatibility; signatures, reservations, and authorization are decided afterward. MCP negotiates the profile once, at initialize, in capabilities.experimental.chioAuthorization: an object naming the extensions the session supports.
A declared information flow travels the same way. A manifest-aware entrypoint checks for an installed flow runtime before metadata validation or dispatch, so an ordinary host with no governed flow runtime refuses a flow-required reader with FlowRuntimeUnavailable, while a configured native host with the verified manifest, an atomically installed runtime, and an authenticated request invokes it. Removing the declaration or choosing an ungoverned entrypoint repairs nothing, and the reader's original destination is still evaluated.
Invoke a flow-required reader through the manifest-aware entrypoint
use chio_kernel::{ChioKernel, KernelError, SecurityInvocationContext,
ToolCallRequest, ToolCallResponse};
use chio_manifest::{BridgeSecurityMetadata, VerifiedManifestRegistry};
/// Invoke through the actual manifest-aware entrypoint. Its required-runtime
/// check happens before metadata validation or dispatch; the registry and
/// security context are independently authenticated selections of the host.
pub fn invoke_required_flow_reader(
kernel: &ChioKernel, original: &ToolCallRequest,
registry: &VerifiedManifestRegistry, security: &BridgeSecurityMetadata,
current_context: &SecurityInvocationContext,
) -> Result<ToolCallResponse, KernelError> {
kernel.evaluate_tool_call_blocking_with_manifest_security_and_security_context(
original, registry, security, None, current_context,
)
}
/// A readiness observation is useful for diagnosis, but not a dispatch permit.
pub fn check_required_flow_host(
kernel: &ChioKernel, registry: &VerifiedManifestRegistry,
) -> Result<(), KernelError> {
if registry.requires_flow_runtime() && !kernel.has_installed_flow_runtime() {
return Err(KernelError::FlowRuntimeUnavailable);
}
Ok(())
}The first function uses the manifest-aware evaluation entrypoint, whose required-runtime check precedes dispatch, and compiles. The second is an advisory readiness query on the verified registry and runtime generation; it grants no permission and never replaces the invocation. Download the function. For each exposed entrypoint, pair a useful admitted read with a credential-file or public-export request that should refuse: the repository matcher and export comparison run those pure checks, and a deployed host adds its own physical observations.
Every language binding is held to the same wire and the same refusals
Ten more required boundaries, P01 to P10 in the consumer ledger's public profile mapping, extend the inventory to portable evaluators, declarative translators, and effect-only connectors the physical scan does not walk. Nine SDK lanes, S01 to S09, name each language package's role, and feature negotiation, required authority, and failure behavior stay equivalent across them.
- Current wire. Python S01, TypeScript S04, and Go S06 are held to the shared fixtures by the
sdk-paritygate, so a generated model that drifts from the canonical schema fails. - Manifest helpers. S02, S05, and S07 recognize v1 only and do not count as current-v2 verification.
- Rust and bindings. The Rust current-wire corpora and the S08
chio-binding-helpersreceipt vectors run in the samesdk-paritygate. Every Chio release passes thesdk-paritygate before it is tagged.chio release verify --evidence qualificationshows its result for the release you run. - C++. S09 runs its own behavioral gates.
Read more in Behavioral gates, which owns the suite's execution.
Unnegotiated features and flow-required manifests stop before dispatch
An MCP tools/call that uses an unnegotiated feature gets the first refusal inside a JSON-RPC error on the same connection. chio mcp serve-http, chio mcp serve, and chio mcp wrap print the other three to stderr, each with help: run the server under an active-defense host profile, and exit 1 before the edge serves a request or the wrapped server launches.
| Refusal | Cause |
|---|---|
JSON-RPC error -32602 "canonical JSON error: invocation feature <feature> was not negotiated" | Call used a feature its session did not negotiate |
error[CHIO- | chio mcp serve-http given a flow-required manifest; its ordinary kernel installs no flow runtime |
error[CHIO- | The same on the stdio chio mcp serve path |
error[CHIO- | The same on the wrapping path |
For an unnegotiated feature, correct the session's negotiation; negotiation still grants no authority. For a flow-required manifest, run an active-defense host that installs the flow runtime, since dropping the manifest requirement would bypass the declared boundary. Integration maintainers check the same refusal on every transport they expose.