28 KiB
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 |
|
|
true |
|
|
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.mdThe 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.
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.
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.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 PASSline naming the D-04 extended verdict. Quote the p95 line + the slowest pairs.- 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 verdictline (or the ladder/escalation path is documented). - The summary quotes BOTH p95 lines + n values + date, and (if used) the
--landmarks 32rebuild 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.
- The 25-route gate exits 0 with
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:/^GATEregex 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.
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 reportsBUDGET-AUDIT SUITE: 19/19 vectors ok).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 lineBUDGET-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:
runCpuLadderGatestill 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.
<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> |
<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`