Two kinds of work: one arrives, one converges
deterministic
done is a check that passes
scope · build · check
convergence
done is a call somebody makes
V1 · V2 · V3 · …
One kind of work arrives. The other circles a target that keeps moving.

For years we ran on triage. One customer needed it to launch, another had waited three weeks on a fix, and a third had paid for ten broken things. We took the loudest first.

That system fit the constraint we had. We build software for food and beverage plants. They wanted more than we could make, so we optimized for shipping. Sprints, estimates, standups, and reviews caught mistakes before they cost a week. Then delivery stopped being the scarce thing.

Over a few months the monorepo became a harness. It gathered the context, skills, conventions, and commands that an agent reads before changing anything. Where a machine can check done, nobody sits inside the loop. A person writes the contract at one end and reads the result at the other. The harness covered the work we expected, then the work we’d assumed would stay manual. Migrations, service internals, frontend features, and hard product work all shipped and stayed shipped.

Building that harness was the strangest project we’d run. Nothing told us it was working. No test says the agent is good enough at frontend now. Every few weeks, we read a stack of output and decided whether we’d gained anything. Then we changed the context and ran it again. It took months.

We couldn’t tell you which round mattered, and we had no name for that kind of work. We beat a problem we’d fought for two years, and it didn’t feel like winning. We still felt stuck. Our constraint had moved from throughput to judgment, and every practice we own was built for the old one. The clearest break separates work with a knowable done from work where done keeps moving. We’d been running both through the same process, and it only ever fit one of them.

The constraint moved

Agentic engineering didn’t make our engineers better. It made a whole category of work close to free. A ticket that used to consume a person’s week now comes back in an afternoon with nobody watching. The tooling around the harness keeps widening that gap. Ticket throughput no longer constrains us. Judgment went scarce instead, in two forms: knowing what’s worth building and knowing whether the result is any good.

The narrow point moved from building to deciding decide build ship then building was the narrow point now deciding is the narrow point
Agents widened one section of the pipe. The constraint moved rather than disappeared.

Neither speeds up with more agents. Reviewing a design still costs an hour of somebody’s whole attention. Deciding whether a workflow survives contact with a plant floor still needs someone who has stood on one.

The cost structure inverted too. Building the wrong thing used to cost a quarter, which made it rare enough that people weighed it. Now it costs a week. You can do it fifty times a year, stay busy, ship all of it, and arrive nowhere.

A backlog says nothing about direction

A backlog looks like a roadmap. It’s ordered, it’s dated, and it holds everything we intend to build, so people read it as a statement of direction.

The items come from escalations, sales promises, bugs, and requests, and every one of them defends itself on its own terms. Nobody picks the direction. It falls out of the addition. Grind that list long enough and you ship a product that answers every request and stands for nothing.

Nobody asked what we’re trying to become. That question lives a layer up from the queue, and we never built a place for it.

An answer looks like a small number of bets sitting above the queue. Three or four, written as theses rather than features, each one specific enough to be wrong. Not “improve the manufacturing experience,” but something you can hold against a quarter of shipped work and lose.

The backlog survives all of this. It just stops being the top-level object. A roadmap item must argue for itself against a bet. Otherwise, we call it what it is: keeping the lights on. We need both kinds. The cost comes from confusing them.

Bets have to be killable. A thesis becomes a slogan if nobody will abandon it after two quarters of evidence. The value comes from admitting we were wrong, with shipped work to prove it. Then the argument moves up a level, which is where an argument is worth having.

flowchart TB
  subgraph s2["A thesis decides"]
    direction TB
    T["Bet: we win by owning X"] --> Q2["Work that advances the bet"]
    Q2 --> P2["A product with<br/>a point of view"]
    L["Keep the lights on"] -.-> P2
  end
  classDef hi fill:none,stroke:#8b5cf6,stroke-width:1.5px
  class T,P2 hi
  subgraph s1["Requests decide"]
    direction TB
    A1["Escalation"] --> Q1["Backlog"]
    A2["Sales commitment"] --> Q1
    A3["Bug"] --> Q1
    A4["Feature request"] --> Q1
    Q1 --> P1["Whatever the product<br/>ended up being"]
  end

