# 完整 FreeCAD 对标实施方案

> 本文是“功能完全对标 FreeCAD”的工程基线和任务分解，不把当前已有的页面、MockFacade 或少量 OCCT 特征误报为完成。所有“支持”都必须经过锁定版本 FreeCAD 的行为黄金测试和文件互操作测试。
>
> 全模块、逐领域任务 ID、执行波次和统一退出条件以 [FreeCAD 1.1.1 全功能对标主任务账本](freecad-complete-parity-backlog.zh-CN.md) 为准；本文保留架构决策、专项设计和阶段门。两者不一致时，能力状态以 `config/compatibility-matrix.json` 为机器可读真值，范围和待办以主任务账本为准。

## 1. 目标与边界

### 1.1 目标

以 FreeCAD `1.1.1` 官方发布标签为首个兼容基线，精确源码提交为 `0108fd4b4850cc46e625b60e53cea7a7bbe69f8d`。实现可在浏览器运行的 CAD 应用：React 负责 FreeCAD 风格界面，Three.js 最新锁定版本负责三维显示，Bitbybit 是唯一入口，FreeCAD/OCCT 业务逻辑在 WASM Worker 中运行，SQLite WASM + OPFS 负责项目、文档、对象、事务和资源存储。

### 1.2 唯一入口原则

对 React 和页面公开的唯一业务入口是 `BitBybitWebCadFacade`。页面不得直接导入 Three.js、OCCT、OCCT Worker、SQLite 或 OPFS；这些实现只能由 Facade 适配器和 Worker 使用。新增工作台、命令、属性、文件格式和诊断，必须先扩展版本化 Facade 合同，再接入页面。

Bitbybit 必须被充分用作几何、Worker、IO、三角化和缓存的首选实现层。对 Bitbybit 1.1.1 npm 包未暴露但 FreeCAD 对标必需的能力，允许锁定 Bitbybit 与 OCCT 源码提交后扩展绑定并用 Emscripten 自构建 WASM；不得以现成包 API 不足作为降低功能范围的理由。自构建 provider 与现有 provider 必须共享 Facade/Worker 合同、能力探测、句柄生命周期、取消/诊断和黄金测试。

### 1.3 “完整对标”的可验收定义

| 等级 | 含义 | 允许的产品表述 |
|---|---|---|
| `exact` | 与基线 FreeCAD 在输入、状态、结果、错误、选择和持久化语义上逐项一致 | “已对标” |
| `compatible` | 结果和核心交互一致，允许明确记录的浏览器呈现差异 | “兼容” |
| `read-only` | 可读取、可显示、可导出，但不能安全编辑和重算 | “只读” |
| `proxy` | 保留未知对象、属性或 Shape 资产，不能保证语义重算 | “代理” |
| `unsupported` | 有意拒绝并生成结构化诊断 | “不支持” |

没有黄金测试、差异报告和迁移策略的功能，不得标记为 `exact` 或 `compatible`。浏览器限制必须体现为能力矩阵和用户可见诊断，不能静默删除 FreeCAD 行为。

### 1.4 全量范围和清册门禁

锁定源码 `src/Mod` 的 34 个目录全部纳入范围：`AddonManager`、`Assembly`、`BIM`、`CAM`、`Cloud`、`Draft`、`Fem`、`Help`、`Idf`、`Import`、`Inspection`、`JtReader`、`Material`、`Measure`、`Mesh`、`MeshPart`、`OpenSCAD`、`Part`、`PartDesign`、`Plot`、`Points`、`ReverseEngineering`、`Robot`、`Sandbox`、`Show`、`Sketcher`、`Spreadsheet`、`Start`、`Surface`、`TechDraw`、`TemplatePyMod`、`Test`、`Tux`、`Web`。同时覆盖 `App`、`Base`、`Gui`、`Main` 暴露的文档、Property、事务、选择、视图、参数、命令、Python 控制台、宏、偏好、快捷键、多文档、剪贴板和打印行为。

`P0-02/INV-01..06` 未完成以前，“全部功能”范围仍视为未冻结。源码模块中的测试、模板或开发设施可以被分为开发等价能力或明确 `unsupported`，但不得遗漏；Python、宏、插件、外部求解器和后处理器必须有沙箱与权限决策。

项目 Node/npm 命令统一经 `./npmw` 执行；系统 `npm` 的结果不得用作阶段门证据。

本机 `FreeCADCmd` 可作为第一层行为 oracle：`./npmw run probe:freecad-reference` 采集版本、提交、已加载模块和核心 Property 元数据；当前构建是无界面 `Part/Material/Measure` 子集。完整桌面/工作台回放必须另行启用 FreeCAD 原生模块，不能将 headless probe 的可用性扩展到未构建的工作台。

## 2. 当前差距与解决策略

| 领域 | 当前切片 | 达到对标还缺少的核心能力 | 主任务包 |
|---|---|---|---|
| 拓扑命名 | 有 `SubshapeRef` 类型和句柄生命周期 | 历史映射、持久名称、歧义检测、版本迁移 | TSN |
| Sketcher | 有轮廓输入验证 | 几何/约束模型、Planegcs 求解、编辑器交互、外部几何 | SK |
| Expression/单位 | Property metadata 可声明单位 | 词法/语法、Quantity、维度检查、引用、循环和 locale | EXU |
| 依赖 DAG/重算 | 有事务和版本号 | Link 图、SCC、调度、取消、增量结果、错误传播 | DAG |
| Part/PartDesign | 已有部分 Primitive/Boolean/Pad/Pocket/Revolution | 完整特征、Body/Tip、附着、模式、失败恢复 | PD/PART |
| 工作台 | manifest 和界面骨架 | Draft、TechDraw、Spreadsheet、Assembly、BIM、CAM、FEM、Mesh 等业务 | WB |
| 文件 | 项目 schema v1、资源对象 | FCStd 读写、BREP/GuiDocument、扩展/代理、格式导入导出 | FC |
| 质量 | Facade Node 测试和部分浏览器矩阵 | FreeCAD 对照回放、几何黄金、压力、跨浏览器和安全门禁 | QA |

## 3. 总体架构与不可破坏的约束

### 3.1 分层

1. **Presentation**：React 页面、FreeCAD 菜单/工具栏、Combo View、Tasks、Property editor、Report view、快捷键和无障碍。
2. **Facade**：`App/Gui/Workbench/Command/Selection/Task/Project/Viewport` 合同、权限、前置条件、请求上下文、诊断、事件和版本。
3. **Domain kernel**：Document、DocumentObject、Property、Link、Expression、Sketch、Feature、Body/Tip、事务、DAG、重算。
4. **Geometry**：Bitbybit OCCT API 和必要的 FreeCAD/OCCT C++ 模块 WASM 化；B-Rep 句柄仅在 Worker 内部存在。
5. **Workers**：几何、求解、重算、持久化各自独占 Worker；消息带 `requestId`、`documentId`、`documentVersion`、取消和诊断。
6. **Persistence**：SQLite WASM OPFS 单写者、项目迁移、资源内容寻址、事务日志、恢复和导入导出。

### 3.2 领域不变量

- 对象 UUID、内部名称和子形状名称永不使用显示 Label 代替。
- 所有长度、角度、面积、体积在内部使用有维度的 Quantity；数据库保存规范单位和原始表达式。
- 任何重算结果只有在请求版本仍等于当前文档版本时才能提交；过期结果必须丢弃。
- 依赖循环、求解冲突、拓扑歧义和未知文件对象必须显式失败并保留诊断。
- Undo/Redo、自动保存和资源引用计数必须以同一事务边界提交。
- Worker 结果不可直接改变 React 状态，必须经 Facade 校验和事件投影。
- 几何能力按 `reuse-bitbybit`、`extend-bitbybit-binding`、`custom-occt-binding` 三档登记；后两档必须锁定源码、补丁、ABI、Emscripten 工具链、许可证和 WASM hash，并完成 Bitbybit/FreeCAD 三方差分。

## 4. 专项一：稳定子形状命名（TSN）

### 4.1 目标

实现与 FreeCAD 特征历史可比的 `TopoRef`：面、边、顶点、壳、实心体和 Compound 在特征重算、参数编辑、保存/加载、布尔操作和导出后仍能被稳定引用；无法唯一判断时返回 `ambiguous`，绝不把错误的面静默绑定给另一个面。

### 4.2 技术措施

