Commit Graph
307 Commits
Author SHA1 Message Date
araharah-executor 17bb950042 feat(06-08): the seven guidance capture legs + the DSGN-02 guidance gallery
- 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
2026-10-24 21:30:01 +08:00
araharah-executor d0d5a7dc27 feat(06-08): the ?drive= fixture-replay knob — the D-16 browser leg's fix source
- ?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
2026-10-24 21:06:17 +08:00
araharah-executor fca2a904d0 fix(06-08): the D-09 confirm card survives a live fix — renderCockpit guards the card rebuild
- 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
2026-10-24 20:59:46 +08:00
araharah-executor 001c8ac8b0 docs(06-07): complete the cron turn-cards plan — SUMMARY
- continuation session: adopted the dead executor's in-flight task-2 GREEN,
  finished + committed it atomically (ad61229), then executed task 3 (9c50fb0)
- 125/0 bot tests, 65/0 routing tests, typechecks clean, 8 committed PNGs
- STATE.md and ROADMAP.md intentionally untouched (orchestrator-owned)
2026-10-24 19:55:47 +08:00
araharah-executor 9c50fb033e feat(06-07): committed 8-glyph PNG set rasterized from the app's SVG sources (D-12)
- 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
2026-10-24 19:53:09 +08:00
araharah-executor ad612299ca feat(06-07): scheduled() cron tick wired — factory, loadGraph street memo, crons trigger (GREEN)
- 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
2026-10-24 19:49:00 +08:00
araharah-executor 37ffefe11c docs(06): A1 decision — c3 now / c2 next milestone; D-12 street-bearing ratified 2026-10-24 19:36:54 +08:00
araharah-executor 620a982e9e test(06-07): failing scheduled() tick suite GC-C1..GC-C9 (RED)
- due-card send captured through createBot(env, {baseFetch}): envelope
  chat_id only, glyph URL, HTML parse mode, ?g= deep link
- R2 mini-graph fake → fixture street; R2-null fake → bare-verb card, send
  still fires; non-due → 0 sends; fail-closed unconfigured; pagination;
  throwing read skipped; failed send continues
2026-10-24 17:11:59 +08:00
araharah-executor f07021e271 feat(06-07): PURE projectTurnCards + makeStreetAt + the 21 turn-card copy keys (GREEN)
- cron.ts: linear progress projection (clamped), stateless 180 s cadence
  (due = nowSec % 180 < 60), dead-trip gate, classifyTurn-authority next-turn
  detection over consecutive-leg bearings, 4-line HTML caption anatomy
- D-12 street by DEFAULT: makeStreetAt hops snapToGraph → matched segment's
  nameId → nameAt (never the node index); snap miss → bare-verb degradation;
  matched-unnamed → cardStreetUnnamed
- strings.ts: cardAction* (8) + cardActionBare* (8) + cardStreetUnnamed +
  cardEtaTemplate + cardHonesty + cardOpenButton, en + ms verbatim
