# WEB FreeCAD 对真实 FreeCAD 差分实施计划

## 1. 文档职责

本文定义 WEB FreeCAD 如何通过真实执行逐项对标锁定版 FreeCAD，并把发现、复现、纠正、回归和能力提升拆成可执行的最小任务。本文不维护实时完成数或下一任务名称；动态状态只读取：

1. `config/freecad-active-work-queue.json`：唯一 `nextTask`、依赖、状态和退出条件。
2. `docs/freecad-active-work-status.generated.zh-CN.md`：同一生成器产生的状态摘要。
3. `config/freecad-web-exact-parity-plan.json`：系统级 exact 任务和阻断项。
4. `config/release-capability-matrix.json`：34 个模块可对外声明的能力等级。
5. `config/*oracle*.json`、`config/*verification*.json`：真实执行证据。

若文档描述与机器报告冲突，以机器报告为准。界面相似、命令存在、OCCT 能生成相似 Shape、Node 单测通过，都不能单独证明与 FreeCAD 对标。

## 2. 对标目标和红线

目标基线固定为 FreeCAD `1.1.1`、Git 提交 `0108fd4b4850cc46e625b60e53cea7a7bbe69f8d`。WEB FreeCAD 必须在浏览器可实现范围内逐项匹配：

- 命令可见性、启用条件、上下文和失败诊断。
- 对象 TypeId、属性类型、默认值、状态位、editor 行为和生命周期。
- Document 对象图、依赖 DAG、recompute、事务、observer、Undo/Redo 和失败恢复。
- Shape 有效性、拓扑数量、质量属性、边界、公差、placement 和 builder 历史。
- Generated/Modified/Deleted、ElementMap2、MappedNameRef、StringHasher 和 LinkSub 稳定性。
- FCStd、BREP、STEP、IGES 及其他格式的读取、编辑、保存、重开和再次保存。
- GUI Task、对话框、选择、预选、焦点、模型树、属性面板、状态栏和长任务。
- Worker、WASM、OPFS、GPU、内存、取消、崩溃和资源释放。

以下行为一律禁止：

- 用手工 JSON、Mock、截图或静态源码推断替代真实 FreeCAD 执行。
- 用最终 Shape 相似掩盖中间 history、命名、事务或对象图差异。
- FreeCAD 原生拒绝时，为了增加 WEB 支持数而偷偷接受。
- 原生来源不唯一时按数组顺序、网格索引或最终拓扑位置伪造稳定名称。
- 未知 Property、Extension、资源或脚本被静默丢弃、重写或标记可编辑。
- UI 绕过 Facade 直接调用 OCCT、Three.js、OPFS、SQLite 或脚本执行器。
- 放宽断言、删除 fixture 或改写报告来让 exact promotion 通过。

## 3. 真实执行环境

### 3.1 锁定产物

| 运行面 | 固定入口 | 用途 | 必须锁定 |
| --- | --- | --- | --- |
| Headless FreeCAD | `.cache/freecad/install-native/bin/FreeCADCmd` | Part/几何、黄金场景、错误和文件回放 | 版本、提交、二进制 SHA-256、Python 驱动 SHA-256 |
| Desktop FreeCAD CLI | `.cache/freecad/install-desktop/bin/FreeCADCmd` | 34 模块对象、Property、PartDesign、命名、FCStd | sysroot、模块加载、隔离配置、二进制 SHA-256 |
| Desktop FreeCAD GUI | `.cache/freecad/install-desktop/bin/FreeCAD` | 命令、Task、QAction、焦点、选择、视图和工作台 | `xvfb-run`/显示环境、用户配置、locale、DPI |
| Bitbybit OCCT | `@bitbybit-dev/occt` 1.1.1 | Web 几何兼容路径 | npm 版本、WASM SHA-256、API surface |
| 原生 history provider | `native/occt-history/dist/*` | builder history、命名 ABI 和三方差分 | JS/WASM/data 哈希、OCCT 版本、导出 ABI |
| Web 浏览器 | Playwright 锁定浏览器 | Worker、WASM、OPFS、UI、GPU 和交互 | 浏览器版本、viewport、deviceScaleFactor、特性开关 |