1. 在 OCCT Worker 内保留每次特征的输入 Shape、输出 Shape、历史对象和拓扑签名；使用 `Generated/Modified/Deleted` 历史关系生成映射。
2. 为每个子形状计算规范签名：拓扑类型、几何类型、解析几何参数、几何中心/长度/面积/体积、邻接度数、方向、局部坐标和量化容差。签名必须区分“用于匹配的特征”与“仅用于诊断的数值”。
3. 采用分层命名：`documentId/objectUuid/featureRevision/subshapeKind/localOrdinal`，再绑定跨版本映射记录；不使用 OCCT transient hash 或三角网格索引作为持久 ID。
4. 对对称、重复和布尔切分结果建立候选集合和评分；最高分不超过唯一阈值时返回歧义，并在 UI 的选择/任务面板显示候选。
5. 保存 `TopoRef` 的来源特征版本、签名、映射算法版本和容差；加载旧版本先迁移，迁移失败保留原引用和报告。
6. 将面/边选择、附着、Fillet/Chamfer、Pocket up-to-face、TechDraw 投影、测量和表达式引用全部改用 `TopoRef`。

### 4.3 任务分解

| ID | 任务与交付物 | 前置 | 验收 |
|---|---|---|---|
| TSN-01 | 从基线 FreeCAD 采集拓扑命名、选择和错误行为 | P0 | 30 个模型有输入/输出映射 |
| TSN-02 | 定义 `TopoRef`、状态和迁移 JSON Schema | P1 | exact/ambiguous/deleted 均可序列化 |
| TSN-03 | OCCT 历史捕获适配器 | P3 | Pad/Pocket/Boolean 产生 Generated/Modified/Deleted 集 |
| TSN-04 | 规范几何/邻接签名库 | TSN-02 | 相同 B-Rep 重放签名稳定，网格精度变化不影响 |
| TSN-05 | 一对一匹配和评分算法 | TSN-03/04 | 平移、参数编辑和重算保持引用 |
| TSN-06 | 对称/重复拓扑歧义检测 | TSN-05 | 低置信度拒绝错误绑定并给出候选 |
| TSN-07 | 布尔与多实体历史映射 | TSN-03 | Union/Cut/Common 后选择引用可迁移 |
| TSN-08 | 引用持久化、版本迁移和回滚 | FC-02 | 保存/加载后 UUID 与状态不变 |
| TSN-09 | Facade 选择、附着和任务 API 接入 | TSN-02 | React 无内部拓扑 API 导入 |
| TSN-10 | 拓扑黄金回放与随机变异测试 | QA-02 | 100 个黄金模型、1000 次参数变异通过 |

## 5. 专项二：Sketcher 求解器（SK）

### 5.1 目标

达到 FreeCAD Sketcher 的约束建模和交互语义：几何创建/编辑、约束、自由度、冗余/冲突诊断、拖拽、外部几何、支持的曲线类型、B-spline、块约束、构造几何、投影和编辑事务。

### 5.2 技术路线

- 优先将 FreeCAD Sketcher 的 `planegcs`/相关 C++ 求解器以独立 WASM 模块编译，固定编译器、Emscripten、浮点和异常策略；Bitbybit Facade 只调用类型化求解服务。
- 若某一模块无法直接编译，先做等价 C++/WASM 端口并建立逐案例差异报告；禁止用页面 JavaScript 中的近似求解器冒充兼容。
- 求解 Worker 采用确定性输入排序、固定容差、最大迭代次数和取消点；输出几何、自由度、约束状态、冲突集合、残差和诊断。

### 5.3 任务分解

| ID | 任务与交付物 | 前置 | 验收 |
|---|---|---|---|
| SK-01 | 采集 Sketcher 几何/约束/快捷键/错误 manifest | P0 | 覆盖所有基线命令和约束类型 |
| SK-02 | 定义 Sketch 文档对象、几何索引和构造标志 | P1 | SQLite/Facade 可往返 |
| SK-03 | 编译 planegcs 求解器 WASM POC | P0-RT | 直线/圆/弧约束结果与 FreeCAD 一致 |
| SK-04 | 确定性求解协议和 Worker 生命周期 | SK-03 | 取消/过期版本不会提交 |
| SK-05 | `PARTIAL`：点、线、圆、弧可由基础 solver 处理；椭圆、B-spline（次数、控制点、权重、节点、周期标志）已进入深拷贝/持久化领域模型 | SK-02 | 椭圆/B-spline 求解与编辑器仍依赖 SK-03/SK-10，基础 provider 对其返回明确 unsupported 诊断，不静默计算 |
| SK-06 | 基础约束：Coincident、Horizontal、Vertical、Distance、Angle | SK-04/05 | 自由度和残差黄金一致 |
| SK-07 | 高级约束：Tangent、Equal、Symmetric、Block、Diameter、Radius | SK-06 | 冲突/冗余分类一致 |
| SK-08 | `PARTIAL`：构造几何标志、外部投影记录、版本化 TopoRef 和 `topo-ref` DAG 边已进入 Facade/持久化 | TSN-09 | 上游对象可触发草图分支重算；真实 OCCT 投影、引用迁移 UI 与黄金行为仍待完成 |
| SK-09 | 拖拽、自动约束、约束编辑器和任务面板 | SK-06 | 鼠标/键盘回放与桌面行为一致 |
| SK-10 | B-spline 编辑、节点/权重和约束限制 | SK-07 | 支持范围明确，无静默降级 |
| SK-11 | Sketch 支持 Pad/Pocket/Revolution 和附着面 | TSN-07/DAG-07 | 轮廓修改触发正确重算 |
| SK-12 | Sketch 黄金文件和求解压力套件 | SK-01..11 | 500 个模型、冲突/欠约束/过约束覆盖 |

## 6. 专项三：Expression 与单位系统（EXU）

### 6.1 目标

与 FreeCAD Quantity/Expression 语义对齐：单位后缀、复合单位、维度检查、对象/属性引用、Spreadsheet 别名、函数、常量、locale 显示、表达式错误和循环诊断。数据库必须同时保留规范 Quantity 与用户输入表达式。

### 6.2 技术措施

1. 词法、解析、类型检查和求值在独立 Worker 完成；UI 只显示 token、候选和诊断。
2. 采用有理数/高精度数值表示可精确保存单位换算；几何内核边界再转换为固定精度浮点。
3. 单位注册表包含维度向量、规范单位、别名、比例/偏移转换和显示格式；所有单位表有版本号。
4. 表达式解析产生依赖边，和对象 Link 一起进入统一 DAG；禁止通过字符串扫描绕开依赖和循环检测。
5. 序列化使用规范 locale（`.` 小数、显式单位 ID），显示 locale 只在 Presentation 层转换。

### 6.3 任务分解

| ID | 任务与交付物 | 前置 | 验收 |
|---|---|---|---|
| EXU-01 | 采集 FreeCAD 单位 schema、表达式函数和错误 | P0 | 建立可机器读取清单 |
| EXU-02 | Quantity/Unit/Dimension 类型与 SQLite schema | P1/FC-02 | 长度、角度、面积、体积可往返 |
| EXU-03 | 表达式 tokenizer/parser AST | EXU-01 | 运算符优先级和函数错误一致 |
| EXU-04 | 维度推导、转换和舍入规则 | EXU-02/03 | `mm+inch`、角度/长度混用按基线拒绝 |
| EXU-05 | 对象属性、Spreadsheet alias 和子形状引用 | TSN-02/DAG-02 | 引用重命名不丢失 |
| EXU-06 | 循环、未知符号、过期引用诊断 | DAG-04 | 错误包含对象/属性/表达式位置 |
| EXU-07 | locale 显示、自动完成和属性编辑器 | EXU-03 | 显示变化不改变规范序列化 |
| EXU-08 | 表达式迁移、导入导出和黄金测试 | FC-05 | 1000 条表达式跨版本一致 |

## 7. 专项四：依赖 DAG 与重计算（DAG）

### 7.1 目标

实现 FreeCAD 文档对象的依赖、Touched/Copy/Recompute 状态和事务语义：Link、Expression、子形状、Body/Tip、外部文档和视图依赖都进入统一有向图；重算按稳定拓扑序执行，循环和失败按对象传播。

### 7.2 技术措施

- 图节点为 `DocumentObject` 的计算版本，边包含 Link、Expression、TopoRef、Container 和 View 依赖类型。
- 每次参数事务生成 immutable snapshot、dirty set 和 recompute generation；使用 Tarjan/Kosaraju 检测 SCC，循环节点不运行几何。
- 调度器按依赖层级把可并行节点分发给 Geometry/Solver Worker；结果带 generation 和输入 hash，只有匹配时提交。
- 一个节点失败不覆盖上一次有效 Shape；下游进入 `UpstreamFailed`，Report view 可定位根因。
- Undo/Redo 恢复参数、图、状态和 Shape 资源引用；保存只提交已确认版本。

### 7.3 任务分解