- GC1-GC8 + CS7 green: 116 passed, 0 failed; bot:typecheck exit 0
2026-10-24 17:07:58 +08:00
araharah-executor ed0e0d0c8e test(06-07): failing turn-card cron suite GC1-GC8 + CS7 card-copy gate (RED)
- 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
2026-10-24 17:03:49 +08:00
araharah-executor c73c96db3c docs(06-06): complete the guidance pump plan — camera, BackButton graph, envelope flows 2026-10-24 15:34:46 +08:00
araharah-executor d5e104b2e9 feat(06-06): envelope flows + composed ladder — minimize POST, resume GET, trip-end DELETE (GREEN)
- 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
2026-10-24 15:31:51 +08:00
araharah-executor 6448e31a29 test(06-06): failing envelope-flow suite G9-G12 — minimize POST/resume GET/trip-end DELETE + the composed-ladder gate (RED)
- 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
2026-10-24 15:19:35 +08:00
araharah-executor 14e8dfcdd9 feat(06-06): the guidance pump — start gate, effects dispatch, cockpit chrome, silent reroute (GREEN)
- 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
2026-10-24 15:16:56 +08:00
araharah-executor 0316be485b test(06-06): failing guidance-pump suite G1-G8 + RS6/RS8 re-pins (RED)
- 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
2026-10-24 14:58:29 +08:00
araharah-executor 2f12c41060 feat(06-06): the D-10 locked-follow guidance camera + the context-aware BackButton resolver (GREEN)
- 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
2026-10-24 14:47:50 +08:00
araharah-executor 77b62da111 test(06-06): failing camera-law + PX-01 full-walk gates — RS7b walk, RS11 pose, RS12 unlock, RS13 no-opts byte-identity (RED)
- 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)
2026-10-24 14:47:39 +08:00
araharah-executor 7dcaa00ea3 docs(06-05): complete the guidance cockpit surface plan — glyphs, banner/cards builders, capability guards 2026-10-24 14:24:03 +08:00
araharah-executor da42c7793b feat(06-05): capability guards — haptics + close protection + optional webapp members + RS10/BA9 gate bumps (GREEN)
- fireHaptic: the three D-08 cues (selectionChanged / impactOccurred medium / notificationOccurred success) via ?. chains; silent no-op without the API; header carries the no-haptic-on-reroute law
- engage/releaseCloseProtection: PX-03 layers gated BEFORE each call — isVersionAtLeast("7.7") body-swipe, ("6.2") native-close net; no-throw on capability-less clients (T-06-06)
- webapp.ts: HapticFeedback / vertical-swipes / closing-confirmation / isActive join as OPTIONAL members only — existing fakes untouched
- RS10 floor 16→24; BA9 input list += web/src/guidance (69507 / 204800 gz, printed)
2026-10-24 14:21:21 +08:00
araharah-executor 47b1524472 test(06-05): failing capability-guard suite GS13-GS14 — haptic cue routing + layered close protection under version gates (RED) 2026-10-24 14:19:44 +08:00
araharah-executor 79836f0a31 feat(06-05): guidance/confirm/trip-end card builders + the token-only shell.css guidance block (GREEN)
- 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)
2026-10-24 14:18:21 +08:00
araharah-executor f0931d6195 test(06-05): failing guidance-card suite GS8-GS12 — evolved card + confirm/trip-end cards + token-only shell.css block scan (RED) 2026-10-24 14:15:12 +08:00
araharah-executor 432f33a983 feat(06-05): the maneuver banner + collapsible list builders + the machine-blink gantry (GREEN)
- buildGuidanceBanner: five-slot discipline over every state — GUIDE // NEXT|REROUTING|RESUMING|NO REROUTE register, 48x48 plate w/ 32x32 committed glyph, distance+unit/'—', street or calm-state copy, LIST/CLOSE toggle; root <button> with aria-expanded/controls/label
- buildManeuverList: transparent tap-out layer + labelled card region (id = aria-controls target), NEXT/FUTURE/PAST rows, real-text streets, aria-hidden 24x24 glyphs
- startGantryBlink/stopGantryBlink: WeakMap-keyed ~500ms duty cycle, idempotent start, stop clears
- GS7 whitespace-verbatim comparison fixed (trailing newline in committed files)
2026-10-24 14:12:59 +08:00
araharah-executor a60443a48d test(06-05): failing guidance-surface suite GS1-GS7 — five-slot banner, list row states, gantry blink, sanctioned-innerHTML + copy gates (RED)
- Node-side ?raw loader twin so tests exercise the committed glyph strings verbatim
- banner/list behavioral cases via the minimal document fake (theme.test pattern)
2026-10-24 14:11:54 +08:00
araharah-executor 0023ab3086 feat(06-05): the 8-glyph committed maneuver set + glyphs.ts + the 18 guidance strings keys
- 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
2026-10-24 14:08:35 +08:00
araharah-executor 46acbf4a53 docs(06-04): complete the engine-A server-surface plan — graph built, /api/route live, A1 escalation surfaced
- 3 tasks: build tool + real 14.7MB KL graph; TDD /api/route + backend #2 +
  RP re-pins; upload/measure/fork-docs + the A1 ladder to its decision point
- gates: routing 65/65, bot 103/103, both typechecks clean
- escalations inside: A1 CPU gate FAIL (ladder a rejected on correctness,
  b sound-but-net-zero, c needs maintainer sign-off); R2 bucket awaits
  one-time dashboard activation (user_setup)
- STATE.md / ROADMAP.md untouched (orchestrator-owned)
2026-10-24 13:58:31 +08:00
araharah-executor ea9584d163 feat(06-04): R2 upload + A*-CPU measurement gate + the A1 ladder executed to its decision point
- 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
2026-10-24 13:56:18 +08:00
araharah-executor 020eb92058 feat(06-04): /api/route engine-A arm + http-source backend #2 — Bearer-gated, honest-null, RP re-pinned (GREEN)
- 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
2026-10-24 13:27:02 +08:00
araharah-executor 0abe64e734 test(06-04): failing http-source suite H1-H8 + /api/route block RT1-RT11 + RP1/RP2 re-pin (RED)
- routing/test/http-source.test.mjs: backend #2 client seam — slug-guard-first,
  fail-honest on throw/non-200/malformed/null-body, defensive RouteResult shape