### 3.2 环境隔离

每次原生执行必须：

1. 使用任务专属临时目录和独立 FreeCAD user/system config。
2. 固定 locale、时区、单位、线程和随机种子；无法固定的字段进入显式归一化清单。
3. 禁止读取用户真实 FreeCAD 配置、最近文件、插件目录和自动恢复文件。
4. GUI 探针在虚拟显示中运行，记录分辨率、DPI、主题、字体和窗口状态。
5. 运行前记录二进制、harness、fixture 和输入资源 SHA-256。
6. 运行后关闭文档、进程和 Worker，检查临时文件、Shape handle、WASM 引用和 OPFS lease。

### 3.3 基线验证命令

```bash
.cache/freecad/install-native/bin/FreeCADCmd --version
.cache/freecad/install-desktop/bin/FreeCADCmd --version
./npmw run check:baseline
./npmw run check:freecad-desktop-oracle
FREECAD_ORACLE_PROFILE=desktop xvfb-run -a ./npmw run probe:freecad-reference
./npmw run check:freecad-oracle-coverage
```

任一版本、提交或 artifact hash 不一致时，当前功能任务停止；先恢复基线，不允许生成新的对标结论。

## 4. 三层真实差分链

### 4.1 原生事实层

原生 FreeCAD 每个案例至少输出：

- `baselineId/freecadVersion/gitCommit`。
- harness、fixture、输入资源路径、字节数和 SHA-256。
- 文档对象集、对象顺序、TypeId、Label、Visibility 和状态。
- Property 名称、TypeId、值、status、editor mode、表达式和链接。
- recompute 返回值、错误、状态字符串、事务和 observer 事件。
- Shape null/valid、类型、Solid/Face/Edge/Vertex、体积、面积、边界和 BREP hash。
- builder 输入、阶段、Generated/Modified/Deleted、命名和歧义。
- save/reopen/resave 的三相快照。

### 4.2 WEB 实现层

相同案例必须通过生产 `BitBybitWebCadFacade` 进入，不直接调用 UI 内部对象。输出至少包含：

- Facade command/request schema 与版本。
- Document revision、transaction id、generation 和依赖重算结果。
- Worker provider、WASM artifact、Shape handle 所有权和释放计数。
- 与原生同结构的对象、Property、Shape、history、命名和诊断快照。
- OPFS checkpoint、项目资源引用、FCStd/交换格式产物。

### 4.3 真实浏览器层

浏览器案例必须验证：

- UI 命令状态与原生 QAction/command manager 状态一致。
- Task 打开、预览、校验、Apply/OK/Cancel、焦点和选择轨迹一致。
- Worker 真正加载 WASM，不能退回 mock provider。
- save/reopen/resave 经过 OPFS 或声明的 fallback，不能只在内存中模拟。
- 取消、崩溃、超时、stale response 不提交旧结果。
- 完成后 Shape、Worker 请求、OPFS lease、GPU/Three 资源回到预期基线。

## 5. 比较合同

### 5.1 比较优先级

| 级别 | 比较域 | 必须一致的字段 | 允许差异的前提 |
| --- | --- | --- | --- |
| D0 | 基线 | 版本、提交、artifact、harness、fixture | 不允许 |
| D1 | 接受/拒绝 | 命令 enabled、builder success、失败阶段、诊断分类 | 仅文案本地化可归一化 |
| D2 | 文档 | 对象集、TypeId、依赖、Tip、Support、状态、事务 | 仅已登记浏览器代理对象 |
| D3 | Property | 类型、值、单位、约束、status、editor、表达式、link | 仅显式 opaque/read-only |
| D4 | 几何 | null/valid、Shape 类型、拓扑计数、质量属性、边界、公差 | 数值必须在场景声明公差内 |
| D5 | 历史命名 | stage、Generated/Modified/Deleted、provenance、LinkSub | 原生歧义必须保持歧义 |
| D6 | 持久化 | 对象/属性/资源、Shape、命名、GUI state | 未知资源只能字节保持或拒绝编辑 |
| D7 | GUI | visible/enabled、Task、焦点、选择、树、对话框、状态 | 浏览器保留键需显式映射 |
| D8 | 资源质量 | 时间预算、内存、取消、崩溃、释放、离线 | 只允许已登记平台差异 |

