From 62f121e0c9fcb8f913d6785fcd3ba24d5db3b78b Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Fri, 17 Jul 2026 16:20:10 -0700 Subject: [PATCH] FN-8247: stop session advisor with oversight Stop now persists session-advisor disablement and reflects inherited advisor state in task details. - Persist an explicit advisor-off override and clear its live runtime when stopping oversight. - Resolve workflow-level advisor defaults for task-detail icons and toggle behavior. - Cover stop cleanup and desktop/mobile oversight state transitions with regression tests. - Document the combined stop contract and add a patch changeset. Files changed: .changeset/fn-8247-session-advisor-stop-and-icon.md | 7 ++ docs/dashboard-guide.md | 6 +- packages/dashboard/app/components/TaskDetailModal.tsx | 86 +++++++++++------ packages/dashboard/app/components/__tests__/TaskDetailModal.oversight-controls.test.tsx | 104 +++++++++++++++++++++ packages/dashboard/app/components/__tests__/TaskDetailModal.oversight-mobile.test.tsx | 62 ++++++++++++ packages/engine/src/__tests__/project-engine-stop-overseer-session-advisor.test.ts | 62 ++++++++++++ packages/engine/src/project-engine.ts | 13 ++- 7 files changed, 310 insertions(+), 30 deletions(-) Fusion-Task-Id: FN-8247 Fusion-Task-Lineage: dcb67af7-9a36-4b25-bafa-84722fe158a0 Co-authored-by: Fusion (runfusion.ai) --- .../fn-8247-session-advisor-stop-and-icon.md | 7 ++ docs/dashboard-guide.md | 6 +- .../app/components/TaskDetailModal.tsx | 86 ++++++++++----- ...askDetailModal.oversight-controls.test.tsx | 104 ++++++++++++++++++ .../TaskDetailModal.oversight-mobile.test.tsx | 62 +++++++++++ ...gine-stop-overseer-session-advisor.test.ts | 62 +++++++++++ packages/engine/src/project-engine.ts | 13 ++- 7 files changed, 310 insertions(+), 30 deletions(-) create mode 100644 .changeset/fn-8247-session-advisor-stop-and-icon.md create mode 100644 packages/engine/src/__tests__/project-engine-stop-overseer-session-advisor.test.ts diff --git a/.changeset/fn-8247-session-advisor-stop-and-icon.md b/.changeset/fn-8247-session-advisor-stop-and-icon.md new file mode 100644 index 0000000000..7dc8b82501 --- /dev/null +++ b/.changeset/fn-8247-session-advisor-stop-and-icon.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: Stop now disables the session advisor, and its on/off state correctly updates the task-detail oversight icon. +category: fix +dev: stopOverseerTask persists sessionAdvisorEnabled:false and clears the advisor runtime; TaskDetailModal effective-state derivation now honors the resolver's workflow-legacy tier (plannerOverseerAdvisorEnabled). diff --git a/docs/dashboard-guide.md b/docs/dashboard-guide.md index 521961df4e..7f223e24b5 100644 --- a/docs/dashboard-guide.md +++ b/docs/dashboard-guide.md @@ -244,8 +244,10 @@ FNXC:PlannerOversight 2026-07-05-00:00: FN-7604 collapses the desktop inline clu FNXC:QuickAddActionRow 2026-07-16-16:00: FN-8194 aligns task-detail metadata actions with Quick Add: attach, GitHub tracking, Oversight (Eye), Priority, then Fast. -FNXC:PlannerOversight 2026-07-17-13:18: FN-8233 makes the task-detail Oversight trigger communicate the combined effective overseer state: it uses Eye when the oversight level is active or the Session advisor is enabled, and EyeOff only when both are off. --> -- The task detail modal's inline meta-controls cluster follows Quick Add order: compact **Attach file** (`data-testid="detail-inline-attach"`), eligible-task **GitHub tracking** toggle (`data-testid="detail-inline-github-toggle"`), **Oversight**, Priority, and Execution mode. Attach opens the existing task attachment picker; GitHub toggles the existing tracking setting and is omitted for GitLab-tracked or non-editable tasks. The Oversight control exposes planner-overseer actions behind a compact **"Oversight" overflow-menu button** (`data-testid="detail-oversight-menu-trigger"`, `Eye` when the oversight level is active or the Session advisor is enabled, otherwise `EyeOff`, `aria-haspopup="menu"`) on every viewport, desktop and mobile alike. Clicking the trigger opens a `role="menu"` popover (mirroring the existing move-action dropdown pattern) containing: a **quick oversight-level select** (`data-testid="detail-oversight-level-select"`) that writes the per-task `plannerOversightLevel` override (Off/Observe/Steer/Autonomous recovery) or clears it back to the inherited workflow/project default via an "Inherit" option; a **manual nudge** button (`data-testid="detail-overseer-nudge"`) that asks the overseer to inject one guidance-only steering comment into the currently watched stage right now (never a merge/PR/destructive action), disabled when the overseer is off/inactive or the task is user-paused/done/archived/`autoMerge:false` in-review; a **stop oversight** button (`data-testid="detail-overseer-stop"`) that disables active oversight for the task (confirmation-gated), hidden once oversight is already off; and an **explain current action** button (`data-testid="detail-overseer-explain"`) that toggles a small read-only panel (`data-testid="detail-overseer-explain-panel"`) showing the overseer's watched stage, reason, last action, and attempt count/limit, with a non-empty-shell inactive state when the overseer is not currently watching. All three action controls call the `POST /tasks/:id/overseer/nudge`, `POST /tasks/:id/overseer/stop`, and `GET /tasks/:id/overseer/explain` routes. The trigger itself is withheld entirely when none of the menu's controls would render (no empty-shell overflow button for the unresolved-default case). +FNXC:PlannerOversight 2026-07-17-13:18: FN-8233 makes the task-detail Oversight trigger communicate the combined effective overseer state: it uses Eye when the oversight level is active or the Session advisor is enabled, and EyeOff only when both are off. + +FNXC:PlannerOversight 2026-07-18-12:00: FN-8247 requires Stop to disable both lifecycle oversight and the independently-enabled session advisor, including its live runtime, so project/workflow defaults cannot leave advisor comments running after an operator stops it. --> +- The task detail modal's inline meta-controls cluster follows Quick Add order: compact **Attach file** (`data-testid="detail-inline-attach"`), eligible-task **GitHub tracking** toggle (`data-testid="detail-inline-github-toggle"`), **Oversight**, Priority, and Execution mode. Attach opens the existing task attachment picker; GitHub toggles the existing tracking setting and is omitted for GitLab-tracked or non-editable tasks. The Oversight control exposes planner-overseer actions behind a compact **"Oversight" overflow-menu button** (`data-testid="detail-oversight-menu-trigger"`, `Eye` when the oversight level is active or the Session advisor is enabled, otherwise `EyeOff`, `aria-haspopup="menu"`) on every viewport, desktop and mobile alike. Clicking the trigger opens a `role="menu"` popover (mirroring the existing move-action dropdown pattern) containing: a **quick oversight-level select** (`data-testid="detail-oversight-level-select"`) that writes the per-task `plannerOversightLevel` override (Off/Observe/Steer/Autonomous recovery) or clears it back to the inherited workflow/project default via an "Inherit" option; a **manual nudge** button (`data-testid="detail-overseer-nudge"`) that asks the overseer to inject one guidance-only steering comment into the currently watched stage right now (never a merge/PR/destructive action), disabled when the overseer is off/inactive or the task is user-paused/done/archived/`autoMerge:false` in-review; a **Stop** button (`data-testid="detail-overseer-stop"`) that disables both active lifecycle oversight and the session advisor for the task (confirmation-gated), including its live advisor runtime; it is hidden once oversight is already off; and an **explain current action** button (`data-testid="detail-overseer-explain"`) that toggles a small read-only panel (`data-testid="detail-overseer-explain-panel"`) showing the overseer's watched stage, reason, last action, and attempt count/limit, with a non-empty-shell inactive state when the overseer is not currently watching. All three action controls call the `POST /tasks/:id/overseer/nudge`, `POST /tasks/:id/overseer/stop`, and `GET /tasks/:id/overseer/explain` routes. The trigger itself is withheld entirely when none of the menu's controls would render (no empty-shell overflow button for the unresolved-default case). - The controls inside the Oversight menu carry a visible, non-interactive **`"Overseer controls"` group label** (`data-testid="detail-oversight-controls-label"`) so Nudge/Stop/Explain read as an identifiable cluster rather than unlabeled entries; the label is gated by the same `(hasTaskOversightOverride || workflowOversightResolved) && !oversightIsOff` condition as the buttons, so it never renders when oversight is Off/unresolved (opening the menu in that state shows only the level select). When **Nudge** is disabled, an always-visible helper line (`data-testid="detail-overseer-nudge-disabled-reason"`) states the reason in-DOM (mirroring the existing hover `title`) instead of relying on a mouse-hover tooltip alone. **Explain** is read-only and non-mutating, so it is never disabled purely because the overseer is inactive — clicking it always opens/closes the panel, which shows the overseer's live state when watching or an informative "not currently watching this task" message otherwise. Nudge's mutating enablement rule (`canNudgeOverseer`, including the human-control suppression cases) and Stop's confirmation dialog are unchanged.