How work enters, moves, and exits
Map the actual path a unit of work takes, and where it stalls.
Look at your team's project board. It tells you what tickets exist and what status they are in, but not where the work is.
A ticket marked "In Code Review" might have sat in someone's review queue for two days. One marked "QA" might be waiting on a deploy window nobody on the team calls a deploy window, and one marked "In Progress" might be blocked because the design moved while the engineer was still building against the older version. None of it shows up on the board.
Most delivery-flow problems surface downstream of where they were caused. The slow cycle time and the QA pile-up are symptoms, and the cause is almost never at the stage where they show up. It is earlier, at how work entered the team and how much was let in at once.
So before optimizing any stage, draw what is happening to one unit of work. The drawing takes an afternoon, and it tells you where to start fixing.
Map the real path
The whole exercise fits in an afternoon: one ticket, walked with the people who touched it.
- Pick a ticket your team shipped in the last two weeks.
- Sit down with the people who touched it, and for every step ask where it waited and for how long.
- Write down the real pauses rather than the column the status sat in:
- Hours in someone's review queue.
- The day lost to a deploy freeze.
- The week the design got redrawn.
The first time you run this, you will find shadow stages, places where work waits that the board does not show:
- Code review queues that no filter surfaces.
- Deploy windows that gate work without being labeled.
- Designs that get redrawn after a ticket is "in progress."
- QA that pauses on a Tuesday because of someone else's release.
The map also tells you whether to run a heavy process or a light one. A six-person team building a 0-to-1 app can run the whole flow on a single spreadsheet, and a heavier ticket tracker would be overhead the team pays in clicks every day. A platform team with three squads and a phased Android rollout would collapse the same sheet inside a week. Walking one ticket tells you which of those teams you are.
Entry: one funnel, one artifact, a reservoir
Most of the real fix lives here, at the boundary between the rest of the company and engineering, because the boundary is where you decide what counts as work and how much engineering takes on at a time. Left to itself, the boundary defaults to open: filing a request costs the filer nothing and the whole bill lands on engineering, so nobody on the filing side ever has a reason to stop.
Route intake through one source. Pick one team to own handover. In my setup that team is product: growth, sales, customer support, and internal engineering work all notify product, and product is the only team that hands work over to engineering. The noise reduction is real, and once everyone gets used to the routing it costs almost nothing.
Treat the handover as a document, the one engineering needs to start work. It contains:
- A spec or PRD.
- A design reference (a design file, a prototype, or a hand-drawn UI sketch in the AI era).
- The target release or sprint.
- A named engineer.
Engineering leads review the handover before it lands, because a problem caught at the handover costs an hour and the same problem caught after engineering has started costs days.
Put a reservoir between product and engineering. A backlog accepts whatever product adds to it. A reservoir works differently: product fills it, and engineering pulls from it at the rate engineering can absorb. The constraint lives on the outflow rather than the inflow. (That is Goldratt's Theory of Constraints, ported from a factory floor to the intake boundary.)
Pulling a ticket out of the reservoir is a small ritual:
- Take the next priority item.
- Give it a high-level T-shirt size.
- Name an engineer.
- Decrement that engineer's available bandwidth (the output of the reserving-capacity exercise).
When the team's bandwidth is full, what is left in the reservoir is what did not fit, and you get to look at the overflow while it is still a list rather than a delivery problem.
This broke for me recently. Product on one of my teams stopped doing its gatekeeping job for a stretch, tickets came in unfiltered, and engineering got buried. The quick patch had three moves:
- Pause the funnel.
- Reprioritize what was in flight.
- Share specific feedback with product about what broke.
The patch is reactive, and nothing in it stops the funnel from breaking the same way again. Three mechanisms from Kanban practice catch the next break early:
- Make the reservoir level public. When it grows past a threshold (a number of items, or weeks of work at the current pull rate), the review triggers on its own.
- Run intake at a cadence. Weekly or biweekly, product and engineering leads compare what came in against what got pulled. A funnel break shows up as inflow outpacing outflow, which is the earliest signal you will get.
- Post per-class quotas inside the reservoir. Urgent, planned, and internal each get a posted share, and when a class exceeds its quota the rule forces a trade against another class. The trade routes the prioritization conversation back to product before engineering absorbs the cost.
Expect some pushback here. Product will sometimes call this waterfall, or call engineering slow, and the pushback is worth tuning around rather than folding to, because the alternative, letting unfiltered volume through and hoping, costs the team more.
Transit: the fewest states that earn their keep
Once a ticket is moving, the temptation is to add states to track every sub-stage. The economics run the wrong way: a new state is cheap for whoever wants the report and charged to everyone else at every transition, so states accumulate unless someone refuses them. My default is to refuse every new state until a retrospective forces one through.
The bar is high:
- The work has to genuinely sit in that phase for a meaningful stretch (order of days).
- The existing states have to mislead someone reporting on them.
- No filter or automation can capture the same signal more cheaply.
QA Done is a state that cleared the bar. On Android a release ships as a phased rollout, the build reaching users gradually (10 percent, then 50, then 100) over days. Before the team added the state, a ticket flipped to Done the moment QA approved the build, while most users still did not have it, so the dashboard said shipped and production told a different story. The state earned its place because the wait was long and no other signal showed the rollout percentage.
The counterexample came from a team I inherited, whose workflow already had a Code Review Done, Deploy Pending state meant to capture the wait between a merged PR and the next QA build. The wait is real, but it runs in hours and the build pipeline already shows it. A few weeks of watching the state in action settled it: people kept confusing it with the other in-flight states, it created more noise than help, and I removed it.
Each transition has a small set of operational preconditions:
- Backlog to In Progress: spec and design reference present.
- In Progress to Code Review: unit tests passing (where the team uses them).
- Code Review to QA: manual code review approved.
- QA Done to Done: rollout at 100 percent.
These are operational gates, and whether the thing is really done (feature shipped, outcome achieved, learning captured) is a separate question.
Gates fail in one specific way, which is theatre: someone ticks the box without doing the underlying check. The tick is free in the moment and the cost lands weeks later, as a quality regression the gate was supposed to catch, so the number worth auditing is the regression rate. The checkboxes will always look fine.
Multiple views
The project board is one view of the work. On a busy week I run at least three views in parallel:
- A dev plate filter (everything from Todo through Code Review).
- A QA plate filter.
- A release filter sliced by target version.
On smaller teams the same views collapse into a single spreadsheet. Pick whichever view answers the question you are asking this week.
The playbook is the artifact
The map, the funnel, the reservoir, the states, the views, the guardrails: none of it is ever finished, and the place it all gets edited is the sprint retrospective.
When the same "you missed doing this" surfaces in retro two or three times, that is the signal to automate the step rather than repeat the reminder. Good automation candidates:
- Multi-board ticket creation.
- Cross-board field sync.
- Status linking.
Some process needs human judgment and stays manual, and the retro tells you which is which.
The playbook that comes out of your first map will be wrong about something within a quarter, and the retro is where you find out which part. Fixing it is another afternoon and another walked ticket.