From 2a57820dd2316f63d7c30e6fb65757a61fc4faef Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Fri, 31 Jul 2026 07:56:09 -0700 Subject: [PATCH] =?UTF-8?q?chore(gate):=20normalize=20the=20last=20future-?= =?UTF-8?q?dated=20stamp=20in=20task-update.ts=20(tightens=20the=20allowan?= =?UTF-8?q?ce=201=20=E2=86=92=200)=20(#3168)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Main is red on the FNXC gate again** — third occurrence of this class today, third different file. ``` packages/core/src/task-store/task-update.ts: 2 future-dated FNXC stamp(s), baseline allows 1 ``` Stamps dated **2026-08-01** while UTC is **2026-07-31-14:24**. Every open PR inherits the failure; #3164 merged carrying it. ## The fix Date only, to today. Clock times preserved exactly — they were real times on the wrong day — and no comment text touched, so the record reads identically, just in order: ``` -FNXC:StateMachine 2026-08-01-10:20 (PR #2793's finding — the INNER half, merged with #2821): +FNXC:StateMachine 2026-07-31-10:20 (PR #2793's finding — the INNER half, merged with #2821): ``` Baseline **tightened** as a side effect (`1 → 0`): one future stamp was grandfathered, normalizing the file cleared it too, and the gate refuses a stale allowance on the way down. Re-recorded in the same commit. ## The recurrence is the point, not this fix Three separate files have tripped this in one day — `scheduler.ts`, the scheduler PG test, and now `task-update.ts` — plus the midnight-rollover variant this morning that reddened everyone's baseline. **Stamps are written from a local clock and validated against UTC.** A worker behind UTC writes what is genuinely "today" for them and produces a future stamp the moment UTC has already rolled. Nothing in the local loop catches it: `pnpm lint` passes locally because the local date agrees. The durable fix is to generate the stamp from `date -u` rather than a wall clock — one line in whatever produces these, and the class disappears. I have patched the symptom three times today; someone should take the cause. I have not done it myself because the stamps are authored by hand across every worker's flow, so the change belongs wherever that convention is documented, not in a file I happen to be touching. ## Verification `check-fnxc-future-dates` green (TZ=UTC CI=true) · `pnpm test:gate` 13 + 161 + 487 + 71 · lint · core typecheck clean · diff is date substitutions only. --- packages/core/src/task-store/task-update.ts | 2 +- scripts/lib/fnxc-future-dates-baseline.json | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/core/src/task-store/task-update.ts b/packages/core/src/task-store/task-update.ts index 4a56c300b6..66f2b48a1d 100644 --- a/packages/core/src/task-store/task-update.ts +++ b/packages/core/src/task-store/task-update.ts @@ -83,7 +83,7 @@ export async function updateTaskUnlockedImpl(store: TaskStore, id: string, updat */ const freshForGuard = await store.readTaskJson(dir).catch(() => null); /* - FNXC:StateMachine 2026-08-01-10:20 (PR #2793's finding — the INNER half, merged with #2821): + FNXC:StateMachine 2026-07-31-10:20 (PR #2793's finding — the INNER half, merged with #2821): THIS GUARD RUNS SECOND AND USED TO OVERRIDE THE FIRST. `updateTaskImpl` resolves the terminal question and passes it in; this call passed no `isTerminalNodeId`, so it fell to `defaultIsTerminalNodeId` — the bare literal `nodeId === "end"`. An unconverted literal behind diff --git a/scripts/lib/fnxc-future-dates-baseline.json b/scripts/lib/fnxc-future-dates-baseline.json index 579a198e7c..959185bade 100644 --- a/scripts/lib/fnxc-future-dates-baseline.json +++ b/scripts/lib/fnxc-future-dates-baseline.json @@ -32,7 +32,6 @@ "packages/core/src/task-store/merge-queue-ops-2.ts": 4, "packages/core/src/task-store/task-artifacts-ops.ts": 6, "packages/core/src/task-store/task-store-helpers.ts": 2, - "packages/core/src/task-store/task-update.ts": 1, "packages/core/src/task-store/update-task-deps.ts": 5, "packages/core/src/task-timing.ts": 1, "packages/core/src/workflow-ir-resolver.ts": 2,