48 Commits
Author SHA1 Message Date
araharah-executor bcab4b9999 feat(08.1-02): re-pin measurement gates for ARG3 and extend the rollout locks (GREEN)
- The optimality gate's decode-failure message names ARG3 and the rebuild
  command (node routing/scripts/build-road-graph.mjs); the frozen D-03
  constants (OPTIMALITY_EPSILON_PCT = 0.1, REQUIRED_BASELINE_ARG_VERSION
  = 1) and the immutable alt-baseline.json record are untouched.
- The oracle sweep's graph-missing (SKIP) and decode-failure wording names
  the ARG3 binary; the seeded 200-pair symmetric-compare constants and the
  three violation classes are unchanged.
- RO1/RO2 ban the ARG3 magic 0x41524733 in the upload script's and the
  Worker's comment-stripped code: the one-path laws now cover the CURRENT
  format, not just the retired ones. The Worker keeps exactly one
  decodeGraph call, no GRAPH_VERSION, no magic, no === 2.
- measure-route-cpu.mjs is untouched here by design: its LADDER HISTORY
  gains the CH rung only once the measured numbers exist (task 3).
2026-10-26 07:48:28 +08:00
araharah-executor 68bbe80894 test(08.1-02): pin ARG3-honest gate wording and frozen measurement constants (RED)
MG1/MG2 fail against the current scripts: the optimality gate and the
oracle sweep still describe the binary-under-test in ARG2-era terms and
their decode-failure messages do not name ARG3 or the rebuild command.
MG3 pins the CPU gate's budget/sample constants exactly-once (already
true — stays green).
2026-10-26 07:47:30 +08:00
araharah-executor 58a5d406a3 feat(08.1-02): replace the ALT build stage with measured CH preprocessing (GREEN)
- The build no longer imports landmark.ts (deleted in 08.1-01) and has no
  --landmarks knob: the compacted directed edges feed contractGraph (the
  ONE CH construction authority) and the tables encode through the single
  encodeGraph authority as the ch: block (never landmarks:).
- Any contraction/encode throw names the CH preprocessing stage and exits 1
  BEFORE any write — collect-then-write keeps the previous binary intact
  (T-08.1-10).
- The build prints the measured CH stats block (D-08/D-09): contracted
  nodes, shortcuts + ratio per node, witness searches + settle-budget hits,
  chRank bytes, shortcut bytes, wall-clock over contraction + encode, and
  total binary bytes. No ARG3 payload ceiling exists (D-08) — the enforced
  1-80 MB D-01 envelope is unchanged and still fails before any write.
- The stale ARG2-era 30 MB forecast advisory is retired with the layout it
  forecasted; the measurement itself is the record.
- --check becomes a pure decode+facts tool for any valid ARG3 (the
  committed mini fixture included): prints chShortcutCount, shortcut
  ratio, chRank length; the envelope appears as an advisory line — the
  enforced gates stay in the build path.
2026-10-26 07:46:41 +08:00
araharah-executor 61e2bfe070 test(08.1-02): add failing maintainer-build CH pins (RED)
BS1-BS5 pin plan 02 task 1's behavior before it exists: the build script
must be landmark-free in stripped code, run ONE contractGraph stage into
the ch: encode input, print the full measured CH stats block (D-08/D-09),
keep the 1-80 MB D-01 envelope single and unchanged, and decode the
committed ARG3 fixture green via --check with CH facts. BS1/BS2/BS3/BS5
fail against the current landmark-era script (which cannot even load —
landmark.ts was deleted in 08.1-01).
2026-10-26 07:43:16 +08:00
araharah-executor 4ca7a71d15 feat(08.1-01): rebuild all fixtures and bot graph builders through the ARG3 path
- mini-graph-arg2.bin: the frozen ARG2-era bytes preserved once as the
  D-12 decode-rejection vector (never regenerated — the arg1 precedent)
- build-mini-graph.mjs: landmark stage out, CH stage in — contractGraph
  over the 25-node grid (41 shortcuts, 1.64/node, 0 budget hits) with
  fail-loud invariants: total-order rank, grid shortcut band, upward
  shortcuts, overlay-exact constituent weights (f64 replay, f32 compare),
  strong connectivity; deterministic ARG3 bytes
