Chio/Docs

EconomyOperations & Governancenew

Comptroller Console

Read the signed receipt log as spend events, budget alerts, burn-rate projections, and anomaly findings.

Use this page when

You are wiring a live spend dashboard, a budget-alert webhook, or an anomaly detector over the receipt log and need the stream cursor, webhook thresholds, projection fields, and finding schema. Don't use this if you want to admit a signed risk or insurance authority's report as passport evidence (see Risk Comptroller Reports) or to run the ledger cycle that closes settlement instructions (see Reconciliation & Watchdog). This page covers the read-only observability layer beside those systems; it verifies nothing for a passport and enforces nothing.

Console vs. Comptroller Reports

The Risk Comptroller is a pure verifier: it admits or rejects one signed capital and risk authority report as evidence for a Transaction Passport. The Comptroller Console serves a different purpose: it projects the signed receipt log into a live spend feed and recomputes corpus-level statistics over it, all in the chio.spend.* signed-record family (canonical JSON, RFC 8785). The two share one rule. Capabilities, policy, and the guards remain the only pre-action authority; nothing on this page can revoke, clamp, or deny a spend. Receipts and findings are evidence, never authority.

The Spend-Event Stream

A spend event is a projection of one already-signed receipt. The chio.spend.event.v1 frame copies that receipt's FinancialReceiptMetadata dimensions (cost_charged, currency, budget_remaining, budget_total, delegation_depth, root_budget_holder, settlement_status) plus the source receipt_id, content_hash, tool_server, tool_name, timestamp, and seq. The frame is digest-bound to the signed receipt, so it is not independently signed: receipt verification authenticates the post-action evidence, it does not turn the event into pre-action authority.

Transport is pull-based long-poll and Server-Sent Events over the existing sequence-cursor pagination, at GET /v1/spend/stream?cursor=<seq>. The cursor is an opaque, authenticated value binding tenant, filter digest, the exclusive last-scanned store sequence, and the store generation. Every batch carries from_cursor, next_cursor, scanned_seq_start, scanned_seq_end, store_high_water_seq, complete_through_seq, a source_checkpoint, and an optional gap.

GET /v1/spend/stream (batch, trimmed)
{
  "from_cursor": "<prior next_cursor>",
  "next_cursor": "<opaque authenticated cursor>",
  "scanned_seq_start": 84120,
  "scanned_seq_end": 84200,
  "store_high_water_seq": 84200,
  "complete_through_seq": 84200,
  "source_checkpoint": "chio.spend.stream-checkpoint.v1",
  "events": [
    {
      "schema": "chio.spend.event.v1",
      "receipt_id": "receipt-order-commerce-001",
      "content_hash": "b7f0...",
      "tool_server": "did:chio:tool-search",
      "tool_name": "web.search",
      "timestamp": 1747776000,
      "seq": 84187,
      "cost_charged": 1200,
      "currency": "USD",
      "budget_remaining": 4800,
      "budget_total": 10000,
      "delegation_depth": 2,
      "root_budget_holder": "did:chio:buyer-enterprise",
      "settlement_status": "settled"
    }
  ],
  "gap": null
}

The source_checkpoint is a signed chio.spend.stream-checkpoint.v1 binding the tenant, store generation, high-water sequence, the base receipt-checkpoint root, a tenant-projection root over every receipt visible to that tenant, a tenant-time-index root over the same leaves ordered by (signed_receipt_timestamp, global_sequence), and a (budget_authority_digest, global_sequence) index root for threshold processing. It never commits only the rows matching a requested filter; the verifier applies the filter itself over proven leaves and derives the count. A cursor older than retention, from another tenant or filter, or from an incompatible store generation yields a typed gap response with earliest_available_seq and no events; the server never silently resumes at the new floor. Because receipt timestamps need not increase with store sequence, a cursor chain alone does not prove an analytic window [start, end) complete: the server instead returns a tenant-time-index range proof containing every key in [(start, 0), (end, 0)) plus the immediate predecessor and successor, which is what separates a thin tail read from a corpus a detector can stand on.


Budget-Utilization Webhooks

Webhooks fire on threshold crossings per verified budget authority at 50, 80, 95, and 100 percent of max_total_cost. A v1 authority key is (tenant, capability_id, grant_index, budget_authority_digest, currency), and the authority digest and grant index are resolved through the trusted capability snapshot, never inferred from copied financial metadata. Crossings are computed from budget_remaining and budget_total on spend events; webhook push is reserved for these discrete crossings, not the full firehose the stream tail already serves. Each crossing is emitted at least once as a signed chio.spend.budget-threshold-crossing.v1 payload whose deterministic crossing_id lets a receiver dedupe and verify the signature, treating the webhook as evidence, never authority.

