19 KiB
phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, duration, completed
| phase | plan | subsystem | tags | requires | provides | affects | tech-stack | key-files | key-decisions | duration | completed | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 08-alt-landmark-preprocessing-routing-backend-v2 | 05 | routing |
|
|
|
|
|
|
|
~50min | 2026-10-25 |
Phase 8 Plan 08-05: Measurement Campaign & Record Truth Summary
The D-03 optimality gate is committed and GREEN (53/53 routed pairs equal the frozen pre-ALT record within ±0.1%) — but only after it caught the four-family ALT steering returning suboptimal real-graph routes; the sound configuration's CPU campaign measured HONEST GATE FAILs (25-route p95 152.788 ms, extended 185.692 ms vs the 8 ms budget; the pre-committed L=32 ladder rung measured worse), so the c3 class is NOT retired — every record (budget gate law, BUDGETS, KNOWN-LIMITATIONS, ROAD-GRAPH) now carries the quoted post-ALT truth and the escalation is handed to the maintainer.
⚠️ Escalation to the maintainer (read this first)
The phase's success criteria land as: SC-2 (optimality) PASS — SC-1 (CPU within budget) FAIL — SC-3 (c3 retirement) NOT TAKEN (the evidence forbids it). Three gates decide, and the decision inputs are:
GATE PASS: D-03 optimality — 53/53 routed pairs equal within ±0.1%, verdict classes preserved (100/100 record pairs; 6 unreachable + 41 unsnappable preserved, 0 re-snapped)
GATE FAIL: p95 152.788 ms exceeds the 8 ms budget (A1) [25-route CI gate, n=23, L=24, 2026-10-25]
GATE FAIL: p95 185.692 ms exceeds the 8 ms budget — D-04 extended verdict [100 cross-metro pairs, n=53, L=24, 2026-10-25]
GATE FAIL: p95 182.725 ms / 204.499 ms [the ladder's L=32 probe — worse, stopped per plan]
The options on the table (all documented in the records): (1) direction-split potentials with a re-proven bidirectional meet rule — search-skeleton work Phase 8's own laws forbid; (2) Contraction Hierarchies (the Phase-6 deferral); (3) Workers Paid — rejected by the $0 law, reversal needs sign-off; (4) keep c3 as the designed degradation (the current shipped posture — router-pending on long reroutes).
Performance
- Duration: ~50 min (11:19–12:09 UTC)
- Started: 2026-10-25T11:19:42Z
- Completed: 2026-10-25T12:09:32Z
- Tasks: 4/4 complete (tasks 3–4 re-scoped per the plan's own honest-FAIL branch)
- Files modified: 7
Accomplishments
- The D-03 gate is a machine gate and it is GREEN.
routing/scripts/measure-optimality-gate.mjs(route-corpus architecture: exportedmeasureOptimalitycore + CLI guard) mirrors the record's epsilon (OPTIMALITY_EPSILON_PCT = 0.1— asserted equal torecord.epsilonby name AND value, before any measurement), refuses non-ARG1 records, refuses an undecodable binary with the rebuild hint, prints the extract-drift WARNING (+36 nodes/+58 edges — never a re-record), compares SECONDS AND VERDICT CLASSES ONLY (no path reads exist —nodes[0]/nodes.lengthgrep = 0), and exits honestly. Final run on the shipped L=24 binary: GATE PASS, max |Δ| 0.005%. - The gate caught a real optimality bug the fixture sweep could not see. First run: 2 D03A violations (x038 +1.637%, x045 +1.019%). A throwaway clean forward Dijkstra on the same graph returned EXACTLY the record's seconds (1214.8 s / 1460.6 s) — the searches disagreed, not the graph. The landmark tables were audited EXACT (0 mismatches vs independent integer Dijkstras, both rows, all 24 anchors — after fixing my own audit's gap-phantom bug). Root cause found by instrumenting labels along the optimal path: the four-family potential's fromTable bound
d̂(ℓ,t) − d̂(ℓ,v)jumps +126.8 s across a 1.49 s edge (the anchor reaches 264611 126.8 s faster than its own upstream 264610 — a oneway reach asymmetry), so the shared Ikeda averagep = (h_f − h_b)/2had reduced costs as low as −62.6 s on unexpanded edges, and BH's closed-set stop rule closed 264611 with a label 43.1 s worse than optimal. Fixtures are bidirectional — no reach asymmetry — which is why 625-pair A1 passed. - The fix is the sound subset, structurally pinned.
potential()now consults ONLY the toTable families (+ haversine) — both two-sided-Lipschitz (u→v→ℓ and v→u→ℓ ride stored traversable edges). The stop rule, reductions, meet probes, and reconstruction are byte-untouched. A11 now pins thatlandmarkFrommust NEVER appear in the comment-stripped search; a new A12 oneway-ring fixture (81-pair Dijkstra sweep with one-way-in spur sentinels) guards the law. routing 80/80, bot 126/126, both typechecks green. - The CPU campaign ran both verdict modes and the pre-committed ladder, honestly. L=24: 25-route
GATE FAIL: p95 152.788 ms/ extendedGATE FAIL: p95 185.692 ms. Ladder rung (a):--landmarks 32rebuild (52.7 MB, coverage 0.980) re-measured WORSE (182.725 / 204.499) — stopped at the plan's documented stop; nothing was retuned, reseeded, or re-rolled (P95_BUDGET_MS = 8grep = 1). - The sound configuration's weakness is theoretical, not incidental: no two-sided-Lipschitz landmark extension exists on a graph with sentinel fringes (a finite filler at a sentinel node would chain through real edges into a finite path to the landmark — contradiction). The only fully sound potentials for the shared-average BH are haversine-class. Sound+fast requires direction-split potentials (
π_ftoward goal from toTable,π_rtoward origin from fromTable) with a re-proven meet rule — skeleton work outside this phase's untouchable lines. This is recorded, not papered over. - Tasks 3–4 executed as the plan's honest-FAIL branch prescribes: the budget gate law now documents the executed-and-measured ALT verdict (no "next-milestone item" wording survives anywhere — grep = 0; drift guard re-anchored 200 → 400 because the documented post-ALT band outgrew the old one; the 8 ms budget unchanged and its FAIL still prints); audit 19/19 vectors ok. KNOWN-LIMITATIONS carries the /cari-shaped record (WHAT CHANGED / what REMAINS, quoted gate lines); its ALT roadmap row reads "Built (Phase 8, 2026-10-25): optimality verified; the CPU verdict measured over budget". ROAD-GRAPH's ladder table carries the (c2) rung with the measured FAIL, the decision paragraph names the real remaining options, and the new "The ARG2 binary layout" section teaches the 72-byte header, the u16 suffix, the sentinel law, and the
landmarkQuantumSfork knob (≈ 6,553 s ceiling, raise-at-rebuild) plus the storage-name-vs-format-truth law. - docs/CONFIGURATION.md: verify-only, no-op — every path/script claim checked (lines 24, 247–248, 294–297): still true; nothing claimed ARG1 decodeable.
Task Commits
- task 1: the D-03 gate + the Rule-1 optimality fix it forced —
149636c(fix) - task 2: the CPU verdict campaign (no commit — measurement only; both modes + the L=32 ladder probe, quoted above)
- task 3: the route-cpu gate law re-anchored (escalation record) —
79a302c(fix) - task 4: the docs records (escalation, no retirement) —
720ad43(docs)
Deviations from Plan
Auto-fixed Issues
1. [Rule 1 - Bug] The four-family ALT potential returned suboptimal real-graph routes
- Found during: task 1 (the gate's first real run — its purpose)
- Issue: fromTable bounds are one-directional Lipschitz across oneway-adjacent edges; the shared
p = (h_f − h_b)/2needs two-sided families; BH closed nodes suboptimally (x038/x045 above) - Fix: potential() consults
landmarkToonly; A11/A12 pins enforce it - Files modified: routing/src/astar.ts, routing/test/astar.test.mjs
- Commit:
149636c
Honest-Stop (the plan's pre-committed branch)
2. The CPU verdict FAILED; the ladder ran to its stop; tasks 3–4 re-scoped to escalation records. The plan wrote this branch itself ("at L=32 still FAIL → STOP … tasks 3–4 re-scope to an honest escalation record instead"). No budget constant was touched, no sample dropped, no lucky re-roll.
3. The plan's task-1 stop-rule was superseded by a better diagnosis: the plan said a D-03 FAIL means "suspect extract drift first … escalation to the user is the only next step". Extract drift was DISPROVEN by measurement (the Dijkstra optimum on the current graph equals the record's seconds exactly), which converted the FAIL from a data problem into a code bug — Rule 1 — fixable within the sanctioned surface. The deviation rules took precedence; the record was never touched.
Total deviations: 1 auto-fixed bug + 1 pre-committed honest stop. Impact: SC-2 green; SC-1 honestly FAIL with quoted numbers; SC-3 correctly NOT taken. The binary on disk is the canonical L=24 ARG2 build (D-02 rule; D-03 green); the R2 upload remains the maintainer's deploy-time act.
Known Stubs
None. Every number quoted in this summary and in the records comes from a printed gate line in this session (files under /tmp/opencode/: d03-final.txt, cpu-25-final.txt, cpu-ext-final.txt, build-l24-restore.txt, build-l32.txt, cpu-25-L32.txt, cpu-ext-L32.txt, d03-gate-L32.txt).
Threat Surface Scan
No new network endpoints, auth paths, file access patterns, or schema changes — the gate script reads two local files and prints; the T-08-13/14/15 mitigations (epsilon mirror, quoted-verbatim records, drift WARNING + immutable record) are all implemented and exercised.
Verification Record (as-run)
node routing/scripts/measure-optimality-gate.mjs→ exit 0,GATE PASS: D-03 optimality — 53/53 routed pairs equal within ±0.1%, verdict classes preserved(final, L=24)- L=32 probe: the same gate exit 1 with x045 +0.761% (the fringe-boundary finding — documented, not shipped)
node routing/scripts/measure-route-cpu.mjs→ exit 1,GATE FAIL: p95 152.788 ms exceeds the 8 ms budget (A1)node routing/scripts/measure-route-cpu.mjs --extended→ exit 1,GATE FAIL: p95 185.692 ms exceeds the 8 ms budget — D-04 extended verdict--landmarks 32rebuild → exit 0 (52.7 MB, L=32, coverage 0.980) → re-measured 182.725 / 204.499 ms — worse; ladder stoppednpm run routing:test→ 80 passed, 0 failed (A1 sweep + A11 pin + A12 oneway sweep)npm test -w bot→ 126 passed, 0 failed;routing:typecheck+bot:typecheckcleannode scripts/test/budget-audit.test.mjs→BUDGET-AUDIT SUITE: 19/19 vectors okgrep -c "P95_BUDGET_MS = 8" routing/scripts/measure-route-cpu.mjs= 1;grep -c "next-milestone" scripts/lib/budget-gates.mjs docs/BUDGETS.md= 0+0;nodes[0]|nodes.lengthin the gate = 0- The record file: untouched (verified by the gate's own mirror asserts + git)
F1 Remediation Addendum (post-plan, 2026-10-25)
Debug session: .planning/debug/alt-potential-4x-slowdown.md — RC-1 (LIVE correctness bug) + RC-2 (the 4× CPU slowdown). D-03's green above was sampling luck: the fixed corpus never crosses a violating edge harmfully, while fresh random pairs caught the shipped routeAstar suboptimal on 1/194 (+0.278%, pair 141683→292552) vs a Dijkstra oracle. Root cause: bound()'s per-node sentinel skip varied the active landmark family set PER NODE across edges leaving the 6,285-node disconnected island (2.02% of cells).
Fix (F1, exactly as the debug report specified): routing/src/astar.ts
- Per-graph WeakMap memo
cleanColumnsFor—clean[l]= "to-column ℓ has zero 0xFFFF cells" (O(L·n) sequential rows once per graph/isolate;reverseForprecedent). - Per-search active list
activeL= clean columns only;bound()loops the active list with NO per-node sentinel branch (constant-table goal/origin NaN checks retained as belt). - On the current binary (0/24 clean columns — island census confirmed) potentials degrade to EXACTLY haversine: the designed sound fallback; the pre-ALT CPU band returns.
- ALT stays LIVE and tested: the committed mini-graph is 0/2 dirty columns and A12's ring is all-clean (both verified by table scan), so the ALT path keeps running in the suite.
- BH stop rule, reductions, balanced alternation, meet probes, real-seconds reconstruction: untouched. F2 (transposed table) explicitly out of scope — future clean-column binaries only.
Test work (re-specified per the debug report):
- A9: island fixture re-pinned as ALL-DIRTY (every to-column holds a B-node sentinel → the whole fixture runs haversine); the old "real ALT bounds live in A" claim (per-node-skip semantics) removed.
- A10: mechanism comment updated to the containment law.
- A11: structural pin rewritten to the F1 shape —
cleanColumnsFor/activeLmust exist in code, inline=== 0xffffsentinel compares BANNED (RC-1's exact shape), named-constant law pinned. Committed RED-first: failed on shipped code exactly as designed. - A12: re-sealed as the ALT-ACTIVE counterpart (all to-columns clean, pinned by table scan).
- A13 (new): mixed clean/dirty columns via a one-way-bottleneck twin-ring fixture — the subset-active-list branch; 64-pair Dijkstra equivalence + 16 honest nulls.
New committed gate: routing/scripts/measure-astar-oracle-sweep.mjs — 200 COMPARED fresh seeded cross-metro pairs (seed 0x08f1, NOT the D-03 corpus; generateCrossMetroPairs core reused; 3× oversample with snap-miss rejection printed; exported sweepOracle core + CLI guard; honest SKIP when the gitignored binary is absent). Gate: 0 suboptimal vs a brute-force label-setting Dijkstra oracle.
Verification (all re-run post-fix, this host):
| Gate | Result |
|---|---|
npm run routing:test |
81 passed, 0 failed (A11 RED pins green, A13 new) |
npm test -w bot |
126 passed, 0 failed |
routing:typecheck + bot:typecheck |
clean |
| Oracle sweep (new) | GATE PASS: 0/200 suboptimal (182 routed, 18 unreachable, worst Δ +0.000%) |
measure-route-cpu.mjs |
p95 136.562 ms / mean 54.081 ms — the pre-ALT band on this host (pre-fix today measured 1037.618 ms; ~7.6× back). Honest c3 record stands: still a FAIL vs the 8 ms budget |
measure-optimality-gate.mjs (D-03) |
GATE PASS: 0 violations, max |Δ| 0.005%, verdict classes preserved |
Commits: c071e20 (test RED), 2a5a0b5 (fix F1), 97d6e35 (oracle sweep). Bench/instrumentation harnesses remain in /tmp/opencode/alt-bench/ (never committed).
Impact on the plan's verdicts: the D-03 gate green above is now backed by a fresh-pair pin that structurally can't pass on sampling luck; the CPU verdict is unchanged in kind (c3 escalation stands — ALT is inert on this binary until a clean-column rebuild exists, and a rebuilt clean-column binary re-arms ALT with no code change).
User Setup Required
None new. The maintainer-time R2 upload (node routing/scripts/upload-road-graph.mjs + the --check roundtrip) remains the deploy-time act — manual by design (account-level validation). Decision needed: pick the escalation track (direction-split potentials / CH / Workers Paid reversal / keep c3).
Next Phase Readiness
- The ARG2 asset is built, checked, and upload-ready; Engine B (Phase 11) consumes the same layout (the ~43 MB payload class holds at L=24).
- The optimality guarantee now travels with a machine gate any future steering change must keep green.
- The c3 record (BUDGETS §c3 + KNOWN-LIMITATIONS) is the single source of truth for the escalation options.
Phase: 08-alt-landmark-preprocessing-routing-backend-v2 Completed: 2026-10-25
Self-Check: PASSED
- All 8 touched files + the SUMMARY exist on disk — FOUND (9/9)
- Task commits
149636c,79a302c,720ad43exist in git history — FOUND (3/3) - Task 2 is intentionally commit-free (measurement only; the quoted gate lines are the deliverable) — VERIFIED
- The record
routing/test/fixtures/alt-baseline.jsonis untouched — VERIFIED (git status; the gate's mirror asserts ran on every pass)