Workflow · last verified 2026-08-14
Deciding what to build when agents outrun your decisions
This is the workflow for the case where you can implement faster than you can decide what to implement. It has four moving parts: classify work on two axes instead of one, protect valuable work with a floor rather than capping maintenance with a ceiling, refuse to admit work that has not been shaped, and run discovery in parallel with delivery rather than inside it.
Every rule below carries the measurement that forced it, including the two rules we built, measured and threw away. It is part of the Engineering Workflow Library. The other workflows in the library are about how work gets done well; this one is about which work gets done at all.
The job this workflow does
The classic reason a backlog stalls is that there is more to build than there are hands to build it. Prioritisation, in that world, is a rationing problem: rank everything on one scale, work down the list, and the ranking is doing real work because the constraint is downstream of it.
Agent-assisted engineering breaks that assumption quietly. Implementation capacity goes up, the decision-making capacity in front of it does not, and the queue in front of the constraint gets longer rather than shorter. DORA's 2025 report on AI-assisted software development frames the same finding organisationally: its headline finding is that "AI's primary role is as an amplifier, magnifying an organization's existing strengths and weaknesses". If your decision process was the weak part, more throughput makes that worse, not better — it produces more of whatever you were already choosing.
And the throughput gain is not always where it feels like it is. METR's randomised controlled trial of experienced open-source developers on their own mature repositories found the developers took 19% longer to complete issues with AI tools, while believing they had been sped up by about 20%. Read the two together and the practical conclusion is uncomfortable but useful: velocity is a poor signal, and a system that optimises for it is optimising the wrong variable.
The measurement that started this
This platform is a solo-operator build with an agent estate around it, and it ran a single-priority backlog from mid-July 2026. Measured four weeks later, on one day in August:
| Measure | Value |
|---|---|
| Commits in the trailing week | 100 |
| Artifacts a user could open, that week | 0 |
| Days since the last new curriculum module | 41 |
| Open backlog items | 42, of which 24 were the lowest two priorities |
| Items whose output was a new thing rather than a fix | 2 |
A hundred commits and nothing shipped that a user would notice is not a capacity failure. Nobody was idle and nothing was blocked. It is a selection failure, and the mechanism was visible in a single pair of backlog rows sitting at the same priority: one was a decision about what members could do with the product, the other was a storage bug that served a truncated body on a suffix range request.
The bug had a file, a line and a test plan. The product move had a paragraph. Ranked on one axis they came out equal, so the tie broke on legibility — and it broke the same way every single week. That is the whole disease. Everything below is treatment.
The workflow
1. Classify on two axes, never one
The most common mistake is collapsing two questions into one number. What kind of work is this and how urgently must it be treated are independent, and Kanban keeps them apart deliberately.
Axis 1 — lane. Every item carries exactly one lane, named for the kind of output it produces. Ours are the five below; yours will differ, and the shape matters more than the names. Each lane needs a one-line test that can be answered without opening the item:
| Lane | Output | Test |
|---|---|---|
| product | Code that changes what a user can do | Would a user notice a new capability? |
| library | A new user-facing artifact | Is there a new file a user can open? |
| distribution | Getting seen | Does this put us in front of someone new? |
| discovery | Finding out what should exist next | Does this produce a candidate rather than a fix? |
| ops | Everything else — fixes, gates, hygiene, infra | Default. If you are unsure, it is ops |
The residual lane is residual on purpose. Work argues its way out of ops, never into it. A classification scheme where the catch-all is the smallest bucket is a scheme people are gaming, usually unconsciously, to make their week look strategic.
Axis 2 — class of service. This is Kanban's term for how differently an item gets treated, and the Kanban Guide teaches it with a traffic analogy worth stealing: an ambulance passes the queue even when the road is at capacity, and it may do so because the criteria are recognisable in advance and known to every other driver. The two halves matter equally. A class of service without published entry criteria is not a class of service, it is a habit of interrupting.
Four classes cover almost everything: expedite (cuts the line, WIP limit 1, severe entry criteria — see step 3), fixed-date (a real external deadline exists, pulled early enough to make it), standard (the default), and intangible (real, but no near-term cost of delay — most hygiene lives here and runs in leftover capacity).
Priority ranks within a lane. Never across lanes. This is the rule that repairs the row-pair in the diagnosis above. The two items never compete again, because they are no longer on the same list.
2. Set a floor, not a ceiling
The intuitive fix for "too much maintenance" is a cap: no more than 40% of the week on plumbing. It does not work, and the reason is structural rather than motivational. Nobody notices crossing a ceiling until the week is already gone. A ceiling is only measurable in the past tense, so it produces an apology, not a decision.
Invert it. Commit to a minimum of the work that would otherwise lose, and check it at the start of the week rather than the end:
| Commitment | How it fails loudly |
|---|---|
| ≥1 product item active at all times | The weekly review is red at the top when the slot is empty — issue #1, not issue #5 |
| ≥1 library artifact shipped per week | A file a user can open. Improving an existing artifact does not satisfy it |
| ≥1 distribution action per week | If it needs a person rather than an agent, it is surfaced as such — not counted as done |
| ops | Takes what is left, plus the expedite slot |
An empty product slot may be displaced only by something meeting the expedite criteria, and the displacement is named: which commitment was dropped, and who decided. Silent borrowing from the protected slot is the failure mode the floor exists to catch, and it is invisible unless someone has to write the trade down.
Do not invent a percentage split. There is no canonical one in the literature, and the 50/20/30 figure that circulates in Kanban discussions is an illustrative example from a twenty-item board rather than a recommendation. For a team this size, percentages of a week are false precision. Integer commitments — one, one, one — are checkable.
What a floor still needs is a consequence when it is breached, and the best-specified version of that comes from Google SRE. Their toil cap is 50% of an SRE's time, and the half people forget is the automatic escalation attached to it rather than the number: the SRE book is explicit that the 50% goal exists "because toil tends to expand if left unchecked and can quickly fill 100% of everyone's time." Ours: if ops overruns its share for two consecutive weeks, the next ops slot must go to root-cause removal or automation, and the overflow returns to whoever sets direction as an explicit trade — these are the items eating the weeks; which planned work do we drop?
The distinction that makes the cap usable: toil is not maintenance. Google defines toil as work that is "manual, repetitive, automatable, tactical, devoid of enduring value, and that scales linearly as a service grows." Novel diagnosis, a durable fix, and building a gate are engineering, and they are supposed to cost time. A recurring manual sweep a script could do is toil, and toil breaching its cap is a signal to automate it, not to work harder at it.
3. Admit nothing that has not been shaped
The floor protects a slot. It does not stop the slot being filled with something useless, and the diagnosis above says exactly why: a vague item loses to a concrete bug on legibility. So stop admitting vague items. Nothing discretionary enters a build lane without five fields:
- Outcome — what changes for a user, in one sentence.
- Evidence, or an explicit hypothesis — what makes us think so. "We believe X; we are wrong if Y" is a complete answer. A guess labelled as a guess is admissible; a guess dressed as a finding is not.
- Appetite — how much time we are willing to spend. Days, for a small team.
- Kill measure — what would make us drop it.
- Acceptance criteria — how we know it is done.
Appetite is not an estimate, and it needs a circuit breaker. An estimate is a prediction about the work; an appetite is a decision about its worth. A bet that blows its appetite stops and comes back to be re-decided rather than silently extending — that is Shape Up's rule, and it is the only mechanism I know of that bounds scope creep without micromanaging.
Take the appetite and the shaping, and leave the ceremony. Basecamp says so themselves: their appendix on small teams states that "a tiny team can throw out most of the structure. You don't need to work six weeks at a time. You don't need a cool-down period, formal pitches or a betting table" — instead, "set an appetite, shape what to do next, build it, then shape the next thing." A two- or three-person team importing cycles, cool-downs and a betting table has adopted the parts that cost and skipped the part that pays.
A slot names a subject, never a category. This is the field that gets faked most often, and the fake is hard to see because it reads like a plan. "Ship a pattern, a workflow or a guide — which one does not matter" satisfies a library commitment on paper and specifies no work at all. Three consecutive weekly reviews here filled a value slot with exactly that sentence, and the artifact count stayed flat across all three. A commitment you can close without deciding anything is a commitment to nothing.
Expedite entry criteria, and why they are severe
All three must hold, or it is not an expedite:
- It is live — reproducible in production right now. Not on the main branch, not in a draft.
- A user hits it, or it is a security or legal exposure.
- Waiting until the next slot costs more than the work it displaces.
WIP limit 1, absolutely. If a second candidate appears while one is running, one of them is not an expedite, and deciding which is the point of the limit.
4. Run discovery beside delivery, not inside it
Here is a structural bias that is easy to miss in an agent-heavy estate. Ours has a dozen automated desks — vendor-release watchers, review agents, content linters, a weekly artifact gate. Every one of them is a detector, and a detector emits corrective work by construction. Point enough of them at a codebase and the backlog fills with genuinely valid items, none of which is a new thing.
That is the second half of the diagnosis: 42 open items, 2 of which would produce something that did not already exist. Nothing in the estate was asking what should exist next that does not exist yet, so the answer arrived only when a human happened to think of it.
The fix is dual-track: discovery runs continuously alongside delivery. It is two kinds of work, not two teams and not two phases. Marty Cagan is explicit on this point: dual-track's workflow is "not characterized by each role delivering artifacts on to the next step; rather it is collaborative" — the alternative he describes, requirements handed to design and then handed to a delivery team, is a mini-waterfall wearing agile vocabulary. If your discovery step produces a document that someone else receives, you have rebuilt the thing it replaces. What changes in practice is smaller than it sounds: the inputs mostly already exist, and none of them was pointed at opportunity.
| Source | What it is normally asked | What discovery asks instead |
|---|---|---|
| Vendor releases | Did any of our claims go stale? | What should now exist? |
| Competitor state | Are we behind? | What door did they leave open? |
| Search and analytics | How are we ranking? | What are they asking that we do not answer? |
| Audience research | Are they satisfied? | What did they say they need? |
| Your own build | Did it work? | What did we just learn that is worth publishing? |
Discovery emits candidates, not tickets. Its output is an opportunity with candidate solutions and the riskiest assumption named — a roadmap candidate that becomes an item only once it clears the five fields in step 3. That ordering is the point: discovery may kill, reshape or defer a candidate, and a discovery step that cannot kill anything is a requirements factory with a better name.
5. Check the premise before you build
This step exists only because agents implement quickly, and it is the one most teams have never needed. When implementation is fast, the backlog rots faster than it is read. An item filed on Tuesday describing a defect can be untrue by Thursday, because something else fixed it in passing — and nothing about the item's text changes when that happens.
Measured here across one batch of 56 items dispatched to agents: 7 of them — 12.5% — had premises that no longer held. The described defect was already fixed. Two would have actively introduced errors if executed literally: one proposed a replacement citation that said the opposite of the claim it was meant to support, the other carried a market figure that re-measurement contradicted. The catch came from a single instruction attached to every dispatch — this item is a claim; verify it against the current code before you edit — and not from any gate.
The same rot shows up at reporting time, which is worse because it looks like corroboration. In one week, four separate agent findings named defects that had been fixed two days earlier. Four independent reports agreeing is normally evidence; here it was four readings of the same stale text.
So the rule is: an item is a claim, and a report about an item is also a claim. Verify against the current tree before you act, and re-verify before you escalate. Which raises the obvious question — why is a manual instruction doing a job that sounds automatable?
Rules we tried, measured, and threw away
Two of them, and the first answers that question directly. This section is here because a system described only by its surviving rules reads as though it was designed correctly the first time, and none of them are.
Abandoned: automating the premise check
A 12.5% failure rate caught by a manual instruction is an obvious candidate for a gate. We built two, measured both in a single day, and kept neither.
- A path-existence check over every file path an item cites. Result: 0 real breakages found in 36 citations, at a 25% false-positive rate. The false positives were not fixable noise but a category error — an item legitimately cites things like a bare filename with a line number, which is not a repository path and never was.
- A quoted-text re-grep, checking that text an item quotes still appears where it says. Result: 35 of 49 quotes flagged, nearly all of them correctly written. An item quotes text that should exist, text that should not exist yet, text quoted from a different file for contrast, and proposed replacement wording — and nothing in the item's format distinguishes those four cases.
Both went in the bin the same day they were built. The manual instruction stayed, because it is the one with evidence behind it: a measured 12.5% catch beats a gate that fires on most of what it reads and is right about almost none of it, and a gate that cries wolf is a gate someone switches off within a fortnight. The useful residue is knowing the precondition — automating this becomes possible only once items mark which of their quotes assert current content, which is a format change, not a script. We have not made it.
The generalisable lesson is not "don't automate." It is that a check which cannot distinguish the failure from the intended case has no threshold that makes it useful, and no amount of tuning creates one. Test that property before building the check, not after.
Abandoned: one priority scale for all work
The four-level priority scale in the diagnosis above ran for four weeks and never once looked broken. That is the interesting part. It failed in a way that is nearly undetectable from inside: every individual ranking decision was defensible on its own terms, and the aggregate outcome was wrong every single week. You cannot find that by reviewing decisions one at a time — it only became visible when someone stopped auditing the ranking and counted the outputs instead.
Worth naming a third rule, honestly labelled: the ops ceiling we did not try. It was the first proposal and it was rejected before being built, on the argument in step 2 — that a ceiling is only measurable after the week is over. That is reasoning, not evidence, and it belongs in a different category than the two above. If you adopt one thing from this page, adopt the habit of labelling which is which.
As built in this repo
The system above is not a proposal here; it is what this platform runs on, adopted 2026-08-13. It is also one day old at the time of writing, and that matters for how much weight to put on it.
- The policy lives in one versioned file —
docs/WORK-SYSTEM.md— separate from the ledger it governs. Policy and ledger drift apart the moment they share a file. - The floor is checked at a weekly review that opens with the protected slots, before any status reporting. An unmet floor is its first item, ahead of anything requiring a decision.
- Discovery is a scheduled step with its own output format, and its first run produced five candidates from sources that had all been read many times before for other purposes. It also reported its own bias in writing: four of five candidates were artifacts rather than capabilities, which tells you which source it under-used.
- The premise check is an instruction in every dispatch, not a script — for the measured reasons above.
What is evidenced and what is not: the failures are measured, the fixes are not yet. Every number on this page describes a problem we observed; none of them describes a result. The honest status is that the diagnosis is data and the treatment is a bet — and the reason to publish it now rather than in six months is that the diagnosis is the part that transfers.
Pitfalls
- Reintroducing cross-lane ranking through the back door. The most common route is a "global top 3" laid over the lanes for visibility. It restores the exact comparison the lanes were built to prevent, and it restores it in the place everyone actually looks.
- Letting the residual lane shrink. If ops stops being your biggest lane, check whether work is being reclassified rather than eliminated. Infrastructure relabelled as product is the same week with a better report.
- Satisfying a commitment with a category. Covered in step 3 and worth repeating, because it is the failure that hides inside a green week.
- Treating an appetite as an estimate. Once "two days" becomes a prediction rather than a limit, blowing it produces an explanation instead of a decision, and the circuit breaker is gone.
- Expedite creep. Every urgent item is urgent to whoever filed it. Without published entry criteria and a WIP limit of 1, the expedite class silently becomes the default and the whole classification collapses into one queue again.
- Trusting agreement between agent reports. Several agents reading the same stale item is one observation, not several. Convergence between passes that share a premise is not corroboration.
When not to use this workflow
Skip it entirely if deciding is not your constraint. A team whose backlog is short, whose direction is set by someone with full context, or whose implementation is genuinely the bottleneck will get nothing from lanes and floors except overhead — the machinery only pays where the queue in front of the decision is longer than the queue behind it. The tell is the measurement in the diagnosis, not a feeling: count the outputs a user could notice against the commits. If those two numbers track each other, you do not have this problem.
Skip the discovery track specifically if you are pre-product-market-fit with a single hypothesis you have not tested yet. You do not need a machine for generating candidates when you already have one candidate and no evidence about it. Discovery earns its slot once you have more plausible directions than weeks.
And skip the whole apparatus for anything genuinely urgent and small. A live outage does not get classified; it gets fixed. The expedite class exists precisely so the system has a defined way of being bypassed, which is the difference between a process and a bureaucracy.
How you know it is working
The measures that would falsify this, stated in advance so they cannot be retro-fitted:
- Outputs a user could notice, per week — the number that was 0 in the diagnosis week. If it stays near zero while commit volume holds, the lanes changed the paperwork and nothing else.
- Share of open items whose output is a new thing — 2 of 42 at the start. Discovery is working only if this ratio moves.
- Weeks where a protected slot was displaced — with the named trade recorded each time. Zero displacements is as suspicious as many; it usually means the floor is being reported rather than enforced.
- Premise-expiry rate on dispatched work — 12.5% baseline. Rising means the backlog is rotting faster than it is being read, which is a signal to shorten the queue rather than to check harder.
Changelog
- 2026-08-14 — initial version. Written against this platform's own work system, adopted 2026-08-13, with the 2026-08-13 measurements that forced each rule and the two abandoned mechanisms measured 2026-08-11.
- Classes of service, the expedite class, and explicit policies — the Kanban Guide (Kanban University), and David J. Anderson, Kanban: Successful Evolutionary Change for Your Technology Business. The 50/20/30 capacity-allocation figure often quoted online is an illustrative twenty-item example, not a published recommendation — verified 2026-08-14.
- Toil definition, the 50% cap and its escalation consequence — Google, Site Reliability Engineering, "Eliminating Toil"; the same chapter in the SRE Workbook. Quotations verified against the live text 2026-08-14.
- Appetite, shaping, the circuit breaker, and the explicit small-team carve-out — Basecamp, Shape Up, Appendix 2: Adjust to Your Size. Quotation verified 2026-08-14.
- Dual-track discovery and the hand-off anti-pattern — Marty Cagan (SVPG), Dual-Track Agile; Teresa Torres, the opportunity solution tree; Jeff Patton on dual-track development.
- Weighted-shortest-job-first, used within a lane and never as a substitute for allocation — SAFe's WSJF definition. Its documented failure mode, a stream of small jobs starving strategically important large work, is the behaviour the diagnosis above measured.
- AI as an amplifier of existing organisational strengths and weaknesses — DORA 2025, State of AI-assisted Software Development. Developers slower while believing themselves faster — METR's 2025 randomised controlled trial; note its stated scope, experienced developers on large mature repositories they already know well.
- Every figure attributed to "this platform" — the commit and artifact counts, the 42/2 backlog split, the 12.5% premise-expiry rate, the 36-citation and 49-quote gate measurements — comes from operating this repo and its agent estate, measured 2026-08-11 and 2026-08-13. They describe a problem we observed, not a result we achieved.
Docs and tooling versions drift; re-verify against the linked source before adopting. Corrections: hello@aiarch.dev.
Learn the engineering underneath the workflow.
aiArch teaches agents, evals, and production AI architecture by building — on a platform whose own build decisions, including the ones that failed, are the curriculum.
See how aiArch helps senior engineers become AI-native, or compare Professional Membership pricing.
Free sample — no signup · every claim cited · full curriculum is waitlist-only