# EM 观察网页可视化阶段 03 交接

状态：完成

阶段目标：完成独立 `netstandard2.0` 可视化类库的嵌入式中文科研风网页、程序集资源路由、确定性合成冒烟模式和独立类库文档；不引入 EM、MDCS、Painter 或 MovementTest 类型。

基线提交：`00501055eb924e8704def7bc7b419248a755ede9`（阶段 02 交接；`b0b79e5` 已核对为祖先）。

实现提交：

- `1ad324ca64d1139d34b2f2848b71f4fd90d4dedb` — `feat: add scientific planning dashboard`
- `8181f0532fb60067287c4d21d25e43c90758a88a` — `docs: document planning visualization library`

修改文件：

- `ClumsyPilot/TrajectoryPlanningVisualization/Runtime/EmbeddedWebAssets.cs`
- `ClumsyPilot/TrajectoryPlanningVisualization/Runtime/LoopbackVisualizationServer.cs`
- `ClumsyPilot/TrajectoryPlanningVisualization/TrajectoryPlanningVisualization.csproj`
- `ClumsyPilot/TrajectoryPlanningVisualization/Web/index.html`
- `ClumsyPilot/TrajectoryPlanningVisualization/Web/app.css`
- `ClumsyPilot/TrajectoryPlanningVisualization/Web/app.js`
- `ClumsyPilot/TrajectoryPlanningVisualization/README.md`
- `ClumsyPilot/tests/TrajectoryPlanningVisualizationVerificationHost/Program.cs`
- `ClumsyPilot/tests/TrajectoryPlanningVisualizationVerificationHost/SampleSnapshotFactory.cs`
- `ClumsyPilot/tests/TrajectoryPlanningVisualizationVerificationHost/WebAssetChecks.cs`
- `ClumsyPilot/tests/TrajectoryPlanningVisualizationVerificationHost/ContractChecks.cs`

新增或确认的接口：

- `EmbeddedWebAssets.ReadText(string)` 从程序集读取 `index.html`、`app.css`、`app.js`；静态资源不使用 CDN、Node.js 或网页运行时文件查找。
- 受既有会话 token 保护的 `/?token=…`、`/app.css?token=…`、`/app.js?token=…`；`/api/bootstrap` 返回静态快照和有效刷新率，`/api/events` 保持既有 SSE 契约。
- 页面固定页签 ID 为 `overview`、`ls-st`、`kinematics`、`history-config`，固定 chart ID 为 `ls`、`st`、`curvature-s`、`curvature-t`、`velocity-t`、`acceleration-t`、`jerk-t`、`yaw-rate-t`。
- `SampleSnapshotFactory` 只使用通用可视化契约，生成两段方向、换向标记、冻结配置和八张图；`--smoke-seconds N` 以 10 Hz 发布 N 秒并打印一次完整 URI。

验证命令与结果：

1. `git merge-base --is-ancestor b0b79e5 HEAD` — 退出码 0。
2. `dotnet run --project ClumsyPilot/tests/TrajectoryPlanningVisualizationVerificationHost/TrajectoryPlanningVisualizationVerificationHost.csproj` — 退出码 0，输出 `PASS trajectory-planning-visualization`。
3. `dotnet build ClumsyPilot/TrajectoryPlanningVisualization/TrajectoryPlanningVisualization.csproj` — 退出码 0，0 警告，0 错误。
4. `dotnet build ClumsyPilot/ClumsyPilot.csproj -p:ExcludeLegacyAutoAvoidance=true` — 退出码 0，0 错误；保留两个既有 obsolete 警告，位于 `MovementTests.TireFollowing.cs` 和 `TireFollowing.cs`，均不在本阶段文件范围。
5. `Resolve-Path` 后从 `$env:TEMP` 执行验证宿主 — 退出码 0，输出 `PASS trajectory-planning-visualization`，证明网页资源来自程序集而非当前工作目录。
6. `dotnet run --project ClumsyPilot/tests/TrajectoryPlanningVisualizationVerificationHost/TrajectoryPlanningVisualizationVerificationHost.csproj -- --smoke-seconds 1` — 退出码 0，恰输出一条 `http://127.0.0.1:<port>/?token=<64-lowercase-hex>` URI 后退出。
7. `git diff --check 0050105..HEAD -- <阶段 03 文件>` — 退出码 0，无空白错误；`git diff-tree --no-commit-id --name-status -r 1ad324c` 仅列出 Task 4 的九个文件，`git diff-tree --no-commit-id --name-status -r 8181f05` 仅列出 Task 5 的两个文件。

未运行的验证及原因：无。

已知警告或遗留问题：启动时工作区有 130 项阶段范围外脏项，暂存区为空；本阶段未展开、暂存、重置、覆盖或提交它们。主项目构建的两个 obsolete 警告同样不属于本阶段。

与原计划的偏差：`WebAssetChecks.cs` 在基线中不存在，虽在 Task 4 文件清单标为 Modify，实际按该任务的“Create WebAssetChecks”步骤新建；其余实现范围和两个独立提交均按 Task 4–5 执行。

下一阶段注意事项：阶段 04 只实施集成计划 Task 1–2 的设置同步与纯换向段状态机。可复用类库已经完成，但不得向其引入 EM、MDCS、Painter 或 MovementTest 类型；继续保持 `OBSERVE_ONLY`，并保护 MovementTest 中用户已经设置的 5.0 s、100000、2.0 s。
