docs(04): create phase plan — 4 plans in 3 waves (search module, corpus/bake-off, /cari surface, webview hand-off + device gate)

This commit is contained in:
araharah-executor
2026-10-23 23:40:41 +08:00
parent aa34e7b50d
commit a575ecd139
6 changed files with 2845 additions and 3 deletions
+22 -3
View File
@@ -123,11 +123,30 @@ Notes:
3. Choosing a result sends a native venue card in chat confirming the destination before navigation opens (SRCH-03)
4. Tapping through from the search result launches the Mini App with the destination preloaded — no re-entry in the webview (ONBD-02); adding araharah to the phone home screen and launching from there lands in the app ready to search (ONBD-03)
5. The self-hosted Photon KL bake-off is concluded against the real-query acceptance corpus with the decision (and any gazetteer/fallback escalation) documented — the search-quality experiment closes, it doesn't stay open
**Plans**: TBD
**Plans**: 4 plans
Plans:
**Wave 1** *(the shared foundation — a fourth npm workspace, `search/`)*:
- [ ] 04-01-PLAN.md — `@araharah/search` workspace: the `SearchSource`/`GazetteerEntry` contract, the JUPEM-derived abbreviation table as editable DATA, the symmetric normalizer, the hand-rolled OSA distance, the disjoint-tier scorer, the curated KL gazetteer with locals' aliases, the lazy three-environment loader, plus the root GPL-3.0 `LICENSE` and the ODbL-1.0 data notice (D-04/05/06/07/08/09/15)
**Wave 2** *(parallel — the measurement instrument and the chat surface)*:
- [ ] 04-02-PLAN.md — the pinned golden corpus (D-13), the D-14 bake-off runner + the in-suite Nyquist gate, the Overpass top-up tool (D-06), the JSON→SQLite converter (D-05), and `docs/SEARCH-QUALITY.md` recording the measured result and the escalation lever (SRCH-01, SRCH-02)
- [ ] 04-03-PLAN.md — the `/cari` command (D-01), the single-message `sendVenue` card with 2-4 inline alternates (D-02/D-10), the honest out-of-area refusal, the OPEN deep link carrying a plain gazetteer id with NO crypto (D-11), `MINI_APP_URL` config, and the four `commands.test.mjs` landmines defused in the same change (SRCH-03, ONBD-02)
**Wave 3** *(the webview hand-off + the blocking device gate)*:
- [ ] 04-04-PLAN.md — the two-carrier destination reader (`?dest=` primary, `initData.start_param` secondary) with one shared validation, the memory-only resolver, the honest "destination unavailable" state, ONBD-03's minimal `addToHomeScreen`/`checkHomeScreenStatus` hooks behind a Bot API 8.0 guard, the build-artifact drift gate, the destination-preload capture, and the blocking Android/iOS/Desktop device gate (ONBD-02, ONBD-03)
**Cross-cutting constraints** *(must_haves.truths asserted by 2+ plans)*:
- The deep-link carrier correction (plain id via `?dest=` URL param read from `location.search`, `start_param` secondary, NO crypto) — plans 03, 04
- The D-14 corpus gate as an executable in-suite assertion (top-3 ≥ 90% on positives, negatives honestly refused) — plans 01 (admission rule), 02 (runner + suite)
- Category-only logging / no query text persisted (D-15) — plans 01 (no logging in the module), 03 (category-only literals), 04 (state-token capture signal)
Notes:
- Budgeted bake-off: research recommends `/gsd-research-phase` (gazetteer sourcing/structure ~200 entries, Malay normalizer, photon-vs-fallback decision; funds a GraphHopper MY dump on the VPS).
- VPS provisioning (Photon + Valhalla hosting) begins here — free-first infrastructure mandate (Oracle Cloud Always Free candidate).
- **D-03 supersedes the roadmap's "VPS provisioning begins here" note** — the search backend is the in-Worker curated gazetteer ($0 infrastructure); Photon-on-VPS is deferred to Phase 5 (Valhalla needs the VPS anyway) and stays behind the `SearchSource` interface as backend #3.
- **Mechanism correction (RESEARCH Pitfall 1, plan 04-03/04-04):** a `web_app` inline button's `WebAppInfo` carries ONLY a `url` — there is no `start_param` field (verified against the installed grammY typings), so the deep link's plain gazetteer id travels as `?dest=<slug>` in that URL and the webview reads `location.search` first, `initData.start_param` second. The D-10/D-11 intent (venue card → one tap → Mini App preloaded with a plain id, no crypto) is unchanged; a structural gate asserts no crypto in the deep-link path.
- The bilingual alias scheme: `/cari` + `/search` are registered together (the Phase 2 D-04 precedent of pairing `/start`↔`/mula`, `/privacy`↔`/privasi`); `/pergi_ke` stays reserved for Phase 5 and its future-stub ban is narrowed to `/pergi_ke`, not removed.
**UI hint**: no
### Phase 5: Routing + Route Display
@@ -205,7 +224,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7
| 1. Design Tokens + Rams Foundation | 0/TBD | Not started | - |
| 2. Bot Skeleton + initData Security | 0/TBD | Not started | - |
| 3. Mini App Shell + Geolocation | 0/4 | Ready to execute | - |
| 4. Destination Search + KL Gazetteer | 0/TBD | Not started | - |
| 4. Destination Search + KL Gazetteer | 0/4 | Ready to execute | - |
| 5. Routing + Route Display | 0/TBD | Not started | - |
| 6. Turn-by-Turn Guidance (Live Driving) | 0/TBD | Not started | - |
| 7. Hardening + Private Launch | 0/TBD | Not started | - |