Files

28 KiB
Raw Permalink Blame History

phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
phase plan type wave depends_on files_modified autonomous requirements must_haves
08-alt-landmark-preprocessing-routing-backend-v2 05 execute 5
08-04
routing/scripts/measure-optimality-gate.mjs
scripts/lib/budget-gates.mjs
scripts/test/budget-audit.test.mjs
docs/BUDGETS.md
docs/KNOWN-LIMITATIONS.md
docs/ROAD-GRAPH.md
true
SC3
SC4
truths artifacts key_links
The D-03 optimality gate is a committed, re-runnable script that reads the FROZEN pre-ALT record (08-01), re-routes the SAME coordinate-pinned pairs on the current ARG2 binary, and gates on seconds-equality (± OPTIMALITY_EPSILON_PCT = 0.1) + verdict-class preservation — never on node paths (equal-cost ties are documented behavior, D-03)
The gate's epsilon constant is asserted EQUAL to the record's epsilon block — a record edit alone cannot fake a pass (constant-mirror law from 08-01)
The ALT verdict is MEASURED, never hoped: the 25-route CI gate AND the D-04 extended 100-pair verdict both print their p95 + GATE lines; the c3 retirement (D-05) happens ONLY on passing numbers, quoted verbatim into every record
The remediation ladder is pre-committed: FAIL → rebuild at --landmarks 32 → re-measure; at L=32 still FAIL → STOP and escalate honestly (retirement never fires on failing numbers); astar's stop rule is untouchable (Pitfall 3)
Every record that documented the accepted c3 degradation tells the post-ALT truth: budget-gates.mjs' route-cpu verdict law, docs/BUDGETS.md's CPU row + c3 section, docs/KNOWN-LIMITATIONS.md's c3 section + ALT pointer row, docs/ROAD-GRAPH.md's ladder table + ARG2 layout — no 'next-milestone item' wording survives (Pitfall 6, docs divorce)
path provides
routing/scripts/measure-optimality-gate.mjs the D-03 gate — exported core + CLI guard (route-corpus pattern); D03A seconds-equality + D03B verdict-class checks with per-pair violations
path provides
scripts/lib/budget-gates.mjs the route-cpu verdict law re-anchored: ≤8 ms PASS; within the shared-host variance guard → loud re-run warning; beyond → uncharted-regression FAIL; all c3-ACCEPTED wording removed
path provides
docs/KNOWN-LIMITATIONS.md the c3 section replaced by the retirement record (FIXED shape, /cari precedent); ALT roadmap-pointer row flipped to built
path provides
docs/ROAD-GRAPH.md ladder table's (c2) rung with measured numbers; the ARG2 layout + landmarkQuantumS knob documented; storage-name-vs-format-truth note
from to via pattern
routing/scripts/measure-optimality-gate.mjs routing/test/fixtures/alt-baseline.json reads pairs (origin/destination lat-lng + seconds + verdict) + epsilon.pct from the frozen record — never regenerates pairs alt-baseline.json
from to via pattern
routing/scripts/measure-optimality-gate.mjs OPTIMALITY_EPSILON_PCT record.epsilon.pct mirror assert before any measurement (mismatch → fail) OPTIMALITY_EPSILON_PCT
from to via pattern
docs/KNOWN-LIMITATIONS.md retirement record the campaign's printed gate lines (task 2's quoted numbers) D-05 evidence law: the record quotes the measured p95s + date, never rounds up or hopes FIXED 2026-
The measurement campaign that turns ALT from code into evidence, and the record retirement that evidence buys: the D-03 optimality gate against the frozen pre-ALT baseline, the SC-1/SC-1′ CPU verdicts (25-route CI + 100-pair extended), then every c3-accepting record — budget gate law, BUDGETS, KNOWN-LIMITATIONS, ROAD-GRAPH — re-written to the measured truth.

Purpose: this plan IS the phase's success criteria. SC-1 (p95 under the ceiling) and SC-2 (optimality unaffected) are measured here; SC-3 (the c3 class retires with evidence) is written here. Output: green optimality gate, green CPU verdicts (or the honest-FAIL escalation), and four documents + one gate law that no longer accept a degradation that no longer exists.

