diff --git a/packages/dashboard/app/utils/taskRevert.ts b/packages/dashboard/app/utils/taskRevert.ts index 4cbb37d4e5..957eba9ce2 100644 --- a/packages/dashboard/app/utils/taskRevert.ts +++ b/packages/dashboard/app/utils/taskRevert.ts @@ -94,9 +94,27 @@ export function findOpenUndoTaskForSource(tasks: readonly Task[], sourceTaskId: and the behaviour was the legacy fallback forever. Reverted rather than left as a dead seam. An unsupplied optional parameter is strictly worse than - the literal — the literal is at least honest, and the census keeps pointing here. Unblocking it - means hoisting the flags derivation above that call, which is a hook-ordering change in a - 5000-line component (same blocker as the near-duplicate gate in that file). + the literal — the literal is at least honest, and the census keeps pointing here. + + FNXC:WorkflowResolvedColumns 2026-07-30-20:50 (correcting the unblock recorded above): + HOISTING THE FLAGS WOULD NOT UNBLOCK THIS — IT WOULD INTRODUCE A WORSE DEFECT. + + The note above says the blocker is hook ordering, i.e. a cost. It is not: it is a correctness + boundary. This function scans the `tasks` list for OTHER tasks pointing back at the source, so the + column it classifies belongs to a NEIGHBOUR. `detailColumnFlags` in TaskDetailModal describes the + MODAL'S OWN task, and its own FNXC note says so explicitly — it is guarded by + `detailFlagsAreForThisTask` precisely because using it for anything else is wrong. + + So supplying it here would answer "is this neighbour finished?" with the modal task's traits: on a + project where two workflows reuse a column id, an open undo task would be classified by a workflow + it does not belong to and the affordance would vanish or persist wrongly. That is the flags-for- + the-wrong-row shape, and it is worse than the literal because it is wrong on data rather than + merely stale on vocabulary. + + A CORRECT conversion needs per-NEIGHBOUR flags — the caller would have to resolve each candidate's + own workflow, which the modal does not have and should not fetch mid-render. Until a per-task lane + map is available at that call site, the literal is the right answer and the census entry is + accurate debt rather than a missed conversion. */ if (candidate.column === "done" || candidate.column === "archived") { continue;