# FreeCAD Web 转换执行总计划

更新时间：2026-08-15

## 1. 目标、口径与真值

项目唯一目标是把锁定的 FreeCAD `1.1.1` 能力迁移到浏览器，并保留 FreeCAD 的文档、属性、重算、拓扑命名、文件和交互语义。项目不是远程桌面、截图流，也不是只复刻界面的通用 Web CAD。

进度必须同时区分两种口径：

1. 兼容实现口径：`config/freecad-execution-plan.json` 的 P01-P10 共 83 项均已完成，证明当前 Web 应用有可运行实现、门禁和明确能力边界。
2. exact 对标口径：`config/freecad-web-exact-parity-plan.json` 共 52 项，当前为 5 completed、36 in_progress、11 pending；34 个模块为 0 exact、26 compatible、5 proxy、3 development。

因此当前结论是“可运行的 FreeCAD 风格 Web CAD 兼容基线已形成”，不是“FreeCAD 已完整 Web 化”。只有 `EX-REL-01` 关闭、52/52 exact 任务完成、34/34 模块为 exact 且未知差异为零，才能改变系统级 exact claim。

发生状态冲突时按以下顺序取真值：

1. `config/freecad-web-exact-parity-plan.json`：exact 任务、依赖、阻断项。
2. `config/release-capability-matrix.json`：34 模块可对外声明的等级。
3. `config/freecad-active-work-queue.json`：当前唯一在执行的微任务。
4. `config/freecad-execution-plan.json`：兼容实现 P01-P10 的完成情况。
5. `config/*-verification.json`、原生报告和 Chrome 报告：某个环境中的实际证据。
6. 本文与 `docs/current-work.zh-CN.md`：解释、顺序和交接入口。

## 2. 当前完成情况重审

### 2.1 已形成闭环的兼容基线

- React/Vite FreeCAD 风格应用壳、菜单、工作台、Combo View、Task、视口、Report/Jobs/Diagnostics 和状态栏可以运行。
- React 只通过 `BitBybitWebCadFacade` 进入 CAD 领域；Three.js、OCCT、SQLite/OPFS 和 Worker 没有成为 UI 业务旁路。
- Bitbybit OCCT Worker、原生 history provider、FreeCAD 私有命名 ABI、planegcs WASM 和 SQLite OPFS 均已有构建或运行门禁。
- Part、PartDesign、Sketcher、FCStd 和 26 个 compatible 模块已有代表性实现与 Chrome 证据。
- CAM 已有 CAD -> OpenCAMLib -> CAMotics -> G-code -> LinuxCNC WASM 的真实浏览器验证链。
- P01-P10 的 83/83 项兼容任务已完成，发布门 G0-G9 在该口径下通过。

### 2.2 已完成的 exact 独立切片

- `EX-TSN-00`：缺失原生命名或 builder 证据时 fail-closed。
- `EX-TSN-01`：已支持 builder 的逐阶段 Shape 与 Generated/Modified/Deleted 证据。
- `EX-TSN-02`：生产 FreeCAD 私有 MappedNameRef/StringHasher 命名来源。
- `EX-TSN-03`：同构拓扑只从唯一原生 provenance 稳定化，多来源保持 ambiguous。
- `EX-PD-02`：Attachment、Datum、ShapeBinder/SubShapeBinder、多 Body 与 XLink 重连生命周期的独立验收范围。

这些任务按自身验收范围关闭，不表示它们依赖的整个 PartDesign、文档或内核任务已经 exact。

### 2.3 已量化但尚未关闭的 P0 阻断

