-
-
Deterministic receivables baseline — Three fictional accounts and three safe agent tools before approval.
-
Approval changes the tool surface — One uniquely scoped execution capability appears after human review.
-
Stale permission disappears — Drift applies nothing and removes the approved execution capability.
-
Exact rehearsal before action — Complete simulated ACME reminder, Jones assignment diff, and Smith policy block.
-
Receipt separates proposed, authorized, executed, and blocked — The final record explains what happened and whether reality changed.
-
Rehearsal against current reality — ACME is no change, Jones remains proposed, and Smith remains blocked.
Short description
LedgerRehearsal is a WebMCP accounts-receivable demo where a human and an agent review the same exact business transition before the webpage exposes a one-time capability to execute it. If reality changes after approval, the page removes that capability and requires a fresh rehearsal.
Inspiration
Approval interfaces often live beside an agent rather than inside the interface the agent can actually use. A screen may say “approved” while the agent’s available actions remain unchanged. LedgerRehearsal asks a narrower question: what if the WebMCP tool surface itself became shared interface state between a person and an agent?
The project uses a familiar accounts-receivable scenario because the stakes are easy to understand. An overdue reminder may be reasonable when an invoice is unpaid and wrong seconds later if a payment arrives. The interesting moment is not generating the reminder; it is proving that a previously reviewed permission disappears when its factual basis changes.
What it does
The agent begins with three safe tools: inspect_accounts, propose_collection_actions, and rehearse_transition.
The first rehearsal proposes an overdue reminder for ACME, proposes assigning Jones to Maya Chen, and blocks a final notice for Smith because the invoice is disputed. The human reviews the complete simulated message, exact before/after values, effects, and blocked reason in the webpage.
Human approval then makes one uniquely named, zero-argument execution capability appear. Before the agent uses it, the human simulates ACME’s payment. That state change invalidates the reviewed transition, so stale execution applies no business mutation, creates no outbox effect or receipt, and removes the capability.
The agent rehearses again against current reality. ACME becomes NO_CHANGE, Jones remains PROPOSED, and Smith remains BLOCKED. A second human approval creates a distinct capability. Using it applies only the stored Jones assignment, adds one simulated outbox effect, writes one receipt, and consumes the capability so replay cannot duplicate the change.
All customers, balances, messages, and effects are fictional. There is no real email, payment provider, financial API, or external financial operation.
How it was built
LedgerRehearsal is a React 19 and TypeScript application built with Vinext for Cloudflare Sites. A D1-backed transition store keeps deterministic fictional account state, reviewed manifests, expected account versions, exact typed changes, simulated effects, blocked items, and lifecycle events.
The browser uses top-level imperative WebMCP registration through document.modelContext.registerTool(tool, { signal }), with the current Chrome compatibility path at navigator.modelContext. Each approved execution registration receives an AbortSignal so it can be removed when authorization expires, drifts, or is consumed.
The execution tool accepts zero mutation arguments. The agent cannot substitute an account, owner, message, or value after review. On execution, the server claims the transition with compare-and-swap semantics, rechecks stored preconditions, applies only stored after-values, appends simulated effects, and records the receipt. Competing callers observe the transition as no longer available, so exactly one wins inside this application boundary.
How LedgerRehearsal uses WebMCP
LedgerRehearsal explores the WebMCP tool surface itself as shared interface state. Human approval makes one reviewed execution capability appear; changing business reality removes it; successful use consumes it.
The choreography is visible in actual tool enumeration:
3 safe tools → 4 with reviewed execution → 3 after drift → 4 with replacement execution → 3 after consumption
Human approval is deliberately not an agent tool. The consequential capability appears only after a person reviews the concrete transition in the webpage.
Human-agent collaboration
The agent is good at inspecting state, proposing work, and explaining exact effects. The person owns the consequential approval. The webpage connects those roles by changing what the agent can do only after the person reviews a specific transition.
That division also makes disagreement legible. Smith is not silently omitted; the rehearsal shows the blocked action and its policy reason. When ACME pays, the system does not reinterpret the old approval. It revokes it and asks the agent and person to review the smaller current transition together.
Creativity and ambition
The project does not claim a new security primitive. Human approval, dry runs, optimistic concurrency, capability-based security, version checks, and single-use authorization all have prior art. The contest contribution is the shared-page experience: approval, drift, replacement, and consumption are reflected directly in the live WebMCP surface rather than only in a status label.
Impact
Agents become more useful when people can see not just what they plan to do, but exactly when permission exists, what that permission covers, and why it disappears. The pattern is relevant anywhere a reviewed action can become stale: finance operations, customer support, fulfillment, compliance, and other consequential workflows.
Challenges
The hardest part was keeping browser capability state, server authorization state, and business state aligned. Removing a tool from the browser is not enough if a stale handle can still reach the server, so the server rechecks the reviewed account versions and lifecycle on every execution.
Another challenge was making the scenario comprehensible without hiding the mechanics. The interface exposes exact diffs, complete simulated messages, blocked actions, lifecycle events, outbox effects, and receipts while keeping the main story readable.
Accomplishments
- A real
3 → 4 → 3 → 4 → 3capability lifecycle in supported WebMCP runtimes. - Zero-argument execution tied to a reviewed manifest rather than agent-supplied mutation values.
- Drift detection that applies zero stale business mutations and creates zero stale effects or receipts.
- Single-use application-boundary execution with replay and competing-caller coverage.
- Deterministic fictional data, visible reset, and judge-accessible public deployment with no signup.
- A 32-test suite covering registration, drift, replay, concurrency, blocked-action exclusion, outbox integrity, receipt integrity, and reset behavior.
What I learned
The most important lesson was that approval is not just a record; it can be part of an interface lifecycle. WebMCP makes that lifecycle observable to both sides of the collaboration. The browser registration still needs authoritative server checks, because a removed UI capability does not prove that no stale caller exists.
I also learned that blocked work deserves first-class representation. A rehearsal is more trustworthy when it explains what will not happen and why, instead of showing only the actions that survived filtering.
What’s next
The next step would be to generalize the choreography carefully without turning the demo into a generic workflow engine: stronger audit export, additional accessibility testing, and more supported-runtime acceptance evidence. Real email, real payments, authentication, customer data, and external finance APIs are intentionally outside this challenge build.
Testing instructions
- Open the live app in the ChatGPT desktop in-app browser, or Chrome 149+ with
chrome://flags/#enable-webmcp-testingenabled and Chrome restarted. - Use Reset demo and verify three initial tools.
- Ask the agent to inspect accounts, propose current collection actions, and rehearse them without execution.
- Review the exact changes and approve them in the webpage. Verify a unique fourth execution tool appears.
- Click Simulate payment received before execution.
- Invoke the old execution handle. Verify drift, zero business mutations, zero outbox additions, zero receipts, and return to three tools.
- Inspect, propose, and rehearse again. Verify ACME
NO_CHANGE, JonesPROPOSED, and SmithBLOCKED. - Approve the smaller transition. Verify a distinct fourth tool appears.
- Invoke it once. Verify only Jones changes, exactly one simulated outbox effect and receipt exist, and the tool list returns to three.
- Attempt replay and verify no duplicate mutation, effect, or receipt.
Browsers without WebMCP, including Safari in the current tested configuration, can inspect and operate the human-facing demo but do not expose the agent tool surface.
Links, license, and provenance
- Source: https://github.com/JAYAPLY/ledger-rehearsal
- Live app: https://ledger-rehearsal-ar.zaitahar.chatgpt.site
- License: MIT
- Challenge-period statement: this fresh repository was created on August 31, 2026; the receivables model, transition lifecycle, D1 store, WebMCP choreography, interface, tests, and evidence were built for this entry.
- ASHVUN statement: no ASHVUN source was imported or reused, and LedgerRehearsal does not depend on private ASHVUN or AplyBot infrastructure.
Built With
- cloudflare
- d1
- react
- typescript
- vinext
- webmcp
Log in or sign up for Devpost to join the conversation.