diff --git a/docs/LANES/LANE_B_NOTES.md b/docs/LANES/LANE_B_NOTES.md index 1dfad5d..bf0aca4 100644 --- a/docs/LANES/LANE_B_NOTES.md +++ b/docs/LANES/LANE_B_NOTES.md @@ -1,5 +1,41 @@ # LANE B — NOTES (measured) +## Round 21 (Fable's ROUND21 → Lane B) — selector from E's towns index (ledger #2, the missed R20 #5) + +Closed the R20 gap Fable caught (`hud.js:11` still hardcoded `REAL_TOWNS`). The real-town list now comes +from **E's `web/assets/towns/index.json`** (`procity-towns-index/1`), so it grows with the town pack instead +of being edited in `hud.js`. Verified fresh Chromium. Nothing else touched — the tram/ground work is done. + +### How it works (fail-soft by construction) +`createHUD` is synchronous, so the picker is **built immediately from the fallback literal** and then +**upgraded in place** when the index resolves. That ordering *is* the fail-soft: if the index never arrives, +the working list is already on screen. +- **Index present** → real names, states and shop counts: `Katoomba, NSW · 80 shops`, `Fremantle, WA · 80 + shops`, `Newtown, NSW · 72 shops`, `Bendigo, VIC · 36 shops`, `Castlemaine, VIC · 24 shops`. (`roads:false` + towns would read `· marched`; none today.) +- **`?noassets`** → the fetch is **skipped entirely** (asset law — the shell doesn't load town caches there + either, so reading the index would be pointless as well as illegal). Measured: **0 index fetches**, + fallback list, 0 errors. +- **Anything wrong with the index** → the fallback simply stands. Exercised the exact chain against every + nasty case; **none throws, none rebuilds from junk**: + +| index case | result | +|---|---| +| 404 / missing · network error · malformed JSON | fallback stands ✅ | +| `towns: []` · `towns` not an array · junk entries (no `key`) | fallback stands ✅ | +| good index | rebuilds from index ✅ | + +`REAL_TOWNS_FALLBACK` is retained **only** as that fallback (comment says so) — it is no longer the source +of truth. Verified live: booting `katoomba_real` shows `Katoomba, NSW · 80 shops` pre-selected; the picker +fits (193 px of its 230 px max); 0 page errors; navigation unchanged (`onchange` is set once on the +`