From 6d4eae01f53df1a950d644c37ca5d39c015a5793 Mon Sep 17 00:00:00 2001
From: Sawyer Cutler
Date: Fri, 21 Aug 2026 15:45:51 -0700
Subject: [PATCH 1/2] Add tests for Insights running-now window decoupling,
elapsed ticking, and run-cap disclosure
Covers three Insights defects: a run started before the 7-day window but
still running must stay in the "Running now" strip and KPI; the elapsed
label next to the live status dot must tick instead of freezing at first
render; and the landing view must disclose when the 100-run fetch cap
truncates the runs backing its KPIs, sparkline, and outcome chart.
---
.../src/pages/insights-page-render.test.tsx | 57 +++++++++++++++++++
apps/web/test/insights-page.test.tsx | 45 +++++++++++++++
2 files changed, 102 insertions(+)
diff --git a/apps/web/src/pages/insights-page-render.test.tsx b/apps/web/src/pages/insights-page-render.test.tsx
index d7e1c994f..4be3a9fa3 100644
--- a/apps/web/src/pages/insights-page-render.test.tsx
+++ b/apps/web/src/pages/insights-page-render.test.tsx
@@ -134,4 +134,61 @@ describe("InsightsPage 'Running now' strip", () => {
expect(el.textContent).toContain("1 in progress");
expect(el.textContent).toContain("Weekly digest");
});
+
+ // Liveness is not a windowed property: a run that started long before the
+ // 7-day window and is still running must not disappear from the strip or
+ // read 0 in the "Running now" KPI just because its start time falls
+ // outside `range`.
+ test("a run started 8 days ago that is still running stays in the strip and the KPI", () => {
+ const eightDaysAgo = new Date(
+ Date.now() - 8 * 24 * 60 * 60 * 1000,
+ ).toISOString();
+ const el = render("/insights", {
+ data: [
+ {
+ id: "run_long_haul",
+ tenantId: "tnt_bench_a",
+ definitionId: "wfd_a",
+ definitionName: "Long haul",
+ address: "addr",
+ status: "running",
+ createdAt: eightDaysAgo,
+ updatedAt: eightDaysAgo,
+ routineId: null,
+ routineName: null,
+ },
+ ],
+ nextCursor: null,
+ });
+ expect(el.textContent).toContain("Running now");
+ expect(el.textContent).toContain("1 in progress");
+ expect(el.textContent).toContain("Long haul");
+ expect(el.textContent).toContain("in flight");
+ });
+
+ test("the elapsed label ticks forward while a run is live, not frozen at first render", async () => {
+ const startedAt = new Date(Date.now() - 2_000).toISOString();
+ const el = render("/insights", {
+ data: [
+ {
+ id: "run_ticking",
+ tenantId: "tnt_bench_a",
+ definitionId: "wfd_a",
+ definitionName: "Weekly digest",
+ address: "addr",
+ status: "running",
+ createdAt: startedAt,
+ updatedAt: startedAt,
+ routineId: null,
+ routineName: null,
+ },
+ ],
+ nextCursor: null,
+ });
+ const before = el.textContent;
+ await act(async () => {
+ await new Promise((resolve) => setTimeout(resolve, 1_200));
+ });
+ expect(el.textContent).not.toBe(before);
+ });
});
diff --git a/apps/web/test/insights-page.test.tsx b/apps/web/test/insights-page.test.tsx
index fd8200b4b..6edbe1f06 100644
--- a/apps/web/test/insights-page.test.tsx
+++ b/apps/web/test/insights-page.test.tsx
@@ -278,6 +278,51 @@ describe("InsightsPage scope switcher", () => {
});
});
+function renderAtPathWithRuns(path: string, nextCursor: string | null): string {
+ return renderToStaticMarkup(
+
+ undefined}>
+
+ null}
+ scopeLabel="All workbenches"
+ />
+
+
+ ,
+ );
+}
+
+describe("InsightsPage landing run-cap disclosure", () => {
+ // The feed is fetched at a fixed limit=100 (see insightsTopLevelRunsPath).
+ // A non-null nextCursor means the window truly holds more runs than were
+ // fetched, so the KPIs/sparkline/outcome chart built from that truncated
+ // set must say so rather than presenting it as the complete series —
+ // InsightsRunsHistory already discloses its own cap; the landing must too.
+ test("a non-null nextCursor discloses the 100-run cap on the landing view", () => {
+ const markup = renderAtPathWithRuns("/insights", "cursor_2");
+ expect(markup).toContain("100 most recent runs");
+ });
+
+ test("a null nextCursor (fewer than 100 runs) shows no cap disclosure", () => {
+ const markup = renderAtPathWithRuns("/insights", null);
+ expect(markup).not.toContain("100 most recent runs");
+ });
+});
+
describe("InsightsPage breadcrumbs", () => {
test("runs history puts an Insights / Run history trail in the top bar", () => {
const markup = renderAtPath("/insights/runs");
From 797522e70857461984246762829f642b64ed5536 Mon Sep 17 00:00:00 2001
From: Sawyer Cutler
Date: Fri, 21 Aug 2026 15:45:58 -0700
Subject: [PATCH 2/2] Insights: decouple running-now from the time window, tick
the elapsed label, disclose the run-fetch cap
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Three fixes to the landing dashboard:
- "Running now" (both the KPI tile and the strip) now reads off every
fetched run rather than the range-filtered subset, since being in
flight is not a windowed property — a run that started before the
7-day window and is still running no longer disappears or reads 0.
- The elapsed label beside the pulsing live status dot now ticks once a
second while a run is running, instead of freezing at whatever instant
the strip last rendered for an unrelated reason.
- The landing now discloses when the feed's fixed limit=100 fetch caps
the runs backing its KPIs, sparkline, and outcome chart, matching the
disclosure InsightsRunsHistory already gives on its own view.
---
apps/web/src/pages/insights-page.tsx | 64 +++++++++++++++++++++++++---
1 file changed, 57 insertions(+), 7 deletions(-)
diff --git a/apps/web/src/pages/insights-page.tsx b/apps/web/src/pages/insights-page.tsx
index b04e84be1..93a9485ae 100644
--- a/apps/web/src/pages/insights-page.tsx
+++ b/apps/web/src/pages/insights-page.tsx
@@ -442,6 +442,29 @@ export function elapsedLabel(createdAt: string, now: number): string {
return durationLabel(Math.max(0, now - startMs));
}
+const ELAPSED_TICK_MS = 1_000;
+
+/** Ticks once a second while `enabled` — the clock the elapsed label next to
+ * the pulsing `StatusDot` reads from, so it counts up like the live indicator
+ * beside it instead of freezing at whatever instant this component mounted
+ * or last re-rendered for an unrelated reason. */
+function useTickingNow(enabled: boolean): number {
+ const [now, setNow] = useState(() => Date.now());
+ useEffect(() => {
+ if (!enabled) return undefined;
+ const timer = setInterval(() => setNow(Date.now()), ELAPSED_TICK_MS);
+ return () => clearInterval(timer);
+ }, [enabled]);
+ return now;
+}
+
+/** A run actually in flight right now (`status: running | updating`) —
+ * liveness is not a windowed property, so this filters the full run set,
+ * never the range-filtered one. */
+function isRunningNow(run: InsightsRun): boolean {
+ return run.status === "running" || run.status === "updating";
+}
+
/**
* "Running now" — a horizontally scrolling strip of the runs actually in
* flight this instant (`status: running | updating`), not a fabricated
@@ -457,11 +480,9 @@ function RunningNowStrip({
readonly runs: readonly InsightsRun[];
readonly onOpenRun: (id: string) => void;
}) {
- const running = runs.filter(
- (r) => r.status === "running" || r.status === "updating",
- );
+ const running = runs.filter(isRunningNow);
+ const now = useTickingNow(running.length > 0);
if (running.length === 0) return null;
- const now = Date.now();
return (
@@ -619,6 +640,7 @@ function InsightsLanding({
byModel,
byTool,
runs,
+ runsNextCursor,
routines,
workbenches,
latency,
@@ -633,6 +655,12 @@ function InsightsLanding({
readonly byModel: readonly ModelUsage[] | null;
readonly byTool: readonly ToolCall[] | null;
readonly runs: readonly InsightsRun[];
+ /** The feed's own `nextCursor` (`limit=100` fetch, see
+ * `insightsTopLevelRunsPath`) — non-null means more runs exist in this
+ * window than the 100 fetched, so the KPIs/sparkline/outcome chart below
+ * disclose the cap instead of silently presenting a truncated series as
+ * complete. */
+ readonly runsNextCursor: string | null;
readonly routines: readonly Routine[];
/** Null while `/workbenches` hasn't resolved (or this landing is already
* scoped to one workbench, where a breakdown of one has nothing to
@@ -653,6 +681,12 @@ function InsightsLanding({
const stats = computeInsightsStats(windowedRuns, routines);
const purposeRuns = purposeRunsForInsights(windowedRuns);
+ // Liveness is not a windowed property: a run that started before
+ // `range.from` and is still going is running right now regardless of when
+ // it started, so "Running now" reads off every fetched run, never the
+ // range-filtered subset above.
+ const runningNow = purposeRunsForInsights(runs).filter(isRunningNow);
+
// Absent usage → zeros at the client boundary (never demo peaks / em-dash
// for "no spend"). Real fetched summary is preserved when present.
const usage = summary ?? EMPTY_OVERALL_USAGE;
@@ -726,17 +760,17 @@ function InsightsLanding({
loading={loading}
/>
) : null}
- {stats.running > 0 || loading ? (
+ {runningNow.length > 0 || loading ? (
) : null}
-
+
{latency !== null && latency.total.samples > 0 ? (
@@ -780,6 +814,21 @@ function InsightsLanding({
) : null}
+ {runsNextCursor !== null ? (
+
+ Runs, sparkline, and outcomes below reflect the 100 most recent runs —
+ more exist in this window.{" "}
+
+ .
+