Classifying work: roadmap, OpEx or internal technical

Every task in the Team Focus window is assigned exactly one class and, where it can be established, one roadmap epic. Four classifiers compete in a fixed order, and whichever one decided is printed next to the task along with a one-line reason you can argue with.

The four classes

GlyphLabelWhat it means
ARoadmap / CAPEXDelivers a roadmap epic, or is unambiguously part of a tracked programme.
BOPEXCustomer-visible bug, performance defect, one-off operational request. Necessary work that keeps the platform standing without advancing it.
CInternal technicalRefactoring, flag removal, tooling, test debt, CI, dev environments, indexes, naming alignment. No roadmap outcome stated on the task.
?UnclassifiedNo classifier could reach it. Counted as its own class in every share on the page — never silently folded into one of the others.
Why these labelsThey use the vocabulary the board is already maintained in. Project.costClassification carries CapEx or OpEx, finance already audits it, and a reader should not have to be told that "CapEx" means "roadmap". Earlier drafts used Roadmap and Defect / operational, which forced exactly that translation.

How is a class decided? The precedence

Evaluated top to bottom; the first row that produces an answer wins. Rows 2 and 3 are one tier — the board's CapEx/OpEx marking — read first from the task itself and then from its nearest classified ancestor.

#TierWhy it sits here
1Human verdictA person taking responsibility for a call. Always wins.
2CapEx / OpEx on the board rowA finance-audited field someone already maintains. Free and authoritative where it exists.
3Inherited CapEx / OpExFrom the nearest classified ancestor. Someone classifying a board row is a decision; a keyword is a guess.
4Rule setOrdered, deterministic and cheap.
5Advisor modelThe residue nothing else could reach.

Inheritance is what makes CapEx worth maintaining

A roadmap lives at epic level: people classify the epic, not the forty tasks under it. So the classifier walks each task's parent chain and takes the classification from the nearest ancestor that carries one.

The difference is not marginal. On the board where this was found, 27 classified epics covered 482 tasks while only 19 were being matched, because only the epics themselves carried the flag. The inherited reason names the row it came from — "Roadmap: inherited from PROJ-14, marked CapEx on the board" — so an inherited call reads as inherited and stays contestable.

A task explicitly marked OpEx underneath a CapEx epic is a deliberate exception, and it wins over the inheritance.

OpEx rules roadmap out, and that beats the rule set

An OpEx marking says one thing reliably — this is not roadmap work — and one thing not at all: whether it is a customer-visible defect or an internal refactor. So it defers to a rule or the model to split B from C, and settles for B if both decline. What it will not accept is a roadmap verdict from either, because that would contradict the flag rather than refine it.

The defect this closedThe built-in epic-link rule returns roadmap for any task whose epic is in the roadmap set. A task marked OpEx on the board and hanging off a CapEx epic therefore came back as roadmap work — contradicting a flag someone had set on purpose. It was invisible until the roadmap epic set started being derived from CapEx-marked board rows, because before that the set was always empty.

The built-in rule set

Rules are ordered matchers on a task's epic link, title or description. The first match by order wins. Four ship by default:

OrderRuleMatchesClass
0epic-linkAny task whose epic is in this board's roadmap setA
10kw/refactorNamespace alignment, pure refactor, renamesC
20kw/toolingSwagger, pipeline, Docker, NuGet, dependency, local dev, CI buildC
30kw/test-debtWrite tests, test coverage, flaky testC

Rule 0 is the only exact classifier in the set — if the tracker says this task belongs to an epic the board treats as roadmap scope, no keyword and no model can improve on that. The three keyword rules deliberately only produce C: "is this a customer-visible defect" is a judgement, and guessing it from keywords is how a classification stops being defensible.

Not yet editable in the UIThe rule set ships as code today. The stage map is the one Focus configuration with an in-product editor — see Delivery stages. Until rules are editable, the practical lever is marking epics CapEx on the board, which is both cheaper and more accurate than any keyword.

The advisor classification run

Whatever the first four tiers could not reach goes to your organisation's advisor model — and only when a board editor asks for it.

deckgauge · Board · Team Focus · Every Task, and Why
26 tasks carry no classification.
Sends up to 200 of them to your advisor model.
Classify with AI