- Oracle：352 个注册对象、348 个可实例化对象、4 个不可实例化对象、1111 个启动 GUI command、19 个 source-only command 和 2 个 context-only command 已分类；命令族的成功、禁用、失败、取消、恢复流程仍未穷尽。
- Property：85 种运行时类型、5510 条记录中，30 种/4361 条为通用原生 codec，5 种/683 条为专用 codec，50 种/466 条仍为 opaque proxy。
- Property status：15 类已观察状态均已进入类型化 Facade 行为；`LockDynamic` 和 `PartialTrigger` 已有原生事务证据，但完整 observer 与局部重算序列未关闭。
- TSN：30/30 原生 mutation、219/219 几何阶段恢复通过；11 个 PartDesign case/28 个恢复命名阶段均已通过第二次独立原生复跑分类为允许演进。
- 生产命名链：五阶段 5/5 几何恢复，2 个恢复拓扑 case/5 个下游阶段已分类为允许演进；仍有 3/5 通用 Shape 代理并缺注册 rotate mutation family。
- 有序操作：19×19 的逐对分类持续执行；实时已完成数、未知数和唯一活动项只从生成状态读取。
- FCStd：支持的原生 codec 与未知资源保留已有证据，但所有对象/属性/Extension/Shape/ElementMap2/StringHasher 的 FreeCAD-Web-FreeCAD 双向变异未穷尽。
- GUI：应用壳和代表性工作流已有浏览器证据，但动态命令、Task、对话框、焦点、上下文和逐工作台流程没有完整原生对照。
- 发布：系统级 exact 为 false，`EX-REL-01` 为 pending，跨浏览器、长期运行和全模块 exact promotion 尚未开始。

### 2.4 可机器核对的完成度仪表盘

实时仪表盘为 `docs/freecad-active-work-status.generated.zh-CN.md`，由 `generate:freecad-active-work-queue` 同活动队列一起生成，并由 `check:freecad-active-work-queue` 逐字校验。此处不再复制任务数、完成数、操作对覆盖数、Property 覆盖数或下一任务；任何手工状态摘要均不具备治理效力。

## 3. 目标架构和不可破坏边界

```text
React / FreeCAD Web UI
        |
BitBybitWebCadFacade + Command/Task contracts
        |
Document + Property + Transaction + DAG/Recompute
        |
Geometry / Sketch / Naming / Project / CAM facades
        |
Dedicated Workers
        |
Bitbybit OCCT + FreeCAD naming + planegcs + SQLite OPFS
        |
FCStd / STEP / IGES / mesh / CAM / engineering resources
```

任何后续任务都必须满足以下边界：

- UI 不直接调用 Three.js、OCCT、OPFS、SQLite 或脚本执行器。
- 最终 Shape 相似不能替代逐阶段 history、命名、文档状态和 FCStd 证据。
- mock 和 Node 单测不能替代真实 Chrome Worker/WASM 回放。
- 未知属性和资源必须无损保留或拒绝编辑，不能猜测性改写。
- 原生来源不唯一时保持 ambiguous，不能按数组顺序或网格索引稳定化。
- FreeCAD 本身拒绝的组合保存原生失败 oracle，不强行实现为成功链。
- 每次只允许一个机器队列任务为 `in_progress`，避免同时扩展多个工作台。

## 4. 最小任务和完成定义

一个“最小实现任务”只处理一个命令、属性类型、特征参数分支、原生 case 或有序操作对。每项按以下九个独立检查点推进：

1. `A-inventory`：锁定源码位置、TypeId/command id、依赖和适用对象。
2. `B-native-success`：采集 FreeCAD 1.1.1 成功结果、状态、事件和资源。
3. `C-native-negative`：分别采集 disabled、failure、cancel；不适用时保存可验证原因。
4. `D-native-mutation`：编辑输入、重算、恢复，并记录逐阶段 Shape/history/naming。
5. `E-facade`：在 Facade/Worker 边界内实现结构化合同和失败诊断。
6. `F-transaction`：覆盖 Undo/Redo、abort、stale generation 和最后有效状态保留。
7. `G-roundtrip`：FreeCAD 保存 -> Web 读取/修改/保存 -> FreeCAD 重开/再保存。
8. `H-browser`：真实 Chrome Worker/WASM/OPFS 回放，结束后 Shape/Worker/资源归零。
9. `I-promotion`：聚焦 check、计划 blocker、能力矩阵和差异账本同步。

只有 A-I 全部完成，最小能力才能提升 exact。若任务仅为 oracle 准备，则只关闭它明确声明的证据范围，不提前关闭实现任务。

## 5. 当前串行微任务队列

当前机器队列由 `scripts/generate-freecad-active-work-queue.mjs` 生成。每个条目只允许一个产物、一个聚焦检查和一个退出条件。

### 5.1 ORA GUI 基线，106 项，已完成

