fix(ingest): retire a day-precision row on the clock the app reads it on
Three parsers decide currency against ctx.now, because their page has no "ongoing" heading worth trusting: bawiki.ts, and the Fate/Grand Order and Infinity Nikki branches of fandom.ts. All three compared Date.parse(endsAt) to now, and all three publish day-precision ends — so the comparison was against the 00:00Z placeholder, which § Domain rules says is not an instant and nothing may read literally. clockFor already knows that and resolves such a boundary to the reset opening that game-day on the reader's server. The parsers did not, so the feed retired a row up to nine hours before the app, the countdown and the game all agreed it was over. On the pinned Infinity Nikki fixture, "Inspiration Burst" left the feed at 2026-08-22T01:00Z while clockFor still called it live for an American reader until 09:00Z, and the page said it ran to 03:59 server time. The reader does not see a stale row; they see the deadline they were counting down to disappear on its last day, which is the silent drop this codebase treats as the dangerous failure. latestBoundaryMs answers clockFor's question for the last region rather than one reader's, so a row is history only once it is history everywhere. It follows a game's own server map and reset hour for the same reason clockFor does — Endfield and Reverse: 1999 both move. Nothing stored changes: this is one comparison, not a resolved boundary written into the feed, and no expected.json moves. Being generous by nine hours costs an expired row at the bottom of a list. Being strict costs a live one. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
0f9c141ea5
commit
c782a265ca
+14
-3
@@ -152,9 +152,20 @@ All live in `src/ingest/dates.ts`, each returning null rather than inferring any
|
||||
above returns `precision: "day"` when the source printed no clock, and stores the date at UTC
|
||||
midnight because it has to store *something*. It is not a statement that the event begins or ends
|
||||
then, and nothing may count down to it literally: `clockFor` resolves a day-precision boundary to
|
||||
that game-day's server reset for the reader's region (`docs/DATA-MODEL.md` § Field notes). The
|
||||
parsers are unaffected by this and must stay so — resolving here would need a region the parser does
|
||||
not have, and would bake one reader's server into the stored feed.
|
||||
that game-day's server reset for the reader's region (`docs/DATA-MODEL.md` § Field notes).
|
||||
|
||||
**No parser may store a resolved boundary, and three of them must read one to decide inclusion.**
|
||||
The stored value stays the printed day at 00:00Z: resolving it here would need a region the parser
|
||||
does not have, and would bake one reader's server into the feed everybody downloads. But a parser
|
||||
whose page carries no "ongoing" heading it can trust decides currency against `ctx.now` itself —
|
||||
`bawiki.ts`, and the Fate/Grand Order and Infinity Nikki branches of `fandom.ts` — and comparing the
|
||||
placeholder to `now` retires a row at UTC midnight, hours before `clockFor` calls it over for
|
||||
anybody. The reader does not see a stale row; they watch the deadline they were counting down to
|
||||
disappear on its last day, which is the silent drop AGENTS.md § Working on parsers calls the
|
||||
dangerous failure. So those three ask `latestBoundaryMs` (`src/shared/time.ts`) when the boundary is
|
||||
day-precision: the last region's reset, and therefore the instant the row is history for every
|
||||
reader rather than for the earliest of them. Being generous by nine hours costs one expired row at
|
||||
the bottom of a list; being strict costs a live one.
|
||||
|
||||
`parseOpenRange` is tried last because it is the most permissive — it accepts any leading full date
|
||||
and reports no end.
|
||||
|
||||
Reference in New Issue
Block a user