Files
FreeCADWasmDev/docs/UNATTENDED_WORKFLOW.md
wangdequan 9a7c4f0335 Save FreeCAD Web workspace sources and user validation evidence
IFC native binding remains incomplete; preserve accurate test results.
2026-09-15 22:01:58 +08:00

176 lines
27 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 无人值守业务实施流程
执行前先核对 `WEB_BUSINESS_MIGRATION_RULES.md` 和当前检查点;本文件只说明操作步骤,不覆盖用户最新要求与统一铁律。DXF 直接复用已有 C++ 实现、WASM 和有效证据,不重新安排算法移植;重复验收不得计作新交付。
2026-09-09 当前执行策略为 `delivery-progress-preserving-v22`,见 `WEB_DELIVERY_CONTEXT_PLAN.md`。顺序为实际运行问题、已有可执行业务结果、优先交付工作流、其余完整范围。编写批次最多 4 项,已有用例最多 16 项;不再由模块切换历史对账抢占优先交付。提示词默认 24000 UTF-8 字节,超限按完整字段/片段压缩;`docs/current/scheduler-context.json` 记录恢复位置、源码指纹和单次请求用量,状态命令直接展示。以下历史版本说明保留追溯,冲突以当前计划为准。
唯一主线是功能模块业务及其路由,完成需要实际业务结果。已有源码、构建目录、WASM、缓存、Facade、Worker 和可复用证据优先使用;API 清单只作为源码导航。
项目铁律:本项目是将桌面版 FreeCAD 移植到 Web FreeCAD,前期已经做了大部分工作,必须充分利用。每个回合先核对已有成果,再按“可用则复用、缺接线则补接线、缺证据则补必要用例、有缺陷则定点修复”推进;不得从零重写或把当前未验收解释为前期工作不存在。执行 `WEB_BUSINESS_MIGRATION_RULES.md` 的“项目定位与已有成果复用铁律”。
铁律:用户已经提供桌面版 FreeCAD 的源码和资料。每次续接先复用 `docs/current/provided-source-index.md` 中已核对的本地路径与成果;尚未查到不等于用户未提供。发现项目内可修复问题应立即利用本地实现定点修复并确认实际结果,不得仅监测、重复索要资料或等待外部服务。详细要求见 `WEB_BUSINESS_MIGRATION_RULES.md` 的“源码与资料优先铁律”。
失败记录从现在开始分类并随模块实施闭环,处理时机和证据要求见 `FAILURE_RECONCILIATION_POLICY.md`。原始失败账本保留,当前分类与对账表是 `docs/current/failure-reconciliation.json`;最终对账属于完成条件。
## 每轮处理
几何业务还需核对 `OCCT_GEOMETRY_BOUNDARY.md` 中的 native/显示边界。前端构建的 `prebuild` 自动执行轻量边界检查;普通 native 批次不为这个检查全量扫描或重编译内核。保留每个请求的真实 OCCT 入口和对象归属,未检查的链路不得写为已统一。
先使用已经编译完成的 WASM,直接接通现有 Worker/Facade 并执行本地针对性测试,不要求用户提交或上传源码。只有产物缺失、相关输入改变或明确 native 缺陷才增量重建受影响目标;纯页面接线、补用例不重建未变化的 WASM。以下源码定位步骤只服务于已确认的缺口,不是每轮重新审阅源码的前置。详见 `WEB_BUSINESS_MIGRATION_RULES.md` 的“现有 WASM 与本地执行优先铁律”。
1. 读取业务清单、当前运行问题、上轮结果和模块恢复状态。
2. 自动定位缺口:native 命令未实现、Worker/Facade 路由缺失、运行策略阻断、产物缺失。生成器将 `implementationGaps` 写入业务记录,流水线报告 `blockingGaps`。
3. 生成完整工作包:桌面源码、native handler、必要 Worker/Facade、应用中的命令执行和 React 挂载位置。诊断与上轮失败原因必须传入模型,不得只提供 ID 或重复创建未挂载组件。
4. 使用现有实现补齐当前业务链。共享依赖缺口属于当前业务的实现范围,不因旧工作包未列出而反复写边界。
5. 对变动目标增量构建、同步产物;按现有业务用例确认实际结果。实现回执与结果证据分别保留。
6. 按新增路由、构建回执、已部署问题修复和业务结果记录进展,继续下一可执行任务。
## 自动诊断与恢复
### 业务解阻固定流程
2026-09-11 PartDesign 恢复经验:`Document::restore(..., true, ...)` 延迟 `afterRestore`,独立 Worker 没有桌面恢复协调器时必须完成这一步;不能只看对象和形状已恢复就认定保存链闭合。当前 PartDesign 采用完整 `restore(..., false, ...)`,新增减料放样/扫掠及原 15 项业务共 17 项通过。后续保存业务要检查重开后的新编辑、撤销重做和原生依赖;保留几何浮点容差和严格的类型/链接检查。详情 `current/partdesign-subtractive-delivery-20260911.md`,不要重做已有放样、扫掠或 OCCT 算法。
2026-09-09 Start/Draft 经验:官方源树已经嵌入配置而旧产物缺模块时,先检查链接是否真正完成,以及 Materials/Part 等静态 Python 模块是否按顺序注册。无界面 Draft 导入共用 `HeadlessDraftImports.h`,不复制新解析器。Python stdlib 整目录打包应排除编译静态库和字节码缓存;本轮仅在 Start/Draft 验证并瘦身约 209 MB,后续按受影响模块采用,不全量重建。详情 `current/start-svg-delivery.md`。
模块专用桌面命令适配保持在模块文件中。TechDraw 已拆到 `web/src/techdraw-desktop-adapter.ts`,普通参数/响应/容器策略修改不要重新塞进共用分发器,避免无关模块的有效证据反复失效。模块文件仍由本模块和使用它的 Web 界面跟踪;真正的共用入口变化仍须确认受影响业务。Sandbox 当前文档保存已接同一 Worker,不以固定样例或全局文档清空判断用户文档业务完成。
2026-09-09 边身份解阻经验:同一拓扑名称首次计算与再次计算不同,先比较原生映射、解析成功标志及首次插入/缓存命中行为,不先归咎于 OCCT 算法。StringHasher 本次误用了失败解析留下的数字索引,修共用编码即可恢复真实依赖,不需要换边或清空映射。回归检查边身份、数值、撤销重做和保存重开;测试 Worker 结束后释放整个线程池,避免已通过仍空等。已关闭的两个故障及证据见 `current/partdesign-edge-identity-fix.md`,后续直接复用。
2026-09-09 构建竞争修复:`run_module_batch_pipeline.py`、`build_web_module_artifacts.py` 已共用 `web_build_lock.run_build`,同一构建目录排他,锁由原生子进程继承,等待单独计时。人工构建同样使用 `python3 tools/web_build_lock.py -- cmake --build <tree> --target <target> -j8`,继承现有 Emscripten 环境。不要让两个原始 Ninja/CMake 进程并发写同一目录;锁不能保护绕过入口的命令。原生边身份错误不能靠清空映射或按编号重绑定抹掉,当前 Fillet/Chamfer 首错见 `current/partdesign-finishing-delivery.md`。
2026-09-09 PartDesign 经验:现有模块已经链接所需 Sketcher/PartDesign 类时,直接保留同一 Worker 的真实文档和特征依赖,不用临时几何对象替代业务特征,也不另建 WASM。按 Body -> 约束草图 -> Pad/Pocket -> 保存重开成组确认;输入参数与 native 输出必须分别验证。发布前校验暂存 WASM 及源文件复制期间的一致性,不能只凭文件哈希认定半成品可运行。实现、耗时和边界见 `current/partdesign-profile-delivery.md`。
2026-09-09 布尔业务补充:局部 catch 未提供预期错误时,先核对该源文件实际编译选项,链接端启用异常不能补回编译时移除的 catch。Web 空材质继承原生对象数据,不继续依赖桌面默认材质目录。同步 WASM 复现应有硬终止期限,产物以完整临时文件原子替换。共用分发器变化后直接成批本地复验已有成功组,不重新安排实现模型回合。实际结果见 `current/part-boolean-delivery.md`。
用户要求把 Part/Mesh 的实际解阻方法用于后续全部移植。每次恢复使用以下顺序,而不是重复原失败批次:
1. 复用:核对现有本机源码、已编译 WASM、真实 Worker 目标和有效证据。OCCT WASM 负责几何,Three.js 负责显示;不重新索要资料、另换内核或重做已完成算法。
2. 缩小:从错误中的业务 ID、实际输入和命令确定最小失败调用。整组超时且输入未变时,不再直接重跑整组;不同 native、文档和浏览器路径分别定位。
3. 计时:区分下载/加载、编译初始化、native 内部阶段和退出清理;记录最后进入与最后完成的阶段。日志留在磁盘,工作包只带首错、耗时和必要源码锚点。
4. 定因:按已定位路径检查 WASM 线程池、递归异步任务、同步等待事件循环、GIL 及资源归属。桌面主机 CPU 数不是可用 WASM 线程数;不能以增大线程池或超时替代原因分析,也不能把所有超时都归为线程故障。
5. 修复:优先修改共用原生入口,保留桌面分支和真实几何/文档语义;只增量构建受影响功能模块并同步配套 JS/WASM/data,不全量重编译。
6. 确认与续接:先确认最小失败用例,再执行实际受影响的业务组。成功项按源码/产物指纹复用,剩余失败继续排队;更新当前过期诊断,保留历史失败、有效证据和完整业务范围。
`prepare_module_implementation_packet.py` 已将简短的 `repositoryContext.businessRecovery` 注入普通和失败恢复工作包;压缩上下文仍保留这六步和参考路径,不携带整份历史报告。实际示例为 `docs/current/part-mesh-business-unblock.md`。本流程约束后续执行方法,不自动将任何模块标记为通过。
### 模型请求传输
`docs/current/scheduler-transport.json` 启用项目级 HTTP/1.1 转发,模型及认证继续使用已有 Codex 配置。转发器仅监听随机本机回环端口,随调度器启动和退出;普通回合、续接和周期优化统一使用该入口。
- 当前上游为 `https://api.weapi.pw/v1`。请求和工具结果原样转发,不改写工具定义、调用 ID、业务输入或响应结果。
- 返回任何上游响应头之前,连接超时或 408/502/503/504 最多重试一次;认证错误、限流及带 Retry-After 的响应直接交给客户端。收到响应头之后不在转发层重试,防止部分工具响应被重复投递。
- 单次请求预算 60 秒,外层首次响应与无活动预算必须覆盖转发器的完整重试预算,避免内层仍在恢复时被外层终止。
- 传输日志为 `docs/current/continuation-runs/transport-<PID>.jsonl`,只记录大小、时间、状态和结束事件,不记录密钥、请求正文或工具输出。关闭重定向,避免认证跨上游地址转发。
- `show_freecad_web_scheduler.py` 的 `modelTransport` 显示实际连接方式、上游及预算。配置中 `enabled=false` 可恢复直接连接,不修改用户全局配置。
- 定位同类故障使用 `tools/probe_codex_transport.py`;必须以命令实际执行及 `turn.completed` 为完整回合证据,不能仅凭文本响应判定恢复。诊断时避免与后台回合争用请求资源。
| 情况 | 自动动作 |
|---|---|
| 已收到服务错误但没有工具运行 | 按无进展预算退出请求,持久化退避;不算业务失败 |
| 同一业务连续三次没有新结果 | 暂时冷却该业务,选其他任务;保留未完成状态 |
| 同一模块连续六次没有新结果 | 冷却整个模块,修复共享依赖和应用接入范围,换其他模块工作 |
| 新工作包增加页面调用点或提高恢复级别 | 轮换旧会话,使新上下文实际生效 |
| 错误地启动已冷却业务或模块 | watchdog 独立检测,等待工具结束后自动重启和重排 |
| 全队列暂时不可执行 | 显示原因和重试时间,不启动空模型回合 |
| 编译或结果失败 | 保存首个真实错误,按对应业务定点修复;不删除记录,不制造通过 |
| 运行问题已有构建回执,但尚未验证 | 保留在自动队列;外层立即执行该业务用例,只有明确覆盖问题 ID 且观察记录未更新的成功证据才能关闭 |
冷却是让其他工作继续推进,不代表问题已经解决。恢复历史在 `docs/current/scheduler-progress.json` 和 `scheduler-recovery-request.json`,当前结果由 `show_freecad_web_scheduler.py` 展示。
## 每 30 分钟自动优化
已按用户要求加入周期优化:梳理无人值守模式,发现并修复业务缺口、空转及高耗时瓶颈,复用已有源码、模块产物和证据,必要时查找权威资料。主线仍是功能模块业务和功能路由,不转为全量逐 API 检查。
- `tools/scheduler_maintenance.py --enable --interval 1800` 启用,配置保存在 `docs/current/scheduler-maintenance.json`。重复启用同一周期不会推迟下次时间。
- 到期后在当前业务回合及外层流水线完成后执行,复用调度器的独占锁,不与业务任务并行写入。等待模型服务退避或正在执行的任务时,实际启动可能晚于计划时间。
- 单次优化有 15 分钟执行预算;允许必要的增量构建和验证。记录真实修改和命令结果,有报告且回合正常完成才记为完成;这不等同于新增业务通过。
- 执行结束后保存下一次时间并退出调度器,由 watchdog 重启,以加载本次修改过的调度代码并恢复业务任务。重启不清空计时;错过多个周期只合并执行一次,不连续补跑。
- 运行记录、诊断上下文和报告写入 `docs/current/periodic-optimization/`。原状态命令显示 `maintenance.enabled`、`maintenance.nextRunAt`(UTC)、`maintenance.lastOutcome`、`maintenance.lastReportPath` 等字段。
- 本地机器在线且调度器和 watchdog 运行时自动执行。配置可跨进程重启保留;停机期间不会执行。
查看周期配置:`python3 tools/scheduler_maintenance.py`。暂停周期优化:`python3 tools/scheduler_maintenance.py --disable`,已开始的回合自然结束后继续普通业务调度。
## 减少重复耗时
- 同模块的用例若使用不同原生文档/几何运行时,可在合同 `buildOverrides` 按业务 ID 声明已存在的 tree/target。规划器按实际目标分组,工作包采用该目标,避免将 DocumentProbe 的业务误建为 PartBoxProbe。manifest 中实际 runtime 对应的 native 源码也参与有效证据指纹,模块名前缀不同不能漏掉真正的实现所有者。
- 2026-09-09 调度策略 `delivery-workflow-first-v3`:连续两次业务恢复无结果后,优先尝试另一个模块已有实现的缺失业务用例包(`--uncovered-only`),保留最多 4 项、冷却规则和全部后续阶段。没有可执行开发包就回到原队列,不停机;完成一次开发机会后恢复正常优先顺序。快速本地证据刷新不抵消恢复回合已消耗的机会,`businessLane` 留在历史中,轮转本身不算进展。
- 业务脚本 stdout 由统一 runner 收到临时常规文件后完整解析,防止 Node 单次同步写大报告时只写出管道前缀却成功退出。新增/修改脚本优先 `await writeBusinessReport(...)` 后退出。超时、无效 JSON、断言失败仍保持失败,禁止截取 JSON 前缀或弱化验证来获取通过。
- TechDraw 导出子项的错误独立保留,不把同组其他已完成业务全部打回。大结果只在证据中保留,错误摘要按实际失败 ID/断言传给工作包,不为损坏报告重复研究原生内核。
- 同一组业务可组合复用多份有效证据,不要求所有通过记录来自同一个报告文件。逐份核对源码/产物指纹、证据哈希、用例依赖和失败/问题观察指纹;任一不匹配仍须重新确认,不能只恢复旧状态数字。复用不改写原始证据或时间戳。
- 2026-09-11 验收执行进一步按业务 ID 增量复用:同一模块批次中只有失效 ID 进入 `FREECAD_BUSINESS_IDS`,已通过 ID 保留旧证据;运行期间仍检查全批次依赖稳定性,脚本返回的非选中结果不会覆盖账本。这样单项修复不再触发整组 WASM/浏览器启动。
- 模块命令到 Worker 的映射集中在 `generate_web_module_registry.py`。需要共享当前文档的命令映射到同一现有 Worker,不在路由器内加容易回退到错误 Worker 的模块特例。启动或无关联请求 ID 的协议错误应立即失败并释放该会话,不能继续空等。
- 前端类型检查使用 `web` 下的 `./node_modules/.bin/tsc --noEmit -p tsconfig.json`,保留 Vite Worker URL 与 JSX 配置;不得用缺少项目配置的临时命令制造无关错误。原生返回的合法取消状态应按本机源码契约接通,并检查取消不改变当前文档。
- v20:停滞批次的缩批依据包含同一候选业务集合最近 100 轮中的有效无进展耗时,切换模块或重建清单不清零。纯服务等待不计入;相关业务产生进展后重置窗口。达到 180 秒时按现有配置缩至 4 条,保留全部未完成记录;已有可链接成果仍走构建路径,不为缩批重复实施。
- 业务验收失败先从完整 JSON 输出提取 reason/error/stderr 和失败业务 ID,再压缩输出。真正的异常优先进入恢复提示,避免长 SVG 或几何结果遮住首错;原始状态、退出码和有界输出继续保留。
- v19:带验收合同的业务验收批次在编译前检查实际合同、用例入口及全部 selected IDs 的覆盖。缺失用例直接返回 `acceptance_required` 和 missingIds,不启动编译、同步或无覆盖的用例;保留构建缓存和待构建记录,未完成业务继续排队。
- 验收工作包优先放入现有合同和用例源码,并列明 coveredIds/missingIds;缺少用例的首次及续接回合使用业务恢复上下文,不套用桌面命令 marker 提示。新增 coveredIds 不是业务完成,后续仍须通过实际输入/结果断言。
- v17:模型服务退避只阻止模型请求。当前批次已有完整业务契约、匹配工作包且未冷却时,可以继续本地流水线;失败或未完成且输入未变时跳过,禁止退避期间反复执行同一失败。周期优化同样遵守模型请求退避。
- 被范围检查拒绝的 Git 只读检查及其受限只读后续命令,可按结构化诊断证据自动对账;原始失败和次数保留。重定向、命令替换、失败后继续执行的分支及混合业务命令不适用此规则。
- 模块路由生成使用输入指纹缓存,稳定排序;未变化文件不重写。
- 同目标批量修改合并链接,切换目标时处理上一目标的待构建事务。
- `FREECAD_WEB_FAST_LINK=ON` 的前端快速构建使用 rsync 增量同步公共资源,保持纳秒时间比较并清理过期文件;普通发布构建保留 Vite 默认完整复制。
- 复用具有相同源码和产物指纹的业务结果,拒绝把固定样例或参数回显作为业务完成证据。
- 运行问题已有业务用例时,先执行确定性流水线;构建和验收已能完成的批次直接推进,不再先启动模型重写实现。相同输入的失败只保留诊断,等相关源码或用例改变后再试。
- 编译、链接问题才进入编译首错恢复;缺少验收契约、用例失败、问题关联遗漏分别回到对应业务文件。工作包优先提供用例和契约的可编辑片段,带上明确的问题 ID 和失败 key。
- 原生构建成功的缓存与业务验收分开保存,验收失败不会丢掉已有构建。Ninja 仍检查真实的头文件和库依赖,资源同步复用现有缓存,不用重复链接来触发验证。
- 运行问题必须明确关联已验证的用例;业务通过但仍有未覆盖问题时返回 `issue_coverage_required`,不把重复刷新已关闭问题计为新闭环。
- 源码检索同时解析项目路径和桌面源码路径,使用实际 ripgrep 避免调度包装器再次拦截;范围过大时明确提示收窄,不再按文件排序静默截断。
- Node WASM 用例复用 `tools/wasm-probe-runtime.mjs`,一次性进程在输出完整结果并清理后退出,避免空闲 pthread 池拖到超时。
- Vite 开发及预览服务提供 COOP/COEP 响应头,使多线程 WASM 可使用 SharedArrayBuffer;部署服务器也必须提供相同响应头。
## 逐步耗时与上下文复用
执行 `python3 tools/analyze_scheduler_timings.py --cycles 20 --report-prefix docs/current/unattended-timing` 会输出汇总,并写入 Markdown 和 JSON 报表。每轮记录准备及流水线步骤,每条命令列出开始前等待、实际执行时间和退出码,另列没有命令运行的事件间隔。并行命令的占用时间按并集统计,避免重复计时。事件间隔可能包含模型、服务排队、通信和客户端等待,不直接当作本地计算时间。
- 定时优化使用独立的业务工作包,直接带入已有文件、源码片段、验收入口和 AGENTS.md 检查结果,不改写普通业务批次。源码搜索默认使用该独立批次,避免误查上一个模块。
- 没有编辑或实际验证的纯探索累计预算为 180 秒;追加搜索输出不会重置预算。正在执行的命令、已经产生编辑的回合及实际构建/验证不受此探索预算打断,原有总超时仍保留。
- 运行问题的有效读取可在有界停止后保留到续接会话;受控工具拒绝一次源码检索不再丢弃整个回合。编译等不属于当前回合的重操作仍走原有外层流水线。
- 优化失败、服务过载或预算耗尽也保存步骤报告,明确记录未完成,不制造成功。历史上下文、源码和产物继续保留用于后续修复。
## 已验证结果复用
### 2026-09-08 请求等待与计时修复 (v16)
- 首次响应与已有活动后的空闲使用独立预算。首次请求 30 秒,连续静默超时后依次允许 60、120、最多 180 秒;通用 45 秒空闲检查不提前终止尚未出现首个活动的请求。真实服务错误仍使用原有错误预算,正在运行的命令不受空闲检查打断。
- 连续请求失败退避依次为 20、40、60、120、240、480、最多 600 秒。状态跨重启保留;真实模型响应后清零。业务未完成记录、源码、已验证证据和构建缓存继续保留。
- 周期优化和业务回合共享请求失败退避;周期优化失败会延长同一等待,不能靠重启绕过,且不会因此增加业务完成记录。
- 状态展示运行时实际首次响应预算、配置上限及加载源码 SHA-256。`firstActivityTimedOut` 表示本地等待超时,不代表接口明确返回过载或网络错误。
- 新周期的退避按实际等待时间写入 `waitingTiming.scheduler/provider-backoff`,与模型、命令、准备和流水线时间分别统计。报告的 `wallTimeline` 用原始日志恢复历史轮次间隔,间隔可能包含准备、退避及重启,不重复累加到阶段表。
- 基线报告:`docs/current/efficiency-audit-baseline.md`,周期 4915-4934 实际跨度 1914.684 秒,其中周期内 815.747 秒、轮次间 1098.937 秒,20 轮命令和文件修改均为零。原统计未覆盖轮次间隔。
- 独立只读请求只要求返回 READY,180 秒内未返回并以退出码 124 超时。该探测说明当时请求链路无响应,不能据此断言所有后续请求均不可用。缩短等待或减少请求次数不等于业务吞吐提高。
`run_business_acceptance.py --reuse` 在业务源码/产物指纹、用例与依赖文件、构建目录覆盖设置以及关联失败和运行问题的观察指纹均未变化时,复用原始证据,不重跑用例、不改写执行时间。新的失败出现或任何相关输入改变时重新执行。契约可通过 `dependencies` 声明 Python 源码和资源目录;Draft 已声明其源码树。
资源同步同时发布对应构建目录中的 pthread Worker。模块 revision 包含 JS、WASM、数据包和线程脚本,避免仅 Python/JS 资源变化时仍保留旧实例。内容未变的模块 manifest 不重写,功能路由生成器因此可以持续命中缓存。
禁止通过 `touch` 或 `os.utime` 反复强制链接。嵌入资源应由构建目标的 `LINK_DEPENDS` 驱动,完成一次必要的增量构建及同步后,使用发布目录中的产物验收。
受控复用对比:`python3 tools/benchmark_business_reuse.py --module Draft --ids Draft:draft.formatBatch`。报告同时保留历史窗口的真实耗时和相同业务、相同产物的缓存对比;不把不同任务窗口的变化解释成统一提速比例。
## 历史对账不阻塞主线
- 无范围的独立 `git status/diff` 被检查规则以退出码 64 拒绝时,记录为可机器核实的诊断拒绝,不视为 CAD 业务失败;保留原始命令、次数及不可变证据,不覆盖业务结果。
- Node 内联检查命令的解析阶段 `SyntaxError` 与真正的 WASM 运行错误分别分类。检查发布产物使用 `python3 tools/inspect_web_module_artifacts.py --module Draft`,不用临时拼接容易出错的 Node 表达式。
- 对账只提供仍未闭环的记录。一次对账尝试后仍未解决的记录暂时冷却,继续业务实施;不据对账停滞冷却整个业务模块,也不把未解决记录标为完成。
- 重复对账复用分类快照,但重新核实证据和相关源码是否仍有效;业务验收缓存每个核验过程只刷新一次,避免长期进程读取旧状态。
- 模型服务的错误原因单独记录,不再被上次对账的 `pendingKeys` 输出覆盖。
## 本次已补齐的功能
CAM JSON 刀轨导入导出使用 FreeCAD `Path::Command`、`Path::Toolpath` 和 `Path::Feature`。导入建立或更新指定文档对象;导出读取对象当前刀轨,不再回显输入或固定返回长度。非法参数不会覆盖已有刀轨,文档保持打开以继续编辑。
`docs/business-acceptance/CAM.json` 声明可复用用例;`tools/cam-business-cases.mjs` 覆盖多组长度、文档隔离、错误输入、原对象更新和无输入内容导出。独立 Chrome 调用已验证公共 Router → Worker → WASM,长度 15 的往返结果一致。本结果不代表 CAM 的其他业务或全部 FreeCAD 功能已完成。
TechDraw 的 `techdraw.createRecompute` 已接通原生 Part::Box、DrawPage、A4 SVG 模板、DrawViewPart 和 viewPartAsSvg。不同尺寸产生实际几何和 SVG;同文档继续编辑,独立文档相互隔离。页面展示原生投影,并提供尺寸编辑和 SVG 下载。
`docs/business-acceptance/TechDraw.json` 声明实际 WASM 用例,显式关联历史加载失败和运行问题。`tools/techdraw-browser-cases.mjs` 检查页面编辑、SVG 下载、重置、统一路由及桌面/手机截图和绘图像素。该结果只覆盖这条创建与重算业务,不表示 TechDraw 全工作台或整个 FreeCAD 已全部移植。
Part 的 `docs/business-acceptance/Part.json` 复用已有原生参数化创建/重算实现,验证尺寸 `[2,3,4]`、`[5,6,7]`、`[0.5,2,3]` 的体积、非法输入拒绝以及后续有效请求恢复。它关闭固定尺寸限制对应的运行问题,不表示整个 Part 工作台完成。