- `ORA-GUI-SETUP-000..002`：拆分 GUI 探针、诊断 BIM 首启弹窗、隔离用户配置。
- `ORA-GUI-SHARD-000..099`：100 个连续分片，覆盖 1111 个命令的 no-document/document/selection 三态。
- `ORA-GUI-MERGE-000`：合并分片并校验 ID 全集、连续区间和 SHA-256。
- `ORA-GUI-CONTEXT-000..001`：分类 `Import_ReadBREP` 与 `NaviCubeDraggableCmd` 的延迟注册边界。

### 5.2 ORA GUI 工作流，7 项，已完成

- `ORA-GUI-WF-000`：选择首个命令族。已选 `PartDesign_Pad`，映射主任务 `EX-UI-03`，关联 `EX-ORA-01/EX-PD-01`。
- `ORA-GUI-WF-001`：Pad 原生成功工作流和聚焦断言，已完成；Task 打开/接受、Body Tip、体积、拓扑和 Undo 证据通过。
- `ORA-GUI-WF-002`：无活动文档时的 disabled 工作流已完成；QAction 与命令管理器入口均被阻止，文档、Task 和事务保持为空。
- `ORA-GUI-WF-003`：open-wire profile 的 failure 工作流已完成；原生诊断、Task 可修正状态和失败清理回滚均已锁定。
- `ORA-GUI-WF-004`：有效预览后的 Cancel 工作流已完成；回滚、活动 Body 及原生选择/焦点轨迹均已锁定。
- `ORA-GUI-WF-005`：失败后在同一 Task 内修复 profile、提交、Undo/Redo、保存重开和二次保存，已完成。
- `ORA-GUI-WF-006`：exact blocker、聚焦门禁和后继 TSN 队列已更新，已完成。

### 5.3 TSN 恢复漂移，13 项，已完成

按以下顺序一次解释一个 case：

| 队列 ID | case | 唯一 mutation 轨迹 | 漂移 ordinal | 阶段数 | 状态 |
| --- | --- | --- | --- | ---: | --- |
| `TSN-DRIFT-000` | `partdesign-plain` | `Pad10.Length: 7 -> 7.75 -> 7` | `0,9` | 2 | completed / allowed_evolution |
| `TSN-DRIFT-001` | `partdesign-midplane` | `Pad11.Length: 8 -> 8.75 -> 8` | `0,9` | 2 | completed / allowed_evolution |
| `TSN-DRIFT-002` | `partdesign-reverse` | `Pad12.Length: 5 -> 5.75 -> 5` | `0,9` | 2 | completed / allowed_evolution |
| `TSN-DRIFT-003` | `partdesign-taper` | `Pad13.Length: 6 -> 6.75 -> 6` | `0,9` | 2 | completed / allowed_evolution |
| `TSN-DRIFT-004` | `partdesign-twoside` | `Pad14.Length: 7 -> 7.75 -> 7` | `0,9` | 2 | completed / allowed_evolution |
| `TSN-DRIFT-005` | `partdesign-pocket` | `Pad15.Length: 8 -> 8.75 -> 8` | `0,9,11` | 3 | completed / allowed_evolution |
| `TSN-DRIFT-006` | `partdesign-pocket-through` | `Pad16.Length: 5 -> 5.75 -> 5` | `0,9,11` | 3 | completed / allowed_evolution |
| `TSN-DRIFT-007` | `partdesign-pocket-midplane` | `Pad17.Length: 6 -> 6.75 -> 6` | `0,9,11` | 3 | completed / allowed_evolution |
| `TSN-DRIFT-008` | `partdesign-pocket-twoside` | `Pad18.Length: 7 -> 7.75 -> 7` | `0,9,11` | 3 | completed / allowed_evolution |
| `TSN-DRIFT-009` | `partdesign-pocket-taper` | `Pad19.Length: 8 -> 8.75 -> 8` | `0,9,11` | 3 | completed / allowed_evolution |
| `TSN-DRIFT-010` | `partdesign-pocket-up-to-face` | `Pad20.Length: 5 -> 5.75 -> 5` | `0,9,11` | 3 | completed / allowed_evolution |
| `TSN-PROD-DRIFT-000` | 生产 `cut` | 五阶段链 cut 参数编辑/恢复 | 由生产报告锁定 | - | completed / allowed_evolution |
| `TSN-PROD-DRIFT-001` | 生产 `rotate` | 五阶段链 rotate 参数编辑/恢复 | 由生产报告锁定 | - | completed / allowed_evolution |