- webhook.test.mjs RT block: 401/413/400 classes, out-of-bbox origin (V5),
  200-null on unknown dest / absent graph / corrupt binary / snap miss / A* miss,
  happy path (engine-a, ONE option, steps) with the 1-GET isolate-memo probe
- route-privacy re-pin (06-04's own gate law): RP1 = claim-bound local routing
  (getClaimByToken, no fetch/proxy, arm wired to worker-router, no routing hosts),
  RP2 = workspace allowlist @araharah/{search,routing}/* subpaths only
2026-10-24 13:22:51 +08:00
araharah-executor d51fd8b47b feat(06-04): road-graph build tool — Overpass extract → pinned CSR binary with the D-01 stats gate
- maintainer-time repo tool (nothing in bot/web/routing src imports it): drivable-class
  Overpass extract (Pitfall 1 filter), nodes deduped by rounded coord, oneway/-1/roundabout
  flag law, maxspeed-tag overrides over class defaults, name-pool interning
- bbox derived mechanically from the committed corpus (gazetteer entries + golden pairs
  ± 0.05 deg, printed) — Open Q 4's pinning
- collect-then-write + ENFORCED size gate (>1 MB, <=80 MB, exit 1 outside) + advisory
  30-80 MB band warning; --check mode decodes and re-prints the gate, zero network
- routing/data/.gitignore: *.bin is an ODbL-derived build artifact — forks build their own
- real KL graph built: 277514 nodes / 598396 edges / 21447 names / 13.1 MB (gate PASS,
  band warning printed for review)
2026-10-24 13:19:07 +08:00
araharah-executor c96f186da6 docs(06-03): merge continuation-pass verification into the plan summary
- session-continuation note (late-flush observation + post-flush gate
  re-verification by the continuation agent)
- plan-agnostic phrasing for the future worker-router RP2 widening
2026-10-24 13:10:18 +08:00
araharah-executor 3f06fdc281 docs(06-03): complete the guidance-envelope service + /api/guidance plan 2026-10-24 13:09:20 +08:00
araharah-executor 371b2a0ad7 docs(06-03): complete guidance envelope service + /api/guidance plan
- 2/2 tasks TDD RED->GREEN: envelope service (0cfa0bd/c87dc7d) +
  /api/guidance endpoints (212aa57/7875ed4)
- GE4-GE7 + RP2 re-pinned with their invalidating changes; GE1-GE3 frozen
- 90/90 bot tests green; typecheck clean
2026-10-24 13:08:05 +08:00
araharah-executor 7875ed4d94 feat(06-03): /api/guidance POST/GET/DELETE — Bearer-claim gated, TTL-only service beneath (GREEN)
- 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
2026-10-24 13:06:25 +08:00
araharah-executor 212aa57c14 test(06-03): guidance endpoint suite GW1-GW11 — 401/413/400 classes, claim-owned chat (T-06-02 injection probe), own-vs-foreign GET/DELETE, 405 (RED)
- 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
2026-10-24 13:04:17 +08:00
araharah-executor c87dc7dc14 feat(06-03): guidance envelope service — TTL-only mint/get/delete beneath the frozen shape
- mintGuidanceSession: crypto.randomUUID id, claim-derived chat_id arg,
  ONE put at guidance:<id> with same-line expirationTtl (GE1/PG1)
- getGuidanceSession: UUID-shape guard BEFORE any KV touch (V5), exact
  4+6-field + type + finite/range validation (the location-pin defensive
  read law) — corrupt records read as null, never reach the cron
- deleteGuidanceSession: active trip-end sweep (D-14's server half)
- module header: the types-only note becomes the shape-frozen + service-
  owns-every-write law; envelope/snapshot interfaces byte-identical (GE2)
- no new namespace (GE5), no new Env field (GE6) — the chat_sessions
  binding is handed in structurally
2026-10-24 13:03:19 +08:00
araharah-executor 0cfa0bde38 test(06-03): re-pin GE4/GE7 to the live service + behavioral envelope suite + PG1 storage list (RED)
- GE1/GE2/GE3 UNCHANGED in meaning (TTL 7200, 4+6 field freeze, inline snapshot)
- GE4 re-pinned: types-only token ban -> the module must EXPORT mint/get/deleteGuidanceSession
- GE7 re-pinned: total consumer ban -> named-imports-only of the service surface
- GE5/GE6 stand (exactly one kv namespace; no Env guidance field)
- GS1-GS5 behavioral: TTL'd mint, roundtrip, 7-class defensive null read,
  UUID key-guard without KV touch (V5), active delete (D-14 server half)
- PG1 storageModules now covers kv/guidance-sessions.ts (same-line TTL law)
2026-10-24 13:02:28 +08:00
araharah-executor a9041fb527 docs(06-02): complete the guidance-brain plan (replays + ETA + throttle)
- SUMMARY: 3/3 tasks, 5 commits, 100/100 web tests, replay-proven D-04
  machine, honest ETA, D-15 throttle; deviations + self-check recorded
- STATE.md / ROADMAP.md deliberately untouched (orchestrator-owned)
2026-10-24 12:53:16 +08:00
araharah-executor a45f8a507e feat(06-02): D-15 distance-throttled watchPosition wrapper + throttle truth table
- shouldAcceptFix: accept when first fix, >=10 m moved, or >=5 s elapsed
  (whichever first) — the pure accept rule over haversineM
- createGuidanceWatch(geo, onFix): high-accuracy watchPosition
  (maximumAge: 0), six-field Fix normalization (null accuracy/heading,
  source webview), rejected fixes die in the wrapper, idempotent stop()
  clearing the watcher id (T-06-05b's privacy-minimal trip end)
- replay suite T1-T3 + R12b: truth table, recorded-options structural
  gate, feed-only-accepted proof, stop idempotence, module purity scan
2026-10-24 12:50:49 +08:00
araharah-executor 299827a469 feat(06-02): honest ETA — per-axis EMA + independent display deadbands + arrival clock (GREEN)
- updateEta(prev|null, remainingS, remainingM): numbers-only signature
  (D-07 structural — no Fix can enter); first update seeds directly
- EMA alpha 0.25/fix per axis; display refreshes only past its axis
  deadband (+-1 min time / +-5% remaining, axes independent)
- composeEtaClock: 24-hour HH:MM instrument format (local wall clock)
- suite E1-E8 green: seed, jitter-holds-display, real-drop-updates,
  independent axes, deadband symmetry, pinned constants, purity gate
2026-10-24 12:48:29 +08:00
araharah-executor 65852940cc test(06-02): add failing honest-ETA suite E1-E8 — EMA + deadband + arrival clock (RED) 2026-10-24 12:47:13 +08:00
araharah-executor ad1fd3059c feat(06-02): THE pure D-04 guidance state machine + forward-only projection + named constants (GREEN)
- createGuidanceSession + stepGuidance: the thresholds+grace reroute machine
  (idle/on_route/off_route/rerouting/resuming/no_reroute) with accuracy-aware
  threshold max(35, 2xacc) capped 100, 3-consecutive-fixes + grace gates,
  missed-turn shortened grace (3s), storm guard with off_route re-request
  after expiry, honest no_reroute degradation
- projectAlongRoute: forward-only cos(lat)-scaled projection, cumulative
  remaining (D-07), haversineM deviation (one distance authority)
- once-per-edge D-08 effect stream: approach 300 m / maneuver impact /
  arrive + arrival at 25 m (D-14); reroute-applied re-arms, measures against
  the NEW model only (Pitfall 6)
- replay suite R1-R12 green: corridor/excursion/missed-turn/jitter drives,
  storm guard mechanics, self-heal, structural purity gate; 88/88 web tests
2026-10-24 12:46:06 +08:00
araharah-executor b879e56bb1 test(06-02): add failing D-16 drive replay suite R1-R12 + four committed drive fixtures (RED)
- guidance-replay.test.mjs: corridor/excursion/missed-turn/jitter replays,
  storm guard, shortened grace, haptic edges, start gate, projection
- fixtures derived from golden pair central-market-to-merdeka-118
  (ODbL attribution in each _notice; Fix-shaped streams per D-16)
2026-10-24 12:35:32 +08:00
araharah-executor 9456a870fe docs(06-01): complete engine-a data-plane plan
- SUMMARY: CSR codec + snapping + typed-array A* (57/57 routing tests,
  625/625 Dijkstra equivalence), 2 documented deviations (header alignment
  padding, compass turn convention), TDD gate sequence intact
2026-10-24 12:16:37 +08:00
araharah-executor e34c2296f5 feat(06-01): typed-array A* + turn classifier + step derivation + public exports (GREEN)
- routeAstar: allocation-free hot loop — binary heap of node indices over
  preallocated typed arrays (grown by doubling), typed-array g/closed/
  came-from, on-demand cached haversine/maxSpeed heuristic (admissible +
  consistent); oneway-reverse edges never relaxed; unreachable -> null
- A1 proves A* == brute-force Dijkstra on ALL 625 mini-graph pairs
- classifyTurn: the one turn authority (compass convention — negative
  delta = left; plan's (0,40)->slight-left case contradicted its own
  (0,-90)/(0,90) pins, documented deviation); TURN_* constants exported
  for plan 07's cron projection
- deriveSteps: splits at non-straight bearings or name changes; steps
  carry kind/name/distanceM + polyline6; depart-first, arrive-last
- index.ts: engine-A named exports + ladder note updated — backend #2 is
  now 'engine-a' (D-01 supersedes the wasm-router note; Valhalla port
  infeasible + geojson-path-finder rejected, engine B = post-v1
  evolution, D-02); createHttpRoutingSource deliberately absent (plan 04)
2026-10-24 12:14:37 +08:00
araharah-executor 6adfd86ade test(06-01): add failing A* equivalence + step-derivation suite A1-A8 (RED)
- A1: exhaustive 625-pair A*-vs-Dijkstra equivalence (the RESEARCH-mandated
  correctness gate); A2 oneway detour; A3 honest-null unreachable
- A4/A5 deriveSteps: L-path turn kinds + name/distance/polyline6; depart/
  arrive invariants; A6 classifyTurn pins (compass convention, documented)
- A7 index.ts public surface (createHttpRoutingSource deliberately absent);
  A8 no-Map structural gate
2026-10-24 12:13:00 +08:00
araharah-executor 2e73068af5 feat(06-01): point-to-edge GPS-fix snapping with memoized grid index (GREEN)
- snapToGraph: bbox+margin guard first (honest null = router-pending,
  D-03), then 3x3 coarse-grid neighborhood (0.002 deg cells, WeakMap
  memo per RoadGraph — LAW 1 lazy memoize, O(local) not O(n))
- projection in cos(lat)-scaled degree space (Pitfall 8); returned
  distance is haversineM; result carries the best segment's nameId
  (null for the unnamed sentinel) for plan 07's cron street-hop
- oneway-reverse edges stay snap-visible (direction is A*'s law);
  gridBuildCount() instrumentation kept internal to the workspace
2026-10-24 12:10:46 +08:00
araharah-executor 72703d26ec test(06-01): add failing GPS-fix snap suite S1-S6 (RED)
- Exact-node hit, mid-edge closer-endpoint projection, nameId resolution
  (named + unnamed-null halves), bbox-margin honest miss, oneway direction
  ignored, WeakMap grid memoization (build-counter + structural greps)
2026-10-24 12:09:18 +08:00
araharah-executor 1ce35907d5 feat(06-01): CSR graph codec + committed mini-graph fixture + RouteStep.kind (GREEN)
- graph.ts: decodeGraph/encodeGraph over the pinned little-endian CSR
  layout; header magic+version+exact byte-size validation BEFORE any view
  allocation (T-06-03/T-06-03b fail-honest null); zero-copy typed-array
  views; street-name pool with UNNAMED_NAME_ID sentinel
- header padded 60 -> 64 bytes so f64 views are 8-byte aligned — unaligned
  Float64Array throws RangeError, making plan-literal offsets incompatible
  with the plan's own zero-copy law (documented deviation; field
  order/content/endian unchanged; consumers inherit via encodeGraph)
- build-mini-graph.mjs + committed mini-graph.bin: hand-built 5x5 grid,
  25 nodes, 80 directed edges, 3 named streets, exactly ONE oneway pair,
  two speed classes (60/30 km/h) — the A* ground truth (G7 pins it)
- types.ts: RouteStep gains optional kind (8 turn kinds) — Engine A
  populates it (06-01); fixture-world steps stay empty arrays (D-10)
2026-10-24 12:07:17 +08:00
araharah-executor 53740944b8 test(06-01): add failing CSR graph codec suite G1-G8 (RED)
- Pinned-layout gates: round-trip, bad magic/version/truncated -> null,
  zero-copy view mutation, name pool, committed mini-graph fixture pin
- Each case lazy-imports ../src/graph.ts — ERR_MODULE_NOT_FOUND is the
  red state (fixture-source.test.mjs pattern)
2026-10-24 12:05:16 +08:00