feat(FN-4465): complete Step 6 — docs and changeset
Fusion-Task-Id: FN-4465 Fusion-Task-Lineage: 4365d4cb-ab93-4ed5-add9-3e14b26237ad
This commit is contained in:
5
.changeset/FN-4465-task-age-staleness.md
Normal file
5
.changeset/FN-4465-task-age-staleness.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@runfusion/fusion": minor
|
||||
---
|
||||
|
||||
Add a diagnostic task-age staleness signal for `in-progress` and `in-review` tasks, with configurable warning/critical thresholds. Surface stale state in the dashboard with task-card badges, task-detail diagnostics, and a new ListView "Stale only" filter. Add scheduler-side structured stale-threshold log emission and settings for per-column warning/critical thresholds.
|
||||
@@ -259,6 +259,10 @@ Override precedence for direct merges is:
|
||||
| `specStalenessEnabled` | `boolean` | `false` | Enforce automatic re-planning for stale plans. |
|
||||
| `specStalenessMaxAgeMs` | `number` | `21600000` | Spec staleness threshold in ms (6 hours). |
|
||||
| `taskStuckTimeoutMs` | `number` | `undefined` | Inactivity timeout for stuck-task recovery. |
|
||||
| `staleInProgressWarningMs` | `number` | `14400000` | Task-age staleness warning threshold in ms for `in-progress` tasks (4 hours). `0` or `undefined` disables warning-level surfacing. |
|
||||
| `staleInProgressCriticalMs` | `number` | `86400000` | Task-age staleness critical threshold in ms for `in-progress` tasks (24 hours). `0` or `undefined` disables critical-level surfacing. |
|
||||
| `staleInReviewWarningMs` | `number` | `86400000` | Task-age staleness warning threshold in ms for `in-review` tasks (24 hours). `0` or `undefined` disables warning-level surfacing. |
|
||||
| `staleInReviewCriticalMs` | `number` | `259200000` | Task-age staleness critical threshold in ms for `in-review` tasks (72 hours). `0` or `undefined` disables critical-level surfacing. |
|
||||
| `staleHighFanoutBlockerAgeThresholdMs` | `number` | `7200000` | Age threshold (ms) before high-fan-out blockers escalate in dashboard task cards/footer. Applies only to blockers currently in `in-progress`/`in-review`; age is computed from `columnMovedAt ?? updatedAt`. |
|
||||
| `capacityRiskBannerEnabled` | `boolean` | `false` | Opt-in gate for the board-level capacity-risk banner. When enabled, the banner is shown once risk conditions are met and can be dismissed per project. |
|
||||
| `capacityRiskTodoThreshold` | `number` | `20` | Todo threshold for the board-level capacity-risk banner (applies when `capacityRiskBannerEnabled` is true). Warning appears only when `todoCount > capacityRiskTodoThreshold` **and** there are zero idle non-ephemeral agents, auto-clears as soon as an idle agent becomes available or todo falls back to threshold/below, and re-arms after threshold/toggle changes. |
|
||||
|
||||
@@ -129,6 +129,31 @@ These entries are rate-limited per `(task, code)` over `taskStuckTimeoutMs`, so
|
||||
|
||||
**Dashboard surface:** In-review, non-paused tasks with `inReviewStall` set show a `Stall` badge on `TaskCard` and a code-specific diagnostic row in `TaskDetailModal` above the PR section. The diagnostic row includes headline/description/action copy, raw reason text, observed timestamp, and a `View activity log` deep-link that switches to Logs → Activity and highlights the most recent matching `In-review stall surfaced [<code>]: <reason>` entry. This UI is diagnostic only: neither the badge nor the jump button mutates task state.
|
||||
|
||||
#### Task age staleness signal
|
||||
|
||||
Fusion now derives `task.ageStaleness` for tasks in `in-progress` and `in-review` (including paused tasks). Age is computed from `columnMovedAt` and falls back to `updatedAt` when needed.
|
||||
|
||||
Signal levels:
|
||||
- `warning`
|
||||
- `critical`
|
||||
|
||||
Threshold settings:
|
||||
- `staleInProgressWarningMs` (default `4h`)
|
||||
- `staleInProgressCriticalMs` (default `24h`)
|
||||
- `staleInReviewWarningMs` (default `24h`)
|
||||
- `staleInReviewCriticalMs` (default `72h`)
|
||||
|
||||
`0` or `undefined` disables that level.
|
||||
|
||||
Invariant: `ageStaleness` is **diagnostic-only**. It never moves, retries, pauses/unpauses, or auto-finalizes tasks.
|
||||
|
||||
Scheduler-side reporting emits structured, rate-limited task-log and engine-log entries in this exact form:
|
||||
- `Stale task age threshold crossed [<level>]: column=<column> paused=<bool> ageMs=<n> warningThresholdMs=<n> criticalThresholdMs=<n>`
|
||||
|
||||
**Dashboard surface:** tasks with `ageStaleness` show a stale badge on `TaskCard`, a diagnostic row in `TaskDetailModal`, and the list view provides a `Stale only` filter that narrows to tasks with a live signal.
|
||||
|
||||
Success metric: maintainers can find all stale cards from the board UI in under 30 seconds.
|
||||
|
||||
Auto-completion/finalization remains owned by existing recovery passes:
|
||||
- `recoverStaleMergingStatus`
|
||||
- `finalizeNoOpReviewTasks`
|
||||
|
||||
Reference in New Issue
Block a user