### 5.2 数值和结构规则

1. 离散值、对象数、拓扑数、状态、枚举和错误分类必须精确一致。
2. 长度、面积、体积、角度和矩阵按 fixture 声明公差比较；禁止使用全局无限放宽公差。
3. BREP hash 只在序列化确定的同一阶段要求相等；若 FreeCAD 合法重序列化，必须同时比较结构摘要并登记原因。
4. 属性和对象顺序只有原生语义明确要求时才比较顺序，否则按稳定 identity 比较。
5. 错误文本保存原文，同时生成稳定 reason code；测试以 reason code 和关键原文片段双重锁定。
6. 指针、UUID、临时路径、进程号等非确定字段只能由集中归一化器处理，禁止单个测试随意删除字段。

## 6. 差异分类与纠正协议

### 6.1 唯一分类

每个差异必须落入且只落入一种分类：

| 分类 | 含义 | 动作 |
| --- | --- | --- |
| `web-implementation-defect` | FreeCAD 稳定，WEB 输出错误 | 同一任务内修复实现并补回归 |
| `web-missing-capability` | FreeCAD 接受，WEB 无实现 | 保持 pending/in_progress，按 A-I 补齐 |
| `web-over-acceptance` | FreeCAD 拒绝，WEB 接受 | 删除/封闭 fallback，匹配拒绝和回滚 |
| `web-over-rejection` | FreeCAD 接受，WEB 拒绝 | 修正输入映射、builder 或能力探测 |
| `native-allowed-evolution` | FreeCAD 自身编辑恢复后命名合法演进 | 保存原生复跑证据，WEB 不强制旧名称 |
| `native-ambiguous` | 原生来源不唯一 | WEB 保持 ambiguous/fail-closed |
| `platform-difference` | 浏览器安全/平台限制无法逐字相同 | 明确 compatible/proxy/excluded 和用户诊断 |
| `oracle-defect` | harness、fixture、归一化或基线错误 | 修复 oracle，旧结论失效并全部复跑 |
| `unknown` | 尚无充分证据 | 阻断任务和能力提升，不得关闭 |

### 6.2 纠正步骤

1. 用同一锁定环境独立复跑至少两次，排除随机性和陈旧 artifact。
2. 缩减为单一 TypeId、命令、Property 或 builder 阶段的最小 fixture。
3. 保留完整原生输入、输出、诊断、对象集和资源，不只截取失败字段。
4. 判断差异首次出现层：UI、Facade、Document、Worker、builder、命名、codec 或 persistence。
5. 先添加会失败的 focused checker，再修改生产实现。
6. 修复不得改变无关场景、放宽公差、删除原生拒绝或引入通用 Shape fallback。
7. 重跑名义、失败、边界、变异恢复、事务、往返和浏览器案例。
8. 将差异分类、根因、修复文件、回归命令和 residual risk 写入证据账本。
9. 所有退出条件通过后才生成队列；生成器必须只推进一个任务。

## 7. 单能力 20 步微任务模板

每个命令、对象类型、Property codec、格式分支、GUI 状态或有序操作对依次拆为：

