Agent online, monitoring Manoj's worksys.status: nominal
Contact

All work

A non-custodial governance layer for agentic payments: AI agents propose, the payer authorises on their own device, and every decision lands in a tamper-evident ledger with independently verifiable evidence.

Payments Infrastructure · Agentic AI

Role
Builder
Context
Self-initiated
When
Sep 2026 to Present
614Tests passing
0Invariant violations
10Stress profiles
14Rule dimensions
01

Problem

?

AI agents can now build a cart and check out. The tooling around them answers two questions: did the agent call the right tool, and did the payment succeed. The question that matters to the payer goes unanswered: was this what I authorised, and can I prove it in a dispute?

Today that proof lives in screenshots and support tickets. When a merchant captures more than the cart, an agent places a duplicate order, or a record is altered after the fact, there is no shared, verifiable record of the authorisation to reconcile against.

02

My call

I built the layer, not another agent. It is agent-agnostic, and one invariant sits above the rest: agents propose, they never authorise. No tool, endpoint or token lets an agent approve. The payer approves on their own device, with a key that unlocks only after on-device user verification, by signing a one-time challenge bound to the hash of exactly what they were shown: amount, payee and items. Any change to the cart forces a fresh approval, the same idea as dynamic linking in strong customer authentication.

The second call was deterministic, replayable decisions. The decision engine is a pure function: same inputs, same determination. Every determination is signed and carries the build digest of the evaluator that produced it, so anyone can replay it byte for byte with the open verifier, without trusting me or my database. The evidence also carries the payer's own device signature, bound to that proposal, so the verifier checks consent itself instead of taking the host's word for it.

The third was to stay non-custodial. The layer never touches funds. It holds authority: budgets, caps, holds and approvals, written as ledger entries, while money settles on existing rails between the payer and the merchant. Policy comes in three layers, jurisdiction, operator and payer, and the strictest answer wins. Every decline names the layer that wrote the failing clause and whether the payer may override it. Payers can override only their own clauses.

How it works, part A

The wheel

Everything an agent may do with a payer's money is one wheel. The payer owns the hub, each spoke is one permission, and the rim holds the rules nobody can loosen. It is drawn as a train wheel because the same system runs as a train in part B.

Tap a numbered balloon to find its card below.

1
The rim: the shared rules

The law where the payment happens and the operator's house rules, the same for every payer.

No payer can loosen them. The operator can stop a wheel, never widen it.

3
The spokes: one permission each

A purpose, a cap and an end date. Yellow repeats can run silently, blue is bound to one agent, dashed sits inside another. Every proposal names its spoke.

2
The hub: the payer's own rules

Rules for every agent, and the monthly budget. Nothing any spoke allows can go past it.

allowed = rim ∩ hub ∩ every parent spoke ∩ this spoke
fits    = room on this spoke, every parent, and the hub
1
The rim
The rules every payer shares

The law where the payment happens and the operator's own house rules. No payer can loosen them. The operator can suspend a wheel, with a stated reason, but never edit or widen what the payer set.

e.g. No silent payment above Rs 2,000. No betting merchants.
2
The hub
The payer's rules and budget

The payer's own rules for every agent, and the monthly budget. Nothing any spoke allows can go past the hub.

e.g. Never after 11 pm. Rs 15,000 a month in total.
3
A spoke
One permission

One purpose, its own cap, its own rules, and an end date. Every proposal names the spoke it uses; a spoke is never guessed.

e.g. Grocery, Rs 4,000 a month.
4
A spoke for one agent
Bound to a named agent

Only the agents the payer enrolled from their own device may use it. A name the agent gives itself counts for nothing.

e.g. Dev tools: Agent B only.
5
Further out on a spoke
A permission inside a permission

For teams and companies. A payment must fit its own cap, its parent's and the hub's, all at once.

e.g. Office Rs 20,000, and the pantry inside it Rs 5,000.
6
The yellow spoke
A repeat order

An exact order the payer signed once. The only kind that may pay without a tap, and only after a notice the payer can stop. Any surprise falls back to a tap.

