Delivery stages: where the work actually ended up

Where the Work Ended Up sorts everything the team touched into five stages. The stages are derived from your own tracker statuses through a per-board map you can edit, and the boundary that matters most — merged — is the one that separates work the engineers still hold from work that is waiting on someone else.

deckgauge · Board · Team Focus · Where the Work Ended Up
In production
Waiting to ship
In development
Aborted work
Not started / stalled

The five-stage funnel over one 90-day window.

The five stages

StageMeansDefault Jira statusesDefault Azure DevOps states
In productionShipped and liveDoneDone, Closed, Deployed to All Prod, Deployed to ZA, Deployed to Africa1
Waiting to shipMerged; someone else's turnReady to Deploy, Client Review, QA Ready, QA In Progress, Live TestingPull Request Done, Deployed to Uat, Deployed to Dev
In developmentStill the engineer's to finishIn Progress, Code ReviewIn Progress, Pull Request Doing, Send Back to Dev
Aborted workStarted, then abandonedCancelledRemoved
Not started / stalledNever begun, or parkedTo Do, On Hold, BlockedNew, To Do, Approved, On Hold

Why "merged" is the line that matters

Earlier drafts called these two stages "merged, not in production" and "in flight", which read as the same thing. They are not. Splitting on merge is what lets the view report "the bottleneck is downstream of the engineers" instead of "56 unfinished tasks" — a sentence that points at exactly the wrong people.

The genuinely arguable statuses are QA and client review. On the reference window they were 14 of the 38 waiting-to-ship tasks, which is precisely why the map is editable rather than fixed.

Aborted work: cancelled tickets are a process signal

Cancelled work is not stalled work, and the four-stage model had nowhere to put it. Before the fifth stage existed, 150 cancelled Jira tickets were filling 46% of the "not started" bar — and the interesting half was invisible.

Only worked tickets countA ticket that somebody started and that was then cancelled is wasted effort and a process signal. A ticket cancelled before anyone touched it is neither — it is not work at all. So only the first kind lands in the Aborted work bar; the second leaves the population entirely, and the caveats widget states how many did.

On that same board the split was 28 worked and 122 never worked. Deployment-wide on the Azure DevOps side, moving Removed into this stage reclassified 783 worked items as aborted work and took 2,224 untouched ones out of the denominators.

The bar reads "Aborted work" rather than "Wasted effort", which is what it said briefly. Same finding, less verdict: the team did the work that was asked of them, and calling their output waste blames them for a decision taken above them.

Counting features, not issues

The funnel and the Landed in Production tile count features — every issue rolled up to the top-level item it hangs under. Every other figure on the tab counts issues.

Without the rollup, an epic, the story under it and the sub-task under that were three peers in the funnel. A cancelled epic with eleven cancelled children scored twelve points; an epic whose children were being actively worked read as idle because nothing had changed its own status. Measured on the reference board:

StagePer issuePer feature
In production460 · 65%41 · 48%
Waiting to ship8 · 1%1 · 1%
In development44 · 6%14 · 16%
Aborted work28 · 4%9 · 11%
Not started / stalled168 · 24%20 · 24%
Population708 issues85 features
The population is the window's issues less those cancelled before anyone worked them — a cancelled-before-started ticket is not work, so it leaves the delivery-stage counts entirely. Totals quoted for this board elsewhere on the site differ by a handful because they were measured on different days; the shape is what carries, not the last digit.

This matches how the timesheet and CapEx/OpEx path has always worked: walk the parent chain to its root, and that root is the feature. Focus was the outlier, not the precedent.

How a feature gets its stage

A feature takes one stage from all the issues beneath it, in this order — the first that any child matches wins:

  1. In development — a feature is being built if anyone is building any part of it.
  2. Waiting to ship
  3. Not started / stalled — a feature is only in production when nothing beneath it is still unstarted.
  4. In production
  5. Aborted work — only when every child was cancelled, i.e. the whole thing was abandoned.