每项必须得到且只能得到一种结论：FreeCAD 稳定语义、允许的命名演进、实现缺陷。实现缺陷必须增加回归测试；未知不能作为结论。

每个 case 再拆成六个必须依次完成的最小检查点；后续能力的 A-I 检查点已经全部进入生成队列：

| 检查点 | 唯一产物 | fail-closed 验收 |
| --- | --- | --- |
| `-A-contract` | case id、target object/type、property path/type、before/edited/restored、drift ordinal | 与锁定 30-case oracle 一致，属性确实可编辑 |
| `-B-replay` | 第二个独立 FreeCAD 1.1.1 进程报告 | 版本、commit、harness SHA-256 和运行状态锁定 |
| `-C-fingerprint` | 每个漂移阶段的 geometry/relation/semantic-name 三相摘要 | 参考与复跑的 before/edited/restored 逐字段一致 |
| `-D-restore` | property 恢复、geometry 恢复、restored-to-nominal 结论 | 任一阶段几何未恢复即停止并调查缺陷 |
| `-E-persistence` | initial/reopened/resaved 命名摘要 | roundtrip/resave drift 为 0，且三态与 restored 一致 |
| `-F-decision` | stable_semantics / allowed_evolution / implementation_defect 唯一分类 | 决策进入连续前缀账本，checker 通过，只推进直接后继 |

任一检查点失败时，当前任务保持 `in_progress`，不得领取下一 case。如果分类为 `implementation_defect`，还必须在同一队列项内完成最小修复、回归测试、原生/Web 对照和资源释放，不另行跳过。

### 5.4 TSN 有序操作对

操作全集为 Fuse、Cut、Common、Rotate、Pad、Pocket、Loft、Pipe、Revolution、Groove、Fillet、Chamfer、Hole、Draft、Thickness、LinearPattern、PolarPattern、Mirrored、MultiTransform。

每个 `from -> to` 是一个独立任务：

1. 确定 `from` 输出类型与 `to` 输入前置。
2. 在原生 FreeCAD 执行并记录接受或拒绝。
3. 接受时使用真实 builder，采集 history/naming。
4. 编辑 `from` 参数并重算 `to`。
5. 恢复参数并分类命名/拓扑变化。
6. 保存、重开、再保存并比较。
7. 在生产 Worker 回放并检查释放。
8. 拒绝时固定原生错误类型和文档未污染证据。

初始五阶段转换和 `fuse->*` 连续前缀均已进入机器分类账本；实时覆盖集合与当前操作对严格从生成状态和 `config/freecad-ordered-operation-pair-classification.json` 读取，其余逐对领取。

## 6. 后续关键路径微里程碑

### M00 当前工作树收口

状态：completed；聚焦门禁、完整 `verify`、发布产物验签、JSON 和 diff 校验均通过。

- M00.1 TSN 原生报告、resave 和 stage correlation 对账。
- M00.2 Property codec/status、Facade 行为和 FCStd 证据对账。
- M00.3 CAM/LinuxCNC artifact hash、浏览器报告和 parser authority 对账。
- M00.4 GUI 分片、source/context-only 分类和 oracle coverage 对账。
- M00.5 `git diff --check`、全部 JSON 解析、完整 `verify`。

退出条件：所有生成文件未陈旧，全部门禁通过，没有以报告改写替代真实执行。

### M01 `EX-ORA-01` GUI 工作流闭合

状态：首个 Pad 命令族 7/7 已完成；`EX-ORA-01` 因其他命令族和运行时对象/Property 未穷尽而继续 `in_progress`。

先完成 Pad 七步，再按风险选择下一族。每个后续命令族仍拆成 success/disabled/failure/cancel/recovery/update 六个状态任务。选择顺序：核心文档命令 -> Sketcher 创建/编辑 -> PartDesign 参数 Task -> Part builder -> FCStd import/export -> 其他工作台。

退出条件：每个运行时命令归入一个工作流族；每族五态都有原生证据或机器可读不适用原因；未知 GUI 状态为零。

