Chio/Docs

EconomyOperations & Governancenew

Fiscal Constitutions

Signed fiscal schedules put an operator's economic parameters under quorum approval, a timelock, and rollback protection.

Use this page when

You are governing the economic parameters of one operator deployment (credit-limit tiers, marketplace discounts, premium schedules, and open-market fees and bonds) and need the charter, amendment, and resolution contract. Don't use this if you need the listing dispute, freeze, and sanction lifecycle (that is Governance Charters and Cases) or the day-to-day operator runbook for rails, bonds, and cadence (that is Operating an Economy).

What a Fiscal Constitution Scopes

A fiscal constitution is a FiscalCharter (chio.fiscal.charter.v1) plus the FiscalSchedule records (chio.fiscal.schedule.v1) it authorizes. The charter names the governing operator, the parameter domains it governs, an explicit signer set, and the amendment rules (approval threshold, timelock, and time-to-live windows); each schedule is a typed parameter set bound to that charter by digest. Both are canonical JSON (RFC 8785) wrapped in a SignedExportEnvelope<T>, and every id is a content hash over a preimage that omits the self id and signature, so a body already carrying its id is never re-hashed.

The governed domains are exactly the parameters that already exist at live pricing and penalty consumers; there is no invented penalty-rate domain. A FiscalDomain selects one of five, and the schedule params field is a FiscalParams enum whose active variant must match the domain.

DomainFiscalParams variantGoverns
Tier limitsTierLimits { ceilings: [MonetaryAmount; 4] }Marketplace credit-limit tier ceilings; replaces MARKETPLACE_TIER_LIMIT_UNITS. Four amounts share one ISO-4217 currency with non-decreasing units.
Marketplace discountMarketplaceDiscountPerHundred { discounts: [u32; 4] }Reputation-tier invocation discount; replaces TIER_DISCOUNT_PER_HUNDRED in its per-hundred unit, each value at most 100 and non-decreasing.
Decision premiumDecisionPremiumBasisPoints { approve, reduce_ceiling }Underwriting premium basis-point tables, non-decreasing in risk-class order with each reduce_ceiling at least the paired approve.
Insurance premiumInsurancePremiumSchedule { ... }Premium floors plus fixed-point score_adjustments_bps; money math is checked integer, and finite f64 is confined to behavioral risk classification.
Open-market fees and bondsOpenMarketFeeAndBondSchedule { legacy_body }Publication, dispute, and participation fees plus bond requirements; carries the exact legacy OpenMarketFeeScheduleArtifact body as a bound compatibility projection.

The Charter and Its Schedules

The charter carries the whole authority model in one signed body. Its preimage (chio.fiscal.charter.id.v1) sorts governed domains and signer keys canonically, so two wire bodies cannot share a normalized id, and each FiscalSigner key id is the lowercase SHA-256 of its canonical public-key bytes.

rust
// schema: chio.fiscal.charter.v1   (id preimage: chio.fiscal.charter.id.v1)
pub struct FiscalCharter {
    pub schema: String,
    pub charter_id: String,                    // sha256 over the sorted id preimage
    pub governing_operator_id: String,
    pub governed_domains: Vec<FiscalDomain>,   // sorted, deduplicated, non-empty
    pub signer_set: Vec<FiscalSigner>,         // FiscalSigner { key_id, public_key }
    pub approval_threshold: u32,               // in 1..=signer_set.len()
    pub timelock_seconds: u64,                 // > 0
    pub proposal_ttl_seconds: u64,             // > timelock_seconds
    pub approval_ttl_seconds: u64,             // > 0
    pub issued_at: u64,
    pub expires_at: u64,                       // required; > issued_at
    pub issued_by: String,
    pub sequence: u64,
    pub predecessor_charter_digest: Option<String>,
}