<execution_context> @$HOME/.config/opencode/get-shit-done/workflows/execute-plan.md @$HOME/.config/opencode/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/STATE.md @.planning/phases/08-alt-landmark-preprocessing-routing-backend-v2/08-CONTEXT.md @.planning/phases/08-alt-landmark-preprocessing-routing-backend-v2/08-RESEARCH.md @.planning/phases/08-alt-landmark-preprocessing-routing-backend-v2/08-PATTERNS.md @.planning/phases/08-alt-landmark-preprocessing-routing-backend-v2/08-VALIDATION.md

The frozen record (Plan 08-01, routing/test/fixtures/alt-baseline.json):

{ "recordedAt": "<ISO>", "epsilon": { "name": "OPTIMALITY_EPSILON_PCT", "pct": 0.1 },
  "graph": { "path": "routing/data/kl-roadgraph.v1.bin", "byteLength": 15449343, "nodeCount": N, "edgeCount": E, "argVersion": 1 },
  "pairRules": { "seed": "0x08a1", "count": 100, "minPairKm": 12 },
  "pairs": [ { "pairId": "x000", "origin": {"lat": …, "lng": …}, "destination": {"lat": …, "lng": …}, "straightLineKm": …, "seconds": …, "verdict": "reachable|unreachable|unsnappable" } ] }

The record is IMMUTABLE (the recorder refuses overwrite; delete by explicit git revert only). Pairs are pinned by COORDINATES (never node indices — Pitfall 2).

routing/scripts/route-corpus.mjs — the gate-script architecture to copy: exported measurement core + CLI guard (const invoked = process.argv[1] ? pathToFileURL(...) : ""; if (invoked === import.meta.url) main();, lines 329–334), the checks-registry + violations pattern (lines 74–92), named-constant bands (lines 41–53), the report/exit law (0 only when every check has zero violations).

routing/scripts/measure-route-cpu.mjs — the two verdict modes: default (zero args, 25-route CI gate, P95_BUDGET_MS = 8, prints p95: <n> ms (…) + GATE PASS|FAIL: …) and --extended (Plan 08-01: ~100 cross-metro coordinate-pinned pairs via generateCrossMetroPairs, seed 0x08a1, its own p95 + gate line naming the D-04 extended verdict). The pre-ALT extended run measured an HONEST GATE FAIL (08-01) — post-ALT PASS is the arc this plan closes.

scripts/lib/budget-gates.mjs — the route-cpu verdict law going stale (lines 24–33 doc, 58–61 ROUTE_CPU_DRIFT_GUARD_MS = 200, 121–133 verdict strings): current strings call an 8 ms overshoot "the DOCUMENTED, ACCEPTED c3 class" and call ALT "a next-milestone item". runCpuLadderGate (lines 78–119) runs measure-route-cpu.mjs with ZERO args and regex-parses ^p95: / ^GATE (?:FAIL|PASS): — that CLI contract is pinned (budget-audit 19/19 vectors; scripts/test/budget-audit.test.mjs also source-token-checks the gates). Read that test IN FULL before editing either file — vectors pinning the stale strings co-update in the same task.

docs state to rewrite: docs/KNOWN-LIMITATIONS.md c3 section (lines 29–41, ending "…it is a next-milestone item and is not in this release."), the /cari FIXED-record precedent (lines 43–57: ROOT CAUSE / what changed / verified date / what REMAINS), ALT pointer row (line 80: "Next-milestone item, not built"). docs/ROAD-GRAPH.md CPU-gate section (lines 77–106: ladder table + the open c1/c2/c3 decision paragraph), key-facts row "pinned CSR v1" (line 130). docs/BUDGETS.md route-cpu row (line 58) + "Cross-metro CPU degradation (the c3 class)" section (lines 162–186, including the 200 ms DRIFT GUARD paragraph). docs/CONFIGURATION.md — verify-only.

