Today a coding agent hands people code to read. Soon it will hand them behaviour to approve. This article imagines a development tool built on poly: the roles around it, the flow of work, the command line people would use, and the loop that brings a running solution's experience back into its design.
Working with a coding agent such as Claude Code means managing a long list of settings and steps. You write instructions in a CLAUDE.md, answer permission prompts, set hooks, watch the context window, split work across sessions and worktrees, and then read the diff. Each of these exists for a good reason: the agent writes code that only a person can vouch for, so the person must stay close to every step.
The bottleneck has moved from writing to reviewing. Spotify reports that its developers now have 76% more pull requests to review. A reviewer reads one change at a time and can follow a few paths through it. The defects that matter (a refund sent twice, a page never answered, private notes sent to the wrong model) live in the paths between the lines.
poly changes what people look at. The agent still writes the program, but the program is a set of state machines that a check explores completely, over declared domains. People no longer need to read every line. They state what must be true, sign the rules the program must follow, and approve the change in behaviour the check reports.
The person who gains most never opens the workbench: the guest who asks for a refund. A refund is never sent twice, a large one never goes out without a person, and an approval that is needed arrives in minutes because it lands in one queue with its reason attached.
This is already measured, not only imagined. On τ²-bench, the airline and retail benchmark for customer-service agents, a gate built this way (the written policy translated into poly, checked over every path, and applied to every action the agent proposes) removed nearly all policy breaches without lowering task success. In two preregistered studies, actions breaking the policy fell from 178 to 0 in retail and from 31 to 1 in airline (the paper).
This is not the compiler story. A compiler translates a complete source into an equivalent program. Here people write a contract that is deliberately incomplete: properties, rules and boundaries. The agent writes an implementation that satisfies it, and makes its own choices wherever the contract is silent. So the code is an implementation of a contract, and three things cover what the contract does not say: people review every new path the build adds, contracts on each action catch errors where they happen, and recorded tests cover the code at the edges.
It is no silver bullet either. Brooks split the difficulty of software into what is essential (deciding what the software must do) and what is accidental (the tools and plumbing around that decision). The workbench removes accidental difficulty: prompts, permissions, context windows, diffs to read. The essential part stays, and moves: it becomes the work of writing properties that say the right thing.
A poly project gives each role a part of the program it writes, and a part it signs.
| Role | Writes | poly construct | Signs |
|---|---|---|---|
| Product manager | Outcomes as sentences: "a request always ends", "no refund is issued twice" | Sentences, confirmed against example paths | That each property means what she meant |
| Property owner | The formal properties, with the product manager: one named owner for each | invariant, liveness, path properties | The properties a release must keep |
| Architect | Boundaries: which calls exist and whether they can be undone, who may see what data, what models may cost, how agents work together | effect, audience, budget, configuration | The structure the agent may not change on its own |
| Coding agent | The machines: states, actions, conditions, decisions, and a contract on each action | machine, decision, require, ensure | Nothing: its work is checked, never trusted |
| Developer | Host handlers and adapters, with their contracts; the mapping from real data to checked values; resolves findings with the agent | TypeScript against generated types and contracts | Acceptance of a finding, when one is kept on purpose |
| Owner, security | Rules: what is allowed, denied, or sent to a person | policy, obligation, never | The policy and the admission of each build |
| Operations | Decisions on escalations and unknown outcomes; rulings on mined rules | The journal, approvals, adjudications | Each approval and each ruling |
Seven roles do not mean seven people. On a small team one person holds several, and the team that owns a machine also owns what it sends to a person: its escalations, its unknown outcomes, its pager. Operations is a duty of the owning team, not a separate team the work is handed to. Signatures follow risk: a change that only adds a reversible path needs the owner; a change that touches an irreversible call or the policy needs security too.
Many signers must not mean many designers. Each project has one owner with the final word when a property and a boundary pull apart, so the design stays one coherent idea. Brooks's surgical team fits the workbench well: one person decides and answers for the result, and the agent is the support team that writes, checks and repairs around that person.
One column per role. Purple columns are people, blue columns are poly itself, grey is the coding agent. Dashed arrows return work to an earlier step.
Work starts from intent, not from a ticket that describes code. The product manager and the architect state what must hold and what the program may touch. The agent writes machines until the check is CLEAN, or returns findings, each with the shortest path that breaks a property. A developer and the agent repair them. People with the right keys sign the policy and admit the build. The runtime runs only that build, sends every call through the gate, and records every step. Operations handles what the program sends to a person. The journal feeds learning, and learning comes back as proposals to the people who own the properties.
The flow is a spiral: each turn runs from intent to the check, review, admission, production and learning, and then starts again. Three of Boehm's anchor points mark where a project stands on it. The objectives are agreed when the owners confirm the properties. The architecture is settled when the boundaries and the policy are signed. The first operational capability is reached when an admitted build serves its first share of real runs.
The screens below are imagined. Each one is built on commands poly already has; the table after them names which. "A working prototype" shows the same steps on screen.
$ poly refunds-desk · build 1.7 admitted · signed by owner, security · running machines Desk, Ledger, Conversation CLEAN 5,762 states policy refunds (12 rules, 2 never) signed by owner live 318 runs today · 4 waiting for a person · 1 unknown outcome learning 3 candidate rules · triage model drifting (agreement 0.71 → 0.64) levels gate 40 ms at p99 ok · escalation wait 6 min median ok · false refusals 2.1% (target 3%) ok cost models $3.12 today · last check 41 s (cached) · agent jobs 7 next poly ops · poly learn · poly intent "…"
$ poly intent "A refund above 100 dollars waits for a person" agent reading the program and its policy … proposal (3 changes) property refund-large-needs-person Desk, step property policy large-refund-reviewed escalate when amount > 100 machine Desk: new state Held, action Resolve by an approver check CLEAN read back "Whenever a refund over 100.00 is issued, a person approved it earlier in the same request." allowed request 240.00 → Held → approved by raj → Issued forbidden request 240.00 → Issued cannot happen owners property → product (ana) · policy → security (raj) Is this what you meant? [y]es [n]o, refine [e]dit
The product manager never sees a line of the machine. She sees her sentence read back in plain words, one path the program allows and one it can no longer take, and who else must sign. Her "yes" is part of the record. This is the validation step: the check verifies the program against the property, and her confirmation validates the property against what she meant. Without it, "proved" would only certify the agent's reading of her sentence.
$ poly review 42
behaviour change build 1.7 → 1.8
paths added Asking → Held → Issued a person approves example ▸
Asking → Held → Released after 48h, refund cancelled example ▸
paths removed Asking → Issued, amount > 100 no longer possible example ▸
effects changed none · stripe.refund still irreversible, sent once
+ property refund-large-needs-person proved · confirmed by ana
= property no-reissue still proved
+ rule large-refund-reviewed needs a signature: security
[w]alk a path [s]ign [c]ommentA behaviour change has a precise meaning: the difference between the paths the old build can take and the paths the new build can take. The review lists the paths added, the paths removed and the paths whose effects changed, each with one example run a person can walk. State counts say nothing to a reviewer and are left out. A diff of lines is still there for anyone who asks for it.
$ poly why page-is-answered PL3301 the page is never answered: a loop of 9 steps 1 Report("db down") Reported → Triaging 2 Triaged(High, 0.93) Triaging → Paging sends pager.page … ↺ 7 Snooze Paged → Snoozed ↺ 8 Wake Snoozed → Paged agent's fix limit snoozes to 2 (2 lines) check with it: CLEAN [a]pply [t]est e[x]plain
$ poly ops
waiting for a person (4)
#811 refund 240.00 guest-17 rule large-refund-reviewed [a]pprove [d]eny
#812 refund 130.00 guest-04 rule large-refund-reviewed [a]pprove [d]eny
unknown outcomes (1)
#799 stripe.refund no answer after one attempt
look it up in Stripe, then: [i]ssued [n]ot issued
journal verified · replay of yesterday's runs: 0 divergences$ poly learn
from 2,140 runs (journal verified, private values replaced by digests)
candidate r-7c1 refunds from 100 to 150 for a returning guest
were approved 97 times out of 97
proposed rule no escalation when amount <= 150 and the guest is returning
check with it CLEAN · narrows large-refund-reviewed
needs product and security [r]eal [s]purious [l]ater
drift triage: the small model agrees with people less often (0.71 → 0.64)
[f]it a new map from people's verdicts · admission requiredThe running solution teaches its designers. Patterns in what people approve become candidate rules. A model that drifts gets a new calibration map. Nothing learned reaches production until a person rules on it, the check runs again, and the build is admitted.
Learning has one trap. Once a rule stops sending these refunds to a person, nobody sees them any more, and the data that justified the rule stops coming in. So an automated rule keeps a small random sample of its cases going to a person, and the workbench compares their verdicts with the rule. When they disagree, the rule goes back to its owners.
| Imagined screen | Built on today's commands |
|---|---|
poly | poly check (its report), poly journal verify, poly cost |
poly intent | poly new (drafts through claude -p today), poly edit-check, poly mcp |
poly review | the check report of two builds, poly sign policy, poly admit |
poly why | poly witness --trace, poly witness --test, poly fix |
poly ops | poly approve, the runtime's escalations, poly journal replay |
poly learn | poly mine, the verdict and refit commands, poly promote, poly journal fit |
A command line suits one person. A release is decided by several. The workbench therefore also opens as a shared, live document, one per project: everyone with the link sees the same page, edits arrive as they are made, and comments sit beside the block they are about. Each tab is a live view of the project, not a copy: a property block shows whether it is proved, a finding block can be walked step by step, and a signature block holds the button that signs.
A mockup. People write and sign; @poly asks the agent from inside the document, and its answer arrives as a block already checked.
Checks take time. A change that touches one machine is checked in seconds from cached results; a change to a large configuration can take minutes. The workbench shows a block as "checking" while the check runs, never as proved before it is, and states its time budget for an answer in a conversation. A question that needs a long check is answered with "checking, results in about N minutes", and the block updates when the check finishes.
The tabs follow the flow of work. Intent holds sentences and the properties they became. Behaviour is the review of what a build can do. Policy holds the rules and their signatures. Operations lists what the running solution sends to a person. Learning holds candidate rules and drifting models, each with the people who must rule on it. A comment can be answered by a person or by the agent; a question that changes the program comes back as a proposal, never as an edit.
The screens above are designs. A first prototype of the shared workbench runs the same steps without a terminal. Each person gets a card when a decision is theirs, answers it on screen, and the agent and the check do the rest.
In the run shown here, a small team changed the refunds desk from build 1.7 to build 1.8: Ana (product), Raj (security), Ben (developer) and JJ (release lead). The agent ran on a real model, and poly v1.5.0 checked every proposal. Each image is the card one person received, cropped from the full screen. The Operations and Learning tabs read a short recorded run prepared for the demo.

