diff --git a/.changeset/taskcard-live-ticker-renamed-lanes.md b/.changeset/taskcard-live-ticker-renamed-lanes.md
new file mode 100644
index 0000000000..c159568d91
--- /dev/null
+++ b/.changeset/taskcard-live-ticker-renamed-lanes.md
@@ -0,0 +1,7 @@
+---
+"@runfusion/fusion": patch
+---
+
+summary: Cards in renamed in-progress or review lanes now show their live elapsed-time indicator.
+category: fix
+dev: `wantsLiveTimeIndicator`'s dependency list omitted `isWipColumn`/`isReviewColumn`/`taskColumnFlags`, so the memo kept the pre-load answer computed before workflow traits resolved.
diff --git a/packages/dashboard/app/components/TaskCard.tsx b/packages/dashboard/app/components/TaskCard.tsx
index 8294cec3eb..141731ae6e 100644
--- a/packages/dashboard/app/components/TaskCard.tsx
+++ b/packages/dashboard/app/components/TaskCard.tsx
@@ -1732,7 +1732,24 @@ function TaskCardComponent({
}
return true;
- }, [task.column, task.status, task.columnMovedAt, task.updatedAt, task.workflowStepResults, task.timedExecutionMs, task.firstExecutionAt, task.cumulativeActiveMs, task.executionStartedAt, task.executionCompletedAt]);
+ /*
+ FNXC:WorkflowResolvedColumns 2026-07-30-23:40:
+ THE LANE ROLES BELONG IN THIS LIST, or the card never subscribes on a renamed board.
+
+ `isWipColumn`/`isReviewColumn` derive from the `taskColumnFlags` PROP, which arrives after first
+ paint — the board resolves workflow traits asynchronously. The first computation therefore runs
+ with the flags undefined, the role helpers fall back to the legacy ids, and on a renamed board that
+ answers false. When the flags arrive `task.column` is unchanged, so a list of `task.*` fields alone
+ never recomputes and the pre-load answer sticks: no live elapsed-time indicator, for the life of
+ the mount.
+
+ A legacy board hid this completely, because there the fallback already answers true on the first
+ paint and the stale list costs nothing.
+
+ This repo has no `react-hooks/exhaustive-deps` rule, so the list is maintained by hand and a
+ disable directive for that rule fails CI.
+ */
+ }, [task.column, task.status, task.columnMovedAt, task.updatedAt, task.workflowStepResults, task.timedExecutionMs, task.firstExecutionAt, task.cumulativeActiveMs, task.executionStartedAt, task.executionCompletedAt, isWipColumn, isReviewColumn, taskColumnFlags]);
const timeIndicatorNowMs = useLiveTimeTicker(wantsLiveTimeIndicator);
diff --git a/packages/dashboard/app/components/__tests__/TaskCard.live-ticker-renamed-lanes.test.tsx b/packages/dashboard/app/components/__tests__/TaskCard.live-ticker-renamed-lanes.test.tsx
new file mode 100644
index 0000000000..b1b3e66d70
--- /dev/null
+++ b/packages/dashboard/app/components/__tests__/TaskCard.live-ticker-renamed-lanes.test.tsx
@@ -0,0 +1,113 @@
+/*
+FNXC:WorkflowResolvedColumns 2026-07-30-23:35:
+THE LIVE ELAPSED-TIME INDICATOR NEVER STARTED FOR CARDS IN A RENAMED WIP OR REVIEW LANE.
+
+`wantsLiveTimeIndicator` decides whether a card subscribes to the shared ticker. It reads
+`isWipColumn` / `isReviewColumn` / `taskColumnFlags` — all derived from the `taskColumnFlags` PROP —
+while its dependency array lists only `task.*` fields.
+
+`taskColumnFlags` arrives ASYNCHRONOUSLY: the board resolves workflow traits after first paint, so
+the first computation always runs with the flags undefined. The role helpers then fall back to the
+legacy ids, and on a renamed board `isWipColumnRole(undefined, "building")` is false. The card
+decides it needs no ticker. When the flags arrive, `task.column` has not changed — so nothing in the
+dependency array changed, the memo never recomputes, and the card never subscribes.
+
+WHY THE DEFAULT BOARD HID IT. With legacy ids the fallback answers `true` on the very first paint
+(`column === "in-progress"`), so the memo's initial value is already correct and the stale dependency
+list costs nothing. The defect is renamed-board-only, which is why it survived.
+
+Found by generalizing the memo-dependency defect in the blocker fan-out (#2993) into a sweep for
+memoized hooks that read a lane value absent from their deps, rather than treating that one as a
+one-off. This repo has no `react-hooks/exhaustive-deps` rule, so the whole class is invisible to lint.
+*/
+
+import { describe, it, expect, vi } from "vitest";
+import { render } from "@testing-library/react";
+import type { Task } from "@fusion/core";
+import { TaskCard } from "../TaskCard";
+
+/* The subscription flag is the observable: `enabled` is exactly `wantsLiveTimeIndicator`. */
+const tickerCalls: boolean[] = [];
+vi.mock("../../hooks/useLiveTimeTicker", () => ({
+ useLiveTimeTicker: (enabled: boolean) => {
+ tickerCalls.push(enabled);
+ return Date.now();
+ },
+}));
+
+const noop = () => {};
+
+function taskIn(column: string): Task {
+ return {
+ id: "KB-1",
+ title: "a card",
+ description: "t",
+ column,
+ createdAt: "2026-06-01T00:00:00.000Z",
+ updatedAt: "2026-06-01T00:00:00.000Z",
+ executionStartedAt: "2026-06-01T00:00:00.000Z",
+ cumulativeActiveMs: 60_000,
+ steps: [],
+ } as unknown as Task;
+}
+
+/** Did the card subscribe on its LATEST render? */
+const subscribedNow = () => tickerCalls[tickerCalls.length - 1] === true;
+
+describe("the live time indicator when column traits arrive after first paint", () => {
+ /* Control: on a legacy board the fallback answers correctly on the first paint, so this passes
+ with or without the fix and proves the harness observes a real subscription. */
+ it("default vocabulary: a card in `in-progress` subscribes with no flags at all", () => {
+ tickerCalls.length = 0;
+ render();
+
+ expect(subscribedNow()).toBe(true);
+ });
+
+ /*
+ The defect. First paint has no flags, so the renamed lane reads as not-WIP and the card declines
+ the ticker; the flags then arrive and nothing recomputes.
+ */
+ it("renamed vocabulary: a card subscribes once its WIP traits arrive", () => {
+ tickerCalls.length = 0;
+ const { rerender } = render(
+ ,
+ );
+ /* Pre-load: correctly declines, because nothing yet says this lane is WIP. */
+ expect(subscribedNow()).toBe(false);
+
+ rerender(
+ ,
+ );
+
+ expect(subscribedNow()).toBe(true);
+ });
+
+ /*
+ The paired negative: recomputing must not degrade into "every card subscribes". A card whose
+ resolved traits say terminal is finished work and must stay off the shared ticker, or the fix
+ trades one stalled indicator for sixty cards waking a backgrounded tab — the exact cost the
+ shared-ticker refactor documented at this site.
+ */
+ it("renamed vocabulary: a card in the renamed COMPLETE lane does not subscribe", () => {
+ tickerCalls.length = 0;
+ const { rerender } = render(
+ ,
+ );
+ rerender(
+ ,
+ );
+
+ expect(subscribedNow()).toBe(false);
+ });
+});