task 1: The D-03 optimality gate script + green run against the frozen record routing/scripts/measure-optimality-gate.mjs - routing/test/fixtures/alt-baseline.json (the committed record — its exact schema is the gate's input contract) - routing/scripts/route-corpus.mjs lines 41–92 + 283–334 (checks/violations pattern, exported-core + CLI-guard, report/exit law — copy this architecture) - routing/scripts/measure-route-cpu.mjs lines 47–84 (existsSync guard, toArrayBuffer, decodeGraph-null fail, graph print shape) - .planning/phases/08-alt-landmark-preprocessing-routing-backend-v2/08-RESEARCH.md (D-03 verbatim; Pitfall 1 — the record is frozen, drift escalates, never re-records; Pitfall 2 — coordinates are the only pin) - routing/scripts/measure-optimality-baseline.mjs (Plan 08-01 — the immutable-record law and the fail() shape it established) - epsilon mirror: the script's OPTIMALITY_EPSILON_PCT ≠ record.epsilon.pct → fail() BEFORE any measurement (constant-mirror law; a record edit alone cannot fake equality) - record.graph.argVersion !== 1 → fail() ("the baseline must be the pre-ALT record") - current binary decodes null (still ARG1 / corrupt) → fail() with the rebuild hint — never a partial comparison - D03B verdict class: record reachable + post-ALT null (or the reverse) → violation naming the pairId; record unreachable + post unreachable → pass - D03A seconds: both routed and |post − pre| > pre × 0.1/100 → violation; within → pass (equal seconds, ties allowed — node paths are NEVER compared) - record "unsnappable" pairs (seconds null): post also unsnappable → pass; post now snaps and routes → an INFO row ("re-snapped") with its seconds printed, NOT a violation — counted and WARNING-printed in the summary if > 0 (D-03's letter gates the reachable/unreachable classes) - a tie-path difference (different equal-cost node path, same seconds) CANNOT produce a violation — the gate structurally never looks at paths Create `routing/scripts/measure-optimality-gate.mjs` (#!/usr/bin/env node; header contract doc-comment in the route-corpus style: purpose, inputs — the COMMITTED record + the LOCAL rebuilt binary — echoes pair ids + measurements only, exit law).

Constants (named, doc-commented): OPTIMALITY_EPSILON_PCT = 0.1 (D-03; the mirror of the record's epsilon block), RECORD_PATH = resolve(here, "..", "test", "fixtures", "alt-baseline.json"), GRAPH_PATH = resolve(here, "..", "data", "kl-roadgraph.v1.bin") (the same path law as measure-route-cpu).

Exported core (the route-corpus split — one measurement, two reporters): export function measureOptimality(graph, record, { snap, astar }) → { checks: { D03A, D03B }, rows, reSnapped, pass } — for each record pair: snap both endpoints (snap-miss on the NEW graph → row class "unsnapped", handled per the unsnappable rules above); route with astar; compare per the rules; per-pair row { pairId, pre, post, deltaPct, verdictPre, verdictPost, class: "pass|violation|re-snapped|unsnapped" }.

CLI main(): existsSync guards (absent record → fail "run measure-optimality-baseline first — the record is the D-03 anchor"; absent binary → fail with the build hint); parse + validate the record; the epsilon + argVersion mirror asserts; decodeGraph (null → fail honest); INFO print comparing record.graph counts vs current (nodeCount/edgeCount drift → WARNING line: "extract drift vs the frozen record — the seconds gate still applies"; NOT a violation, and NEVER a reason to re-record — Pitfall 1); run the core; print per-pair rows ( xNNN: pre 5123.4s post 5123.4s (Δ 0.000%) pass shape), the summary (violations per check, re-snapped count, max |Δ%|, the epsilon used), and exit 1 on any violation else GATE PASS: D-03 optimality — N/N pairs equal within ±0.1%, verdict classes preserved.

Then RUN it — the rebuilt ARG2 binary from 08-04 is on disk: node routing/scripts/measure-optimality-gate.mjs. Expected: GATE PASS (ALT is steering-only; A1-class change). A FAIL here is honest and STOPS the plan: report the violating pairs, suspect extract drift first (compare the WARNING counts), and NEVER edit the record — escalation to the user is the only next step (Pitfall 1's immutable law). export PATH="$HOME/.nvm/versions/node/v24.18.0/bin:$PATH" && node routing/scripts/measure-optimality-gate.mjs 2>&1 | tail -3 && echo "D03-GATE-GREEN" <acceptance_criteria> - The script is committed; grep gates: OPTIMALITY_EPSILON_PCT ≥ 3 (const + mirror assert + report line); the mirror assert (record.epsilon) present; alt-baseline.json referenced as RECORD_PATH. - The real run exits 0 printing per-pair rows for the record's full pair count (100), 0 violations, and the GATE PASS: D-03 optimality … line; the run's tail is quoted in the summary. - Seconds/verdict-only law: the script contains NO node-path comparison (grep -c "nodes\[0\]\|nodes.length" routing/scripts/measure-optimality-gate.mjs = 0). - Honest-refusal structure verified by reading main(): the epsilon + argVersion mirror asserts and the decodeGraph-null branch ALL precede any measurement call (code-order check, quoted in the summary). </acceptance_criteria> D-03 is a machine gate and it is GREEN: post-ALT seconds equal the frozen pre-ALT record within ±0.1% with verdict classes preserved.

task 2: The CPU verdict campaign (SC-1 + SC-1′) with the pre-committed ladder - routing/scripts/measure-route-cpu.mjs IN FULL (185 lines — the two modes whose output you will quote; the GATE lines' exact shapes) - .planning/phases/08-alt-landmark-preprocessing-routing-backend-v2/08-RESEARCH.md (D-04; Pitfall 3 — the remediation ladder and the temptation it forecloses; A6 — the verdict is expected but the gate decides) - .planning/phases/08-alt-landmark-preprocessing-routing-backend-v2/08-01-PLAN.md (the pre-ALT extended FAIL — the honest before-number this verdict answers) Run BOTH verdict modes over the ARG2 binary and quote every gate line in the summary. These numbers are the phase's SC-1 evidence and the raw material for tasks 3–4's records.
  1. node routing/scripts/measure-route-cpu.mjs — the 25-route CI gate. Expected: GATE PASS: p95 <X> ms <= 8 ms budget. Quote the p95 line, the worst 3 per-pair lines, and the routed/unreachable split.
  2. node routing/scripts/measure-route-cpu.mjs --extended — the D-04 ALT verdict on ~100 coordinate-pinned cross-metro pairs. Expected: its own p95 + GATE PASS line naming the D-04 extended verdict. Quote the p95 line + the slowest pairs.
  3. THE PRE-COMMITTED LADDER (Pitfall 3) — apply ONLY in this order, only on FAIL: a. node routing/scripts/build-road-graph.mjs --landmarks 32 (the measured D-02 knob, top of the rule) → re-run BOTH gates. b. At L=32 still FAIL → STOP. Record the honest numbers; do NOT proceed to tasks 3–4 as retirements (they re-scope to an honest escalation record instead — D-05's evidence law forbids retiring on failing numbers); report to the user. NEVER: edit P95_BUDGET_MS, touch routeAstar's stop rule/reductions, drop sample pairs, reseed, or re-run until a lucky box moment and quote only that one (print-the-measurement law gates even a PASS — quote the run you got; a suspiciously loaded box gets a NOTE in the summary, not a re-roll). export PATH="$HOME/.nvm/versions/node/v24.18.0/bin:$PATH" && node routing/scripts/measure-route-cpu.mjs 2>&1 | tail -1 && node routing/scripts/measure-route-cpu.mjs --extended 2>&1 | tail -1 && echo "CPU-VERDICTS-RECORDED" <acceptance_criteria>
    • The 25-route gate exits 0 with GATE PASS: p95 … <= 8 ms budget (or the ladder was exercised to its documented stop).
    • The extended verdict exits 0 with its GATE PASS … D-04 extended verdict line (or the ladder/escalation path is documented).
    • The summary quotes BOTH p95 lines + n values + date, and (if used) the --landmarks 32 rebuild command and both re-measurements.
    • grep -c "P95_BUDGET_MS = 8" routing/scripts/measure-route-cpu.mjs = 1 (the budget was never touched). </acceptance_criteria> SC-1/SC-1′ are measured with ALT live; the numbers that retire (or honestly keep) the c3 class exist, printed and quoted.
task 3: Budget-record truth-out — the route-cpu gate law + docs/BUDGETS.md scripts/lib/budget-gates.mjs, scripts/test/budget-audit.test.mjs, docs/BUDGETS.md - scripts/lib/budget-gates.mjs lines 20–135 IN FULL (the runCpuLadderGate law, ROUTE_CPU_DRIFT_GUARD_MS, the verdict strings citing the ACCEPTED c3 class + "next-milestone item") - scripts/test/budget-audit.test.mjs IN FULL (the 19/19 vectors — identify which pin the stale strings/exit laws; they co-update here) - docs/BUDGETS.md lines 50–70 (the route-cpu row) + 155–190 (the c3 section + the DRIFT GUARD paragraph) - .planning/phases/08-alt-landmark-preprocessing-routing-backend-v2/08-CONTEXT.md (D-05 — the record retires WITH evidence) - Task 2's quoted numbers (the new measured p95s) Retire the c3 acceptance in the gate law and the budget record — the audit must stop DOCUMENTING a degradation that no longer exists (Pitfall 6):
  1. scripts/lib/budget-gates.mjs — re-anchor the route-cpu verdict law (the zero-arg CLI contract with measure-route-cpu.mjs and the ^p95: / ^GATE regex parsing stay BYTE-COMPATIBLE — that is pinned by budget-audit):
    • ≤ P95_BUDGET_MS (8): unchanged PASS path.
    • 8 < p95 ≤ ROUTE_CPU_DRIFT_GUARD_MS (200 — the constant STAYS, re-documented): exit 0 with a loud WARNING line: over the product budget within the shared-host variance guard (documented ≈2x box variance; the 06-04 band history cites 38–93 ms on IDENTICAL pre-ALT code) — "re-run on a quiet box before treating as regression; the c3 class was RETIRED in Phase 8 (ALT preprocessing)".
    • p95 > 200: exit 1 "UNCHARTED REGRESSION — the c3 degradation class was retired in Phase 8; a p95 here means the ALT binary/graph or the search regressed".
    • DELETE the stale strings: "DOCUMENTED, ACCEPTED c3 class", "the ALT landmark lever is a next-milestone item", and the doc-comment lines 24–33's c3-acceptance framing — replaced by the retirement framing with the Phase 8 citation.
  2. scripts/test/budget-audit.test.mjs — co-update ONLY the vectors that pinned the stale strings/exit law (the suite must return to 19/19 green with the NEW law; the count stays 19 unless a vector was solely a stale-string pin, in which case it becomes the new-law equivalent — never silently dropped; the final line still reports BUDGET-AUDIT SUITE: 19/19 vectors ok).
  3. docs/BUDGETS.md — the route-cpu row: new measured value (task 2's quoted p95 + date + n; keep the "not statically pinnable / re-run the audit" honesty and the shared-host variance note), the headroom cell flips positive, the "accepted c3 class" disposition cell becomes "RETIRED 2026-10-25 (Phase 8, ALT)". The c3 section becomes the retirement record in the same shape (what changed: ALT preprocessing + ARG2; the measured numbers that retired it; the DECIDED posture now: p95 ≤ 8 is the gate, the variance guard is measurement hygiene, NOT an accepted class; the ladder history stays as history). The DRIFT GUARD paragraph re-anchors to the new law (variance guard ≠ accepted degradation). export PATH="$HOME/.nvm/versions/node/v24.18.0/bin:$PATH" && node scripts/test/budget-audit.test.mjs 2>&1 | tail -1 && grep -rn "next-milestone item" scripts/lib/budget-gates.mjs docs/BUDGETS.md | wc -l && echo "C3-GATE-LAW-REANCHORED" <acceptance_criteria>
    • node scripts/test/budget-audit.test.mjs → final line BUDGET-AUDIT SUITE: 19/19 vectors ok (co-updated vectors included).
    • grep law: zero hits for "next-milestone item" in scripts/lib/budget-gates.mjs and docs/BUDGETS.md; zero hits for "ACCEPTED c3" in budget-gates.mjs.
    • ROUTE_CPU_DRIFT_GUARD_MS still exported and used (the constant survives with its new documented meaning).
    • docs/BUDGETS.md's route-cpu row carries task 2's measured p95 + date; the c3 section leads with the retirement (grep "RETIRED" ≥ 1 in the file).
    • The zero-arg child-process contract is untouched: runCpuLadderGate still executes measure-route-cpu.mjs with no args and the same regexes (the audit suite's own pins prove it). </acceptance_criteria> The budget record and its gate law state the post-ALT truth: ≤8 ms is the gate, the variance guard is hygiene, c3 is retired with quoted numbers.
task 4: Docs retirement (D-05) — KNOWN-LIMITATIONS + ROAD-GRAPH (+ CONFIGURATION verify) docs/KNOWN-LIMITATIONS.md, docs/ROAD-GRAPH.md - docs/KNOWN-LIMITATIONS.md IN FULL (104 lines — the c3 section 29–41; the /cari FIXED-record precedent 43–57, the exact shape to copy; the roadmap-pointer table 77–81) - docs/ROAD-GRAPH.md IN FULL (130 lines — the CPU-gate section 77–106 incl. the open c1/c2/c3 decision paragraph; the fork contract's build/check steps; the key-facts table 119–130) - docs/CONFIGURATION.md lines ~24, ~248, ~294 (verify-only: path/script-name claims that could have gone false) - .planning/phases/08-alt-landmark-preprocessing-routing-backend-v2/08-RESEARCH.md (D-05; Pitfall 6 — docs divorce; the ROAD-GRAPH.md section of PATTERNS) - Tasks 1–3's quoted numbers (the retirement record's evidence) 1. `docs/KNOWN-LIMITATIONS.md`: - Replace the "Cross-metro routes may not resolve" c3 section with the retirement record, in the /cari record's shape: ROOT CAUSE (BH's weak geographic/max-speed potentials on 20–30 km cross-metro routes — the survey-predicted weak spot), FIXED 2026-10-25 (Phase 8): ALT landmark preprocessing — build-time ĉ-metric distance tables in the ARG2 graph layout + max-combined ALT/haversine A\* steering; the measured numbers that retired it (25-route p95 X ms; extended 100-pair p95 Y ms — quoted from task 2's printed lines; the D-03 optimality gate green vs the frozen pre-ALT record); what REMAINS: equal-cost tie-paths may differ (documented behavior, never a failure), and an old ARG1 binary is router-pending until ONE re-upload — the designed degradation, now the only one. Workers Paid stays rejected ($0 law). - Flip the roadmap-pointer ALT row: "Next-milestone item, not built" → built (Phase 8) with the measured p95; adjust the surrounding "none in this release" framing accordingly (the WASM-router and Engine-B rows stay as they are). 2. `docs/ROAD-GRAPH.md`: - CPU-gate section: the ladder table gains the (c2) rung — executed, with the measured p95s + date; the decision paragraph flips from OPEN (c1/c2/c3) to DECIDED: c2 built (this phase), c1 and c3 rejected (c3 retired by measurement). Note the extended 100-pair verdict as the cross-metro evidence. - New short section "The ARG2 layout": 72-byte header (landmarkCount / landmarkQuantumS / reserved), the u16 dual-family table suffix + u32 anchors, the sentinel 0xFFFF law, and the `landmarkQuantumS` fork knob — 0.1 s default ⇒ ≈6,553 s expressible ceiling, raise-at-rebuild instructions for larger forks (Pitfall 5). The storage-name-vs-format-truth note: the R2 key stays `kl-roadgraph.v1.bin` (D-01 lock); the HEADER version is the format truth — never rename the key. - Key-facts table: "pinned CSR v1" → ARG2 wording; add the optimality-gate script to the tools list. - The fork contract's build step text gains the landmark facts (the stage prints them; no new commands — the contract's commands are unchanged). 3. `docs/CONFIGURATION.md`: READ-verify — edit ONLY if a statement became false (paths and script names are unchanged; expected no-op). Note the check in the summary either way. TONE LAW: honest-engineering voice throughout — quote measured numbers with their date, name what remains, never overpromise ("routes in budget" only as far as the gates measured). export PATH="$HOME/.nvm/versions/node/v24.18.0/bin:$PATH" && grep -c "Next-milestone item, not built" docs/KNOWN-LIMITATIONS.md; grep -c "FIXED 2026-10-25" docs/KNOWN-LIMITATIONS.md docs/ROAD-GRAPH.md; grep -c "landmarkQuantumS" docs/ROAD-GRAPH.md && echo "DOCS-RETIRED" - KNOWN-LIMITATIONS: `grep -c "Next-milestone item, not built"` = 0; the retirement record present with `FIXED 2026-10-25` + the measured p95 strings from task 2 (grep the exact quoted number ≥ 1); the tie-path and router-pending remainders named. - ROAD-GRAPH: the (c2) ladder rung present with numbers (`grep -c "(c2)" ≥ 1` in the ladder table region); `landmarkQuantumS` ≥ 2; "ARG2" ≥ 3; the decision paragraph states c2 executed and c1/c3 rejected; the storage-name note present. - No doc claims ARG1 binaries remain decodeable (grep -ci "arg1" in both docs shows only retirement/router-pending contexts — read the hits). - CONFIGURATION.md untouched OR the touched lines quoted in the summary. - Both docs keep the honest tone: no "always"/"never" claims beyond what the gates measured. SC-3 is written: the c3 class is retired with quoted evidence in every record that documented it, and the fork contract teaches ARG2.

<threat_model>

Trust Boundaries

Boundary Description
frozen record → optimality gate the record is the phase's comparison anchor; editing it must never be able to fake a pass
campaign verdicts → public docs the retirement records quote measurements; unmeasured claims are the failure mode D-05 exists to prevent

STRIDE Threat Register

Threat ID Category Component Disposition Mitigation Plan
T-08-13 Tampering gaming the optimality gate by editing the record mitigate the epsilon constant-mirror assert + the record's refuse-overwrite immutability (08-01) + committed git history make any edit visible; the gate re-snaps the record's COORDINATES and re-measures live, so only a genuine equal-seconds run passes
T-08-14 Repudiation retirement docs citing numbers never measured mitigate D-05's evidence law: tasks 3–4 quote task 2's printed gate lines verbatim; the review leg cross-checks the quotes against the summary
T-08-15 Tampering extract drift faking a pass/fail mitigate the gate prints the counts-diff WARNING; the seconds epsilon + verdict classes are the gates; a mass-failure escalates to the user — the record is never silently re-recorded (Pitfall 1)
T-08-16 DoS campaign runtime (100 routes + rebuild retries) accept maintainer-time; seconds-class measurements; the ladder is capped at one rebuild (L=32)
</threat_model>
- `node routing/scripts/measure-optimality-gate.mjs` → GATE PASS (D-03). - Both measure-route-cpu modes → GATE PASS (SC-1/SC-1′) or the documented honest-FAIL escalation. - `node scripts/test/budget-audit.test.mjs` → `BUDGET-AUDIT SUITE: 19/19 vectors ok`. - `npm run routing:test && npm test -w bot && npm run routing:typecheck && npm run bot:typecheck` — the full battery green one final time at the phase's last code-touching commit (only the new gate script + doc/gate-law edits since 08-04). - Docs greps (task 4's acceptance) all green; the summary quotes every gate line the records cite. - MANUAL (maintainer, after this plan): `node routing/scripts/upload-road-graph.mjs` + the roundtrip `--check` — the R2 upload is an account-level act (validation map, manual-only); the plan stops at the local evidence.

<success_criteria> The D-03 optimality gate is green against the frozen pre-ALT record; the 25-route and extended CPU verdicts pass with ALT live (or the honest-FAIL escalation is recorded); every record that accepted the c3 degradation — budget gate law, BUDGETS, KNOWN-LIMITATIONS, ROAD-GRAPH — now states the measured post-ALT truth with dates and quoted numbers; the fork contract teaches ARG2; nothing claims more than the gates measured. </success_criteria>

After completion, create `.planning/phases/08-alt-landmark-preprocessing-routing-backend-v2/08-05-SUMMARY.md`