I’m not certain that bets are the right mechanism. I am certain about the problem beneath them. Shipping the next item on the list looks exactly like shipping something that moves the product toward a goal: same velocity, same burndown, same demo. The difference surfaces a year later, in whether the product landed somewhere on purpose.

Shaping tells you how to build something well. It doesn’t tell you why this and not the fifty other things, and that question belongs to everybody now.

Two kinds of work

We reviewed this year’s project history to find what pushes a project off track. Estimate size didn’t predict it. Team didn’t. Neither did anything we’d normally call complexity. One thing did, and it was whether the project had a knowable done.

Deterministic work has one. Examples include data mapping, exports, a screen, or an integration against a written specification. You define done before you start and give that definition to a machine. It becomes unit, integration, or end-to-end tests, or an agent that reports back. A machine does the verifying, which is why this whole category got cheap when writing code got cheap.

It also closes the loop without us. A machine that can judge the work can keep trying until it lands. You write the criteria, hand them over, and read what comes back, and nobody stands in the middle. Deterministic work makes a handoff.

Convergence work doesn’t. Consider onboarding, an alert threshold, a price, or a forecast. Done sits at a threshold on a number, and no threshold holds up in advance. Ninety-two percent might make a product. It might mean nothing.

The only way to find out is to show the result to someone who understands how the number gets used. You walk toward a target that you keep redrawing. No test settles it. No agent settles it either. The models are not the limit. The optimizer cannot judge when to stop.

DeterministicConvergence
What done meansA check that passesA threshold on a number
Who decidesThe criteriaA person, against the business
Who does itAn agent, end to endA person, with agents running turns
VerificationMechanical, and cheap nowJudgment, and still costly
ShapeA lineA loop
FailureA slipped dateNever stopping
flowchart LR
  subgraph c["Convergence"]
    direction LR
    F["Floor"] --> T["Try"]
    T --> M["Measure"]
    M --> J{"Good<br/>enough?"}
    J -->|"No"| T
    J -->|"Yes, or budget spent"| X["Decide, then stop"]
  end
  subgraph d["Deterministic"]
    direction LR
    S["Scope"] --> B["Build"] --> V["Checks pass"] --> DN["Done"]
  end
  classDef hi fill:none,stroke:#8b5cf6,stroke-width:1.5px
  class DN,X hi

You can see it in our own history. Convergence projects grow V2s: a project closes, and a new epic appears carrying work the first one promised. That isn’t sloppiness. We cut a shippable line through unfinished work, call it V1, get it to customers, and carry on under a new number.

Drawing the line is the right instinct, and recording everything behind it as complete is where we go wrong. V1 ran round one of a loop we never planned as a loop.

Build the floor first

One project this year taught us more than the rest together. It spent months building on ground that wouldn’t hold, and not one of those runs told us anything.

  • The fields the model trained on sat empty, and nothing filled them.
  • A stretch of history lacked the identifier that attributes it.
  • The eval returned a confident number from a run that measured nothing.
  • Two sources disagreed, so the instrument moved between runs.
  • No naive baseline existed, so no result could beat doing the obvious thing.

None of that is a people problem. It comes from starting convergence work before the deterministic foundation is finished. Teams do this because the convergence part is interesting.

Build the deterministic floor before you spend a week converging on top of it. Not early. First.

The floor has three parts. It needs clean data and an eval that scores the same result the same way twice. That eval must report regressions. It also needs a naive baseline, the dumbest approach that could work. You beat it or lose to it on day one.

flowchart BT
  subgraph floor["The floor, all of it deterministic"]
    direction BT
    D["Clean, populated data"] --> E["An eval you trust"]
    E --> B["A naive baseline to beat"]
  end
  B --> T["Tuning"]
  T --> R["A result you can believe"]
  classDef hi fill:none,stroke:#8b5cf6,stroke-width:1.5px
  class R hi