### M02 `EX-TSN-04A` 恢复漂移闭合

状态：13/13 已完成；11 个 PartDesign case/28 个阶段及 2 个生产 case/5 个阶段均完成独立复跑分类。

- M02.1-M02.11：11 个 PartDesign case/28 个命名摘要演进已全部分类为允许演进。
- M02.12：生产 Cut 恢复拓扑漂移已分类为允许演进。
- M02.13：生产 Rotate 恢复拓扑漂移已分类为允许演进。
- M02.14：若发现实现缺陷，只修改一个 operation/case 并补回归。
- M02.15：汇总 zero-unknown drift gate，不直接提升系统 exact。

退出条件：13/13 case 有分类，未知为零，缺陷修复均有原生与浏览器证据。

### M03 `EX-TSN-04B` builder 与 19×19 转换矩阵

状态：`in_progress`；实时覆盖数和当前操作对见生成状态。

- M03.1：用真实 builder 替换五阶段链中 Cut 之后的通用 Shape 代理，一次替换一个 stage。
- M03.2：增加 Rotate 原生 mutation family。
- M03.3：按 361 个独立任务完成有序组合分类。
- M03.4：每个允许组合完成 mutation、restore、naming、resave、浏览器释放。
- M03.5：每个拒绝组合固定错误和无文档污染证据。

退出条件：361/361 分类；所有原生允许组合为真实 builder；所有拒绝组合可稳定复现；0 generic Shape proxy、0 未解释恢复漂移。

### M04 `EX-DOC-01` Property codec 批次

状态：等待 M01，可在不改变单任务并行上限的前提下准备只读 oracle。

每个类型严格执行第 4 节 A-I。批次内一次只领取一个 Property 类型，按复用度和安全风险排序：

- M04.A 量纲标量：Acceleration、Area、Force、HeatFlux、Moment、Power、Pressure、Speed、Stiffness、StiffnessDensity、Temperature、ThermalTransferCoefficient、VectorDistance、Quantity。
- M04.B 数学与集合：BoolList、Color、ColorList、Direction、Font、IntegerSet、Map、Matrix、PlacementList、Position、Rotation、UUID、VectorList。
- M04.C 链接族：LinkListHidden、LinkSubHidden、LinkSubListGlobal、XLink、XLinkList、XLinkSub、XLinkSubList。
- M04.D Material：App PropertyMaterial/PropertyMaterialList 与 Materials::PropertyMaterial，先固定 schema、继承和资源边界。
- M04.E 文件资源：PropertyFile、PropertyFileIncluded、PropertyPath，禁止把宿主绝对路径写入浏览器项目。
- M04.F PythonObject：先定义禁止执行、可信序列化、代理编辑和迁移边界，再决定 codec；不得反序列化执行任意 Python。
- M04.G 几何/求解内核：Part ShapeHistory/TopoShapeList/FilletEdges，Mesh MeshKernel/CurvatureList，Fem FemMesh/PostDataObject，Points PointKernel，Robot Trajectory。
- M04.H 工作台专用：Spreadsheet Sheet/RowHeights/ColumnWidths，TechDraw CenterLine/CosmeticEdge/CosmeticVertex/GeomFormat lists，Inspection DistanceList。

每个类型的退出条件：原生默认/非默认/边界值、所有观察 status、Data/View editor、动态增删、Undo/Redo、FCStd reopen/resave、Chrome 回放和资源释放全部通过。只有运行时报告变为 native codec 后，opaque 计数才允许下降。

### M05 `EX-DOC-02/03` 文档语义

状态：等待 M03+M04。

- M05.1 对象 add/remove/rename 的 observer 前后事件顺序。
- M05.2 Property add/remove/rename/change 的事务顺序。
- M05.3 nested transaction、commit、abort、undo、redo。
- M05.4 DAG 脏标记、局部重算和跨分支顺序。
- M05.5 recompute 失败时保留最后有效 Shape 与诊断树。
- M05.6 partial document load、PartialTrigger、完整加载后重算。
- M05.7 copy/clone/delete/relink/group/extension 生命周期。
- M05.8 Extension 动态属性、版本迁移和未知 Extension 保留。
- M05.9 FeaturePython 默认禁执行、代理、签名能力和显式授权边界。
- M05.10 外链关闭、缺失、重开、路径恢复与多文档事务。