- graph.test.mjs: committed-fixture G4 added (ARG3 magic/version, 25
  nodes, 80 edges, rank 25, >=1 shortcut, ARG2 vector -> null); G7
  restored (full ARG3 pin)
- astar.test.mjs: A1-A6 restored — the 625-pair Dijkstra equivalence,
  oneway law, deriveSteps, depart/arrive, classifyTurn all green against
  the CH query on the committed ARG3 fixture
- snap.test.mjs: S1-S6 restored on the ARG3 fixture; S3's synthetic
  graph rebuilt as the ARG3 ch-block star
- webhook.test.mjs: landmarkBlock -> chBlock (contractGraph); corridor
  gains the fast nonstop chord (a pure line starves to zero shortcuts);
  sparse star keeps node ids 0-hub; RT9's split carrier is now two
  disconnected decodable stars (the honest A\* miss)
- guidance-cron.test.mjs: GC6b's 2-node graph becomes the lowest-id-mid
  3-node star (a 2-node graph cannot carry a valid shortcut)
- routing 87 passed / bot 126 passed; routing+bot+web typechecks green
2026-10-26 07:30:15 +08:00
araharah-executor 06624bb688 feat(08.1-01): ARG3 codec + uphill CH query — ALT deleted, one search path (GREEN)
- graph.ts: ARG3 layout (magic 0x41524733, version 3, chShortcutCount
  u32 @60, reserved @64/@68) with the CH suffix chRank ++ shortcut CSR;
  fail-honest decode (ARG1/ARG2 -> null, chShortcutCount 0 -> null,
  exact-size before any allocation, 4-byte alignment load-bearing);
  loud ch-block encode validation
- ch-query.ts: routeCH — bidirectional uphill search (strict rank filter,
  forward originals+shortcuts, backward reverse views incl. shortcuts),
  edge-ref meet probe, iterative via-unpacking (edge-aware: a parallel
  original edge is never expanded as a shortcut; DERIVE prefers the
  cheaper of original/shortcut), seconds re-summed from the unpacked
  original-edge path. STOP RULE: min(topF, topB) >= mu — the classical
  sum rule is unsound under the rank filter (Q1 caught it: 36 vs 24)
- astar.ts: routeAstar validates + delegates every request to routeCH;
  ALT/BH internals, clean-column memo, landmark tokens DELETED (D-04);
  classifyTurn/deriveSteps untouched
- landmark.ts + landmark.test.mjs deleted (D-05); index.ts additively
  exports contractGraph + CH constants + routeCH
- snap.test.mjs: S3's encode moved to the ARG3 ch block (3-node star —
  a 2-node graph can carry no valid shortcut); committed-fixture S-cases
  suspended until task 3 (Rule 3: same pattern as G7/A1-A6)
- routing suite: 86 passed, 0 failed; typecheck clean
2026-10-26 07:15:28 +08:00
araharah-executor d3f0b4577f test(08.1-01): re-pin codec + search suites for ARG3 and the CH query (RED)
- graph.test.mjs: G1-G11 re-pinned for the ARG3 layout (chShortcutCount
  @60, CH suffix); G7 suspended until task 3 regenerates the fixture
- astar.test.mjs: committed-fixture cases A1/A2/A4/A5/A6 suspended;
  A3 re-pinned on an in-memory ch block; A8 extended to ch-query.ts;
  A11 becomes the D-04 one-search-path pin; ALT-era A9/A10/A12/A13 fold
- ch-query.test.mjs: Q1-Q5 (625-pair equivalence, directed oneway law,
  original-edge seconds, island nulls, structural deletion) + G1-G3
  in-memory ARG3 pins; all fixtures through contractGraph + encodeGraph
2026-10-26 06:48:24 +08:00
araharah-executor f75dc9e8c6 feat(08.1-01): implement CH contraction core — ordering, contraction, overlay witness, CSR (GREEN)
- contractGraph: greedy edgeDifference + λ·deletedNeighbours priority,
  lazy PQ with id tie-breaks, rank = contraction position (total order)
- overlay-only witness search: contracted node + candidate absent,
  bounded by candidate distance and max(60, 4·localDegree) settles
- directed shortcut emission (ascending from, then to), via midpoints,
  f32 CSR; dominated-insert guard; explosion tripwire fails loud at 4×N