Without the floor you don’t converge. You wander. Every round takes a step, nothing scores the step, and the next one starts as blind as the last. Gradient descent with no gradient. Run it long enough and you get motion, a burn rate, and a report at the end that means nothing.

That trade holds if tokens come free and the quarter never closes. Tokens come close to free. Quarters close on the day they always did, and the attention we spend reading those runs stays the dearest thing we own. A floor costs a week. Skipping it costs the months that follow and takes the evidence with it, because a project without a floor can’t even tell you it failed.

Nobody skips it on purpose. It goes missing because it looks like setup, plumbing before the real work. It carries no demo and no headline, and the project plan calls it week zero. Then a quarter later the numbers come out clean and worthless, and every hour spent on top of that missing week goes in the bin.

Look at what the floor is made of, though: clean data, a working harness, a stub. All of it knows its own done, and a machine can check every piece. Every convergence project has a deterministic project hiding inside it, and that hidden project decides whether the visible one means anything.

What a floor unlocks

Building the floor pays for itself twice. Once because it makes the results worth believing, and again because it lets us point agent loops at convergence work.

Convergence runs as a loop: try, measure, choose what to try next. The trying used to cost the money, so a person sat inside every turn and the loop ran at the speed of that person’s week. The trying comes close to free now, so the turns can run unattended.

The round becomes the unit. A turn makes one attempt against the metric. A round gathers turns and ends in a decision. Agents own turns. People own rounds. That line holds, because a round boundary asks the one question the optimizer cannot answer: does this number serve the business well enough.

We use this pattern in three forms today.

Research loops. An agent runs an experiment, reads the result, forms the next hypothesis, and continues without waiting for anyone. Give it an eval and the set of controls on our alerting rules. It replays six months of plant events and counts the alerts that each configuration would have sent to a supervisor. It checks how many mattered, drops settings that earn nothing, and tests the next combination. You get a ranked table and a log of every run, turning a week of somebody’s mornings into an afternoon.

Self-improving prompts. The loop rewrites its own brief each round, so round ten starts clearer than round one. Take a prompt that maps a supplier’s spreadsheet onto our schema. The first version mangles the ambiguous columns. The loop reads its own failures, writes rules to catch them, and runs again. The result stays in the repo, so the next integration starts with twenty runs of evidence, not a blank file and somebody’s memory.

Completion conditions. Write down what finished means and let the loop run until it gets there. Both tenants five points above baseline, or twenty variations spent, whichever comes first, then write up what you found. That maps onto convergence work without any translation. A completion condition states the stop we agreed at kickoff in a form a machine can act on. Writing one forces the clarity we needed anyway, because nobody writes a stop condition and stays vague about good.

The pattern has two limits, and both weigh more than the upside.

A loop amplifies its eval, including its defects. If the harness reports confident numbers from empty runs, the loop optimizes noise faster than a person and returns a clean report. Speed cuts both ways here. On a good floor the loop buys a week of iteration in a day. On a bad one it buys a week of being wrong in a day, and the report reads the same either way. The floor decides whether the loop produces anything at all.

The second limit cuts deeper. A loop climbs the hill it stands on. It finds the top of the approach you gave it, faster than a team would. It never tells you that the hill sits in the wrong place. It also cannot tell you when the last four points of accuracy stopped mattering to the customer.

A loop finds the local maximum of the approach it was given local maximum the loop climbs this in an afternoon the approach nobody tried the gap only judgment finds
A loop optimizes the approach it was handed. Choosing the approach is still ours.

Agents run the turns. We choose the hill, and we call the stop.

Most features hold both

Sorting work into two kinds makes it sound like a feature arrives as one or the other. Very few do. A convergent core comes wrapped in ordinary work: data, a screen, a decision record, and a job that runs at three in the morning.

Take a suggested reorder quantity. The suggestion converges. Pulling inputs, storing the result, showing the number, letting the buyer change it, and recording the change all have a knowable done.

The mistake is to size and sequence the whole thing as one unit, with one epic and one estimate and one release. Nothing ships until the number gets good, and the number never gets good, because nobody outside the room says what good means. Four months later a deadline carves out a V1, and a V2 carries the rest.

