# Implementation Plan ## Checklist 1. Capture a parity baseline before product-code edits: `node scripts/parity.js capture feature-registry-before --stages blender,cesium` 2. Add `blender/osmassets/features.py` with a small `FeatureHandler` contract and `dispatch_ways(...)`. 3. Import `features.py` in `blender/generate_scene.py`. 4. Convert the current OSM way `if` / `elif` chain into ordered local handlers: water, grass, scrub, tree-row, building. 5. Keep handler bodies mechanically equivalent to the current branch bodies. 6. Leave road GeoJSON/fallback, tree placement, fountain point processing, scene metadata, and `SCENE_DONE` behavior unchanged except for any small phase comments needed to clarify ordering. 7. Run Python checks: - `python3 -m py_compile blender/osmassets/features.py` - `python3 -m py_compile blender/generate_scene.py` - `python3 -m unittest blender/tests/test_pure.py` 8. Capture parity after the refactor: `node scripts/parity.js capture feature-registry-after --stages blender,cesium` 9. Compare parity: `node scripts/parity.js compare feature-registry-before feature-registry-after` 10. Update `.trellis/spec` and `docs/changelog.md` only for durable registry conventions or P2 status changes discovered during implementation. 11. Commit, archive the task, and record the journal entry. ## Validation Commands ```bash node scripts/parity.js capture feature-registry-before --stages blender,cesium python3 -m py_compile blender/osmassets/features.py python3 -m py_compile blender/generate_scene.py python3 -m unittest blender/tests/test_pure.py node scripts/parity.js capture feature-registry-after --stages blender,cesium node scripts/parity.js compare feature-registry-before feature-registry-after ``` ## Risk Points - Handler order is equivalent to the old `elif` chain. Changing it can alter which feature claims a way. - Object creation phase order affects `.blend` and GLB digests. - Material creation order affects GLB material indices. - Tree rows and scrub interior trees feed the later tree placement phase; do not place trees inside the way dispatch loop. - `catalog.check_layers()` must stay warning-only and keep the exact printed prefix. - Do not add a new road layer id list; keep deriving road layers from `catalog.ROAD_LAYERS`. ## Rollback Point If parity shows a non-ignored difference, first compare object order, object names, mesh/material names, `SCENE_DONE`, and scene custom properties. If the cause is not obvious, revert the registry dispatch and return to the current way loop before trying a narrower refactor.