- deterministic: no PRNG/map-order; identical input -> identical output
- 25-node grid: 41 shortcuts (1.64/node), 0 budget hits
2026-10-26 06:39:09 +08:00
araharah-executor a3e2c3253f test(08.1-01): add failing CH construction core tests (RED)
- C1 total order / C2 shortcut weights / C3 upward shortcuts
- C4 hand-computed 3-node fixture (literal rank + shortcut set)
- C5 overlay-only witness law (contracted node cannot witness)
- C6 explosion tripwire (hand-traced 42-shortcut cascade on 9 nodes)
- C7 determinism + bit0 oneway law
2026-10-26 06:29:32 +08:00
araharah-executor e77bbe9f72 fix(08): WR-04 — quantized weight validated at the i32 boundary before the Int32Array store
- new named constant LANDMARK_I32_WEIGHT_CEILING (0x7fffffff) in
  landmark.ts: a seconds/quantumS quotient at or past 2^31 would wrap
  NEGATIVE on the Int32Array store, silently bypassing the
  LANDMARK_MAX_QUANTA throw in dijkstraPass (a negative contribution
  never exceeds it) and — at a -1 wrap — becoming the 0xFFFF sentinel;
  prepare() now fails loud at the table-build entry, naming the edge,
  the ceiling and the fix (raise landmarkQuantumS)
- 'nothing is clamped, ever' now holds at the storage boundary;
  validation is per-edge at build entry — the search hot path stays
  allocation-free and validation-free
- L5b regression vector: 3e10 s edge (3e11 quanta) throws in both
  landmarkTables and farthestPointAnchors; just-under-ceiling
  (2147483646) still fails via the documented 65000 law; ordinary
  weights untouched
2026-10-25 22:35:47 +08:00
araharah-executor 11e55c11bc fix(08): WR-01 — oracle-sweep optimality compare is symmetric (|Δ| both directions)
- sweepOracle: Math.abs(deltaS) > ORACLE_EPSILON_S replaces the one-sided
  'seconds > optimal + eps' check — a result FASTER than the Dijkstra
  oracle (the traversal-law-break signature, e.g. a oneway relaxed) is
  now a violation, stamped ORACLE-MISMATCH, never a pass
- worstDeltaPct tracks MAGNITUDE not sign — a -40% law break moves it
- pass gate: suboptimal === 0 && oracleMismatch === 0 && classBreaks === 0
- header gate description + exit codes updated: the check is |Δ| in both
  directions; GATE FAIL names both violation classes; GATE PASS reads
  0/N |Δ| violations
- row-level signed Δ printout unchanged (sign/direction reporting kept)
2026-10-25 22:35:37 +08:00
araharah-executor 97d6e35c3a feat(08): committed 200-pair real-graph Dijkstra-oracle sweep — the optimality pin D-03's fixed corpus cannot be
measure-astar-oracle-sweep.mjs (maintainer-time, route-corpus law: exported
core sweepOracle + CLI guard, print-the-measurement, honest exit codes):

- FRESH seeded cross-metro pairs via measure-optimality-baseline.mjs's
  exported generateCrossMetroPairs core — seed 0x08f1, deliberately NOT
  the D-03 corpus seed 0x08a1, so this sweep never measures the corpus
- compared-pair law: one 3x-oversampled draw, consumed in order until 200
  COMPARED pairs (reachable + null-vs-null unreachable both compare;
  snap misses counted and printed; same binary + seed => same set) —
  random bbox coordinates are ~20% off-road and an unsnappable pair
  cannot exercise the search
- brute-force unidirectional Dijkstra oracle (label-setting, heap, the
  shared oneway traversal law) on the SAME snapped node pair
- gate: 0 suboptimal (epsilon 1e-6 s — f64 summation-order noise floor,
  A1's epsilon); class-breaks (one side routes, other doesn't) violate
- honest skip when the gitignored binary is absent (exit 0, SKIP printed)

First run on the fixed engine: 200 compared (182 routed, 18 unreachable),
0 SUBOPTIMAL, worst delta +0.000% — GATE PASS. The pre-F1 engine measured
1/194 suboptimal on this pair shape (bench7, debug session).
2026-10-25 22:11:02 +08:00
araharah-executor 2a5a0b5b6a fix(08): F1 — ALT landmark containment is clean-columns-only; per-node sentinel skip removed (RC-1)
Debug session alt-potential-4x-slowdown, root cause RC-1 (LIVE correctness
bug): bound()'s per-node sentinel skip (tv === 0xffff -> drop landmark l)
varied the active landmark family set PER NODE, so the toTable max lost
cross-edge consistency across edges leaving the 6,285-node disconnected
island (2.02% of cells) — shipped routeAstar returned suboptimal seconds
on 1/194 fresh random real-graph pairs vs the Dijkstra oracle (worst
single-edge family variance 1,026 s). D-03's fixed corpus was green on
sampling luck.

