13 KiB
phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, requirements-completed, duration, completed
| phase | plan | subsystem | tags | requires | provides | affects | tech-stack | key-files | key-decisions | requirements-completed | duration | completed | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 05-routing-route-display | 02 | routing |
|
|
|
|
|
|
|
|
9min | 2026-10-23 |
Phase 5 Plan 2: Fixture Corpus — Golden Pairs + OSRM-Demo Precompute + Offline Tolerance Gate Summary
The fixture corpus is REAL: 15 pinned KL pairs precomputed from the public OSRM demo server (23 verbatim polyline6 routes, 8 with alternates), pinned behind the RT1–RT10 offline tolerance gate — CLI and in-suite reporters green, the D-12 "public data between public places" law mechanically proven against the gazetteer, 16.6 KB gzipped against the 100 KB early-warning budget.
Performance
- Duration: 9 min
- Started: 2026-10-23T21:11:43Z
- Completed: 2026-10-23T21:20:27Z
- Tasks: 2/2
- Files touched: 9 (4 created, 5 modified)
Accomplishments
- The data product exists (D-02):
routing/src/data/route-fixtures.jsoncarries 15 golden pairs — 5.2 km KL Tower→KL Sentral to 23.1 km Mid Valley→IOI City Mall — each with 1–3 best-first routes stored as VERBATIM polyline6 strings from the OSRM demo (alternatives=2&overview=full&geometries=polyline6), ODbL header fields preserved (T-05-06). The 05-01 empty seed is resolved. - The maintainer tool follows the repo-tool law (D-12):
fetch-route-fixtures.mjsdocuments the maintainer-machine boundary verbatim in its header, validates the whole corpus against the gazetteer BEFORE any request leaves the machine (origin ≡ landmark within 1e-4 deg, destination known), sends a mandatory descriptive User-Agent, spaces requests 1200 ms apart, retries once on network/5xx, and writes only on total success (collect-then-write);--only=<pairId>repairs one pair without churning the rest. - The phase's primary acceptance instrument is armed (amended SC3):
measurePairs()performs RT1–RT10 fully OFFLINE — corpus size, schema + RT2b public-origin proof, route shape, probe exclusion, haversine↔summary band [0.85, 1.10] + bbox+0.05 deg, speed sanity [1.0, 30] m/s, codec round-trip per route, ODbL header surfaces, gz budget (measured 16,576 B / 102,400 B), alternatives floor (8 multi-route pairs / floor 4). The CLI (npm run routing:corpus) and the suite (npm run routing:test) assert the SAME numbers. - 05-01's deferred gates armed themselves exactly as designed: loader-env L3 now proves the default source serves pair 1 at its pinned origin and resolves honest null ~300 m away; F8's positive half runs its assertions now that pairs exist; C6 re-pinned from the empty-seed state to the populated corpus.
- Suite state: 35 passed, 0 failed (C1–C6, F1–F8, L1–L3, P1–P8, RT1–RT10);
npm run routing:typecheckexit 0; zerofetch(occurrences in the gate (only the maintainer tool touches the network).
Task Commits
Each task followed RED→GREEN with atomic commits:
- task 1: pinned golden-pairs corpus + fetch script + populated committed dataset
01b0ed6test(05-02): tighten loader-env L3 to require pair 1 serving at pinned origin (RED)4e89cfffeat(05-02): pinned golden-pair corpus + OSRM-demo fetch tool + populated committed dataset (GREEN)
- task 2: the offline corpus tolerance gate (CLI + in-suite Nyquist gate)
63ef408test(05-02): add failing offline corpus tolerance gate suite RT1-RT10 (RED)6c0880bfeat(05-02): offline corpus tolerance gate — measurePairs core + CLI + in-suite RT1-RT10 (GREEN)
Files Created/Modified
routing/test/fixtures/golden-pairs.json— the 15-pair pinned corpus verbatim from the plan (pairId, originId, pinned origin + label, destinationId), plus klBbox, fixtureGzipBudgetBytes (102400), pendingProbeDestinationId (national-museum), alternativesFloorPairs (4)routing/scripts/fetch-route-fixtures.mjs— the build-time tool: pre-flight D-12 proof, UAaraharah-fixtures/1.0, 1200 ms delay, one retry, hard-fail diagnostics naming the pair, 2-space JSON + trailing newline, header fields preserved from the committed filerouting/src/data/route-fixtures.json— 15 pairs / 23 routes committed (waspairs: [])routing/scripts/route-corpus.mjs—measurePairs(corpus, fixtures, gazetteer, fixturesPath?)+ CLI with per-check table, measured gz size, fixed escalation ladder (--onlyrepair → regenerate → re-gate); imports decode/encode/haversine from../src/index.ts; direct-invocation guardrouting/test/corpus.test.mjs— onetest()per RT check assertingviolations.length === 0with named messages; prints gz size + multi-route count so suite output and CLI output agreerouting/test/loader-env.test.mjs— L3 armed (RED commit); header comment updatedrouting/test/contract.test.mjs— C6 re-pinned to populated corpus (10..20 pairs), ODbL assertions unchangedpackage.json—"routing:fixtures"delegaterouting/package.json—"fixtures"+"corpus"scripts
Decisions Made
- C6 re-arm (05-01 documented the handoff on the test itself: "the seed ships EMPTY — plan 05-02's build-time script populates it"): the empty-state pin became a populated-state pin (10..20 pairs); the ODbL header gate (T-05-06) is unchanged. Same category as the plan-ordered L3 update.
- Optional 4th
fixturesPathparameter on measurePairs — RT9's spec gzips the committed file; the default (dataset URL relative to the script) keeps the plan's 3-arg signature valid at both call sites. - Whole-corpus pre-flight validation in the fetch script — nothing is sent until every pair is proven public, the strongest reading of D-12's red line.
- No padding of alternates — the demo server returned 1 route for 7 pairs; the floor is met by 8 genuine multi-route pairs. Fabricating extra routes would poison RT5/RT7.
Deviations from Plan
Auto-fixed Issues
1. [Rule 1 - Stale state pin] C6 empty-seed assertion re-armed to the populated corpus
- Found during: task 1 GREEN verification
- Issue: 05-01's
contract.test.mjsC6 assertedpairs.length === 0("the seed ships EMPTY — plan 05-02's build-time script populates it"), which the plan's task-1 acceptance ("05-01's suites pass against REAL data") supersedes; the plan explicitly ordered the analogous L3 update but C6's identical handoff pin needed the same treatment - Fix: re-pinned C6 to assert 10..20 pairs; ODbL header assertions unchanged
- Files modified: routing/test/contract.test.mjs
- Commit:
4e89cff
Judgment calls within plan laws (not deviations)
measurePairs' optional 4thfixturesPathparameter (RT9 spec requires reading the committed file; default keeps the 3-arg shape)- Fetch script validates the entire corpus pre-flight rather than per-pair lazily (D-12 strongest reading)
Known Stubs
None. The 05-01 known stub (route-fixtures.json pairs: []) is resolved by this plan — the corpus is fully populated and gate-pinned.
Threat Surface Scan
No new surface beyond the plan's <threat_model>: the only network touchpoint is the maintainer fetch tool itself (T-05-05b — the declared, documented boundary; the gate is grep-proven offline), the committed dataset ships public data only (RT2b mechanically proven), the gz budget gate gives the T-05-12 early warning (16,576 B / 102,400 B), and the ODbL surfaces are regeneration-proof (RT8). No threat flags.
Issues Encountered
- Node lives under nvm in this environment; non-interactive shells start without it — every command sourced
~/.nvm/nvm.shfirst (05-01 precedent). No project impact. - OSRM demo stayed reachable throughout; the plan's unreachable-server checkpoint path never triggered.
User Setup Required
None — no external service configuration. The OSRM demo is touched only by the maintainer tool (npm run routing:fixtures), never by tests, CI, builds, or the runtime.
Next Phase Readiness
- 05-04 (web route surface): imports
createFixtureRoutingSourcefrom@araharah/routing/src/index.ts— the committed corpus now serves 15 real pairs with best-first options, decoded geometry + cumulative distances, honest null for unknown origins (the "router pending" state). - 05-05 (gates):
?fixpair=<pairId>values are exactly the 15 committed pairIds (getPairOriginresolves each); BA9's 200 KB all-in budget has 16.6 KB of fixtures against it; the C4 banned-token gate can grow with the corpus script as planned. - Phase 6 (guidance): route snapshots can embed decoded option geometry with
cumulativeDistanceMderived at decode — the D-07 fields are live data now, not just types.
Phase: 05-routing-route-display Completed: 2026-10-23
Self-Check: PASSED
- All 4 created files verified present on disk (golden-pairs.json, fetch-route-fixtures.mjs, route-corpus.mjs, corpus.test.mjs).
- All 4 plan commits verified in git log:
01b0ed6,4e89cff,63ef408,6c0880b(RED→GREEN per task). npm run routing:corpusexit 0 (RT1–RT10 ok, gz 16576 B);npm run routing:test35 passed, 0 failed;npm run routing:typecheckexit 0.- Committed dataset: 15 pairs, ODbL-1.0 header, zero probe-id destinations.
- STATE.md and ROADMAP.md untouched (orchestrator-owned writes); only 05-02-SUMMARY.md added (force-add, .planning/ ignored).