| ID | 任务与交付物 | 前置 | 验收 |
|---|---|---|---|
| DAG-01 | Link/Expression/TopoRef 统一边模型 | TSN-02/EXU-05 | 图可解释每条边的来源 |
| DAG-02 | 对象注册、删除传播和反向索引 | P4-01 | 删除前显示受影响对象 |
| DAG-03 | Touched/Up-to-date/Error 状态机 | P4-04 | 状态转换与 FreeCAD 回放一致 |
| DAG-04 | SCC 循环检测和诊断 | DAG-01 | 循环不进入 OCCT/Sketch 求解 |
| DAG-05 | 稳定拓扑排序和并行层 | DAG-04 | 相同输入顺序可复现 |
| DAG-06 | generation、取消和过期结果丢弃 | P1-03 | 快速连续编辑不回写旧结果 |
| DAG-07 | Body/Tip、容器、Feature 链和支持映射 | DAG-05/TSN-07 | PartDesign 链正确显示 Tip |
| DAG-08 | 失败保留、下游传播和恢复 | DAG-07 | 修复上游后仅重算必要节点 |
| DAG-09 | 事务/Undo/Redo/Autosave 原子提交 | P2-04 | 崩溃恢复不出现半个图 |
| DAG-10 | DAG 可视化、诊断和性能计数器 | DAG-08 | 用户可定位耗时/失败节点 |
| DAG-11 | 1000 对象、长链、宽图、随机图基准 | DAG-01..10 | 记录内存、吞吐、取消和尾延迟 |

## 8. 专项五：核心业务对象与剩余工作台（WB）

### 8.1 共通实施规则

每个工作台都必须完成四份资产：`workbench-manifest.json`（菜单、命令、快捷键、任务面板和前置条件）、对象/属性 schema、Facade API、FreeCAD 黄金回放集。只有页面按钮存在而命令状态、选择过滤、重算和文件兼容未完成时，状态仍为 `ui-only`。

### 8.2 工作台分解

| 工作台 | 业务范围 | 主要任务 | 进入条件 |
|---|---|---|---|
| PartDesign | Body、基准、草图、Pad/Pocket、Dress-up、Pattern、Boolean、Additive/Subtractive | PD-01..PD-18：附着、支持面、两长度、Draft、Fillet/Chamfer、Hole、Pattern、Thickness、Tip | SK、TSN、DAG |
| Part | 原语、布尔、管道、阵列、变换、检查/修复、导入导出 | PART-01..PART-16：ShapeBinder、CompSolid、Refine、Make compound、容差和修复 | TSN、DAG |
| Sketcher | 见 SK 专项 | SK-01..SK-12 | Solver WASM |
| Draft | 2D 绘图、尺寸、阵列、图层、Working Plane、BIM 辅助 | DRAFT-01..DRAFT-14：吸附、网格、文本、样条、偏移和参数化 | EXU、DAG |
| TechDraw | 页面、视图、投影、尺寸、模板、SVG/PDF 导出 | TD-01..TD-15：隐藏线、剖视、链接视图、模板兼容和打印比例 | TSN、FC |
| Spreadsheet | 单元格、公式、别名、格式、链接和导出 | SS-01..SS-10：表达式依赖、循环、CSV/XLSX 边界和大表性能 | EXU、DAG |
| Assembly | 组件、连接器、约束、求解、变体、BOM | ASM-01..ASM-16：组件链接、joint solver、装配树、碰撞和导出 | DAG、TSN |
| BIM/Arch | 结构/建筑对象、材料、楼层、墙/梁/窗、IFC | BIM-01..BIM-20：属性集、族、空间、IFC2x3/IFC4 映射和代理 | FC、EXU |
| FEM | 材料、网格、边界、求解器、结果 | FEM-01..FEM-18：网格接口、求解器 WASM 构建、结果场和单位 | EXU、WB 安全门 |
| Mesh | 网格导入、修复、布尔、简化、分析和导出 | MESH-01..MESH-14：法向、非流形、误差、LOD 和大网格 Worker | FC、QA |
| Surface | 曲面创建、偏移、放样、填充、修剪、缝合 | SURF-01..SURF-14：NURBS/BSpline 参数、边界和缝合容差 | OCCT 扩展、TSN |
| CAM | Job、刀具、路径、后处理、仿真和 G-code | CAM-01..CAM-20：刀具库、碰撞、后处理器沙箱、单位和输出黄金 | FEM/Mesh 可选，安全门 |
| Inspection/Measure | 测量、剖切、偏差、标注和报告 | INSP-01..INSP-10：TopoRef 选择、精度、报告和导出 | TSN、EXU |
| 数据/交换模块 | Import、Points、ReverseEngineering、OpenSCAD、IDF、JT、Material、MeshPart | IMP/PTS/RE/OSC/IDF/JT/MAT：格式、单位、颜色、代理、几何转换和往返 | FC、QA |
| 应用/扩展模块 | Start、Help、AddonManager、Cloud、Show、Web | APPMOD/ADDON：最近项目、离线帮助、扩展治理、分享/云和安全边界 | P0 manifest、安全门 |
| Robot/Plot | 机器人、轨迹、运动学、数据绘图和结果输出 | ROBOT-01..12、PLOT-01..06 | DAG、EXU、QA |
| 脚本/宏/桌面通用 | Python 控制台、宏、插件、偏好、自定义、剪贴板、打印、多文档 | SCRIPT/GUI-REST：沙箱、权限、等价 Web 工作流或逐项不支持诊断 | P0 manifest、安全门 |
| 开发/测试模块 | Sandbox、TemplatePyMod、Test、Tux | DEV-01..06：保留开发/自动化等价入口或明确非产品能力 | P0 manifest |

### 8.3 工作台交付顺序

先完成 `PartDesign + Part + Sketcher` 的参数化闭环与 FCStd 双向往返，再做 TechDraw/Spreadsheet/Draft/Plot，随后做 Assembly/BIM/Mesh/Surface，最后处理 FEM/CAM/Robot/Inspection、数据交换模块、应用/扩展模块和脚本/桌面通用能力。每个工作台在进入下一层前必须通过对象创建、编辑、重算、撤销、保存、加载和导出七项门禁。

## 9. 专项六：文件兼容与迁移（FC）

### 9.1 兼容范围

1. **FCStd 读取**：ZIP 容器、`Document.xml`、`GuiDocument.xml`、BRep/Shape 资源、缩略图、对象属性、Expression、Link、视图状态和未知扩展。
2. **FCStd 写入**：生成 FreeCAD 1.1.1 可打开的最小等价文件；写入前完成 schema、内核和工作台能力检查。
3. **项目格式**：继续维护 `.webcad` manifest、SQLite schema、OPFS 资源包和迁移版本；FCStd 与 `.webcad` 不混用语义。
4. **交换格式**：STEP/IGES/BREP、STL/OBJ/PLY、SVG/PDF、DXF、glTF、IFC、CSV；每种格式记录精度、颜色、单位、拓扑和只读限制。
5. **未知对象**：保留原始 XML/资源和 proxy Shape，显示兼容报告；禁止执行 FCStd 中的 Python、宏或任意代码。

### 9.2 任务分解

| ID | 任务与交付物 | 前置 | 验收 |
|---|---|---|---|
| FC-01 | 采集 FCStd 文件结构和 FreeCAD 读写样例 | P0 | 每个核心对象有最小/复杂样例 |
| FC-02 | `.webcad`/SQLite schema v2 与迁移框架 | P2 | 迁移可回滚、旧版本可读 |
| FC-03 | ZIP 安全读取、大小/路径/压缩比限制 | FC-01 | zip bomb、路径穿越、恶意 XML 被拒绝 |
| FC-04 | Document/GuiDocument XML 映射 | P4/DAG | 树、属性、视图状态可往返 |
| FC-05 | BRep/Shape 资源读写和精度策略 | P3 | 体积、拓扑数和几何容差有报告 |
| FC-06 | Expression/Unit/Link/TopoRef 序列化 | EXU/TSN/DAG | 保存后可重算或明确 proxy |
| FC-07 | 未知对象/扩展 proxy 和差异报告 | FC-04 | 不丢原始资源、不假称可编辑 |
| FC-08 | STEP/IGES/BREP 导入导出 | PART | 100 个模型几何黄金通过 |
| FC-09 | Mesh/DXF/SVG/PDF/glTF/IFC/CSV 适配 | WB | 单位、颜色、精度和失败诊断正确 |
| FC-10 | FreeCAD↔WebCAD round-trip 测试 | FC-04..09 | 读→改→写→读的语义差异可解释 |
| FC-11 | 大文件、损坏文件和中断恢复 | FC-03 | 2 GB 级别按能力矩阵降级，不崩溃 |

## 10. 实施阶段与依赖