The fix (reverseFor precedent, in-constraint):
- per-graph WeakMap memo cleanColumnsFor: clean[l] = 'to-column l has ZERO
  sentinel cells' — O(L*n) sequential row scans once per graph/isolate
- per-search active list activeL = clean columns only; bound() loops the
  active list with NO per-node sentinel branch; the constant-table
  goal/origin NaN checks are retained (belt)
- on the current binary (0/24 clean columns) potentials degrade to EXACTLY
  haversine — the designed sound fallback; the pre-ALT CPU band returns
- ALT stays live and tested on strongly connected fixtures (mini-graph
  0/2 dirty columns, A12 ring all-clean, new A13 mixed subset case)
- LANDMARK_SENTINEL_U16 named constant; sentinel compares at setup scope
  only; pure-module law untouched

BH stop rule, reductions, balanced alternation, meet probes, real-seconds
reconstruction: UNTOUCHED. F2 (transposed table) explicitly out of scope.

Battery: routing 81/81 (A11 RED pins now green, A13 new), bot 126/126,
routing+bot typecheck clean.
2026-10-25 22:07:07 +08:00
araharah-executor c071e205e4 test(08): RED — re-spec ALT suite to the F1 clean-columns law (debug alt-potential-4x-slowdown)
- A9: island fixture re-pinned as ALL-DIRTY (every to-column holds a
  B-node sentinel -> every landmark drops search-scoped -> the whole
  fixture runs the haversine fallback); the old 'real ALT bounds live in
  A' claim is gone — it described the per-node sentinel skip RC-1 removed
- A10: mechanism comment updated to the containment law (active list
  empty at search scope, never a per-node l-mask)
