**`main` is currently red on the FNXC gate.** ``` $ node scripts/check-fnxc-future-dates.mjs # on origin/main scripts/reconcile-task-state-consistency.mjs: 2 future-dated FNXC stamp(s), baseline allows 0 scripts/lib/backend-db.mjs: 1 scripts/__tests__/reconcile-task-state-consistency.test.mjs: 1 exit 1 ``` #2994 carried four `2026-07-30-26:10` stamps. I flagged them on that PR before it merged; #2995 (the hour check) landed first, so the merge order turned the warning into a red gate rather than a red PR. Clamped to `23:10` — same rule as the nine before it: hour to `23`, minutes preserved, so ordering within each file survives. This is a normalization with a stated rule, not a claim about the true minute. **Verified:** FNXC gate exit 0, `reconcile-task-state-consistency` 8 pass / 0 fail. Comment-text only. ### Worth fixing at the source Thirteen impossible-hour stamps across six PRs in two days, and the hours climb — `24:40` → `25:30` → `26:10`. They are being written as a continuing sequence past midnight rather than read off a clock, which is a reasonable instinct and produces an invalid stamp every time. The trap is that the honest spelling does not work either: a genuine post-midnight stamp needs *tomorrow's* date, and the gate compares against the **local** calendar — so `2026-07-31-00:40` written from UTC-7 is future-dated and fails for a different reason. Clamping to `23:xx` is currently the only spelling that satisfies both, which is not obvious and is why this keeps recurring. If it recurs again, the fix is probably in the error message rather than more normalization PRs: the gate could name the valid range and the timezone it compares against, so the next author sees the constraint at the moment they hit it. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -106,7 +106,7 @@ test("apply reconciles done task and emits exactly one note", async () => {
|
||||
});
|
||||
|
||||
/*
|
||||
FNXC:OperatorScriptLaneAssumptions 2026-07-30-26:10:
|
||||
FNXC:OperatorScriptLaneAssumptions 2026-07-30-23:10:
|
||||
THE INVARIANT: both consistency checks ask the task's OWN lanes, and they failed in OPPOSITE directions.
|
||||
|
||||
Keyed on the literals, `hasDoneTransient` (`column === "done"`) NEVER fires on a renamed board, so a
|
||||
|
||||
@@ -38,7 +38,7 @@ function ensureMigrationsStaged() {
|
||||
}
|
||||
}
|
||||
|
||||
/* FNXC:OperatorScriptLaneAssumptions 2026-07-30-26:10: exported so operator scripts can reach core
|
||||
/* FNXC:OperatorScriptLaneAssumptions 2026-07-30-23:10: exported so operator scripts can reach core
|
||||
helpers (lane resolution) through the SAME staged-dist seam `openBackend` already uses, rather than
|
||||
each growing its own dist path — `@fusion/core` is not resolvable from the repo-root `scripts/`. */
|
||||
export async function importCore() {
|
||||
|
||||
@@ -5,7 +5,7 @@ import { openBackend, importCore } from "./lib/backend-db.mjs";
|
||||
const DEFAULT_NOTE = "FN-4000 reconciliation: cleared stale transient failure state using TaskStore done-normalization so database and task JSON remain synchronized.";
|
||||
|
||||
/*
|
||||
FNXC:OperatorScriptLaneAssumptions 2026-07-30-26:10:
|
||||
FNXC:OperatorScriptLaneAssumptions 2026-07-30-23:10:
|
||||
Both checks ask this task's OWN lanes, because keyed on the literals they fail in BOTH directions.
|
||||
|
||||
`hasDoneTransient` gated on `column === "done"`. On a board whose complete lane is named anything
|
||||
@@ -48,7 +48,7 @@ export function findTaskStateInconsistencies(task, lanes = {}) {
|
||||
}
|
||||
|
||||
/*
|
||||
FNXC:OperatorScriptLaneAssumptions 2026-07-30-26:10:
|
||||
FNXC:OperatorScriptLaneAssumptions 2026-07-30-23:10:
|
||||
`resolveLanes` is INJECTED, not built here, and `main` below supplies the real one.
|
||||
|
||||
Resolving inside this function would drag `importCore()` — and therefore a built `packages/core/dist`
|
||||
|
||||
Reference in New Issue
Block a user