e.g. The weekly list, within 10% of last time.
One payment through the wheel: Agent A proposes Rs 1,200 of groceries, naming the Grocery spoke.
  1. 4
    Is this agent allowed on that spoke? Agent A is enrolled and bound to Grocery.pass
  2. 1
    The rim: grocery is a permitted category, the rail is supported.pass
  3. 2
    The hub's rules: it is 7 pm, inside the payer's hours.pass
  4. 3
    The spoke's rules: allowed merchant, allowed items, no extras.pass
  5. 3
    The spoke's cap: Rs 1,800 left of Rs 4,000. Rs 1,200 fits.pass
  6. 2
    The hub's budget: Rs 6,000 left of Rs 15,000. Fits.pass
  7. ✓
    Allowed, with a tap. The payer sees the cart on their phone and approves. Rs 1,200 is then held on the spoke and the hub until the payment settles. Had anything failed, the answer would list every failing rule and who wrote it, not just the first.
How it works, part B

The railway

The wheel says what an agent may do. The railway shows how one payment moves. The owner fuels and drives the train, every carriage carries one permission, every station is a check, and a sealed log book records every movement.

The train

  1. 1
    Enginethe payer's rules

    Pulls the whole train. Every carriage follows its rules. The hub of the wheel.

  2. 2
    Fuel tankthe monthly budget

    One tank for the whole train, refilled each month. Nothing runs on fuel that is not there.

  3. 3
    Carriageone permission

    One purpose, its own allowance. A spoke of the wheel.

  4. 4
    Couplingwhat it is for, who may use it

    Attaches a carriage to the train. Uncouple it and the permission is gone.

  5. 5
    Crew IDthe agent's credential

    Issued by the owner from their own device. A name painted on the side counts for nothing.

  6. 6
    Timetabled coacha repeat order

    The same order every week. The only coach that may leave without a tap, after a notice.

  7. 7
    Van behind a coacha nested permission

    Needs room in the van, its coach and the tank.

  8. 8
    Speed limit boardthe shared rules

    The law and the railway's own limits. Every train obeys them and no owner can change them. The rim of the wheel.

  9. 9
    The trackpromises that never change

    The same for every train on the network, whoever runs it.

  10. 10
    Lamp on the last carriageproof it arrived

    The trip only counts as done when the station sees this lamp. The driver saying so is not enough.

Along the line

  1. 11
    Signaldoes the owner need to tap?

    Red means wait for the owner. If any rule says wait, the train waits.

  2. 12
    Stationa check

    Every payment is checked when proposed, and again just before it leaves.

  3. 13
    Ticket checkerreconciliation

    Compares what arrived with what was booked, using the merchant and the bank, and notes anything off.

  4. 14
    Log bookthe ledger

    Every page carries a seal made from the page before it, so no page can be changed quietly.

  5. 15
    Control officethe wheel's host

    Holds the wheel. Answers may it go with a signed yes or no.

How the wheel fits the train

Every part of the wheel turns up somewhere on the train. Follow a line to see where.

rim to speed limit board hub to engine and fuel tank spoke to carriage yellow spoke to timetabled coach further out on a spoke to the van behind its coach

Run a journey

Agent A wants to buy Rs 1,200 of groceries. Pick what goes wrong on the way and press Run. Each station is one check; a red stop means the train never leaves.

System words, train words

Operator and jurisdiction rulesSpeed limit board
HubEngine
Hub budgetFuel tank
SpokeCarriage
Spoke bindingCoupling
Standing instructionTimetabled coach
Nested spokeVan behind a coach
Caller credentialCrew ID
InvariantsThe track
Approval modeSignal
Settlement signalLamp on the last carriage
ReconciliationTicket checker
Hash chained ledgerLog book
Wheel hostControl office
DivergenceAccident

Where the analogy stops working

No money on the train

Fuel is permission to spend, not money. The railway checks tickets but never carries the cash; payments go straight from payer to merchant.

Couplings are not a chain

A real train is one line of coaches. Here every carriage takes its permission from the engine directly; only a van takes it from its own coach.

Allowances can overbook

Carriage allowances can add up to more fuel than the tank holds. That is deliberate: the tank still decides.

How it works, part C

The whole layer

Ten building blocks, one payment path, and a set of promises the code keeps no matter who runs it. The layer is generic: it never names a merchant, device or amount, and each country plugs in as data.

One payment, end to end

Eight steps. The payer's step is the only one that can say yes.

The building blocks

Ten parts inside one boundary. The agent, the payer, the merchant and the bank stay outside it. Tap a balloon to find its card.

1DecisionRules engine

A pure function. It checks 14 dimensions, from merchant category to time of day, takes the strictest answer, and lists every failing rule with who wrote it. Anything it cannot model is refused.