Convergence hell is a decomposition failure, not a discipline problem or a modelling problem. Find the seam. A line runs through the feature with the convergent part on one side and everything else on the other. Draw it, and make it a contract: a function signature, an interface, or a service boundary. Give it a shape that survives whatever stands behind it.

Then the sequence writes itself. Week one ships the envelope with the naive baseline behind the seam. That baseline might be last quarter’s average, a supplier minimum, or another simple approach that works. You had to build it anyway, since it makes the third piece of the floor. It goes to a customer now instead of into a benchmark table.

flowchart LR
  IN["Inputs and pipeline"] --> S{{"The seam:<br/>one contract"}}
  S --> UI["Surface, override,<br/>record of what changed"]
  V1["V1 naive baseline"] -.-> S
  V2["Round 2 model"] -.-> S
  V3["Round 3 model"] -.-> S
  classDef hi fill:none,stroke:#8b5cf6,stroke-width:1.5px
  class S,V1 hi

The envelope has to survive a weak core, and that’s a design constraint like any other. Call the output a suggestion rather than an answer, let people override it, and record what they overrode and by how much. If the screen can’t ship with something mediocre behind it, fix that in week one while it costs little.

Now two clocks run instead of one. The feature finishes when it meets its contract: shipped, checks green, ticket closed and staying closed. The core keeps running rounds against the metric on its own budget, and each version lands behind a seam that carries traffic. Nobody reopens the feature to improve the model.

The seam cuts more than code. Outside it, work makes a handoff, with criteria going in and software coming out and nobody standing over it. Inside it, somebody stays. The seam tells you what the estimate never did, which is how many hours of your team’s attention this feature demands. The number comes back smaller than anyone guessed, and it sits in one place.

Look at what the shipped baseline bought. No threshold holds up in advance, and no planning meeting settles it, but a live baseline does. If buyers take the suggestion four times in five, the number works and round two turns optional. If they override everything, you learn that in week two instead of month five, with the failing cases in hand.

One case breaks this: an answer that cannot be undone. Money might move, a compliance record might be written, or the result might reach a customer’s customer. The envelope cannot absorb a bad core there, because shipping the baseline ships a defect.

Send the same slice inside first. Keep the same seam, override, and record, but put our own people at the other end. The slice remains the unit of delivery, and the baseline remains a real implementation of it.

Write the whole feature out as tickets and the order settles itself. Take the suggested reorder quantity again, in the form somebody would actually file it.

  • Consumption history and on-hand stock, pulled into one table.
  • The supplier lead times that half the items lack.
  • An eval that scores a suggestion against what the buyer ordered.
  • One contract: item and site in, quantity and reason out.
  • Last quarter’s average, behind the contract.
  • A panel on the purchasing screen.
  • An override, with a field for why.
  • A record of every suggestion and every change.
  • The job that runs it before the buyers arrive.
  • A model that beats the average.

Ten requirements. One of them converges.

The old instinct draws a dependency graph and walks it. That graph misleads us now, because it ranks the work by what the code needs, and writing code comes close to free.

Order by decisions instead. Three items block everyone: the data, the eval, and the contract. Nobody measures anything before the first two land, and nobody builds against a shape that doesn’t exist. Those three make the critical path, and the other seven block nobody.

After the floor, the work splits into two lanes. One lane runs wide. Give each task to an agent with its criteria, and start them together. The panel, override, record, job, and backfill do not queue behind each other or the model. Six people would have run them in some order across six weeks, but the work never needed an order.

One lane runs single file: a round against the eval, then a call, then another round. Each round reads the result of the last one, and the same person makes every call, so the lane can’t widen. Judgment doesn’t fan out. Hand somebody two convergent requirements at once and they’ll run them in series anyway, slower, with less attention on each.

Agents fill that lane too. They run the turns inside every round, dozens of them, while nobody watches, and what they can’t run sits between the rounds. The narrow lane holds no less machine work than the wide one. It holds a person at each boundary, and the boundaries set its pace.