| 步骤 | 微任务 | 单一交付物 | 退出条件 |
| --- | --- | --- | --- |
| T01 | 定位源码 | 模块、TypeId/command、C++/Python 路径 | 来源和版本可追溯 |
| T02 | 锁定输入 | 参数、单位、对象图、选择和资源 | fixture 可重复解析 |
| T03 | 锁定适用性 | enabled/disabled 和前置条件 | 三种基本上下文均有事实 |
| T04 | 原生名义执行 | 成功快照 | 二次执行一致 |
| T05 | 原生边界执行 | 最小/最大/空/多项/单位边界 | 每项有接受或拒绝 |
| T06 | 原生失败执行 | 无效输入和精确诊断 | Shape/对象污染已记录 |
| T07 | 原生取消执行 | preview/cancel/abort | 文档和事务恢复 |
| T08 | 原生参数编辑 | before/edit/restore | 变化和恢复可分类 |
| T09 | 原生历史命名 | stages/history/naming | 无缺失 builder 证据 |
| T10 | 原生持久化 | save/reopen/resave | 三相无未知漂移 |
| T11 | WEB 合同 | Facade request/result/error schema | UI 无内核旁路 |
| T12 | WEB 实现 | production provider | 无 mock/隐藏 fallback |
| T13 | WEB 失败与取消 | structured error/cancel | stale result 不提交 |
| T14 | WEB 事务 | commit/abort/undo/redo | revision 和对象图正确 |
| T15 | WEB 命名 | TopoRef/ElementMap2/LinkSub | 唯一来源稳定，歧义封闭 |
| T16 | WEB 持久化 | Web save/reopen/resave | codec/资源无静默丢失 |
| T17 | 三方差分 | FreeCAD/Bitbybit/native provider 报告 | unknown difference 为零 |
| T18 | 浏览器回放 | Worker/OPFS/UI 证据 | 真实浏览器且资源归零 |
| T19 | 缺陷纠正 | 根因、修复、focused regression | 所有已知差异关闭或分类 |
| T20 | 能力提升 | gate、blocker、matrix、队列同步 | 只推进直接后继 |

如果某项不适用，必须保存机器可验证的 `not-applicable` 原因；不能跳过后只在文档中声称完成。

## 8. 阶段和细粒度里程碑

### M00 基线与治理

- M00.01 验证 FreeCAD headless 版本/提交/hash。
- M00.02 验证 FreeCAD desktop 版本/提交/hash。
- M00.03 验证 sysroot、Python 模块和动态库闭包。
- M00.04 验证 Bitbybit 和原生 history WASM/hash/ABI。
- M00.05 验证浏览器版本、Playwright、GPU 和 OPFS 能力。
- M00.06 验证隔离配置、locale、单位、字体和虚拟显示。
- M00.07 验证队列恰好一个 `in_progress`。
- M00.08 验证 exact claim 保持 fail-closed。

退出条件：任一执行机器都能复现同一基线；所有报告携带来源和 hash。

### M01 原生清册与 GUI oracle

- M01.01 34 模块构建/导入状态。
- M01.02 运行时 TypeId 全集和不可实例化原因。
- M01.03 每 TypeId 的 Property、默认值、status、editor。
- M01.04 命令注册全集、source-only 和 context-only 分类。
- M01.05 空文档、活动文档、单选、多选三态命令矩阵。
- M01.06 每命令族 success/disabled/failure/cancel/recovery。
- M01.07 Task、QAction、焦点、选择和对象集快照。
- M01.08 分片合并、重复/遗漏检测和 artifact hash。

退出条件：清册候选全部有运行时事实或显式排除；未知命令状态为零。

### M02 稳定拓扑、history 与有序操作对

- M02.01 每个生产 builder 的输入、阶段 Shape 和 history。
- M02.02 final-shape-only 和缺失 builder 证据 fail-closed。
- M02.03 MappedNameRef/StringHasher 来源和 ABI。
- M02.04 同构拓扑唯一/多来源分类。
- M02.05 参数编辑恢复的 geometry/relation/name 三相摘要。
- M02.06 生产链恢复拓扑和命名演进分类。
- M02.07 19×19 有序操作对逐对原生执行。
- M02.08 接受对的真实 builder、变异、命名和 FCStd。
- M02.09 拒绝/no-op 对的诊断、事务回滚和干净 FCStd。
- M02.10 长链 LinkSub 保存、重开、再次保存。

