8.4 KiB
phase, slug, status, nyquist_compliant, wave_0_complete, created, updated
| phase | slug | status | nyquist_compliant | wave_0_complete | created | updated |
|---|---|---|---|---|---|---|
| 5 | routing-route-display | final | true | false | 2026-10-24 | 2026-10-24 |
Phase 5 — Validation Strategy
Per-phase validation contract for feedback sampling during execution.
Test Infrastructure
| Property | Value |
|---|---|
| Framework | Existing hand-rolled harnesses (bot/test/runner.mjs, web/test/runner.mjs, search/test/runner.mjs); plan 05-01 adds the fifth workspace's identical pair (routing/test/runner.mjs + routing/test/harness.mjs, copied verbatim) — no new framework |
| Config file | None — suites are discovered by filename convention (*.test.mjs) per workspace |
| Quick run command | npm run routing:test / npm test -w web / npm test -w bot |
| Full suite command | npm run routing:test && npm test -w web && npm test -w bot && npm test -w search && npm run audit -w theme + typechecks + npm run routing:corpus |
| Corpus gate command | npm run routing:corpus (fixture-pair tolerance gate; also asserted in-process by routing/test/corpus.test.mjs so npm run routing:test fails on a pair regression) |
| Estimated runtime | ~20 seconds (hand-rolled runners are sub-second; the capture harness and the production-build BA9 gate are plan-scoped legs) |
Sampling Rate
- After every task commit: Run the touched workspace's suite (
npm run routing:test, ornpm test -w web/npm test -w bot) plus that workspace's typecheck. - After every plan wave: Run the full suite (
npm run routing:test && npm test -w web && npm test -w bot) plusnpm run routing:corpus— the golden-pair gate must hold at every wave merge, not just at the end. - Before
/gsd-verify-work: Full suite green + corpus gate green + BA9 bundle-budget gate green (production build). - Max feedback latency: 20 seconds (excluding the plan-scoped capture harness and the production build the BA gate requires — per-plan legs, not per-commit legs).
Per-task Verification Map
| task ID | Plan | Wave | Requirement | Threat Ref | Secure Behavior | Test Type | Automated Command | File Exists | Status |
|---|---|---|---|---|---|---|---|---|---|
| 05-01-T1 (workspace + contracts + route model) | 01 | 1 | RTNG-01, D-01/D-07 | T-05-01/06/07 | typed RoutingSource seam; day-one step-geometry + snapped-progress fields pinned by tests; no logging/storage | unit | npm run routing:test + npm run routing:typecheck |
❌ W0 | ⬜ pending |
| 05-01-T2 (polyline6 codec) | 01 | 1 | RTNG-01 | T-05-02 | pure codec; round-trip law; malformed-input refusal (never NaN points) | unit | npm run routing:test |
❌ W0 | ⬜ pending |
| 05-01-T3 (fixture backend + lazy loader + index) | 01 | 1 | RTNG-01, D-03/D-04/D-05 | T-05-03/04 | null = honest pending; 200 m tolerance law; lazy index; three-environment loader proof; empty-fixture schema committed | unit + bundle | npm run routing:test + esbuild bundle marker |
❌ W0 | ⬜ pending |
| 05-03-T1 (guidance_sessions envelope types + gates) | 03 | 1 | D-06/D-07 | T-05-08 | types-only: no KV namespace, no runtime writes, TTL constant 7200 | gates + typecheck | npm test -w bot + npm run bot:typecheck |
❌ W0 | ⬜ pending |
| 05-02-T1 (golden-pairs corpus + fetch script) | 02 | 2 | RTNG-01/02, D-02/D-12 | T-05-05 | public coords only; UA mandatory; per-pair hard-fail on non-Ok; 10–20 pairs committed | fixture-driven | npm run routing:test |
❌ W0 | ⬜ pending |
| 05-02-T2 (offline tolerance gate + corpus runner) | 02 | 2 | RTNG-01/02 | T-05-05/12 | geometry↔summary consistency offline; codec round-trip per fixture; alternatives floor; fixture size early-warning | corpus | npm run routing:corpus + npm run routing:test |
❌ W0 | ⬜ pending |
| 05-04-T1 (route layers + markers + camera) | 04 | 2 | RTNG-01, D-09 | T-05-09 | addLayer-after-building-3d ordering; zero style re-set; verbatim hex constants; pitch 35 preserved | unit + typecheck | npm test -w web + npm run web:typecheck |
❌ W0 | ⬜ pending |
| 05-04-T2 (route card + chips + pending card + strings) | 04 | 2 | RTNG-02, D-03/D-08/D-10 | T-05-10 | COPY5 strings-module law; no per-card padding overrides; chips = <button type="button">; no start-guidance affordance |
unit | npm test -w web |
❌ W0 | ⬜ pending |
| 05-04-T3 (main.ts wiring + BackButton two-state walk) | 04 | 2 | RTNG-01/02, D-10 | T-05-10/11 | auto route consult after live+destination; no route request when destination unavailable; back always walks to root | unit | npm test -w web |
❌ W0 | ⬜ pending |
| 05-05-T1 (BA9 bundle-budget gate) | 05 | 3 | RTNG-01, D-11 | T-05-12 | fixture+route code ≤ 200 KB gz over production-shaped artifacts | build-artifact | npm test -w web (after npm run build -w web) |
❌ W0 | ⬜ pending |
| 05-05-T2 (route capture legs + ?fixpair knob + gallery) | 05 | 3 | RTNG-01/02 | T-05-14/15 | state-token signals only (no coordinates in console); pairId-only harness knob; harness module provably excluded; route drawn/alt/pending/dark legs non-blank | capture | npm run web:capture |
✅ extend | ⬜ pending |
05-05-T3 (no-/api/route + no-user-coordinate gates) |
05 | 3 | D-05/D-12 | T-05-16/05 | Worker gains no route proxy; fixtures carry zero user-coordinate risk surface | gates | npm test -w bot + npm run routing:test |
❌ W0 | ⬜ pending |
Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky
Wave 0 Requirements
All new this phase (the repo has no routing infrastructure today). The owning tasks are marked; a task's <verify> may reference a suite created in the SAME task (RED-first per the repo's TDD convention).
routing/test/runner.mjs+routing/test/harness.mjs— the fifth workspace's harness pair, copied verbatim fromsearch/test/(05-01-T1)routing/test/contract.test.mjs— RoutingSource shape, day-one model fields, null-pending contract (05-01-T1)routing/test/polyline.test.mjs— codec vectors + round-trip + malformed-input refusal (05-01-T2)routing/test/fixture-source.test.mjs+routing/test/loader-env.test.mjs— matching law, tolerance boundary, lazy index, no-logging/no-storage, three-environment loader proof (05-01-T3)routing/test/fixtures/golden-pairs.json— the pinned 10–20 pair corpus with tolerances (05-02-T1)routing/scripts/fetch-route-fixtures.mjs+routing/scripts/route-corpus.mjs+routing/test/corpus.test.mjs— the maintainer tool + the offline tolerance gate (05-02)bot/test/guidance-envelope.test.mjs— types-only envelope gates (05-03-T1)web/test/route-surface.test.mjs— layer order/paint constants, card/chips structure, camera constants, BackButton walk (05-04)- Extend (not new):
web/test/copy-gate.test.mjs(COPY1 floor + route keys verbatim),web/test/build-artifact.test.mjs(BA9 bundle budget),web/test/no-storage.test.mjs(explicitweb/src/route/case note),bot/test/privacy.test.mjsor new bot structural gate (no/api/route),web/scripts/capture.mjs+web/index.html(?fixpair legs)
The corpus runner is the phase's primary acceptance instrument (D-02's tolerance gates) — it is both a script and an in-suite gate, so npm run routing:test fails whenever a committed pair regresses.
Manual-Only Verifications
| Behavior | Requirement | Why Manual | Test Instructions |
|---|---|---|---|
| Route card + chips render legibly on a real device | RTNG-01/02 | Visual truth on real Telegram clients (the automated legs prove structure + capture the 390×844 viewport) | Optional: open the Mini App with ?dest=suria-klcc on device after deploy; confirm the orange route, card, and chips against web/screenshots/shell-route-fixture.png |
One optional manual leg only — the fixture world removes the real-device blocker Phase 3/4 carried. The phase's "router pending on device" behavior is covered by the pending capture leg.
Validation Sign-Off
- All tasks have
<automated>verify or Wave 0 dependencies - Sampling continuity: no 3 consecutive tasks without automated verify (every task carries an automated verify)
- Wave 0 covers all MISSING references
- No watch-mode flags
- Feedback latency < 20s (excluding plan-scoped capture/build gates)
nyquist_compliant: trueset in frontmatter
Approval: planner-complete (2026-10-24) — statuses flip to ✅ during execution