Files
arah2/.planning/phases/08-alt-landmark-preprocessing-routing-backend-v2/08-03-SUMMARY.md
T

9.9 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
08-alt-landmark-preprocessing-routing-backend-v2 03 routing
alt
landmarks
astar
bidirectional
potentials
sentinel
typed-arrays
structural-pins
tdd
phase provides
08-alt-landmark-preprocessing-routing-backend-v2 (plan 08-02) the ARG2 RoadGraph fields (landmarkCount/landmarkQuantumS/landmarkTo/landmarkFrom) the potential consumes, and landmark.ts's table builder the A-suite fixtures flow through
phase provides
06-turn-by-turn-guidance-live-driving the proven BH skeleton (reductions, balanced alternation, meet probes, stop rule, real-seconds reconstruction) this plan leaves byte-identical, and A1's 625-pair Dijkstra-equivalence seal
ALT steering live inside routeAstar — per-search Float64Array(L) constant tables in quanta (0xFFFF → NaN = search-scoped landmark drop), lazy per-node max over the four triangle families with RAW u16 sentinel compares, haversine max-fallback (Pattern 3 containment)
the A-suite extended to A1–A11 — A9 island sweep (169 pairs, anchors pinned in one component), A10 search-scoped-skip sweep (16 anchorless pairs), A11 structural pin (landmark-table reads in CODE, one sentinel spelling)
routing/test/rollout.test.mjs — RO1 upload-format-agnostic + RO2 one-decode-path structural pins
the D-01 rollout locks enforced suite-side (T-08-08), not customary
the optimality seal re-proven under ALT — A1's exhaustive 625-pair Dijkstra-equivalence sweep green with the potentials live
08-04 (build script landmark stage feeds these tables at KL scale)
08-05 (CPU gate + optimality campaign measures THIS search)
docs retirement record (c3 class evidence)
added patterns
ALT max-rule: h = max(haversine bound, best triangle bound) — max of two consistent admissible heuristics stays consistent + admissible; sentinel-flooded nodes degrade to exactly the pre-ALT behavior
search-scoped skip law: landmark drop decisions live ONLY in the per-search constant tables (0xFFFF stored as NaN); per-node sentinel cells just skip their ℓ — never a per-node ℓ-mask mid-max (max-of-Lipschitz consistency)
raw-u16-before-float sentinel discipline: `tv === 0xffff` on the Uint16Array read, one spelling (never the decimal), so the sentinel can never masquerade as a finite bound
created modified
routing/test/rollout.test.mjs
routing/src/astar.ts (potential() + its init + doc-comments ONLY — every other function pinned)
routing/test/astar.test.mjs (case index A1–A11, buildIslandFixture helper, A9/A10/A11)
The per-direction ℓ-loop factored into one local `bound()` helper (plan allows executor naming/shape) — the two cache-miss branches mirror through it instead of duplicating the family loop; the pf tail stays byte-identical
A9/A10 written to PASS at RED as baseline-equivalence seals and to stay green as containment seals after the swap (the plan's TDD shape); A11 is the RED gate
A9's anchor set is HAND-PINNED ([0, 8] inside component A) through landmarkTables, never derived — the island precondition (every B cell 0xFFFF in both families) is asserted as a fixture law before the sweep
Structural pins for rollout locks: RO1/RO2 copy A8's comment-stripping grep shape so a doc mention can never satisfy a format-agnosticism law
Seconds-only equivalence assertions for steering changes (never node-path equality) — D-03's tie law carried into every new case
SC3
SC4
~9min 2026-10-25

Phase 8 Plan 08-03: ALT Potentials + Rollout Pins Summary

ALT steering is live in routeAstar — h_f/h_b are now max(ALT triangle bounds, haversine) over the ARG2 landmark tables inside the byte-identical BH skeleton, with A1's 625-pair Dijkstra-equivalence sweep re-proving optimality under ALT, dedicated island/skip containment cases, and RO1/RO2 pins locking the upload/router seams format-agnostic (routing 79/79 + bot 126/126 + both typechecks green).

Performance

  • Duration: ~9 min (10:55–11:04 UTC)
  • Started: 2026-10-25T10:55:12Z
  • Completed: 2026-10-25T11:04:00Z
  • Tasks: 2/2 (task 1 with full RED→GREEN gate commits)
  • Files modified: 3 (1 created, 2 modified)

Accomplishments

  • The entire runtime change of Phase 8 landed in one function: routeAstar's potential() now derives h_f/h_b from graph.landmarkTo/landmarkFrom/landmarkQuantumS — four per-search constant tables hoisted in quanta (0xFFFF written as NaN drops that landmark for the WHOLE search), then a lazy per-node max over the four triangle families (toward-goal A/B, toward-origin A/B) with RAW u16 sentinel compares before any float conversion, max-combined with the existing haversine bound. The (h_f−h_b)/2 combination, reductions, balanced alternation, meet probes, stop rule, and real-seconds reconstruction are byte-identical — the survey's (πf−πr)/2 is what p_f already was.
  • Optimality re-proven under ALT: A1's exhaustive 25×25 = 625-pair brute-force Dijkstra-equivalence sweep is green with the potentials live, plus A9 (169-pair island sweep: A-internal pairs with real ALT bounds, B-internal pairs on the haversine fallback, 72 cross pairs → null) and A10 (16 anchorless-component pairs — all families dropped at search scope, still exactly optimal).
  • The D-01 rollout locks are mechanical: new rollout.test.mjs pins upload-road-graph.mjs's KEY/BUCKET + zero format tokens in comment-stripped code (RO1), and worker-router.ts's unchanged GRAPH_KEY + exactly ONE decodeGraph call + no version branch (RO2) — the campaign (08-05) cannot silently grow format awareness (T-08-08 enforced, not customary).
  • Full battery green at the final commit: routing:test 79/79 (A1 seal + A9/A10/A11 + RO1/RO2 + untouched L/G/A/P/R/S suites), bot 126/126 — the FIRST commit where the RT trunks and guidance-cron run with ALT potentials reading real tables on their ARG2 corridor graphs — and routing+bot typechecks clean. git diff --stat on worker-router.ts and upload-road-graph.mjs is empty.

Task Commits

Each task was committed atomically (task 1 carried its RED→GREEN gates):

  1. task 1: ALT potentials in routeAstar + the containment A-cases — 92b97fc (test, RED: A11 failing for the right reason, A9/A10 baseline-equivalent) → ddd2f3c (feat, GREEN)
  2. task 2: Rollout pins (RO1/RO2) + the full-battery seal — 8fac68b (test)

Files Created/Modified

  • routing/src/astar.ts — ALT per-search constant tables + bound() helper + potential() swap + ALT doc paragraphs (module header + routeAstar BH block; Ikeda history intact); NO other function touched, no new imports
  • routing/test/astar.test.mjs — case index A1–A8 → A1–A11; buildIslandFixture (two-component synthetic whose tables flow through the ONE landmark module); A9 island sweep, A10 search-scoped-skip sweep, A11 structural pin (landmark tokens in comment-stripped CODE, one sentinel spelling, A8's no-Map law unchanged)
  • routing/test/rollout.test.mjs — created: RO1/RO2 structural pins in the harness's zero-dep shape

Decisions Made

  • One bound() helper instead of a duplicated ℓ-loop: the plan's sketch marks shape/naming as the executor's; both cache-miss branches mirror through the same allocation-free loop, keeping the family logic in exactly one place while the const value = (hf - hb) / 2 tail stays byte-identical.
  • A9/A10 pass at RED by design: they assert seconds-only Dijkstra equivalence, which the pre-ALT haversine implementation already satisfies — they are baseline-equivalence at RED and containment seals at GREEN; A11 (structural) is the RED gate and fails for exactly the right reason ("must reference landmarkTo in code").
  • Fixture anchors pinned, not derived: buildIslandFixture(anchors) takes the anchor array and routes it through landmarkTables — the island precondition (every component-B cell is the 0xFFFF sentinel in both families) is asserted as a fixture law inside A9 before any routing assertion.

Deviations from Plan

None - plan executed exactly as written. (One in-task compliance edit: the GREEN comment initially cited the sentinel's decimal value; the plan's own acceptance grep 65535 = 0 caught it before the commit — reworded, no behavior change, contained in ddd2f3c.)

TDD Gate Compliance

Task 1 ran full RED→GREEN with separate commits: 92b97fc (test — A11 FAIL verified for the right reason, 76/77 passing) BEFORE ddd2f3c (feat — 77/77). No gate skipped; no refactor commit needed (the swap landed clean).

Issues Encountered

  • None beyond the in-task comment reword above. The full battery passed on its first run after each gate.

User Setup Required

None - no external service configuration required.

Next Phase Readiness

  • 08-04 (build script): the preprocessing stage now has its live consumer — build-road-graph.mjs still encodes WITHOUT landmarks until its stage lands; once it emits ARG2 the real binary steers with these exact potentials.
  • 08-05 (campaign): the search-side surface is final; the CPU gate (p95 ≤ 8) and the D-03 optimality gate measure THIS code. The D-02 remediation knob (raise L, rebuild) touches build parameters only — the reductions/stop rule are pinned untouched by A1/A8/A11 and RO1/RO2.
  • Known state: the real KL binary on disk is still ARG1 → decodes null → router-pending (designed, D-01) until 08-04/08-05 rebuild + re-upload; the committed fixtures all carry tables, so every suite surface runs ALT live.

Phase: 08-alt-landmark-preprocessing-routing-backend-v2 Completed: 2026-10-25

Self-Check: PASSED

All 3 claimed files exist on disk; all 3 task commits (92b97fc, ddd2f3c, 8fac68b) exist in git history. Final battery at 8fac68b: routing:test 79/79, bot 126/126, routing:typecheck + bot:typecheck clean; git diff --stat bot/src/routing/worker-router.ts routing/scripts/upload-road-graph.mjs empty.