Files
arah2/.planning/phases/06-turn-by-turn-guidance-live-driving/06-08-SUMMARY.md
T
araharah-executor e546bcb2e0 docs(06-08): complete the automated half — captures + replay knob; the ONE REAL DRIVE is the BLOCKING gate
- task 1 done: the ?drive= replay knob, the seven guidance legs, the
  DSGN-02 guidance gallery — all committed and green (web 148/148,
  bot 125/125, routing 65/65, captures 20/20)
- two device-gate bugs fixed before the road (G7b confirm survival,
  G7c puck+freshness)
- task 2 = checkpoint:human-verify gate=blocking: the executor STOPPED
  per protocol — 06-DEVICE-GATE.md carries the real-drive checklist
  (Parts A/B/C); device results are never faked
- STATE.md and ROADMAP.md intentionally untouched (orchestrator-owned,
  per the dispatch)
2026-10-24 21:41:06 +08:00

21 KiB
Raw Blame History

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, duration, completed
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established requirements-completed duration completed
06-turn-by-turn-guidance-live-driving 08 web-capture-harness
capture-harness
d16-device-gate
drive-replay
mock-telegram
guidance-legs
dsgn02-gallery
no-red-law
console-hygiene
blocking-checkpoint
tdd
phase plan provides
06-turn-by-turn-guidance-live-driving 02 the four committed D-16 drive fixtures (web/test/fixtures/drives/*.json — the replay ground truth ?drive= names) + the D-04 machine the LIVE pump rides
phase plan provides
06-turn-by-turn-guidance-live-driving 03 POST/GET/DELETE /api/guidance — the envelope lifecycle the confirm/tripend legs' teardown executes (DELETE on abandon)
phase plan provides
06-turn-by-turn-guidance-live-driving 04 engine A live (deploy 75b0ff14, R2 graph round-trip verified) — the /api/route shape the capture stub answers
phase plan provides
06-turn-by-turn-guidance-live-driving 06 the LIVE pump (start gate → cockpit → reroute → teardown) — the surface the captures prove; camera.ts's locked pose
phase plan provides
06-turn-by-turn-guidance-live-driving 07 the cron turn-cards + the committed glyph PNGs — Part C's street-source ratification item
phase plan provides
05-routing-route-display 05 the capture-leg pattern (one leg = one context + one screenshot, console-token races, the DSGN-02 composer) — extended, never replaced
web/src/mock/telegram-mock.ts — the ?drive=<fixture> replay knob: navigator.geolocation replaced by a committed-fixture stream (real-time schedule, lazy clock start at the first watch arm, window.__ARAHARAH_DRIVE pause()/resume() freeze), honest unknown-name fallback
web/scripts/capture.mjs — the seven guidance legs (active/list/rerouting/confirm/tripend/dark + guidance-gallery-compare) with the engine-A-shaped /api/route stub (consult = the drive model with real graph street names; reroutes = a merge model held 5s), the D-15 coordinate-hygiene scan, the computed-color NO-RED scan
web/screenshots/{shell-guidance-active,shell-guidance-list,shell-guidance-rerouting,shell-guidance-confirm,shell-guidance-tripend,shell-guidance-dark,guidance-gallery-compare}.png — the seven committed captures (force-added; the DSGN-02 fidelity artifact rides the blocking checkpoint)
web/src/route/route.ts + web/src/main.ts — TWO Rule-1 device-gate fixes: the D-09 confirm card survives a live fix (G7b); the pump's accepted fixes ride the chain's surfaces — puck + freshness (G7c, updatePuck dep)
06-08 task 2 (the ONE REAL DRIVE — BLOCKING
awaiting the human)
phase-6 verification close
DSGN-02 gallery review
added patterns
fixture-replay through the REAL watch: the ?drive= knob swaps navigator.geolocation, so the shell's unmodified D-15 throttle + D-04 machine consume the committed stream — captures prove the shell, never bypassing validation (the trust boundary's law)
root-absolute import.meta.glob: Vite 8's importGlob matches NO relative pattern escaping src/ (../test/... compiles empty — verified by the dev-server probe); /test/fixtures/drives/*.json works
engine-A-shaped stub by construction: POST #1 = consult (drive model, street names snapToGraph'd off the LOCAL kl-roadgraph.v1.bin at each post-maneuver segment midpoint); later POSTs = merge models held REROUTE_HOLD_MS — the REAL http-source validation still runs on every answer
computed-color NO-RED law: class lists cannot carry the token, so the rerouting/confirm legs scan getComputedStyle for rgb(237, 63, 28) across the banner/confirm subtrees
created modified
web/screenshots/shell-guidance-active.png
web/screenshots/shell-guidance-list.png
web/screenshots/shell-guidance-rerouting.png
web/screenshots/shell-guidance-confirm.png
web/screenshots/shell-guidance-tripend.png
web/screenshots/shell-guidance-dark.png
web/screenshots/guidance-gallery-compare.png
.planning/phases/06-turn-by-turn-guidance-live-driving/06-DEVICE-GATE.md
web/src/mock/telegram-mock.ts
web/scripts/capture.mjs
web/src/route/route.ts
web/src/main.ts
web/index.html
web/test/route-surface.test.mjs
The replay plays REAL-TIME (the recorded schedule), never compressed: the machine's grace/storm clocks read wall time (route.ts's now()), so compressed playback would desync every D-04 timing; the ?drive= clock starts LAZILY at the first watchPosition arm (the route draw) so no fix is ever emitted before a consumer exists.
The /api/route stub lives in capture.mjs via Playwright interception (not index.html): it keeps the plan's file set, cannot leak into any shipped artifact (it never exists outside the capture run), and the client-side http-source validation still gates every answer.
Street names come from the LOCAL road graph (routing/data/kl-roadgraph.v1.bin) snapped at each post-maneuver segment midpoint — the same OSM-derived source engine A serves, so the film reads real KL streets (Jalan Tun Sambanthan, Jalan Petaling, ...); a graph-absent fork degrades to the honest streetUnnamed fallback.
TWO device-gate-blocking bugs were fixed rather than papered over: the confirm card evaporating on a live fix (the D-09 exit guard breaking under exactly the drive's step 6) and the puck/freshness freeze (a navigation UI whose position marker never moves and whose strip falsely flips SIGNAL LOST at 45s). Both pinned by new G-gates; both found by tracing the live-drive path, not by capture failure alone.
the guide wait mode: state-token race + DOM text polls + theme-slot honesty + whole-console coordinate scan — the D-15/T-06-04 hygiene law carried into capture legs
GUID-01
GUID-02
GUID-03
GUID-04
GUID-05
GUID-06
PX-01
PX-03
48min 2026-10-24

Phase 6 Plan 8: The Verification Close — Replay Captures + THE ONE REAL DRIVE Gate Summary

The shell is proven on film: the ?drive= fixture-replay knob streams the committed corridor/missed-turn drives through the LIVE pump and seven capture legs freeze the cockpit — banner with real OSM street names, collapsed-default list with the NEXT lamp, the calm no-red REROUTING state, the bottom-register abandon confirm, the trip-end deletion card, the dark-theme chassis — beside the mockup in the DSGN-02 guidance gallery — while two real device-gate bugs were caught and fixed before the road: the abandon confirm evaporating on a live fix, and the puck/freshness freeze that would have flipped SIGNAL LOST mid-drive; the ONE REAL DRIVE itself is now the BLOCKING human gate (06-DEVICE-GATE.md).

Performance

  • Duration: 48 min
  • Started: 2026-10-24T12:10:00Z (approx; fresh dispatch after verified-dead prior passes)
  • Completed (automated half): 2026-10-24T12:58:00Z approx
  • Tasks: 1 of 2 (task 1 complete + committed; task 2 = the BLOCKING device gate — awaiting the human)
  • Files: 14 (7 created, 7 modified) + the checkpoint file

Accomplishments

  • The ?drive= replay knob (task 1, step 1): installMockWebApp reads drive from location.search (harness-only module), validates the name through a slug guard + defensive fixture shape check against the committed web/test/fixtures/drives/*.json, and replaces navigator.geolocation with a replay source. The REAL pump arms its REAL createGuidanceWatch against it — the unmodified D-15 throttle and D-04 machine consume the committed stream; no test-only bypass of validation (the threat model's trust-boundary law). The clock starts lazily at the first watch arm (the route draw) and plays REAL-TIME; window.__ARAHARAH_DRIVE = { pause(), resume(), name } freezes/resumes emission mid-stream. An unknown name emits one honest token (ARAHARAH-DRIVE state=unknown) and falls back — never a crash, never arbitrary data (T-06-08).
  • The seven guidance legs (task 1, step 2), exactly per the UI-SPEC capture table:
    • shell-guidance-active.png — ?mock=android&dest=merdeka-118&fixpair=central-market-to-merdeka-118&drive=corridor-follow: banner GUIDE // NEXT + white 85 M + beige JALAN TUN SAMBANTHAN + orange arrow on the plate, compacted strip (data-guidance="active"), the guidance card (GUIDE register, Merdeka 118, 4 MIN · 1.9 KM · ETA HH:MM, progressbar, END TRIP), collapsed-default LIST toggle, matte-black chassis rgb(26,26,26).
    • shell-guidance-list.png — scripted banner tap → aria-expanded=true, CLOSE toggle, the NEXT row lamp + real text rows.
    • shell-guidance-rerouting.png — drive=missed-turn-excursion captured INSIDE the REROUTING window (the stub holds the merge answer 5s): GUIDE // REROUTING, — dash, the calm copy, the blinking gantry, the last glyph held — zero functional-red computed colors in the banner or card.
    • shell-guidance-confirm.png — scripted END TRIP → the bottom-register confirm card (GUIDE // CONFIRM, Abandon route?, YES, ABANDON primary, CONTINUE) — no red.
    • shell-guidance-tripend.png — scripted YES, ABANDON → the center-register trip-end card with the visible deletion clause; banner/list cleared; the full-height strip returned.
    • shell-guidance-dark.png — scheme=dark: the theme-slot honesty check + the chassis Rams-constant.
    • guidance-gallery-compare.png — the DSGN-02 composite beside active_route_guidance/screen.png (the composer generalized with mockup params; legs 8/13 byte-identical behavior).
  • The engine-A-shaped route stub: the shell's route consult rides /api/route through the composed ladder; the guidance legs intercept it with an answer built from committed data — the pair's ODbL geometry + the drive's recorded maneuverIdx/kinds + street names snapped off the LOCAL road graph at each post-maneuver segment midpoint (engine A's deriveSteps semantics). Reroute requests get a merge model from the requesting fix (the replay controller's buildRerouteModel semantics), held 5s so the calm window is photographable. The REAL validatedResult still runs on every answer.
  • D-15 console hygiene carried into captures: every guidance leg scans its WHOLE console capture for coordinate-bearing lines (assertNoCoordinateLines) — the legs assert ARAHARAH-GUIDE state=<state> tokens and the ABSENCE of coordinates; the replay source itself logs nothing per fix (T-06-04: no new logging).
  • Two device-gate bugs caught and fixed BEFORE the road (see Deviations):
    • The D-09 confirm card evaporated on the next accepted fix (renderCockpit rebuilt the guidance card over the ONE exit guard) — G7b pins the survival.
    • The pump's accepted fixes never touched the chain's surfaces: the puck froze at the boot fix while the camera rode the snapped line (the UI-SPEC's recorded call: "the puck … carr[ies] progress"), and lastFix stayed at boot so the 45s staleness law would falsely flip SIGNAL LOST mid-drive and re-run the chain — one injected updatePuck dep composes lastFix = fix + marker.update (the RAW fix; the camera rides the SNAPPED foot) + setStale(false). G7c pins the call + main.ts's composition.
  • Suite state: web 148 passed / 0 failed (146 baseline untouched-green + G7b + G7c), bot 125/125, routing 65/65; all typechecks clean; npm run web:capture 20/20 (all 13 prior legs unbroken); zero new dependencies.

Task Commits

  1. task 1: the replay knob + the seven legs + the gallery (with the two Rule-1 fixes committed separately first)
    • fca2a90 fix(06-08): the D-09 confirm card survives a live fix — renderCockpit guards the card rebuild (G7b RED→GREEN, atomic test+fix)
    • d0d5a7d feat(06-08): the ?drive= fixture-replay knob — the D-16 browser leg's fix source
    • 17bb950 feat(06-08): the seven guidance capture legs + the DSGN-02 guidance gallery
    • ed86196 art(06-08): the seven committed guidance captures — the shell proven on film
    • b83a88e fix(06-08): the pump's accepted fixes ride the chain's surfaces — puck + freshness (G7c)
    • 5eeccdf art(06-08): regenerate the guidance captures — the puck rides the line

Files Created/Modified

  • web/src/mock/telegram-mock.ts — the ?drive= knob: fixture glob (root-absolute pattern), slug + shape validation, the replay geolocation (real-time schedule, lazy clock, pause/resume), the honest unknown-fallback token
  • web/scripts/capture.mjs — the guide wait mode, the stub installer, the seven legs, the generalized composer, the coordinate + computed-color scans, the expected list at 20
  • web/src/route/route.ts — the confirm-card renderCockpit guard (G7b) + the updatePuck dep call per accepted fix (G7c)
  • web/src/main.ts — updatePuck wiring: lastFix refresh + marker.update + setStale(false), the camera untouched
  • web/index.html — the runner-page knob comment (docs-only; the knob is read inside the mock module)
  • web/test/route-surface.test.mjs — G7b + G7c (147→148)
  • web/screenshots/*.png — the seven committed captures
  • .planning/phases/06-turn-by-turn-guidance-live-driving/06-DEVICE-GATE.md — the blocking gate's protocol + checklist

Decisions Made

See key-decisions: real-time replay, the Playwright-side stub, graph-snapped street names, and the two fix-over-paper-over calls.

Deviations from Plan

Auto-fixed Issues

1. [Rule 1 - Bug] The D-09 confirm card evaporated on a live fix

  • Found during: task 1's confirm-leg design (traced the live-drive path before filming)
  • Issue: renderCockpit rebuilt the guidance card over the open confirm on every accepted fix — the ONE PX-03 exit guard survived only between fixes; G7 tested confirm without a subsequent fix so the gate never saw it. The real drive's step 6 (END TRIP on a live road, fixes every ~2–5s) would have hit it within one watch tick.
  • Fix: renderCockpit skips the card rebuild while confirmOpen; banner/list still re-render. G7b pins: confirm mounts → live fix → confirm still shown → YES ABANDON still tears down.
  • Files modified: web/src/route/route.ts, web/test/route-surface.test.mjs
  • Commit: fca2a90

2. [Rule 1+2 - Bug/critical gap] The pump's fixes never rode the chain's surfaces (frozen puck + false SIGNAL LOST)

  • Found during: task 1's active-leg design (the puck's visual trail on the probe capture) + the 45s staleness trace
  • Issue: the UI-SPEC's recorded call pins "the puck … carr[ies] progress", but the pump's onWatchFix moved only the camera — the puck froze at the boot fix and the driver would lose it within seconds; and lastFix never refreshed during guidance, so the strip's 45s staleness law would flip SIGNAL LOST (red) mid-drive and re-run the chain (a marker jump + a 60s nudge poll on the road).
  • Fix: one injected dep (updatePuck) called per accepted fix; main.ts composes lastFix = fix + marker.update (raw fix) + setStale(false); the camera untouched (the guidance camera owns the viewport). G7c pins the dep call + the main.ts source-scan composition.
  • Files modified: web/src/route/route.ts, web/src/main.ts, web/test/route-surface.test.mjs
  • Commit: b83a88e

3. [Rule 3 - Blocking] The route consult needed a steps-bearing answer for the legs to exist at all

  • Found during: the first capture run (every guidance leg failed: the fixture-backend fallback's steps: [] model puts the arrive mark at 0m → instant arrival → teardown before any assert)
  • Issue: the plan's interfaces name only the mock's fix source; but the LIVE pump's cockpit needs maneuver marks the fixture backend never serves (D-10's honesty law — fixture steps stay empty).
  • Fix: the engine-A-shaped /api/route stub in capture.mjs (Playwright interception, installed pre-goto): consult = the drive model (committed geometry + recorded maneuverIdx/kinds + graph-snapped street names), reroutes = merge models held 5s. No index.html behavior change, nothing shipped; the client-side validation still gates every answer.
  • Files modified: web/scripts/capture.mjs
  • Commit: 17bb950 (rode the legs commit)

4. [Rule 3 - Blocking] Vite 8's import.meta.glob matches no relative pattern escaping src/

  • Found during: the knob build (the eager glob compiled to Object.assign({}) — zero fixtures)
  • Fix: the root-absolute pattern /test/fixtures/drives/*.json (verified by the dev-server probe; all four drives inline into the harness bundle, production tree-shake verified clean in both directions).

Judgment calls within plan laws (not deviations)

  • The replay's pause() freezes EMISSION only; the shell's wall clock keeps running (the machine's grace windows inflate across a pause) — legs that pause close before any machine timing matters; documented in the mock's header.
  • The unknown-name token (ARAHARAH-DRIVE state=unknown) is the knob's ONLY console line (the plan's sanctioned honest token); a successful load is silent — diagnostics ride window.__ARAHARAH_DRIVE.name.

Auth Gates

None — the capture run is offline (harness stubs + Playwright interception); no Telegram/network credentials needed.

Known Stubs

Task 2 (the ONE REAL DRIVE) is NOT RUN — by design, never faked. It is the phase's declared exit gate (D-16) and a checkpoint:human-verify gate="blocking" task: physical GPS, real road geometry, and human legibility/haptic judgment are the declared device-gate protocol. .planning/phases/06-turn-by-turn-guidance-live-driving/06-DEVICE-GATE.md carries the full checklist (Parts A/B/C). The phase stays OPEN until the drive's per-step verdict lands; a FAIL holds it open (the Phase 3 UNVERIFIED precedent). Everything automatable on the path is green: web 148/148, bot 125/125, routing 65/65, captures 20/20.

Threat Surface Scan

No new surface beyond the plan's <threat_model>: the replay knob feeds the REAL pump with committed, attributed fixtures (unknown names fail honest — the Tampering mitigation); the guidance legs assert state tokens and scan their whole console for coordinate-bearing lines (the D-15 hygiene law carried into captures — T-06-04); no new production logging (the knob is harness-only, tree-shaken from web/dist — verified in both directions this plan); the real-drive protocol rides the product's own privacy posture (no location history exists; the KV spot-check proves the post-trip deletion on real infrastructure). No threat flags.

Issues Encountered

  • The prior 06-08 dispatches died without landing work (verified quiet + clean before starting); this session started fresh and landed the whole automated half.
  • Concurrent processes are writing the shared tree again (.planning/*, AGENTS.md, README, mockup code.html files, a bot command file) — every commit staged ONLY this plan's files individually; none of the concurrent files were touched.
  • Node lives under nvm; every shell command sourced ~/.nvm/nvm.sh first (all prior plans' precedent).

User Setup Required

For the device gate itself: nothing beyond the standing deploy posture (npm run deploy -w bot; the R2 graph already uploaded; the R2 dashboard activation possibly still pending — see 06-DEVICE-GATE.md's executor notes).

Next Phase Readiness

  • The blocking checkpoint (task 2): Parts A (gallery), B (the drive), C (the street-source ratification) await the user; the verdict rides 06-08-SUMMARY.md's update + 06-DEVICE-GATE.md.
  • The phase verifier: D-16's three legs now have their evidence — recorded drives (06-02), captures (this plan), the drive pending (the gate). The two new fixes (G7b/G7c) are pinned by gates, not claims.
  • Phase 7: the gallery artifact + the recorded calls are the DSGN-02 close-out material.

Phase: 06-turn-by-turn-guidance-live-driving Automated half completed: 2026-10-24; the ONE REAL DRIVE awaits the user (BLOCKING)

Self-Check: PASSED

  • All 7 committed captures verified present on disk + in git (ed86196, 5eeccdf); all 6 plan commits verified in git log (fca2a90, d0d5a7d, 17bb950, ed86196, b83a88e, 5eeccdf) — zero deletions in any of them.
  • Acceptance greps re-run at close: import.meta.glob over /test/fixtures/drives/*.json + the __ARAHARAH_DRIVE surface present in telegram-mock.ts; all 7 UI-SPEC leg names present in capture.mjs asserting ARAHARAH-GUIDE tokens.
  • npm test -w web 148/148 (G7b + G7c included), bot 125/125, routing 65/65, all typechecks clean; npm run web:capture 20/20 with the coordinate-hygiene scan green on every guidance leg.
  • STATE.md and ROADMAP.md untouched by this executor (per the dispatch's explicit instruction; their working-tree diffs are other processes' concurrent writes).
  • The prior dispatch's "quiet tree" note held this time: every commit staged only this plan's files.