diff --git a/plugins/fusion-plugin-dependency-graph/src/DependencyGraph.tsx b/plugins/fusion-plugin-dependency-graph/src/DependencyGraph.tsx index 5b77ad424f..4b52beab39 100644 --- a/plugins/fusion-plugin-dependency-graph/src/DependencyGraph.tsx +++ b/plugins/fusion-plugin-dependency-graph/src/DependencyGraph.tsx @@ -31,7 +31,6 @@ export interface DependencyGraphProps { onDeleteTask?: (id: string, options?: { removeDependencyReferences?: boolean }) => Promise; onRetryTask?: (id: string) => Promise; onOpenDetailWithTab?: (task: Task, initialTab: "changes") => void; - taskStuckTimeoutMs?: number; onOpenMission?: (missionId: string) => void; onMoveTask?: (id: string, column: Task["column"], optionsOrPosition?: { preserveProgress?: boolean } | number) => Promise; lastFetchTimeMs?: number; @@ -53,7 +52,6 @@ export function DependencyGraph({ onDeleteTask, onRetryTask, onOpenDetailWithTab, - taskStuckTimeoutMs, onOpenMission, onMoveTask, lastFetchTimeMs, @@ -500,7 +498,6 @@ export function DependencyGraph({ onDeleteTask={onDeleteTask} onRetryTask={onRetryTask} onOpenDetailWithTab={onOpenDetailWithTab} - taskStuckTimeoutMs={taskStuckTimeoutMs} onOpenMission={onOpenMission} onMoveTask={onMoveTask} lastFetchTimeMs={lastFetchTimeMs} diff --git a/plugins/fusion-plugin-dependency-graph/src/GraphTaskNode.tsx b/plugins/fusion-plugin-dependency-graph/src/GraphTaskNode.tsx index 123003d172..67b316c70c 100644 --- a/plugins/fusion-plugin-dependency-graph/src/GraphTaskNode.tsx +++ b/plugins/fusion-plugin-dependency-graph/src/GraphTaskNode.tsx @@ -3,7 +3,6 @@ import type { TraitFlags } from "@fusion/core"; import type { GraphPosition } from "./types.js"; import { useNodeDrag } from "./hooks/useNodeDrag.js"; import { TaskCard } from "@fusion/dashboard/app/components/TaskCard"; -import { isTaskStuck } from "@fusion/dashboard/app/utils/taskStuck"; import "./GraphTaskNode.css"; import "./GraphHighlight.css"; import "./styles/drag.css"; @@ -23,7 +22,6 @@ type TaskCardBridgeProps = Pick< | "onDeleteTask" | "onRetryTask" | "onOpenDetailWithTab" - | "taskStuckTimeoutMs" | "onOpenMission" | "onMoveTask" | "lastFetchTimeMs" @@ -34,10 +32,8 @@ export interface GraphTaskNodeProps extends TaskCardBridgeProps, Pick> = onOpenDetailWithTab: vi.fn(), onMoveTask: vi.fn(), onOpenMission: vi.fn(), - taskStuckTimeoutMs: 1000, lastFetchTimeMs: Date.now(), workflowStepNameLookup: new Map(), ...overrides, diff --git a/plugins/fusion-plugin-dependency-graph/src/__tests__/GraphTaskNode.test.tsx b/plugins/fusion-plugin-dependency-graph/src/__tests__/GraphTaskNode.test.tsx index 47a04bb50d..e1e1ac7780 100644 --- a/plugins/fusion-plugin-dependency-graph/src/__tests__/GraphTaskNode.test.tsx +++ b/plugins/fusion-plugin-dependency-graph/src/__tests__/GraphTaskNode.test.tsx @@ -48,7 +48,6 @@ function createProps(task: Task) { onOpenDetailWithTab: vi.fn(), onMoveTask: vi.fn(), onOpenMission: vi.fn(), - taskStuckTimeoutMs: 60_000, lastFetchTimeMs: Date.now(), workflowStepNameLookup: new Map(), }; @@ -384,38 +383,8 @@ describe("GraphTaskNode", () => { }); }); -/* -FNXC:WorkflowLifecycleColumns 2026-07-31-15:30: -THE INVARIANT: a stalled card in the board's OWN wip lane reads as stuck, not as healthily running. - -`isTaskStuck` was called without its `columnFlags` argument, so `isWipColumnRole` fell back to the -literal `in-progress`. On a renamed board no graph card could ever be stuck — and because `isStuck` -gates `isActive`, a wedged card rendered with the ACTIVE styling instead: the graph said "running" -about a task that had not moved in hours, while the main board showed the same card as stuck. - -That asymmetry between two views of one task is the whole defect, and it is what this pins. - -Reverted (the 4th argument dropped, or the flags not threaded from the host context), the first case -gets the `--active` class back and fails. -*/ -describe("stuck detection on a renamed board", () => { - const STALE_MS = 120_000; - - function stalledCard() { - return createTask({ - column: "building", - status: "executing", - updatedAt: new Date(Date.now() - STALE_MS).toISOString(), - } as Partial); - } - - it("treats a stalled card in a RENAMED wip lane as stuck, not active", () => { - const props = createProps(stalledCard()); - render(); - - expect(screen.getByTestId("graph-task-node-FN-TEST").className).not.toContain("graph-task-node--active"); - }); - +// FNXC:StuckTagRemoval 2026-08-17-22:30: stuck-task tagging removed from the dashboard; the stalled-card-as-stuck coverage went with it. +describe("active styling", () => { it("still reads a legacy in-progress card as active when it is fresh", () => { const props = createProps(createTask({ column: "in-progress", status: "executing", updatedAt: new Date().toISOString() } as Partial)); render(); diff --git a/plugins/fusion-plugin-dependency-graph/src/__tests__/interactions.test.tsx b/plugins/fusion-plugin-dependency-graph/src/__tests__/interactions.test.tsx index ec15f8a624..e1d898906b 100644 --- a/plugins/fusion-plugin-dependency-graph/src/__tests__/interactions.test.tsx +++ b/plugins/fusion-plugin-dependency-graph/src/__tests__/interactions.test.tsx @@ -157,7 +157,6 @@ describe("dependency graph interactions", () => { onOpenDetailWithTab={vi.fn()} onMoveTask={vi.fn()} onOpenMission={vi.fn()} - taskStuckTimeoutMs={1_000} lastFetchTimeMs={Date.now()} workflowStepNameLookup={new Map()} />, diff --git a/plugins/fusion-plugin-dependency-graph/src/dashboard-interop.d.ts b/plugins/fusion-plugin-dependency-graph/src/dashboard-interop.d.ts index ddcb29ee92..499100d807 100644 --- a/plugins/fusion-plugin-dependency-graph/src/dashboard-interop.d.ts +++ b/plugins/fusion-plugin-dependency-graph/src/dashboard-interop.d.ts @@ -1,21 +1,7 @@ -declare module "@fusion/dashboard/app/utils/taskStuck" { - import type { Task, TraitFlags } from "@fusion/core"; - - /* FNXC:WorkflowLifecycleColumns 2026-07-31-15:30: the 4th parameter existed upstream and this shim - did not declare it, so the plugin could not pass resolved traits even once it had them — and - `isWipColumnRole` fell back to the literal, meaning NO card in the graph was ever shown stuck on a - renamed board while the same card showed stuck correctly on the main board. */ - export function isTaskStuck( - task: Task, - /* FNXC:PluginInteropDrift 2026-07-31-07:50: positionally REQUIRED in the real signature - (`number | undefined`), not optional — a mirror that is merely approximate is the drift this - file already caused once. Found by check-plugin-interop-drift. */ - taskStuckTimeoutMs: number | undefined, - lastFetchTimeMs?: number, - columnFlags?: Partial, - ): boolean; -} - +/* +FNXC:StuckTagRemoval 2026-08-17-22:30: +The taskStuck shim was deleted with the dashboard's stuck-task tagging; the host module no longer exists. +*/ declare module "@fusion/dashboard/app/plugins/types" { import type { ReactNode } from "react"; import type { Task, TaskDetail, TraitFlags, WorkflowStep } from "@fusion/core"; @@ -57,7 +43,6 @@ declare module "@fusion/dashboard/app/components/TaskCard" { onDeleteTask?: (id: string, options?: { removeDependencyReferences?: boolean }) => Promise; onRetryTask?: (id: string) => Promise; onOpenDetailWithTab?: (task: Task | TaskDetail, initialTab: "changes") => void; - taskStuckTimeoutMs?: number; onOpenMission?: (missionId: string) => void; onMoveTask?: (id: string, column: Column, optionsOrPosition?: { preserveProgress?: boolean } | number) => Promise; lastFetchTimeMs?: number;