From 195fd75ba402026e15de7a87391e7d2c23ce56d6 Mon Sep 17 00:00:00 2001 From: Lucas Winther Date: Wed, 19 Aug 2026 04:11:18 +0200 Subject: [PATCH] docs: a live Infinity Nikki source exists, and it states no timezone MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The lane's Game8 page is a year stale, and the last pass concluded there was nowhere to move it. That was wrong: infinity-nikki.fandom.com is maintained, permitted by the same standard Fandom robots.txt as Nikke, and its Event page carries Current and Upcoming tables with full dates and clocks on both sides. What it does not carry is a timezone on the Duration column. The page says UTC-7 in prose about version launches and notes a 04:00 Server Time reset, and the durations run 04:00 to 03:59, which only lands on a reset boundary if the column is server-local. Strong, and circumstantial. It matters because the offset moves the day, and the start's day is half an event ID. Four options are written out with what each costs. The recommendation is to take the printed date at day precision, which invents nothing and treats these cells exactly as every Game8 date is already treated — and which contradicts the Blue Archive rule as written, so that rule needs narrowing to say which case it governs. Flagged rather than resolved: it changes an existing lane, and retiring the game instead would drop a GameId that prefixes every completion key its readers hold. Co-Authored-By: Claude Opus 5 (1M context) --- docs/FEEDBACK.md | 4 +- docs/SOURCES.md | 170 +++++++++++++++++++++-------------------------- 2 files changed, 78 insertions(+), 96 deletions(-) diff --git a/docs/FEEDBACK.md b/docs/FEEDBACK.md index eac0a95..2db276d 100644 --- a/docs/FEEDBACK.md +++ b/docs/FEEDBACK.md @@ -305,9 +305,9 @@ diagnosis in each item still holds — what changed is whether it has been acted | P1b cap the long list | **Done** (2026-08-18). Both sections cap at six with "show all N" — truncation of the view, not a re-sort | | P1b persist `view` | **Done** (2026-08-18). `prefs.view`, and the first run now asks which one to open on (PRD F8) | | P1b Calendar → Timeline | **Done.** The tab reads "Timeline" | -| P1c more games | **Done, nine of them.** Infinity Nikki, Persona 5: The Phantom X, Reverse: 1999, Blue Archive, then Fate/Grand Order and hololive Dreams, then Girls' Frontline 2, Stella Sora, Chaos Zero Nightmare and Umamusume (2026-08-19). Of the games named in this thread, **Umamusume is now built** — via Game8, not the declined `uma.moe` — and Azur Lane and Aether Gazer stay declined. **Nikke is blocked, not declined**: its data is the best of anything unbuilt and its wiki's `robots.txt` can no longer be read from any client here, so the permission cannot be established. See `docs/SOURCES.md` § 3 | +| P1c more games | **Done, ten of them.** Infinity Nikki, Persona 5: The Phantom X, Reverse: 1999, Blue Archive, then Fate/Grand Order and hololive Dreams, then Girls' Frontline 2, Stella Sora, Chaos Zero Nightmare, Umamusume and Nikke (2026-08-19). Of the games named in this thread, **Umamusume is now built** — via Game8, not the declined `uma.moe` — and Azur Lane and Aether Gazer stay declined. **Nikke is built too** (2026-08-19), once its `robots.txt` was read in a browser and turned out to be the standard Fandom file. See `docs/SOURCES.md` § 3 | | P1c roadmap in the colophon | **Not done** | -| P1 games still unserved | Nikke (blocked on a readable `robots.txt`), Azur Lane, Punishing: Gray Raven, Guardian Tales, Aether Gazer (shutting down), Silver Palace (unreleased). Separately, **Infinity Nikki's source is stale** and has no reachable replacement — `docs/SOURCES.md` § 11 | +| P1 games still unserved | Azur Lane, Punishing: Gray Raven, Guardian Tales, Aether Gazer (shutting down), Silver Palace (unreleased). Separately, **Infinity Nikki's source is stale** and has no reachable replacement — `docs/SOURCES.md` § 11 | | P2 colour and screenshot | **Layout done** (2026-08-18), colour untouched. The palette was left alone deliberately — the two-axis system was not what made the screenshot read as unfinished, a dense single column on a wide screen was. Past `lg` the page is now a pinned deadline rail beside the lists, the timeline is a board with its axis and names pinned, and the footer and settings are columns. The screenshot still wants reshooting | | P2 custom events | **Done.** PRD F13 first, then the code; `mygame:` / `myevent:` key spaces, in the export | diff --git a/docs/SOURCES.md b/docs/SOURCES.md index f41ebda..e7eddcd 100644 --- a/docs/SOURCES.md +++ b/docs/SOURCES.md @@ -8,9 +8,9 @@ re-deriving it. What changed on 2026-08-19, in one paragraph. **Built:** Girls' Frontline 2 (`iopwiki`, new parser), Stella Sora (`stellasorawiki`, new parser), Chaos Zero Nightmare (`game8`, no parser work) and -Umamusume (`game8`, after widening its section and column vocabulary). **Blocked:** Nikke — its -`robots.txt` cannot be read from here at all any more, so the permission this file required before -building could not be obtained. **Declined:** Punishing: Gray Raven, Guardian Tales, Azur Lane and +Umamusume (`game8`, after widening its section and column vocabulary). **Built on 2026-08-19 after the +permission was read in a browser:** Nikke, whose `robots.txt` turned out to be the standard Fandom +file. **Declined:** Punishing: Gray Raven, Guardian Tales, Azur Lane and Aether Gazer, all as proposed. One thing not on the original list also came out of the pass: the **Infinity Nikki source is stale** and has no reachable replacement — see § 11. @@ -48,7 +48,7 @@ Two things this method cannot tell you, and both matter: |---|---| | Arknights, Reverse: 1999, Blue Archive, Persona 5X | **Built** (2026-08-17/18) | | **Girls' Frontline 2, Stella Sora, Chaos Zero Nightmare, Umamusume** | **Built** (2026-08-19) | -| Nikke | **Blocked.** Best unbuilt data here; `robots.txt` unreadable, so the permission cannot be established — see § 3 | +| Nikke | **Built** (2026-08-19), once the `robots.txt` was read in a browser — see § 3 | | Azur Lane | Declined on conduct (`azurlane.koumakan.jp` `ai-input=no`), and both Fandom alternatives are dead archives | | Punishing: Gray Raven, Guardian Tales, Aether Gazer | Declined — see §§ 6, 7, 9 | | Silver Palace | Unreleased | @@ -59,7 +59,7 @@ Two things this method cannot tell you, and both matter: |---|---|---|---|---| | Girls' Frontline 2 | `iopwiki.com/wiki/GFL2_Events` | new (`iopwiki`) | likely (permissive robots, unproven) | **BUILT** 2026-08-19 — best data quality of anything here | | Stella Sora | `stellasora.miraheze.org/wiki/Main_Page` | new (`stellasorawiki`) | yes (Miraheze proven) | **BUILT** 2026-08-19 — banners only, from the main page | -| Nikke | `nikke-…-international.fandom.com/api.php?…page=Event` | new shape | **no** — Fandom robots fails closed | **BLOCKED** — the robots.txt precondition could not be met from any client here | +| Nikke | `nikke-…-international.fandom.com/api.php?…page=Event` | `fandom`, third template | **no** — Fandom robots fails closed | **BUILT** 2026-08-19 — story events *and* dated pickup banners, with an evidenced reset clock | | Chaos Zero Nightmare | `game8.co/games/Chaos-Zero-Nightmare/archives/559899` | **existing** `game8` | **no** — game8 202s the runner | **BUILT** 2026-08-19 — no parser work, fixture-only lane | | Umamusume | `game8.co/games/Umamusume-Pretty-Derby/archives/536311` | `game8` + section and column vocabulary | **no** | **BUILT** 2026-08-19 — cost more than "two header words"; see § 5 | | Punishing: Gray Raven | `grayravens.com/wiki/Events` | — | — | **Decline for now** — one dated string on the whole page | @@ -165,74 +165,27 @@ source immediately — full coverage, no template dependency. --- -## 3. Nikke — blocked on a permission that can no longer be read +## 3. Nikke — BUILT 2026-08-19 -> **Outcome (2026-08-19): not built, and not declined either.** The precondition this section set — -> "read this wiki's `robots.txt` in a browser and confirm it is the same file" — could not be met. -> From this machine that file answers **403** to our fetcher, and a real headless browser gets a -> Cloudflare managed challenge that never resolves. Worse, the same is now true of *every* Fandom -> wiki tried, including `blhx.fandom.com`, which served it `200` on 2026-08-18 and is what this -> section's permission argument was leaning on. Nothing about the data changed — it is still the -> richest schedule of anything unbuilt — but the permission has to be in writing before the adapter -> exists, and it cannot currently be obtained. **Unblocking it is one action by someone on an -> address Fandom serves:** open that URL, confirm the standard file (allows `/api.php?action=`, -> disallows only `Special:`/`User:`/`Template:`/`Help:`), and paste it into this file. Everything -> below then applies unchanged, including the free `resetOffsets` win. - - - -**Source:** `https://nikke-goddess-of-victory-international.fandom.com/api.php?action=parse&page=Event&prop=text&formatversion=2&format=json` - -**Conduct, and one thing to check before building.** The API answered our real `User-Agent` with a -`200`. `robots.txt` on that subdomain answered **403** (Cloudflare) from this address — so the robots -gate fails closed and the runner will report `skipped_robots`, exactly as it does for Reverse: 1999. -The standard Fandom `robots.txt`, which `blhx.fandom.com` served us fine at `200`, explicitly allows -`/api.php?action=` for `*` and disallows only `Special:`, `User:`, `Template:` and `Help:`. Before -building, **read this wiki's `robots.txt` in a browser and confirm it is the same file** — that is the -precedent `AGENTS.md` § Fandom sets, and the permission has to be in writing before the adapter -exists, not inferred from a sibling wiki. - -**Shape.** `Story Events` is a per-year tabbed set of tables: - -``` -Event | Start (UTC+9) | End (UTC+9) | Archived (?) -``` - -Dates are machine-readable — `` — with the end -carrying a clock (`04:59:59`) and the start carrying none. A second table, `Pick Up Recruitments`, -gives banners with a clock on **both** ends (`05:00:00` → `04:59:59`). - -**It is current.** The live event, `Persona on Frontline`, is listed: 12 August → 10 September 2026 -04:59:59 (UTC+9). - -**Hazards, and the nastiest one is real.** - -- **Event titles are images, not text.** Each `Event` cell is a logo. Normally the name is recoverable - from the wrapping ``. But the newest row — the live event — has **no - uploaded logo**, so the cell is a red link rendering as the literal text - `File:Persona on Frontline logo.png`. A parser that reads only `` silently drops today's - event and publishes a calendar whose most important row is missing. Read the title from the file - name as a fallback, strip the `File:` prefix and the ` logo.png` suffix, and put a test on exactly - this row. -- **Five tables of identical shape**, one per year tab (2026 … 2022), plus `Recurring Events`, - `Mission Passes`, `Costume Gacha`, `Web Event` and `Popularity Poll`. Fence by heading and by year - tab; do not take every `wikitable`. -- **`fandom.ts` will not read this page.** `canParse` returns `false` — that module is shaped around - the Reverse: 1999 and FGO `Event_List_(US)` templates. This is a new shape: either a third branch - in `fandom.ts` or a new module. - -**A free win while you are there.** Every story event ends at `04:59:59 (UTC+9)` and every pickup -banner starts at `05:00:00 (UTC+9)` — an event ending one second before the reset the next one begins -on. That is the Reverse: 1999 evidence pattern, and it means Nikke wants -`resetOffsets: { asia: 9, america: 9, europe: 9 }` and `resetHourLocal: 5` in `games.ts`, set **in the -same commit that ships the game**, before any reader has a day key that a later correction would -re-label. - -**One naming trap.** The `GameId` for this is `nikke`, and `nikki` (Infinity Nikki) already exists. -One letter apart, both are the first segment of every completion key that game will ever have. Worth -a moment's care in `games.ts`, `schema.ts` and the fixture directory name. - ---- +> **Outcome: built.** The precondition this section set — read the wiki's `robots.txt` in a browser — +> was met on 2026-08-19, and it is the standard Fandom file: no `Disallow: /` for `*`, +> `/api.php?action=` explicitly allowed, and only `Special:`, `User:`, `User_talk:`, `Template:`, +> `Template_talk:`, `Help:` and `UserProfile:` refused. The AI crawlers it names (`GPTBot`, `CCBot`, +> `OAI-SearchBot`, `ImagesiftBot`) are not us. Recorded in `AGENTS.md` § Fandom. +> +> Three notes for whoever touches it next, all of them corrections or additions to what follows: +> +> - **The 403 is on `robots.txt` only.** `api.php?action=parse` answers our own User-Agent with a +> `200` from a datacentre address; it is the robots file that is challenged. So the adapter could +> be written and fixture-backed from here, and what it cannot do is pass the gate at refresh time. +> - **The zone is in the column header, not the cell** — `Start(UTC+9)` / `End(UTC+9)`. That makes +> the header load-bearing: a table that stops naming its zone is refused rather than read as UTC. +> - **Story-event starts carry no clock, only their ends do.** The start keeps the day the page +> printed rather than being shifted nine hours into the previous one, which is the FGO rule applied +> to the opposite gap. Pickup banners carry a clock on both sides and convert fully. +> +> The `resetOffsets` / `resetHourLocal` win this section predicted was real and shipped with the +> game: UTC+9 for every region, rolling at 05:00. ## 4. Chaos Zero Nightmare — BUILT 2026-08-19; the cheapest adapter available, and a ninth blind source @@ -415,31 +368,63 @@ projections point at late 2026 / early 2027. Nothing to scrape, as `docs/FEEDBAC --- -## 11. Infinity Nikki — not on the original list, and the most urgent thing found +## 11. Infinity Nikki — a live source exists, and one fact is missing from it This game already has an adapter, which is why it was not assessed on 2026-08-18. It should have been. `game8.co/games/Infinity-Nikki/archives/487445` fetches, parses, and passes every test — and the page itself says `Last updated on: August 31, 2025`, with **zero** occurrences of the string -`2026`. Seven events parse out of it, five of them with `endsAt: null`, which the app renders as +`2026`. Seven events parse out of it, five with `endsAt: null`, which the app renders as live-with-unknown-end indefinitely. A year-old event presented as current is precisely the failure this product exists to prevent, and it arrives through a source that looks perfectly healthy to the -runner: a stale page is not a broken one, so no failure streak, no annotation, no `broken` tier. +runner: a stale page is not a broken one. -Every replacement was checked on 2026-08-19 and none works: +**A live replacement was found on 2026-08-19, and it is nearly right.** +`infinitynikki.fandom.com` 301s to `infinity-nikki.fandom.com`, whose `robots.txt` was read in a +browser and is the standard Fandom file — same permission as Nikke (§ 3). The wiki is maintained: +pages edited as recently as 2026-08-17, and its `Event` page mentions 2026 seven hundred and +thirty-one times. The page is shaped exactly as we would want: -| Candidate | Result | +``` +Current Events / Upcoming Events / Permanent Events / Past Events (h2 headings) + Event | Duration | Description | Type + Deep Breakthrough July 20, 2026 04:00 – August 10, 2026 03:49 ... Double Rewards +``` + +Full dates with the year on both sides, a wall clock on both sides, a description, and the source's +own event type. Better material than the Game8 page has ever carried. + +**The missing fact is the timezone, and it is missing in an interesting way.** The Duration column +names no zone. What the page *does* say, elsewhere and in prose: + +- version launches are dated `(UTC-7)` — "Version 2.1 goes live on January 29 (UTC-7)"; +- `Rewards reset daily at 04:00 (Server Time)`; +- and the durations themselves run `04:00` → `03:59`, which only lands on a reset boundary if the + column is server-local. + +That is a strong circumstantial case for UTC-7 and it is still circumstantial. It matters more than +usual because the offset moves the *day*: `July 16, 2026 20:00` read as UTC-7 is +`2026-07-17T03:00Z`, and the start's day is half of every event ID this game will ever have. + +**Four options, and this is the repository owner's call:** + +| Option | What it costs | |---|---| -| `infinitynikki.wiki.gg` | 401 — no such wiki (as with Nikke, Umamusume, Blue Archive, R1999) | -| `infinitynikki.miraheze.org` | Exists, serves robots.txt, **abandoned** — front page last edited 11 Feb 2025, `/wiki/Events` returns a permission error | -| `prydwen.gg/infinity-nikki` | 404 — not a game prydwen covers | -| `game8.co/…/archives/487444` (Banners) | Staler still: last updated 20 May 2025 | -| `infinitynikki.fandom.com` | Behind the blanket Fandom 403 (§ 3) | +| **(a) Leave the Game8 lane** | A knowingly stale lane, carried only by the footer's freshness disclosure. The status quo, and the worst of these | +| **(b) Build the Fandom source at day precision**, taking the printed date and dropping the clock | Loses a stated clock; invents nothing. Treats the cells exactly as every Game8 date is already treated. **Recommended** | +| **(c) Build it at exact precision, assuming UTC-7** | Almost certainly correct, and an assumption we would be unable to falsify from the page. If wrong, every date is hours out and some days are wrong | +| **(d) Retire the game** | Drops a `GameId` that prefixes every completion key its readers hold, with no server-side recovery | -So there is nothing to move the lane to. **This is a call for the repository owner**, and both -options cost something: leaving it means a knowingly stale lane carried only by the footer's -freshness disclosure, and retiring it means dropping a `GameId` that is the first segment of every -completion key that game's readers hold, with no server-side recovery. Recorded in `AGENTS.md` -§ Scraping conduct so the next pass does not rediscover it. +**(b) has a precedent tension worth stating rather than glossing.** `AGENTS.md` § Blue Archive +rules that unzoned wall clocks are "deliberately unparsed", and that "rounding to a day does not save +it". That ruling was made about tables which additionally *did not say which server they described*. +Here the wiki is the Global one for a game with a single global service, and the printed date is +being taken at face value in exactly the way `game8` dates already are — Game8 states no zone either, +and the whole day-precision mechanism in `clockFor` exists to resolve such a boundary on the reader's +own server. If (b) is chosen, that rule needs amending to say which case it governs, because as +written the two conflict. + +Asking the wiki's editors to state the zone on the Duration column would settle it outright, and is +cheaper than any of the above. ## What every one of these costs, beyond the source @@ -457,15 +442,12 @@ Adding a game is never only a `SOURCES` entry: ## Recommended order -Steps 1, 2, 4 and 5 were done on 2026-08-19, and step 6's declines are now written into `AGENTS.md` +Steps 1 through 5 were done on 2026-08-19, and step 6's declines are now written into `AGENTS.md` § Scraping conduct. What is left is not a queue of sources any more — it is two decisions: -1. **Nikke** (§ 3) — the richest schedule of anything unbuilt, needing one action from someone on an - address Fandom serves: read that wiki's `robots.txt` and record it here. Everything else about - the adapter is specified above, including the evidenced `resetOffsets`/`resetHourLocal` pair that - must ship in the same commit as the game. -2. **Infinity Nikki** (§ 11) — decide whether a lane with no reachable source stays or is retired. - Not a research task; there is nothing left to find. +1. **Infinity Nikki** (§ 11) — choose between four options for a lane whose current source is a year + stale and whose live replacement states no timezone on its schedule column. Not a research task; + the research is done and the recommendation is option (b). Below that, in descending order of value: re-check `grayravens.com` if it ever puts its schedule in a table, and re-check Azur Lane if `koumakan` ever drops `ai-input=no`. Neither is worth a pass