退出条件：原生和 Web 事件序列一致；失败不污染有效状态；重开后 DAG/链接/事务语义稳定；资源归零。

### M06 `EX-KER-01/ORA-02` 内核纵向切片

状态：M02 证据已可消费，等待 M05 文档闭环。

按一个 builder/参数分支执行 A-I：Box、Cylinder、Cone、Sphere、Torus、Prism、Wedge、Helix、Ellipsoid；Extrusion、Revolution、Loft、Sweep；Fuse、Cut、Common；Fillet、Chamfer；随后是 tolerance、healing、validation 和失败诊断。

退出条件：参数、单位、placement、公差、有效性、质量属性、逐阶段 history、错误和 Worker 所有权均与原生 fixture 一致。

### M07 `EX-SK-01/02` Sketcher 纵向切片

状态：等待 KER/DOC 前置。

- M07.1 直线/圆/圆弧/椭圆/椭圆弧/双曲线/抛物线/B-spline 的创建与编辑。
- M07.2 几何约束每个 overload 的成功、冗余、冲突和退化。
- M07.3 尺寸、参考、Driving/Driven、单位和表达式。
- M07.4 外部几何 Projection/Intersection/Both 与 TopoRef 漂移。
- M07.5 InternalAlignment、SnellsLaw、B-spline Weight 辅助几何。
- M07.6 autoconstraint、trim/extend/split、construction、virtual space。
- M07.7 任务焦点、选择、键盘、cancel 和 solver stale/crash 恢复。

退出条件：每个 geometry/constraint overload 经过 A-I；求解分类、自由度和诊断与原生一致。

### M08 `EX-PART-01` Part 纵向切片

状态：等待 M03+M06。

每个 primitive 和 builder 单独闭环；随后逐项完成 Boolean 参数、Refine、placement、multi-solid、healing、inspection、失败与恢复。不能用一个成功 Box 或最终体积代表整个 Part 工作台。

退出条件：所有注册 Part command/TypeId/参数分支均有原生与浏览器证据，未知选项为零。

### M09 `EX-PD-01` PartDesign 纵向切片

状态：等待 M03+M08。

顺序为 Pad -> Pocket -> Revolution -> Groove -> Additive/Subtractive Loft -> Additive/Subtractive Pipe -> Fillet -> Chamfer -> Hole -> Draft -> Thickness -> Linear/Polar Pattern -> Mirrored -> MultiTransform。每个特征再按模式拆分，例如 Length/ThroughAll/UpToFace、Midplane/Reverse/TwoLengths/Taper、成功/无效 profile/失效 support/取消/恢复。

退出条件：每个模式完成 A-I，Body Group/Tip、Support/Attachment、跨特征命名和 FCStd 保持一致。

### M10 `EX-FC-01/FMT-01` FCStd 与核心格式

状态：等待 M03+DOC-04。

- M10.1 每种已支持对象/Property 的 FreeCAD -> Web 无修改往返。
- M10.2 Web 修改 -> FreeCAD 重开 -> FreeCAD 再保存 -> Web 重开。
- M10.3 Shape、ElementMap2、StringHasher、Expression、GuiDocument 资源逐项变异。
- M10.4 未知 XML、BRep、脚本和 Extension 的字节保留或只读拒绝。
- M10.5 损坏 ZIP、路径穿越、压缩炸弹、超限和取消。
- M10.6 STEP/IGES/BREP 的单位、颜色、层、名称、装配关系和高级元数据。

退出条件：两次保存重开后未知语义漂移为零；不支持资源有明确只读/代理策略。

### M11 `EX-UI-01..05` GUI 全量对标

状态：先执行 M01，完整阶段等待文档与核心特征稳定。

按应用壳、菜单、工具栏、工作台切换、MDI、Combo View、模型树、Task、Data/View 属性、对话框、快捷键、上下文菜单、状态栏、Report/Jobs、3D 选择逐域拆分。每域分别采集空文档、活动文档、单选、多选、Task、错误、取消和恢复状态；随后按工作台完成端到端流程。

