From e9ab1f03ebe56cbaa243c67e296c9a6775645a67 Mon Sep 17 00:00:00 2001 From: que01 Date: Tue, 18 Aug 2026 13:59:42 +0800 Subject: [PATCH] chore(task): plan native-only pipeline replacement --- .../check.jsonl | 1 + .../design.md | 51 +++++++++++++++ .../implement.jsonl | 1 + .../implement.md | 27 ++++++++ .../prd.md | 63 +++++++++++++++++++ .../task.json | 26 ++++++++ 6 files changed, 169 insertions(+) create mode 100644 .trellis/tasks/08-18-native-only-pipeline-replacement/check.jsonl create mode 100644 .trellis/tasks/08-18-native-only-pipeline-replacement/design.md create mode 100644 .trellis/tasks/08-18-native-only-pipeline-replacement/implement.jsonl create mode 100644 .trellis/tasks/08-18-native-only-pipeline-replacement/implement.md create mode 100644 .trellis/tasks/08-18-native-only-pipeline-replacement/prd.md create mode 100644 .trellis/tasks/08-18-native-only-pipeline-replacement/task.json diff --git a/.trellis/tasks/08-18-native-only-pipeline-replacement/check.jsonl b/.trellis/tasks/08-18-native-only-pipeline-replacement/check.jsonl new file mode 100644 index 0000000..9dd3234 --- /dev/null +++ b/.trellis/tasks/08-18-native-only-pipeline-replacement/check.jsonl @@ -0,0 +1 @@ +{"_example": "Fill with {\"file\": \"\", \"reason\": \"\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."} diff --git a/.trellis/tasks/08-18-native-only-pipeline-replacement/design.md b/.trellis/tasks/08-18-native-only-pipeline-replacement/design.md new file mode 100644 index 0000000..35545c6 --- /dev/null +++ b/.trellis/tasks/08-18-native-only-pipeline-replacement/design.md @@ -0,0 +1,51 @@ +# Design + +## Provider Boundary + +`build-area.js` will resolve a native provider by default. Native stages consume only OSM, native +road overrides, and `native-road/` outputs. Legacy `intermediates`, `reimport`, and osm2streets +Blender input remain behind explicit legacy selection and keep their existing output contract. + +## Native Data Flow + +```text +OSM + native-road-overrides.json + -> compile-native-roads.js + -> native-road/layers/*.geojson + compiled.json + traffic-signals.json + -> Blender generate_scene.py --native-road --traffic-signals + -> .blend + -> Cesium/package GLB + manifest + runtime/traffic-signals.json + -> preview HTML + optional native vehicle route +``` + +The native compiler is the sole authority for road geometry, lane semantics, intersection surfaces, +stop lines, and signal runtime. No native stage reads `geojsonDir` or legacy assembly files. + +## Preview Route + +Add a native route adapter that derives route segments from `compiled.json` model roads/endpoints and +native lane/connector geometry. If the native route cannot be built for a valid area, preview remains +usable without vehicles and records a warning; missing legacy osm2streets lane polygons is never a +hard failure on the native path. + +## Package Runtime + +The package stage will copy the native-road signal runtime into its staging runtime directory and +declare it in the package manifest. Preview receives the package-relative runtime URI. Legacy signal +runtime publication remains conditional on the legacy provider. + +## Configuration And Compatibility + +`roadProvider` defaults to `native`; native stages are the default stage set. QGIS config fields and +legacy stage aliases remain accepted for explicit migration/debug commands, but native manifests and +docs do not claim them as inputs. + +The Workbench may continue to read an existing `geojsonDir` only for an explicitly labeled reference +layer and comparison counters. Those reads are optional, isolated from native compile state, and must +never become required inputs for `/api/state`, native editing, package publication, or preview. + +## Rollback + +The original QGIS/osm2streets branch baseline is tagged +`qgis-original-baseline-20260818` on `main`. Reverting the native-only work can therefore use the tag +or switch to `main`; no destructive cleanup of legacy scripts is required. diff --git a/.trellis/tasks/08-18-native-only-pipeline-replacement/implement.jsonl b/.trellis/tasks/08-18-native-only-pipeline-replacement/implement.jsonl new file mode 100644 index 0000000..9dd3234 --- /dev/null +++ b/.trellis/tasks/08-18-native-only-pipeline-replacement/implement.jsonl @@ -0,0 +1 @@ +{"_example": "Fill with {\"file\": \"\", \"reason\": \"\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."} diff --git a/.trellis/tasks/08-18-native-only-pipeline-replacement/implement.md b/.trellis/tasks/08-18-native-only-pipeline-replacement/implement.md new file mode 100644 index 0000000..5855ffd --- /dev/null +++ b/.trellis/tasks/08-18-native-only-pipeline-replacement/implement.md @@ -0,0 +1,27 @@ +# Implementation Plan + +1. Add native provider/default-stage contracts and explicit legacy provider routing. +2. Make package publication and stage manifests consume native runtime artifacts. +3. Replace preview's hard dependency on osm2streets lane/network/intersection files with a native + route adapter and optional-route behavior. +4. Audit Blender, Cesium, preview, diagnostics, and area config for native-path legacy reads; retain + only the Workbench's optional, clearly labeled osm2streets reference layer. +5. Update README/config/spec documentation and add dependency-boundary regression tests. +6. Run native-only tests with legacy directories absent, then run focused legacy compatibility tests. +7. Run area compile/check plus available Blender/Cesium/preview validation; record any environment-only + limitation without weakening native contracts. + +## Validation + +```bash +npm run test:native-road +npm run test:traffic-signals +npm run test:road-workbench +npm run test:preview-assets +npm run road:compile -- --config config/areas/nantaizi-lake-innovation-valley.json +npm run road:check -- --config config/areas/nantaizi-lake-innovation-valley.json +node --check scripts/build-area.js +``` + +The final gate must also exercise a native-only config/output directory without QGIS/osm2streets +intermediates and assert package/runtime/preview outputs. diff --git a/.trellis/tasks/08-18-native-only-pipeline-replacement/prd.md b/.trellis/tasks/08-18-native-only-pipeline-replacement/prd.md new file mode 100644 index 0000000..10a56e8 --- /dev/null +++ b/.trellis/tasks/08-18-native-only-pipeline-replacement/prd.md @@ -0,0 +1,63 @@ +# Complete native-only pipeline replacement + +## Goal + +Make the native road compiler the primary and complete production path. A normal build of an +area must generate Blender, Cesium/package, and preview outputs directly from OSM plus native +artifacts without installing or running QGIS, GDAL, or osm2streets. + +The existing QGIS/osm2streets workflow remains available only as an explicit legacy/debug path and +an optional Workbench reference layer. It is protected by the `qgis-original-baseline-20260818` tag +on `main`. + +## Confirmed Current Gaps + +- `normalizeAreaConfig()` defaults `stages.intermediates` to true and `blender.roadProvider` to + `osm2streets`. +- `build-area.js` sends `intermediates` to `build-osm2streets-qgis.js` and `reimport` to GDAL/QGIS. +- Native Blender input exists, but `preview` still requires `osm2streets_web_out/lane_polygons.geojson`, + `network.json`, and `intersection_surface.geojson` for vehicle-route generation. +- Package/runtime publication still copies `outputs..trafficSignals` from the legacy GeoJSON + directory instead of the native-road runtime artifact. +- README, config templates, stage names, and manifest descriptions still present QGIS as the normal + workflow. + +## Requirements + +- R1: Native is the default road provider and default build stages do not invoke QGIS, GDAL, or + osm2streets. +- R2: Native build generates all required road, lane, marking, junction, stop-line, and traffic-signal + inputs consumed by Blender and preview; no native stage reads `osm2streets_web_out`. +- R3: Native package publication copies runtime traffic signals and any other runtime descriptors + from native-road outputs, with stable package-relative URIs. +- R4: Native preview route generation uses native lane/road topology and native intersection geometry, + or explicitly omits the optional vehicle route when native route data is unavailable; it must not + fail because legacy osm2streets files are absent. +- R5: QGIS/osm2streets stages remain callable only through an explicit legacy provider/stage selection + and are not part of native defaults or native manifests. Workbench may display their existing + GeoJSON as a clearly labeled reference/comparison layer, but native editing, compile, package, and + preview results must not depend on it. +- R6: Documentation and config templates describe native-only as the primary workflow and clearly + mark the legacy path as transitional/debug-only. + +## Acceptance Criteria + +- [ ] A clean native-only area build succeeds with QGIS absent and no `osm2streets-js-node` runtime + call, producing `.blend`, package manifest/GLB, runtime traffic signals, and preview HTML. +- [ ] Native preview opens when `osm2streets_web_out/` is absent; optional vehicle cruise either uses + native route data or is omitted with a visible non-fatal diagnostic. +- [ ] Native package manifest contains runtime traffic-signal anchors sourced from + `native-road/traffic-signals.json`; disabled signals remain absent from runtime. +- [ ] Workbench edits survive save, native recompile, package publication, and preview reload without + QGIS or osm2streets files. +- [ ] Explicit legacy QGIS/osm2streets commands still pass their existing focused tests, but no longer + run when using native defaults. +- [ ] Workbench remains usable when the optional osm2streets reference directory is absent; only the + reference layer/comparison counters degrade to unavailable. +- [ ] Tests assert the native-only dependency boundary and the QGIS baseline tag is documented. + +## Out Of Scope + +- Reimplementing QGIS editing features in the native compiler beyond existing Workbench controls. +- Deleting legacy scripts or historical output files in this task; they remain rollback/debug tooling. +- Changing Blender/Cesium visual semantics unrelated to removing the input dependency. diff --git a/.trellis/tasks/08-18-native-only-pipeline-replacement/task.json b/.trellis/tasks/08-18-native-only-pipeline-replacement/task.json new file mode 100644 index 0000000..8f6b220 --- /dev/null +++ b/.trellis/tasks/08-18-native-only-pipeline-replacement/task.json @@ -0,0 +1,26 @@ +{ + "id": "native-only-pipeline-replacement", + "name": "native-only-pipeline-replacement", + "title": "Complete native-only pipeline replacement", + "description": "", + "status": "planning", + "dev_type": null, + "scope": null, + "package": null, + "priority": "P2", + "creator": "dingkang", + "assignee": "dingkang", + "createdAt": "2026-08-18", + "completedAt": null, + "branch": null, + "base_branch": "feature/native-road-compiler", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": null, + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file