on the railway: the signal
2AuthorityThe wheel

The payer's permissions as one signed document: the rim, the hub, spokes with caps and end dates. Changes are versioned; only the payer widens.

on the railway: the train itself
3RecordLedger

Append only, hash chained, every record signed. Triggers refuse edits even from the table owner, and integrity is re-checked from the stored bytes.

on the railway: the log book
4MoneyMoney in flight

Holds, captures, releases, refunds and overcharges as postings per account and month. Usage always derives from the ledger, never from a counter.

on the railway: the fuel gauge
5ExecutionRails and merchant adapters

One idempotency key per decision. On a timeout it looks for the order before any retry, so a cart is never ordered twice.

on the railway: the line
6TruthReconciliation

Compares the ledger, the merchant and the bank. Nine kinds of finding, from overcharges to orders nobody approved.

on the railway: the ticket checker
7ProofEvidence and open verifier

A bundle per role, showing each party only their part. The open verifier checks the chain, the host's signatures and the payer's own signature on every approval, and replays the decision byte for byte.

on the railway: the inquiry file
8WhoIdentity and keys

Device keys for the payer, OAuth 2.1 with PKCE or signed proofs for agents, one time challenges, and recovery that never widens what anyone can spend.

on the railway: crew IDs
9AccessHTTP API and MCP server

The ways in for agents and devices. The MCP server has no tool to approve, override or decline: agents propose, payers decide.

on the railway: the booking office
10DurabilityWorking state and recovery

Pending approvals, challenges and tokens in Postgres under per payer locks. A payment interrupted by a crash is settled by asking the merchant, never by ordering again.

on the railway: the depot

Who is involved

protectedPayer

Owns the wheel and the money. The only party that authorises.

customerOperator

Runs the service and sets house rules. May suspend, never widen.

proposesAgent

Known by an enrolled credential, never by the name it declares.

verifiesMerchant

Checks a payment against the decision without reading the wheel.

acceptance testRegulator

Can a rogue agent be stopped, and a dispute settled from records?

Three layers of rules, one of promises

The promises are code and never change. The rest is data a deployment sets, and every decision records which versions it used. A lower layer can only narrow what the layer above allows.

The promises it keeps

Checked by tests on every commit, and by every simulated run in the stress campaign.

  1. 01Agents propose. Only the payer approves, on their own device.
  2. 02The payer approves exactly what they were shown. A changed cart is shown again.
  3. 03Anything the model does not know about is refused, never waved through.
  4. 04The strictest rule wins, and every refusal names who wrote the rule.
  5. 05Money moves only after a hold that fits the spoke, every parent and the hub.
  6. 06One approval, at most one order. No blind retries after a timeout.
  7. 07No record can be changed or removed quietly. The chain shows it.
  8. 08Any decision can be replayed from its inputs by anyone, without trusting the host.
  9. 09Each party sees only their part: the merchant never reads the wheel.
  10. 10Held money is always explained: by a payment in progress or an open finding.
  11. 11The layer never holds anyone's money. It holds authority.
  12. 12Recovering a lost device never widens what anyone can spend.
How it works, part D

Plug it in

The layer is a reference implementation, not a hosted service: Python packages and one host service you run yourself. It meets the world through four ports, and each one is a small, fixed interface.

Try it

Needs uv and the PostgreSQL binaries. The tests and demos start a throwaway database of their own.

git clone https://github.com/manojacharix/governed-agent-payments
cd governed-agent-payments
uv sync
make demo     # agent proposes, payer approves, an overcapture is caught, a forged bundle fails
make stress   # ten adversarial profiles, every invariant checked

Build on it

Who plugs into which port, and the calls they use.

OperatorRun the host

Pick a jurisdiction mapping, India or the UK, and write a Tier 0 config for your house rules. The repo ships three: personal ordering, B2B procurement and a UK personal example. Then run the one host service on your own Postgres.

mappings/ · tier0/examples/
Merchant integrationWrite an adapter

Implement the merchant adapter protocol for the shop you connect: carts, placing an order with an idempotency key, order status, cancels and refunds. Two contract-tested fake merchants show the shape.

get_cart · place · get_order · list_refunds
Agent developerConnect an agent

Register with OAuth 2.1 and PKCE, get enrolled by the payer, then propose over MCP or HTTP and hand the proposal to the payer. There is no tool to approve.

propose_order · get_determination · proceed_to_pay
Payer's appApprove on the device

