ReferenceSpec
Swarm Protocol
The chio-swarm/v1 authority bundle: the signed artifacts a verifier accepts, the fixed order it checks them in, and the graph invariants.
Source
This page normatively reflects spec/PROTOCOL.md section 6.4.2 and the schemas under spec/schemas/chio-swarm/v1/ in the chio repository. Status: Current bounded Chio release profile. Version 1.0. The keywords MUST, SHOULD, and MAY are normative.
Where the crate is the truth for behavior the page follows the crate and names the file: crates/kernel/chio-swarm-authority/src/verifier.rs with its submodules verifier/witness.rs, verifier/util.rs, and verifier/budget_accounting.rs; the bundle types in crates/kernel/chio-swarm-authority/src/types.rs; the budget-pool digest projection in crates/kernel/chio-swarm-authority/src/finding_pool.rs; and the worked example crates/kernel/chio-swarm-authority/examples/agent_os.rs.
This specification describes chio-swarm/v1. Validate against the schema identifier carried in the artifact. A change to the shape or meaning of any required field mints a new version identifier.
Synopsis
A hop presents one bundle, and verify_swarm_authority_bundle accepts it whole or rejects it.
pub struct SwarmAuthorityBundle {
pub task_graph: SwarmTaskGraph,
pub continuation_tokens: Vec<SwarmContinuationToken>,
pub witness_chains: Vec<SwarmDelegationWitnessChain>,
pub join_receipts: Vec<SwarmJoinReceipt>,
pub route_plan_receipts: Vec<SwarmRoutePlanReceipt>,
pub budget_pool: SwarmBudgetPool,
pub revocation_epoch: SwarmRevocationEpoch,
#[serde(default)]
pub terminal_receipts: Vec<SwarmTerminalGraphReceipt>,
pub now_unix_ms: u64,
}Bundle artifacts
The registry tracks 9 schema files under chio-swarm/v1. Every artifact is a signed, closed object: unknown fields are rejected on both the schema and the Rust side. The field shape of each one is specified on its own page.
| Schema title | Registry id | What it proves | Field shape |
|---|---|---|---|
| Chio Swarm Task Graph | chio.swarm.task-graph.v1 | The signed DAG the whole bundle belongs to, carrying the structural ceilings a verifier enforces across every task and every hop. | Task graphs |
| Chio Swarm Continuation Token | chio.swarm.continuation-token.v1 | That one hop was authorized, binding the child task to its graph digest, its single parent context, its route, its allocation, and the revocation epoch it was checked against. | Continuations |
| Chio Swarm Delegation Witness Chain | chio.swarm.delegation-witness-chain.v1 | That authority only ever narrowed from parent to child across the hop, with a checked scope subset proof and a pinned signature at every step. | Witness chains |
| Chio Swarm Join Receipt | chio.swarm.join-receipt.v1 | That a fan-in fired against exactly the parent set the graph declared for it, under the predicate that fan-in carries. | Terminal receipts |
| Chio Swarm Route Plan Receipt | chio.swarm.route-plan-receipt.v1 | That egress for one task was pinned to a chosen route, bridge, and target before dispatch, under the single egress constraint the protocol defines. | Route plans |
| Chio Swarm Budget Pool | chio.swarm.budget-pool.v1 | What each task may spend and what it has already spent, in a per-task rollup that must balance and a total the tasks together may not exceed. A market purchase names the pool by the digest of its projection rather than by the pool JSON. | Budgets |
| Chio Swarm Revocation Epoch | chio.swarm.revocation-epoch.v1 | The block list the whole bundle was checked against, hashed over its own contents so the list cannot be widened after signing. | Revocation epochs |
| Chio Swarm Terminal Graph Receipt | chio.swarm.terminal-graph-receipt.v1 | That the graph closed over exactly the task set, the fan-in set, and the route set it declared, with a final spend rollup that reconciles against the pool. | Terminal receipts |
| Chio Swarm Authority Verifier Report | chio.swarm.authority-verifier-report.v1 | The accepted verdict, one entry per delegating hop, and the claim ids for the checks that ran. | Swarm authority |
An accepted report carries claim ids drawn from a closed set of 8, declared as constants in crates/kernel/chio-swarm-authority/src/types.rs: claim.swarm.task_graph_bound, claim.swarm.continuation_fresh, claim.swarm.attenuation_witness_chain_bound, claim.swarm.route_plan_bound, claim.swarm.join_receipt_bound, claim.swarm.budget_pool_bound, claim.swarm.revocation_epoch_bound, and claim.swarm.terminal_graph_receipt_bound. All but one appear on every acceptance. A graph with no fan-in in it carries no fan-in receipt, so its report omits claim.swarm.join_receipt_bound.
Verification order
A verifier runs these steps in this order. Any failing step rejects the bundle immediately and produces no partial report.
- Reject if the trusted witness issuer key set is empty, before any artifact is read.
- Validate task-graph shape, then its signature.
- Require at least one continuation token and one witness chain.
- Validate and index route plan receipts, then join receipts, then the budget pool, then the revocation epoch, in that order.
- Validate terminal graph receipts against the task, route, fan-in, and budget indexes.
- Validate continuation tokens against the task graph canonical sha256, witness chains, routes, budget allocations, and the revocation epoch.
- Validate that witness chains cover every task-graph hop exactly once, with continuous scope hashes and capability digests hop to hop.
- Assemble the verifier report: one hop report per continuation-bearing task, plus the claim ids for the checks that ran.
Step 4 is not uniform in how it binds. Route plan receipts, join receipts, and the revocation epoch each carry an issuer and a signature, and a verifier checks the signature against a pinned key. The budget pool carries neither. It binds to the bundle through the signed graph, which names the graph the pool must belong to and the pool identifier itself, and through the allocations the continuation tokens draw on. A caller who trusts a pool because it looks signed has misread the artifact.
Invariants
Schema conformance does not make a delegation graph admissible. The structural rules below are checked in code, and a bundle that breaks any one of them is rejected whole.
- Single root. A task graph MUST contain exactly one task at root depth, that task MUST have no parent, and every task below root depth MUST name one. Checked by
validate_roots. - Acyclic. The graph MUST be acyclic. A verifier walks it depth first and rejects on re-entry to a task already on the current path. Checked by
validate_acyclicandvisit_task. - Exact depth arithmetic. Every hop target MUST sit at exactly the source depth plus one. Depth overflow MUST reject instead of wrapping. Checked by
validate_edge_depths, and stated inspec/PROTOCOL.mdsection 6.4.2. - Signed ceilings, enforced graph-wide. The depth ceiling and the fan-out ceiling MUST sit inside the signed body, so widening either one requires a fresh signature from a pinned key. A verifier MUST enforce both across the whole graph: any task deeper than the depth ceiling rejects the bundle, and so does any task with more outgoing hops than the fan-out ceiling. The fan-out ceiling MUST be positive. Checked by
validate_graph_limits. - Exactly one parent context per hop. Each continuation token MUST name either a direct parent task or a fan-in receipt. Naming both rejects. Naming neither rejects. Checked by
validate_continuation_parent. - Witness coverage exactly once per hop. Every hop in the graph MUST be covered by exactly one witness chain. A missing chain rejects and a duplicate chain rejects. Every chain MUST terminate on a hop the graph actually declares. Checked by
validate_witness_chainsincrates/kernel/chio-swarm-authority/src/verifier/witness.rs. - Budget balance and budget ceiling. Each allocation's own five-way unit rollup MUST equal its ceiling exactly, and arithmetic overflow MUST reject instead of clamping. The allocation ceilings summed MUST NOT exceed the pool total. A terminal receipt's per-dimension rollup MUST equal the sum over allocations exactly, and its total MUST NOT exceed the pool total. Checked by
validate_budget_allocation_units,validate_budget_pool, andvalidate_terminal_budget_rollups. A cognition-marketpool_sha256MUST hash the RFC 8785 canonical bytes of thechio.swarm.budget-pool-digest-projection.v1preimage rather than the wire serialization of the pool. That preimage carries the projection identifier, the source pool schema, the pool id, graph id, and currency, and the allocations in their original order; the pool total and every allocation unit field MUST be the shortest unsigned base-10 string, with0as the only representation carrying a leading zero. Built byswarm_budget_pool_digest_projection_bytesand hashed byswarm_budget_pool_sha256incrates/kernel/chio-swarm-authority/src/finding_pool.rs. - Closed egress constraint set. A route plan receipt MUST carry a non-empty, duplicate-free constraint list, and every entry MUST be
deny-private-network. That is the whole set: any other string rejects the bundle as an unsupported constraint, and the schemaenumlists the same one value. Checked byvalidate_route_plan_egress_constraintsatcrates/kernel/chio-swarm-authority/src/verifier.rs:979, and mirrored inspec/schemas/chio-swarm/v1/route-plan-receipt.schema.json:70. Route plans carries the rest of the receipt.
Run it
The crate ships one runnable bundle. examples/agent_os.rs mints a three-task incident graph, signs every artifact with keys it generates in process, verifies the bundle, and then re-verifies four tampered copies of it.
$ cargo run -p chio-swarm-authority --example agent_oschio swarm authority · one task graph, verified before any child runs task graph swarm-incident-42 orchestrator depth 0 scope 6ab7b09faf2a route - budget holds the pool researcher depth 1 scope c5a04ca641ec route route-researcher budget 2500 of 10000 units writer depth 1 scope c5a04ca641ec route route-writer budget 2500 of 10000 units join researcher + writer -> orchestrator (all_success) verdict verified (3 tasks, 2 continuations, 1 joins, 2 routes) researcher continuation continuation-researcher witness witness-researcher (1 hop) writer continuation continuation-writer witness witness-writer (1 hop) claims claim.swarm.task_graph_bound, claim.swarm.continuation_fresh, claim.swarm.attenuation_witness_chain_bound, claim.swarm.route_plan_bound, claim.swarm.join_receipt_bound, claim.swarm.budget_pool_bound, claim.swarm.revocation_epoch_bound, claim.swarm.terminal_graph_receipt_bound then someone tries to add an edge from the writer back to the orchestrator rejected: swarm task graph cycle at task-orchestrator hide a hop by understating the writer's depth rejected: swarm task depth mismatch: task-researcher -> task-writer allocate 5,000 units out of a 100 unit pool rejected: swarm budget allocations exceed pool total run the researcher after its task was revoked rejected: swarm task is revoked: task-researcher
crates/kernel/chio-swarm-authority/examples/agent_os.rsat fe56570The checked-in fixtures verify the same way through the CLI. The proof doctor loads one valid bundle and the negative bundles beside it, and reports whether each was rejected for the reason its fixture pins, which is a different check from rejecting at all.
$ source scripts/proof-room-quickstart-env.sh
$ chio proof doctor --scenario swarm-authority --root .chio proof doctor swarm-authority [passed] swarm_recursive_delegation: transaction passport verified [passed] swarm_stale_continuation: transaction passport rejected [passed] swarm_budget_allocations_exceed_pool: transaction passport rejected [passed] swarm_graph_cycle: transaction passport rejected [passed] swarm_join_parent_set_mismatch: transaction passport rejected [passed] swarm_replayed_continuation_nonce: transaction passport rejected [passed] swarm_revoked_task: transaction passport rejected [passed] swarm_stale_route_plan: transaction passport rejected [passed] swarm_route_plan_mismatch: transaction passport rejected [passed] swarm_witness_child_scope_mismatch: transaction passport rejected verdict: passed
fixtures/proof-room/swarm-authority/at fe56570The refusals in that output are the verifier's own sentences. Swarm denial codes indexes every one of them back to the check that produced it, and the 11 signed negative bundles under fixtures/proof-room/swarm-authority/ replay the same refusals through chio proof verify.
Guarantees and limits
| Status | Claim | Evidence |
|---|---|---|
| Shipped | One function decides admission. The runtime admission hook, the proof room, and the CLI proof path all call it, so the workspace holds one definition of acceptance. | verify_swarm_authority_bundle, crates/kernel/chio-runtime-core/src/admission_hook/swarm_authority.rs, crates/products/chio-proof-room/src/source_verifier.rs |
| Shipped | Acceptance is whole or absent. Any failing check returns immediately, and the report shape pins a single verdict value, so a partial report has no representation. | spec/schemas/chio-swarm/v1/authority-verifier-report.schema.json |
| Shipped | An empty trusted key set rejects the bundle before any artifact is read. Fail-closed is the first step of the check order. | require_trusted_witness_issuer_keys |
| Shipped | A well formed graph with no delegation in it never verifies. A bundle carrying no continuation token, or no witness chain, is refused. | require_signed_swarm_delegation_evidence |
| Proved by test | A back hop from a child to the root rejects as a cycle. The same case is frozen as a signed negative fixture and bound to a claim id. | swarm_authority_stage0_rejects_graph_cycle, fixtures/proof-room/swarm-authority/graph-cycle/, claim.swarm.task_graph_bound |
| Proved by test | A stale continuation token rejects, and so does a second token reusing a nonce. Two negative fixtures back one claim id. | fixtures/proof-room/swarm-authority/stale-continuation/, fixtures/proof-room/swarm-authority/replayed-continuation-nonce/, claim.swarm.continuation_fresh |
| Proved by test | A child scope that does not match the scope the graph signed rejects the chain. | swarm_authority_stage0_rejects_witness_child_scope_mismatch, fixtures/proof-room/swarm-authority/witness-child-scope-mismatch/, claim.swarm.attenuation_witness_chain_bound |
| Proved by test | A stale route plan receipt rejects, and so does one naming a constraint outside the closed set. | fixtures/proof-room/swarm-authority/stale-route-plan/, fixtures/proof-room/swarm-authority/egress-constraint-unsupported/, claim.swarm.route_plan_bound |
| Proved by test | A fan-in that omits a parent the graph declared for it rejects. | swarm_authority_stage0_rejects_join_parent_set_mismatch, fixtures/proof-room/swarm-authority/join-parent-set-mismatch/, claim.swarm.join_receipt_bound |
| Proved by test | Allocations that outrun the pool total reject, and so does a terminal rollup that fails to reconcile against them. | swarm_authority_stage0_rejects_budget_allocations_exceeding_pool, swarm_authority_stage0_rejects_terminal_budget_rollup_mismatch, fixtures/proof-room/swarm-authority/budget-allocations-exceed-pool/, claim.swarm.budget_pool_bound |
| Proved by test | A revocation epoch naming a task the bundle carries rejects the whole bundle, and so does one naming a subject the bundle's authority rests on. | swarm_authority_stage0_rejects_revoked_task, swarm_authority_stage0_rejects_revoked_authority_subject, fixtures/proof-room/swarm-authority/revoked-task/, claim.swarm.revocation_epoch_bound |
| Proved by test | Widening a ceiling and re-sealing every downstream token against the new graph digest does not rescue the bundle. | swarm_authority_stage0_rejects_task_graph_tampering_after_continuations_are_resealed |
| Proved by test | The signed positive fixture verifies. The randomized conformance test then mutates that bundle case by case and asserts the rejection message each mutation is expected to produce. | crates/tooling/chio-conformance/tests/r_t03_recursive_swarm_conformance.rs:132-138, fixtures/proof-room/swarm-authority/valid-recursive-delegation/ |
| Spec | The protocol text states the same admission binding, the same two ceilings, and the same depth arithmetic. Code and text agree, and the text is the contract a third-party implementation is held to. | spec/PROTOCOL.md section 6.4.2 |
| Bounded | The verifier refuses with English sentences. Its error type carries two variants over free-form text, so a caller matches on prose instead of on a registry code. | SwarmAuthorityError, crates/kernel/chio-swarm-authority/src/error.rs |
| Bounded | Verification is the specified surface. Issuance is a separate contract, and the minting and signing helpers in this crate serve fixtures, examples, and tests. | crates/kernel/chio-swarm-authority/ARCHITECTURE.md |
| Bounded | The budget pool is the one artifact in the bundle with no issuer and no signature of its own. It binds through the signed graph that names it. | validate_budget_pool, SwarmBudgetPool |
| Not claimed | That schema validation happens. The nine schemas are hash-pinned and closed to unknown fields, and no crate loads them. The verifier is the enforcement, and the schemas are the published shape. | spec/schemas/MANIFEST.sha256, crates/kernel/chio-swarm-authority/src/verifier.rs |
| Not claimed | That every structural rule carries a regression test. The single-root rule, the fan-out ceiling, hop coverage, and the both-or-neither parent branches are enforced in code with no test asserting their refusal message. | validate_roots, validate_graph_limits, validate_witness_chains, validate_continuation_parent |
| Not claimed | That every rule carries a negative fixture. 12 scenarios ship, 11 of them negatives. Three of those negatives carry no claim binding, and the terminal-receipt claim has no negative fixture bound to it. | crates/core/chio-core-types/tests/claim_registry_integrity.rs, claim.swarm.terminal_graph_receipt_bound |
| Not claimed | That the ceilings bound graph size. They bound depth per task and outgoing hops per source. Nothing caps the total task count, so a full tree at both ceilings is well formed and grows exponentially in the depth ceiling. The only quantitative bound on spend is the pool. | validate_graph_limits, validate_budget_pool |
Related
- Swarm Authority · the same verifier as a mechanism, with the runtime admission path around it
- Swarm Denial Codes · every refusal string, and the runtime code that replaces it
- Swarm Overview · the field-level shape of each artifact, one page per family
- Protocol Reference · the single-call protocol a hop sits inside
- Schemas and Errors · the signed-artifact registry these 9 files are listed in