Settlement
Settlement is how Covenant accounts for resource consumption. Today the daemon writes local receipts. The Solana settlement program is deployed and live on mainnet; the daemon-driven path that batches those receipts and anchors them to the program is not yet production.
Receipt
SettlementReceipt {
id: uuid,
payer: AgentId, // who consumed resources
resource: "memory" | "compute" | "tool" | "message" | "registration",
credits_consumed: u64,
settled_at: u64, // unix milliseconds
memory_record_id: uuid | null, // set when resource == "memory"
chain: string | null, // populated when anchored on-chain
cluster: string | null, // Solana cluster identifier when anchored on-chain
batch_id: string | null, // identifier of the receipt batch
merkle_root: string | null, // batch merkle root committed on-chain
tx_sig: string | null, // signature of anchor_receipt_batch tx
slot: u64 | null, // chain slot where the batch confirmed
confirmed_at: u64 | null, // unix milliseconds at confirmation
onchain_sig: string | null // populated when flushed on-chain
}Receipts accumulate in $COVENANT_HOME/receipts/working.jsonl. The daemon writes one receipt per resource event. For example, every memory write produces a receipt with resource = "memory", memory_record_id, and credits_consumed proportional to bytes written.
Credit pricing
Each resource kind has a pricing function that maps the underlying unit (bytes, milliseconds, calls) to credits. The pricing functions are deliberately simple and live in one place, so operators can audit them at a glance and downstream integrations can replicate the math without a dependency.
The default for memory writes is one credit per kilobyte (round up). Compute, tool calls, and egress have their own pricing functions that compose the same way.
Future on-chain flush
The on-chain side is an Anchor program deployed on Solana mainnet. Three of its instruction shapes describe the credit flow:
initialize: one-shot setup of aConfigPDA under seedb"settlement-config"; records the authority, mints, and rates.buy_credits(amount_covnt): transfer$CVNTinto the treasury in exchange for credits at the configured rate.consume_credits(amount, receipt_hash): destroy credits at the point of consumption (memory write, tool call, etc.).receipt_hashbinds the on-chain consumption to a specific local receipt batch for reconciliation.
The intended production flow is for the daemon to batch local receipts and submit consumption to the program. Once an on-chain transaction confirms, the receipt's onchain_sig can be populated with the signature. This daemon-driven reconciliation path is not yet production.
Planned economic model
The target model is credits minted against an external payment input, credits consumed at resource-use time, and treasury policy that can route a portion of inflows toward buyback or provider payout. Those mechanics require oracle integration, mint authority decisions, and deployment review before they should be treated as operational.
Storage layout
| Path | Format | Purpose |
|---|---|---|
receipts/working.jsonl | JSONL, append-only | Local receipts. Future flushed receipts can populate onchain_sig. |
Reading recent receipts
covenant chain status --json
covenant receipts recent --limit 20 --json
covenant chain flush-receipts --limit 20 --json
covenant chain receipt-batches --limit 20 --json
# Or via HTTP:
curl -s '127.0.0.1:8421/receipts/recent?limit=20&since_ms=1714938000000' | jqVerification
covenant verify --json cross-checks memory writes against settlement receipts by memory_record_id when the receipt carries one, with owner/resource count fallback for older rows. Missing, duplicate, orphaned, or wrong-payer correlations surface as drift. The daemon is fail-soft on receipt write (a failed receipt does not cancel the memory write), so drift in this dimension is the principal operator-visible indicator of a settlement-side fault.
Backfill
When covenant verify reports legacy receipts without a memory_record_id correlation, the operator can repair them with the covenant settlement backfill-receipts --json CLI verb (HTTP equivalent: POST /settlement/receipts/backfill). Verify remains read-only; the backfill mutator runs only when explicitly invoked. The verb applies by default; pass --dry-run to report the row_count an apply would change without writing. Dry-run requires the settlement.backfill.dry_run capability; apply requires settlement.backfill.apply. See capabilities for the scope contract. An apply path writes a rollback checkpoint sibling file before mutation, fsyncs both the rewrite and the rename, then emits an operator-issued SettlementReceiptBackfillApplied audit row carrying row_count, rollback_path, and dry_run.
$ covenant settlement backfill-receipts --dry-run --json
{"schema":"covenant.settlement.backfill.v1","row_count":12,"rollback_path":null,"dry_run":true}x402 payment rail
Distinct from the internal receipt flush above, the agent-to-service payment rail over HTTP 402 (x402) is live. The daemon can pay for metered x402 resources outbound, and Covenant operates a deployed x402 seller that settles in USDC on Solana mainnet — selling Covenant-Verified attestations, on-chain identity passports, and reputation reads, with the seller’s signing key published at/.well-known/x402— alongside an escrow service and an Ephemeral-Rollup credit facilitator. This is a separate concern from anchoring internal resource receipts: the payment rail being live does not make the receipt flush production.
Release
Local receipts and recent-receipt reads are implemented. The Solana settlement program is deployed and live on mainnet — $CVNT-to-credits, staking, slashing, and on-chain receipt anchoring transact on-chain. The daemon-driven per-intent settlement lifecycle that anchors internal resource receipts is not yet production.
Related
- Architecture: the settlement program in the broader system map.
- Identity and keys: the same local identity signs capability grants today and is the planned signer boundary for future settlement transactions.
- Audit log: settlement receipts pair 1:1 with memory writes; drift shows up here.