Both of the last two placements are counter-intuitive, and they were found in different ways. In production sat above not started until a board owner read a funnel that was wrong: a single Done sub-task beat two To Do ones, and a feature was reported as landed while most of its scope had not begun. Aborted work sat above not started too, so a feature with one cut sub-task and one unstarted one read as wholly abandoned and left the page — that one was latent on the reference data, moved no published figure, and only a test could find it.

What the rollup loses, and where it comes backA feature with one shipped child and ten cancelled ones reads in production — something did ship. Those ten binned children leave the bar entirely, and their days are reported separately as wasted days inside live features. Without that second figure this precedence would start hiding waste.

Editing the stage map

Under the funnel, a board editor gets Configure stage map →. When something is unmapped it reads Map these N states → instead, next to the amber line naming them:

On the widgetCounted as not started because this board's stage map does not know them: Awaiting Sign-off, Ready for UAT.

The editor lists only the statuses your own sources actually report, read live from the synced history and sorted with the unmapped ones first. It is deliberately all-time rather than windowed: configuring a board-level map is not a statement about this quarter, and a windowed list would refuse a status the board genuinely uses but has not touched in ninety days.

Saving evicts this board's widget cache, so the bars move without a page reload. A viewer can read the map; only an editor can change it.

The "Approved" check, run per window

Approved means different things in different Azure DevOps projects. In the Agile template it commonly means groomed and ready to start, and the observed path is New → Approved → In Progress. Treating it as completion added around 30 phantom deliveries to an early draft of the reference report.

Rather than trusting the default, each render counts transitions out of Approved and reports what it found in the caveats — for example "41 of 44 transitions out of Approved led to a working state — counted as NOT started." If nothing left Approved in the window, it says that too rather than asserting a verdict it could not verify.

If it looks wrong

SymptomCauseFix
The two middle bars are empty and "not started" is enormousYour statuses are not in the stage mapUse the Map these N states → link under the chart
QA work counts as unfinished engineeringYour QA statuses map to in developmentMove them to waiting to ship in the editor
Aborted work reads 0 despite many cancelled ticketsNone of them were ever worked, or your cancel status is unmappedCheck the caveats for the "cancelled before starting" count
Funnel total ≠ ledger totalFeatures versus issuesExpected — both totals are named in the caveats
A status is missing from the editorNo synced item on this board has ever carried itSync first; the list is built from your own data

Frequently asked

What is the difference between "in development" and "waiting to ship"?
The boundary is merged. In development is the engineer’s to finish; waiting to ship is not. Keeping them apart is what lets the view say a bottleneck sits downstream of the engineers, rather than reporting one large count of unfinished tasks, which reads as the opposite conclusion.
How does Deckgauge count cancelled tickets?
As a fifth stage called Aborted work, and only when somebody actually worked on the ticket. A ticket cancelled before anyone touched it leaves the population entirely and is reported separately in the caveats. On the reference board, 150 cancelled tickets split into 28 that had been worked and 122 that never were — counting all 150 as stalled work had been filling 46% of the not-started bar.
Why does the delivery funnel show a different total to the ledger?
Because the funnel counts features and the ledger counts issues. An issue is rolled up to the top-level item it hangs under, so work on a sub-task counts for its epic. On the reference board 828 issues rolled up to 85 features. Both totals are printed in the Method and caveats widget so the difference is never a surprise.
My tracker uses custom statuses. Will the funnel work?
Partly, until you map them. A status the board’s stage map does not know is counted as not started, which empties the two middle bars. The widget names those statuses underneath the chart and offers a "Map these N states" link straight into the editor, which lists only the statuses your own sources actually report.
Does Deckgauge treat an "Approved" status as done?
No, and it verifies that per window rather than assuming it. In Azure DevOps Agile templates Approved commonly means groomed and ready to start, with the observed path New to Approved to In Progress. Each render counts how many transitions out of Approved led to a working state and states what it found in the caveats. Treating it as completion added roughly 30 phantom deliveries to an early draft of the reference report.

Related

Last updated