- Part A: the ONE consolidated walk (D-05) — four clients × seven
interactions, ⬜ cells, PASS/FAIL/NOT RUN vocabulary defined in-file
- Part B: the Android battery record (D-04) — 11 required fields, the
no-extrapolation rule in the file's own voice
- Part C: the 12 automated-half commands with ⬜ result cells + the
--live NOT-RUN-is-not-a-pass note
- Part D: the six D-09 checklist items, each naming its evidence
- Executor notes: the /cari defect ROOT-CAUSED+FIXED (script param
name), the c3 posture, the R2 graph state, the KV-list over-ceiling
options (user decision), the kv-expiry credential caveat, never-fake
- FINAL VERDICT: ⬜ NOT YET SIGNED — the human fills the verdicts
- the Bot API parameter is 'scope' (verified against
core.telegram.org/bots/api/methods/setmycommands); the script's
'bot_command_scope' was an unknown field Telegram silently ignores,
so every call hit the default scope and the two clear calls wiped the
default set entirely — the ok:true lines proved nothing about scope
- registration re-run: default (agnostic/en/ms) + all_private_chats
(agnostic/ms) read back help, privacy, cari via getMyCommands with
the correct 'scope' param; group scopes verified cleared
- docs/KNOWN-LIMITATIONS.md: the 'Telegram-side defect' attribution
corrected to the actual script bug; residual client menu-caching
caveat + type-the-command workaround kept
- bot/README.md command row updated to the real scope set
- banner takes one step down the SAME type-token scale in landscape
(headline-md distance / label-lg street) + xs vertical padding so the
measures fit the 72px min-height instead of overflowing it
- guide-list chrome offset corrected to its own margin stack
(sm + 72 + 1 + 24 + sm = 113px, was 104px)
- bottom register: the portrait 64px control-clearance composite already
seats the guidance/confirm card inside the landscape height — the
landscape override is removed (measured card top 159 vs banner bottom
103 at 844x390); attribution chip + recenter control clear
- device-walk feedback on 07-02's committed geometry; tokens binding
- captures re-run: CAPTURE OK — 22/22 non-blank
- /start sendPhoto now points at MASTER_FILE-arah2_logo.png (deployed
from web/public/ — the untracked asset lands here so the reference
resolves on deploy)
- README + AGENTS.md + the 4 mockup screens swapped the Stitch
googleusercontent logo placeholder for the local master logo
- pre-existing on the tree through 07-03..07-05 execution; verified by
this session's baselines (bot 126/126, web 165/165, captures 22/22)
- source-side runtime-hosts gate gains DOC_POINTER_STATIC_TEXT_HOSTS (the
MapLibre-attribution precedent): the published repo origin may appear
ONLY as a bare URL literal in bot copy (D-08/D-09), never fetched
- class is NARROW and pinned by SA6: a fetch( target naming the same
host is still a violation
- Rule 1 (found by SA6's RED): the fetch( handler's declaration
heuristic misclassified any quoted absolute URL as a TS declaration —
quoted strings are targets; they now reach the host check
- docs/PRIVACY-AUDIT.md: adjudication documented + dated re-run addendum
- deferred-items.md #1 closed: npm run privacy-audit exits 0 again
(PRIVACY AUDIT CLEAN — 5 gate(s) passed, 0 violations; suite 13/13)
- asset-header probe reads HTTP status BEFORE interpreting headers — a
non-2xx is deployment drift (the notRun exit-2 class), never a cache
violation; the violations.length count bug fixed
- XHTML namespace URI joins the SVG spec-identifier adjudication
- probeUnavailable carries the reason only (the CLI prints NOT RUN)
- CP2/AU1 suite vectors updated to the corrected contracts
Residue note: these edits were on the tree during 07-03/07-04 execution
but escaped those plans' commits (07-04-SUMMARY residue caution).
- 3 tasks (TDD RED→GREEN), 7 commits, 19/19 budget-audit suite vectors
- BUDGET AUDIT CLEAN (exit 0); --live exits 2 on deployment drift (honest class)
- 2 deviations documented: the c3-aware route-cpu verdict (plan contradiction),
the golden-corpus environment-drift class
- open items for 07-06 flagged: the KV-list cadence finding + the privacy-audit
RED (07-05's gitmirah strings) — both in deferred-items.md
- a missing package.json in the audit root is T-07-22's environment-drift class,
not a corpus failure — the corpora cannot even be spawned there
- AU1's flag-skip assertion matches the printed 'NOT RUN — (pass --live)' shape
- the full ceilings table (Cloudflare Workers limits / KV limits / pricing, sourced)
- current measurements: A* p95 83.989 ms vs 8 ms ladder budget (the accepted c3 class,
negative headroom printed), BA9 79,815/204,800 gz, app bundle 479,178/500,000 gz,
KV write classes (cron = 0, source-proven), golden corpora exit 0
- the per-request-class subrequest inventory (source-derived, not a live Workers Logs metric)
- the DISCOVERED finding: KV list rate 1,440/day (60 s cron x 1 list/tick) OVER the
1,000/day ceiling — documented with options, decision deferred to the 07-06 launch gate
- the c3 cross-metro escalation restated; honest Statement; unsigned signature block
- npm run budget-audit: 5 required gates + the --live cache-header probe; one evidence line per gate
- the FREE-TIER COMPARISON table: every documented Cloudflare free-plan ceiling beside the
current value where measured, `not measured` where not — the console form of docs/BUDGETS.md
- exit 0 CLEAN / 1 FAILED / 2 NOT RUN — a skip is never a pass (T-07-22)
- no secret, no coordinate in the output (D-14's category-only law, applied to budgets)
- route-cpu: RE-RUNS routing/scripts/measure-route-cpu.mjs as a child process; p95 printed
against the 8 ms product budget + 10 ms free ceiling; the child's GATE FAIL line carried
verbatim; the accepted c3 band has a 200 ms drift guard — uncharted regression fails
- bundle-budget: BA9 route-payload gz sum + whole-app bundle ceiling (500000 gz bytes);
Worker bundle honest NOT MEASURED when bot/dist is absent (never zero)
- kv-writes: 4 write sites inventoried by family, every write TTL-named (PG1); the cron
zero-write law is source-proven — runGuidanceCronTick's body must contain no .put(/.delete(
- subrequests: per-request-class external-subrequest inventory derived from the route table;
uninventoried classes FAIL; source-derived honesty sentence verbatim; never a fabricated zero
- cache-headers: reuses cloudflare-probes' runAssetHeaderProbe (imported, never forked)
- golden-corpus: RE-RUNS routing:corpus + search:corpus as child processes (SC4.a/SC4.b)
- every gate must print its measurement and carry its contract id
- every gate must be able to FAIL on a synthetic violation (fixture injection)
- a skip is never a pass (notRun class; T-07-22)
- web/public/_headers: /assets/* → public, max-age=31556952, immutable (Vite content-hashed output)
- / → public, max-age=0, must-revalidate (the HTML entry points at the current hashed assets)
- no CORS/Set-Cookie/other rules — same-origin policy stays the app's design
- verified: web/dist/_headers exists after the theme+web build
- /cari re-arm RAN 2026-10-25: all six scopes ok:true — 'all command scopes
armed'; residual Telegram client-menu caching risk stated, workaround
pointers at docs/KNOWN-LIMITATIONS.md (T-07-24/T-07-26)
- A1: NOT RETIRED as a mechanism hypothesis — mitigated-by-design via the
chain.ts polling degradation; A3: RETIRED as a decision constraint
(remote workers.dev origin, no LAN-IP dev deployment)
- the Phase-3 FINAL VERDICT table untouched (1 occurrence; the dated
section is the closure)
- docs/KNOWN-LIMITATIONS.md — new, for drivers AND forks: OSM data gaps,
the c3 cross-metro CPU degradation (2-8 ms short / p95 38-93 ms cross-metro,
measure-route-cpu.mjs LADDER HISTORY as evidence, ALT as the committed lever,
Workers Paid rejected on the $0 mandate), the /cari menu defect + the
type-the-command workaround, the beta-quality statement, the roadmap
pointers (WASM-router / ALT / engine B — none in this release), the
privacy paragraph, and the fork-facing audit commands
- strings.ts helpMenu (en+ms): ONE pointer line each, not /-prefixed so the
CS5 menu parse ignores it; URL is the repo's actual remote deep link
(http://gitmirah:3000/c-fu/arah2/src/branch/main/docs/KNOWN-LIMITATIONS.md),
identical in both locales — single-copy law (D-05)
- suite 126/126, CS5 green
- IN-01: delete the never-constructed ParsedInitData export (sole repo hit was
its own declaration); the three read-helper catches now carry Intent:
comments stating malformed-vs-tampered precedence and the chat-degrade law
- IN-02: wrangler.jsonc line 2 states the post-fact truth — the chat_sessions
namespace id below is live, no re-creation
- IN-03: new T4 vector 'age 900 s → ok:true (the boundary is INCLUSIVE)' pins
the strictly-greater comparator's inclusive edge (T-07-08); suite 126/126
- Findings table carries the ACTUAL printed evidence from the audited run
(commit 9c55e9a): 5 static gates PASS, 0 violations; live legs recorded
honestly as NOT RUN with the launch-gate re-run protocol
- Storage inventory: the four TTL-only KV families; Log vocabulary: the
category-only surfaces; Runtime network: the printed host inventory
(allowlist + documented static-text class) and D-02's zero-telemetry posture
- human signature block left blank for the launch gate (D-09)
- runs the five static gates in Pattern-4 order; --live adds the KV-expiry
and asset-header probes; the no-flag skip prints '(pass --live)' and is
never silently green
- exit 0 CLEAN / 1 FAILED (violations counted across gates) / 2 NOT RUN
(credentials or build or deployment drift — never mistaken for a pass)
- header states the maintainer-time-tool law, the GPL fork-reuse contract,
and D-02's zero-telemetry prove-the-absence posture
- AU1-3 CLI vectors green: CLEAN exit 0 on this tree, FAILED exit 1 via the
PRIVACY_AUDIT_ROOT fixture, NOT RUN exit 2 for --live without credentials
- runBundleTelemetryGate: PRODUCTION web/dist ONLY (dist-harness forbidden,
BA5); analytics/beacon token set (sendBeacon explicit form); positive
host allowlist with the host inventory printed, never assumed (A4);
deep-link crypto (D-11) and storage tokens JS-assets-only; a missing
build is notRun, never a silent pass
- runKvExpiryProbe: npx wrangler kv key list (current syntax, deprecated
colon form forbidden), namespace id read from bot/wrangler.jsonc at
runtime; parses name/expiration/metadata + list_complete/cursor and
follows the cursor; unexpected families REPORTED (A5); oldest/newest
expiry reported; raw key names never printed (category-only evidence)
- runAssetHeaderProbe: curl -sSI cache-control/cf-cache-status reported
VERBATIM (probabilistic — printed, never interpreted)
- documented adjudications: MapLibre static-text hosts, W3C namespace
identifiers, bare-array = CLI's internally-paginated complete set
- SA1-5: each source gate returns {id, pass, evidence}, passes the current
tree, and FAILS a synthetic violation via injected fixture roots
- BG1-2: production web/dist only; missing build is notRun (never a pass)
- CP1-2: probeUnavailable exact shape + credentials-absent degradation
- AU1-3: CLI exit 0/1/2 — CLEAN on this tree, FAILED on a fixture root
(PRIVACY_AUDIT_ROOT), NOT RUN for --live without credentials
- captureLeg accepts a per-leg viewport (default 390x844 unchanged)
- shell-guidance-landscape.png: corridor drive leg verbatim at 844x390 — the
@media (orientation: landscape) block exercised in a real browser
- shell-route-pending-landscape.png: the designed pending card in landscape
- both legs under the existing MIN_BYTES blank bar; capture 22/22 non-blank
- consult filters degenerate options (geometry.points < 2) into the pending-card class
- reroute ladder: no drawable option = the honest reroute-failed degradation, never a half-drawn snap-in
- GREEN for FM4; web suite 165/165, typecheck clean
- FAILURE_VECTORS as data: 7 classes (empty/error/no-geometry/off-road/
location-timeout/old-client/route-timeout), each with trigger + expected surface
- FM2 drives the REAL buildRoutePendingCard (text, no undefined, CTA wired)
- FM3 rejecting + never-settling sources both stay off the draw path (200ms guard)
- FM4 RED: a <2-point geometry currently reaches the draw path — the pending
card must replace the half-drawn line (T-07-12)
- FM5 pure-reducer excursion: one reroute-requested, storm guard holds, CALM slot
- FM6 old-client chrome builds with zero capability calls (07-01 owns fullscreen)
- FM7 location chain lands designed denied/awaiting-pin states
- route.ts: requestGuidanceFullscreen at BOTH guidance-start edges (activateGuidance + resume) directly after engageCloseProtection — synchronous, best-effort, return ignored
- route.ts: exitGuidanceFullscreen at BOTH teardown edges (teardownGuidance + stopGuidanceArtifacts) directly after releaseCloseProtection
- route.ts: watchFullscreenEvents registered exactly ONCE at the guidance-start edge; the callback is a deliberate no-op (observability only, D-14)
- main.ts: watchSafeAreaChanges(getWebApp()) called at the boot site directly after applySafeArea(resolveSafeInsets(getWebApp())) — insets re-resolve at runtime, not only once at boot (T-07-06b)
- no new logging; the route module's state-token console law unchanged
- telegram-mock gains requestFullscreen/exitFullscreen/lockOrientation/unlockOrientation + __fullscreen* state fields in the SAME change as the contract (contract + fake + test together)
- FS1-FS7: both-halves guard vectors, the throwing-platform path (FS4), the exit mirror (FS5), the event categories (FS6), the old-client fallback (FS7, SC2.e)
- FS8: safeAreaChanged re-resolution through the union authority, with a minimal document stub restored in finally
- FS9: comment-stripped source-scan ban on the DOM-fullscreen/orientation-lock escape hatches (T-07-10) + the guard-is-not-optional assertion
- suite 157 passed, 0 failed (148 baseline + 9); mutation check: neutering the 8.0 guard fails FS2/FS5
- new watchSafeAreaChanges(wa): registers handlers for both Telegram inset events, each re-applying through the SAME union authority (resolveSafeInsets -> applySafeArea) — never a duplicated computation
- each handler wrapped in try/catch so a throwing client event cannot break the boot (T-07-06b)
- resolveSafeInsets/applySafeArea behaviour unchanged; nothing written to storage
- TelegramWebAppLike gains requestFullscreen/exitFullscreen/isFullscreen/lockOrientation/unlockOrientation as OPTIONAL members only (no existing member reshaped)
- new web/src/telegram/fullscreen.ts: requestGuidanceFullscreen/exitGuidanceFullscreen/watchFullscreenEvents behind the BOTH-halves guard (method presence AND isVersionAtLeast("8.0"))
- every platform call in try/catch — a refused request is a supported degradation, never an error surface (T-07-06)
- no DOM Fullscreen API, no generic orientation lock, zero logging (T-07-10, T-07-09)
Checker-issue round 1 on the Phase 7 plan set:
BLOCKER (07-01) — watchSafeAreaChanges and watchFullscreenEvents were created
and unit-tested but never called in production: main.ts:74 was the only
safe-area site and was not in files_modified, and the fullscreen events were
never registered. Insets never re-resolved at runtime on a real device while
every gate stayed green.
- web/src/main.ts joins 07-01's files_modified; task 4 step 8 wires
watchSafeAreaChanges(getWebApp()) directly after the boot site's
applySafeArea(resolveSafeInsets(getWebApp())) line.
- task 4 step 6 registers watchFullscreenEvents once at the guidance-start
edge in route.ts, with a deliberately no-op callback (events are
observability, never correctness).
- New grep acceptance criteria pin BOTH production call sites; two new
must_haves key_links name them; T-07-06b now names the boot-site call.
WARNING (07-04 / VALIDATION.md) — the golden corpora were attributed to 07-04
t3, which never ran them. Folded into the budget audit: runGoldenCorpusGate()
re-runs `npm run routing:corpus` and `npm run search:corpus` as child
processes (the same shape runCpuLadderGate already uses), so the ONE
budget-audit command enforces SC4.a/SC4.b. VALIDATION.md rows now name 07-04
t2 and the budget-audit command.
WARNING (07-02 t3) — the landscape-leg snippet omitted the required setup.
The action now says to copy the existing corridor guidance leg VERBATIM
(setup stubGuidanceRoute(page, corridorModel) + guideQuery carrying dest +
fixpair + waitMode/expectGuide) and change ONLY the name, the scheme, and the
viewport; two grep criteria pin the setup and the query.
WARNING (07-04) — D-06/SC4 name subrequests but nothing measured beside the
50/request ceiling. Added runSubrequestClassGate(): a per-request-class
inventory derived from the Worker's route table (engine-A /api/route = 0
external subrequests; the cron tick's Telegram send is the only recurring
class; KV ops tracked separately against their own ceiling). Unmeasurable
counts read "not measured", never 0. docs/BUDGETS.md gains a
"## Subrequests per request class" section and the record states that the
inventory is source-derived, not a live Workers Logs metric.
WARNING (07-RESEARCH.md) — "## Open Questions" is now
"## Open Questions (RESOLVED)" and each of the five items carries its adopted
disposition; Q2/Q3 resolve to "answered by measurement at the launch gate per
D-04/D-06".
INFO (07-VALIDATION.md) — nyquist_compliant flipped to true and the sign-off
is approved 2026-10-25 after the map-row correction.
Waves, dependencies, autonomous flags, and the other three plans are unchanged.
- 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)
- the same 7 files regenerated after b83a88e (updatePuck): the active/
dark legs now show the puck ON the route line instead of frozen at
the origin; 20/20 non-blank captures
- during guidance the pump consumed fixes without refreshing 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 strip's 45s staleness
law falsely flipped SIGNAL LOST mid-drive and re-ran the chain
- one injected dep (updatePuck) composes both in main.ts: lastFix = fix,
marker.update (the RAW fix — the camera rides the SNAPPED foot, the
two-authorities-one-line law), marker.setStale(false); the camera is
NOT touched (the guidance camera owns the viewport — the guard
handleLive already keeps)
- G7c pins the dep call per accepted fix + the main.ts source-scan for
the marker composition (the RS2 boot-wiring shape)
- found while building the real-drive gate: any drive past 45s would
have hit both defects on the road
- web 148/148, typecheck clean; captures regenerated 20/20
- shell-guidance-active/list/rerouting/confirm/tripend/dark.png +
guidance-gallery-compare.png (DSGN-02 fidelity artifact beside
active_route_guidance/screen.png) — driven by the committed corridor/
missed-turn drive fixtures through the LIVE shell's real pump
- force-added from web/screenshots/ (gitignored regenerated output; the
captures are the phase gallery's review material at the device gate)
- guide wait mode: the ARAHARAH-GUIDE state-token race (expectGuide
on_route|rerouting) + DOM text polls + the PX-02 theme-slot honesty
check + the D-15 coordinate-hygiene scan over the WHOLE leg's console
(assertNoCoordinateLines — state tokens only, never coordinates)
- the engine-A-shaped /api/route stub (per-leg Playwright interception,
installed pre-goto): POST #1 = the consult — the drive model built
from the committed fixture corpus + the drive's recorded maneuver
indices + street names snapToGraph'd off the LOCAL road graph (the
road the turn puts you on); later POSTs = reroutes — the merge model
held 5s so the calm REROUTING window is photographable; the REAL
http-source validation still runs on every answer
- legs 14-19 per the UI-SPEC capture table: active (banner slots +
compact strip + card + progressbar + LIST default), list (scripted
banner tap -> CLOSE + NEXT row lamp), rerouting (calm copy + dash +
gantry + NO functional-red computed colors), confirm (bottom register
+ both CTAs + no red), tripend (center card + deletion clause + chrome
cleared + strip returned), dark (matte-black chassis constant)
- leg 20: guidance-gallery-compare.png vs active_route_guidance/screen.png
(the composer generalized with mockup params; legs 8/13 unchanged)
- prior 13 legs unbroken: 20/20 non-blank captures
- ?drive=<name> replaces navigator.geolocation with a replay source
streaming a committed drive fixture (web/test/fixtures/drives/*.json)
through the LIVE shell: the real pump arms the real
createGuidanceWatch against it — no test-only bypass of validation
- the replay clock starts lazily at the first watchPosition arm (the
route draw — nothing emitted before a consumer exists) and plays
REAL-TIME: the machine's grace/storm clocks read wall time
- window.__ARAHARAH_DRIVE = { pause(), resume(), name }: pause freezes
emission mid-stream (the capture legs' freeze for scripted taps and
the REROUTING window), resume continues; the machine's wall clock
keeps running across a pause (documented harness semantics)
- unknown drive name -> one honest token (ARAHARAH-DRIVE
state=unknown) + the default geolocation stays — never a crash,
never arbitrary data (T-06-08 Tampering mitigation); slug guard on
the name, defensive fixture shape check
- import.meta.glob pattern is ROOT-ABSOLUTE (/test/fixtures/drives/*.json
— Vite 8's importGlob matches no relative pattern escaping src/,
verified by the dev-server probe); fixtures inline into the harness
bundle only — production tree-shake verified clean in BOTH directions
- BA5 posture held: production scan clean, harness bundle carries the
replay; 147/147 web tests, typecheck clean
- a fix arriving while the abandon confirm is open rebuilt the guidance
card over it (the ONE PX-03 exit guard evaporating mid-decision); the
pump now re-renders banner/list only and the confirm surface survives
until CONTINUE or YES, ABANDON
- G7b pins it: confirm mounts -> live fix -> confirm still shown,
guidancePhase=confirm holds, YES ABANDON still tears down
- found while building 06-08's scripted END TRIP capture leg; the real
drive's step 6 (END TRIP on a live road) would have hit this within one
watch fix
- routing/scripts/build-glyphs.mjs: maintainer shell (Usage/Exit codes/
collect-then-write — a missing/invalid source exits 1 with the kind named
and nothing written); recolors currentColor → #EB8008 in-memory and
injects a full-bleed #1A1A1A plate (stroke="none" — it must not inherit
the root's orange stroke); the committed SVGs are THE single source and
stay untouched
- sharp 0.35.5 as a routing devDependency (maintainer-only, zero runtime
deps); 'glyphs' script added
- 8× 256×256 PNGs committed (web/public/glyphs/) — the chat turn-card's
sendPhoto URL rides the Worker's static handler; two render bugs fixed
en route: density multiplied the explicit size attrs into 2048² (dropped),
and the plate inherited the root stroke (orange frame — stroke="none")
- SVG sources verified unchanged after the run
- webhook.ts: createExportedHandler(opts) factory (offline send capture via
baseFetch); scheduled() wraps runGuidanceCronTick in ctx.waitUntil —
fail-closed unconfigured gate, paginated guidance: KV list (list_complete
respected), loadGraph awaited ONCE per tick (the shared R2 memo), per-key
getGuidanceSession → projectTurnCards → sendPhoto to envelope.chat_id ONLY
(T-06-02), every log a [guidance-cron] category, zero KV writes
- guidance-sessions.ts: GUIDANCE_KEY_PREFIX exported — the ONE key-scheme
authority (list scans derive prefix + slice ids from it)
- wrangler.jsonc: triggers.crons */1 * * * * (60 s scan, cadence in code)
- guidance-cron.test.mjs GREEN completion: GC-C3/C5/C8/C9 wire the recording
baseFetch through the factory (the header-documented seam — they defined
the recorder but never passed it); GC-C7 uses readdirSync (require is
undefined in ESM); GC-C1/C8/C9 drain inside the withConsole window (the
tick's logs fire under waitUntil)
- guidance-envelope.test.mjs: GE7 allows the GUIDANCE_KEY_PREFIX named import
- 125/125 bot tests green; bot:typecheck clean
- GC1-GC7: PURE projectTurnCards behavior — projection math, cadence table,
dead-trip gate, 4-line caption anatomy, street-bearing DEFAULT (D-12) vs
bare-verb degradation, real makeStreetAt against the committed mini-graph
- GC8: the pure-module structural law (no console, routing-workspace imports,
nameId street hop, zero KV writes)
- CS7 in commands.test.mjs pins the 21 UI-SPEC turn-card keys in en + ms
- route.ts: onDeactivated POSTs the FROZEN six-field snapshot with
keepalive (the minimize race's belt) and stores the server-minted id;
onActivated DELETEs (the cron pauses — structural) and RETAINS the id;
teardown's deleteEnvelope completes the idempotent pair; a live
envelope is never double-minted; best-effort honesty throughout (D-13)
- resume(trip): the controller computes the projection from
startedAtSec + avg speed (the cron's own math, one formula), renders
GUIDE // RESUMING + gantry + projected card, draws the rebuilt line,
arms the watch, DELETEs immediately (a resumed boot is foregrounded),
and seeds the session mid-route on the first fix through the machine's
own resuming path — synthesized terminal marks keep the arrive mark at
the line's END (a steps-less envelope model would instantly arrive)
- backAction(): the PX-01 resolver's single authority — driving →
confirm, confirm → CONTINUE, ended/route → the walk, root → close
- guidance.ts: resumingView keeps the progress math in guidance/ (RS6)
- main.ts: the COMPOSED LADDER (engine-a first, fixture fallback —
code-constructed, zero env reads), the ?g= UUID-validated reader with
the defensive envelope validation (fail-honest → honest boot), the
capability-guarded activated/deactivated wiring, the recenter
re-lock at the guidance pose, the chain-fix camera skip while driving,
and the no-double-consult resume guard
- merged suite: G9-G12 + the E-family (co-executor tests reconciled:
pre-gate probe, builder-format asserts, terminal-mark fixture)
— 146 passed, typecheck clean
- G9 minimize POST: EXACTLY the frozen six-field snapshot (id/chat_id/
created_at are server-minted), keepalive:true (the minimize race),
the Bearer header; a live envelope is never double-minted
- G10 DELETE with the stored id on activated (the cron pauses —
structural) AND at teardown (the D-14 active sweep, idempotent)
- G11 ?g= resume: GUIDE // RESUMING + gantry + projected numbers, the
watch armed, the line drawn; the first fix flips live ON_ROUTE through
the machine's own resuming path; the ?g= envelope deletes at teardown
- G12 main.ts composition gate: createHttpRoutingSource + the
'?? (await' ladder, the UUID-validated ?g= carrier, the
activated/deactivated wiring, the guidance-aware camera pose, the
no-double-consult guard, zero env reads
- route.ts grows the pump beside the Phase 5 graph: the injected watch arms
with the route draw; the first fix opens the 06-02 session; the start
gate (>= GUIDANCE_START_ALONG_M along) activates the cockpit — PX-03
close protection, [data-guidance=active], banner + card + list, camera
eased to the SNAPPED line, state=on_route token
- effects dispatch: haptics via fireHaptic, reroute-requested through the
injected RoutingSource (fail-honest catch; success = setData snap-in with
NO camera jump + list re-render; failure = calm NO REROUTE + card state
line); arrival -> the D-14 teardown (watch stop, protection release,
chrome clear, trip-end card center)
- END TRIP/BackButton -> the ONE confirm card; YES ABANDON = same teardown;
CONTINUE dismisses with guidance alive; guidancePhase exposes
none/driving/confirm/ended for the PX-01 resolver; walkBack refuses
while the confirm owns the exit and vacates the route stack on the walk
- guidanceView (guidance.ts): banner/card/list view data composed beside
the machine's own maneuver marks — route/ imports and calls it, never
re-derives (the RS6 re-pin's boundary; zero banned tokens in route/)
- G1-G8 green; RS6/RS8 re-pins green; 137 passed, typecheck clean
- G1 activation gate: sub-threshold fix keeps the Phase 5 route state;
a fix >= 30 m along mounts the cockpit (data-guidance, close protection,
banner + card, the locked camera pose, state=on_route token)
- G2 pump updates: banner distance/street from the model, ETA card,
stepping progress bar (pct = alongM/totalM)
- G3 no premature signal during the OFF_ROUTE grace; G4 REROUTING calm
swap + dash + gantry with exactly ONE source.route call under the storm
guard; G5 pending precondition + NO REROUTE fail-honest degradation;
G6 reroute success = setData snap-in, NO camera jump, gantry stop
- G7 END TRIP -> confirm -> YES ABANDON teardown (watch stop, protection
release, trip-end card, state=ended); CONTINUE dismisses, guidance alive
- G8 arrival runs the same teardown from the machine's arrival effect
- RS6 re-pinned: banned tokens only on ../guidance/ import lines (guidance
IMPLEMENTATION lives in web/src/guidance/); RS8 re-pinned: the
ARAHARAH-GUIDE token family joins the console discipline
- guidance/camera.ts: GUIDANCE_CAMERA_PADDING {320,64,64,64} / ZOOM 16 /
EASE_MS 400 / PITCH 35; easeToSnapped rides the follow controller (ONE
easing discipline) and never passes bearing — north-up, recorded call;
onRerouteApplied is the documented camera no-op (setData lives in the
route layer)
- map/follow.ts: follow(point, opts?) pose overrides spread over the
Phase 3/5 defaults — no-opts calls stay byte-identical (RS13); the
re-lock announces the mode (the recenter notch's return signal, RS12);
the originalEvent unlock law untouched
- telegram/backbutton.ts: BackAction resolver ({hidden|close|callback})
consulted per click + wire.sync() visibility re-apply (visible iff
actionable); the legacy (hasOverlay, walkBack) shape composes internally
so Phase 5 call sites and RS7 stay valid; close() only at the true root
- RS7b: the context-aware BackButton resolver walks search → routes →
guidance → (confirm) → routes → search; close() NEVER fires from a
pushed state; the wire exposes sync() for state changes
- RS11: GUIDANCE_CAMERA_PADDING/{ZOOM,EASE_MS,CAMERA_PITCH} pinned at the
UI-SPEC pose; bearing key NEVER present; onRerouteApplied moves nothing
- RS12: programmatic moves never unlock follow; a user movestart
(originalEvent) unlocks — Phase 3 free state returns
- RS13: follow(fix) without opts stays byte-identical (no pitch/zoom keys)
- fakeMap grows flyTo/on/emit recording; suite header documents the RS6/RS8
re-pins landing with the guidance wiring (tasks 2-3)
- buildGuidanceCard: GUIDE register, verbatim headline, live telemetry row (MIN / {km} KM / ETA), 4px progressbar with full aria value set + instant inline width, no-reroute state line only when degrading, ONE btn-secondary END TRIP
- buildConfirmCard: GUIDE // CONFIRM + exact en/ms privacy copy, btn-primary YES ABANDON + btn-secondary CONTINUE, guide-confirm bottom-register hook — the ONE primary CTA in guidance chrome
- buildTripEndCard: GUIDE // END, exact deletion copy, no actions
- shell.css guidance block: banner chassis + 1px separator, CSS-only strip compaction under [data-guidance], list panel + row states + lamp, progress bar — token vars only, zero motion/depth/radius/hex (theme audit clean)
- 8 hand-authored 32x32 SVGs per the UI-SPEC geometry table (3px stroke, square caps, orthogonal/45° only; uturn = machined staple, no arc)
- glyphs.ts: GLYPH_KINDS/GLYPHS via Vite ?raw (committed files are the single source) + svgHost — the ONE sanctioned innerHTML site, a static import value
- strings.ts: 18 ShellStrings keys appended in en + ms, values verbatim from the 06-UI-SPEC copywriting contract
- copy-gate: COPY1 floor 40→58 + COPY8 pins all 18 guidance keys verbatim in both locales
- upload-road-graph.mjs: wrangler-shelled maintainer tool (pre-flight 1-80MB,
round-trip verify hint); bucket araharah-graphs NOT created — R2 is not yet
enabled on the account (wrangler code 10042) — dashboard one-time activation
is the phase's user_setup item
- measure-route-cpu.mjs: 25-pair gate (corpus + seeded quadrant spread),
hrtime around routeAstar, warm-up excluded, unreachable probes reported
SEPARATELY from the routed p95, exits 1 over the 8ms budget
- Rule 1 (measured): the class set lacked *_link ramps — the graph FRAGMENTED
(7.7% of nodes in severed motorway islands; corpus pairs 'unreachable').
5 link classes added -> 311325 nodes / 677068 edges / 14.7 MB, all landmarks
in one component; enforced floor corrected 1KB -> 1MB (D-01)
- ladder (a) drop tertiary+residential: p95 17.8ms but 12/25 pairs unreachable
— REJECTED on correctness (D-03), reverted, ladder history recorded
- ladder (b) bidirectional A* (BH, Ikeda potentials, reverse-CSR WeakMap):
provably optimal (A1 625-pair sweep green), alternation balanced by heap
size (raw-top comparison starves the backward side 19501:3), reduction
signs in the standard feasible form. Measured: p95 ~38-93ms — NO GATE PASS.
The potential split halves each side's steering, cancelling the halved radius
- GATE FAIL is the honest verdict: ladder (c) — Workers Paid vs layout-v2 ALT
(still $0) vs free-plan-with-degradation — requires maintainer sign-off;
docs/ROAD-GRAPH.md carries the decision table and the fork contract
- bot/src/routing/worker-router.ts: module-scope per-env graph memo (1 R2 GET per
cold isolate, shared with the 06-07 cron arm via loadGraph), snap+A*+deriveSteps,
claim-gated 401 / 4096-cap 413 / V5 bbox 400, 200-null on every miss class,
ONE best route (no alternatives), category-only logs
- webhook.ts: /api/route arm delegating to handleRoute (405 non-POST)
- config.ts: ROAD_GRAPH: R2Bucket — first R2 binding (never a KV namespace, GE5)
- wrangler.jsonc: r2_buckets ROAD_GRAPH -> araharah-graphs with the fork law comment
- routing/src/http-source.ts: createHttpRoutingSource — slug-guard-first, fail-honest
(throw/non-200/malformed/null-body -> null), defensive RouteResult validation;
exported from index.ts; ladder note: backend #2 LIVE
- A7 re-pinned (06-01 named 06-04 as the owner of createHttpRoutingSource)
- test-side fix during GREEN: the R2 fake hands decodeGraph an exact ArrayBuffer
(Node Buffers are views; encodeGraph output is already an ArrayBuffer)
- bot 103 passed / routing 65 passed; both typechecks clean
- POST: WR-01 cap (MAX_GUIDANCE_BODY_CHARS 8192, pre/post-read double check),
hand-rolled snapshot validation (slug destinationId, bounded name, finite
metrics, integer startedAtSec, polyline6 geometry >= 2 points via
decodePolyline6) -> mintGuidanceSession with the CLAIM's chat_id — a body
chat_id is structurally ignored (T-06-02 injection probe GW4)
- GET/DELETE: resolve then OWN — envelope.chat_id === claim.chat_id else 404,
foreign and absent indistinguishable (T-06-02b); DELETE actively removes
the record (D-14's server half); non-POST/GET/DELETE -> 405
- category-only logging: [guidance] rejected: unauthorized|malformed —
literal strings, no interpolation of body/claim values (D-14)
- RP2 re-pin ships WITH the change (gate re-pin law): the total
@araharah/routing ban becomes an explicit allowlist — exactly the
polyline6 codec may enter the Worker (geometry validation); the routing
stack stays web-side; RP1 unchanged
- bot/package.json + lock: @araharah/routing workspace dep
- offline undici Request/Response pattern; claims minted through the real
/api/session path (mintSession) against the Map-fake KV
- GW8 green-by-construction (the catch-all already 404s absent ids);
ownership teeth live in GW7/GW10