退出条件：所有注册转换均已分类；wrong binding、unexplained relation 和 round-trip name drift 为零。

### M03 Property codec 与状态语义

- M03.01 通用标量和枚举。
- M03.02 长度、角度、面积、体积和单位。
- M03.03 Vector、Matrix、Placement、Color 和材料。
- M03.04 String/List/Map/ExpressionEngine。
- M03.05 Link、LinkSub、LinkList、LinkSubList 和 XLink。
- M03.06 Shape、Mesh、Geometry、Constraint 和复杂专用类型。
- M03.07 Extension/FeaturePython/动态 Property。
- M03.08 opaque 类型逐个 native codec 或只读保留。
- M03.09 status/editor/readonly/hidden/transient 行为。
- M03.10 每 codec 的 mutation 和 FCStd 往返。

退出条件：运行时 Property 清册无未分类 opaque；未知值不会被 WEB 改写。

### M04 Document、DAG、事务与 observer

- M04.01 create/delete/rename/copy/clone。
- M04.02 add/remove/change Property。
- M04.03 dependency DAG、拓扑排序和 cycle。
- M04.04 dirty/touched/recompute scope。
- M04.05 partial recompute 和失败传播。
- M04.06 transaction commit/abort/nested/merge。
- M04.07 undo/redo 和失败后的最后有效状态。
- M04.08 observer 事件顺序和 payload。
- M04.09 multi-document、cross-document link、MDI。
- M04.10 Extension、FeaturePython、proxy 和 unknown object。

退出条件：事件、对象图和 revision 与原生一致；失败和取消无污染。

### M05 Kernel、Sketcher、Part 和 PartDesign

- M05.01 OCCT 原语、曲线、曲面和 topology inspection。
- M05.02 Boolean、section、split、refine、heal 和 tolerance。
- M05.03 Sketcher 几何、约束、DOF、冗余和冲突。
- M05.04 Sketcher 编辑、drag、external geometry 和 solver recovery。
- M05.05 Part primitive/builder/boolean/modification。
- M05.06 Body、Tip、Group、Support 和 attachment。
- M05.07 Pad/Pocket/Revolution/Groove。
- M05.08 Loft/Pipe/additive/subtractive 组合。
- M05.09 Fillet/Chamfer/Hole/Draft/Thickness。
- M05.10 Pattern/Mirrored/MultiTransform 和跨 Body/XLink。

退出条件：每个 feature 的 T01-T20 完成；失败诊断、事务、history、naming 和 FCStd 全部对齐。

### M06 FCStd 与交换格式

- M06.01 Document.xml/GuiDocument.xml/schema/version。
- M06.02 Property codec 和 unknown XML 保留。
- M06.03 BRep、ElementMap、StringHasher 和资源 identity。
- M06.04 Embedded files、scripts、thumbnails 和 extensions。
- M06.05 FreeCAD→Web→FreeCAD 变异链。
- M06.06 Web→FreeCAD→Web 变异链。
- M06.07 BREP/STEP/IGES 单位、颜色、名称、层和装配。
- M06.08 STL/OBJ/PLY/DXF/SVG/PDF。
- M06.09 IFC/CSV/G-code/JT/IDF/OpenSCAD 边界。
- M06.10 损坏、超限、取消、路径穿越和压缩炸弹。

退出条件：支持项双向无未知语义漂移；不支持项无损代理或明确拒绝。

### M07 GUI 与工作台闭合

- M07.01 Shell、菜单、工具栏和 Workbench 切换。
- M07.02 MDI、模型树、Combo View、Dock 和布局保存。
- M07.03 Task panel 和属性 editor 生命周期。
- M07.04 对话框 validation/apply/accept/reject。
- M07.05 3D selection/preselection/context menu。
- M07.06 keyboard、focus、shortcut conflict 和 clipboard。
- M07.07 status/report/jobs/progress/cancel。
- M07.08 desktop/tablet/mobile 响应式和触控。
- M07.09 screenshot、accessibility tree 和 locale。
- M07.10 每工作台端到端 success/failure/cancel/recovery。

