Second FN-8596 strand, found after the first fix shipped. Clearing the
stale `planning` status moved the card into a state owned by NOBODY:
- planning excluded it: stale `firstExecutionAt` from its first pass made
hasAdvancedPastPlanning true, and the previous fix only rescued cards
that still carried a planning-stage status;
- recoverAdvancedTriageTasks — the designated owner of that
"stranded-advanced" class — also excluded it, because it bails on
`workflowIrPinColumnId === "triage"`: it cannot resume a card into the
column it already occupies (the pin was plan-replan, which lives in
triage).
So the card sat indefinitely with no sweep, log, or audit event naming it.
hasAdvancedPastPlanning now decides on arrival order alone for any card in
the planner column: a stamp written BEFORE the card reached triage belongs
to a previous pass, whatever the status is now. A card that genuinely
advanced is still caught by the column check at the top, and one claimed by
execution AFTER landing here has a stamp newer than its arrival, so it
still reads advanced and stays with advanced-recovery. This flips one case
I added in the previous commit — production proved that classification
stranded the card.
Hardening, so this class cannot hide again:
- detectStalledCards: a detect-only watchdog emitting
`task:stall-watchdog-detected` for any non-terminal, unpaused card idle
past 30m with no live session and no queued continuation. Deduped per
shape. It deliberately does NOT mutate — a generic mutator racing the
specialized sweeps is the bug class this file keeps re-fixing, so
recovery stays with the sweep that owns each shape and this guarantees
visibility.
- The silent skips are now loud: runIfStillPlanningUnderTaskLock (all
four callers inherit it), the planning handoff moveTaskIf, and the four
requestPreMergeOptionalStepFix refusals now log why nothing was
scheduled and that the card was left parked.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Changeset Format Guide
Each changeset file in this directory describes one user-facing change for release notes.
Required body format
---
"@runfusion/fusion": minor
---
summary: Add a Command Center productivity control for LOC backfills.
category: feature
dev: Uses the new `fn_backfill_loc` tool; settings key `commandCenter.locBackfill`.
Fields
| Field | Required | Description |
|---|---|---|
summary |
Yes | One line, user-facing, max 120 chars. Describe what changed for the operator. |
category |
Yes | One of: feature, fix, breaking, security, performance, internal. |
dev |
No | Developer or migration detail. Preserved in per-package CHANGELOGs but excluded from distilled release notes. |
Audience
The summary is the only content that appears in end-user release notes by default. Write for Fusion operators — describe behavior, fixes, and what changed. Avoid internal class names, file paths, and implementation detail.
Bump types
patch— bug fixes, internal changesminor— new features, CLI additions, toolsmajor— breaking changes
Validation
Run pnpm check:changesets to validate. The linter runs in the PR-check gate and test:gate. Legacy freeform changesets pass with a warning during the transition period.