- A11: structural pin rewritten to the F1 bound() shape — cleanColumnsFor
  memo + activeL list must exist in code; inline '=== 0xffff' sentinel
  compares BANNED (RC-1's exact shape); named-constant law pinned —
  FAILS ON SHIPPED CODE (the RED gate)
- A12: re-sealed as the ALT-ACTIVE counterpart — all to-columns clean
  (strongly connected ring + spur), pinned by table scan
- A13 (new): mixed clean/dirty columns via a one-way-bottleneck twin-ring
  fixture — the subset-active-list branch neither A9 nor A12 exercises;
  64-pair Dijkstra equivalence + honest nulls

Fails today by design: A11 (4 pins) against the shipped per-node skip.
2026-10-25 22:05:55 +08:00
araharah-executor 149636ce0a fix(08-05): D-03 optimality gate green — fromTable families removed from the ALT potential
Task 1: the D-03 gate script (measure-optimality-gate.mjs) reads the frozen
pre-ALT record, re-routes the same coordinate-pinned pairs on the current
ARG2 binary, and gates on seconds-equality (±0.1%) + verdict-class
preservation — never on node paths (equal-cost ties are documented behavior).

Rule-1 deviation the gate forced on its first run: routeAstar returned
SUBOPTIMAL real-graph routes (x038: 1234.6s vs the 1214.8s Dijkstra optimum;
x045: 1475.5s vs 1460.6s) — the fixture sweep could not see it. Root cause:
the fromTable bound d̂(ℓ,t) − d̂(ℓ,v) is one-directional Lipschitz (its u-side
term needs the REVERSE edge; a oneway does not provide one — the anchor
reached node 264611 126.8s faster than its own 1.49s upstream neighbour
264610), and the shared Ikeda average p = (h_f − h_b)/2 is consistent only
when every family inside h_f/h_b is two-sided. The toTable bound
d̂(v,ℓ) − d̂(t,ℓ) rides stored traversable edges in BOTH directions; it alone
joins the haversine now. Stop rule, reductions, meet probes, reconstruction:
untouched. landmarkTables/build verified EXACT (0 mismatches vs independent
integer Dijkstras, both rows, all 24 anchors).

- measure-optimality-gate.mjs: exported core + CLI guard (route-corpus
  pattern); epsilon mirror + argVersion asserts precede any measurement;
  per-pair rows, extract-drift WARNING (never a re-record), honest exit law
- astar.ts: potential() consults landmarkTo only; doc-comments carry the
  one-directional-Lipschitz law and the x038/x045 evidence
- astar.test.mjs: A11 re-pinned (landmarkFrom must NOT appear in the
  comment-stripped search — re-adding it trips the pin); A12 oneway-ring
  sweep added (directed reach asymmetry stays Dijkstra-equal on every pair)

Battery: routing 80/80, bot 126/126, both typechecks green.
D-03 gate: GATE PASS — 53/53 routed pairs equal within ±0.1% (max |Δ| 0.005%),
verdict classes preserved (6 unreachable + 41 unsnappable, 0 re-snapped).
2026-10-25 19:54:24 +08:00
araharah-executor 698fdf4689 feat(08-04): ALT preprocessing stage in the build tool — landmark tables through the ONE module
- The stage between edge compaction and encode feeds the graph's edges to
  landmark.ts (farthestPointAnchors + landmarkTables + landmarkCoverage) —
  the script quantizes and implements nothing itself (single-authority law)
- D-02 scaling rule L = clamp(round(N/13000), 16, 32) (~24 at KL's 311k
  nodes) with a --landmarks <n> measured knob (positive int, hard cap 128,
  parsed before --check)
- Honest gates before any write: quantum-ceiling throw -> fail with the
  raise-quantum hint (Pitfall 5); per-anchor coverage >= 0.9 (the SAME
  fraction for any L — the override cannot lower it, T-08-11); anchor
  shortfall fails loud instead of encoding a weaker ALT
- encodeGraph receives landmarks: { quantumS, nodes, to, from } — the one
  ARG2 authority; no local fallback encode
- Stats gate prints L/quantum/coverage min-mean/table bytes/sentinel totals
  BEFORE the size gates; --check mirrors the facts from the decoded binary
  (landmarkCount/quantum/anchors/coverage/sentinels, no network)
- A1 ladder history gains rung (c2): EXECUTED in this preprocessing stage
2026-10-25 19:10:53 +08:00
araharah-executor 8fac68bca7 test(08-03): rollout pins RO1/RO2 — the D-01 locks enforced suite-side (full battery green)
- RO1 upload-format-agnostic: upload-road-graph.mjs keeps KEY
  'kl-roadgraph.v1.bin' + BUCKET 'araharah-graphs'; comment-stripped code
  contains ZERO format tokens (landmark/encodeGraph/decodeGraph/ARG1/ARG2
  magics/GRAPH_VERSION) — the migration is byte-shipping of the same key,
  forever (A8 grep-shape)
- RO2 one decode path: worker-router.ts keeps GRAPH_KEY unchanged, exactly
  ONE decodeGraph call in the loadGraph flow, no version-conditional branch
  (GRAPH_VERSION / magics / '=== 2' absent) — an undecodable binary flows
  to the existing null -> router-pending path (D-01 at the consumer)
- full battery at this commit — the FIRST where routeAstar consults real
  landmark tables on the bot suite's ARG2 corridor graphs: routing 79/79
  (A1 seal + A9/A10/A11 + RO1/RO2), bot 126/126 (RT trunks + cron),
  routing+bot typechecks clean; worker-router.ts and upload-road-graph.mjs
  untouched (git diff --stat empty)
2026-10-25 19:03:08 +08:00
araharah-executor ddd2f3c093 feat(08-03): ALT potentials inside the proven BH skeleton — GREEN
- routeAstar's ONLY change: the h_f/h_b bodies become max(ALT triangle
  bounds, haversine) — per-search Float64Array(L) constant tables in quanta
  (0xFFFF written as NaN = search-scoped landmark drop), lazy per-node
  max over the four triangle families with RAW u16 sentinel compares
  BEFORE any float conversion, haversine max-fallback on sentinel-flooded
  nodes (Pattern 3 containment)
