From 6b0b6d10ad8645339978024b79c5e0a59e890647 Mon Sep 17 00:00:00 2001 From: Codeman maintainer Date: Sun, 23 Aug 2026 19:54:15 +0200 Subject: [PATCH] fix(test): anchor the workflow-run fixture to now instead of a pinned epoch test/workflow-run-watcher.test.ts pinned its fixture's newest activity at 2026-06-14T20:06:40Z and then asked getRecentRunSummaries(100000) to return it. That argument is MINUTES, so the window is 69.4 days: the assertion expired at 2026-08-23T06:46:40Z and the file has failed on every branch since, on a suite nobody had touched. The last green CI run finished at 06:47:43Z, about a minute inside the boundary, which is why it landed as a surprise rather than a bisectable regression. The fixture epochs now hang off a RUN_ANCHOR of Date.now() - 601s with every offset preserved verbatim, so the parsed durations, the ordering and the live-vs-done discriminators are all unchanged, and the recency filter is still the thing under test. It just cannot rot again. --- test/workflow-run-watcher.test.ts | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/test/workflow-run-watcher.test.ts b/test/workflow-run-watcher.test.ts index 73fa042b..04acc3f7 100644 --- a/test/workflow-run-watcher.test.ts +++ b/test/workflow-run-watcher.test.ts @@ -17,11 +17,22 @@ const PROJECT_HASH = '-home-arkon-default-claudeman'; const SESSION_UUID = '388113c8-cd01-4e80-93a8-3be66ab1519b'; const RUN_ID = 'wf_test1234-abc'; +/** + * The fixture's epochs are anchored to "now", never pinned, because the recency + * assertions below compare them against `Date.now()`. A frozen epoch plus a fixed + * window is a time bomb: the original fixture's newest activity sat at + * 2026-06-14T20:06:40Z, and `getRecentRunSummaries(100000)` — that argument is + * MINUTES, i.e. 69.4 days — stopped matching it on 2026-08-23T06:46:40Z, turning + * CI red on a suite nobody had touched. Offsets from the anchor are preserved + * verbatim, so every parsed duration and ordering assertion is unchanged. + */ +const RUN_ANCHOR = Date.now() - 601_000; + /** A run JSON shaped like a real (killed) run: all three agent states + the bloat fields. */ function sampleRunJson() { return { runId: RUN_ID, - timestamp: '2026-06-15T00:00:00.000Z', + timestamp: new Date(RUN_ANCHOR).toISOString(), taskId: 'task_abc', // --- bloat fields that MUST be stripped --- script: 'export const meta = {};\n'.repeat(5000), // ~110KB @@ -35,7 +46,7 @@ function sampleRunJson() { workflowName: 'review-open-prs', status: 'killed', error: 'user stopped the task', - startTime: 1781466999000, + startTime: RUN_ANCHOR, defaultModel: 'claude-opus-4-8[1m]', totalTokens: 109703, totalToolCalls: 44, @@ -55,13 +66,13 @@ function sampleRunJson() { agentId: 'a6c0e282c3f5ac0bf', model: 'claude-opus-4-8[1m]', state: 'done', - startedAt: 1781467000002, - queuedAt: 1781466999962, + startedAt: RUN_ANCHOR + 1002, + queuedAt: RUN_ANCHOR + 962, attempt: 1, lastToolName: 'StructuredOutput', lastToolSummary: 'Does the profile setting make the allowlist dead config', promptPreview: 'You are reviewing a pull request...', - lastProgressAt: 1781467524143, + lastProgressAt: RUN_ANCHOR + 525_143, tokens: 104703, toolCalls: 41, durationMs: 524140, @@ -76,12 +87,12 @@ function sampleRunJson() { agentId: 'a1234567890abcdef', model: 'claude-opus-4-8[1m]', state: 'progress', - startedAt: 1781467010000, - queuedAt: 1781466999970, + startedAt: RUN_ANCHOR + 11_000, + queuedAt: RUN_ANCHOR + 970, attempt: 1, lastToolName: 'Read', promptPreview: 'Review PR 127...', - lastProgressAt: 1781467600000, + lastProgressAt: RUN_ANCHOR + 601_000, tokens: 5000, toolCalls: 3, }, @@ -93,9 +104,9 @@ function sampleRunJson() { phaseTitle: 'Verify', model: 'claude-opus-4-8[1m]', state: 'start', - queuedAt: 1781466999980, + queuedAt: RUN_ANCHOR + 980, promptPreview: 'Verify finding x...', - lastProgressAt: 1781466999980, + lastProgressAt: RUN_ANCHOR + 980, }, ], };