Roadmap
What Recurro has built, what it is building, and what comes next. Order within a track is the order of the work. There are no dates: a date on something unbuilt is a promise nobody asked us to make.
Settlement
6/11 builtHow does a payment move privately, and how does it become final?
The private rail, end to end on a devnet
✓ BuiltDeposit, private send, scan and move-to-public run against a development network with no shortcuts in the path: real proofs in roughly half a second, a pool holding the generated verifier, an indexer, and a relayer.
Settling with the wallet you already have
✓ BuiltA payee who will not manage keys gives a wallet address instead of a Recurro address, under the same one-address-one-payee rule and the same second-person control on any change. The run pays that line as an exit from the pool inside the same chained sequence: the relayer submits, so the payer stays hidden, while the amount and the address are public and the payee is told so. Their receipt carries the transaction as its evidence, since there is no key to sign a confirmation with. Proven on a devnet with real proofs, private and public lines in one run.
Proving in the browser
✓ BuiltA payment is made entirely on the payer's device: the notes are chosen, the proof is generated, and the note is encrypted to the payee, because every one of those needs a key that never leaves the browser. Verified end to end against a devnet, the payee received exactly what was sent, with the reference, and could read it with their own key. The proving parameters are served from this site rather than a third party, because asking someone else for them announces an intention to pay privately. Bringing the browser proving time down is the remaining work.
Requires Threaded proving is broken rather than merely unmeasured, and that is the work. In a cross-origin-isolated build the prover asks for four workers, one loads and three are aborted by the browser, and it falls back to a single thread, 2.5 seconds becomes about twenty. bb.js creates them with Promise.all over one URL, so every worker fetches the same module script at the same moment. Two explanations have been tested and ruled out: it is not the request racing, because warming the script into the cache first changes nothing, and it is not the embedder policy, because require-corp on the chunks behaves exactly as credentialless does. Whoever picks this up should start somewhere else. A ceiling and a single-thread fallback mean a proof always finishes, so this costs time and never correctness.
Funding and moving to public
✓ BuiltMoney into the pool from a connected wallet, and a private balance back out to a public address, both proved in the browser and confirmed on a development network. The approval is for exactly the amount, never unlimited; the amount that will actually arrive is shown rather than the amount typed; and a move that has been submitted but not confirmed is reported as neither success nor failure, because retrying it could pay twice.
Requires Live on Base Sepolia, settling Circle's test USDC. The pool, the verifier and the relayer are all public, with the indexer served by the app itself until activity outgrows a per-request rebuild.
Combining notes, so a balance stays spendable
✓ BuiltA proof spends two notes, so a balance spread across more than two cannot all move in one payment, so the product got worse the more it was used, and every screen touching a balance had to explain why. Combining is now a button where that message appears: a private payment to yourself for the sum of your two largest notes, which the builder consumes exactly, returning one note worth both. The gain is stated in money before anything starts, because each step is a proof somebody waits through.
Requires A circuit wider than two inputs, which would make most of this unnecessary rather than automatic.
An x402 facilitator that pays the payee privately
✓ BuiltAn agent signs an ordinary USDC authorisation; the payee is named by a Recurro address and receives a private note. Every refusal is a named reason, and a payment the pool's float cannot deliver is refused before the public transfer, never taken and owed. Works with no key; a key meters what it settles. A suite of hostile requests is sent at it every night, and each must be refused by name.
Requires USDT, through a second signing scheme: the exact scheme is EIP-3009, which Tether's token does not implement.
Widening to many payees in one proof
BuildingThe circuit and pool move one payment at a time today. Batch payroll needs many payees settled under a single proof.
Requires The circuit widened and re-sized; gas re-measured on the pool contracts.
Live pools: USDC and USDT, on Base and on Ethereum
NextOne pool per token per chain, each with a deposit cap the owner can raise, named in the path and chosen per payroll line. Privacy is per pool and the product says so. The registry, the screens, the executor and the deploy script are done; what is left is the deployment itself, behind the readiness review.
Requires Mainnet readiness reviews complete. No exceptions for a first customer.
Finality and the interrupt point
NextWhere a payment becomes irreversible, and who, if anyone, can interrupt it before then. No freezing authority unless it is explicitly built and disclosed.
Requires The pool contracts finished and their behaviour under contention tested.
Cancelling a payment before it settles
LaterWho can cancel, until when, and what the payee sees when they do.
Requires The interrupt point above, defined: cancellation is meaningless until that line exists.
Refunds
LaterA refund back through the pool to whoever paid, rather than a fresh payment to a new address.
Requires A decision on the private-balance format, made before the circuit hardens further, because today’s format cannot express a refund.
Control
15/17 builtWho may authorise a payment, within what limits, and how is it stopped or recovered?
Agents, and the wallet each one may spend from
✓ BuiltA registry of the software agents allowed to initiate payments, each bound to one wallet. Binding is write-once over the API: a stolen key must not be able to redirect an agent's spending. Rebinding is a governed action with an approver and a receipt.
Requires Members and roles, so a governed action has someone to be governed by.
The rules that decide a payment, in plain English
✓ BuiltEvery payment is decided by a policy. This shows the rule in prose beside the JSON that actually runs, with version history and what changed between versions, so a reader can see which version decided a given payment.
Requires Policy evaluation wired into the decision path.
A hold desk, not an approvals list
✓ BuiltHeld payments with the clock running against their SLA, the investigation attached, and a second approver required where the policy says so. The schema already carries the deadline, the investigation and the second approver; the screen shows none of them today.
Requires Members and roles, so the second approver is a different person.
Approvals reads the database
✓ BuiltHeld payments, decided-today history, and the empty state a fresh organisation actually sees, read from Postgres, scoped by environment, not a fixture.
Mandate creation shows real reference data
✓ BuiltThe saved payee, cap, allowed rails and projected run schedule on the new-mandate screen read the database.
Payroll review reads a real run
✓ BuiltA run’s rows, held rows, and totals read from the database rather than a static table.
Organisations, members and roles
✓ BuiltWho can create a mandate, approve one, issue a key, or export evidence. Roles map to the key hierarchy that already exists rather than a separate permissions model.
Requires The remaining screens below, which read and write org membership.
The remaining screens read the database
✓ BuiltOverview, Send, the mandate list, and Keys still show fixed numbers while Approvals, Mandate creation and Payroll review already read real data.
Standing mandates and the scheduler
✓ BuiltA payee, a cap, a cadence and an expiry, authorised once, that runs itself without asking again. Signed in the browser over a hash of exactly what it authorises, so changing any of those terms invalidates the signature and the mandate has to be authorised again. Every run claims its due moment before paying, which is what makes two schedulers, a retry and an overlapping cron all safe. A late scheduler owes every payment it missed rather than one, and a paused mandate resumes on its own schedule instead of firing months of payments at once.
Requires Batch payroll below, so one mandate can pay a cohort rather than a person.
Payee directory and address controls
✓ BuiltAdding, verifying and changing a payee’s address, with a second approver required on any change: the classic payroll fraud vector.
Requires Organisations and roles above.
Recovery for the payee's words
✓ BuiltLosing the passphrase used to lose the money. A payee now splits their words between people they choose, any two of three, on their own device, and restores from any two in a fresh browser to the same address and balance. The pieces are shown once; a piece from a different split, a duplicate, or one piece alone is refused with the count needed rather than producing wrong words.
Transaction limits and policy administration
✓ BuiltOrganisation policies (caps, thresholds, allowed rails, approval rules) versioned, not overwritten.
Requires Organisations and roles above.
Recovery and rotation for organisations
✓ BuiltAn employee leaves, a device is lost, and the money stays reachable without any one person holding it alone. The passphrase is split in the browser with Shamir's scheme over GF(256): any chosen number of named colleagues restore it together, and any smaller group learns nothing at all, which is a stronger statement than "learns less" and the reason this is not a matter of cutting the key into pieces. We never receive a share; what is recorded is the shape of the arrangement and whether each holder has confirmed keeping theirs, because a piece nobody stored is a threshold nobody knows they have lost.
Requires Rotation, replacing a key across an organisation without a recovery, and passkeys as a second route.
A mandate that says what it is for
✓ BuiltA sentence of purpose inside the signed terms, and each payment's description judged against it. A purchase that clearly does not fit waits for a person, with the reason on the receipt. An instruction aimed at the reviewer and a cash equivalent under the wrong mandate each hold. It can add a hold and never allow what the caps refuse, and a judge that is slow or down changes nothing. Known cases are asked every night, and the check turns itself off if the answers drift.
Agents sign exactly what the server prepared
✓ BuiltThe external-signing flow, adopted from the Cartulary control plane. A live allow returns the unsigned transaction; the agent's key signs exactly those bytes and posts a 65-byte signature; the server verifies it recovers to the bound wallet and relays. A deviating payment is unconstructable from either side: the server never holds the key, and the agent never constructs a transaction. Fee bumps re-bid the same bytes with only the fees raised, same nonce, same recipient, same calldata, and a sweep writes the settled receipt at confirmation depth, appends reorg observations rather than rewriting, and returns a vanished transaction to the watch. The agent-side verifier decodes the template with its own RLP and refuses anything that pays the wrong address, the wrong amount, the wrong token or the wrong chain; a test holds its hash equal to the server's, computed by two independent implementations.
Requires Retargeting the template at a private-pool transact, so an agent's payment settles through the pool rather than in the open: the roadmap's agentic step, and this flow is the shape it reuses.
Batch payroll
NextMany payees under one mandate, run from a CSV or the API.
Requires Standing mandates above, and the circuit widened for many payees in one proof (settlement).
Duplicate, failed and partial batches
NextA re-run never pays twice, and a partially completed batch is a first-class state with a receipt per row.
Requires Batch payroll above.
Evidence
9/14 builtWhat can be proved about a payment afterwards, and to whom?
Evidence bundles, exportable and scoped
✓ BuiltEverything provable about a payment, exported as a file an auditor can check without us, and shareable through a link scoped to one counterparty and a date range that the payer can revoke.
Requires The receipt chain verifying, which it now does.
The receipt format, published
✓ BuiltThe canonical form and hash rule written down as a specification, so a receipt can be checked by software we did not write. A format only we can read is not evidence.
Receipts that can be recomputed
✓ BuiltA receipt's hash is computed from its own contents in canonical form, so anyone holding the file can check it without us. Every chain is recomputed on read and by a script that fails the build if one does not match.
Receipts read a real payment
✓ BuiltA receipt page reads its payment from the database by id, with the not-found case handled as an empty state.
Signed receipt chain and evidence bundle export
✓ BuiltEvery payment carries a receipt chained to the one before it and signed on the payer's own device. The key is Ed25519, derived in the browser from their passphrase; the private half is never transmitted, so a signature is worth more than our assertion, we could not make one. A bundle carries the signature and the public key that checks it, and the offline verifier shares no code with the application, so agreement between them is evidence rather than coincidence.
Requires A published transparency log of enrolled keys, so a key named in a bundle can be checked against a record we cannot quietly change.
Scoped disclosure keys
✓ BuiltAn auditor holds a key scoped to a date range and a set of payees, sees exactly that, and every use is logged for the organisation that issued it - including refused ones, because somebody trying a key you revoked is the fact you most want. The scope is applied by the query that answers the key, not by a rule anyone has to remember, and the sentence describing it is generated from the same fields, so it cannot drift. Only a hash of the link is stored: a database that leaks does not become a set of working keys.
Requires Per-payment decryption, so a key opens the note contents rather than the payment record around them.
What the amount was calculated from
✓ BuiltA payment recorded an amount and nothing about where it came from. It now carries the rate, the quantity, the unit, the currency the contract is written in and, when that differs from what was sent, the conversion used and where it came from, because a rate nobody can trace is a number somebody typed. All of it sits in the receipt payload, so the hash and the signature cover it. The arithmetic is exact: rates multiply as scaled integers, since 40 × 105.10 in floating point is 4203.9999999999995 and a reconciliation that fails by a ten-billionth of a cent teaches everybody to ignore the check. A line item that does not reconcile to the amount is refused rather than stored, because one of the three numbers is wrong and evidence that contradicts itself is worse than none.
Requires Several line items on one payment, for an invoice that is not a single rate times a single quantity.
The document the payment answers
✓ BuiltA payment names the invoice, contract or timesheet it settles, and carries a SHA-256 of that file computed in the payer's browser. We hold the reference and the fingerprint and never the document: enough to prove which one was meant and that it has not changed, without becoming its custodian. Paying the same invoice twice is refused by the database rather than noticed later, one settled payment per reference, while a payment that was refused leaves the reference free, because the bill is still owed.
Requires Several documents against one payment, and one document across several payments.
A privacy score, before you move money out
✓ BuiltShown where it can be computed rather than guessed: moving to a public wallet, the one step that becomes visible. Four things are checked against the reader's own notes and the pool, how much activity is there to blend into, whether the amount exactly matches a payment they received, whether anything is left behind, and whether the notes being spent all arrived at the same moment. Each line says what it saw and what to do instead, and the reading is described as a guide rather than a guarantee, because it cannot know what a watcher already knows.
Requires Shown only where something becomes public; on a private send nothing does, and a score there would be theatre. Next: usability testing of what it changes in what people do.
Who can see your payments, and what they did with it
BuildingViewing keys issued to a named holder with a stated scope, an expiry and a use count, revocable without the holder's cooperation, alongside a log of every use including refused ones.
Requires Export and the scoped share link itself, which is the rest of evidence bundles.
Security review of the circuit and contracts
BuildingStatic analysis over the contracts and the application code, a web scanner over the running application, and a line-by-line reading of the circuit for any statement a prover could make that is false. Every finding is tracked, and each fix lands with a test that pins it.
Requires The circuit widened for batches and the note format settled, so what is reviewed is what ships.
A written threat model
NextWhat an observer of the chain, a relayer, an RPC provider, an indexer and a timing analyst can each learn, written down and argued rather than assumed. Everything we say about privacy is measured against this document.
Requires Nothing. It is the gate the others are measured against, and it is the one we should hold ourselves to first.
Evidence the pool can hide anyone
NextPrivacy grows with the activity a pool holds. This is the measurement of how much unrelated activity a pool holds and what that means for a single payment in it: the number behind every privacy claim, and the reason the solvency page opens only once publishing its figures does not itself leak.
Requires Design partners paying through the pools.
Reconciliation
LaterAn internal ledger of private payments that ties back to receipts and to the pool, in the shape an accountant already expects.
Requires The signed receipt chain above.
Compliance
1/5 builtWhat must be checked before money moves, and what are we allowed to operate at all?
Screening against the public lists, every vendor a key away
✓ BuiltSeven public sources fetched into our own tables and matched there: OFAC SDN names and aliases, the OFAC consolidated list, the digital-currency addresses OFAC publishes, the UN, EU and UK OFSI consolidated lists. The Chainalysis sanctions oracle on Ethereum is read for every address. Chainalysis's API, TRM, OpenSanctions, Companies House, OpenCorporates, Sumsub and Persona sit behind the same provider interface and switch on the day a key exists; the screening page lists each as off, with the variable, until then. A payee is screened when added, when a wallet is set, when a run is raised and every Monday. A match refuses the run by name; a near match holds the line until a person clears it with their name and one sentence on the record. Every screening is stored with every provider's answer and the list date it used.
Requires A provider key, which switches on business verification of the paying organisation through the register and document providers; the wiring is in place.
The licensing answer
BuildingWhich licence this needs, if any, and in which jurisdictions. Screening and business verification are built so that each provider switches on per jurisdiction, and the answer decides which.
False-positive review and escalation
BuildingA near match is cleared by a named person with a sentence that stays on the row and in the audit log, and the screening that found it is kept beside the decision. A held payroll line is released while its run is in progress. What remains: an owner and a clock on the review itself, and the decision carried into the evidence bundle.
Requires The evidence bundle to carry the screening row a payment was decided on.
One committed design partner
NextAn organisation that has said yes to running a real payout cohort, not an expression of interest. Their cohort decides which parts of this matter most.
Requires The wedge interviews clearing the threshold they were given before they were run.
Data retention and deletion
NextWhat is stored (encrypted private balances, receipts, logs), for how long, and on what legal basis.
Requires The licensing answer above.
Platform
6/12 builtWhat makes the rest usable, operable, and safe to depend on?
The control plane as an API
✓ BuiltOne call decides allow, hold or refuse, writes the payment and its receipt chain, and returns the receipts; a second reads a payment's state and full chain so an agent can watch it settle without touching a chain node. Retries are idempotent, a repeated request must never become a second payment.
Requires Policy evaluation and the agent registry.
The demonstration environment does what the product does
✓ BuiltTest mode is not a slideshow. Sending decides a payment against the policy in force, opens a hold when the policy calls for one, and writes a receipt that verifies; mandates, agents, payees and approvals all write real rows. The same code answers the API, so a payment made through the interface and one made through the API cannot be decided differently.
The product's own claims, checked against its data
✓ BuiltTwenty-one statements the interface makes: a mandate cannot permit more per payment than per day, a held payment has an open or escalated hold, a receipt names a predecessor that exists, asserted against the database rather than assumed. They exist because the screen and the data behind it are written by different code and nothing else compares them.
The design system
✓ BuiltWritten principles and a tokens file every screen derives from: a paper canvas, one accent, hairlines, and verdict colour used only for verdicts.
The application shell
✓ BuiltOne Next.js app for the marketing site, the payer and payee surfaces and the API, with the browser/server boundary enforced by the build rather than by convention.
Magic-link sign-in
✓ BuiltSign-in protects live organisation data; the seeded test environment needs no account, so the product can be seen before it is trusted with anything.
A generated test environment, not fixtures
BuildingTest mode is currently hand-written rows scoped to one screen, which is why other screens had nothing to read. A deterministic generator builds a whole organisation from one seed, agents, instruments, traffic over a window, and a declared scripted incident, so every screen has real data to query.
Test mode, seeded against empty live
BuildingA simulated environment seeded with a demo organisation sits next to a live mode that starts empty and shows the states we designed for it: the same queries serve both, scoped by environment.
Requires Every remaining screen wired to the same environment-scoped queries the shipped ones already use.
Notifications for the first customers
NextThe payer’s system tells its payees a payment is coming; a payee’s own client finds it by scanning. Signed, idempotent, retried webhooks on the payer side.
Requires The launch surface decided (below) and the indexer scanning continuously (settlement).
Service monitoring, incident response and support
NextRelayer and indexer health, on-call, and a support path that never requires Recurro to see anyone’s private data.
Requires The relayer set and indexer running in production, not just on a devnet (settlement).
CSV-first or API-first
LaterOne surface is primary for the first customer; the other follows once a second kind of partner needs it.
Requires A committed design partner to build the primary surface against, rather than guessing.
Connectivity
LaterApproving a run from a second device, scanning to check out, encrypted delivery that holds no personal data: sessions and pairing over the same private delivery path a payment already uses.
Requires Everything above.
Scope cuts are recorded here, not deleted. If something on this page turns out to be wrong, it changes here first.