EconomyOperations & Governance
Governance Charters and Cases
Signed charters and cases for registry listings, evaluated into an effective state and admission decision.
Charter and Case Records
Both record types scope to a namespace and a governing operator, and both reference a listing identity from chio-listing. A charter is issued once and authorizes a set of case kinds; cases are issued against individual listings under that charter.
| Record type | Schema tag | Purpose |
|---|---|---|
GenericGovernanceCharterArtifact | chio.registry.governance-charter.v1 | Grants a governing operator authority over a namespace and the case kinds it may open. |
GenericGovernanceCaseArtifact | chio.registry.governance-case.v1 | Records one dispute, freeze, sanction, or appeal against a single listing under a charter. |
Each record is wrapped in a SignedExportEnvelope<T> containing the body, an Ed25519 signer key, and a signature over the RFC 8785 canonical JSON body. The aliases are SignedGenericGovernanceCharter and SignedGenericGovernanceCase. The crate is re-exported by chio-core and chio-open-market as governance.
The charters on this page govern registry listings: their dispute, freeze, sanction, and appeal lifecycle. The economic parameters an economy runs on, credit tiers, discount curves, premium schedules, fees, and bonds, are governed by a separate, specialized charter family whose amendments move through a propose, m-of-n approval, timelock, then activate lifecycle before they take effect. That fiscal system is documented in Fiscal Constitutions.
The Charter
A charter names the governing operator, the namespace it covers, the case kinds it may open, and an optional set of escalation operators. Its authority_scope can pin the charter to specific listing publishers and actor kinds; an empty list on either field means the scope is unrestricted on that axis.
pub const GENERIC_GOVERNANCE_CHARTER_ARTIFACT_SCHEMA: &str =
"chio.registry.governance-charter.v1";
pub struct GenericGovernanceCharterArtifact {
pub schema: String, // chio.registry.governance-charter.v1
pub charter_id: String, // "charter-{sha256}", derived by the builder
pub governing_operator_id: String,
pub governing_operator_name: Option<String>,
pub authority_scope: GenericGovernanceAuthorityScope,
pub allowed_case_kinds: Vec<GenericGovernanceCaseKind>,
pub escalation_operator_ids: Vec<String>, // operators a case may be escalated to
pub issued_at: u64,
pub expires_at: Option<u64>, // must be greater than issued_at
pub issued_by: String,
pub note: Option<String>,
}
pub struct GenericGovernanceAuthorityScope {
pub namespace: String,
pub allowed_listing_operator_ids: Vec<String>, // empty = any publisher
pub allowed_actor_kinds: Vec<GenericListingActorKind>, // empty = any actor kind
pub policy_reference: Option<String>,
}allowed_case_kinds must be non-empty, and a validated charter with an expires_at requires it to be strictly greater than issued_at. The builder derives the identifier as a content hash so the same inputs always yield the same charter id:
pub fn build_generic_governance_charter_artifact(
local_operator_id: &str,
local_operator_name: Option<String>,
request: &GenericGovernanceCharterIssueRequest,
issued_at: u64,
) -> Result<GenericGovernanceCharterArtifact, String>;
// charter_id = "charter-" + sha256_hex(canonical_json_bytes((
// local_operator_id,
// normalize_namespace(namespace),
// allowed_case_kinds,
// issued_at,
// )))The builder returns an unsigned body; the governing operator signs it with a governance-authority keypair issued through chio-federation-authority:
let charter = build_generic_governance_charter_artifact(
"origin-a",
Some("Origin A".to_string()),
&request,
130,
)?;
let signed = SignedGenericGovernanceCharter::sign(charter, &authority_keypair)?;The Case
A case binds a charter to one listing and carries the case kind, its lifecycle state, at least one evidence reference, and optional links to a prior case for appeals and supersession.
pub const GENERIC_GOVERNANCE_CASE_ARTIFACT_SCHEMA: &str =
"chio.registry.governance-case.v1";
pub struct GenericGovernanceCaseArtifact {
pub schema: String, // chio.registry.governance-case.v1
pub case_id: String, // "case-{sha256}", derived by the builder
pub charter_id: String,
pub governing_operator_id: String,
pub kind: GenericGovernanceCaseKind, // dispute | freeze | sanction | appeal
pub state: GenericGovernanceCaseState, // open | escalated | enforced |
// resolved | denied | superseded
pub namespace: String,
pub listing_id: String,
pub activation_id: Option<String>, // required for freeze / sanction
pub subject_operator_id: Option<String>,
pub opened_at: u64,
pub updated_at: u64, // must be >= opened_at
pub expires_at: Option<u64>, // must be greater than opened_at
pub escalated_to_operator_ids: Vec<String>, // required when state = escalated
pub evidence_refs: Vec<GenericGovernanceEvidenceReference>, // must be non-empty
pub appeal_of_case_id: Option<String>, // required for, and only valid on, appeals
pub supersedes_case_id: Option<String>,
pub issued_by: String,
pub note: Option<String>,
}
pub struct GenericGovernanceEvidenceReference {
pub kind: GenericGovernanceEvidenceKind, // listing | trust_activation | certification |
// registry_search | operator_report | external
pub reference_id: String,
pub uri: Option<String>,
pub sha256: Option<String>, // 64-char hex digest when present
}Body validation enforces the shape independently of any evaluation context: the schema must match, evidence_refs must be non-empty, an appeal must carry appeal_of_case_id (and no other kind may), and an escalated case must list at least one escalated_to_operator_ids.
The case builder verifies the signatures on the charter, listing, and (when present) trust activation before minting the body, and it refuses a case whose charter is governed by a different operator, or whose trust activation was issued by anyone other than the governing operator:
pub fn build_generic_governance_case_artifact(
local_operator_id: &str,
request: &GenericGovernanceCaseIssueRequest,
issued_at: u64,
) -> Result<GenericGovernanceCaseArtifact, String>;
// case_id = "case-" + sha256_hex(canonical_json_bytes((
// local_operator_id, charter_id, listing_id,
// kind, state, opened_at,
// appeal_of_case_id, supersedes_case_id,
// )))Case Kinds
Four kinds cover the adjudication lifecycle. A charter must list a kind in allowed_case_kinds before a case of that kind evaluates.
| Kind | Active effective state | Can block admission | Extra requirement |
|---|---|---|---|
dispute | disputed | No | — |
freeze | frozen | Yes, when enforced | Matching trust activation from the governing operator |
sanction | sanctioned | Yes, when enforced | Matching trust activation from the governing operator |
appeal | appealed | No | appeal_of_case_id plus a matching non-appeal prior_case |
Effective State and Admission
Evaluation resolves a case to a GenericGovernanceEffectiveState (one of clear, disputed, frozen, sanctioned, appealed) and a boolean blocks_admission. The mapping is driven by the case lifecycle state and kind together.
| Case state | Effective state | Blocks admission |
|---|---|---|
resolved, denied, superseded | clear | No, for every kind |
open, escalated | Mirrors the kind (disputed / frozen / sanctioned / appealed) | No, for every kind |
enforced | Mirrors the kind | Only freeze and sanction |
One rule blocks admission
blocks_admission = true: an enforced case whose kind is freeze or sanction. A dispute or appeal never blocks, and a resolved, denied, or superseded case resolves to clear regardless of kind. The relying party consumes blocks_admission as the gate; the effective state is the human-readable status.Case Evaluation
evaluate_generic_governance_case takes the current listing, the current publisher, the charter, the case, and optionally a trust activation and a prior case. It returns a GenericGovernanceCaseEvaluation.
pub fn evaluate_generic_governance_case(
request: &GenericGovernanceCaseEvaluationRequest,
now: u64,
) -> Result<GenericGovernanceCaseEvaluation, String>;
pub struct GenericGovernanceCaseEvaluationRequest {
pub listing: SignedGenericListing,
pub current_publisher: GenericRegistryPublisher,
pub activation: Option<SignedGenericTrustActivation>,
pub charter: SignedGenericGovernanceCharter,
pub case: SignedGenericGovernanceCase,
pub prior_case: Option<SignedGenericGovernanceCase>,
pub evaluated_at: Option<u64>, // defaults to now
}
pub struct GenericGovernanceCaseEvaluation {
pub listing_id: String,
pub namespace: String,
pub charter_id: String,
pub case_id: String,
pub governing_operator_id: String,
pub kind: GenericGovernanceCaseKind,
pub state: GenericGovernanceCaseState,
pub effective_state: GenericGovernanceEffectiveState,
pub evaluated_at: u64,
pub blocks_admission: bool,
pub findings: Vec<GenericGovernanceFinding>,
}Evaluation is ordered. The first failure ends evaluation and returns a finding without an Err:
- Validate the listing body and the
current_publishershape. These are the only hardErrpaths, alongside an internal crypto or canonicalization error. - Verify the signature and body of the listing, charter, and case, and of the activation and prior case when present.
- If an activation is present, its
local_operator_idmust equal the charter'sgoverning_operator_id. - Charter, case, and listing must agree on governing operator, charter id, namespace, and listing id.
- Neither the charter nor the case may be expired as of
evaluated_at; expiry is exclusive at the boundary (expires_at <= evaluated_atis rejected). - The charter must allow the case's kind and, where its scope is set, admit the current publisher operator id and the listing subject actor kind.
- A
freezeorsanctioncase requires a trust activation whoseactivation_idmatches the case; a superseding case requires a matchingprior_case; an appeal requires a matching non-appealprior_case. - On success, the case state and kind map to an effective state and the
blocks_admissionflag, and the evaluation carries an emptyfindingslist.
Failure handling
Ok evaluation carrying a single finding, with effective_state = clear and blocks_admission = false — an unverifiable or malformed case does not block admission, and the finding explains why. Only an internal crypto or canonicalization error returns Err(String). A clear result on a failed case means "could not enforce".Finding Codes
When evaluation short-circuits it emits one GenericGovernanceFinding with a typed code and a human-readable message. The codes:
| Code | Meaning |
|---|---|
ListingUnverifiable | Listing signature or body failed verification |
ActivationUnverifiable | Trust activation signature or body failed verification |
CharterUnverifiable | Charter signature or body failed verification |
CaseUnverifiable | Case signature or body failed verification |
PriorCaseUnverifiable | Referenced prior case signature or body failed verification |
CharterExpired | Charter expires_at reached as of evaluation |
CaseExpired | Case expires_at reached as of evaluation |
CharterScopeMismatch | Current publisher or listing actor kind falls outside the charter scope |
CharterKindUnsupported | Charter does not authorize this case kind |
CaseMismatch | Charter or case does not match the current listing identity or namespace |
MissingActivation | A freeze or sanction case was submitted without a trust activation |
ActivationMismatch | Activation was not issued by the governing operator, or its id does not match the case |
AppealTargetMissing | Appeal is missing appeal_of_case_id or its prior_case |
AppealTargetInvalid | Appeal target does not match a valid, non-appeal prior case |
SupersessionTargetMissing | Superseding case is missing its prior_case |
SupersessionTargetInvalid | Supersession target does not match the referenced prior case |
Worked Example: An Enforced Freeze
Operator origin-a governs the namespace https://registry.chio.example under a charter that allows all four case kinds. It freezes listing listing-artifact-1 and signs the case, referencing a trust activation it also issued. On the wire the case envelope uses camelCase fields and snake_case enum values:
{
"body": {
"schema": "chio.registry.governance-case.v1",
"caseId": "case-6f2a9c...",
"charterId": "charter-1d4b0e...",
"governingOperatorId": "origin-a",
"kind": "freeze",
"state": "enforced",
"namespace": "https://registry.chio.example",
"listingId": "listing-artifact-1",
"activationId": "activation-8c71...",
"subjectOperatorId": "origin-a",
"openedAt": 140,
"updatedAt": 140,
"expiresAt": 500,
"evidenceRefs": [
{ "kind": "trust_activation", "referenceId": "activation-8c71..." }
],
"issuedBy": "governance@chio.example",
"note": "freeze"
},
"signerKey": "9f2c1a...",
"signature": "b0e4d7..."
}A relying party evaluates it against the live listing at now = 150:
let evaluation = evaluate_generic_governance_case(
&GenericGovernanceCaseEvaluationRequest {
listing,
current_publisher,
activation: Some(activation),
charter,
case,
prior_case: None,
evaluated_at: Some(150),
},
150,
)?;
assert!(evaluation.findings.is_empty());
assert_eq!(evaluation.effective_state, GenericGovernanceEffectiveState::Frozen);
assert!(evaluation.blocks_admission);Drop the activation from the request and the same case resolves to a single MissingActivation finding with blocks_admission = false: a freeze the crate cannot substantiate does not silently take effect. Move the case to resolved and the effective state becomes clear with no block, which is how a lifted freeze reads.
Leases and Receipts in the Same Crate
chio-governance defines charter and case records plus two other record groups. The other groups govern action authority instead of listing status and use the same signature and schema checks:
- Capability leases (
chio.capability-lease.v1) carry an action class —ScopedObservation,DelegatedAction, orNarrowDestructive— and a scope digest.verify_capability_leasechecks schema, signature, the validity window, and an exactscope_digestmatch. - Destructive-action governance receipts (
chio.governance-receipt.v1) authorize a single destructive workflow step.verify_destructive_authorizationbinds a receipt to an expected lease id, workflow id, and step hash, andverify_step_governance_boundaryrequires a valid, unexpired receipt for any step marked destructive and none otherwise.
See Capabilities for the scoped, time-bounded authority these leases attenuate, and Mandates & Capabilities for how the kernel enforces a destructive-step boundary at runtime.
Related Reading
- Capability Discovery · the
chio-listingmarketplace module whose listing identity a case references - Operating an Economy · how an operator wires governance authority into a running economy
- Trust Model · the admission and trust-activation decisions a governance case gates
- Compliance Certificates · the session-scoped attestation that shares this crate's canonical-JSON signing substrate