chio.spend.budget-threshold-crossing.v1
{
  "schema": "chio.spend.budget-threshold-crossing.v1",
  "crossing_id": "sha256(threshold_key, first_crossing_seq)",
  "tenant": "tenant-enterprise",
  "capability_id": "cap-search-001",
  "grant_index": 0,
  "budget_authority_digest": "9c2a...",
  "currency": "USD",
  "threshold_bps": 8000,
  "prior_utilization_bps": 7600,
  "current_utilization_bps": 8100,
  "first_crossing_seq": 84187,
  "source_checkpoint": "chio.spend.stream-checkpoint.v1",
  "signature": "sig-ed25519:3f0d...:bf31..."
}

Evaluation is strictly ordered per authority key against the checkpoint-bound authority-event index: a threshold_cursor row advances only to the next proven member, and gaps, out-of-order input, missing authority evidence, or stale versions freeze it rather than firing a stale crossing. Ordinary budget fluctuation does not re-arm a threshold; only a new signed budget-authority digest starts a new lifecycle. Delivery reuses the receipt-export webhook exporter: HTTPS enforcement and a typed HttpEgressContract that fixes scheme, host, port, path, and response bounds, so a tenant writer cannot register an exfiltration host. Rows keyed by delivery_id = sha256(crossing_id, registration_id, registration_version) run a closed state machine (Pending -> Leased -> Delivered | Pending | DeadLetter) with leased retry, capped backoff on 429 and 5xx, and dead-letter on permanent 4xx, so delivery is at least once and history is never rewritten.


Burn-Rate and Time-to-Exhaustion Projections

A projection over a trailing window [now - W, now), with W declared on the request, names exactly one verified budget-authority key. In integer arithmetic only it computes spend_in_window (a checked sum of cost_charged minor units), time_to_exhaustion_seconds as a checked budget_remaining * W / spend_in_window (integer division, null when window spend is zero), and projected_window_spend scaled by an integer window multiple; overflow returns a typed incomplete projection, never a saturated value. All aggregates are MonetaryAmount (u64 minor units, ISO-4217), and a mixed-currency window follows the null-unless-converted rule: a per-currency partition is always returned and any cross-currency total is null unless an OracleConversionEvidence is attached. The same math runs over commerce mandate allowances, whose chio.commerce.mandate-allowance-ledger.v1 binds a maximum amount, currency, validity window, and usage count. The output at GET /v1/reports/burn-rate is a signed chio.spend.burn-rate-projection.v1 carrying the window bounds, inputs, integer results, source checkpoint, and range proof, so a verifier recomputes it exactly; an incomplete corpus emits a chio.spend.incomplete-corpus.v1 signal instead of a numeric result.


Spend-Anomaly Detectors

Three deterministic corpus-level detectors, all integer or fixed-point so a verifier independently recomputes the statistic from the cited receipts. Each carries a canonical detector_config_digest over its exact version, algorithm, window and baseline, and thresholds, and its severity is derived deterministically from that config and the statistic, never supplied on the side.

Detector classStatisticFires when
delegation_amplificationSum of cost_charged over a verified child capability-lineage subtree against the complete parent-level corpus, as a basis-point ratioChild-to-parent ratio in bps exceeds a declared bound
spend_pattern_driftPer (subject, tool_server, tool_name), current-window mean per-invocation cost against a trailing baseline mean, as a fixed-point bps ratioDivergence in bps exceeds a declared threshold
velocity_clusteringSummed sibling-grant invocation and spend counts under one verified lineage root within a complete windowAggregate exceeds a declared multiple of the per-grant VelocityGuard ceiling

The detector_class strings shown are the canonical-form rendering of the spec's prose detector names, not verbatim spec constants.

On complete input each detector emits a signed chio.spend.anomaly-finding.v1 at GET /v1/reports/spend-anomalies. The finding_id is SHA-256 over the complete canonical unsigned body excluding only finding_id and the signature, so it binds the detector config, severity, subject, window, checkpoint, evidence roots and refs, statistic, and threshold; it is not keyed by any single evidence receipt.