退出条件：命令可见/启用、事务、焦点、选择、树、属性、视图和诊断均与 oracle 对齐；桌面和 390px 视口无重叠、溢出和无名控件。

### M12 文档与工程工作台

状态：deferred。

顺序为 Draft -> Spreadsheet -> TechDraw -> Plot -> 跨工作台文档闭环；Assembly -> BIM/IFC -> Surface -> Mesh/MeshPart -> Material。每个对象/命令仍按 A-I，不按整个工作台一次性提升 exact。

退出条件：相关 exact 任务逐项完成，跨工作台链接、表达式、导出和保存重开无未知差异。

### M13 平台工作台、脚本与代理

状态：deferred。

顺序为 FEM、CAM、Robot、Points/ReverseEngineering、Inspection/Measure、Python/Macro、Addon，最后处理 Cloud/Help/IDF/JT/OpenSCAD 的 browser implementation、sidecar、proxy 或正式排除。安全边界先于功能数量。

退出条件：每项均有可执行策略、依赖/许可证/SBOM、能力限制和失败策略；代理不得被标记 exact。

### M14 QA、跨浏览器与发布

状态：deferred，日常门禁持续运行。

- M14.1 Chrome 当前基线重跑。
- M14.2 Firefox/Safari 或明确不支持的可复核边界。
- M14.3 Windows/macOS/Linux 与 GPU/软件渲染矩阵。
- M14.4 键盘、屏幕阅读器、locale、长文本和窄屏。
- M14.5 fuzz、1000 次重算、长会话、崩溃、迁移和回滚。
- M14.6 性能、WASM/JS/GPU/OPFS 保留量与资源归零。
- M14.7 SBOM、许可证、签名、离线安装和发布回滚。
- M14.8 52/52 exact、34/34 exact、零未知差异的 promotion report。

退出条件：`EX-REL-01` 的所有前置完成；promotion gate 从 fail-closed 报告自然变为通过，不能通过放宽断言或改写静态报告达成。

## 7. 执行顺序

当前只允许以下主顺序：

```text
M00
 -> M01 ORA GUI workflows
 -> M02 TSN drift
 -> M03 TSN ordered pairs / real builders
 -> M04 Property codecs
 -> M05 Document semantics
 -> M06 Kernel oracle slices
 -> M07 Sketcher
 -> M08 Part
 -> M09 PartDesign
 -> M10 FCStd/core formats
 -> M11 GUI full replay
 -> M12 document/engineering workbenches
 -> M13 platform/script/proxy
 -> M14 QA/release
```

只读 oracle 准备可以与当前实现任务交错，但不能让机器队列出现第二个 `in_progress`，也不能绕过依赖提前提升 exact 状态。

## 8. 每轮执行模板

1. 从 `config/freecad-active-work-queue.json` 读取唯一 `nextTask`。
2. 验证依赖与输入报告哈希，确认没有陈旧 artifact。
3. 只修改该任务直接影响的 oracle、实现、测试、报告和 blocker。
4. 先运行该域聚焦 probe/test，再运行只读 check。
5. 运行 `test:facade`、相关 Chrome gate、`check:execution-plan`。
6. 运行完整 `./npmw run verify`、`git diff --check` 和全部 JSON 解析。
7. 将当前任务改为 completed，并只把直接后继改为 in_progress。
8. 更新 `docs/current-work.zh-CN.md` 的数字和下一任务；历史事实追加到 continuation 日志。

任何失败报告、资源泄漏、哈希陈旧、未知语义差异都优先于新增功能。

## 9. 本轮实际启动点

`ORA-GUI-WF-000` 已完成：首个命令族为 `partdesign-pad-task`，代表命令 `PartDesign_Pad`，主 exact 映射为 `EX-UI-03`，关联 `EX-ORA-01/EX-PD-01`。选择依据和五态配方保存在 `config/freecad-gui-workflow-plan.json`，由 `check:freecad-gui-workflow-plan` 校验。

`ORA-GUI-WF-001` 也已完成：锁定 FreeCAD 1.1.1 的 Pad 成功 GUI 工作流通过原生命令打开 Task，点击 `Done` 后清理 edit 状态，得到 `PartDesign::Pad`、Body Tip=Pad、体积 120、6 面/12 边/8 点和 UndoCount=1。

