Governance Ladder
Pin each operator’s governance manifest in a treaty, fold the manifests into one contract, and require its evidence at admission.
On this page
Operators that cooperate under a treaty each declare what an action class requires: a governance mode, a co-signature, a consistency model, and the evidence to present. Each kernel folds those declarations into one contract in which the stricter requirement wins.
The Quickstart treaty admits workspace.read, workspace.write, model.invoke, and merge, and both sides declare merge as co-signed. A ladder manifest carries one kernel’s declarations, the treaty pins each participant’s manifest hash, and admission checks the folded contract against the evidence a particular action brings.
Each kernel folds the pinned manifests into one contract
compute_ladder_intersection takes a fresh treaty scope and one fresh manifest per participant, recomputes the manifest hashes, and compares them with the treaty’s pinned hash set. Every allowed class must resolve in every manifest, by canonical id or alias.
One LadderIntersection over 3 action classes.
One LadderIntersection over 3 action classes.
In Rust · treaty.rs:27634 lines
for participant in &treaty_scope.participant_kernel_ids {
// … find this participant's action class
let rank = ladder_mode_rank(&action.mode)?;
if rank > mode_rank {
mode_rank = rank;
mode.clone_from(&action.mode);
}
destructive |= action.destructive;
if let Some(existing) = consistency_model.as_ref() {
if existing != &action.consistency_model {
return rejected(
"chio_federation_ladder_consistency_mismatch",
"governance ladder consistency models do not intersect",
);
}
} else {
consistency_model = Some(action.consistency_model.clone());
}
if co_sign_requirement_rank(&action.co_sign)? > co_sign_requirement_rank(&co_sign)? {
co_sign.clone_from(&action.co_sign);
}
// … merge the co-sign quorum
for item in &action.evidence_required {
evidence_required.insert(item.clone());
}
// … record participant_modes
}
if destructive && mode_rank < ladder_mode_rank("receipt_backed")? {
return rejected(
"chio_federation_ladder_destructive_below_floor",
"intersected destructive action resolves below receipt backed mode",
);
}
// … then the destructive crdt-commutative check
Mode and co-sign requirement take the highest rank, required evidence takes the union, and the consistency model must be identical; any rejection stops the whole computation. The fold supports two or more participants and keeps each participant’s declared mode beside the combined one.
The intersection is a derived contract. Approval sessions, signing ceremonies, and the action itself happen later, each checked against it.
Modes and co-sign requirements combine by rank
Five governance modes rank from observation (0) through guarded, receipt_backed, and partition_contingency to maintenance (4). Four co-sign requirements rank from none (0) through bilateral_if_cross_org and bilateral_required to n_of_m (3). The intersection takes the highest of each.
When several participants declare quorum metadata, m and scope must agree exactly and n takes the maximum. A disagreement is refused with chio_federation_ladder_quorum_misdeclared, so no participant’s roster size or scope is picked silently.
Destructive work has a floor. destructiveFloor sets the minimum mode for a manifest’s destructive actions, and the combined result places any destructive action at receipt_backed or above. Unknown action classes are refused: defaultUnknownMode must be deny, a required value outside the five ranks.
Read more in Mode ranks and Co-sign ranks.
Consistency models must agree exactly
Consistency models carry no rank. Each participant declares crdt-commutative, totally-ordered, single-kernel, or quorum-required for every requested class, and all declarations must match.
One mismatch aborts the whole call with chio_federation_ladder_consistency_mismatch and returns no partial intersection. A contract established before the mismatch stays in force.
A declaration names the model, and the action’s integration implements it. The strict treaty DSSE review compares consistency_anchor with the expected runtime-step evidence and requires the matching binding, and a destructive class may never declare crdt-commutative.
A passport revocation folds to a 2-of-3 quorum with four evidence labels
Extend the Quickstart treaty with credentials.passport_revoke, so either side can revoke the passport of an agent working across the boundary, such as your partner’s fixer-2. You and your partner both mark the class destructive and receipt_backed with quorum-required consistency; the two declarations differ in co-sign requirements and evidence.
| Declaration | coSign | Quorum | Evidence |
|---|---|---|---|
| Your kernel | n_of_m | 2 of 3, treaty | anchor_epoch, passport_presentation |
| Partner kernel | bilateral_required | none declared | anchor_epoch, trust_activation |
| Stored intersection | n_of_m | 2 of 3, treaty | the union of all three labels |
| At admission | n_of_m | 2 of 3, treaty | the union plus quorum_signature |
The extra quorum_signature label comes from required_evidence_for_action at admission and stays out of the stored evidenceRequired list. Every required class must arrive with a verified reference, and the two operators are separate from the three FROST roster participants that sign the quorum.
Had your partner declared totally-ordered, the computation would return chio_federation_ladder_consistency_mismatch. A quorum with a different m or scope returns chio_federation_ladder_quorum_misdeclared.
Admission checks the pinned contract and the evidence a caller brings
A handshake challenge can carry a LadderManifestRef, whose manifest id, digest, and validity window sit inside the challenge bytes the handshake signature covers. The strict bilateral verifier then requires a fresh reference for both peers at its pinned time.
evaluate_cross_boundary_admission checks the scope and intersection windows, the treaty, participant, and hash-vector relationships, the caller’s expected intersection digest, and the requested class. It then derives the required evidence, any co-sign label included, and requires every class to be present and marked verified.
Each evidence reference is built after the artifact’s own verifier has run, and an n_of_m class takes the strict path in FROST Quorum. A refusal returns a report with accepted: false.
Worked Rust example: Sign, pin and evaluate two ladder manifests
Sign, pin and evaluate two ladder manifests
Two operators publish observation and guarded modes for analysis.read. Authenticate each export, pin the manifest hashes in a treaty, compute the intersection and evaluate that named action.
Use the Rust example setup, or download the complete source project. The files below belong to that project; shared constructors and configuration are included in the download.
Run it
cargo run --locked --features federation --bin ladderImplementation
use chio_core_types::{
crypto::{sha256_hex, Keypair},
receipt::lineage::SignedExportEnvelope,
};
use chio_federation::treaty::*;
use swarm_authority_examples::now_ms;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let now = now_ms();
let keys = [Keypair::generate(), Keypair::generate()];
let mut manifests = Vec::new();
for (i, mode) in ["observation", "guarded"].into_iter().enumerate() {
let manifest = GovernanceLadderManifest {
schema: CHIO_FEDERATION_GOVERNANCE_LADDER_MANIFEST_SCHEMA.into(),
manifest_id: format!("operator-{i}-ladder"),
kernel_id: format!("operator-{i}"),
issuer: keys[i].public_key().to_hex(),
key_id: format!("operator-{i}-key"),
issued_at_unix_ms: now - 1000,
expires_at_unix_ms: now + 60000,
destructive_floor: "receipt_backed".into(),
default_unknown_mode: "deny".into(),
action_classes: vec![GovernanceLadderActionClass {
action_class_id: "analysis.read".into(),
mode: mode.into(),
destructive: false,
consistency_model: "single-kernel".into(),
co_sign: "none".into(),
co_sign_quorum: None,
evidence_required: vec![],
aliases: vec!["read".into()],
}],
};
validate_governance_ladder_manifest(&manifest)?;
// The manifest has no signature field. A signed export envelope can
// authenticate distribution; the treaty separately pins the body hash.
let signed = SignedExportEnvelope::sign(manifest.clone(), &keys[i])?;
assert_eq!(signed.signer_key, keys[i].public_key());
assert!(signed.verify_signature()?);
manifests.push(manifest);
}
let scope = TreatyScope {
schema: CHIO_FEDERATION_TREATY_SCOPE_SCHEMA.into(),
treaty_id: "analysis-treaty".into(),
participant_kernel_ids: manifests.iter().map(|m| m.kernel_id.clone()).collect(),
participant_public_keys: keys.iter().map(Keypair::public_key).collect(),
ladder_manifest_sha256s: manifests
.iter()
.map(governance_ladder_manifest_sha256)
.collect::<Result<_, _>>()?,
allowed_action_classes: vec!["analysis.read".into()],
issued_at_unix_ms: now - 1000,
expires_at_unix_ms: now + 60000,
revocation_epoch_sha256: sha256_hex(b"local revocation snapshot"),
trust_bundle_sha256: sha256_hex(b"local two-operator trust configuration"),
};
let intersection = compute_ladder_intersection(&scope, &manifests, now)?;
let report = evaluate_cross_boundary_admission(CrossBoundaryAdmissionInput {
treaty_scope: &scope,
ladder_intersection: &intersection,
expected_ladder_intersection_sha256: Some(ladder_intersection_sha256(&intersection)?),
action_class_id: "analysis.read",
present_evidence: vec![],
verified_evidence: vec![],
now_unix_ms: now,
})?;
println!(
"analysis.read: mode {}, accepted {}",
report.mode, report.accepted
);
assert!(report.accepted);
manifests[0].action_classes[0].mode = "maintenance".into();
println!(
"changed pinned manifest: {}",
compute_ladder_intersection(&scope, &manifests, now)
.expect_err("changed manifest must not match treaty pin")
);
Ok(())
}Captured result and refusal
analysis.read: mode guarded, accepted true
changed pinned manifest: federation treaty rejected: chio_federation_ladder_manifest_hash_mismatch: computed ladder manifest hashes do not match treaty scopeChanging a manifest after pinning refuses the intersection. The signed export authenticates distribution; the manifest body itself has no signature field. These local trust inputs are not a completed peer-establishment ceremony.
Exit 0 indicates a successful example run. Expected refusals shown in the output are checked by the program; invalid command inputs exit nonzero. Keys, digests, timestamps and run-directory names vary.
The downloadable project has two operators publish observation and guarded for analysis.read, pins both manifest hashes, and admits the action at guarded. Changing a manifest after pinning refuses the intersection with chio_federation_ladder_manifest_hash_mismatch.
Ladder fields, rules, and refusal codes
Try coSignQuorum, partition_contingency, or a failure code.
Mode ranks
| Mode | Rank | Design intent |
|---|---|---|
observation | 0 | Observe, investigate, or publish signals. |
guarded | 1 | Perform constrained, non-destructive work. |
receipt_backed | 2 | Require evidence for consequential commitments and state changes. |
partition_ | 3 | Represent a declared contingency path during a partition. |
maintenance | 4 | Represent work controlled by an authenticated operator. |
The names state the ladder’s design intent. The intersection implements rank selection and the structural rules, while the action’s declared evidence and its execution integration supply the operational controls: an operator is authenticated, and a contingency lease issued, by their own mechanisms.
Action class fields
| Wire field | Meaning and requirement |
|---|---|
actionClassId | Required. A nonempty class id. It must be unique within the manifest. |
mode | Required. One of the five canonical governance modes. |
destructive | Required boolean. Classification is explicit; the class name does not determine this flag. |
consistency | Required. One of the four canonical consistency models. |
coSign | Required. The co-signing requirement described below. |
coSignQuorum | Required for n_of_m and forbidden otherwise. Contains n, m, and scope. |
evidence | Required list of unique lowercase letters, digits, and underscore labels. Destructive actions require a nonempty list. |
aliases | Defaults to an empty list. Each alias is nonempty and must not collide with another alias or canonical class id. |
The wire object rejects unknown fields. Six fields are always required; aliases may be omitted and coSignQuorum is conditional. The general ladder requires 2 ≤ n ≤ m and a quorum scope of treaty, kernel, or operator, and an enabled FROST action must also match its narrower registered quorum contract.
Aliases map a treaty’s requested class to a local declaration. The intersection keeps the class id the treaty requested, and the local class’s requirements still apply in full.
Co-sign ranks
| coSign | Rank | Admission evidence added by this helper |
|---|---|---|
none | 0 | No additional label. |
bilateral_ | 1 | No additional label in required_ |
bilateral_ | 2 | bilateral_ |
n_of_m | 3 | quorum_ |
The extra evidence label is derived from the resulting coSign value at admission and is never appended to the stored intersection’s evidenceRequired list.
Consistency declarations
crdt-commutative. Operations with the required commutative merge behavior. Refused for a destructive class.totally-ordered. The integration supplies and enforces the ordering mechanism the invocation is bound to.single-kernel. The action stays under the declared single-kernel consistency boundary.quorum-required. The integration supplies the required threshold authorization and its current authority checks.
Intersection rules
mode. The highest declared mode rank.destructive. True if any participant marks the action destructive.consistencyModel. Exact agreement across participants.coSign. The highest declared co-sign rank.coSignQuorum. The maximum n; every declared m and scope must match.evidenceRequired. The sorted, deduplicated union of the declared labels.participantModes. Each kernel id mapped to its original mode.
The intersection expires at the earliest expiry of the scope or any manifest. Its intersectionId combines the treaty id and the supplied generation time, so its canonical hash identifies one computed record, time included. It carries participant ids and manifest hashes and no co-signature field, so its inputs and expected hash are established through the surrounding trust process.
Manifest wire format
A manifest binds a kernel id, issuer and key id, validity window, destructive floor, deny-by-default behavior, and action declarations. The published camelCase JSON Schema matches the Rust wire type. This example follows the public treaty test fixture at its fixed evaluation time:
{
"schema": "chio.federation.governance-ladder-manifest.v1",
"manifestId": "ladder-kernel.vendor",
"kernelId": "kernel.vendor",
"issuer": "did:chio:kernel.vendor",
"keyId": "ladder-key-1",
"issuedAtUnixMs": 1800000000000,
"expiresAtUnixMs": 1800003600000,
"destructiveFloor": "receipt_backed",
"defaultUnknownMode": "deny",
"actionClasses": [{
"actionClassId": "workflow.destructive.vendor_call",
"mode": "receipt_backed",
"destructive": false,
"consistencyModel": "totally-ordered",
"coSign": "bilateral_required",
"evidenceRequired": ["receipt_lineage"],
"aliases": []
}]
}The source test computes its intersection at 1800000001000 and evaluates admission at 1800000002000, inside the fixture’s window. With no evidence supplied, admission returns chio_federation_treaty_missing_required_evidence. The action’s destructive flag is false despite the word in its id, because the explicit flag controls classification.
Specification document shape
The embedded schema in CHIO_LADDER.md uses the same manifest identifier for a different snake_case shape that includes an embedded signature object. Integrations use the published governance-ladder-manifest.schema.json and the Rust wire type, and deserialization refuses the keys that belong only to the document shape.
The wire manifest body has no signature property; its issuer and keyId fields are declarations. A signed export authenticates distribution, and the handshake authenticates the manifest’s reference, digest included.
Manifest reference
manifestId. Nonempty after trimming whitespace.sha256. 64 hexadecimal characters; this reference validator accepts either letter case.issuedAtUnixMs. Start of the validity interval, inclusive.expiresAtUnixMs. End of the interval, exclusive, and strictly after issuance.
The canonicalization helper validates the reference before signing. The strict bilateral verifier reports a missing or expired reference as ladder.manifest_missing or ladder.manifest_stale. That check tests freshness only: fetching the manifest, recomputing its contents, and checking any signature over it happen when the pin is established.
The public three-vendor proof package retains four peerLadderBindings, for the buyer and three vendors. Each reference spans 1765999940000 through 1766000060000, a two-minute interval around the fixture’s generatedAtUnixMs value 1766000000000; these are retained fixture times.
Admission refusals
CrossBoundaryEvidenceRef carries evidenceClass, artifactSha256, and verified. The admission helper reads these references as supplied, so the expected contract and verified evidence are established in a trusted integration before it runs.
| Failure code | Inspect |
|---|---|
chio_ | The evaluation time against both validity windows. |
chio_ | The required expected intersection hash. |
chio_ | The hash, treaty id, participant vector, and manifest-hash vector. |
chio_ | The class in both scope and intersection. |
chio_ | Presence of every derived required evidence class. |
chio_ | The supplied verified reference for each required class. |
These refusals return a report with accepted: false; malformed scope or intersection inputs return an error before a report exists. A report records this check, and the action and its external effect leave their own receipts.
Quorum binding
The strict bilateral n_of_m path requires a separately verified FROST authorization, a treaty binding, quorum-required consistency, and the exact frost-quorum anchor. It matches the authorization’s action class, treaty scope, invocation resource id, and validity at the pinned time.
FROST authority supplied for an ordinary bilateral mode is refused. The binding step compares identifiers; the typed action digest and the current resource version and fence are checked by FROST Quorum verification and the effect path.
Runtime vocabulary aliases
The federation and runtime wire types share the action-class fields and defaults. The federation validator accepts the canonical spellings, and runtime helpers also normalize these aliases:
consistencyModel.crdt_commutative,totally_ordered,single_kernel, andquorum_requirednormalize to the four hyphenated names.coSign.quorum_requirednormalizes ton_of_m.mode.quorum_requiredis accepted at rank 4 alongsidemaintenance; this rank alias is not a portable canonical mode.
Runtime intersection normalizes consistency and co-sign values before combining them, and incoming DSSE paths may accept only canonical names. Emit canonical mode names, hyphenated consistency models, and the four canonical co-sign values at shared boundaries.
Workflow action classes
The reference authority’s trust-bundle builder requires workflow.grant_issue and workflow.aggregate_publish, which classify issuance of the workflow grant and publication of its aggregate evidence, separately from the classes inside a treaty intersection.
The buyer verifier’s action map uses routine or receipt_backed to decide whether governance evidence is required. That two-kind map serves its own purpose and carries none of the five-rank ordering.
Manifest validation diagnostics
The federation validator returns the first failure, with a code and a detail that locate the malformed declaration. A valid manifest can still fail a later intersection or admission check.
| Code | Condition |
|---|---|
unsupported_ | The schema identifier is unsupported. |
governance_ | manifestId is empty or whitespace. |
governance_ | kernelId is empty or whitespace. |
governance_ | issuer is empty or whitespace. |
governance_ | keyId is empty or whitespace. |
governance_ | Issuance is at or after expiry. |
governance_ | default |
governance_ | No action classes are declared. |
governance_ | An actionClassId is empty or whitespace. |
chio_ | A canonical action-class id appears twice. |
chio_ | An alias repeats or collides with a canonical class id. |
chio_ | A class mode or destructive |
chio_ | consistency |
chio_ | coSign is outside the canonical vocabulary. |
chio_ | Conditional presence, n/m bounds, or scope is invalid. |
chio_ | A destructive class’s mode is below its manifest’s floor. |
chio_ | A destructive class declares crdt- |
governance_ | A destructive class declares no required evidence. |
governance_ | A label is empty or contains characters outside lowercase letters, digits, and underscore. |
governance_ | An evidence label appears twice in one class. |
governance_ | An alias is empty or whitespace. |