chore(planning): phase 5/6/7 planning artifacts + milestone-completion state sync
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
# Phase 5: Routing + Route Display - Context
|
||||
|
||||
**Gathered:** 2026-10-24
|
||||
**Status:** Ready for planning — **with a roadmap amendment** (SC3 rewording, below)
|
||||
|
||||
<domain>
|
||||
## Phase Boundary
|
||||
|
||||
The route EXPERIENCE ships end-to-end in fixture world: a `RoutingSource` interface (mirroring `SearchSource`), a fixture backend whose geometries for 10–20 real KL pairs were precomputed at build time, Rams route rendering (orange casing on the grayscale map), up-to-3 alternatives as a bottom card + chips, selection redraw with camera refit, and an honest "router pending" state for arbitrary origins. The `guidance_sessions` envelope is designed as a types-only frozen contract for Phase 6. **No VPS, no Worker route proxy, no third-party routing calls** — the engine itself is deferred to the WASM-router OSS track (client-side routing, backend #2), with Valhalla-on-VPS documented as backend #3.
|
||||
|
||||
**ROADMAP AMENDMENT (planning must apply):** SC3 is reworded from "routes cleanly through self-hosted Valhalla … behind the Worker proxy" to: "the golden-route corpus (10–20 real KL pairs) routes cleanly through the fixture RoutingSource backend with bundle-size and type gates holding; the RoutingSource interface carries the documented backend ladder (fixtures → client-side WASM router → Valhalla-on-VPS) and the 'router pending' state is deliberate and designed." RTNG-01's "calculated route" is satisfied by fixture calculation; the arbitrary-origin router is a documented deferral, not an omission.
|
||||
|
||||
</domain>
|
||||
|
||||
<decisions>
|
||||
## Implementation Decisions
|
||||
|
||||
### Routing infrastructure — THE PIVOT (user decision, supersedes roadmap SC3 v1)
|
||||
- **D-01:** **No VPS this phase. No third-party routing API ever at runtime** (origin+destination to a third party is a core-value privacy leak). Routing is a **`RoutingSource` interface** with a backend ladder: **#1 fixtures (this phase) → #2 client-side WASM router (OSS track, deferred) → #3 Valhalla-on-VPS (documented, provision scripts as a documented path, not shipped)**.
|
||||
- **D-02:** Backend #1 = **fixture routes for the 10–20 golden KL pairs**, geometries precomputed at BUILD time by a repo script hitting the public OSRM demo server once (build machine, fixed public coordinates — no user data, no runtime dependency), committed as compact encoded polylines. Each pair pins expected distance/duration tolerances.
|
||||
- **D-03:** Arbitrary origin/destination combinations return an honest **"router pending"** state — a designed, deliberate Rams surface (UI-SPEC scope), never a blank map, never a fake route, never a silent failure.
|
||||
- **D-04:** The **WASM-router track** (client-side routing in the webview — origin+destination never touch a server; static-hosted; fork-perfect) is captured as the post-v1 OSS project that becomes RoutingSource backend #2, exactly parallel to the search backend #2 pattern. The user's static-hosting/fork-model intent is preserved as the architectural direction, not abandoned.
|
||||
- **D-05:** The Worker gains **no `/api/route`** this phase. Fixtures ride in the web bundle (gazetteer precedent). The interface stays backend-shaped so a server backend could slot in later without client rework.
|
||||
|
||||
### guidance_sessions envelope (Phase 6's contract, frozen now)
|
||||
- **D-06:** **Types-only contract**: `guidance_sessions` envelope = { id, chat ref, route snapshot (inline), created_at } with a **~2h TTL** — shipped as code types + docs, **no KV namespace, no service, no runtime writes**. Phase 6 builds the service on the frozen shape.
|
||||
- **D-07:** Route snapshot lives **inline in the envelope record — one key, one TTL**; nothing outlives 2h, nothing reconstructable after expiry. Consistent with the location-pin TTL precedent (Phase 3). The route model itself carries **step geometry + snapped-progress support fields from day one** (GUID-05/06 upstream obligation).
|
||||
|
||||
### Route UX surface (UI-SPEC scope; phase-terminal)
|
||||
- **D-08:** Alternatives present as a **bottom card + chips**: one card for the selected route (time, distance, one-line difference vs best) with compact alternates as selectable chips — tap → redraw. Map stays dominant.
|
||||
- **D-09:** Route line = **signal-orange casing** (dark under-line for grayscale contrast) + orange center line — Phase 1's reserved accent, per the navigate_map_overview mockup. Destination pin keeps venue semantics; origin = subdued ring. Camera **fits route bounds** on draw.
|
||||
- **D-10:** **Display-only terminal surface**: selection redraws + camera refits; a restart/search-again affordance returns to the destination state. **No start-guidance button, no turn instructions, no progress UI** — Phase 6. No placeholder-shaped furniture (Phase 3 D-08 law).
|
||||
|
||||
### Gates replacing SC3's latency/subrequest budgets
|
||||
- **D-11:** **Bundle budget**: fixture geometry + route-model code ≤ ~200KB gzipped added to the web bundle, enforced as a BA build-artifact gate. **Type gates**: route model readiness (step geometry + snapped-progress fields) pinned by tests. "Router pending" state covered by UI-SPEC + captures. Latency/subrequest budgets are not applicable to fixture world (documented as such, not faked).
|
||||
|
||||
### Privacy (carried + made specific)
|
||||
- **D-12:** Fixture geometries are public-data routes between public places — no user coordinate ever enters a fixture. The build-time OSRM fetch happens on the maintainer's machine against fixed public points; the script documents this boundary. Runtime: origin stays in memory only (Phase 3 law); no route persists (envelope is types-only this phase).
|
||||
|
||||
### OpenCode's Discretion
|
||||
- Fixture encoding format (encoded-polyline vs simplified GeoJSON) within the ≤200KB budget
|
||||
- RoutingSource interface shape (async, backend-tagged results, tolerance metadata)
|
||||
- Which Phase 4 corpus destinations become the 10–20 pairs; realistic origins list
|
||||
- One-line-difference copy per alternative card (en/ms, clinical tone); "router pending" copy
|
||||
- Chip/card visual details within the Rams system (UI-SPEC will bind exact geometry)
|
||||
|
||||
</decisions>
|
||||
|
||||
<specifics>
|
||||
## Specific Ideas
|
||||
|
||||
- The route experience should feel like the mockup distilled: the orange line is THE accent on a grayscale world — nothing else competes.
|
||||
- "Router pending" copy should be honest and calm: the app knows what routing is, states it isn't wired yet, offers search again. Same clinical register as the denied card.
|
||||
- Fixture pairs double as the demo script: the 10–20 pairs are the routes a reviewer walks to see the product work.
|
||||
|
||||
</specifics>
|
||||
|
||||
<canonical_refs>
|
||||
## Canonical References
|
||||
|
||||
**Downstream agents MUST read these before planning or implementing.**
|
||||
|
||||
### Phase scope + decisions
|
||||
- `.planning/ROADMAP.md` §Phase 5 — goal, success criteria **+ this file's SC3 amendment (planning applies it)**
|
||||
- `.planning/REQUIREMENTS.md` §RTNG-01/02 (+ GUID-05/06 upstream obligations)
|
||||
- `.planning/phases/04-destination-search-kl-gazetteer/04-CONTEXT.md` — SearchSource pattern to mirror; backend-ladder pattern; fork-model law (GPL-3.0)
|
||||
- `.planning/phases/03-mini-app-shell-geolocation/03-CONTEXT.md` — map boot, marker/follow controller, memory-only law, location-pin TTL precedent
|
||||
|
||||
### Codebase
|
||||
- `web/src/map/` — MapLibre boot (style never re-set — route layers must be addLayer, not style mutation), marker, follow controller
|
||||
- `web/src/search/resolve-destination.ts` — the preloaded destination this phase routes TO
|
||||
- `search/` — the interface+backend+ladder pattern to mirror
|
||||
- `web/scripts/capture.mjs` + mock profiles — the capture harness the route display must extend (`?dest=` profiles exist)
|
||||
- `bot/src/i18n/strings.ts` pattern — copy discipline for card/difference strings
|
||||
|
||||
</canonical_refs>
|
||||
|
||||
<code_context>
|
||||
## Existing Code Insights
|
||||
|
||||
### Reusable Assets
|
||||
- `search/` workspace: interface + ladder + loader + corpus-gate patterns to mirror for `routing/`
|
||||
- Phase 4 corpus gate (D-13/D-14) — the fixture-pair tolerance gate follows its shape
|
||||
- Mock harness profiles (`?dest=`) — route-state capture profiles extend these
|
||||
- BA build-artifact gates — the bundle-budget gate joins them
|
||||
|
||||
### Established Patterns
|
||||
- npm workspaces + delegate scripts; TDD RED→GREEN; hand-rolled runners
|
||||
- Interface + documented backend ladder (SearchSource → RoutingSource)
|
||||
- Types-only frozen contracts (session envelope) with TTL-only storage law
|
||||
- UI-SPEC gate applies this phase (UI hint: yes) — planning routes through it
|
||||
|
||||
### Integration Points
|
||||
- Destination resolver → route destination input (Phase 4 hands off where Phase 5 begins)
|
||||
- Route model step geometry + snapped-progress fields → Phase 6 guidance consumes
|
||||
- `guidance_sessions` envelope types → Phase 6 bot service implements
|
||||
|
||||
</code_context>
|
||||
|
||||
<deferred>
|
||||
## Deferred Ideas
|
||||
|
||||
- **WASM-router OSS project** — client-side routing in the webview (RoutingSource backend #2); static-hosted, privacy-maximal, fork-perfect; its own post-v1 project
|
||||
- **Valhalla-on-VPS** — RoutingSource backend #3; docker-compose + Caddy + provision scripts as a documented path (Oracle Always Free candidate; full-MY extract chosen if provisioned)
|
||||
- **Worker `/api/route` proxy** — only meaningful with a server backend
|
||||
- **Real routing for arbitrary origins** — arrives with backend #2/#3; the "router pending" state is the honest interim
|
||||
- Turn instructions/progress UI — Phase 6 (GUID-*)
|
||||
- Toll-avoidance / costing knobs — v1.x
|
||||
|
||||
</deferred>
|
||||
|
||||
---
|
||||
|
||||
*Phase: 05-routing-route-display*
|
||||
*Context gathered: 2026-10-24*
|
||||
Reference in New Issue
Block a user