- the (h_f - h_b)/2 combination, reductions, balanced alternation, meet
  probes, BH stop rule, and real-seconds reconstruction are byte-identical
  (research Pattern 1 — the survey's (pf-pr)/2 is what p_f already is)
- no Map/Object allocations (A8 green), no new imports, one search path
  (L >= 1 is the decodeGraph guarantee, D-01)
- A1's 625-pair Dijkstra-equivalence sweep re-pinned under ALT: the
  standing optimality proof; A9 island + A10 skip laws sealed; A11
  structural pin green
- module header + routeAstar doc gain the ALT paragraph (c-metric
  exactness, sentinel laws, Ikeda history intact)
2026-10-25 19:02:21 +08:00
araharah-executor 92b97fc97f test(08-03): ALT containment cases — A9 island sweep + A10 search-scoped skip + A11 structural pin (RED)
- A9: two-component synthetic (3x3 grid + 4-node path), anchors HAND-PINNED
  inside component A only via landmarkTables; full 169-pair sweep asserts
  seconds-only Dijkstra equivalence (A-internal with ALT live, B-internal
  on the haversine fallback, 72 cross pairs -> null)
- A10: origin AND goal inside the anchorless component — all families drop
  at SEARCH scope, the 16 B-internal pairs still route Dijkstra-equal
- A11: comment-stripped astar.ts must reference landmarkTo/landmarkFrom/
  landmarkQuantumS in CODE; one sentinel spelling (0xffff, never 65535);
  A8's no-Map law unchanged — FAILS now (RED: the potential is still
  pure haversine)
- case-index doc-comment extended A1-A8 -> A1-A11; buildIslandFixture
  helper routes fixture tables through the ONE landmark module