// schema: chio.fiscal.schedule.v1   (id preimage: chio.fiscal.schedule.id.v1)
pub struct FiscalSchedule {
    pub schema: String,
    pub schedule_id: String,
    pub charter_id: String,
    pub charter_digest: String,                // sha256 of the signed charter
    pub domain: FiscalDomain,
    pub params: FiscalParams,                  // active variant must match domain
    pub sequence: u64,                         // first is 1, then + 1 checked
    pub supersedes_schedule_id: Option<String>,
    pub valid_from: u64,
    pub valid_until: u64,                       // required; > valid_from
    pub issued_at: u64,
    pub issued_by: String,
}

A genesis charter is accepted only against an operator-configured FiscalGenesisPolicy that pins the exact charter digest, the bootstrap authority key, the fiscal-anchor identity and namespace, and a bounded currency-to-ceiling bootstrap_tier_limits map. Any later charter must be approved and activated under the currently pinned charter's threshold; its own new signer set cannot authorize its adoption. The first schedule for a domain carries sequence = 1 and no supersedes id; every successor increments the sequence with checked arithmetic and names the exact current active schedule, so a gap, a duplicate, or a cross-domain predecessor rejects at load.


The Amendment Lifecycle

A parameter change is never an in-place edit. It moves through four signed records: a FiscalProposal (chio.fiscal.proposal.v1) names a candidate schedule or a charter rotation; a durable-store FiscalProposalAdmission (chio.fiscal.proposal-admission.v1) stamps the trusted admitted_at, a checked-monotonic admission_sequence, and the proposal_expires_at deadline; distinct charter members each sign a FiscalApproval; and once the approvals reach the threshold and the timelock has elapsed, a FiscalActivation aggregates them and takes effect.

rendering…

The admission body is the timelock anchor. Its proposal_expires_at must equal admitted_at + proposal_ttl_seconds, and each approval's approval_expires_at must equal approved_at + approval_ttl_seconds; a signed proposed_at or a caller-selected time cannot shorten the delay. The admission state moves by compare-and-swap from Admitted to Activated, so two concurrent activations for one admission have exactly one winner.

rust
// schema: chio.fiscal.proposal.v1
pub struct FiscalProposal {
    pub schema: String,
    pub proposal_id: String,
    pub target: FiscalProposalTarget,   // Schedule { candidate } | CharterRotation { successor }
    pub rationale_digest: String,       // sha256 of an out-of-band rationale document
    pub proposed_by: String,
    pub proposed_at: u64,               // signed provenance only, not the timelock clock
}

// schema: chio.fiscal.approval.v1     (one single-signer envelope per charter member)
pub struct FiscalApproval {
    pub schema: String,
    pub approval_id: String,
    pub signer_key_id: String,          // must be a member of the active signer_set
    pub proposal_id: String,
    pub proposal_digest: String,
    pub admission_id: String,
    pub admission_digest: String,
    pub approved_at: u64,
    pub approval_expires_at: u64,       // approved_at + charter.approval_ttl_seconds
}

// schema: chio.fiscal.activation.v1   (aggregates m-of-n, valid only past the timelock)
pub struct FiscalActivation {
    pub schema: String,
    pub activation_id: String,
    pub proposal_id: String,
    pub proposal_digest: String,
    pub admission_id: String,
    pub admission_digest: String,
    pub charter_id: String,
    pub charter_digest: String,
    pub approval_set_digest: String,    // sha256 over the sorted (signer_key_id, envelope_digest) list
    pub target: FiscalActivationTarget, // Schedule { .. } | CharterRotation { .. }
    pub approvals: Vec<SignedFiscalApproval>,
    pub activation_not_before: u64,     // admitted_at + charter.timelock_seconds
    pub activated_at: u64,
    pub issued_by: String,
}

Activation is valid only when every nested signature verifies, distinct charter signers reach approval_threshold, all approvals sign the same proposal digest, the candidate schedule is in its validity window, and verify_at is at or past activation_not_before while still inside the proposal, approval, charter, and candidate windows. A CharterRotation is evaluated against the predecessor charter's membership and, because every active schedule binds its predecessor charter digest, must carry one successor-bound replacement for every already-activated domain; a missing, extra, or parameter-changing replacement rolls back the whole rotation. On the capability ladder this transition is fiscal.amendment_activate: mode receipt_backed, destructive: true, with the m-of-n approvals as the domain authorization rather than the ladder's quorum n_of_m semantics.


