# 补全 Trellis 项目规范文档 **类型**:docs · **负责人**:dingkang · **创建**:2026-08-03 --- ## 背景 `trellis init` 在本仓库生成了 `.trellis/` 脚手架(v0.6.12),但把项目误判成了前端项目: - `.trellis/spec/frontend/` 下 6 个文件全是 React/TypeScript 的空模板,状态栏统一写着 "To fill" - 本仓库实际是 **OSM → QGIS/Blender/Cesium 的资产生成管线**,没有任何前端代码 - `task.json` 的 `notes` 直接写着 "First-time setup task created by trellis init (frontend project)" 后果是具体的:`trellis-implement` / `trellis-check` 子代理会按 `implement.jsonl` / `check.jsonl` 自动加载 spec 文件。当前 spec 为空且方向错误,等于子代理在无约束下写代码——而这个项目有大量**违反直觉、必须遵守**的约定(详见下方"关键约定"),一旦被子代理无意破坏,产物会静默出错而不是报错。 ## 目标 用真实代码中提取的约定,替换错配的 spec 脚手架,使任何 AI 会话在动手前就能拿到本项目的实际工程约束。 ## 非目标 - **不改动任何业务代码**。本任务只写 `.trellis/` 下的文档 - **不修复代码中的已知缺陷**。`docs/refactor-plan.md` 记录的 D1/D2/D3 只做记录,不在此任务修 - **不重写 README/changelog**。它们面向人类使用者,spec 面向 AI 执行者,两者共存不合并 - **不引入新的检查脚本或 CI** ## 交付物 | # | 交付物 | 说明 | |---|---|---| | D1 | 删除 `.trellis/spec/frontend/` | 6 个空的 React 模板文件,全部移除 | | D2 | `.trellis/spec/pipeline/` | Node 构建管线约定,4 个文件 | | D3 | `.trellis/spec/blender/` | Blender Python 约定,4 个文件 | | D4 | `.trellis/spec/preview/` | Cesium 预览层约定,1 个文件 | | D5 | `.trellis/spec/config/` | 区域配置 JSON 约定,1 个文件 | | D6 | `.trellis/spec/guides/` 本地化 | 更新 index,新增产物一致性指南 | | D7 | `.trellis/spec/index.md` | 顶层索引 | | D8 | `task.json` 元数据修正 | `relatedFiles` / `notes` 去掉 frontend 误判 | 结构详见 `design.md`。 ## 关键约定(必须被 spec 覆盖) 这些是从代码注释和 `docs/refactor-plan.md` 中确认的、**违反直觉且破坏后果静默**的约束。spec 的价值主要在这里: 1. **图层表跨语言单一事实源** — 九个 osm2streets 图层的顺序在 `scripts/lib/scene-layers.js`(JS 侧)和 `blender/osmassets/catalog.py`(Python 侧)各存一份,靠 `catalog.check_layers()` 运行时校验。颜色**故意不同步**(QGIS sRGB 调试色 vs Blender 线性场景色)。 2. **顺序是承重的** — `ROAD_LAYERS` / `MATERIALS` 是 list 不是 dict,因为材质创建顺序决定导出 GLB 里的材质索引。只能追加。 3. **`ogr2ogr` 不能设 `COORDINATE_PRECISION`** — 显式设置会触发 GDAL 的精度裁剪,实测丢失 7 个箭头多边形的 28 个顶点。 4. **`ogr2ogr` 导出失败会留下 0 字节文件** — 所以 `reimport` 必须先导到临时目录、全部校验通过才拷回,不能直接写目标目录。 5. **`intermediates` 与 `reimport` 互斥** — 前者从 OSM 重建 gpkg,正好抹掉后者要读回的手工修改。代码里是显式抛错,不是警告。 6. **`osmassets` 按依赖分包,不按功能** — `osm.py` / `geom.py` 是纯 Python(可用系统 python 测试),其余可以 import `bpy`。这条线一旦被破坏,`blender/tests/test_pure.py` 就跑不起来。 7. **测试的期望值必须从几何推导** — `test_pure.py` 开头明确写着"记录当前输出的测试会把 bug 固化成规范"。 8. **重构必须过 parity 校验** — `scripts/parity.js` + `glb-digest.js` + `scene_digest.py` 三件套,比对的是结构摘要而非字节。哪些字段天然不稳定已经用 control 实验确定并列入忽略名单。 ## 验收标准 - [ ] `.trellis/spec/frontend/` 已删除,`python3 ./.trellis/scripts/get_context.py --mode packages` 输出的 Spec layers 为 `blender, config, pipeline, preview` - [ ] 每个 spec 文件都包含**至少 2 处指向真实文件的引用**(`path:line` 或 `path` + 函数名),没有假想路径 - [ ] 上方"关键约定" 8 条全部落到具体 spec 文件中,可通过 grep 定位 - [ ] 没有任何文件残留 "To fill" / "TODO" / 模板占位文本 - [ ] 文档语言为中文;标识符、路径、代码示例保持英文原样 - [ ] 每个包目录有 `index.md`,且顶层 `.trellis/spec/index.md` 能索引到全部包 - [ ] `blender/tests/test_pure.py` 仍能通过(确认本任务未误改代码) ## 完成后 ```bash python3 ./.trellis/scripts/task.py finish python3 ./.trellis/scripts/task.py archive 00-bootstrap-guidelines ``` 归档后,新加入的开发者会拿到 `00-join-` 引导任务而不是这个 bootstrap 任务。