退出条件：命令状态、对象结果、事务和交互轨迹对齐；无重叠、溢出或无名控件。

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

按 Draft、Spreadsheet、TechDraw、Plot、Assembly、BIM、Surface、Mesh/MeshPart、Material 顺序，每个工作台分别完成：清册、创建、编辑、失败、引用、事务、格式、GUI、浏览器和跨工作台十个微里程碑。

退出条件：每个对象和命令有 T01-T20；跨工作台引用和导出无未知差异。

### M09 分析、制造、数据和扩展

按 FEM、CAM、Robot、Inspection/Measure、Points/ReverseEngineering、Python/Macro、Addon、Cloud/Help/IDF/JT/OpenSCAD 顺序执行。每个外部求解器或 sidecar 还必须锁定版本、许可证、输入输出、超时、取消、资源限制和生产授权边界。

退出条件：可执行能力有真实差分；不可浏览器实现的能力被正式标为 proxy/excluded，不冒充 exact。

### M10 平台、可靠性和发布

- M10.01 Chrome/Firefox/WebKit。
- M10.02 Linux/Windows/macOS。
- M10.03 GPU/软件渲染和驱动矩阵。
- M10.04 locale/单位/时区/输入法。
- M10.05 keyboard/screen reader/zoom/high contrast。
- M10.06 fuzz/stress/百万级拓扑或求解重放。
- M10.07 长会话、内存、GPU、Worker 和 OPFS 泄漏。
- M10.08 crash、checkpoint、migration、rollback 和 offline。
- M10.09 SBOM、依赖、许可证、安全和签名。
- M10.10 52/52 exact、34/34 exact 和零差异 promotion。

退出条件：所有支持平台无未知语义差异；签名产物可重建、验签和回滚。

## 9. 每轮执行步骤

```text
1. 读取 config/freecad-active-work-queue.json.nextTask。
2. 核对该任务 dependencies、输入报告和 artifact hash。
3. 创建最小 fixture；不得顺手扩大到第二个队列项。
4. 运行锁定 FreeCAD 原生成功/失败/变异/持久化探针。
5. 运行 Bitbybit/原生 provider/Facade 的同输入回放。
6. 运行真实浏览器 Worker/OPFS/UI 回放（任务要求时）。
7. 逐字段比较 D0-D8，产生差异列表。
8. 对每项差异执行唯一分类；unknown 阻断任务。
9. 对 WEB 缺陷先补失败检查器，再修生产代码。
10. 重跑 focused probe、focused check 和相关回归。
11. 确认事务、文档、Shape、Worker、OPFS 和 GPU 资源恢复。
12. 更新 oracle/verification/分类账本和后续工作完成证据。
13. 重新生成 active queue 和状态页，只允许推进一项。
14. 运行 execution-plan、JSON、git diff 和风险相称的回归。
15. 发布点运行完整 verify、构建、SBOM、签名和验签。
16. 提交、推送，随后再从机器队列读取新的 nextTask。
```

## 10. 常用真实执行命令

```bash
# 原生清册和桌面 GUI
FREECAD_ORACLE_PROFILE=desktop xvfb-run -a ./npmw run probe:freecad-reference
./npmw run probe:freecad-gui-command-shards
./npmw run check:freecad-desktop-oracle
./npmw run check:freecad-oracle-coverage

# 三方几何、历史和命名
./npmw run test:freecad:threeway
./npmw run check:freecad:threeway
./npmw run probe:freecad-ordered-operation-pairs
./npmw run check:freecad-ordered-operation-pairs
./npmw run check:freecad-tsn-stage-correlation

# FCStd 和真实浏览器
./npmw run test:freecad-fcstd-native
./npmw run check:freecad-fcstd-roundtrip
./npmw run ci:real:chrome
./npmw run ci:check:chrome

# 队列和发布门禁
./npmw run generate:freecad-active-work-queue
./npmw run check:freecad-active-work-queue
./npmw run check:execution-plan
./npmw run verify
git diff --check
```