`ORA-GUI-WF-002` 已完成：在独立原生进程中，`PartDesign_Pad` 的 `isActive()` 与 QAction 均为 false；QAction trigger 和 `Gui.runCommand()` 两条入口都未创建文档、Task 或事务。

`ORA-GUI-WF-003` 已完成：open-wire profile 打开无效 Pad 预览，接受时原生报告 `Wire is not closed.`，Task 保持打开；失败清理 reject 后临时 Pad 与事务被回滚，原有 Body/Sketch 状态保持不变。

`ORA-GUI-WF-004` 已完成：17.5 mm Pad 预览为 210 体积的有效单实体，reject 后临时 Pad、Tip 变化与事务全部回滚，活动 Body 保持不变。原生选择从 Sketch 被消费为空并保持为空；焦点从 3D View 进入 `lengthEdit`，取消后落到 TaskView，而非恢复原 3D View。

`ORA-GUI-WF-005` 已完成：open-wire Pad 首次接受产生 `Wire is not closed.`，Task 保持可修正；同一 Task 内补齐闭合矩形并通过 `lengthEdit.rawValue` 输入 12 mm 后，预览和提交均为 6 面/12 边/8 点、体积 144 的有效单实体。Undo 回到两段 open-wire 且 Pad 不存在，Redo 恢复 12 mm Pad；保存、关闭重开、再次保存和再次重开均保持相同语义。

`ORA-GUI-WF-006` 已完成：工作流计划、exact blocker、聚焦 checker 和活动队列同步，Pad 命令族 7/7 关闭，但没有据此提升 `EX-ORA-01`、`EX-UI-03` 或系统 exact。

`TSN-DRIFT-000` 已完成：`partdesign-plain` 的 `Length 7 -> 7.75 -> 7` 在 Body 和 Pad 两个阶段恢复相同几何，但从首次创建命名演进为新的稳定历史。锁定报告与第二次独立 FreeCAD 1.1.1 复跑的逐阶段摘要一致，演进值又在 save/reopen/resave 中保持，因此分类为 `allowed_evolution`，不是 Web 实现缺陷。

`TSN-DRIFT-001` 已完成：`partdesign-midplane` 的 `Length 8 -> 8.75 -> 8` 在 Body11 和 Pad11 两个阶段恢复相同几何，关系与语义命名摘要演进为新的稳定历史。锁定报告与第二次独立 FreeCAD 1.1.1 复跑的逐阶段摘要一致，演进值在 save/reopen/resave 中保持，因此同样分类为 `allowed_evolution`，不是 Web 实现缺陷。

`TSN-DRIFT-002` 已完成：`partdesign-reverse` 的 `Length 5 -> 5.75 -> 5` 在 Body12 和 Pad12 两个阶段恢复相同几何，关系与语义命名摘要演进为新的稳定历史。锁定报告与第二次独立 FreeCAD 1.1.1 复跑的逐阶段摘要一致，演进值在 save/reopen/resave 中保持，因此同样分类为 `allowed_evolution`，不是 Web 实现缺陷。

`TSN-DRIFT-003` 已完成：`partdesign-taper` 的 `Length 6 -> 6.75 -> 6` 在 Body13 和 Pad13 两个阶段恢复相同几何，关系与语义命名摘要演进为新的稳定历史。锁定报告与第二次独立 FreeCAD 1.1.1 复跑的逐阶段摘要一致，演进值在 save/reopen/resave 中保持，因此同样分类为 `allowed_evolution`，不是 Web 实现缺陷。

`TSN-DRIFT-004..010` 与生产 `cut`/`rotate` 漂移均已完成独立复跑，并唯一分类为 `allowed_evolution`；恢复漂移队列因此关闭。

`fuse->pad` 已由原生 OCCT builder 和 FreeCAD `PartDesign::Pad` 文档路径稳定拒绝，事务 abort 后对象集与源 Shape 恢复，干净 FCStd save/reopen/resave 不受污染。`fuse->pocket` 已由真实 `BRepPrimAPI_MakePrism+BRepAlgoAPI_Cut` 接受，长度变异与恢复、history/naming 和 FCStd 三阶段均通过。唯一下一任务不在此手工记录，只读取生成状态。
