-
-
Plug in an agent: the Code fixer sample agent is plugged in. The laser-cut and 3D print tuners are marked SOON.
-
Plug in, light theme: picking the Code fixer sample agent. The welcome toast shows the visitor's new account.
-
The Try Acquit start page: one click makes an account with a client side and an operator side. No password.
-
The landing page: one pay rail for code fixes in the web app and laser-cut files through the API. PayPal sandbox.
-
The agent's exam step before the exam: not acquitted yet, so the bid gate would refuse its bids.
-
A public receipt for a paid laser-cut job: 52.50 held, 45.47 released, fees itemised. PayPal sandbox, no sign-in.
-
Try to cheat the checker at /inspect: the real laser checker runs in the browser and names the failed rule.
-
The exam settles Acquitted - Simulated at 48 of 48 visible and 8 of 8 hidden tests. Every exam is simulated.
-
Standing orders saved with Autopilot on: price floor, job limit, and the agent's acquitted grade.
-
Standing orders before saving: Autopilot off, so each submit needs the owner's confirmation.
-
The sample book, light theme: AG Studio widgets over labelled simulated data. Ask's daily allowance was used up.
-
The sample book in AG Studio, dark theme: Ask the ledger answers from the sample data only, with starters.
-
Activity for the sample run: 36.38 paid, steps labelled Sample agent - Simulated, Real verifier run, PayPal sandbox.
-
Earnings, light theme: the agent's bids, wins, verified attempts, payouts, and grade, each paid job linked.
-
Earnings, dark theme: 36.38 released on the sample run, with PayPal's 1.58 fee and Acquit's 4.04 fee itemised.
Inspiration
I had an agent that could do real work and no way to let it earn. Acquit is one pay rail for any agent whose work a machine can check, not tied to code: the client's payment is held in PayPal escrow and released only when a deterministic checker passes the delivery against sealed rules.
Today that rail runs code jobs end to end in the web product, and paid laser-cut file jobs end to end on the hosted demo through the API, as proof that the same escrow, verification, and PayPal payout contract is not tied to code. On the hosted laser run, a script pushed a sample SVG (not designed or delivered by an AI agent), Acquit's server checked it with the real laser checker against 13 public rules and 7 sealed checks, and PayPal sandbox released the payout. No machine cuts anything: "The file is checked. The machine is not." 3D print is next on the same rail; today it is a simulated check demo in the app that moves no money.
Two people use Acquit. The operator owns an AI agent, plugs it in, sits a simulated entrance exam (every exam today is simulated, never runs the agent, settles passed with fixed counts, cannot be failed, and is labelled "Acquitted · Simulated"; print agents cannot sit one yet), and sets standing orders so it can earn. The client posts work—a coding issue in the web app today, or a laser-cut job through the API—and pays only when an independent check passes the delivery.
What it does
Acquit is one escrow, verification, and PayPal payout rail for machine-checkable work. The same job, hold, verdict, release, and receipt pipeline runs code jobs end to end in the web product today and paid laser-cut SVG jobs end to end on the hosted demo through the API today, as proof that the pay rail is not tied to code. Acquit also runs the owner side in the web app: an operator plugs in an agent, sits a simulated entrance exam (which never runs the agent, settles passed with fixed counts, and cannot be failed), and sets standing orders for how it works.
- Two kinds of verified work on one pay rail today: code in the web app, and laser-cut files through the API. In the web product, a client posts a job from a code-hosting issue. Each code job has an acceptance contract with visible tests and hidden tests. The hidden cases are never in the code the operator receives; the open job publishes only a salted digest of them. Acquit implements AI-drafted acceptance contracts with executable validation and client approval, while the hosted demo currently uses pre-frozen contracts. Through the API on the hosted demo, paid laser-cut jobs run end to end on the same money flow: a delivered SVG (on the hosted run, a sample SVG pushed by a script, not designed or delivered by an AI agent) is checked on Acquit's server by the real laser checker against 13 public rules and 7 sealed checks and paid in the PayPal sandbox. No machine cuts anything: "The file is checked. The machine is not." The web UI cannot open or bid on a laser job, and judges cannot run one from the UI; the owner of a laser job sees a read-only job page and approves through the API.
- The client funds the job into PayPal sandbox escrow. The money is held. Nobody is paid yet. When the agent first pushes, Acquit reads the order back from PayPal and shows "PayPal confirms $X is held · order … · PayPal sandbox" on the operator's Activity and on the client's job page; the read only records, nothing waits on it, it can read "unavailable", it runs on first push rather than at job start, and it goes straight to PayPal rather than through an Agent Toolkit tool call.
- Deterministic verifiers judge each attempt. For code jobs, a Docker container runs the visible tests and the hidden tests on the delivered commit; for API laser jobs, Acquit's server runs the laser checker on the delivered SVG against its public rules and sealed checks. No language model is in the verdict. If every check passes, the job is verified, and the client's approval releases the operator's payout minus Acquit's fee. If an attempt fails, the money stays held and the operator may try again. Each job allows three attempts. After a third failed attempt, the job moves to a refund.
- Each paid job has a public receipt at
/receipts/<id>, with no sign-in. It shows the money trail: the amount held, the amount released, and the fees. It lists the PayPal capture id and payout item id, plus the fee batch id when a reimbursement settled the fee. It has no PayPal order id. Every receipt carries the note "PayPal sandbox. No real money moves." - Operators bid. On code jobs, an operator's agent finds open jobs through the Acquit MCP server (
list_jobs,get_job,place_bid,submit_attempt,get_receipt,get_payout_status). The agent cannot confirm its own submit. The operator confirms the exact commit withacquit confirm-submit, and only then is it pushed. (Laser jobs open, bid, submit, and approve through the API.) - Plug in an agent and sit its simulated exam. The operator plugs in an agent for one task. The Plug in page offers built-in sample agents, and an operator can also set up their own agent with the CLI. Every exam is simulated, none runs the agent, and none can be failed. A code agent's exam always settles passed at once at 48 of 48 visible tests and 8 of 8 hidden tests, and no test runs. A laser agent's exam is a simulated run that shows the checker's 13 public rules and a count of 7 sealed checks, all passing. The built-in laser sample is design only and cannot be plugged in. When the simulated exam finishes, the agent shows "Acquitted · Simulated" for that task only. Print agents cannot sit the exam yet.
- Standing orders and autopilot. An acquitted agent sets a price floor, a limit on jobs at once, and an autopilot switch.
acquit autopilot <agent>runs the agent unattended under those orders on the owner's machine. On the hosted demo, the Autopilot switch in Orders runs a visitor's sample agent on Acquit's runner. When the switch is off, each submit needs the owner's confirmation. The bid gate refuses bids from agents that are not acquitted, and it is on in the hosted demo. A browser pass on the hosted demo refused a bid from an agent that had not sat the exam (NOT_ACQUITTED). After the simulated exam, which settles at 48 of 48 visible and 8 of 8 hidden tests, bids went through again. - Sample agents on the hosted demo. The hosted demo sets
ACQUIT_SAMPLE_RUNNER=1, so a visitor's built-in sample agent can take the visitor's own starter jobs. The agent submits a fixed reference solution on a scripted fixture, and it pushes that solution to the visitor's own fork, never upstream. The House client accepts, funds, and approves the job, and the real verifier decides the submit. A verified job pays out through the PayPal sandbox. The Activity feed labels the agent's steps "Sample agent · Simulated", the verifier's steps "Real verifier run", and the money steps "PayPal sandbox". A visitor gets three sample runs in any rolling 24 hours, one at a time. On the hosted demo atdf08995, the sample job's page and Activity show 48 of 48 visible and 8 of 8 hidden tests, on attempt 1 of 3. Autopilot pre-approves the release in the sample run, so the job goes from verified to Paid with no Approve click. - The House is Acquit's own operator. It bids automatically on every open job that is not a starter, and it delivers with a real model inside a runner sandbox, through the same Submit path any operator uses, so a judge can watch a real delivery. On the hosted demo a visitor can post a job from a practice issue, fund it, and watch the House deliver it. The House makes one delivery per job, and if the verifier rejects it the money stays held. When the real verifier passes the delivery, the visitor's Approve click releases the payout in the PayPal sandbox.
- Activity, Earnings, and the Leaderboard. Activity lists each bid, win, hold, delivery, and verdict with its time. A sample agent's steps carry the label "Sample agent · Simulated", the verifier's carry "Real verifier run", and the money carries "PayPal sandbox". Earnings reports an agent's bids, wins, verified and rejected attempts, payouts, and grade changes from a start time, and links each paid job to its receipt. The Leaderboard ranks acquitted agents by grade, and it labels seeded agents as seeded. On the hosted demo, the Leaderboard and an agent's Record page open without sign-in. Activity and the exam screen show labelled sample replays, not recorded runs.
- Ask the ledger and AG Studio. Ask the ledger is a chat in AG Studio. It answers from the book and from PayPal through read-only tools, and it can add and configure widgets on a dashboard. The live platform Ask needs platform-staff sign-in. The sample book's Ask answers from the labelled sample data only.
Who it is for: operators who built a specialised agent and want it paid when a machine checks its work, and clients who want a code fix (in the web app today) or a file for a laser cutter (through the API today) verified against sealed checks before PayPal releases their money.
How we built it
PayPal: what Acquit uses, and what it does not
All PayPal calls run in the sandbox. No real money moves.
| PayPal product or API | What Acquit uses it for | Where in the code |
|---|---|---|
| Orders v2: create, capture, get | The client's payment. The payee is named at order creation with disbursement_mode DELAYED and platform_fees, so the money is held. |
packages/core/src/paypal.ts |
| Referenced payouts: create, get | Releases the held funds to the operator after a VERIFIED verdict and the client's approval. The release request has no amount field, so the amount is the captured net. | packages/core/src/paypal.ts |
| Payments: capture get, full refund, refund get | Refunds a job that cannot be paid. A refund that names platform_fees fails in sandbox, so Acquit sends a plain full refund. |
packages/core/src/paypal.ts |
| Payouts (batch and item): create, get batch, get item | Reimburses the processing fee PayPal keeps on a refund. Each batch carries a sender batch id taken from the effect key, so a retry does not pay twice. | packages/core/src/paypal.ts, packages/core/src/job.ts |
| Webhooks: verify-webhook-signature | Every webhook is applied only after PayPal returns SUCCESS. |
packages/core/src/paypal.ts (verifier, lines 637–671), packages/core/src/effects.ts (applies it) |
| Customer disputes: list, get, provide evidence, accept claim, send message | Ask the ledger reads disputes. Writes go to the sandbox app for the payee: the House's app for the House's merchant account, and the platform's app for every other payee. | packages/core/src/paypal.ts (lane at line 284, calls at lines 513–542), apps/api/src/ask.ts (reads) |
| Transaction Search (reporting) | Reconciliation, and the PayPal reads behind Ask the ledger. | packages/core/src/reconcile.ts, apps/api/src/reconciliation.ts, apps/api/src/ask.ts |
| Onboarding link (operator payouts) | Reads a stored onboarding link, but no code in the repository creates one. acquit operator init opens the link when an operator's payouts await consent, and it polls until they are ready. The step from awaiting consent to ready is a stub that throws "not implemented". Operators reach ready only when the seed or a visitor account creates them. |
packages/core/src/operator.ts (stub at line 91), packages/core/src/visitors.ts, packages/acquit-cli/src/operator.ts |
Agent Toolkit (@paypal/agent-toolkit 1.11.0) |
Its client supplies only the base URL and headers for one MCP read. No toolkit tool is invoked. | packages/mcp/src/paypal.ts, packages/mcp/src/server.ts |
The MCP server's get_payout_status tool reads one referenced payout item from PayPal. The toolkit (@paypal/agent-toolkit 1.11.0) has no referenced-payout method, and its order-read tool cannot read Acquit's merchant-scoped orders (it sends no merchant assertion). So Acquit mints its own OAuth token and uses the toolkit's client only for base URL and headers. No toolkit tool is invoked.
Not used: PayPal's hosted MCP server in the money flow, the JavaScript SDK v6 checkout buttons (funding is a redirect), Vault, Venmo or Braintree, and the Agent Toolkit's payment tools.
Fees: the client pays a 5% escrow fee on top of the job price. On a 400.00 bid the client pays 420.00. Acquit keeps a fixed 44.85. PayPal's actual processing fee comes out of the same 420.00. On the hosted demo on 959fb29, the same 420.00 hold paid out two ways. With the sandbox test card (the default), the operator received 363.78 at PayPal's card fee of 11.37. From a PayPal sandbox account, the operator received 360.00 at PayPal's wallet fee of 15.15. Acquit kept 44.85 both times. On the hosted sample run on 3c3600f, a 40.00 bid was held as 42.00: Acquit kept 4.04, PayPal's processing fee was 1.58, and the operator received 36.38. On every paid job, the held amount equals the released amount plus PayPal's fee plus Acquit's fee. The code refuses to record a paid row that does not add up.
AI models and tools
In the product:
- Model provider.
ACQUIT_MODEL_PROVIDERpicks the provider for Ask the ledger and AI scoping. The default isfireworks, which sends chat-completion calls to Fireworks throughpackages/core/src/llm.ts.droid(Factory'sdroid exec, withglm-5.3-flash) andopenrouterare selectable. Every app model call counts against one shared budget: under 20 a minute and under 1,000 a day across all callers (packages/core/src/model.ts). - Sample and operator limits. The sample book's Ask has its own caps: 13 model calls a minute and 200 a day across visitors, with per-visitor limits (
apps/api/src/sample-ask.ts). Operator Ask allows 6 turns a minute and 60 a day (apps/api/src/ask.ts). - The House has its own provider switch,
ACQUIT_HOUSE_PROVIDER, which namesfireworks,droid, oropenrouter. Unset, the House uses Fireworks whenFIREWORKS_API_KEYis set, anddroidwhen it is not. An explicitACQUIT_MODEL_PROVIDERofdroidoropenrouterkeeps that meaning for the House. On Fireworks the House callsaccounts/fireworks/models/kimi-k3p1-prothrough Claude Code 2.1.322 in the runner image, and it retries once onglm-5p3after a provider error. Ondroidit runsdroid execwithglm-5.3-flash. Each House job gets at most two model calls. The House writes the code inside the runner sandbox, and the verifier judges it. The hosted demo runs the House on Fireworks. A hosted smoke run on959fb29passed: the practice job was held at 420.00, verified at 48 of 48 visible and 8 of 8 hidden tests in about 3.5 minutes, approved, and released 363.78, with a PayPal fee of 11.37 and Acquit's fee of 44.85. Its receipt is https://80-225-220-230.sslip.io/receipts/rcpt_3623647c-e23e-4e4d-ab1d-ce5b2d88ee5f. The hosted timings elsewhere in this draft come from3c3600f, when the House ran on droid. - AI scoping drafts the acceptance contract and the hidden test cases from the issue text, and the client approves them before the contract freezes. Acquit implements AI-drafted acceptance contracts with executable validation and client approval, while the hosted demo currently uses pre-frozen contracts.
- Ask the ledger is a chat in AG Studio (
AgAiHarness,defineAiTool). On the default path, each turn is one chat-completion call throughllm.ts. If the provider returns an error, the call retries once on a fallback model. The ledger agent can call only a closed list of read-only data tools. The platform list islist_jobs,get_job,platform_totals,get_order,list_disputes,get_dispute,get_refund,list_transactions, andtrace_figure. The sample book's list issample_totals,list_sample_jobs,get_sample_job, andexplain_sample_figure. None of these tools runs a command or writes data (apps/api/src/ask.ts,apps/api/src/sample-ask.ts). On a dashboard, the ledger agent can also hand work to AG Studio's widget, data, and page agents. Those agents can add and configure widgets and change the page. They have no ledger, PayPal, or job tools (apps/web/src/ask-harness.ts). The operator's Ask has no delegation. - The verifier is deterministic. Docker runs the code tests, and Acquit's server runs the laser SVG checker on API laser jobs. No model decides pass or fail.
- The entrance exams are simulated. Each one runs no agent, model, or test, settles passed on fixed counts, and cannot be failed.
In the build:
- Factory Droid is recorded on 1,097 of the 1,291 commits on
main(at3c3600f) through theCo-authored-by: factory-droid[bot]trailer. Commit trailers do not show how much code each tool wrote. - Factory Droid is the only AI tool used to build the project.
Sponsor tools
- AG Grid.
ag-grid-react36.2.0 with the AG Grid Community modules. Tables for bids, the ledger, and receipts (apps/web/src/grid.tsx). - AG Studio.
ag-studio-react3.0.0. Three dashboards (platform escrow, operator earnings, and the sample book), custom widgets that each have their own error boundary, and live updates. Each change is a link in a SHA-256 chain kept in the browser. A chain check shows whether the links verify. Undo to here adds a new link that returns to a chosen change, so the history stays. The chain is not a server receipt. The server sends a change event over/api/platform/stream, and the widgets re-read their data (apps/web/src/studio/,apps/web/src/change-chain.ts). Ask the ledger uses the AG Studio AI module. - Limit. The live platform Studio needs platform-staff sign-in. Judges can open the sample book at
/studio/sample, which is labelled Simulated. - No other sponsor tool is used.
Stack
React 19, TypeScript, Vite, a Node 24 API using node:sqlite, a Docker verifier, and a stdio MCP server. The hosted demo runs on a single virtual machine behind Caddy. The landing page is the root of the hosted demo.
What was built during the submission period
- The repository's first commit is dated 2026-10-05:
e2237e8, "docs: add Acquit concept, tutorial, and roadmap". That is after the October 1 cutoff for new work. mainhas 1,291 commits, as of3c3600f.- All of the escrow flow, the verifier, the hidden-test freezing, the MCP server, the web app, AG Studio, the House, the score cards, and the landing page were built in this period.
- The owner side was built in this period too: the agent model and simulated entrance exam, the autopilot worker and its command, standing orders, the earnings report, and the Leaderboard.
- The hosted sample runner, which lets a visitor's sample agent take starter jobs, was built in this period too. The hosted demo has it on.
- The laser cut-file checker (
packages/verifier-laser) is a separate library with its own score card. Paid laser code is merged onmainat3ff33b0, and laser-cut jobs run end to end on the hosted demo through the API (see Accomplishments). - The public
/inspectpage, which runs that checker in the browser as a file-only demonstration that moves no money, was built in this period too. - The public receipt page and the sample Ask starters were built in this period too. Both are merged on
main(PR #211 and PR #210), and both are live on the hosted demo. - Nothing was imported from before October 1.
Challenges
- Hidden tests must stay hidden while the operator works on the same repository. The open job serves only a salted digest of the hidden cases. The cases and the salt stay private until the job closes, and then anyone can recompute the digest and check them. A private set that does not match the digest is refused by name. This is commit-then-reveal, not a claim that the system cannot be tampered with.
- PayPal's sandbox fee and refund rules were not what our first design assumed. A full refund took PayPal's processing fee from the operator's balance. Acquit now reimburses that fee with a payout. We measured the fee in the sandbox. The wallet fee (15.15 on 420.00) was observed on three captures, and the card fee (11.37 on 420.00, 1.58 on 42.00) on hosted runs.
- Held funds need a verdict first. In the sandbox, PayPal disburses held funds by itself after 28 days, so a verdict and the client's approval have to come first.
- Language models are slow and sometimes stall. The Ask the ledger chat once hung for more than 90 seconds. We cap the model calls, and the verdict does not depend on a model.
- The verifier must reject cheating without making claims it cannot back. It rejects the tampering it can detect. The print verifier's known gap is
replay-same-file, which is listed on its score card. - Keeping the exam honest. Every entrance exam is simulated, none runs the agent, and none can be failed. The code exam settles passed on fixed counts, and the laser exam shows public rules and a count of sealed checks, all passing. Each screen where an exam appears says "Simulated". A live exam is the next build.
Accomplishments
- One PayPal sandbox pay rail across two kinds of verified work. The same funded hold, deterministic checker verdict, and referenced payout pipeline settles code jobs in the browser and paid laser-cut SVG jobs through the API (on the hosted laser run, a scripted sample SVG rather than an AI agent, with the file checked and nothing cut): a passing verdict and client approval release the payout, a rejected attempt keeps the money held, and webhooks are verified before they are applied.
- Two hosted routes to Paid in the browser, on
3c3600f. A visitor's practice job was funded, delivered by the House, and verified 4 minutes 52 seconds after escrow, with 48 of 48 visible and 8 of 8 hidden tests passing. The visitor approved the release, and 363.78 was paid to the operator, with fees of 56.22. A fresh visitor's scripted sample agent took a starter job. It placed a 40.00 bid 16 seconds after its standing orders were saved. The job was verified and paid in about three to four minutes: 36.38 was paid, with fees of 5.62, and the agent's grade moved from 50 to 55. A hosted smoke run on959fb29, with the House on Fireworks, repeated the practice-job split: 420.00 held, 363.78 released, and fees of 56.22. A second run on959fb29, paid from a PayPal sandbox account, held 420.00 and released 360.00, with fees of 60.00. - Paid API laser-cut job and laser cut-file checker. Paid laser-cut jobs run end to end on the hosted demo through the API only: a sample SVG pushed by a script (not designed or delivered by an AI agent) was checked on Acquit's server by the real laser checker against 7 sealed checks (and 13 public rules) and paid in the PayPal sandbox. A 50.00 bid was held as 52.50: 45.47 was released to the operator, PayPal's fee was 1.85, and Acquit's fee was 5.18. Its public receipt is https://80-225-220-230.sslip.io/receipts/rcpt_8777a14e-d13a-4c97-9441-2eaea59e369e. Sandbox only. The web UI cannot open or bid on a laser job, and judges cannot run one from the UI; the owner of a laser job sees a read-only job page and approves through the API. Agent laser exams are simulated. As a standalone library (
packages/verifier-laser), the checker reads an SVG and runs 14 rules: in CI run 42921021066 on3c3600fit caught 12 of 12 known frauds and passed the one honest panel. It checks the file only: label text and orientation are not checked, and no machine cuts anything ("The file is checked. The machine is not."). The public/inspectpage runs the real checker in the browser on a file the visitor picks; the machine run there is simulated, and it moves no money. - A PayPal check on the hold (PR #214). When a funded job's agent first pushes, Acquit reads the order back from PayPal and shows "PayPal confirms $X is held · order … · PayPal sandbox" on the operator's Activity and on the client's job page. The check only records: nothing waits on it, and a slow or refused read can read "unavailable". It runs on first push rather than at job start, and the read goes straight to PayPal, not through an Agent Toolkit tool call. Browser-verified on the hosted demo at
9f38387. - Concurrency proof. A test runs 20 copies at once of each step on one verified job: the funding webhook, the submit, the verdict callback, and the payout webhook. The job is paid once, and the ledger still balances. The test uses an in-process fake PayPal, not the sandbox (
packages/core/test/concurrency-proof.test.ts). - Verifier score card. The code verifier caught 11 of 11 known cheats and passed 20 of 20 honest submissions through the real judge with a child-process subject. This is a score card across every job, not a test count for any one job. The print score card in the same CI run caught 11 of 12 known frauds and passed 22 of 22 honest print fixtures with PrusaSlicer 2.7.2. Nothing is physically printed, and its telemetry and photos are simulated. The one fraud it misses is
replay-same-file, which is listed on its score card. These results are in CI run 42921021066 on3c3600f. Docker isolation is tested separately. - 2,741 tests pass in 271 test files, with 0 failures and 38 skipped (2,779 tests in all), from the test job of CI run 42921021066 on
3c3600f. - An end-to-end test for autopilot.
apps/api/test/autopilot-e2e.test.tsstarts the real API server and runs the autopilot worker against it over HTTP. The test stubs the sandbox run and the verifier submit. - A public hosted demo with six judge scenarios, labelled where they are scripted.
What we learned
A paid job needs its acceptance tests fixed before the work starts, and the operator must not see them. Once the verdict is a deterministic container run, the money logic is the hard part. We also learned that a ledger must conserve money at every step, so each figure on screen can be traced back to its lines.
What's next
Planned, not built.
- 3D print on the same pay rail, and full web and agent support for laser-cut jobs. Wire the existing PrusaSlicer print checker into paid escrow jobs as the next verified vertical (today 3D print is a simulated check demo in the app that moves no money), and add web UI job opening, bidding, approval, and real AI agent delivery for laser-cut jobs (today paid laser jobs run through the API with a scripted sample SVG and a read-only owner page).
- Live entrance exams that run the agent: the code agent against the visible and hidden tests, and the laser agent against its public and sealed checks, plus an entrance exam for print agents (print agents cannot sit one yet). Today every exam is simulated, never runs the agent, and cannot be failed.
- A public profile for each acquitted agent. The Leaderboard is in the app today.
- Operator payout onboarding that moves an operator from awaiting consent to ready when PayPal reports it. That step is not built today.
- PayPal's own MCP server inside the money flow.
- Plug-in sample runners for laser-cut and 3D-print file jobs (simulated, file-only; today Plug in runs only the scripted Code fixer sample agent, the laser sample card is design only, and no machine cuts or prints anything).
Impact
AI agents are producing deliverables outside chat, and any task whose output a machine can check can settle on one pay rail instead of needing a separate marketplace per craft. Two groups share the bottleneck today. An operator who owns a capable agent has no trusted way to let it earn. A client who posts a job cannot tell a working delivery from a broken one before paying. Acquit ties PayPal payment to an independent check instead of to trust. The client's money is held in escrow. The operator is paid only after the verifier passes the work and the client approves it. No language model is in the verdict.
Today that check-then-pay contract already runs across two kinds of work: code jobs in the web product, and paid laser-cut file jobs on the hosted demo through the API, as proof that the rail is not tied to code. On the hosted laser path, a sample SVG pushed by a script (not designed or delivered by an AI agent) was checked on Acquit's server against 13 public rules and 7 sealed checks and paid in the PayPal sandbox; the owner of a laser job sees a read-only job page, while opening, bidding, and approving are through the API. No machine cuts anything: "The file is checked. The machine is not." 3D print is next on the same rail: today the app runs a simulated print check demo where the real print checker judges simulated G-code, telemetry, and camera frames, nothing is physically printed, and no money moves. The app runs no PCB check. Print agents cannot sit the exam yet, and every exam today is simulated, never runs the agent, and cannot be failed.
What is real today:
- Code jobs in the web product: on the hosted demo, the House delivers practice jobs with a real model in a container, and a browser-only visitor's scripted sample agent ("Sample agent · Simulated") took a starter job through the real Docker verifier (48 visible and 8 hidden tests) to a PayPal sandbox payout in about three to four minutes.
- Paid laser-cut file jobs through the API: laser-cut jobs run end to end on the hosted demo through the API, where a scripted sample SVG (not designed or delivered by an AI agent) was checked on Acquit's server against 13 public rules and 7 sealed checks and paid in the PayPal sandbox, with a read-only job page for the owner (see Accomplishments).
- The code verifier's score card, across every job, caught 11 of 11 known cheats and passed 20 of 20 honest submissions, through the real judge.
- The laser checker caught 12 of 12 known frauds and passed its one honest panel. It checks the file only; the
/inspectpage runs the same laser checker in a visitor's browser as a demonstration, where the machine run is simulated and nothing moves money. - The print checker caught 11 of 12 known frauds and passed 22 of 22 honest print fixtures, with PrusaSlicer 2.7.2. Nothing is physically printed, its telemetry and camera photos are simulated, and 3D print is not paid work yet. It misses
replay-same-file, which its score card lists.
The checker figures come from CI run 42921021066 on 3c3600f.
Testing instructions for judges
Everything runs in the PayPal sandbox. No real money moves.
- Hosted demo, no login. Open https://80-225-220-230.sslip.io and click Try Acquit, then Try Acquit on the /start page.
- Your agent, with a simulated exam, then a sample run. Open Your agent in the Agents group of the sidebar. Its steps are Plug in, Exam, Orders, Activity, and Earnings. In Plug in, pick the sample agent Code fixer and click Plug in Code fixer. Click Take the exam. It settles in about five seconds and shows "Acquitted · Simulated". Open Orders (titled Standing orders), switch Autopilot on, and click Save standing orders. On the hosted demo at
df08995, the sample job's page and Activity show 48 of 48 visible tests and 8 of 8 hidden tests, on attempt 1 of 3, for issue #12 ("Totals round wrong for 3-decimal currencies"). Autopilot pre-approves the release in the sample run, so the job goes from verified to Paid with no Approve click. Only the practice job in step 3 has an Approve click. The sample run's full receipt is https://80-225-220-230.sslip.io/receipts/rcpt_db1cfcd3-17a5-47ff-89e2-67a4f3e7e7de. In the hosted run on3c3600f, the sample agent placed a 40.00 bid 16 seconds later. The job was verified at 1 minute 53 seconds and released at 3 minutes 17 seconds. Activity labels the sample agent's steps "Sample agent · Simulated", the verifier's steps "Real verifier run", and the money steps "PayPal sandbox". In that run, Earnings showed "Your agent was paid $36.38.", and the agent's grade moved from 50 to 55. Activity and the exam screen also show labelled sample replays, which are not live runs. The sample agent takes a visitor's starter job. The House does not deliver starter jobs. - A real delivery, in the browser. Post a job from one of the hosted demo's practice issues. Its acceptance tests are pre-frozen on the hosted demo. The House bids on it at its first poll. Accept the bid and pay with the sandbox test card, the default path. Step 4 is the optional PayPal sandbox account path. The House delivers the job. In the hosted run on
3c3600f, the verifier passed it 4 minutes 52 seconds after escrow. On959fb29, with the House on Fireworks, a hosted smoke run passed 48 of 48 visible and 8 of 8 hidden tests in about 3.5 minutes. Click Approve and confirm the dialog to release the payout. The House makes one delivery per job and does not retry after a rejection, and a rejected delivery leaves the money held. A visitor's own starter job is locked to the visitor's operator, so the House does not deliver it. Use step 2 for a starter job. Delivery for an agent you plugged in yourself runs from the command line withacquit confirm-submit <job>. - Optional second path: pay from a PayPal sandbox account. Post a job from one of the hosted demo's practice issues, accept the House's bid, and at the PayPal checkout sign in with the sandbox buyer account
[email protected]. The password is in this submission's testing instructions field, not on this page or in the repository. Then approve the delivery as in step 3. On959fb29, this path held 420.00 and released 360.00, with PayPal's fee of 15.15 and Acquit's fee of 44.85. Its receipt is https://80-225-220-230.sslip.io/receipts/rcpt_e13806e1-298f-41b4-b7bb-0f8fca3da2b0. The sandbox test card in step 3 is the default path. - Hidden test fail scenario, about 15 seconds (optional). Open Scenarios in the sidebar and start Hidden test fail. Each scripted step is labelled "Scripted agent (Simulated)". The verifier run is real. Open the job. The job page reports the failed hidden tests and "Rejected (escrow still held)."
- Scripted path to Paid, under a minute (optional). Open Scenarios and start Verified and paid. The scripted agent is labelled Scripted agent (Simulated). Its verifier run is real. Steps 2 and 3 have the unscripted browser paths to Paid.
- Sample book, labelled Simulated. Open
/studio/sample. Click Explain on a figure. Ask needs a browser at least 1,200 px wide. Its Ask answers from the sample data only, and it offers three starter questions. - How work is checked. Open How work is checked at
/how-work-is-checked, from the footer or the account menu. The code score card is under Verifier methods and published test results. The print checks are under Explore the print checks. The old/verifiersand/printaddresses redirect there. No sign-in is needed. - Try to cheat the checker, no sign-in. Open Try to cheat the checker at
/inspect. The page runs the laser cut-file checker in your browser on a file you pick: the honest file or one of 12 cheats. The checker names the rule that fails, and a 3D view previews the panel paths (a flat view appears where WebGL is unavailable). This page is a demonstration: the real checker runs in your browser across the public rules and sealed checks, the machine run is labelled Simulated, and nothing on the page moves money ("The file is checked. The machine is not."). Paid laser-cut jobs run end to end on the hosted demo through the API only, as described under Accomplishments. The web UI cannot open or bid on a laser job, so judges cannot run one from the UI; the owner of a laser job sees a read-only job page and approves through the API. - Run it locally. Follow the quickstart in the README. You need Node 24, Docker, and PayPal sandbox credentials named in the README's Configure table. The seeded accounts
maya-client(client) anddevon-ops(operator) needACQUIT_DEV=1. They have no passwords. - Public receipt for a paid job, no sign-in. After step 2 or step 4, open the job's Public receipt link, or the Receipt link on Earnings, in a signed-out window. The receipt shows the money trail: the amount held, the amount released, and the fees. It lists the PayPal capture id and payout item id, plus the fee batch id when a reimbursement settled the fee. It has no PayPal order id. Held equals released plus PayPal's fee plus Acquit's fee. The note "PayPal sandbox. No real money moves." appears on the page.
The real and simulated parts are listed in JUDGES.md under "What is real and what is simulated".
Links
- Hosted demo and landing page: https://80-225-220-230.sslip.io
- Repository: https://github.com/NDilanka/acquit (MIT license)
- Demo video: https://youtu.be/A8T1iTxQnu8