具体任务优先使用队列条目指定的 focused 命令，不应每次先运行整个 suite。完整 `verify` 用于发布点或高风险共享合同变更。

## 11. 证据文件最低结构

```json
{
  "schemaVersion": 1,
  "baseline": {
    "freecadVersion": "1.1.1",
    "gitCommit": "0108fd4b4850cc46e625b60e53cea7a7bbe69f8d",
    "runtime": "desktop|headless|browser",
    "artifacts": []
  },
  "case": {
    "id": "machine-generated-id",
    "inputs": {},
    "preconditions": [],
    "phases": {}
  },
  "comparison": {
    "dimensions": [],
    "knownDifferences": [],
    "unknownDifferences": []
  },
  "resources": {},
  "decision": "accepted|rejected|no-op|compatible|proxy|blocked",
  "status": "pass|fail"
}
```

报告生成器必须写入 harness hash；checker 必须重算 hash、验证连续前缀并在 unknown difference 非空时失败。

## 12. 里程碑验收与汇报

每个微里程碑关闭时记录：范围、真实 FreeCAD 命令、输入、原生结论、WEB 结论、差异分类、修复、focused check、浏览器证据、持久化证据、资源释放和剩余风险。

阶段里程碑只能在所有子项自然变为 completed 后关闭。系统级“完全对标 FreeCAD”只能在以下条件同时满足时声明：

- exact 计划全部完成。
- 34 个模块全部达到 exact 或从最终声明中正式排除。
- 所有命令、对象、Property、格式和入口无未知项。
- wrong binding、unexplained relation、round-trip name drift、unknown semantic difference 和 release blocker 均为零。
- 跨浏览器/OS/GPU、无障碍、locale、长稳、安全和迁移门禁通过。
- 发布物、SBOM 和能力矩阵签名可验证。

在此之前，项目只能按机器能力矩阵声明 exact、compatible、proxy、development 或 excluded 的实际范围。

## 13. 首次按本文执行发现并纠正的 oracle 差异

本计划落地时立即执行真实基线审计，发现旧 `.cache/freecad/reference-desktop.json` 缺少 `determinism.normalizedProcessFields`，`check:freecad-desktop-oracle` 因此正确失败。重新运行完整 desktop probe 后又在 `BIMWorkbench` 激活阶段触发默认 300 秒超时；同一 BIM workbench 的 registration-only 原生探针可正常完成，证明不是二进制或模块缺失。

根因位于 `scripts/freecad-reference-probe.py`：隔离配置只在 `gui-commands` scope 设置 `BIM.FirstTime=false`，但 `full` scope 同样会激活 BIM；报告又仅根据“使用隔离配置”声称首启已抑制，没有读取真实参数。纠正后：

1. 所有隔离 GUI probe 在激活任一 workbench 前设置 BIM `FirstTime=false`。
2. 立即读回参数，只有真实值为 false 才报告 `suppressed-before-workbench-activation`。
3. 完整 desktop probe 重新执行并通过，未再发生 BIM 首启超时。
4. 锁定 FreeCAD 1.1.1、34 模块、352 个运行时 TypeId 候选、348 个可实例化对象、4 个明确不可实例化对象和 5510 条 Property 记录。
5. `check:freecad-desktop-oracle`、`check:freecad-oracle-coverage`、`check:freecad-gui-commands` 和 26 场景 `check:freecad:threeway` 全部通过。
6. 由 desktop report 派生的 Property 语义报告因来源 hash 变化而 fail-closed，已重新真实生成；85 种 Property/5510 条记录中 4987 条由原生 codec 表示，523 条继续保持 opaque proxy，未被误报 exact。

该修复只纠正 oracle 的真实执行隔离和证据可信度，不提升任何 WEB 模块的 exact 等级。
