--- phase: 08-alt-landmark-preprocessing-routing-backend-v2 plan: 05 type: execute wave: 5 depends_on: ["08-04"] files_modified: - 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 autonomous: true requirements: [SC3, SC4] must_haves: truths: - "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)" artifacts: - path: "routing/scripts/measure-optimality-gate.mjs" provides: "the D-03 gate — exported core + CLI guard (route-corpus pattern); D03A seconds-equality + D03B verdict-class checks with per-pair violations" - path: "scripts/lib/budget-gates.mjs" provides: "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: "docs/KNOWN-LIMITATIONS.md" provides: "the c3 section replaced by the retirement record (FIXED shape, /cari precedent); ALT roadmap-pointer row flipped to built" - path: "docs/ROAD-GRAPH.md" provides: "ladder table's (c2) rung with measured numbers; the ARG2 layout + landmarkQuantumS knob documented; storage-name-vs-format-truth note" key_links: - from: "routing/scripts/measure-optimality-gate.mjs" to: "routing/test/fixtures/alt-baseline.json" via: "reads pairs (origin/destination lat-lng + seconds + verdict) + epsilon.pct from the frozen record — never regenerates pairs" pattern: "alt-baseline\\.json" - from: "routing/scripts/measure-optimality-gate.mjs OPTIMALITY_EPSILON_PCT" to: "record.epsilon.pct" via: "mirror assert before any measurement (mismatch → fail)" pattern: "OPTIMALITY_EPSILON_PCT" - from: "docs/KNOWN-LIMITATIONS.md retirement record" to: "the campaign's printed gate lines (task 2's quoted numbers)" via: "D-05 evidence law: the record quotes the measured p95s + date, never rounds up or hopes" pattern: "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. @$HOME/.config/opencode/get-shit-done/workflows/execute-plan.md @$HOME/.config/opencode/get-shit-done/templates/summary.md @.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`): ```json { "recordedAt": "", "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: 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" - 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). 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 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" - 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). 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" - `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). 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. ## 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) | - `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. 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. After completion, create `.planning/phases/08-alt-landmark-preprocessing-routing-backend-v2/08-05-SUMMARY.md`