The classification notice, below the filters and above the ledger.

  • It is never on the render path. Opening the board classifies nothing and costs nothing. Inference stays off the page load and out from behind the lock it shares with the conversational advisor.
  • It is bounded. At most 200 tasks per run.
  • It is cached. Verdicts are stored against the task fingerprint, so an unchanged task is never re-classified. Spend is bounded to genuinely new work.
  • Invented epics are dropped. A model that returns a plausible-looking epic key that is not in the roadmap set has that attribution discarded — an accepted hallucination would put a task into the coverage of an epic nobody worked on, which is the exact number these widgets exist to report.
  • The model cannot return Unclassified. "No classifier could reach this" is a fact about the pipeline, not a judgement the model gets to make about its own answer.

If your organisation has no advisor provider configured, the button refuses with "No advisor model is configured for this organization, so there is nothing to run." That is a correct refusal, not a bug — see Advisor providers to configure one.

Overriding a call you disagree with

In the ledger, the Cl column is a control. A board editor picks A, B, C or Unclassified and the call sticks — recorded as a human verdict, which outranks every other tier.

Two properties make the override durable:

  • Content-addressed. The verdict is filed against a SHA-256 of the task's normalised title and description, not its id. So it survives the Jira/Azure DevOps de-duplication that merges the same task from two systems — which on the reference window was roughly half of them — as well as an id change and the next window.
  • Organisation-scoped. One call, honoured on every board that sees the same task.

Setting a task explicitly to Unclassified is a real verdict, not an absence. It records "a person looked at this and judged it unclassifiable", which the provenance widget then counts as a human decision.

How Work Was Classified — the provenance widget

The provenance widget breaks the window down by which tier decided each task. It exists to make one incentive explicit: the more of your work is decided by CapEx markings, the less of it depends on a model's guess.

Why CapEx coverage matters commerciallyMeasured across one real install: 36,932 board rows, of which 111 carried any cost classification at all — 0.3%, concentrated almost entirely on a single board. The field only ever fed a timesheet export, so nobody maintained it. Once it feeds a roadmap-share figure a VP reads weekly, it acquires a purpose, and the team that maintains it gets a visibly better tab.

You can set CapEx/OpEx from the board's CapEx/OpEx column, one row at a time or on a multi-row selection — see Groups and rows.

If it looks wrong

SymptomCauseFix
Nearly everything is ?No CapEx markings, no rule matched, no advisor run yetMark your epics CapEx, then run the classifier for the residue
A task is roadmap and shouldn't beAn ancestor is marked CapExMark the task itself OpEx, or override the class in the ledger
An override reverted after a syncThe title or description changed materially, so the fingerprint changedRe-apply it — this is intended behaviour, not a lost write
The classify button 409sNo advisor provider is configured for the organisationConfigure a provider
Provenance counts exceed the ledger's task countThey should not — provenance divides by every task including cancelled onesCompare against the caveats widget's stated totals

Frequently asked

How does Deckgauge decide whether a ticket is roadmap work?
Four classifiers in a fixed precedence: a human override wins, then the CapEx/OpEx marking on the board row or its nearest classified ancestor, then an ordered rule set, then the advisor model for whatever is left. Each one records which tier decided and a one-line reason, and both are printed next to the task in the ledger.
Do I need an LLM to use the Team Focus view?
No. The view renders without one. Tasks nothing cheaper could classify are reported as Unclassified — counted as their own class, never quietly assumed into another — and the count is stated in the caveats. Marking epics CapEx on the board classifies most work without any model at all, because the classification is inherited down the parent chain.
What happens to my manual classification when the ticket is re-synced?
It survives. Verdicts are keyed by a fingerprint — a SHA-256 of the normalised title and description — rather than by ticket id. That means an override also survives Jira/Azure DevOps de-duplication, an id change, and the next reporting window. Change the title and description substantially and the task becomes a different row, which is the intended behaviour.
Does marking a ticket OpEx stop it being counted as roadmap work?
Yes, and that outranks both the rule set and the model. An OpEx marking cannot separate a customer-visible defect from a refactor, so it defers to a rule or the model to refine the class, but it discards any roadmap verdict either of them returns. Promoting OpEx work to roadmap would contradict a flag someone set deliberately rather than refine it.
How much does an advisor classification run cost?
It is bounded by design. A run classifies at most 200 tasks, only ever the residue nothing cheaper could reach, and results are cached against the task fingerprint — so an unchanged task is never re-classified. Opening the board never triggers inference; a run is an explicit button press by a board editor.

Related

Last updated