diff --git a/.changeset/board-header-active-chrome-count.md b/.changeset/board-header-active-chrome-count.md
new file mode 100644
index 0000000000..f446373b13
--- /dev/null
+++ b/.changeset/board-header-active-chrome-count.md
@@ -0,0 +1,7 @@
+---
+"@runfusion/fusion": patch
+---
+
+summary: Board column headers now count REVISING (replan) cards and other visibly active cards in the processing count.
+category: fix
+dev: Column header count = shared Running predicate ∪ card activity-chrome predicate (isTaskAgentActive); footer/admission keep live-agent-only semantics.
diff --git a/packages/dashboard/app/components/Column.tsx b/packages/dashboard/app/components/Column.tsx
index 46685c2225..ab577471af 100644
--- a/packages/dashboard/app/components/Column.tsx
+++ b/packages/dashboard/app/components/Column.tsx
@@ -11,6 +11,8 @@ import { WorktreeGroup } from "./WorktreeGroup";
import { QuickEntryBox } from "./QuickEntryBox";
import { PluginSlot } from "./PluginSlot";
import { groupByWorktree } from "../utils/worktreeGrouping";
+import { isTaskAgentActive } from "../utils/taskActivity";
+import { isTaskStuck } from "../utils/taskStuck";
import type { ToastType } from "../hooks/useToast";
import type { TaskContextMenuColumnMetadata } from "./TaskContextMenu";
import { ChevronDown, ChevronUp, MoreVertical } from "lucide-react";
@@ -291,10 +293,22 @@ function ColumnComponent({ column, tasks, projectId, maxConcurrent, showWorktree
FNXC:BoardColumnCount 2026-07-21-19:30:
Column header is executing/total (e.g. 3/4). Executing uses the same Running predicate as the
footer (unpaused WIP, live planners, active review). Total is the card count in this lane.
+
+ FNXC:BoardColumnCount 2026-07-22-06:10:
+ The header must agree with the cards below it: a Todo card parked in the durable
+ `needs-replan` stage keeps its REVISING badge and activity chrome (FN-8494), so a header
+ that only counts live agents read 0/2 under a glowing card. Union the shared Running
+ predicate with the card's own activity-chrome predicate (isTaskAgentActive, same
+ globalPaused/stuck gates the card applies) so the count equals the number of visibly
+ active cards. Footer Running and admission intentionally keep the live-agent-only truth —
+ a parked replan must not consume top-level concurrency capacity.
*/
const activeTaskCount = useMemo(
- () => tasks.filter((task) => isRunningAgentTask(enrichRunningAgentTaskShapeFromFlags(task, columnFlags))).length,
- [tasks, columnFlags],
+ () => tasks.filter((task) =>
+ isRunningAgentTask(enrichRunningAgentTaskShapeFromFlags(task, columnFlags))
+ || isTaskAgentActive(task, { globalPaused, isStuck: isTaskStuck(task, taskStuckTimeoutMs, lastFetchTimeMs) }),
+ ).length,
+ [tasks, columnFlags, globalPaused, taskStuckTimeoutMs, lastFetchTimeMs],
);
// When search is active, skip pagination so all matching tasks are visible
const shouldPaginate = !isArchived && !isSearchActive && !showWorktreeGroups && tasks.length > PAGINATED_COLUMN_THRESHOLD;
diff --git a/packages/dashboard/app/components/__tests__/Column.test.tsx b/packages/dashboard/app/components/__tests__/Column.test.tsx
index 47e1ce47a4..e0220e200f 100644
--- a/packages/dashboard/app/components/__tests__/Column.test.tsx
+++ b/packages/dashboard/app/components/__tests__/Column.test.tsx
@@ -179,6 +179,44 @@ describe("Column count-flash", () => {
expect(screen.getByLabelText("1 executing of 4")).toHaveTextContent("1/4");
});
+
+ it("counts cards with active chrome — a REVISING (needs-replan) todo card and a live code-review gate", () => {
+ // Header must equal the number of visibly active cards (FN-8494 keeps REVISING chrome on
+ // parked replans; a live gate session runs with null status and a pending step lease).
+ const tasks = [
+ { ...makeTask("FN-001"), column: "todo" as ColumnType, status: "needs-replan" as any },
+ { ...makeTask("FN-002"), column: "todo" as ColumnType },
+ ];
+ render(
+ ,
+ );
+ expect(screen.getByLabelText("1 executing of 2")).toHaveTextContent("1/2");
+ });
+
+ it("counts an in-review card whose code-review gate holds a pending step lease", () => {
+ const tasks = [
+ {
+ ...makeTask("FN-001"),
+ column: "in-review" as ColumnType,
+ workflowStepResults: [{ workflowStepId: "code-review", workflowStepName: "Code Review", status: "pending" as const, startedAt: new Date().toISOString() }],
+ },
+ { ...makeTask("FN-002"), column: "in-review" as ColumnType },
+ ];
+ render(
+ ,
+ );
+ expect(screen.getByLabelText("1 executing of 2")).toHaveTextContent("1/2");
+ });
});
/*