Serialize judgment. Parallelize everything else. The critical path runs through the calls and through nothing else.

Agents run both lanes. A person stands at the round boundaries floor and seam agents alone at once agents + a person in order pipeline and backfill the panel override record of every change nightly job round 1 round 2 round 3 agents run the turns inside every round a person makes the call between them the slice goes live time
The floor blocks everyone. Agents work both lanes. Only the diamonds belong to a person.

The wide lane has a ceiling, and headcount stopped setting it. Every finished agent task returns something a person must read. Fan out twenty tasks and the queue moves from the keyboard to the reviewer. Width belongs to whatever one person can judge in a day. We can measure that, and we seldom do.

Order the narrow lane by what could kill the feature. A round boundary pays only while stopping stays cheap, and stopping gets dear once the surface, the record, and the job all exist. Ask the question that could end the project in round one, before the wide lane has spent much.

Week one lands the floor, the contract, the panel, and last quarter’s average, and the buyers see a number. The wide lane finishes a few days behind it. What remains runs single file, one round at a time, behind a seam that carries traffic. Nine requirements finish and stay finished. One keeps working, and it blocks nothing.

Long does not mean fuzzy

One integration has run for seven months. At a glance it fits the pattern.

It doesn’t fit at all. The scope held from day one. What grew were the distributed-system edges. Status reversals arrived out of order. Charges and discounts had to survive a round trip through a partner’s system. The integration also encountered load spikes that most teams never see.

A framework applied without care does more harm than no framework, and a long timeline proves nothing about a fuzzy target. Sometimes the map lied about the terrain.

A loop would have helped there, just not the convergence kind. That project spent its money finding edge cases, and finding things is a search problem. Point an agent at the partner specification and have it write hostile payloads. Let it replay them through the integration and report failures while you work elsewhere. Done stays knowable and the check stays mechanical, so the loop enumerates instead of converging. That work belongs in week one.

What the ceremony managed

Look at what the old lifecycle moved around. Estimates forecast a queue. Grooming fed the queue. Sprints cut it into batches a fixed team could carry. Standups caught the handoffs, because people drop things. Team shaping decided how much queue each group could hold.

Scope, specification, build, and delivery each had a ritual at the seam between them. Every ritual answered the same question: how do we use a scarce, serial, human ability to write code. We no longer have that scarcity, so the ceremony now measures the one thing we hold in surplus.

An estimate costs more than the ticket it estimates. Grooming feeds a queue nobody stands in. A standup reports on work that ran overnight while the team slept. A sprint boundary batches capacity that stopped arriving in fixed amounts. Team shaping spreads a shortage we don’t have.

None of that argues for no process. It argues that our process solves a solved problem, and the one we need doesn’t exist yet. The new process runs thinner and weighs more. It needs three or four bets, a classification for each requirement, a seam, and a round budget with a stop. It also needs a plan that somebody read before the week of work existed. Five decisions replace forty meetings, and each decision costs more than the meeting it replaced.

The ceremony also did work nobody wrote in the charter. It put people in a room, showed them the same board, and gave the week a shape. Remove it and the hole remains. Whoever removes it must fill that hole.

At the companies furthest along, most of this has gone. The rest will follow, and not because someone wins the argument. A team that spends Tuesday grooming a backlog competes with a team that spends Tuesday deciding what to build. One of them ships a product with a point of view. The other ships the list.

What changes

Naming the two kinds is the easy part. The change sits in how we plan, staff, review, and decide we are finished.

Two kinds of work, two contracts

Everything moves through one shape now: scope, size, build, review, close. That shape tells the truth about deterministic work and lies about the other kind.

Deterministic work keeps it and grows stronger. Write the criteria first, encode them as checks, and hand the whole thing over. Two human questions survive, one at each end. Does this deserve building, and did we get what we asked for. When code and tests both come cheap, the risk moves out of execution and into whether the thing belonged on the list at all.

