-
-
The live clearing dashboard: Confluent topics in and out, accrued minutes, the priced obligation and the audit chain on one screen.
-
The settlement notice, approved and sealed. Clause 4.2 cited, the agent cross-check recorded on its face, the chain hashed.
-
Google ADK contract intake: raw contract text in, machine-readable pricing rules out. A live call, nothing cached.
-
IBM Bob governance: five headless runs, 30 tool calls, 5.803 coins, 90 of 90 tests green, full ledger in the repo.
-
The architecture: events in through Confluent Cloud, deterministic pricing, three ADK agents, obligations streamed back out.
Inspiration
Residuals and participation royalties in film and streaming settle 60 to 90 days after the exhibition that earned them. The distributor reports late, the rights holder cannot independently verify the number, and when a contractual escalator trips — a fixed bonus the moment a title crosses five million stream minutes, say — nobody finds out until a quarterly reconciliation months later. Guilds arbitrate. Artists wait.
The striking part is that the money is rarely what is in dispute. The evidence is. Two parties look at the same exhibition and cannot agree on what it earned, because neither of them was watching when it happened.
So we stopped treating royalty clearing as an accounting job that runs after the fact, and built it as something that runs during.
What it does
Residual Live turns royalty clearing from a retroactive batch process into a continuous, event-driven one.
Exhibition events stream into a Confluent Cloud topic. A deterministic engine prices each event against machine-readable contract rules. When a contractual threshold trips, the system generates a settlement notice, cross-checks the amount against the clause it cites, hashes it into a three-tier SHA-256 chain, publishes it back out on a second Confluent topic, and puts it in front of a human for one-click approval.
The result: the obligation exists the moment the title earns it — priced, cited, and provable by both sides.
In the demo, a licensed title accrues toward a 5,000,000 stream-minute escalator. When event six pushes it to 5,040,000, the threshold trips and the engine prices the obligation at $25,000.00, the fixed milestone bonus that Clause 4.2 makes payable the moment the title crosses the line. The notice quotes the clause verbatim, the cross-check result is recorded beside it, and a rights administrator approves it with one click. The notice is re-hashed and sealed on approval.
How we built it
Three Google ADK agents, each with a job an LLM is actually good at
- Contract Intake — an
LlmAgentbehind aRunnerreads raw contract text and returns structured, machine-readable rules through a typed output schema. It is a live call: run it twice on the same document and you get the same two rules with different generated rule IDs, which is the easiest way to prove nothing is cached. Measured at 13.5s, 15.2s and 20.0s across three runs. - Clause Cross-Check — verifies the deterministic engine's number back against the clause text. On a mismatch it flags rather than passing through. This agent is allowed to say no.
- Notice Writer — drafts the settlement notice with the exact clause citation.
Confluent Cloud as a bidirectional nervous system
demo-eventscarries exhibition telemetry in, keyed by title, deduplicated by deterministic hash so a replayed event cannot double-charge.obligationscarries priced obligations back out, so downstream finance systems subscribe to settlements rather than polling for them.
Roundtrip on the cluster was measured at 2.2 seconds for three produce plus three consume before we built anything on top of it.
The audit chain
Three tiers of SHA-256: per-entry hashes, a chain hash across entries, and a notice hash over the whole document. Approval re-hashes and seals. Both counterparties can recompute every number from the event log without trusting the other's system.
IBM Bob (watsonx Code Assistant), headless
Bob was used for structural work, not cosmetics. Five governed runs built the core domain schemas (RoyaltyEvent, ContractRule, SettlementNotice), the contract-intake test cases and clause analysis, the audit-chain hardening (chain hashing, party binding, notice fingerprint), and the multi-title clause test corpus with isolation checks. 30 tool calls, 5.803 coins against a 50-coin trial budget, a full ledger committed at bob-runs/coins-ledger.md, and a live proof endpoint at /api/bob-audit.
Rest of the stack: Python, FastAPI, WebSockets for live push, and 90 pytest unit and integration tests, all green.
Challenges we ran into
An LLM must never do the arithmetic. Our first design had an agent compute the settlement. That is indefensible in a financial pipeline: it is non-deterministic and it cannot be audited. We split it — the engine prices, the agent verifies against the clause. The agent's job is to disagree, not to calculate.
That split paid off in a way we did not expect. The contract-intake agent is a live call, so what it extracts varies between runs. On the run captured in our demo the verifying agent and the rules engine disagreed about the amount: the engine held a firm figure from Clause 4.2, the agent returned zero. The cross-check caught it and stamped the disagreement on the face of the notice:
[WARN: agent extraction mismatch - agent found $0.00, rule dictates $25,000.00]
We left it on screen, and it is the single thing in this project we are most confident about. The system settled the number the rule dictates, not the number the model produced, and it told the reader that the two did not agree. A pipeline that quietly resolves that disagreement is the one you should not trust with money.
Agent latency is real and we chose not to hide it. Contract intake takes 13 to 20 seconds. We could have cached a response and called it instant. Instead the button says what it is doing, and we say "about fifteen seconds" out loud. A financial system that lies about its own latency has already lost the argument it exists to win.
Idempotency on a stream that can replay. Exhibition events are deduplicated on a deterministic hash of the payload, so a redelivered event does not accrue twice.
Accomplishments that we're proud of
- A cross-check that fails loudly. Most agentic demos are built so that nothing can go wrong on stage. Ours shows its disagreement on screen.
- Determinism where it matters, and language models where they earn their place — at the edges, reading contracts and drafting prose, never on the ledger.
- IBM Bob used as a governed build process with a complete, inspectable coin ledger, not a wrapper around a chat window.
- 90 of 90 tests green, covering schemas, multi-title isolation and idempotency.
What we learned
The useful question about agents in a regulated workflow is not "what can the model do" but "what is the model allowed to be wrong about". Reading a contract into a schema: acceptable, because the next stage checks it. Computing a payable: not acceptable, ever. Drawing that line explicitly made the architecture fall out almost on its own.
We also learned that an honesty boundary is a design constraint worth keeping. Marking what is real and what is curated forced better engineering, because anything we had to mark curated was something we had not actually proven yet.
What's next for Residual Live
- Real distributor telemetry in place of the curated stream, starting with a single SVOD reporting feed.
- Rule packs per guild — SAG-AFTRA, DGA and WGA residual schedules differ in ways the intake agent should learn once and reuse.
- Payment rail integration, so approval triggers disbursement rather than recording an intent to disburse.
- Counterparty-side verification: give the licensor its own client that recomputes the chain independently, so trust never depends on our server.
What is real and what is curated
We would rather say this plainly than have a judge wonder.
| Real | Curated |
|---|---|
| Confluent Cloud cluster, both topics, live | The residuals schedule is a sample, modeled on public guild terms |
| Google ADK agents, live LLM calls, nothing cached | The six exhibition events are a scripted stream, injected on click |
| SHA-256 audit chain, hashes, approval seal | Three catalog titles are configured; one is streaming in the demo |
| IBM Bob runs, coin ledger, 90/90 tests |
Latency is stated in seconds throughout, because that is what it is.
Built With
- apache-kafka
- confluent
- css3
- fastapi
- gemini
- google-adk
- html5
- ibm-bob
- javascript
- pytest
- python
- watsonx
- websockets


Log in or sign up for Devpost to join the conversation.