chore(task): archive 08-27-junction-dominated-roads
This commit is contained in:
@@ -0,0 +1 @@
|
||||
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. 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."}
|
||||
@@ -0,0 +1 @@
|
||||
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. 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."}
|
||||
@@ -0,0 +1,68 @@
|
||||
# 实施计划
|
||||
|
||||
轻量任务,一个提交即可。门禁不过就停。
|
||||
|
||||
前置:无。客户端置灰渲染路径已由 `08-26-direct-edit-map-editor` 第 3 步交付并有单测覆盖,
|
||||
本任务只补服务端输入。
|
||||
|
||||
## 关键决定:置灰只影响手柄,不影响求解
|
||||
|
||||
`editable: false` 只改变 handle manifest,**不改变 `solveConstraints()` 的行为**。
|
||||
落在被置灰 segment 上的既有约束仍然照常应用、照常参与几何编译。
|
||||
|
||||
理由:否则本次改动会让升级后的编译静默丢掉用户已保存的编辑——一个 UI 可编辑性的判断
|
||||
不该回溯否决已持久化的意图。用户想撤销这类编辑,走 undo / 禁用约束的正常路径。
|
||||
|
||||
这也让「几何输出逐字节不变」这条验收标准成立,从而使本步骤可安全回滚。
|
||||
|
||||
## 1. 判据与置灰
|
||||
|
||||
- 目标:可编辑带短于道路宽度的 segment,其全部 `road-*` 手柄 `editable: false`。
|
||||
- 位置:`src/compile/direct-edit-solver.js` 的 `makeRoadHandles()`。
|
||||
该函数已算出 `start` / `end` / `length` / `width`,判据是纯本地计算,不需要新数据。
|
||||
- 实现要点:
|
||||
- 带长米数 `(end - start) * length`,与 `width`(该 segment 双向宽度之和)比较。
|
||||
- 复用既有 `baseDisabled` 机制与既有文案「该道路全部位于路口保留区,请进入 JunctionTools 编辑。」,
|
||||
不新增第二套提示语。
|
||||
- 保留原 `unavailable` 判断作为兜底,两者取或。
|
||||
- 被置灰的 segment 仍然产出手柄(位置照旧),只是 `editable: false` 且带 `disabledReason`。
|
||||
- 不改:`junctionReserves()` 的 0.45 上限、cutback 推导、`solveConstraints()`、junction 手柄。
|
||||
|
||||
## 2. 测试
|
||||
|
||||
- 位置:`test/direct-edit-solver.js`。
|
||||
- 覆盖:
|
||||
- 短路段(带长 < 宽度)的全部 `road-*` 手柄 `editable: false` 且 `disabledReason` 非空。
|
||||
- 正常路段 `editable: true` 且无 `disabledReason`。
|
||||
- 判据边界:带长略小于 / 略大于宽度两侧各一例。
|
||||
- junction 手柄仍 `editable: true`。
|
||||
- 置灰 segment 上的既有约束仍被求解(`constraintStates` 里 `applied: true`),
|
||||
证明置灰没有回溯否决已保存编辑。
|
||||
|
||||
## 3. 验证
|
||||
|
||||
```bash
|
||||
npm run test # 含 test/direct-edit-solver.js
|
||||
npm run test:client # 客户端类型
|
||||
npm run test:client:unit # 客户端纯逻辑
|
||||
npm run format:check
|
||||
npm run build
|
||||
```
|
||||
|
||||
几何不变的实测(本任务的核心安全性证明):对 `test/fixtures/fengshu-er-road.osm`
|
||||
在改动前后各跑一次 `compileGeometry`,比较全部输出图层的 JSON,必须完全一致。
|
||||
`npm run test` 里的 fixture 基线测试已覆盖这条,若基线有 diff 即为回归。
|
||||
|
||||
手测(可选,`directEdit` 开关打开):选中 `test/fixtures` 里那 6 段短路之一,
|
||||
应看到灰色手柄且 header 显示原因。这是父任务 prd 那条验收标准第一次真正可演示。
|
||||
|
||||
## 4. 门禁
|
||||
|
||||
- 几何输出零变化(fixture 基线无 diff)。
|
||||
- 正常路段行为与当前 main 完全一致。
|
||||
- 既有约束不因置灰而失效。
|
||||
|
||||
## 回滚点
|
||||
|
||||
单文件单函数改动,`git revert` 即可回到当前行为。
|
||||
客户端不需要任何配合改动,回滚后灰色手柄自然消失,回到「空真」状态。
|
||||
@@ -0,0 +1,87 @@
|
||||
# 路口主导的短路段整条置灰
|
||||
|
||||
父任务:`.trellis/tasks/08-26-direct-manipulation-road-editor`。约束模型与编辑所有权的权威定义在父任务 `design.md`。
|
||||
|
||||
## 问题
|
||||
|
||||
`src/compile/direct-edit-solver.js` 里 `editable: false` 的唯一来源是 `unavailable`:
|
||||
|
||||
```js
|
||||
const start = Math.min(1, startReserve);
|
||||
const end = Math.max(0, 1 - endReserve);
|
||||
const unavailable = start >= end;
|
||||
```
|
||||
|
||||
但 `junctionReserves()` 给每端保留区的比例有硬上限 `Math.min(0.45, cutback / length)`,
|
||||
于是 `start ≤ 0.45`、`end ≥ 0.55`,`start >= end` 结构上永远为假。
|
||||
**该分支是死代码,连带那句提示语「该道路全部位于路口保留区,请进入 JunctionTools 编辑。」永远不可能显示。**
|
||||
|
||||
实测 `test/fixtures/fengshu-er-road.osm`:126 个道路手柄,0 个 `editable: false`。
|
||||
|
||||
后果是短路段拿到了一条无意义的编辑带(`test/fixtures/fengshu-er-road.osm`,20 个有保留区的段):
|
||||
|
||||
| 路长(米) | 总宽(米) | 窗口 | 可编辑带(米) |
|
||||
| --- | --- | --- | --- |
|
||||
| 14.5 | 9.8 | [0.45,0.55] | 1.5 |
|
||||
| 15.4 | 9.8 | [0.45,0.55] | 1.5 |
|
||||
| 18.6 | 9.8 | [0.45,0.55] | 1.9 |
|
||||
| 19.1 | 9.8 | [0.45,0.55] | 1.9 |
|
||||
| 19.2 | 9.8 | [0.45,0.55] | 1.9 |
|
||||
| 19.6 | 6.5 | [0.45,0.55] | 2.0 |
|
||||
| 82.2 | 9.8 | [0.17,0.83] | 54.9 |
|
||||
| 199.2 | 9.8 | [0.00,0.93] | 185.6 |
|
||||
|
||||
第一行那条路只有 14.5 米长、9.8 米宽,cutback 是 `max(宽度) × 1.4 ≈ 13.7` 米——
|
||||
**每一端**的路口都要这条路的 94%,两端合计 188%,远超全长。上限把它压成各 45%,
|
||||
凭空造出中间 10%(1.5 米)的「可编辑带」。
|
||||
|
||||
这违反两条已写明的约定:
|
||||
|
||||
- 父任务不变量「相邻 profile 之间必须有可计算的过渡」。约束默认 `transition: 'smoothstep'`
|
||||
作用于区间两端回归基线,1.5 米的区间两侧紧贴保留区,没有任何余量做过渡。
|
||||
- 父任务「编辑所有权」:主地图只编辑两个 junction reserve **之间**的道路内部 interval。
|
||||
这种路的真实路口几何占满全长,根本不存在「之间」。
|
||||
|
||||
## 目标
|
||||
|
||||
让路口几何占满的短路段整条归 JunctionTools,恢复那个分支的可达性,
|
||||
并使父任务 prd 的验收标准「落在 junction reserve 内的手柄不可拖动,并提示进入 JunctionTools」
|
||||
从空真变成可演示。
|
||||
|
||||
## 判据
|
||||
|
||||
**可编辑带长度(米)< 道路总宽度(米)→ 该 segment 的所有道路手柄 `editable: false`。**
|
||||
|
||||
用物理长度而非归一化 station,理由是过渡段需要的是实际距离,与道路长短无关。
|
||||
一条比自身宽度还短的编辑带装不下横断面的平滑变化。
|
||||
|
||||
在上表数据上分界干净,无边界模糊样本:1.5 < 9.8 置灰;54.9 > 9.8 保留。
|
||||
恰好切出可编辑带 < 10 米的那 6 段。
|
||||
|
||||
判断必须在上限生效**之后**用实际窗口算,而不是拿未截断的 `cutback / length` 之和——
|
||||
后者与「过渡段放不下」这件事没有直接关系。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [ ] 可编辑带短于道路宽度的 segment,其全部 `road-*` 手柄 `editable: false` 且带 `disabledReason`。
|
||||
- [ ] `disabledReason` 复用既有文案,引导进入 JunctionTools。
|
||||
- [ ] 可编辑带不短于道路宽度的 segment,行为与当前 main 完全一致(手柄数量、位置、`editable: true`)。
|
||||
- [ ] 置灰不改变 `reserves` 本身,也不改变任何几何输出:`compileGeometry` 结果与置灰前逐字节一致。
|
||||
- [ ] 置灰的 segment 仍然出现在 manifest 中(不是被删除),否则客户端无法解释为什么不能编辑。
|
||||
- [ ] junction 手柄不受影响,仍然 `editable: true`。
|
||||
- [ ] `test/direct-edit-solver.js` 覆盖:短路段全部置灰、正常路段不受影响、判据边界(带长 ≈ 宽度)。
|
||||
- [ ] `npm run test`、`npm run test:client`、`npm run test:client:unit`、`npm run format:check`、`npm run build` 全绿。
|
||||
- [ ] 客户端无需改动即可显示灰色手柄与原因(`08-26-direct-edit-map-editor` 已实现该路径)。
|
||||
|
||||
## 不做
|
||||
|
||||
- 不改 `junctionReserves()` 的 0.45 上限本身。上限保护的是 reserve 语义,改它会牵动 junction 侧几何。
|
||||
- 不改 cutback 的推导公式。
|
||||
- 不实现 JunctionTools 侧的编辑能力(属 `08-26-direct-edit-junction-tools`)。
|
||||
- 不做客户端改动。
|
||||
- 不把置灰的 segment 从 manifest 里移除。
|
||||
|
||||
## 顺序依赖
|
||||
|
||||
与 `08-26-direct-edit-map-editor` 的第 4、5 步无依赖,可并行或后置。
|
||||
客户端置灰渲染路径已在该任务第 3 步交付并有单测覆盖,本任务只补上服务端的输入。
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"id": "junction-dominated-roads",
|
||||
"name": "junction-dominated-roads",
|
||||
"title": "路口主导的短路段整条置灰",
|
||||
"description": "",
|
||||
"status": "completed",
|
||||
"dev_type": null,
|
||||
"scope": null,
|
||||
"package": null,
|
||||
"priority": "P2",
|
||||
"creator": "dingkang",
|
||||
"assignee": "dingkang",
|
||||
"createdAt": "2026-08-27",
|
||||
"completedAt": "2026-08-28",
|
||||
"branch": null,
|
||||
"base_branch": "main",
|
||||
"worktree_path": null,
|
||||
"commit": null,
|
||||
"pr_url": null,
|
||||
"subtasks": [],
|
||||
"children": [],
|
||||
"parent": "08-26-direct-manipulation-road-editor",
|
||||
"relatedFiles": [],
|
||||
"notes": "",
|
||||
"meta": {}
|
||||
}
|
||||
Reference in New Issue
Block a user