| 阶段 | 必须完成的结果 | 依赖 | 阶段门 |
|---|---|---|---|
| F0 基线冻结 | FreeCAD 提交/构建容器、Bitbybit/OCCT、Three、SQLite、浏览器、许可证和黄金样例 | 无 | G0：版本、来源、SBOM 完整 |
| F1 Facade/文档核心 | DocumentObject、Property、事务、选择、任务、诊断和 schema | F0 | G1：React 仅能通过 Facade 编译 |
| F2 表达式/单位/DAG | Quantity、Expression、统一依赖图、SCC、重算和恢复 | F1 | G2：1000 对象图和循环/错误黄金通过 |
| F3 稳定拓扑命名 | 历史映射、歧义、安全引用和迁移 | F2 + OCCT | G3：参数编辑/布尔/保存加载引用稳定 |
| F4 Sketcher | Solver WASM、约束、编辑器、外部几何和轮廓输出 | F2/F3 | G4：欠约束/冲突/拖拽/回放通过 |
| F5 Part/PartDesign 闭环 | Body/Tip、基准、特征、附着、DAG、Undo、FCStd | F3/F4 | G5：核心参数化建模闭环 |
| F6 TechDraw/Spreadsheet/Draft | 页面、投影、公式表、2D 参数化 | F2/F3/F5 | G6：核心生产文档可保存导出 |
| F7 Assembly/BIM/Mesh/Surface | 工作台对象、求解/几何和互操作 | F3/F5/F6 | G7：各工作台七项门禁 |
| F8 FEM/CAM/其余模块 | 数值库、后处理器、仿真和明确能力矩阵 | F0/F7 | G8：每个模块 exact/compatible/read-only/proxy |
| F9 发布验收 | 全量回放、跨浏览器、性能、安全、迁移和回滚 | F0..F8 | G9：无未解释的 unsupported 核心路径 |

## 11. 详细任务包（跨领域共通）

| ID | 任务 | 交付物 | 验收标准 |
|---|---|---|---|
| P0-01 | `IN PROGRESS`：已固定 FreeCAD 源码提交、原生编译器/依赖版本、无界面 Part 构建脚本与产物哈希；依赖镜像 digest 尚未完成 | lock、容器、构建日志 | 同一输入产生相同版本信息 |
| P0-02 | 生成 UI/命令/对象/Property/工作台 manifest | JSON manifest | 每条能力有来源和等级 |
| P0-03 | `IN PROGRESS`：声明式契约、FreeCADCmd driver/比较器和首批 5 个 Part 成功样例已通过；100 个黄金文件与 50 个错误文件尚未达到 | fixtures、expected | 桌面结果可复现 |
| P0-04 | 固定浏览器能力矩阵和 COOP/COEP | browser matrix | Chrome 最新两个版本有结果 |
| P0-05 | 许可证、供应链、WASM 安全评审 | SBOM、许可证清单 | 无未知二进制和高风险漏洞 |
| API-01 | Facade API 版本化和 JSON Schema | `src/facade` 合同 | 破坏性变更有迁移和弃用期 |
| API-02 | 统一请求上下文、取消、进度和诊断 | protocol types | 过期结果无法提交 |
| API-03 | 事件溯源与状态投影 | event log/reducer | 刷新后状态可重建 |
| APP-01 | Document/Object/Property 完整模型 | schema + adapter | Data/View、只读、隐藏、枚举、Link 全覆盖 |
| APP-02 | Transaction/Undo/Redo/Autosave 原子化 | transaction service | 崩溃点恢复无半提交 |
| APP-03 | Body/Container/Group/Link/Extension | object types | 树与依赖图一致 |
| GEO-01 | OCCT C++/WASM 构建和版本隔离 | build scripts | 资源、符号、许可证可追溯 |
| GEO-02 | Shape 生命周期、引用计数和 Worker 回收 | handle service | 长会话无不可控增长 |
| GEO-03 | B-Rep→Three 网格、选择和增量缓存 | viewport adapter | 选择不重建无关对象 |
| GEO-04 | 几何精度、容差和确定性 | tolerance policy | 体积/面积/拓扑黄金稳定 |
| QA-01 | 单元/属性/解析器/图算法测试 | tests | 分支和错误分类达标 |
| QA-02 | FreeCAD CLI/GUI 回放对照器 | comparator | 差异含输入、版本、对象和数值 |
| QA-03 | 浏览器 E2E、视觉和几何黄金 | Playwright fixtures | Chrome 能力结果可审计 |
| QA-04 | 性能/内存/取消/恢复压力 | benchmark reports | P95、峰值内存、失败率达门槛 |
| QA-05 | 安全测试和 fuzzing | corpus/reports | 文件、表达式、Worker 消息不可越权 |

## 12. 每个功能的开发模板

1. 在基线 manifest 登记 FreeCAD 命令、对象、属性、选择前置和错误。
2. 先写 Facade 类型、请求上下文、诊断和事件，再写 Worker/domain 实现。
3. 添加最小成功、失败、取消、Undo/Redo、保存/加载和过期结果测试。
4. 建立 FreeCAD 对照 fixture，记录几何容差、单位、拓扑和状态差异。
5. 接入 React 页面和 FreeCAD 风格任务面板；页面不直接访问内部实现。
6. 更新 SQLite migration、`.webcad`/FCStd 映射、兼容矩阵和文档。
7. 通过阶段门后才把状态从 `experimental` 提升为 `compatible` 或 `exact`。

## 13. 质量门禁与发布阻断条件

发布必须同时满足：`./npmw run verify`、Facade-only 依赖守卫、所有核心黄金回放、FCStd round-trip、跨浏览器 OPFS/Worker、几何精度、长会话内存、安全 fuzzing 和许可证检查。下列任一项阻断发布：

- 旧版本/未知对象被静默删除或当作可编辑对象；
- 过期 Worker 结果覆盖新版本文档；
- 子形状歧义被强行绑定；
- Expression 单位错误、循环或 locale 转换被静默吞掉；
- FCStd 读取后保存造成未报告的对象、属性、Shape 或视图丢失；
- 任一页面绕过 `BitBybitWebCadFacade` 导入内部 Worker、OCCT、Three 或 SQLite；
- 性能/内存超出能力矩阵而没有明确降级和诊断。

## 14. 下一轮实际执行顺序

1. 使用项目本地 Node 运行时完成 P0-RT、依赖安装和验证，清除引擎警告。
2. 继续完成 P0-01/P0-03：在已验证的提交、原生构建和 5 个黄金样例上补齐 digest 锁定构建容器、100 个黄金文件、50 个错误文件和 GUI 回放。
3. 实现 `DAG-01..DAG-06` 与 `EXU-01..EXU-06`，让属性修改从“Touched 标记”升级为可解释的依赖重算。
4. 实现 `TSN-02..TSN-07`，再把附着、Pocket up-to-face、测量和 TechDraw 选择切换到 `TopoRef`。
5. 编译/验证 `SK-03`，然后按基础约束→高级约束→编辑器→PartDesign 轮廓的顺序推进。
6. 以 PartDesign 核心闭环为第一条完整垂直链，随后完成 FCStd 对象/属性/Shape/视图双向读写和 round-trip。
7. 按 `TD→SS→DRAFT/PLOT→ASM/BIM/MESH/SURF→FEM/CAM/ROBOT/INSP` 顺序完成工作台七项门禁。
8. 完成 Import/Points/ReverseEngineering/OpenSCAD/IDF/JT/Material、Start/Help/AddonManager/Cloud/Show/Web、Python/宏/插件和桌面通用能力的逐项兼容决策与实现。
9. 完成跨浏览器、OPFS 故障、性能/内存、安全 fuzzing、a11y/i18n、PWA、升级回滚、SBOM 和发布差异报告。

## 15. 完成定义

“完整 FreeCAD 对标”只有在 F0-F9 全部阶段门通过、核心与扩展工作台均有兼容等级、稳定子形状命名/Sketcher/Expression/单位/DAG/重算/FCStd 均有黄金报告、跨浏览器和安全门禁通过，并且发布文档列出所有差异后才能使用。当前仓库仍处于核心 Facade、OCCT 几何和属性编辑的进行中阶段，下一工作目标按第 14 节执行。

完整对标还要求 34 个源码模块和 App/Base/Gui 通用能力全部进入机器可读清册；任何尚未登记的命令、对象、属性、格式、Python/宏/插件入口都会阻断 G9。详细关闭条件见主任务账本第 3、11、13 节。

## 16. 已实现切片与剩余边界

本轮已完成 `EXU-02..EXU-06` 的基础版本：Quantity 以 mm/deg 等规范单位保存，表达式支持四则运算、对象属性引用和维度错误；已完成 `DAG-01..DAG-06` 的领域版本：Link/Expression 边、下游传播、SCC 循环检测、稳定拓扑计划、generation 和 recompute 状态已进入 Facade 与 SQLite schema v3。还未把每个 DAG 节点接入真实 OCCT/Sketcher 计算 Worker，因此当前是可验证的业务调度层，不是完整几何重算。