Fetch a challenge for the proposal, sign it with the device key after on-device user verification, and send approve, decline or override.

POST /v1/proposals/{id}/challenges
AuditorVerify a bundle

Run the open verifier on an evidence bundle, against the pinned host key and the evaluator's build digest. It replays the decision and checks the payer's own signature on every approval, without trusting the operator.

verify_bundle(bundle, key, evaluator, rp_id=...)

Before a real deployment it still needs an adapter for each merchant, a hosting choice, a purge job for expired state, failover testing across machines, and confirmed licences for the merchant category and GS1 code lists.

03

What I shipped

A working layer in Python and Postgres, delivered in nine phases.

A decision engine that evaluates 14 policy dimensions on every proposal, strictest wins. A permission model drawn as a wheel: a budget at the hub, scoped spend permissions on each spoke with their own caps, merchants and end dates, nestable for teams, plus standing instructions for repeat orders within a signed price tolerance. A signed, hash-chained, append-only ledger that rejects edits even from the table owner and tracks budget holds per period. Merchant adapters with idempotency keys and safe retries. Three-way reconciliation across the ledger, the merchant and the bank, with nine finding types, from overcaptures to orders nobody authorised. Evidence bundles with role-scoped disclosure, checked by an open verifier that replays the decision and checks the payer's own signature on every approval. Identity with device-bound keys, OAuth 2.1 with PKCE for agents, and account recovery through a backup key, or a waiting period with recovery questions, completed on a new device that passes user verification. Jurisdiction mappings for India and the UK, with rail profiles for UPI, e-mandates and cards, and for Faster Payments and Open Banking. An HTTP API, and an MCP server for the layer itself: six tools for an agent to propose, check a determination and hand off to the payer, and none to approve.

Then I tried to break it.

Stress profiles, 0 violations10.
04

Outcome

make demo runs the whole flow end to end. An agent proposes over MCP, the payer approves on their device, the merchant overcaptures by Rs 7, the bank statement shows it, reconciliation raises an overcapture finding, and the open verifier passes the payer's evidence bundle. Then the bundle is edited to hide the overcapture, and the verifier rejects it.

A stress campaign fuzzed every entry point and ran the full flow under ten adversarial profiles: merchants that time out and overcapture, a bank feed that is late and wrong, device compromise and recovery, proposal bursts, amounts at the limit of the money type, and a budget period rolling over at midnight. It surfaced ten real defects, the worst a race condition in which concurrent requests corrupted each other's transactions. Each one is fixed and pinned by a regression test. The final sweeps ran about 29,000 simulated proposals with zero invariant violations, in memory and again on durable Postgres state.

A follow-up security audit went after what the simulator never tried, and found eight loopholes: among them an agent citing one merchant while the cart sat at another, and a host able to record an approval without the payer's signature in the evidence. All eight are closed, each pinned by a regression test, and three further security reviews tightened the verifier until every consent check fails closed.

614 tests pass, and every stress profile still runs clean. The whole infrastructure is on GitHub: the code, the specs, the stress campaign and every test, at manojacharix/governed-agent-payments.

05

How I built it

Spec-first. Seven specs and a model spec defined every record, rule and invariant before any code, and each phase had to pass its own tests and a seeded simulation before the next began. The specs also map each spoke onto an AP2 open mandate; that mapping is specified, not yet built. I built it with Claude Code as my pair: I wrote the specs, made the calls and ran the review gates.

The ledger is Postgres with append-only triggers, per-chain locks and a signature on every record, re-verified from the stored bytes, so even a superuser edit is detected. Canonical JSON (RFC 8785) and ES256 signatures keep records verifiable outside the system. Working state, such as pending approvals, challenges and tokens, lives in a separate Postgres store under per-payer advisory locks with version-checked writes, so several server processes can share it and any of them can restart. A payment interrupted mid-execution is recovered by querying the merchant with its original idempotency key, never by resubmitting the order.

Testing leaned on synthetic data: property-based tests, a seeded simulator with a shadow ledger, and mutation checks proving the concurrency tests fail when the locks are removed. Automated security reviews ran on every commit, and I fixed what they found, including a redirect URI check a lookalike host could pass and a lockout counter a database rollback could erase.

TagsAgentic AIPaymentsInfrastructure0-to-1
Next case study

Got something to build?
Let's talk. Actively looking for Product Manager roles in payments and agentic AI.