paybondpaybond
Sign in

Ledger & provenance

The Paybond provenance ledger — append-only signed events, tip hashes, and how Signal and audit bundles reconcile to it.

Ledger & provenance

The provenance ledger is Paybond's append-only signed journal of every intent state transition. It is the ground truth for Signal rollups, audit exports, and dispute arbitration packages.

  • Ledger service: crates/paybond-ledger. Backing store: sled (filesystem tree, separate from the Harbor intent sled).
  • Consumer of record: go/signal-indexer tails ledger events, applies them idempotently, and produces signed operator receipts.

Event shape

Each ledger event is a signed envelope containing:

FieldRole
seqMonotonic sequence number. Unique per ledger.
tenant_idAuthenticated tenant realm. Harbor refuses to append without it.
kindEvent type (intent_created, intent_funded, evidence_submitted, intent_released, intent_refunded, intent_disputed, dispute_resolved, …).
payloadCanonical JSON body; the exact keys depend on kind.
parent_hash32-byte BLAKE3 digest of the previous event's signed envelope. Forms the Merkle chain.
signatureEd25519 signature over the canonical envelope with the Harbor signing key.

The current tip is the most recent sequence and entry commitment for the tenant. Harbor exposes it at GET /ledger/v1/tip. Paginated history for Signal and operators is GET /ledger/v1/events with after_seq (exclusive cursor; default 0) and limit (Harbor clamps to 256). The deployment verifying key is GET /ledger/v1/authority; the latest Merkle anchor envelope is GET /ledger/v1/merkle/latest.

For intent_created, Harbor now mirrors both operator_did and principal_did into the signed event payload. Signal uses that tenant-scoped principal/operator edge only for additive cluster-detection and shadow-risk explanation; it is not a canonical score input in score_version = 1.0.

Tenant scoping

Ledger appends are rejected before persistence unless the tenant envelope matches the authenticated context. On multi-tenant deployments that share one ledger, the tenant id is part of the signed envelope; Signal and audit queries filter by tenant on every read.

Replay semantics

The Signal indexer consumes events starting from its checkpoint. Inserts into tenant-scoped Postgres tables are idempotent (ON CONFLICT DO NOTHING on intent keys and terminal outcomes). Consequences:

  • Restarting the indexer is safe and does not double-count.
  • Lowering the checkpoint alone does not re-apply counters. A controlled rebuild requires PAYBOND_SIGNAL_ALLOW_DESTRUCTIVE_RESET=true and PAYBOND_SIGNAL_RESET_MODE=full_tenant_signal on the indexer.

Audit exports

The Gateway builds audit ZIP bundles by joining:

  1. A tenant-scoped slice of the provenance ledger (Harbor events).
  2. Signal operator rows and signed receipts.
  3. Dispute case rows from Postgres.
  4. Stripe settlement rows for the same wall-clock window.

Every bundle includes a signed manifest.json linking file SHAs to the ledger tip at build time, so a downstream auditor can verify the bundle matches a specific ledger position. Contract: docs/api/gateway-audit-export-openapi.yaml and docs/operations/audit-export-compliance.md.

Signing keys and rotation

  • Harbor ledger signing key is configured via PAYBOND_HARBOR_LEDGER_SIGNING_KEY_HEX (or an HSM-backed variant in production). Rotation is additive: new keys come online, old keys remain valid for verifying historical events.
  • Signal receipts and portfolio artifacts use separate Ed25519 keys (PAYBOND_SIGNAL_RECEIPT_SIGNING_KEY_HEX, PAYBOND_SIGNAL_ARTIFACT_SIGNING_KEY_HEX).
  • Audit export manifests use a dedicated signing key on the Gateway.

Key rotation runbook: docs/security/secrets-and-key-rotation-v1.md.

Backup and DR

  • Back up the ledger sled tree and the Harbor intent sled tree together. They share consistency invariants (for example a funded row points at a ledger sequence).
  • Restores: copy both sled paths to the new host with identical file permissions; validate the tip hash on startup.
  • Drill record: docs/operations/backup-restore-drill-record-v1.md.