属性领域合同现覆盖标量、枚举、颜色、Vector、Placement、ObjectLink、ObjectLinkList/StringList 和版本化 SubshapeLink。Placement/Vector 使用结构化值并做有限数、角度范围及非零旋转轴校验，复合值深拷贝进入 Undo/Redo 与持久化。Facade 的对象级几何重算已在 Shape 生成后执行 Placement，并对恒等变换、畸形结构、变换失败释放和最近有效缓存保留给出测试证据；这不是 FreeCAD Body/Tip、Support、AttachmentOffset 或特征局部坐标链的等价实现，File/Shape 摘要和多选 mixed 编辑也仍未完成。

TSN 已完成面/边/顶点量化签名、邻接指纹消歧和匹配 API，并挂接到实际重算 generation。成功 Shape 会产生对象拓扑快照、迁移 matches、`signature-fallback`/`occt-native` 历史和 schema v1 ElementMap；提交阶段自动写回 LinkSub 与草图外部几何，稳定引用更新 generation，歧义/删除引用保持显式状态、标脏所有者并产生修复诊断。候选替换 Facade 事务验证当前拓扑和 kind 后原子写入 stable TopoRef，重建 DAG、进入 Undo/Redo；属性面板和诊断页均通过 Facade 调用。schema v7 保存拓扑快照和稳定原生对象标签。Three.js 已支持多对象 Mesh 注册、OCCT analytic 面/边/顶点点击、预选、完整边折线高亮、window/crossing 框选和诊断聚焦闪烁；普通单向 Pad/Pocket/Revolution/Groove 已接入已有 OCCT `Generated/Modified/Deleted` provider，其余复合模式仍显式回退。

Sketcher 已有 Facade 事务模型和基础求解器适配器：Sketch 几何/约束快照进入 `DocumentObjectSnapshot`，新增几何、约束和求解会更新 `ConstraintStatus`、历史、自动保存与 SQLite schema v4；基础约束现覆盖 Diameter、Symmetric、Tangent。该适配器的职责是验证数据模型和提供可替换协议；它不宣称已经等价于 FreeCAD `planegcs`。SK-03 的 planegcs WASM、SK-07 的完整约束分类、SK-09 的交互回放和 SK-10 的 B-spline 仍是兼容门禁。

Bitbybit 的 OCCT `filletEdges` 与 `chamferEdges` 已进入 Geometry Facade，支持全边或显式索引、参数验证、句柄版本和 Worker 隔离。由于 OCCT 瞬时边索引不是持久命名，当前接口仍不能作为 FreeCAD PartDesign 的长期选边引用；必须等 TSN 的边级 `TopoRef`、历史映射和参数化重算完成后，才能标记为 `compatible`。

Geometry Facade 还接入了 Bitbybit IO 的 STEP 和 ASCII STL 导出，作为 FC-08/FC-09 的第一条交换格式垂直切片。导出数据仍只代表当前 Shape；对象树、Expression、Sketch 约束、TopoRef 和重算历史必须由 FCStd/.webcad 格式任务独立保存，不能因“能导出 STEP”而宣称参数化文件兼容。

PartDesign Mirrored 已形成 experimental whole-shape 垂直切片：Facade 验证并调用 OCCT 平面法向镜像，文档对象/Task 保存 Base、XY/XZ/YZ 原点平面和 Fuse，重算 union 后释放临时副本并进入 generation 拓扑写回。这不是 FreeCAD 局部特征历史镜像；DatumPlane/Sketch axis/TopoRef 平面、单实体规则、跨 Body 支持和 Mirrored 的原生历史映射仍未完成。

本轮又补齐了拓扑和恢复边界：面之外增加了由 BitBybit 网格端点派生的 edge/vertex 签名，并通过 `geometry.topology()` 返回面/边/点引用，签名使用量化坐标、长度/端点而不使用面索引；这仍不是 OCCT `Generated/Modified/Deleted` 历史。FCStd inspection 现在同时生成只读 `proxyDocument`，对象属性带有 `recognized/proxy/blocked` 状态；SQLite/OPFS Project API 增加 `recovery(documentId)`，报告完整性、schema、最后保存版本和降级警告。持久化写入现在在支持的浏览器使用 Web Locks 跨标签页互斥，并通过 BroadcastChannel 广播保存版本；无 Web Locks 环境明确报告 `local-queue`，不能解释为跨标签页安全。代理文档和恢复报告都不能被解释为 FCStd 参数化写回或崩溃恢复已经完成。

## 17. 本轮后续实现记录与下一批任务

本轮继续执行了重算、文件安全和命令能力三个关键边界。实现与验收必须按下面的定义理解，不能把“接口存在”解释成“FreeCAD 业务已完成”：