poly intent. Ana typed one sentence. The card reads it back in plain words, with one path the program allows and one it can no longer take. Her answer is recorded; "No, refine" sends the proposal back to the agent.
poly why. Ben asked @poly what happens if the approver never answers. poly found that a held refund can wait for ever (PL3301). The agent's fix checks CLEAN, and Ben applies it or sends it back.
poly review. The paths build 1.8 adds and removes compared with build 1.7, each with an example run and the amounts checked. No state counts, no lines of code.
poly sign policy. Raj sees the rule before and after, and the check result. Signing records his signature, made with his key.
poly admit. JJ admits build 1.8 once the check, Ana's confirmation and Raj's signature are in.
poly ops. A refund call got no answer after one attempt. The program never sends it twice; a person looks it up and says what happened.
poly ops. Refunds waiting for a person, and the unknown outcome above, from the recorded run of build 1.8.
poly learn. A candidate rule from recorded runs, with its human sample: 1 refund in 10 still goes to a person, and their verdicts are compared with the rule.The release waits for three people: Ana's confirmation of the read-back, Raj's signature and JJ's admission. Each has a date, and a missing one puts the release at risk before its date, not after.
This prototype is the one to throw away. Brooks warned that a team will build one anyway, and that the second system tends to carry every idea the first one left out. The smallest workbench worth building is three things: the read-back of a property, the behaviour review of a build, and one queue for what the program sends to a person. Everything else on these pages comes after those prove their value.
The workbench does not need its own model. The coding tasks (drafting a machine from a sentence, writing a handler, proposing a fix for a finding, explaining a path in plain words) go to Claude Code in headless mode, claude -p. On one developer's machine it runs under that developer's own login, as poly new does today. In a shared workbench it runs under a service identity that belongs to the project, and every job records who asked for it, so the journal says "proposed by the agent, at Ana's request". The team checks that its plan's terms allow this kind of automated use on its behalf.
edit-check, witness, fix), so every change it proposes is parsed and checked before anyone sees it.This is where the intricacies of today's agents go. The prompt, the context, the permissions and the session are the workbench's business. People see a sentence, a proposal, a verdict and a button.
Imagined, like the screens above. The runtime, the gate, the journal and its replay exist today; the rollout steps do not.
A build that is proved correct still has to reach production safely, keep running when parts of the system fail, and stay affordable. The check answers none of these. The workbench has to.
Admission makes a build eligible to run; it does not switch traffic. Every run records the certificate it started under, so a run never changes build halfway: runs in flight finish on 1.7 while new runs start on 1.8. Before any new run starts on 1.8, the journal's recent runs are replayed against it, and any divergence the behaviour review did not announce stops the rollout. Then a small share of new runs moves to 1.8, while the team watches its service levels. Rolling back means sending new runs to the previous certificate, which is still signed and still loadable.
From admission to production. At each step a divergence or a broken service level sends new runs back to the previous certificate.
| What fails | What happens | Why |
|---|---|---|
| The gate | Calls are refused, nothing irreversible is sent, and refused calls wait in the escalation queue with their reason | Failing closed is safe but it is an outage for the customer. The queue turns it into a delay a person can clear. |
| The agent service | Running solutions are unaffected; new proposals wait | The agent is on the development path only. No model sits between a call and the gate. |
| The check | Nothing new is admitted; production keeps its current build | A slow or INCONCLUSIVE check delays a change. It never weakens the build in production. |
| The journal store | The runtime stops taking new runs | A run that cannot be recorded cannot be replayed or audited, so it does not start. |
The gate sits on every call, so it has a latency budget like any other service. Its decisions are local and need no model, which keeps them fast. Loading a large build is the slow part: a bridge loads it once when it starts, not on each call, and the overview screen reports both.
The metrics of the previous section become targets the owning team runs to: the gate's latency, how long an escalation waits for a person, and the false-refusal rate. The last one matters most. A gate that refuses too much is safe and useless, and only a target makes that visible before customers feel it. Cost sits beside them on the same screen: model spend, check time and agent jobs, per day and per run.
Properties speak about a whole run. People also need statements they can read one action at a time, and that say where an error happened. Each action carries a contract: what must be true before it runs, and what it guarantees after.
action Approve(by: Person, amount: Money) require state == Held and by != requester ensure state == Issuing and approvedBy == by
An illustration: poly has require today; ensure and this action form are proposed.
The check proves the machine contracts on every path. The host handlers sit outside the check, so their contracts are checked at runtime, on every call: a handler that breaks its contract stops the step and records which side was at fault. This is where the proof meets the code people still write by hand.
The same edge exists for data. The check explores declared, finite domains; real amounts, names and dates are not finite. Each project therefore states its mapping from real values to checked values, for example an amount as "100 or less" or "over 100". The mapping is code, and it is tested at the boundary values (100.00 and 100.01) with recorded tests. A proof is only as good as this mapping, so the mapping has an owner too.
None of this starts from zero. Software delivery and factories have learned, over decades, how to let many people and machines work fast without losing control. Each lesson below has a direct place in the workbench.
Toyota did not make its workers faster. It made a defect stop the line. Coding agents need that more than they need speed.
| Source | The lesson | In the workbench |
|---|---|---|
| Toyota, Lean | Stop the line on a defect (jidoka); let anyone call for help (andon); design the wrong move out (poka-yoke); improve in small steps from what the floor sees (kaizen) | The gate refuses and fails closed; escalations go to a person; checks cover every path; learning turns the journal into rules people rule on |
| Amazon, "you build it, you run it" | The team that writes a service also runs it, so it feels what breaks | The agent that writes a machine also reads its journal, replays it and proposes the repair; nothing ends at the commit |
| Royce (1970) | Often cited as the source of the sequential "waterfall"; the paper itself argues for feedback between phases and for doing the work twice | Specifying first is fine when the loop is short: a spec, tests by a separate writer, then the code, repeated on every change |
| Boehm, the spiral model | Let risk decide how much care each step gets | An effect's class (reversible, compensable, irreversible) decides how closely the gate looks; irreversible calls go to a person |
| The Agile Manifesto (2001) | Working software over long documents; people and conversation over process | The contract is executable, not a document; the shared workbench is where people talk and sign |
| Shift-left security | Find problems at design time, not in a final audit | Both ends: the check before anything runs, and the gate at every step while it runs |
Boehm showed that a defect costs more to fix the later it is found. A wrong rule caught when the owner reads a property back costs a minute. The same rule caught by the check costs a short repair. Found in production, it costs a refund paid twice, an audit, and a customer's trust. This is the economic case for the workbench: it moves the discovery of whole classes of defects to the left of the chart, before anything runs.
DORA's four metrics (deployment frequency, lead time for changes, change failure rate, time to restore service) measure a delivery pipeline. They still apply to software an agent writes. An agent that acts on its own also needs measures of its behaviour while it runs:
| DORA measures | For an acting agent, also measure | What it tells you |
|---|---|---|
| Change failure rate | Breach rate | How often an action broke a rule the policy states |
| Time to restore service | Time to settle an unknown outcome | How long a call with no answer waits for a person |
| (none) | pass^k | Whether the agent succeeds every time on the same task, not just once |
| (none) | False-refusal rate | How often the gate stopped an action that was in fact allowed: the price of safety |
The last two pull in opposite directions. A gate that refuses everything has no breaches and a useless agent. The workbench reports both, side by side, for every build.
Boehm's advice is to let the largest risks decide where the effort goes. Ranked by our own estimate of how likely each is and how much it would cost:
| Risk | Likelihood | Impact | What the workbench does |
|---|---|---|---|
| A property says the wrong thing | High | High | The read-back with an allowed and a forbidden path; a named owner for each property |
| People become the bottleneck | High | Medium | Signatures follow risk; one queue with reasons attached. Not solved: approvals still wait for people |
| The gate refuses too much | Medium | Medium | A false-refusal target beside the breach rate, reported for every build |
| The check cannot finish | Medium | Medium | INCONCLUSIVE instead of a false CLEAN; cached checks; smaller machines |
| One agent provider | Medium | Medium | The agent only proposes and the check decides, so another provider can be swapped in. Not yet shown in practice |
| A signing key is stolen | Low | High | The agent's identity can propose, never sign; keys held by named people |
INCONCLUSIVE rather than CLEAN. Even when it finishes, a cold check can take tens of minutes, which shapes how people work.Coding agents will not stay tools that people supervise line by line. When the program an agent writes can be checked as a whole, people stop reading code and start approving behaviour. They write outcomes as properties, draw the boundaries, sign the rules and admit the builds; the agent writes the machines, and the check covers every path. The intricacies we manage today (prompts, permissions, context windows, diffs) move into the tool. The first evidence is encouraging: on τ²-bench, a checked gate removed nearly all policy breaches with no measurable cost in task success. None of this is a silver bullet, and none of it is new in spirit: it is Toyota's stopped line and Amazon's "you build it, you run it", applied to software that acts. What remains for people is the part that was always theirs: deciding what the software must do, and answering for it.
poly is open source: github.com/cognitive-fab/poly.
Sources: F. Brooks, The Mythical Man-Month (1975) and "No Silver Bullet" (1986); B. Boehm, Software Engineering Economics (1981); W. Royce, "Managing the Development of Large Software Systems" (1970); B. Boehm, "A Spiral Model of Software Development and Enhancement" (1986); W. Vogels, interview in ACM Queue (2006); the DORA research program; Spotify Engineering, Coding is no longer the constraint (June 2026); J.-J. Dubray, Enforcing written policies on AI agents with a checked gate: evidence from τ²-bench (2026).