diff --git a/AGENTS.md b/AGENTS.md index c7d362b954..aceb41974b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -387,7 +387,7 @@ Note: the embedded main-content views Workflows (`_WorkflowEditorView`), Import ## FNXC_LOG comments: - Please whenever you're working on a codebase. I want you to add comments describing the date of the change (must be in this format yyyy-MM-dd-hh:mm) and describing the requirements or the change in requirements that made you implement certain functionality. - - **Take the timestamp from `date -u`, not your local clock.** `check-fnxc-future-dates` validates against UTC, so a stamp written from a clock behind UTC is a FUTURE stamp the moment UTC rolls over — and `pnpm lint` passes locally, because the local date agrees with what you wrote. It surfaces only as a red `main` for everybody else. This cost the fleet four separate breakages in one day (`scheduler.ts`, a scheduler PG test, and `task-update.ts` twice, by different authors); every one was a real time on the wrong day. The gate also rejects an impossible clock time, so an hour above 23 or a minute above 59 fails for a different reason. + - **Write your own local date and a real clock time.** `check-fnxc-future-dates` accepts a stamp that is not ahead of BOTH the runner's local calendar and UTC, which is what makes it safe for a fleet whose machines sit in different zones. Do NOT reach for `date -u` to satisfy it: this instruction previously said to, back when the gate compared against UTC alone, and following it from a machine EAST of the runner writes tomorrow's date and reddens `main` for everybody else — five separate breakages in two hours on 2026-07-31, all invisible to their authors because `pnpm lint` passed locally. An earlier round of the same defect from the other direction (authors WEST of the runner, whose correct 5pm stamp read as "tomorrow" under a UTC comparison) cost four breakages in one day. Both directions are now accepted; a genuinely invented date — days out rather than hours — still fails. The gate also rejects an impossible clock time, so an hour above 23 or a minute above 59 fails for a different reason. - I want you to write FNXC:Area-of-product in front of all your comments so they can be grepped. - Most of this should be written as jsdocs but you can add short comments around for the important variables and more complex parts of the codebase. - The idea is to encode the requiements of the system (especially software behavior, UX, and important technical decisions) into the code so it's clearer later why a certain piece of code was written. diff --git a/scripts/check-fnxc-future-dates.mjs b/scripts/check-fnxc-future-dates.mjs index 815c1f8c90..be75f2a998 100644 --- a/scripts/check-fnxc-future-dates.mjs +++ b/scripts/check-fnxc-future-dates.mjs @@ -94,13 +94,33 @@ FNXC:FnxcStampHygiene 2026-07-31-03:40 (#2941 review): `toISOString()` is UTC, s Greenwich it rolls the date forward for part of each day — a stamp written correctly at 5pm in California read as "tomorrow" and failed the gate. Authors write the local date, so the comparison has to use the local one. + +FNXC:FnxcStampHygiene 2026-08-01-00:10 (five reds in two hours — LOCAL alone is not enough either): +The fleet writes stamps from MANY machines and this gate evaluates them on ONE. #2941 fixed the +author-west-of-the-runner case; the mirror case is an author EAST of it, and that is what broke main +five times in two hours. Measured: three direct-to-main commits landed at 16:12/16:32/16:40 PDT — +23:12/23:32/23:40 UTC on the 31st — carrying stamps of 2026-08-01-00:20/00:50/01:05. Those are +neither the runner's local date nor UTC; they are the AUTHOR's local date in a UTC+1 container. The +gate, running in PDT, called every one of them "tomorrow" and reddened main for every other lane. + +So "future" cannot mean "after the runner's calendar". It means after EVERY calendar a correct +author could plausibly be writing from, which is bounded below by the runner's local date and above +by UTC (or vice versa west of Greenwich). Comparing against the LATER of the two accepts both +honest cases and still catches a genuinely invented date — the 2026-08-06 stamp in scheduler.ts, +six days out, fails under this rule exactly as it did before. + +This preserves #2941's fix rather than reverting it: west of Greenwich the local date is the earlier +of the pair, so a 5pm-in-California stamp still passes. */ const now = new Date(); -const today = [ +const localToday = [ now.getFullYear(), String(now.getMonth() + 1).padStart(2, "0"), String(now.getDate()).padStart(2, "0"), ].join("-"); +const utcToday = now.toISOString().slice(0, 10); +/** The later of the two — a stamp is future only if it is ahead of both. */ +const today = localToday > utcToday ? localToday : utcToday; function scan() { const counts = {};