| 任务 | 实施措施 | 验证结果 | 剩余边界 |
|---|---|---|---|
| P1-03 / DAG-06 重算执行器 | `RecomputeCoordinator` 为每次运行分配 generation；后发运行取消前发；节点完成后校验 AbortSignal、文档 ID/版本和当前 generation；结果状态为 `completed/failed/cancelled/stale`；按 DAG `levels` 使用 `Promise.all` 并行执行同层节点，并按稳定计划顺序合并结果和进度；可选的 `createFacadeGeometryRecomputeExecutor` 在 OCCT Worker ready 时执行真实 Pad/Pocket/Revolution/Fillet/Chamfer | 取消、过期版本、依赖失败传播、独立节点并行、闭合 Sketch 特征链、Revolution 角度/反向和 Facade 提交测试通过 | 默认数据模型仍不持久化 ShapeHandle；Up to face、拓扑历史映射、每节点独立 Worker 和完整 PartDesign 特征仍待实现；失败时缓存保留最近有效 Shape |
| DAG-08 失败/抑制传播 | 上游 `error` 将下游置为 `upstream-failed`；Feature 的可持久化 `Suppressed` 属性将自身置为 `suppressed`、下游置为 `upstream-suppressed`，不误报重算失败；抑制时释放缓存 Shape，解除后只重算依赖闭包；重算错误映射为带版本、generation、根因、依赖路径和修复动作的诊断树 | 上游失败、抑制跳过、Shape 释放、保存恢复、根因树、对象定位和解除错误后的最小闭包修复测试通过 | 多配置抑制、Body Tip 重定向、最近有效 Shape 显式回滚和完整 FreeCAD 状态机仍待实现 |
| P4-06 任务提交与重算闭包 | Task 草稿在 Facade 事务内写入 Boolean Base/Tool 等链接；新对象和依赖闭包进入 `touched/dirty`，React OK 通过 `recomputeAsync()` 提交并反馈结果；Facade `diagnostics` 提供根因树和定位/闭包重算/合法抑制修复，Diagnostics 页面只做事件投影 | Boolean Task 链接/依赖测试、Task dirty 快照、根因路径和修复后诊断清理通过 | Apply 预览仍未持久化临时 Shape；多选选择集、Shape 回滚和完整 FreeCAD Task 校验仍待实现 |
| DAG-07 Body/Tip 与来源链接 | Part Design 特征提交时按来源类型绑定 Profile/Base，更新只读 Body.Tip，并将 Body 与新特征一并纳入 dirty/recompute 闭包；Undo/Redo 恢复 Tip | Pad Task、Body.Tip、Undo/Redo 回归测试通过 | 单实体规则、Tip 抑制/重定向、复杂容器和跨 Body 支持仍待实现 |
| SK-04 求解器边界 | `DONE`：版本化请求/响应、provider 能力探测、取消/过期 generation 隔离和回放合同已落地 | 基础 provider 回放、并发取消和文档版本过期测试通过 | 当前是基础 TypeScript solver；`planegcs-wasm` provider 明确报告 unavailable，不虚报 SK-03 完成；高级约束、拖拽、外部几何和 B-spline 未完成 |
| FC-03 ZIP 安全读取 | 先读中央目录再解压；限制 archive/entry/total 字节、压缩比、条目数；拒绝路径穿越、重复路径、加密项、ZIP64 和 XML entity | 缺 Document.xml、路径穿越、压缩炸弹测试通过 | 尚未恢复 BRep/Shape、视图、表达式和参数化对象 |
| FC-04/FC-07 只读报告 | `project.fcstd.inspect()` 解析 Document.xml 对象声明、Label、属性数量和类型；未知类型为 proxy，Python 类型为 blocked；脚本资源只告警且不执行 | recognized/proxy/blocked 分类和 Facade-only 测试通过 | `metadata-compatible` 仅表示 XML 元数据可读，不表示 FCStd 可编辑或 round-trip |
| P2-04 Project list/load | `project.list()` 暴露 SQLite/内存快照摘要，`app.document.load()` 将选定快照作为活动 Document 事务恢复，清理旧重算/Shape/Task 状态、保留 Undo 边界并按完整对象图异步重算；Projects 页面按 documentId 调用 Facade API | 列表摘要、保存→修改→加载后属性恢复、选择清空、任务清空和加载重算调用通过测试 | FCStd 导入仍是只读 metadata/proxy；跨文档 ShapeHandle 和 Shape 持久化仍待完成 |
| P2-01/P2-02 Migration/write pressure | schema v7 与统一事务 migration runner；v6 新增对象拓扑快照 JSON，v7 新增稳定原生对象标签；失败 rollback；写队列严格串行并在失败后继续 | migration 排序/跳过/回滚测试、真实 Chrome OPFS v1→v7、标签重开/checkpoint 往返及 1000 次队列压力通过 | 跨发布降级、断电 journal 恢复和用户数据备份仍待完成 |
| P2-03 Resource/recovery fallback | SQLite Worker 在无 OPFS 时使用内存资源表；OPFS 模式增加配额预留、重复内容免写、缺失文件重建和孤儿/零引用/缺失文件对账清扫；Facade 暴露 sweep 报告 | quota/sweep 纯策略、fallback API、Worker 类型检查和生产构建通过 | 真实 OPFS 孤儿清扫、QuotaExceeded、大文件压力及浏览器崩溃注入仍待完成 |
| P2-04 Version checkpoints | 文档规范化保存与完整 JSON checkpoint 同事务；每文档保留最近 5 版；Recovery 列出版本，Facade 可加载指定/最新 checkpoint | 7 版保存后仅保留 3..7、指定版本/最新版加载、过期版本删除和深克隆测试通过 | 当前测试使用 transient fallback；SQLite/OPFS 断电点恢复和保留策略 UI 待完成 |
| PART-07 Shape check | `check-shape` 使用 Facade `geometry.topology()` 生成面/边/顶点数量和 `SHAPE_CHECK_PASSED` 信息诊断；空缓存、空拓扑和 Worker 错误分别返回结构化失败诊断 | 无 Shape、错误选择前置和拓扑调用边界通过测试/构建 | 当前是网格派生拓扑检查，不等价于 OCCT `BRepCheck_Analyzer`，完整修复建议和自交诊断仍待实现 |
| P1-02 命令准确性 | manifest 仍可完整展示；Part `primitive/union/cut/intersection` 与 Part Design 核心命令已有 Facade executor；命令状态同时检查工作台和对象类型选择谓词；其余未接入 executor 的命令返回 disabled 与 `COMMAND_UNIMPLEMENTED`，不再静默完成 | Part 基本体/布尔 Shape 缓存、选择不兼容时的禁用原因、`additive-loft` 未实现状态与诊断测试通过 | 其余工作台要逐项增加真实 executor、Task 参数和黄金回放后才能启用 |
| P3-05 Pattern 实验切片 | `linear-pattern` 和 `polar-pattern` 通过 Part Design 选择谓词、Task 和类型化属性创建对应对象；Linear 按总 Length 等距平移，Polar 在小于 360° 时覆盖首末角、360° 时不复制重合端点；两者均由 OCCT union 合并并释放临时副本 | 线性间距/方向、圆周完整/部分角度分布、联合输入、句柄释放、非法参数诊断、Base 链接、Body.Tip、属性校验和任务提交回归测试通过 | 当前为 FreeCAD 1.0+ 的 Transform body 近似，只复制整个 Base Shape；未实现 Transform tool shapes、连接单实体过滤、稳定 TopoRef、历史映射、反向轴和引用轴，因此保持 `experimental` |
| P3-07 MultiTransform 实验切片 | `multi-transform` 使用结构化有序 Linear/Polar/Mirrored 步骤，Task 与属性面板共用编辑器；重算逐步扩展 whole-shape 实例并最终 union，限制最多 6 步和 100 个组合实例 | 6 实例组合、方向/平面映射、故障注入、中间 Shape 完整回收、最近有效缓存、深拷贝、Undo/Redo、fallback 保存恢复与任务提交测试通过 | 不是 FreeCAD 局部 Transform feature history；未实现特征列表、Datum/TopoRef 轴面、单实体规则与原生拓扑历史，保持 `experimental` |
| P3-05 Hole 基础切片 | `hole` 创建 `PartDesign::Hole`，用 32 边圆形 Profile 或圆锥刀具调用现有 OCCT Pocket/Cut；支持 Diameter、DepthType/Depth、Position/Direction、Reversed、Flat/Angled DrillPoint、DrillForDepth、Tapered/TaperedAngle 以及 Dimension/ThroughAll，校验正尺寸并纳入 Base 链接和 Body.Tip | 圆孔 Profile、有限深度调用、位置/方向、90 度基准锥度、包含钻尖总深度、非法直径/方向诊断、Task 属性提交和 Tip 更新测试通过；Counterbore/Countersink/Counterdrill、Angled drill point 和 Tapered 由 Bitbybit 圆柱/圆锥刀具加 Boolean Cut 组合执行，并有 Chrome 非空 mesh 与 0/0 release 证据 | 仍未实现 Threaded/ModelThread、标准尺寸、Support/Profile 面定位和完整局部特征历史；螺纹保持显式 `HOLE_THREADING_UNSUPPORTED`，能力保持 `experimental` |
| TSN-02/05/06/08 TopoRef 基础迁移 | `topologyReferences` 提供 schema v1 创建、序列化、安全解析、解析和跨版本迁移；重复几何通过邻接指纹唯一消歧，一旧多新不会错误继承；匹配按 kind 隔离并用形状尺度归一化几何评分支持纯平移；对象快照附带 schema v1 ElementMap；新增原生 ElementMap2 v1 token AST/schema v2 writer，以及 StringHasher v1 AST/schema v2 codec | round-trip、瞬时索引拒绝、resolved/ambiguous/deleted、重复拆分、邻接唯一/对称回归、FaceN/EdgeN/VertexN 写出和持久化通过；FreeCAD 1.1.1 的 30 模型、91 个 ElementMap2、11 个 StringHasher 表完成解析、写回和引用闭合 | Web 拓扑仍不能凭最终几何生成 FreeCAD 私有算法未提供的历史 token/StringID；对称 Boolean 的同构子形需要原生候选证据才能消歧 |
| TSN-08/09 LinkSub 文档接线 | `PropertyValue` 支持 schema v1 TopoRef；重算 generation 自动迁移 LinkSub/草图外部几何，歧义/删除不强绑；schema v7 保存对象拓扑快照、ElementMap 与稳定原生对象标签；Facade 候选替换事务验证当前同 kind persistentId，重建 DAG 并支持 Undo/Redo；属性/诊断 UI 可替换；Three.js 多 Mesh 场景已将对象/OCCT analytic 面边点拾取、预选、完整曲线折线高亮、诊断闪烁和 window/crossing 框选回调 Facade；Pocket 暴露 `UpToFace` 槽；Pocket/Groove/Hole/MultiTransform 及双侧线性/角度特征可携带内部 builder 的 STEP/topology/history stage；ElementMap2 writer 可从 MappedNameRef/StringID 证据生成 FreeCAD 1.1.1 token，FCStd reader/writer 会校验 StringHasher 引用闭包 | 非法瞬时索引/候选拒绝、DAG 边、稳定/歧义/删除迁移、邻接消歧、候选替换、Undo/Redo、保存加载、无三角对角线的 BRep 边拾取、多选集合、真实双对象穿越框、诊断聚焦事件、live ElementMap、Pocket 双侧、Revolution/Groove 双角 Chrome 回放及 30 模型 naming-evidence gate 通过 | 未提供逐阶段 Shape/history 或 MappedNameRef/StringHasher 证据的算法继续保守回退；同构子形无唯一原生证据时不宣称 exact |
| TSN-03/07 历史适配器回退 | Bitbybit 1.1.1 绑定仅有 `HasGenerated()`，没有逐 Shape 的 Generated/Modified/IsDeleted；独立 native provider 已接入普通及双侧 Pad/Pocket/Revolution/Groove 参数路由与既有 Boolean/Pattern/Dress-up 子集；协议新增显式 input/stage、sourceStage/resultStage、一对多 resultIndexes、有序 feature sides 和 rotate stage，可向后兼容旧 object/tool 载荷；stage capture 按各自产生结果解释 index 并以邻接唯一性约束同构候选 | 平移修改、新增/删除/重复面、邻接唯一消歧、跨对象竞争、generation 写回、采集失败隔离、Up-to-face 有效距离、Two sides/Midplane/Two angles 路由通过；Groove 双角按 FreeCAD profile offset + 单 sweep + Cut 得到 native valid 单 solid；30 模型 history/ElementMap2/StringHasher exact gate 与 Facade `182/182` 通过 | provider 仍通过 STEP/BREP 跨 WASM；同构候选和未提供私有 builder/命名证据的算法仍需逐项黄金模型后才能声明 exact |