Resolution Order

Consumers never read a parameter table directly. They call one pure resolver, which returns governed parameters, a bootstrap-only fallback, or an explicit denial. No Governed value exists without verifying the complete activation chain: signed-schema admission, every record signature, the locally anchored admission authority, the approval threshold and uniqueness, the authenticated timelock, the validity window, the monotonic sequence, and the supersession lineage.

rust
pub enum FiscalResolution<P> {
    Governed { schedule_id: String, sequence: u64, source: GovernedSource, params: P },
    Fallback(FiscalFallbackReason),
    Denied(FiscalDenialReason),
}

pub enum GovernedSource { Active, LastKnownGood }

pub enum FiscalFallbackReason { AuthoritativeBootstrap, NeverActivated }

pub enum FiscalDenialReason {
    AnchorUnavailable,
    AnchorRollbackOrDivergence,
    ActivatedStateUnavailable,
    NoValidLastKnownGood,
    ClockRollback,
    VerificationFailed,
}

The resolver walks a fixed order and stops at the first outcome it can prove:

  1. Bootstrap. Fallback is returned only when the anchored genesis checkpoint proves the domain was never activated, using the exact built-in constant or the pinned genesis-policy currency map.
  2. Active. A verified, in-window active schedule resolves to Governed { source: Active }.
  3. Last-known-good. When the newest candidate is bad, the prior verified in-window schedule still holds as Governed { source: LastKnownGood }, so a broken update never bypasses it.
  4. Fail-closed. When no valid constitution resolves, the resolver returns Denied and the consumer must not price, bind, charge, or penalize.

Once the anchored ever_activated marker is true for a domain, the built-in constant can never reappear: unavailable governed state resolves to Denied, never a silent fall back to the old source. Rejection and resolution are distinct code paths, so a bad amendment cannot replace trustworthy state.


The Anti-Rollback Continuity Anchor

The local SQLite state is a cache and staging store, not proof that a domain was never activated or that a trusted clock has not moved backward. Production resolution requires a configured FiscalStateAnchor that lives outside the database backup and restore domain: a remote append-only witness or a hardware-backed monotonic store can implement the port, but another table copied with the same snapshot cannot. Missing, unavailable, unauthenticated, or non-monotonic anchor state fails startup before any fiscal read or mutation is served.

The anchor holds the latest signed chio.fiscal.continuity-checkpoint.v1 body for one operator. Each checkpoint binds a monotonic continuity_sequence and the previous digest, the exact FiscalGenesisPolicy id and body digest, the pinned charter, the runtime-readiness digest, per-domain ever_activated plus active and last-known-good heads, the trusted-clock high-water second, and any staged transition needed for recovery.

Every activation runs one recoverable protocol: stage the transition and the next checkpoint in an Immediate SQLite transaction while consumers still read the prior state, compare-and-swap the independent anchor from the exact prior checkpoint to the next signed one, then finalize locally against that anchored checkpoint. The swap accepts only a VerifiedFiscalContinuityAdvance built by a private verifier: a continuity_sequence + 1 step, a non-decreasing clock floor, an unchanged genesis-policy digest, and an ever_activated bit that moves only from false to true. A signature over a rollback, a skipped sequence, a cleared activation bit, or a reduced clock is rejected before the anchor mutates. Recovery reads the anchor first, so if it is ahead of a restored database the snapshot is stale and startup fails closed rather than reconstructing an unactivated domain from an older copy. Restoring SQLite alone can therefore never reopen the bootstrap fallback or roll the time boundary backward.


Devnet limits

This is a devnet, parameters-only design. Activation changes pricing and penalty parameters; it never moves or holds funds, issues no token, and takes no custody. The honest trust model is m-of-n operator signers plus a timelock: it is deliberately not a vote and not democratic governance. When no valid constitution resolves, the resolver returns Denied and the consumer must not price, bind, charge, or penalize. A fiscal schedule is signed intent scoped to one charter (evidence of an operator's own governed parameters, not authority over a peer); there is no cross-federation recognition, and this page makes no availability claim.

See Also