mapv10 Roadmap
Status: M0-M10 implemented; active follow-up is source-of-truth documentation reconciliation
Scope: map generator and viewer only
Primary target: continent-scale 3D fantasy map, proved from smaller slices through the first full-continent streaming artifact
mapv10 now has useful artifacts on disk and a plain Three.js viewer reading those artifacts. The early smaller-slice path remains important because it proved the pipeline, product contracts, renderer separation, and visual direction before M10 scaled the same contract to a full continent.
Current implementation status:
- Milestone 0: implemented.
- Milestone 1: implemented for a deterministic
province-slicerun. - Milestone 2: implemented with a plain Three.js viewer boot and browser nonblank verification.
- Milestone 3: implemented with generated water topology, masks, material products, and viewer water/material rendering.
- Milestone 4: implemented with realm/province/Location products, semantic ID rasters, borders, and typed picking.
- Milestone 5: implemented with route, crossing, map feature, footprint, and label products plus viewer routes/markers/labels.
- Milestone 6: implemented with raster/vector/semantic/mesh tile manifests, z0/z1 tile assets, tile previews, viewer tile selection, cancellable terrain tile loading, cache budget, and LOD switching.
- Milestone 7: implemented with terrain chunk meshes, water meshes, route ribbons, border-SDF raster rendering, mesh manifests, mesh validation, and separated renderer passes.
- Milestone 8: implemented with a validated
regional-sliceusing the same stage pipeline, product contracts, tile API, mesh API, and viewer loading path asprovince-slice. - Milestone 9: implemented as readiness evidence: explicit memory/cache/artifact budgets, coordinate precision report, many-tile streaming proof, and draft
continentpreset config. Full continent generation was intentionally deferred from M9 to M10. - Milestone 10: implemented as the first real full-continent generation/viewer proof with performance-grade streaming telemetry, LOD evidence, required-product hard-failure verification, MZ z6/z7 physical LOD + semantic display policy, and concrete remaining-work analysis.
Guiding Rules
- Generator and viewer are separate projects.
- Rust generator writes typed artifacts, previews, and validation.
- Plain TypeScript + Three.js renderer consumes artifacts.
- UI talks to renderer through typed commands/events.
- React/R3F must not own the map scene.
- Use the same pipeline for
province-slice,regional-slice,realm-slice, andcontinent. - Produce real products at every stage; do not hide important data inside memory-only structures.
- Pretty PNGs are previews, never map truth.
Milestone 0 - Skeleton And Contracts
Goal: establish the repo shape and executable boundaries.
Deliverables:
generator/Rust crate skeleton.viewer/TypeScript/Three.js skeleton.schema/folder for artifact schemas/manifests.- typed renderer API draft.
- typed event model draft.
- initial roadmap, architecture, and viewer UX docs.
Exit criteria:
- folder structure matches
architecture.md. - no generator/viewer code depends on downstream application simulation.
- no React renderer architecture is introduced.
Milestone 1 - Minimal Artifact Run
Goal: produce a tiny deterministic province-slice artifact run.
Scale:
province-slice- 2,000-10,000 km²
- 5-10 Locations
Generator stages:
00-config01-continent02-geography-graph03-heightfield14-previews
Required products:
manifest.jsonconfig.jsonstage-index.jsoncontinentPolygons.jsoncoastlines.jsonseaRegions.jsonridgeGraph.jsonbasins.jsonheight.f32.binslope.f32.binnormal.rg16.bin- preview PNGs
Exit criteria:
- same seed/config produces identical core product bytes.
- previews render from generated data.
- validation catches malformed polygons and invalid raster dimensions.
Milestone 2 - Plain Three.js Viewer Boot
Goal: load the Milestone 1 artifact run and display a clean 3D terrain scene.
Viewer systems:
- manifest loader
- binary raster loader
- Three.js renderer core
- camera controls
- resize handling
- basic layer toggles
- debug product drawer
Renderer requirements:
- no React scene ownership
- no R3F
- renderer API exists as a framework-neutral TypeScript module
- canvas renders nonblank
- terrain uses generated height data
Exit criteria:
- viewer loads the canonical generated fixture (
public/continent-lod6, served as/mapv10/runs/continent-lod6/manifest.jsonfor the current browser proof). - terrain is visible.
- height/slope/normal previews are inspectable.
- Playwright screenshot verifies nonblank desktop and wide viewports.
Milestone 3 - Water And Materials
Goal: make the map read as a real landscape, not a bare heightfield.
Generator stages:
04-water05-biomes-materials
Required products:
riverGraph.jsonriverCenterlines.jsonlakePolygons.jsonseaRegions.jsonconsumed by the mesh stage as generated open-sea surface truthwaterMask.u8.binriverWidth.f32.binbiome.u8.binmaterialWeights.rgba8.binforestMask.u8.binwetlandMask.u8.bin- previews
Viewer systems:
- water mesh rendering
- terrain material/splat rendering
- geography map mode
Exit criteria:
- rivers/lakes derive from generated topology.
- lakes are rendered from polygons/meshes, not bbox quads.
- open sea is rendered from generated sea-region mesh products, not a viewer-created plane.
- terrain materials are driven by generated material products.
Milestone 4 - Provinces, Locations, Picking
Goal: prove the strategic map layer.
Generator stages:
06-political- basic semantic ID rasters
Required products:
realmPolygons.jsonprovincePolygons.jsonlocationPolygons.jsonprovinceId.u32.binlocationId.u32.binneighborGraph.jsonpolitical-preview.png
Viewer systems:
- border rendering
- hover/selection
- typed pick results
- political map mode
Exit criteria:
- one province contains 5-10 Locations.
- picking returns typed entity refs.
- borders render over 3D terrain.
- ID rasters are used for picking/debug, not preview PNG colors.
Milestone 5 - Routes, Features, Labels
Goal: make the map readable as a strategy map.
Generator stages:
07-routes08-map-features
Required products:
locationConnections.jsonroadNetwork.jsonrouteGraph.jsonrouteCenterlines.jsoncrossingAnchors.jsonmapFeatureAnchors.jsonmapFeatureFootprints.jsonlabelAnchors.json
Viewer systems:
- route ribbons
- sparse point markers
- label projection
- label collision/fade
Exit criteria:
- labels are generated anchors, not baked images.
- route and feature markers can be toggled.
- labels change by zoom band.
Milestone 6 - Tile Pyramid And LOD
Goal: make the architecture scale beyond the prototype slice.
Status: implemented for province-slice.
Generator stage:
11-tile-pyramid
Required products:
- raster tile manifests
- vector tile manifests
- semantic tile manifests
- mesh tile manifests
- tile previews
Viewer systems:
- camera-bound tile selection
- cancellable tile loading
- explicit tile cache
- LOD switching
Exit criteria:
province-sliceandregional-sliceuse the same tile API.- viewer does not load all high-detail products by default.
- missing required tiles fail visibly.
Milestone 7 - Mesh Products And Render Passes
Goal: move from prototype geometry to explicit render products.
Status: implemented for province-slice.
Generator stage:
12-meshes
Required products:
- terrain chunk meshes
- water meshes
- border-SDF raster products
- route ribbons
- mesh manifests
Viewer systems:
- terrain pass
- water pass
- route pass plus border-SDF terrain-shader branch
- overlay pass
- marker pass
- label pass
- picking/debug pass
Exit criteria:
- render systems are separate.
- meshes have finite, non-degenerate geometry.
- non-rectangular shapes use real generated geometry.
Milestone 8 - Regional Slice
Goal: prove the target strategic scale.
Status: implemented.
Scale:
regional-slice- 45,000 km²
- roughly 90-180 Locations
Exit criteria:
- same pipeline as
province-slice: implemented. - same viewer path: originally proven on a local regional fixture, now superseded by the canonical
viewer/public/continent-lod6browser proof. - zoom bands work from region to Location detail: browser verifier loads z0 overview and z1 detail tiles.
- generated products stay inspectable: implemented through manifests, previews, tile products, mesh products, and validation reports.
Milestone 9 - Continent Readiness
Goal: prepare for continent-scale generation.
Status: implemented as readiness artifacts; full continent generation is not part of this milestone.
Deliverables:
- memory budget documented.
- tile cache budget documented.
- artifact size budget documented.
- coordinate precision verified.
- streaming validated with many tiles.
- continent preset config drafted.
Exit criteria:
- no architecture changes required to move from
regional-slicetocontinent: readiness report and draft preset show the same config/product contract. - at the end of M9, only generator content/scale settings remained; M10 has since generated and verified the full continent run.
Milestone 10 - Full Continent Streaming And LOD Proof
Goal: turn the draft continent preset into the first real full-continent artifact run and prove that the viewer can stream it with useful LOD.
Status: implemented by the canonical viewer/public/continent-lod6 fixture and viewer/verification/m10-lod6-continuity-proof.json.
Scale:
continent- millions of km²
- thousands of strategic Locations
- many-tile artifact set loaded by viewport and zoom, not eagerly
Deliverables:
- validated full-continent generator run: implemented.
- continent artifact-size, count, tile, mesh, and coordinate-precision reports: implemented under
readiness/andstages/13-readiness/. - viewer proof that boot loads only overview/core products plus visible tiles: implemented by the browser probe network and debug-state telemetry.
- request cancellation, max in-flight request limit, cache bytes, and eviction counters: implemented in terrain/runtime/auxiliary mesh caches and exposed through debug telemetry.
- scripted browser performance probe across continent overview, province/realm zoom, Location detail, detail tile boundary pan, and zoom-back: implemented.
- LOD proof for terrain, water, borders, routes, labels, and markers: implemented through named visible tile bands and auxiliary mesh tile membership; visual quality remains subject to verifier-lane review.
- required-product hard-failure proof: implemented in
viewer/scripts/verify-browser.mjsand recorded by the focused M10 verifier artifact.
Exit criteria:
- full
continentrun uses the same product pipeline as smaller presets. - streaming is proven by counters and cache budgets, not by visual impression.
- LOD levels are proven by zoom-band/selection evidence, runtime counters, and screenshots.
- missing required products fail visibly and hard; the viewer must not silently fall back to
sample-runor fabricated products. - no downstream game/application logic is introduced.
Milestone 11 - World Genesis Source of Truth
Goal: replace the synthetic ridge/basin/lake/river/hardcoded-feature placeholder stack with a recipe-driven, archetype-composable, terrain-genesis-and-hydrology-truth-product pipeline.
Status: ten sub-waves split into one accepted ADR + nine implementation
waves (S, C, G1, G2, T-M11e, T-M11f, T-M11g, D, P, Final-A). Wave
Final-B (baseline + capture refresh) is deferred. The committed
contract is
docs/ad-mapv10-m11-world-genesis-source-of-truth.md.
| Sub-wave | Scope | Status |
|---|---|---|
| Wave S (M11a) | Five JSON schemas, bundled vocabulary, four starter recipe pairs, Rust DTO mirrors, validator stubs, narrative docs, validator script | Landed |
| Wave C | .claude/rules/mapv10.md + four agent files + roadmap prompt updated to encode the M11 invariants | Landed |
| Wave G1 (M11c) | stages/continent.rs + stages/geography_graph.rs redesign — Lloyd-Voronoi tectonic provinces, eight terrain-genesis truth products, four CLI flags, four-tuple determinism | Landed |
| Wave G2 (M11d) | stages/water.rs redesign — priority-flood + D8 + Strahler/Shreve + marching-squares lake polygons + 10 raster channels + hydrology truth product | Landed |
| Wave T-M11e | stages/biomes_materials.rs vocabulary-driven Whittaker classifier (orographicRainfall + crustAge ingest) | Landed |
| Wave T-M11f | stages/political.rs consume basin_id / valley_id / orogen_segment_id membership for Location classification | Pending political.rs Tier-0 follow-up; tracked in next-work.md |
| Wave T-M11g | stages/routes.rs consume passCandidates as first-class route nodes; bedrockHardness-driven slope cost | Landed |
| Wave T-M11h | stages/map_features.rs consume World Intent Directives for named features; delete the six hardcoded anchors | Pending; tracked in next-work.md |
| Wave D (M11i+j) | tile pyramid + meshes new raster/mesh ingest + viewer-side typed loaders + Valenar export enrichment | Pending; tracked in next-work.md |
| Wave P (M11k-edit) | World Lab UX shell — recipe editor, intent editor, run launcher, run library, compare runs (plain DOM, no React, no R3F) | Landed |
| Wave Final-A (M11l) | New archetype-preset scenarios + unsatisfiable-hard-fail scenario + river-branching + marching-squares-lake + no-rectangular-fallback + no-hardcoded-anchors + world-lab boundary scenarios; new Mapv10GateSpec variants; CLI forbidden-pattern grep guard; audit-doc closures; ADR M11l section; roadmap + next-work updates | Landed (this wave) |
| Wave M11x-W1 (Explore) | Explorer audit of the bbox-grid coast tile path in meshes.rs::terrain_mesh_for_tile; coverage matrix for the new contract; A2 audit findings | Landed |
| Wave M11x-W2 (Contract) | mesh-product.schema.json family/renderPass/boundaryIds extension; new coastlines.schema.json v2 with boundaryEdges; meshes.rs::contract() text rewrite; ADR ad-mapv10-m11x-coast-geometry-contract.md; architecture.md § Water Architecture and docs/generator.md Stage 12 rewrites; .claude/rules/mapv10.md M11x invariants block; roadmap + next-work updates | In progress (this wave) |
| Wave M11x-W3 (Implement) | terrain_mesh_for_tile rewrite to clip against tile-local continent/sea polygons; new seafloor_mesh_for_tile and shoreline_transition_mesh_for_tile writers; coastlines.json v2 emit with boundaryEdges; deletion of terrain_mesh_emits_full_seabed_for_mixed_coastline_tiles and replacement tests; clipping algorithm selection (Sutherland-Hodgman / Greiner-Hormann / earcutr / Shewchuk CDT) | Pending |
| Wave M11x-W4 (Validators) | Generator-side validators coast_mesh_terrain_land_clipped_to_continent_polygon, coast_mesh_terrain_seafloor_clipped_to_sea_polygon, coast_mesh_no_triangle_straddles_boundary_id, coast_mesh_shoreline_transition_owns_every_coast_segment, coast_mesh_shoreline_transition_owns_every_lake_segment, coast_mesh_boundary_ids_referenced_by_exactly_two_families, coast_mesh_terrain_land_excludes_lake_interiors, coastlines_json_boundary_edges_match_segment_count, coast_mesh_no_full_rectangular_grid_for_mixed_coast_tile; viewer-side scenario gates for the new families | Pending |
| Wave M11x-W5 (Hydrology conditioning contract) | New Stage 4c terrain-conditioning seam between Stage 4 hydrology and Stage 5 biomes. New schema/terrain-conditioning.schema.json declaring conditionedHeight, conditionedSlope, conditionedNormal, riverbedElevation, channelDepth, waterSurfaceElevation, bankMask as required products. New stage scaffold generator/src/stages/terrain_conditioning.rs with generate() signature consuming &HeightfieldProducts + &WaterProducts immutably and returning ConditioningProducts. ADR ad-mapv10-m11x-hydrology-conditioning-contract.md. pipeline.rs registers Stage 4c. validation.rs ships validate_terrain_conditioning stub. Wave 5 is contract-only: stub body returns zero-allocated products; Wave 6 fills them in. | Pending (this wave) |
| Wave M11x-W6 (Hydrology incision implementation) | Implement priority-flood + stream-power incision (Howard 1994) inside terrain_conditioning::generate() to populate riverbedElevation, channelDepth, and waterSurfaceElevation; depth derived from Leopold-Maddock hydraulic geometry (depth = c * Q^f). Recompute conditionedSlope and conditionedNormal from the incised height. Thread the conditioning products into Stage 5 biomes-materials, Stage 11 tile-pyramid, and Stage 12 meshes consumers per the ADR. Extend validate_terrain_conditioning to assert channelDepth > 0 where streamOrder > 0 and riverbedElevation < waterSurfaceElevation for every river cell. | Pending — depends on M11x-W5 |
| Wave M11x-W7 (Viewer loader / schema alignment) | viewer/src/data/types.ts retires the terrain mesh family, splits LoadedRun.meshes.terrainMeshes into three per-family slots, adds the 7 conditioning channels to LoadedRuntimeTile.raster + SidecarKey, adds a shorelineTransition render pass + ShaderMaterial in Mapv10ThreeRenderer. viewer/src/data/manifestLoader.ts consumes terrainLandMeshManifest / terrainSeafloorMeshManifest / shorelineTransitionMeshManifest + the 7 conditioning rasters via requiredProduct(...). viewer/scripts/forbidden-pattern-check.mjs flags viewer-side coastline extraction AND viewer-side hydrology derivation. Generator-side ripple: MeshTileSlot replaces terrain_mesh_key with three per-family vecs (tile_pyramid.rs::generate); valenar_worlddata.rs::mesh_artifacts() emits three per-family artifact-map entries instead of the retired terrain_mesh_manifest; validation.rs mesh-slot-key assertion updates to span the three vecs. Folds the prior M11x-W7b waterMask cleanup into a single ripple. | Pending (this wave) |
| Wave Final (M11l-Final-B) (Fixture regen + scenarios + capture refresh) | Regenerate viewer/public/continent-lod6/ and viewer/public/sample-run/ against the new five-family mesh manifest + seven conditioning rasters; refresh baselines under viewer/baselines/browser/<run-id>/ and tools/llm-bundles/captures/ once the chain is fully live; consolidates the prior M11x-W7 (fixture refresh) and M11x-W9 (baseline refresh) rows. Rolls into the existing M11l-Final-B baseline wave. | Deferred — blocked on M11x-W7 + Wave T M11h + political.rs Tier-0 |
M11x Acceptance Criteria
-
mesh-product.schema.jsonfamily enum dropsterrain, addsterrain-land,terrain-seafloor,shoreline-transition; renderPass enum addsshoreline-transition; mesh asset gains optionalboundaryIds[]field; schema version bumped tomapv10-mesh-family-v2(Wave 2). -
coastlines.schema.jsonshipped withboundaryEdges[]and versionmapv10-coastlines-v2(Wave 2). -
meshes.rs::contract()text replaced; old "terrain meshes emit full grids for coastal tiles" rule removed; new clipped-mesh + BoundaryId + viewer-extraction-ban rules added (Wave 2). -
architecture.md§ Water Architecture anddocs/generator.mdStage 12 reflect the M11x contract (Wave 2). -
.claude/rules/mapv10.mdcarries the M11x invariants block (Wave 2). - ADR
ad-mapv10-m11x-coast-geometry-contract.mdcommitted (Wave 2). -
terrain_mesh_for_tilerewrite landed;terrain_mesh_emits_full_seabed_for_mixed_coastline_tilestest deleted and replaced (Wave 3). - Validators landed in both generator and viewer (Wave 4).
- Hydrology conditioning contract landed: Stage 4c scaffold,
terrain-conditioning.schema.json, ADRad-mapv10-m11x-hydrology-conditioning-contract.md,validate_terrain_conditioningstub (Wave 5). - Hydrology incision implementation landed: stream-power incision + Leopold-Maddock depth + Stage 5/11/12 consumer threading (Wave 6).
- Viewer typed loaders + render pipeline + generator-side
MeshTileSlotand Valenar artifact-map ripple updated; forbidden-pattern guards extended (Wave 7). -
continent-lod6andsample-runfixtures regenerated, scenarios green, and baselines refreshed against the M11x-live chain (Final wave / M11l-Final-B).
Deliverables (Wave Final-A, shipped):
- 15 new scenarios under
viewer/src/scenarios/mapv10_scenarios.json, scattered to their peer clusters (continent / close-zoom-detail / visual-foundation / world-lab boundary). - New Mapv10GateSpec variants in
viewer/src/scenarios/scenarioTypes.ts(recipeArchetypeTokenPresent,biomeRasterContainsToken,terrainGenesisBasinCountMatchesRecipe,recipeSatisfactionScoreAtLeast,recipeUnsatisfiedHardCountAtLeast,hydrologyMaxStrahlerOrderAtLeast,lakePolygonsAreMarchingSquaresContour,riverMouthsTerminateInSea,routesUsePassCandidates,intentDirectiveSatisfied,intentDirectiveHardFail,codeBoundaryNoImports,manifestContentHashChangedFromPrior). - New CLI grep guard
viewer/scripts/forbidden-pattern-check.mjsplusnpm run check:forbidden-patterns+npm run lint:m11package scripts. The guard is in expected-FAIL state whilestages/map_features.rsstill ships the six hardcoded anchors —TODO(M11h)row innext-work.mdtracks the resolution. - New
viewer/src/ui/world-lab/__tests__/world-lab-boundary.test.tsVitest unit test enforcing the no-renderer / no-three import contract on the World Lab UX shell. - Cross-scenario state-file plumbing in
viewer/scripts/run-scenarios.mjsfor the recipe-edit hash-change pair, plus generator-product fetching for the new gate variants. - Closure annotations on the visual-foundation audit docs
(
verification/visual-foundation-audit/02-viewer-audit.mdand03-generator-audit.md). ## M11lsection appended todocs/ad-mapv10-m11-world-genesis-source-of-truth.md.
Deferred (Wave Final-B):
- Baseline and capture refresh under
viewer/baselines/browser/<run-id>/and viasbundle capture mapv10 <scenario>. TODO(Final-B). Blocks on Wave T M11h + political.rs Tier-0 so the regenerated fixture carries the M11 truth products. - Full population of the new scenario gates against a real generator
run (Wave Final-A ships the scenarios in pre-implement FAIL state
per
wave-protocol.md's fail-first pattern; populating a green scenario evidence baseline requires the M11 generator surface to produce realrecipeRef.contentHash+recipeSatisfaction.directives[]terrainGenesis.json+hydrology.jsonartifacts).
Exit criteria (Milestone 11 closure):
- Five JSON schemas + four starter recipes + bundled vocabulary committed (Wave S).
- Path-scoped rule + agent files reflect the M11 invariants (Wave C).
-
stages/continent.rs+stages/geography_graph.rsredesigned (Wave G1). -
stages/water.rsredesigned with hydrology truth products (Wave G2). -
stages/biomes_materials.rs+stages/routes.rsconsume the truth products (Wave T-M11e, T-M11g). -
stages/political.rs+stages/map_features.rsconsume the truth products (Wave T-M11f, T-M11h). Tracked innext-work.md. - Tile pyramid + meshes ingest new raster/mesh channels
(Wave D / M11i+j). Tracked in
next-work.md. - World Lab UX shell shipped in plain DOM (Wave P).
- Scenarios + gates + grep guard + audit closures + ADR + roadmap updates committed (Wave Final-A).
- Baseline + capture refresh against a real M11 run (Wave Final-B). TODO(Final-B).
Current Follow-Up Recommendation
M10 is structurally implemented and the LOD/Data Coherence Foundation chain (Waves 1-4.5) has now shipped on top of it. MZ extends that foundation with an eight-rung physical LOD ladder (z0..z7), repairs z1 so it is no longer a same-sample physical refinement, adds generated closeDetailNormal truth with close-detail scale metadata, and separates strategic semantic zoom into the generated semanticDisplayPolicy product. The R-25 route-adaptive-batching baseline (23 scenarios, 0 hard failures, 0 warnings) is historical: the gate vocabulary has since grown (Wave 1 added forbidZ0UnderlayAtPrimaryZ, ancestorZDistanceMax, sidecarReadyForActiveMeshes, noPlaceholderTextureBound, coverageHoleMax, labelTextUniqueness, labelTextMinDistinctCount, labelMaxDuplicatesForText; MZ added semanticPolicyLoaded, semanticBandEquals, primaryZAtLeast, closeDetailScaleMin, and influenceProductRequiredBeforeRendering) and the current scenario evidence covers all 32 defined scenarios. Current evidence in viewer/verification/scenarios/latest/scenario-results.json records scenarioCount: 32, stores 32 result entries, and reports 0 hard budget/fail-condition issues; the two warn-only budget entries are fallbackSlotCountMax=48 > 32 in mapv10_zoom_continent_to_location_clean_lowland and mapv10_zoom_realm_to_location_overlays_z5. PROC reclassifies remote/network-throttled stress metrics as non-blocking evidence for a local-only product; clean/local omitted-slot regressions still belong in blocking gates. The local browser screenshot baselines under viewer/baselines/browser/continent-lod6/ were captured 2026-05-07 against the pre-Wave-2 fixture and need a user-accepted recapture/update only after foundation behaviour is accepted; never update them to mask a regression. docs/wave-3b-lod-ladder-camera-decision.md records the accepted and implemented z6/z7 physical LOD decision.
The recent foundation passes:
- Moves byte-length checks, typed-array decode, mesh world-coordinate transform, per-vertex normal computation, and vector-tile JSON parse off the main thread into a fixed pool of decoder workers (transferable typed-array results, zero-copy on most browsers).
- Restores incremental batched merge for water/route meshes per material kind, with a per-batch dirty signature and a
FrameBudgetthat amortizes rebuild over frames so transitions never produce a synchronous burst; borders render from the generated border-SDF raster in the terrain shader. - Memoizes label canvas/texture pairs by text and caches footprint materials by kind, eliminating per-label canvas allocation churn and per-footprint material allocation.
- Keeps generator/viewer separation, the 24-tile request scheduler, the typed renderer events, and zero-fallback hard failure on missing required products.
- Established the scenario CLI, browser screenshot baseline commands, generated-artifact middleware boundary, and run-local Valenar export validation while keeping Valenar's runtime default on its small dummy fixture.
Remaining lane work after docs reconciliation:
- Wire scenario/browser verification into CI after the fixture/bootstrap and baseline-distribution policy is settled.
- Keep generated Valenar WorldData as a run-local product lane until an explicit import/package step selects it; do not switch Valenar's runtime default away from the dummy fixture in a docs reconciliation wave.
- Add targeted direct polish scenarios for borders and labels before changing their visual thresholds.
- Continue to treat full state-field producer transport, Stage 6 Voronoi optimization, and binary artifact fingerprinting as deferred unless explicitly scoped.