原生历史 provider 适配器现已进入重算执行器：当 Geometry Worker 暴露 `topologyHistory()` 且 Base/Tool/Profile 有拓扑快照时，Facade 将真实输入/输出 Shape 和记录交给 `captureNativeTopologyHistoryStages()`，再由 `composeNativeTopologyHistoryLineage()` 把上游对象 stage 接入当前关系；普通 Pad/Pocket/Revolution/Groove、Up-to-face 有效长度以及双侧/Midplane/Two angles 会进入同一参数协议。Pocket、Hole、MultiTransform 和双侧 builder 保存中间 STEP/拓扑/记录；Groove TwoAngles 按 FreeCAD 语义保存 `rotate -> revolution -> cut` 的 BREP/history，并已通过 native BRepCheck Chrome 黄金门。provider 不声明组成 operation 时保留单响应兼容路径。exact 判定仍必须同时拥有逐阶段 Shape/history 与 MappedNameRef/StringHasher 命名证据，任一缺失都不能由最终几何补推。

后续按以下顺序连续开发：

1. `P4-06/DAG-08`：同步/异步重算已共享抑制传播和根因诊断语义，并支持定位、解除错误后的最小闭包重算与合法特征抑制；继续补齐多配置抑制、Body Tip 重定向、最近有效 Shape 显式回滚和性能计数器。Shape 缓存已进入 Facade，但尚未持久化。
2. `P3-04/P3-05`：Pad/Pocket/Revolution/Fillet/Chamfer 已有 OCCT Worker 输入适配和 Shape 缓存回写；Up-to-face 实际距离、Part 双向 Extrude/Revolution、PartDesign Two sides/旧 TwoLengths 与 Revolution/Groove Midplane/Two angles 已进入原生协议，Groove 双角的 FreeCAD 单 sweep 语义和结构有效性已闭合。继续扩展锥度逐阶段 history、局部 feature-list 重算、螺纹/标准尺寸及稳定 Support；未通过黄金 Shape/history 的能力保持 compatible 或 experimental。
3. `TSN-03/07/08`：TopoRef schema、面/边/点签名、基础迁移和歧义处理已落地；继续补齐 OCCT Generated/Modified/Deleted、邻接/曲率签名、跨布尔历史和数据库属性接线；任何 transient index 不得写入持久引用。
4. `SK-03/SK-06/SK-07`：编译和验证 planegcs WASM，按基础/高级约束建立 FreeCAD 黄金回放；基础 solver 维持 experimental。
5. `P2-04/P2-05/P2-06`：完成保存点恢复报告、迁移回滚、配额回收和 BroadcastChannel 单写者冲突。
6. `FC-04/05/06/10`：增加 XML/Shape/Expression/Link 映射，未知字段原样保留，完成 WebCAD↔FCStd↔FreeCAD 差异报告。
7. `P6-03/P8-02`：把 disabled 原因、重算进度/取消、FCStd 报告和能力矩阵接入 React，并通过目标浏览器回放和视觉基线。

启用规则：`RecomputeExecutionResult.status=completed` 只表示已注册节点成功；FCStd `metadata-compatible` 只表示安全元数据可读；只有 FreeCAD 对照黄金测试、取消/失败/只读、保存/加载和跨浏览器门禁都通过，才能把对象或命令从 `experimental` 提升到 `compatible`，`exact` 还要求锁定版本后的逐项差异为零。

### 20. 命名证据与系统级 exact 评估（2026-08-09）

运行时命名证据必须来自 native provider 的 `MappedNameRef`/`StringHasher` 或逐阶段 builder capture。`NativeStageNamingEvidence` 对缺失证据写出 `final-shape-only`，对只有原始表而没有可重建回调的 FCStd 资源写出 `opaque-preserved`；两者都不能仅凭最终 Shape 生成新 FreeCAD token。跨阶段 ElementMap2 映射保存 `sourceStageId`、来源集合和 `ambiguous` 候选，校验失败直接阻断写回。

`FreeCADPrivateNamingABI v1` 已定义为版本化 Embind/JSON 合同，并接入 direct provider 与真实 Worker：请求携带 operation、输入 STEP、最终 STEP/BRep、阶段 DAG 和原生 history，响应必须同时提供 `MappedNameRef`、StringHasher 与 ElementMap2，且逐项通过 stage/result 绑定、大小上限、schema、StringID 和引用闭包校验。生产运行时声明 `freecad-private-v1-optional-worker`，mock 明确为 `not-exposed`；未导出三项回调、版本/锁定提交不符、证据不闭合或 operation 未声明时均 fail-closed 到 `final-shape-only`，禁止合成 token。当前仓库随附的 `native/occt-history` 已链接锁定的 FreeCAD 1.1.1 私有命名实现，但该完成只关闭生产 ABI/builder 覆盖，不把系统整体提升为 exact。

ABI 输入现同时携带文档 `objectId`、FCStd 原生正整数 object tag、上一阶段命名证据、明确的 result object/tag 和阶段 DAG；object tag 会从 `Document.xml` 的 `Object.id` 导入，按稳定值写回 FCStd，并通过 SQLite schema v7、OPFS 重开和 checkpoint 往返。命名 ABI 只接收能解析到传输输入 `inputId/role` 的历史来源：Hole、Pattern、Mirrored 等 builder 的内部 tool/copy 记录会被明确排除，C++ bridge 继续拒绝未知来源，禁止把内部形体冒充为外部 Base。`build:occt-history` 现在是生产 fail-closed 构建入口，只接受锁定提交、Emscripten 3.1.69、wasm Qt/Python、FreeCADBase/FreeCADApp/Part 静态库及三回调 bridge 的哈希清单，并发布 JS/WASM/DATA；OCCT-only 构建只允许写入不发布的候选目录。`check:occt-history-artifact` 会实际实例化 WASM 并探测三回调，Node 与 Chrome 生产矩阵还会逐项执行 19 类 builder。因此 `EX-TSN-02=completed`，而 `systemExact=false` 继续成立。

Qt 前置条件已按独立、可离线复现的链路落地：`build:qt6-wasm-core` 使用 Emscripten 3.1.69 构建 QtBase 6.8.2 静态 wasm `Qt6Core`，下载使用 USTC 国内镜像，但必须先通过 Qt 发布包官方 SHA-256；离线模式缺包时直接失败，不允许回退联网。`build:freecad-naming-source-probe` 进一步锁定 FreeCAD 提交及 `IndexedName.cpp`、`MappedName.cpp`、`StringHasher.cpp`、`MappedElement.cpp`、`ElementNamingUtils.cpp`、`ElementMap.cpp`、`Base/Handle.cpp` 七个原始编译单元的内容哈希，并验证它们能与 wasm Qt6Core 一起生成和执行 wasm32 探针。运行时覆盖名称解析、StringHasher 去重/SHA-1 阈值/索引引用、ElementMap 编码/双向查找/历史/保存恢复以及 MappedElement 稳定排序；真实 ElementMap 保存体和 StringHasher 表还会经过 Web 侧 ElementMap2 parser、引用闭包及严格 `FreeCADPrivateNamingABI` 校验。探针只导出隔离的 `freecadNamingCandidate*` 名称，持久化流、Python 包装、类型系统、日志和 Application/Document 生命周期仍由适配头提供；FreeCADApp/Part/Python 静态库、真实文档集成、OCCT builder 上下文和生产 bridge 均未链接。因此它证明的是锁定私有源码子集与 ABI 数据可交叉编译/运行，不构成生产命名实现。

`check:freecad-private-naming-boundary` 同时读取 ABI 合同、兼容性矩阵、exact 计划及 Node/Chrome 生产报告，固定校验 `shippedWorkerImplementation=freecad-linked`、`freecadNamingBuild.status=production-linked`、`EX-TSN-02=completed` 与 `systemExact=false`。检查还要求三项回调、19 类 builder、链式 StringHasher、缺历史 fail-closed 及 JS/WASM/DATA/harness 哈希同时成立；该检查已进入默认 `verify`、真实 wasm lane和离线 smoke。

生产 SDK 前置已有完整候选闭包。七个锁定命名编译单元仍保留 `libFreeCADPrivateNamingProbe.a` 作为源码先决条件；实际 bridge 则链接真实 FreeCADBase/FreeCADApp/Part、QtCore、CPython 及 21 个传递依赖，并初始化真实 `App::Application`。`check:freecad-naming-sdk-readiness` 解析所有静态 `ar` 成员并拒绝宿主 ELF；`generate:freecad-naming-sdk-manifest` 还锁定 C++20、pthread、兼容头、host adapter 和预加载的 Python wasm stdlib。完整 `check:freecad-naming-sdk` 对库、源码和运行时文件逐项复算 SHA-256。

