refactor: move road compiler core into package

This commit is contained in:
2026-08-25 17:12:58 +08:00
parent 5220c6b2a2
commit 73707dabbe
35 changed files with 11739 additions and 454 deletions

View File

@@ -0,0 +1,53 @@
# Phase 1 Technical Design
## Boundary
`packages/road-compiler/` becomes the single implementation owner for native
road compilation. It is a CommonJS workspace package with explicit public
entrypoints for compiler APIs, traffic-signal schema, turn-lane helpers, OSM
parsing, reference conversion, and CLIs. It never imports `area-config`, reads
`config/areas`, or derives host paths.
The host owns `scripts/lib/area-config.js` and maps normalized configuration to
the v1 `RoadCompilerInput` shape using `toRoadCompilerInput(area)`. During P1,
`build-area.js` calls the package in-process; P2 is the only phase that changes
that call to a child process.
## Source Ownership and Compatibility
The following current `scripts/lib` implementations move into package `src`:
`native-road`, `complex-junction`, `turn-lane-arrows`, `lane-geometry`,
`gaode-junction-reference`, `native-traffic-signals`, and `osm`.
Some moved modules also serve legacy host paths: QGIS uses turn-lane arrows,
vehicle preview and reimport use OSM parsing, and preview tests use lane
geometry. Those consumers import the package entrypoints after the move. This
preserves one implementation while allowing host -> package dependency.
Traffic signal ownership follows the matrix in
`research/traffic-signals-split-matrix.md`: schema, geometry, validation, and
runtime construction move to the package. The host retains only two file-I/O
adapters, `readTrafficSignalFeatures()` and `readTrafficSignals()`, both
delegating to package exports. No duplicated schema code remains.
## Input and Path Handling
The package compiler API accepts only `RoadCompilerInput` from
`docs/native-road-package-v1.md`. Package CLI commands accept an explicit JSON
input file (`--input`) and never load area configuration. The compatibility
host CLI still accepts `--config`, but immediately maps it through
`toRoadCompilerInput()` before entering the package.
`junctionTemplates.*.referenceFile` changes to a path relative to its area
configuration. `readAreaConfig()` resolves it while normalizing configuration;
the package receives an absolute path and does no path resolution.
## Tests and Rollout
The package receives the required Fengshu OSM fixture plus migrated unit tests.
Its `npm test` must run from the package directory without reading host inputs
or outputs. After each source batch, run the two Phase 0 parity baselines. The
existing host command names remain compatibility wrappers through P1.
Rollback is a normal Git revert of the latest batch commit. No module has a
parallel host copy after its batch lands, preventing divergence.

View File

@@ -6,13 +6,13 @@
```bash
# 基线必须先绿
for a in fengshu-er-road hanyang-block nantaizi-lake-innovation-valley; do
for a in fengshu-er-road nantaizi-lake-innovation-valley; do
node scripts/road-parity.js --config config/areas/$a.json \
--compare .trellis/tasks/08-25-road-compiler-extraction/baseline/$a.json || echo "FAIL $a"
done
```
- [ ] 区域基线全绿(否则回 Phase 0
- [ ] 两个有效区域基线全绿(否则回 Phase 0
## Step 1 — K1 矩阵(动代码之前)
@@ -89,7 +89,7 @@ packages/road-compiler/
```bash
# parity
for a in fengshu-er-road hanyang-block nantaizi-lake-innovation-valley; do
for a in fengshu-er-road nantaizi-lake-innovation-valley; do
node scripts/road-parity.js --config config/areas/$a.json \
--compare .trellis/tasks/08-25-road-compiler-extraction/baseline/$a.json || echo "FAIL $a"
done

View File

@@ -66,9 +66,9 @@
## Acceptance Criteria
- [ ] AC1.1 区域 `road-parity --compare` 对 Phase 0 基线全绿
- [ ] AC1.1 两个有效区域 `road-parity --compare` 对 Phase 0 基线全绿
- [ ] AC1.2 `npm run test:native-road``npm run test:road-workbench` 通过
- [ ] AC1.3 `npm run build:area` 三区域完整跑通(含 blender / cesium 阶段)
- [ ] AC1.3 `npm run build:area` 枫树二路完整跑通(含 blender / cesium 阶段)
- [ ] AC1.4 `grep -rn "area-config\|config/areas" packages/road-compiler/` 无命中
- [ ] AC1.5 `packages/road-compiler/``npm test` 不访问宿主 `inputs/``outputs/`
- [ ] AC1.6 `scripts/lib/` 下无搬迁文件的残留副本

View File

@@ -0,0 +1,21 @@
# Traffic Signals Split Matrix
Evidence gathered from `scripts/lib/traffic-signals.js` and repository-wide
call-site search on 2026-08-25.
| Export | Current users | Owner after P1 | Migration |
|---|---|---|---|
| `SIGNAL_LAYOUT` | `buildTrafficSignalsFromFeatures` | compiler package | Export from `@osm-asset/road-compiler/traffic-signals` |
| `signalNodeKey` | `buildTrafficSignalsFromFeatures` | compiler package | No host caller today; preserve public export for runtime identity contract |
| `buildTrafficSignalFeatures` | `native-traffic-signals`, `readTrafficSignalFeatures` | compiler package | Host QGIS adapter imports it from the package |
| `validateTrafficSignalFeatures` | `native-traffic-signals`, signal tests | compiler package | Tests import package entrypoint |
| `validateTrafficSignalSourceReferences` | `native-traffic-signals`, `reimport-gpkg`, `readTrafficSignals` | compiler package | Reimport adapter imports package function |
| `buildTrafficSignalsFromFeatures` | `native-traffic-signals`, `readTrafficSignals`, `buildTrafficSignals` | compiler package | Host preview adapter imports package function |
| `buildTrafficSignals` | `test-preview-assets` | compiler package | Test imports package function; it is geometry/schema behavior, not host I/O |
| `readTrafficSignalFeatures` | `build-osm2streets-qgis` | host adapter | Keep a thin file-reading wrapper under `scripts/lib/traffic-signals.js`; it imports package functions |
| `readTrafficSignals` | `build-area` | host adapter | Keep a thin file-reading wrapper under `scripts/lib/traffic-signals.js`; it imports package functions |
`scripts/lib/traffic-signals.js` must not retain a second implementation of
the schema or geometry. Its only P1 responsibility is host file I/O for the
legacy QGIS / preview paths. This preserves the one-way dependency:
host -> compiler package; the package never imports the host.

View File

@@ -3,7 +3,7 @@
"name": "rc-p1-package-boundary",
"title": "Phase 1包边界不换仓库",
"description": "在本仓库内建 packages/road-compiler移入编译器模块用窄输入契约替换 readAreaConfig 耦合,产物对基线逐字节一致",
"status": "planning",
"status": "in_progress",
"dev_type": null,
"scope": null,
"package": null,