diff --git a/.planning/STATE.md b/.planning/STATE.md
index 8a7157f..495df01 100644
--- a/.planning/STATE.md
+++ b/.planning/STATE.md
@@ -5,7 +5,7 @@ milestone_name: routing-engine-upgrades-and-extras
status: ready_to_plan
stopped_at: "F1 remediation applied (debug alt-potential-4x-slowdown RC-1): clean-columns-only ALT containment in routing/src/astar.ts — per-node sentinel skip removed; suite re-spec'd RED-first (A11) + new A13 mixed-column case; new committed oracle sweep measure-astar-oracle-sweep.mjs 0/200 suboptimal; CPU back in the pre-ALT band (p95 136.6 ms this host vs 1037.6 pre-fix — honest c3 FAIL vs 8 ms stands); D-03 gate green. Commits c071e20 / 2a5a0b5 / 97d6e35. NEXT: maintainer R2 upload + the SC-1 escalation decision (unchanged)"
last_updated: "2026-10-25T14:15:06.953Z"
-last_activity: 2026-10-25
+last_activity: 2026-10-26
progress:
total_phases: 4
completed_phases: 2
@@ -28,7 +28,7 @@ See: .planning/PROJECT.md (updated 2026-10-22)
Phase: 08.1
Plan: Not started
Status: Ready to plan
-Last activity: 2026-10-25
+Last activity: 2026-10-26 - Completed quick task 261026-d95: isolated ALT direction-split research (NO-GO; no production integration)
Progress: [██████████] 100%
@@ -82,6 +82,7 @@ None yet.
| # | Description | Date | Commit | Directory |
|---|-------------|------|--------|-----------|
| 261024-001 | Replace logo references with master assets | 2026-10-24 | TBD | [261024-001-logo-asset-replacement](./quick/261024-001-logo-asset-replacement/) |
+| 261026-d95 | Isolated ALT direction-split research: proved and measured, NO-GO for integration | 2026-10-26 | 9a671bd | [261026-d95-alt-direction-split-isolated-research-si](./quick/261026-d95-alt-direction-split-isolated-research-si/) |
## Deferred Items
diff --git a/.planning/quick/261026-d95-alt-direction-split-isolated-research-si/261026-d95-PLAN.md b/.planning/quick/261026-d95-alt-direction-split-isolated-research-si/261026-d95-PLAN.md
new file mode 100644
index 0000000..5c675a5
--- /dev/null
+++ b/.planning/quick/261026-d95-alt-direction-split-isolated-research-si/261026-d95-PLAN.md
@@ -0,0 +1,57 @@
+---
+gsd_plan_version: 1.0
+mode: quick
+task: Prove and measure isolated asymmetric directional ALT bidirectional search
+quick_id: "261026-d95"
+slug: alt-direction-split-isolated-research-si
+date: "2026-10-26"
+branch: research/alt-direction-split
+base_commit: ceb71c2
+autonomous: true
+---
+
+# Quick task 261026-d95: Isolated direction-split ALT research
+
+## Objective
+
+Establish whether a **sound** asymmetric, direction-split ALT bidirectional search exists for this directed ARG2 graph with sentinel fringes, and whether it actually improves the fixed-seed KL workload. This is a research sidequest on `research/alt-direction-split` only: **never edit the shipped `routing/src/astar.ts`, `routing/src/index.ts`, baseline fixture, bot/web integrations, or the separate `/home/C-Fu/araharah` checkout; never merge into main or claim the Worker budget is met without a measured passing gate.** Reference `docs/ALT-DIRECTION-SPLIT.md`, `routing/src/{astar,graph,landmark}.ts`, and the existing routing scripts/tests. No ROADMAP update.
+
+## Must-haves
+
+- A written, checkable derivation **before experimental code** separates P-1 (each directional heuristic's edge consistency) from P-2 (a valid bidirectional meeting invariant and stopping bound), including directed edges, stale heap entries, signed potentials, unreachable pairs, and `0xffff` transitions. A counterexample or impossibility result is an honest outcome; do not implement a search with an unproved stop rule.
+- Isolated experiments (only if both proofs succeed) compare seconds and reachability with Dijkstra on synthetic directed/sentinel cases and a fixed seeded real-graph sample. The shipped A1/625 test, D-03 frozen record, and original `routeAstar` remain the controls, never altered to make an experiment pass.
+- Same-pair, warmed, host-relative expansion and CPU measurements against shipped haversine fallback are reported, including p95 and the 8 ms gate status, with missing binary/runtime and inconclusive results explicitly marked **NOT MEASURED** rather than PASS. Final verdict states proof status, counterexamples, optimality violations, expansion ratio, and budget verdict; experimental code stays on this branch.
+
+## Tasks
+
+
+ task 1: Derive P-1 and P-2, including sentinel boundary
+ docs/ALT-DIRECTION-SPLIT-EXPERIMENT.md
+ First confirm branch/HEAD and clean status in this checkout; read the handoff and existing BH reductions/meet probes. Define table-indexing and quantized lower bounds without treating `0xffff` as numeric distance. For **every traversable directed edge** `u→v`, prove the forward `h_f(u) ≤ c(u,v)+h_f(v)` and backward (reverse-search) `h_b(v) ≤ c(u,v)+h_b(u)` independently; do NOT infer P-2 from these inequalities. Account for max-with-haversine, search-scoped landmark selection, and actual edges across finite↔sentinel cells; a per-node family skip is not automatically consistent. Explicitly examine whether graph-wide clean-column selection on this 0/24-clean binary makes ALT inert; propose a different rigorously proved frontier/domain mechanism only if required and possible. Derive the precise keys, bridge-meeting costs, v-independent offsets (or a conservative stopping lower bound), treatment of stale keys/reopenings, and termination when one frontier empties; algebraically show why the criterion implies no undiscovered cheaper path. Test proof claims on hand-calculated oneway ring/bridge/island counterexamples. If no correct nontrivial sentinel policy or meet rule is established, record a NO-GO counterexample/unresolved obligation and stop before coding the search.
+ test -s docs/ALT-DIRECTION-SPLIT-EXPERIMENT.md && grep -q 'P-1' docs/ALT-DIRECTION-SPLIT-EXPERIMENT.md && grep -q 'P-2' docs/ALT-DIRECTION-SPLIT-EXPERIMENT.md && grep -q '0xffff' docs/ALT-DIRECTION-SPLIT-EXPERIMENT.md
+ Document contains independently checkable inequalities and stop-rule proof or an explicit NO-GO with counterexample, including finite/sentinel cross-edge and disconnected-component cases, before any search code.
+
+
+
+ task 2: Implement branch-only experimental runner and adversarial oracle checks, conditional on proof
+ routing/scripts/experiment-alt-direction-split.mjs, routing/test/alt-direction-split-experiment.test.mjs
+ Only after task 1 establishes P-1 **and** P-2 with an executable sentinel rule: add a separate maintainer-time experiment script exporting a testable `routeDirectionSplit` and counters; do not import it from production, change shipped ASTAR, or change existing A11's ban on `landmarkFrom` in `astar.ts`. Match ARG2 semantics (row `[l*n+v]`, floor-quantized edge costs, bit0 forbidden in both traversal directions) and validate/reconstruct paths with exact traversable edge seconds. Implement exactly the proven potential pair, reduced costs, meeting updates and stop criterion; assert reduced-cost non-negativity on test graphs, fail loud for violated proof assumptions rather than substituting an unproved shortcut. Write new tests using `encodeGraph`/`decodeGraph` + `landmarkTables`: exhaustive directed ring + flagged mirrors + incoming spur, one-way bridge in BOTH travel directions, isolated anchored/unanchored components, origin/goal and interior sentinel cells, mixed clean/dirty columns, equal-cost alternatives and unreachable nulls; check every pair against independent Dijkstra, including paths' legal edges and symmetric seconds delta. Use a targeted adversarial edge where a per-node sentinel mask would violate consistency. If task 1 is NO-GO, do not create this runner/tests; document the blocked verification in the experiment record instead.
+ if grep -q '^Verdict: NO-GO' docs/ALT-DIRECTION-SPLIT-EXPERIMENT.md; then test ! -e routing/scripts/experiment-alt-direction-split.mjs; else test -s routing/scripts/experiment-alt-direction-split.mjs && npm run routing:test && npm run routing:typecheck; fi
+ Proof-qualified branch-only experiment passes adversarial oracle tests and preserves full existing suite; or NO-GO prevents unsupported code. If Node/npm unavailable, report tests NOT RUN (never green).
+
+
+
+ task 3: Measure fixed-seed oracle and paired CPU/expansions; record honest verdict
+ routing/scripts/experiment-alt-direction-split.mjs, docs/ALT-DIRECTION-SPLIT-EXPERIMENT.md
+ For a proof-qualified candidate, run the experiment against the **same** compared 200 seeded cross-metro pairs as `measure-astar-oracle-sweep.mjs` (seed `0x08f1`, oversample 3x, 12 km floor, snap misses reported), with independent Dijkstra and symmetric ±1e-6 s verdict/class checks; additionally run A1 full suite and the existing D-03 frozen-record gate unchanged. Use the seeded `0x08a1` 100-pair extended workload for paired experimental-versus-shipped searches: same snapped endpoints, warm-up printed separately, count settled expansions per direction, report misses outside routed p95, median/mean/p95 CPU, expansion ratio and host/Node/version/graph SHA-256; alternate run order or repeated rounds to reduce JIT/thermal order bias. Shipped `routeAstar` with 0/24 clean columns is the **haversine-only control** for the present binary; instrument it only via an isolated copy/runner if needed and verify bit-identical costs before comparison. The original `measure-route-cpu.mjs --extended` budget gate is a separate shipped-control run and a FAIL exit is a measurement, not an instruction to weaken the gate. The gitignored ARG2 graph is available read-only at `/home/C-Fu/araharah/routing/data/kl-roadgraph.v1.bin`: if missing locally, link into this checkout's gitignored `routing/data/` only after verifying no existing path and binary ARG2; never write the target or any file in the other checkout. If unavailable/undecodable or Node/npm missing, record NOT MEASURED; never claim a speedup or PASS from synthetic data or 0 active landmarks. Report proof+oracle+expansion+p95 outcomes with a GO/NO-GO verdict and next-step recommendation confined to a later separately approved phase. Do not merge/integrate.
+ test -s docs/ALT-DIRECTION-SPLIT-EXPERIMENT.md && test -z "$(git diff --name-only ceb71c2 -- routing/src/astar.ts routing/src/index.ts routing/test/fixtures/alt-baseline.json .planning/ROADMAP.md)" && test "$(git branch --show-current)" = research/alt-direction-split
+ Document prints the oracle and paired workload results with provenance and explicit gate statuses, or explains exactly why a proof or measurement blocked execution; no production/baseline/main-checkout changes.
+
+
+## Verification and guardrails
+
+At execution, ensure Node/npm are actually available (this planning shell currently reports `node: command not found`; do **not** pass an absent-runtime gate). Use `npm run routing:test`, `npm run routing:typecheck`, `node routing/scripts/measure-optimality-gate.mjs`, and `node routing/scripts/measure-route-cpu.mjs --extended` where available; record expected budget-gate FAIL honestly. Existing `measure-astar-oracle-sweep.mjs` measures shipped search, **not** the experiment: inject the candidate into the exported `sweepOracle` core or reproduce its exact seeded pair-selection/oracle contract in the isolated runner, labeling each separately. A missing real graph must never be counted as a 0/200 success (the shipped sweep's SKIP exits 0). Verify scope at end with `git status --short`, `git branch --show-current`, and `git diff --name-only ceb71c2`; inspect any untracked experiment files separately. No production deployment, no main merge.
+
+## Outcome
+
+Completion means either a proved and measured branch-only search with 0 optimality violations and transparent steering/cost numbers, **or** a precise NO-GO identifying the failed proof/benchmark. The 8 ms Worker gate remains FAIL unless directly measured to pass on a representative free-plan host; a local CPU win alone cannot retire the budget concern.
diff --git a/.planning/quick/261026-d95-alt-direction-split-isolated-research-si/261026-d95-SUMMARY.md b/.planning/quick/261026-d95-alt-direction-split-isolated-research-si/261026-d95-SUMMARY.md
new file mode 100644
index 0000000..474aace
--- /dev/null
+++ b/.planning/quick/261026-d95-alt-direction-split-isolated-research-si/261026-d95-SUMMARY.md
@@ -0,0 +1,52 @@
+---
+phase: quick
+plan: 261026-d95
+subsystem: routing
+tags: [ALT, bidirectional, directional, oracle, benchmark]
+requires: [ARG2 landmark tables, shipped routeAstar]
+provides: [proved pair-domain ALT, isolated research runner, NO-GO verdict]
+affects: []
+tech-stack:
+ added: []
+ patterns: [pair-restricted landmark family selection, independent A* frontier stop]
+key-files:
+ created: [docs/ALT-DIRECTION-SPLIT-EXPERIMENT.md, routing/scripts/experiment-alt-direction-split.mjs, routing/test/alt-direction-split-experiment.test.mjs]
+ modified: []
+decisions: [Do not integrate candidate because paired p95 regresses despite reduced expansions]
+metrics:
+ completed: 2026-10-26
+---
+
+# Quick Plan 261026-d95: Direction-split ALT isolated research summary
+
+An independently consistent asymmetric ALT bound can be used on a query-restricted sentinel-free path domain with a conservative single-frontier A* stopping criterion, but this isolated implementation is **NO-GO**: p95 516.778 ms versus original shipped 118.923 ms on paired host measurements.
+
+## Tasks and commits
+
+1. `57fd5ed` — Proved P-1 and P-2 separately, including sentinel boundary and disconnected-path handling before writing experiment code.
+2. `92fc213` — Added isolated experimental search and adversarial exhaustive Dijkstra-oracle tests (no production imports).
+3. `9a671bd` — Added seeded real-graph oracle, paired original/clone measurement, expansion instrumentation, and recorded exact results/NO-GO in the experiment document.
+
+## Validation and verdict
+
+- New and existing routing suite: **85 passed, 0 failed**, including unchanged shipped A1/625. Typecheck passed.
+- Fixed-seed 200-pair real graph: 182 routes, 18 unreachable, 120 rejected snap probes, **zero** suboptimal, oracle-mismatch or class-break cases.
+- Extended paired workload: 53 routed/100 drawn, 41 snap misses, 6 unreachable. Two alternate-order rounds. Experiment/isolated shipped clone expansions **0.709×**; experiment/original shipped p95 **4.35× slower**. Original shipped p95 118.923 ms; experimental p95 516.778 ms.
+- D-03 unchanged frozen gate passed. Shipped extended CPU gate **FAILED** at p95 127.933 ms > 8 ms. Representative free-plan Worker CPU: **NOT MEASURED**.
+- Full provenance and proof details: `docs/ALT-DIRECTION-SPLIT-EXPERIMENT.md`. Neither this branch nor the read-only binary symlink was deployed or merged.
+
+## Deviations from Plan
+
+**[Rule 3 - Blocking]** Local `node_modules` was initially absent (L2 bundle marker failed and `tsc` was unavailable); ran `npm ci --ignore-scripts --no-audit --no-fund`, then tests and typecheck passed. No lockfile changes.
+
+**[Rule 1 - Bug]** The initial diagnostic assertion reversed the backward edge inequality in code; corrected to compare the reverse search's `h_b(v)-h_b(u)` on `v→u`. Initial run failed loud on a real edge; rerun passed the 200-pair oracle and new tests.
+
+**[Rule 2 - Measurement completeness]** The shipped search does not export expansion counters. Created and automatically removed a source-identical temporary clone with settled counters injected and measured the unmodified original separately; compared every route's seconds across the two controls. No production file modified.
+
+## Known Stubs
+
+None in the search. Shipped-original settled expansions are deliberately **NOT MEASURED** directly; the source-identical instrumented clone supplies an explicitly labeled proxy rather than fabricated numbers. Worker-host CPU remains NOT MEASURED.
+
+## Self-Check: PASSED
+
+Verified all three experiment files exist, commits `57fd5ed`, `92fc213`, `9a671bd` exist, branch is `research/alt-direction-split`, and protected production/baseline/roadmap files differ neither from `ceb71c2` nor this task's commits.