隔离 bridge 的 Node 烟测已用真实 `ElementMap/MappedName/StringHasher` 生成首阶段和链式证据，并验证 `$#id:index` 与 StringHasher 闭包。独立 pthread OCCT 候选仍保留为不发布的前置门；生产 Worker 则在 Node 和真实 Chrome 中对同一共享矩阵执行 19 类 OCCT builder，再从同一 wasm 调用三项 FreeCAD 私有命名回调。Chrome 执行与报告检查分开，检查器会拒绝与当前 JS/WASM/DATA 或共享 harness 哈希不一致的旧报告。生产链接已完成；剩余 exact 阻断为同构来源唯一性、完整跨特征/FCStd 往返和完整文档/属性语义。

Sketcher/PartDesign 的 Web 支持范围新增可执行参数合同：Sketcher 覆盖 FreeCAD 1.1.1 FCStd 表面的 9 类 geometry、19 类 constraint 和 10 类 InternalAlignment 语义；PartDesign 覆盖 Facade 已支持的 21 个 family、202 个属性槽和 72 个语义分区，并在对象创建及属性编辑时执行跨字段校验。`check:freecad-sketcher-partdesign-abi` 会从实现重算这些计数并拒绝陈旧报告；该“完整”限定于 supported Web Facade，不包含尚未实现的 FreeCAD PartDesign TypeId，也不表示 basic TypeScript solver 已求解全部圆锥曲线约束。

逐 feature 等级目前由 `config/compatibility-matrix.json` 的 `facadeCapabilities.geometry.featureLevels` 管理：Pad/Pocket/Revolution/Groove/Boolean 为有 native history 子集的 `compatible`，Fillet/Chamfer/MultiTransform 保持 `experimental`。`systemExactEvaluation.exact` 必须在所有 feature 的阶段 Shape/history、私有 token 证据和同构来源都闭合后才允许改为 true；当前值固定为 false，阻断项为私有 FreeCAD token 算法、没有原生 builder stage、以及无唯一同构来源。

### 21. 全功能 exact 计划（2026-08-09）

全功能对标不再沿用已经 `83/83 completed` 的 compatible 发布 WBS 作为完成判据。`config/freecad-web-exact-parity-plan.json` 建立 EX01..EX10、52 项 exact 任务，覆盖 34 模块、15 格式、6 入口，详细依赖和验收见 `docs/freecad-full-parity-execution-wbs.zh-CN.md` 第 20 节。优先顺序为原生 oracle -> kernel/history/naming -> document/property -> Sketcher/Part/PartDesign -> FCStd/formats -> GUI -> 生产/工程/平台工作台 -> 跨浏览器质量 -> exact 签名发布。

`check:freecad-web-exact-parity-plan` 与旧 execution-plan gate 一起进入默认 verify。开放任务必须保留 `exactBlockedBy`，完成任务必须具有已登记的可执行 evidence 且不能继续带阻断项；34 模块和 21 个格式/入口必须逐项映射到任务。最终 `EX-REL-01` 只有在所有任务完成、34 模块均为 exact、八项零差异指标成立时才允许关闭。计划建立时基线为 `1/52 completed`；截至第 23 节已推进为 `3/52 completed`，系统仍为 `exact=false`。

`check:freecad-web-exact-promotion` 进一步阻止直接编辑 `claim.exact` 或能力矩阵来“提升”版本：在 `exact=false` 状态只输出 fail-closed；只有 `EX-REL-01` 完成并提交结构化 promotion report，报告同时满足 52/52、34/34、八项指标全零和八类证据，才允许 promotion gate 通过。

详细实施手册见 `docs/freecad-exact-promotion-runbook.zh-CN.md`，报告结构见 `config/freecad-web-exact-promotion-report.schema.json`。手册按七个阶段规定输入、任务、命令、退出条件和失败回退，防止把规划状态、兼容子集或静态清册当成 exact 证据。

### 22. 参数 mutation 与阶段命名证据闭合规则（2026-08-10）

EX-ORA-02 的 mutation corpus 由 `config/freecad-parameter-mutation-plan.json` 定义为五项独立证据：nominal 参数、非法边界、两个以上显式参数快照、真实编辑-重算-恢复事务，以及无差异 FCStd 往返。`config/freecad-parameter-mutation-report.json` 必须由现有黄金证据生成，`check:freecad-parameter-mutations` 会逐字节重算并拒绝陈旧或手工提升的报告。该矩阵建立时只有 `1/35` family 完整，当前已为 `35/35`；EX-ORA-02 仍因逐 family 原生 Shape/history/ElementMap2/StringHasher 和未知语义差异的更大验收范围保持 `in_progress`。

30 个复合模型的 219 个文档阶段已通过 FreeCAD 运行时 `getElementMappedName/getElementIndexedName/getElementHistory` 获得直接命名证据，并由两个门禁逐阶段验证。此处的 `native-evidence=219/219` 不等于内部 builder exact：219 个阶段都有 IndexedName，但只有 74 个阶段的全部子形有 MappedName，145 个阶段只有原生索引身份；当前识别出的 42 个操作阶段仍为 `internalBuilderEvidence=0`。没有内部 builder Shape/history 时，最终几何不能用于制造中间 Generated/Modified/Deleted；没有实际 StringHasher/MappedNameRef 时也不能制造私有 token；同构候选没有唯一原生来源时继续持久化为 ambiguous。

### 22.1 30-case 原生 mutation 与恢复门（2026-08-14）

`freecad-composite-history-elementmap-oracle` 现把固定语料锁定为 `9 Boolean + 11 PartDesign + 6 复合 Boolean + 4 dress-up`，每个 case 声明目标对象、原生 Property TypeId、editor mode、编辑值和最终对象。采集器对每个 case 执行 before/edit/recompute/restore/recompute，并为全部 219 个阶段保存三相几何、关系和命名摘要，共 657 条阶段记录。解析几何摘要包含拓扑计数、包围盒、顶点坐标、边长、面面积、面积和体积，不依赖 B-Rep 文本中的瞬时内部布局；原始 B-Rep SHA-256 仍单独保留作证据。

锁定 FreeCAD 1.1.1 实跑结果为 `mutation=30/30`、最终传播失败 `0`、几何恢复失败 `0/219`。mutation 恢复后的状态才作为 FCStd nominal 基线，30 个 case 再完成 save/reopen/resave，219 个阶段的 `roundtripNameDrift=0`、`resaveNameDrift=0`。FreeCAD 重算过程中，11 个 PartDesign case 的 28 个阶段在参数恢复后产生不同的原生 relation/semantic-name digest；该差异被单独锁定为 mutation naming drift，不能与几何恢复混算，也不能被零保存漂移掩盖。

`check:freecad-composite-history-elementmap`、`check:freecad-tsn-stage-correlation` 和 `check:freecad-exact-history-elementmap-gate` 共同按 case id、类别配额、stage ordinal 和三相 identity fail-closed。来源解析同时接受 FreeCAD 原生 `FaceN/EdgeN/VertexN`、`#d:1`、`#42` 与 `g1v2;SKT` 语法，不再把原生局部 token 误判为未解释关系。当前三门结果均为 `wrongBindings=0`、`unexplainedRelations=0`，但 mutation naming drift、五阶段 proxy/builder 缺口及未分类操作对仍使 `EX-TSN-04=in_progress`、`exactPromotionReady=false`。

### 23. EX-PD-02 Attachment 与跨文档引用闭合（2026-08-13）

`EX-PD-02` 已按独立机器证据关闭。FreeCAD 1.1.1 原生 Attachment 注册表仍为 55 项，四类引擎实现并集为 50 项；新增全组合 oracle 将 Plane/Sketch/Line/Point 的所有模式及所有引用组合展开为 236 个可执行槽位。每项都通过初始重算、统一源几何平移和 FCStd 关闭重开，Placement 与支持引用无漂移。原有未实现模式反例仍要求 `Touched + Invalid`，不会因本批完整执行覆盖而被误判为实现。

跨文档 corpus 同时覆盖 `PropertyXLink`、`PropertyXLinkSub`、`PropertyXLinkList`、`PropertyXLinkSubList` 和 SubShapeBinder。源关闭与源文件缺失时链接值清空、Binder 保留最后有效 Shape；恢复原文档 ID/路径后自动重连，后续参数编辑和再次 FCStd 往返继续传播。Web Chrome 以真实 OCCT Shape、OPFS、undo/redo 和最终 `0/0` ownership 回放同一生命周期，执行命令与静态报告检查分离。

该完成不解除更大范围任务：`EX-PD-01` 仍需完整注册 PartDesign TypeId 与参数交叉积，`EX-DOC-04` 仍需全应用多文档/merge/conflict/crash recovery；生产 Worker 命名链接已由 `EX-TSN-02` 关闭，同构 provenance 已由 `EX-TSN-03` 关闭。系统维持 `exact=false`，当前 exact 计划计数为 `5 completed / 36 in_progress / 11 pending / 0 blocked`。