Convergence work needs another contract: a floor before tuning, an accepted metric, a round budget, and a written stop condition. Write the stop before anyone loves the outcome. Either the target lands or the rounds expire. It also needs a named owner for the rounds, because agent-assisted work is not unowned. A loop with nobody at its boundaries just spends money.

Rounds get planned

If a project needs three rounds before it earns its place, we say three rounds at kickoff. We also say what each round buys. Round one buys the floor and the baseline. At the end, we can measure and know what doing nothing clever looks like. If the seam allows it, the slice already serves customers.

Round two makes the first real attempt. It answers one question: did we improve enough to pay for a third? Round three buys what we need to show the result to a customer without an apology.

flowchart TB
  R1["Round 1<br/>floor and baseline"] --> D1{"Decide"}
  D1 -->|"Continue"| R2["Round 2<br/>first real attempt"]
  D1 -->|"Stop"| E1["Nothing shipped,<br/>and we know why"]
  R2 --> D2{"Decide"}
  D2 -->|"Continue"| R3["Round 3<br/>good enough to show"]
  D2 -->|"Ship what we have"| E2["V1 out, loop closed"]
  R3 --> E3["Ship, or spend<br/>another budget"]
  classDef hi fill:none,stroke:#8b5cf6,stroke-width:1.5px
  class E1,E2,E3 hi

Each boundary holds a decision rather than a milestone: continue, ship what we have and stop, or stop with nothing. All three deserve respect, and agreeing on that at kickoff is what makes the third one possible.

Loops make rounds cheap without making them optional. A round that took three weeks takes three days, so more rounds fit the same budget, which means more decision points rather than fewer. Agents run the turns, and somebody stands at every boundary and makes the call.

Planned this way, a V2 is the loop working. Discovered after the fact, a V2 is evidence we told ourselves a story about being finished.

Classification opens a conversation

At the start of a project, someone asks whether we can define done in a form a machine can check. If we can, the project is deterministic, and it should feel fast and dull. If done is a number somebody must judge against the business, it needs a floor and a round budget before tuning starts.

The answer also decides where our people go, which is the part that costs something. One answer delegates the work. The other reserves somebody’s attention at planned intervals for a fixed number of rounds.

flowchart TD
  A["A project starts"] --> B{"Can done be written<br/>as a machine check?"}
  B -->|"Yes"| C["Deterministic<br/>criteria, checks, a date we defend"]
  B -->|"No, someone has to judge it"| D["Convergence<br/>floor, metric, round budget, stop condition"]
  classDef hi fill:none,stroke:#8b5cf6,stroke-width:1.5px
  class C,D hi

Most of the time, the honest answer is which parts, not which kind. That answer locates the seam, and the seam lets deterministic work ship on its own clock. The answer isn’t always obvious, and a project sometimes wears the costume of the other kind. The value sits in asking early and out loud, rather than discovering the answer eight months later, from the wreckage.

Judgment gets the calendar

If judgment holds the limit, a calendar full of mechanical work means we still staff the old constraint. An hour spent inside deterministic work goes to the one thing that no longer needs us. That time goes to choosing what to build and reading what came back. We put the people with the most context on questions agents cannot answer.

The same shift applies to review. Ours was built to catch mistakes in code. Most of what hurts us now starts as a mistake in intent, and a plan holds those cheap. Nobody rejects a merge request over “this assumes every lot has one supplier.” They say it against a plan, in one sentence, before the week of code exists. When a week buys what a quarter used to buy, the leverage moved to the plan.

Hiring points elsewhere as well. We don’t lack delivery speed. We lack people who can look at a workflow, a threshold, or a plan and say with authority whether it holds up.

Done stops meaning closed

Deterministic work finishes when the checks pass. Convergence work ends when the metric clears the bar we agreed, or when the rounds run out and somebody makes the call.

Closed tickets stop being a measure of anything. They always stood in for delivery capacity, and delivery capacity stopped being scarce.


We spent years on a throughput problem and we beat it, and a judgment problem was waiting behind it. One kind of work we can hand away now. The other stays ours, and no better model takes it off our hands. It needs a different muscle and a different operating system, and I’d rather build that on purpose than find it one V2 at a time.