Skip to main content

Data model, state machines and ledger

APPROVED · IMPLEMENTATION SPECIFICATION · London 0.1.0

Authoritative engine​

The deterministic RocksDB ledger owns all domain mutations. The record catalogue below describes logical entities, not SQL tables. Map entities to the specified column-family/key layout, enforce references and uniqueness in the transaction engine, and atomically append journal entries with state/outbox changes. Private identity/provider mappings belong in private_aux or protected evidence storage and are excluded from replayable financial inputs.

Persistence conventions​

Use UUIDv4 primary IDs, UTC timestamps and integer amounts. Numeric wire values larger than safe JavaScript integers are decimal strings. Values are versioned canonical JSON; amounts are unsigned u64 decimal strings checked before arithmetic and persistence. Use checked wide intermediates for allocation. Durations/times use checked integers. Never reuse an ID. Referential checks and explicit uniqueness sentinel keys are release requirements, not optional optimisations. Each material record stores schema version, creation timestamp, correlation ID and provenance where appropriate.

Logical record familyRequired fields beyond IDConstraints
accountsprovider_subject, roles, statusUnique provider/subject; no PII in chain IDs
subscription_periodsaccount, provider IDs, start/end, entitlement state, clearance, gross/net GBPUnique provider period; end greater than start
works / rights_versionscatalogue metadata, licence reference, version, effective time, recipientsUnique work/version; splits sum 10000; append-only history
renditions / chunkswork, manifest hash, codec, duration; chunk index/media interval/size/hashUnique rendition/index; complete ordered coverage
operators / nodes / node_keysowner, independence declaration, endpoint, status, payout account, key intervalsOne owner per node; approved endpoint; no overlapping active key versions
sessionsaccount, work, rendition, rights version, start/expiry/close, leasePartial unique active account; lock for issuance
grantssession or fill destination, node, chunk, purpose, nonce hash, expiry, consume sequence/request/time, cancellationUnique nonce; one consumption; monotonic coordinator sequence
receiptsreceipt ID, grant, raw object/hash, signature, ingest timeUnique ID and one final receipt per consumed grant; conflicting body rejected
decisionsreceipt/session, revision, disposition, reason, actor, predecessorAppend-only, one current projection; no raw input mutation
peer_fillssource/destination, grant, receipt hash, verified outcomeNever joins royalty-duration tables
funding_lotsverified deposit, asset, amount, conversion referencesUnique deposit evidence; allocated total at most received
budgetsperiod, lot contributions, B, daily slices, unspent/reserved/allocatedConserved; unique period funding version
allocation_lineslistener-day, work/rights, role, recipient snapshot, duration, amount, revisionNo double allocation; linked reversal/replacement for corrections
batcheskind, period, artifact location/hash, parent/correction, chain stateUnique batch ID; immutable payload after freeze
statementsrecipient, accounting batch, private artifact hash, public proof IDUnique recipient/batch; public ID random and unlinkable across periods
payment_runs / paymentsapproved hash, approver, cap; recipient, amount, contribution set, stateEach payable contribution reserved once; no duplicate paid obligation
payment_attemptspayment, sender sequence, signed bytes/hash, expiry, outcome, ledger versionUnique sender/sequence and transaction hash; write before broadcast
exceptions / audit / outboxtarget, actor, event, payload reference, timestampAppend-only audit; unique event business key

Only the ledger owner has write access to the database directory. Its typed commands prohibit update/delete of immutable receipts, frozen artifacts, posted monetary entries and audit events; RocksDB does not enforce these business restrictions itself. Derived status tables can be rebuilt. Append-only here is an enforced domain/API property; chain anchoring adds external tamper evidence. Backups and retained object versions provide availability.

State machines​

Receipt decisions: recorded -> accepted | rejected | partial | late | held. Releasing a hold appends a new decision revision. Eligibility is evaluated on the closed session, not the individual receipt alone. Grant state, receipt state and allocation state are separate columns; do not conflate them in one overloaded status.

Batch states: preparing -> frozen -> submitted -> confirmed, with failed retryable against the same payload and uncertain requiring reconciliation. A frozen batch may be abandoned before submission, retaining its ID and reason; never reuse that ID with different bytes. A confirmed batch has no editable-content state. Corrections are new batches.

Payment states: prepared -> approved -> signed -> submitted -> confirmed; branches held, failed, uncertain, cancelled. Cancel only before signing, or after proving a signed attempt cannot succeed. confirmed is terminal. Failure is per attempt; obligation remains unpaid until success or an authorised accounting correction closes it.

Ledger conservation​

Use explicit debit/credit postings per business event. Each journal balances in a single asset/currency; never mix GBP and USDC in one numeric balance. Track USDC funding availability, unallocated reserve, artist payables, operator payables, Porto retained share, reserved payouts and confirmed paid amounts. Reconcile chain treasury balances separately from economic attribution. Conversion links GBP and USDC journals through actual provider evidence, not an invented common unit.

Invariant for each funded budget: original funded units plus approved additions equal unallocated plus outstanding allocations plus paid allocations plus recorded refunds/reversals, with corrections represented exactly once. Reservations are a subdivision of unpaid allocations, not another expense. Ledger transitions, journal entries, uniqueness keys and outbox events commit in one synchronous RocksDB transaction. Run the invariant check after every accounting job and before signing; any mismatch blocks payouts.

Audit events​

Required event families: account/entitlement change; catalogue activation/withdrawal; operator admission/key change/suspension; session/grant issue/consume/cancel; receipt disposition; peer fill verification; hold change; funding import; day close; allocation freeze; commitment submission/confirmation; run approval; payment signed/submitted/confirmed/failed; export access; profile change. Store actor, target, payload digest, reason enum and timestamp. Detailed private notes use separate restricted references.

Contents · Implementation plan · Launch inputs