chio.spend.anomaly-finding.v1 (trimmed)
{
  "schema": "chio.spend.anomaly-finding.v1",
  "finding_id": "sha256(canonical unsigned body)",
  "detector_class": "delegation_amplification",
  "detector_config_digest": "4d19...",
  "severity": "elevated",
  "tenant": "tenant-enterprise",
  "subject": "did:chio:agent-orchestrator",
  "window": { "start": 1747689600, "end": 1747776000 },
  "source_checkpoint": "chio.spend.stream-checkpoint.v1",
  "lineage_refs": ["cap-root-001", "cap-child-014"],
  "evidence_receipt_refs": ["receipt-84187", "receipt-84190"],
  "statistic": { "child_to_parent_ratio_bps": 42000 },
  "threshold": { "max_ratio_bps": 20000 },
  "derivation_class": "observed",
  "evidence_class": "observed",
  "signature": "sig-ed25519:3f0d...:9ab2..."
}

Complete Corpus, Findings, and Underwriting

A statistic is a finding only over a complete, lineage-verified corpus: a boundary-complete tenant-time-index proof through a named checkpoint, sequence-root cross-bindings, verified receipt signatures, and verified subject and capability bindings. The delegation_amplification and velocity_clustering detectors additionally require a complete signed capability lineage (root holder, capability id, grant index, parent-child grant edges, and the receipt refs that establish each edge); a copied root_budget_holder or delegation_depth alone is not lineage proof.

When any of that is missing (a partial window, a retention gap, conflicting lineage), the console emits a signed chio.spend.incomplete-corpus.v1 and no finding. That record is an operational health signal: it cannot be deserialized as an anomaly finding and is never adverse underwriting evidence. Complete-corpus-or-health-signal is the load-bearing rule that keeps an unproven statistic from becoming a fact.

rendering…
Signed receipts project into the spend stream; detectors and projections run over the proven corpus. A boundary-complete corpus yields a signed finding; an incomplete one yields a health signal. Only an explicit anomaly-evidence policy promotes a finding to an underwriting signal.

Promotion to an Underwriting Signal

A finding becomes an underwriting signal only through an active signed chio.spend.anomaly-evidence-policy.v1. Its canonical SpendAnomalyEvidencePolicyV1 body names the accepted finding-authority key ids, a detector-to-version map of accepted detector_config_digest values, a maximum finding age, a minimum sample count and window, and a severity-to-signal mapping, under a not_before / expires_at validity. The default accepts none: an absent, expired, superseded, or revoked policy means no spend finding is admissible.

A finding records derivation_class separately from evidence_class. Local deterministic computation is observed, but the final evidence class is the floor across every receipt, capability-lineage, conversion, and other source dependency, so one asserted input caps the finding, and the same finding presented across an organization boundary is capped at asserted with no trust-pack upgrade. After policy filtering, findings group by exact (tenant, subject, UnderwritingReasonCode) into one deterministic UnderwritingSignalV2 taking the maximum class (Guarded < Elevated < Critical) and the evidence-class floor, so a lower-severity finding never suppresses a higher one. The reason codes are SpendDelegationAmplification, SpendPatternDrift, and SpendVelocityClustering, under the evidence kind UnderwritingEvidenceKind::SpendAnomalyFinding. For how those signals price a premium and set a credit ceiling, see Underwriting Risk Taxonomy.


Devnet limits

The Comptroller Console provides devnet observability and signed evidence. It does not enforce policy: no detector, webhook, or projection revokes, clamps, or denies a spend; capabilities plus policy and the guards remain the only pre-action authority. A statistic is a finding only over a complete, lineage-verified corpus; an incomplete corpus yields a chio.spend.incomplete-corpus.v1 health signal, never a finding and never adverse underwriting evidence. Only an active chio.spend.anomaly-evidence-policy.v1 can promote one to an underwriting signal. The public claim is signed spend observability with policy-gated underwriting inputs, never automatic spend control, and nothing here is an availability or uptime commitment.

See Also

  • Risk Comptroller Reports for the pure verifier that admits a signed capital and risk authority report as passport evidence, distinct from this live spend feed.
  • Regulatory & Audit APIs for the read-only signed receipt export and the webhook exporter this console reuses for delivery.
  • Underwriting Risk Taxonomy for how a policy-admitted spend-anomaly finding becomes an UnderwritingSignalV2 that prices a premium.
  • Reconciliation & Watchdog for the ledger cycle that closes the settlement instructions the receipts on this stream record.