# Implementation Plan: QGIS Traffic Signal Overrides ## 1. Contracts and Pure Logic - [x] Add an auxiliary editable-layer definition without modifying `SCENE_LAYERS` ordering. - [x] Extend OSM arm parsing with deterministic approach identity inputs. - [x] Split traffic-signal logic into automatic editable-feature generation, feature validation/normalization, and runtime pose derivation. - [x] Use stable technical ids for runtime signal ids; keep `display_id` as editable metadata. - [x] Add pure Node tests for T/cross counts, stable ids, movement/heading reconstruction, disabled features, duplicate ids, and invalid values. ## 2. Intermediates and QGIS - [x] Write `traffic_signal_assemblies.geojson` after stop-line/intersection outputs are stable. - [x] Import the auxiliary point layer into the GeoPackage after the nine render layers. - [x] Extend generated QGIS project code with point/direction styling, labels, and field widgets/constraints. - [x] Confirm the auxiliary layer is excluded from merged road scene ordering and raster preview behavior. ## 3. Reimport and Stage Ownership - [x] Extend `reimport-gpkg.js` to discover/export render and auxiliary layers through staging. - [x] Validate the staged editable layer before replacing any output artifact. - [x] Rebuild runtime `traffic_signals.json` from editable GeoJSON after `intermediates`, `reimport`, and at Blender entry. - [x] Remove Blender-entry OSM placement regeneration so QGIS edits remain authoritative. - [x] Extend stage manifests and diagnostics with auxiliary input/output records and feature counts. ## 4. Cross-Layer Consumers - [x] Preserve `display_id` and stable runtime ids through Blender and Cesium metadata where useful. - [x] Verify static signal objects, dynamic lenses, countdown nodes, and vehicle stop behavior all consume the same enabled runtime records. - [x] Update pipeline specifications to replace the old prohibition with the editable-layer/derived-runtime distinction. ## 5. Validation - [x] Run Node syntax checks and focused unit tests. - [x] Run existing preview-assets, preflight, budget, and relevant pipeline tests. - [x] Run `intermediates` and inspect the GeoPackage/QGIS project feature schema and styling. - [ ] Make a controlled QGIS edit to one signal (display id, point, heading), run `reimport,blender,cesium,preview`, and verify only the intended assembly changes. (`reimport` and Blender passed; Cesium/preview refresh was not repeated.) - [x] Confirm an invalid/duplicate edit fails before overwriting valid outputs. - [ ] Inspect Blender/Cesium structural digests and Safari preview for T and cross junctions. (Blocked this run by Blender 4.5.12 Metal startup SIGSEGV before project Python.) ## Risky Files / Rollback Points - `scripts/lib/traffic-signals.js`: identity and pose contract; land pure tests before pipeline integration. - `scripts/build-osm2streets-qgis.js`: GeoPackage recreation and generated QGIS Python; verify auxiliary import independently before styling. - `scripts/reimport-gpkg.js`: atomic overwrite boundary; preserve staging semantics. - `scripts/build-area.js`: stage ownership; ensure Blender derives from editable GeoJSON rather than overwriting it. - `blender/osmassets/traffic_signals.py` and preview runtime should require minimal or no geometry changes; unexpected edits here indicate contract leakage. ## Review Gate Before Start - [ ] User approves the final planning summary. - [ ] `prd.md`, `design.md`, and `implement.md` agree on full editable layer ownership and out-of-scope intermediates persistence. - [ ] No unresolved product decision remains.