2026-10-25 19:00:56 +08:00
araharah-executor 32a00b5b0b feat(08-02): ARG2 codec — one version, one decode path (G-suite GREEN)
graph.ts versioned IN PLACE (no second codec): GRAPH_MAGIC 0x41524732,
GRAPH_VERSION 2, HEADER_SIZE 72 (72%8==0 keeps f64 views aligned);
header gains landmarkCount u32 @60 (the old pad), landmarkQuantumS f32
@64, reserved u32 @68; the landmark suffix (u16 toTable, u16 fromTable,
u32 landmarkNodes) extends layoutFor's total arithmetic — exact-size
law covers the variable suffix BEFORE any view allocation (T-08-01).
D-01 fail-honest: ARG1 bytes / version!=2 / landmarkCount=0 / hostile
quantum / size mismatch all decode null (committed mini-graph-arg1.bin
is the standing rejection vector). GraphInput.landmarks REQUIRED and
loud-validated (T-08-04). RoadGraph gains the five landmark fields
(Plan 08-03's ALT potentials consume them).

Fixture regenerated as ARG2 through the SAME encode authority: the
builder gains the tiny real landmark stage (L=2, anchors [0,18],
quantum 0.1s, coverage 1.0 — identical bytes every re-run).

Rule-3 call-site updates forced by the required-landmarks law (missed
by the plan's files list): astar.test A3 + snap.test S3 synthetics
carry inert hand landmark blocks. Fixture regen pulled forward from
task 3 so this commit's own battery is green (74 passed, 0 failed).
2026-10-25 18:48:23 +08:00
araharah-executor 34d96b0cdb test(08-02): ARG2 codec G-suite — RED gate (G3/G5/G7/G8 re-pins + new G9-G11)
Re-pins: G3 consumes the frozen mini-graph-arg1.bin as the standing ARG1
rejection vector (D-01 one-path law) + v1/v3 tamper; G5's zero-copy flip
moves to byte 72 (the ARG2 header end); G7 expects the regenerated ARG2
fixture (landmarkCount >= 1, quantum 0.1, L*N tables, anchor self-cells
0); G8 re-pins the exported constants to 0x41524732/2.

New: G9 table round-trip (four landmark properties, sentinel-is-DATA,
zero-copy u16 views); G10 encode-validation matrix (9 named-throw cases,
T-08-04); G11 decode rejection (landmarkCount=0 refused even when the
byte size exactly matches the L=0 layout — D-01/A5 — plus the monster
landmarkCount=2e6 arithmetic rejection, T-08-01).
2026-10-25 18:46:00 +08:00
araharah-executor 5b7a1300c2 feat(08-02): implement the pure landmark compute core — L-suite GREEN
farthestPointAnchors + landmarkTables + landmarkCoverage over the
ĉ metric: edge weights floor-quantized once (Math.floor(seconds/q)),
exact integer Dijkstras (Int32 labels, binary heap, lazy deletion),
0xFFFF sentinel, 65000-quantum loud overflow. Traversal law mirrors
astar.ts verbatim: bit0 edges never relaxed in EITHER direction.

Test-vector corrections caught at GREEN (expectations were wrong,
implementation was right):
- L4: rows index by anchor POSITION (row-major [l*N+v]), not node id
- L6: the c-metric farthest node from corner 0 is interior node 18
  (297q: interior hops cost 2x perimeter), not corner 24 (264q) —
  verified against an independent brute-force Dijkstra
2026-10-25 18:40:17 +08:00
araharah-executor 1bf413b3ac test(08-02): L5 overflow vector becomes a 3-node path
A 2-node graph has no degree>=2 candidates, so farthestPointAnchors
returns empty before any Dijkstra runs and never reaches the overflow
throw. Node 1 on a 3-node path is a candidate, so the selection pass
actually exercises the law.
2026-10-25 18:37:01 +08:00
araharah-executor c3a31ae7ee test(08-02): add failing landmark-core suite (L1-L6) — RED gate
Hand-computed vectors for the pure landmark compute core: deterministic
degree-filtered farthest-point anchors, exact integer quanta
(floor(2.55/0.1)=25, two edges=50), 0xFFFF sentinel + self-cell laws,
oneway asymmetry, the 65000-quantum overflow throw, and the 5x5-grid
corner-to-corner 264-quanta vector with coverage 1.0.
2026-10-25 18:35:15 +08:00
araharah-executor 477961addd feat(routing): 08-01 task 3 — --extended D-04 verdict on the CPU gate (100 cross-metro pairs, seed 0x08a1 shared with the baseline); default zero-arg mode byte-compatible, budget-audit 19/19 2026-10-25 17:15:02 +08:00
araharah-executor 643df1a07b feat(routing): 08-01 task 2 — pre-ALT optimality baseline: recorder + committed 100-pair record (D-03 anchor, measured before ARG2 lands, immutable) 2026-10-25 17:13:09 +08:00
araharah-executor 0fca2e08db feat(routing): 08-01 task 1 — freeze ARG1 fixture bytes as mini-graph-arg1.bin (the v1 decode-rejection vector); provenance in the builder 2026-10-25 17:11:41 +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 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 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
araharah-executor 6c0880b4db feat(05-02): offline corpus tolerance gate — measurePairs core + CLI + in-suite RT1-RT10 (GREEN)
- routing/scripts/route-corpus.mjs: the shared measurement core (exported
  measurePairs) + CLI reporter in the gazetteer-corpus.mjs shape — one
  measurement, two reporters, no drift
- RT1 corpus size 10..20; RT2 schema + RT2b mechanical D-12 proof (every
  committed origin equals its gazetteer landmark within 1e-4 deg); RT3 route
  shape; RT4 probe exclusion (national-museum never a destination); RT5
  haversine-vs-summary band [0.85, 1.10] + bbox+0.05; RT6 speed [1.0, 30] m/s;
  RT7 codec round-trip per route; RT8 ODbL header surfaces; RT9 gz budget
  (measured 16576 B / 102400 B); RT10 alternatives floor (8 pairs / floor 4)
- fully offline: zero network in the measurement path (T-05-05); pair ids and
  measurements printed, never geometry strings (D-15); fixed escalation
  ladder on failure (--only repair -> regenerate -> re-gate)
- suite: 35 passed, 0 failed; npm run routing:corpus exits 0; typecheck clean
2026-10-24 05:19:55 +08:00
araharah-executor 63ef408197 test(05-02): add failing offline corpus tolerance gate suite RT1-RT10 (RED)
- one test per check, mirroring search/test/corpus.test.mjs: the suite imports
  measurePairs from routing/scripts/route-corpus.mjs IN-PROCESS (never spawns
  the CLI) — one measurement, two reporters, no drift
- RED: the measurement core does not exist yet -> 10 named ERR_MODULE_NOT_FOUND
  failures; the committed dataset itself is already green material (task 1)
- fully offline by construction: zero network in the measurement path (T-05-05)
2026-10-24 05:18:16 +08:00
araharah-executor 4e89cff552 feat(05-02): pinned golden-pair corpus + OSRM-demo fetch tool + populated committed dataset (GREEN)
- routing/test/fixtures/golden-pairs.json: the hand-authored 15-pair pinned
  corpus (D-02/D-12) — origins AND destinations are gazetteer landmarks,
  klBbox + 100 KB gz budget + probe id + alternatives floor pinned
- routing/scripts/fetch-route-fixtures.mjs: the maintainer build tool
  (overpass-topup.mjs pattern) — D-12 boundary in the header, pre-flight
  public-coordinate proof against the gazetteer (1e-4 deg), mandatory
  User-Agent, 1200 ms inter-request delay, one retry on network/5xx,
  collect-then-write, --only=<pairId> single-pair repair merge
- routing/src/data/route-fixtures.json: 15 real OSRM-demo pairs committed
  (1-3 verbatim polyline6 routes each; 8 pairs carry >= 2 alternates),
  ODbL header fields preserved (T-05-06)
- loader-env L3 armed (RED commit 01b0ed6) + C6 re-pinned from the empty-seed
  state to the populated corpus (05-01 documented both as 05-02 handoffs)
- npm delegates: root routing:fixtures; routing fixtures + corpus scripts
2026-10-24 05:17:01 +08:00
araharah-executor 01b0ed6884 test(05-02): tighten loader-env L3 to require pair 1 serving at pinned origin (RED)
- L3 previously pinned the 05-01 empty-seed state (honest null at the pinned origin)
- it now asserts the default fixture source SERVES pair 1 (kl-tower-to-kl-sentral)
  at its pinned public origin and resolves honest null ~300 m away (outside the
  200 m tolerance, D-03)
- RED until plan 05-02 populates the committed fixture dataset
2026-10-24 05:14:15 +08:00
araharah-executor 3e0c5e3eb4 feat(05-01): geo math + fixture RoutingSource backend + public API
- geo.ts: haversineM + deriveCumulativeDistanceM (D-07 snapped-progress field)
- fixture-source.ts: backend #1 — ORIGIN_TOLERANCE_M=200 matching law,
  honest-null pending semantics (D-03), defensive pair skip at index build,
  lazy memoized index (LAW 1), static JSON import (LAW 2), zero
  logging/storage/network (LAW 3, D-12)
- index.ts: named-export public surface, subpath-with-extension import law
- loader proven in three environments (bare Node 24, esbuild, Vite-family)
2026-10-24 05:03:07 +08:00
araharah-executor 0599ffe14f test(05-01): add failing fixture-source + loader-env suites (F1-F8, L1-L3)
- synthetic injected datasets only — never the network, never the committed file
- F3 pins the 200 m haversine tolerance boundary; F6 the defensive pair skip
- F7 the lazy-index source gate (LAW 1); L2 the esbuild inline marker
2026-10-24 05:02:08 +08:00
araharah-executor 4acb878c33 feat(05-01): polyline6 codec (pure, zero-dependency)
- standard encoded-polyline algorithm at 1e6 precision, double math
  (no int32 shifts) so no coordinate range wraps silently
- decode THROWS on truncated varints — never partial/NaN points (T-05-02)
- round-trip law encode(decode(s)) === s proven on all vectors incl.
  the external live-OSRM geometry (RESEARCH Finding 1)
2026-10-24 05:01:13 +08:00
araharah-executor 9b66f90a4b test(05-01): add failing polyline6 codec vectors (P1-P8)
- hand-derived vectors from the plan's <polyline_vectors> block
- external live-OSRM demo geometry (RESEARCH Finding 1) as ground truth
- P7 pins the truncated-varint refusal law (T-05-02)
2026-10-24 05:00:32 +08:00
araharah-executor c92a955272 feat(05-01): RoutingSource contract + day-one route model + fixture seed schema
- types.ts: the D-01 backend-ladder seam (fixture -> wasm-router -> valhalla),
  D-03 null contract documented on the interface, D-07 day-one fields
  (RouteStep typed + RouteGeometry.cumulativeDistanceM, GUID-05/06 obligation)
- route-fixtures.json: committed EMPTY seed with the ODbL header
  (license/attribution/notice, T-05-06) — plan 05-02 populates it
2026-10-24 04:59:45 +08:00
araharah-executor 69b6a20350 test(05-01): scaffold routing workspace with failing contract suite
- fifth npm workspace @araharah/routing (buildless TS, search/ precedent)
- root delegates routing:test / routing:typecheck / routing:corpus
- C1-C6 RED: contract gates fail while src/types.ts + seed are absent
2026-10-24 04:59:17 +08:00