状态:目标设计(Target Design),尚未实现或验收
feature_id: workcell-composition-v1
contract_version: workcell-composition-draft-20260805-g1-migration-reviewed
Wayfinder:Uni-Lab-Core #181
冻结设计:Uni-Lab-Core@8841d27
问题陈述(Problem Statement)
Uni-Lab 当前使用大型启动 JSON/GraphML 同时表达设备实例、固定资源、父子关系、连接、位置、初始化配置和遗留运行 data。这种文件难以由人安全审阅,也让 AI 难以在强约束和快速反馈下完成局部修改;现有读取路径还会把未知根字段移动到 config,无法证明哪些值属于定义、候选启用或运行权威。
工站设计实际包含两个相互关联但生命周期不同的目标:一是确定设备、固定资源、库位(Site)、数量、选型、连接和毫米制物理布置;二是把同一固定结构绑定为可以启动的设备配置。除此之外,工站内部已验证的工作流(Workflow)还需要以公共动作(Action)形式供上层实验室工作流复用,同时保留唯一工作流任务(WorkflowTask)、执行计划(ExecutionPlan)、调度器(Scheduler)和物理结算(PhysicalSettlement)权威。
如果继续把这些目标写成任意 Python、两个相互漂移的 JSON/Python 真相,或一套新的站内运行时,就会产生不可校验源码、重复设备实例化、秘密泄漏、库存覆盖、双重调度和盲目物理重放(Blind Physical Replay)风险。
解决方案(Solution)
提供一等、可版本化、可嵌套的候选工作单元定义(WorkCell Definition)。人和 AI 可以在受限 Python、规范 NetworkX node-link JSON 和结构化画布之间进行双向语义创作;所有创作方式进入同一个纯编译、链接、校验、发布和摘要链。已发布定义只描述固定候选装配拓扑(Assembly Topology)、物理 pose、库位(Site)设计约束、公开启动合同和公共动作(Action),不拥有真实物料(Material)、库位占用(SiteOccupancy)、遥测或任务状态。
启动继续使用 -g/--graph。候选启用解析器(Activation Resolver)通过唯一 prepare_activation(...) 接口,将精确已发布定义、零个或一个候选启用请求(Activation Request)、实例部署字段和敏感配置(Secret)引用降低为候选启用图(Activation Graph)与脱敏、内容寻址的候选启用快照(Activation Snapshot);全部验证和快照持久化在驱动导入、构造或硬件连接之前完成。
内部工作流(Workflow)只有通过显式导出才能成为工作流支持动作(Workflow-backed Action)。调用继续复用组合工作流调用(CompositeWorkflowInvocation),在任务创建时静态降低到同一个工作流任务(WorkflowTask)与执行计划(ExecutionPlan);不同调用的内部作业可以交错,物理安全只由完整逐作业执行占用(JobExecutionClaim)保护。
OS 实现必须进入现有快速功能迁移收敛线(Fast Feature Migration Convergence Lane):每个切片从当时最新、已验收的 feat/fast-feature-migration-reviewed 提交创建 migration/fXX-<feature-name> 分支,并同时冻结其父提交和行为供体提交。integration/workflow-task-runtime 只作为行为、测试和不变量供体,不作为候选工作单元(WorkCell)生产实现基线,也不得整体合入。这样可以让候选工作单元(WorkCell)复用当前收敛线已经建立的深模块接缝,而不重新引入已被替换的工作流服务、存储、组合、运行时和 D1A bridge 门面。
用户故事(User Stories)
作为领域设备开发者,我希望用受限 Python 声明固定设备和资源结构,从而不再手写大型启动 JSON。
作为领域设备开发者,我希望一个 @workcell 文件可以直接作为 -g/--graph 输入,从而让定义文件与启动入口保持一致。
作为 AI 编码代理,我希望所有可用构造、字段和错误都有封闭 Schema 与结构化诊断,从而可以根据机器反馈稳定修复输出。
作为 AI 编码代理,我希望能够修改受限 Python 或提交有类型图编辑,而两条路径经过同一校验器,从而不需要猜测哪个表示才是权威。
作为工站设计者,我希望在 2D 与 3D 中编辑同一个毫米制物理 pose,从而让测绘、设计和模型展示没有第二坐标真相。
作为工站设计者,我希望用 layout_plane 选择 XY、XZ 或 YZ 编辑平面,从而专注于当前测绘平面并保持第三轴不变。
作为工站设计者,我希望定义设备、台面、固定反应器、固定容器和库位(Site)的数量、选型、父子关系与连接,从而表达完整固定候选装配拓扑(Assembly Topology)。
作为包维护者,我希望所有成员拥有稳定 member_id,从而局部变量重命名不会创建新的物理身份。
作为包维护者,我希望发布时固定精确依赖、资产闭包、revision 和摘要,从而 workspace、clean wheel 与缓存 archive 得到相同语义。
作为包维护者,我希望发布失败为原子失败,从而无效候选不会部分进入 PackageCatalog、设备注册表(Device Registry)或 Palette。
作为现场集成人员,我希望公开启动参数由 InitParam 强类型声明,从而只覆盖作者明确开放的配置,而不能通过深路径修改私有设备配置。
作为现场集成人员,我希望没有外部覆盖时无需创建空 params 文件,从而使用全部默认值的工站只保留一个 workcell.py。
作为现场集成人员,我希望一次启用最多接受一个外部覆盖对象,从而不存在来源优先级和隐式叠加歧义。
作为安全管理员,我希望敏感配置(Secret)只以 SecretRef 和版本进入启用过程,从而源码、日志、诊断、目录和快照都不包含明文。
作为运行维护人员,我希望每次启用都生成不可变、脱敏的候选启用快照(Activation Snapshot),从而能够审计使用的定义、目录、参数、部署和 Secret 版本。
作为运行维护人员,我希望完全相同的输入在重启时复用同一快照,而任何输入变化要求显式重新启用,从而重启不会静默改动设备拓扑或配置。
作为运行维护人员,我希望 --check_mode 在任何驱动导入、构造或硬件连接之前完成校验,从而 CI 可以安全验证包与启动文件。
作为组合工站作者,我希望嵌套引用精确已发布候选工作单元定义(WorkCell Definition),从而复用子工站而不复制内部 JSON。
作为组合工站作者,我希望内部成员默认私有并可显式 export/re-export,从而上层只能寻址维护者承诺的稳定公共表面。
作为实验室工作流作者,我希望把选定内部工作流(Workflow)显式发布为公共动作(Action),从而像调用设备动作一样组合整站能力。
作为实验室工作流作者,我希望工作流支持动作(Workflow-backed Action)复用既有输入、输出、Handle 和物料占位符(ResourceSlot)合同,从而不学习第二套站级参数模型。
作为调度维护者,我希望候选工作单元调用静态进入唯一执行计划(ExecutionPlan),从而不会产生嵌套任务或第二调度器(Scheduler)权威。
作为调度维护者,我希望不同调用的内部作业可以交错且各自取得完整作业执行占用(JobExecutionClaim),从而在保持安全的前提下避免不必要的整站串行。
作为安全审计人员,我希望未建模的共用门、轨道、安全区或机箱风险阻止并发安全声明,从而系统不会从节点不同错误推断物理独立。
作为库存维护者,我希望候选工作单元定义和启用始终对真实物料(Material)与库位占用(SiteOccupancy)零写入,从而启动或升级不会覆盖库存权威(Inventory Authority)。
作为操作者,我希望缺少动态物料时工站仍可启用,而工作流任务(WorkflowTask)由任务物料准入(TaskMaterialAdmission)决定是否开始,从而定义部署与业务物料准备不被混为一体。
作为前端用户,我希望 Python、规范 JSON 和结构化画布共享单一草稿 revision,并在模式切换前看到完整语义 diff,从而不会产生两份可写真相。
作为前端用户,我希望无效草稿保留编辑内容和结构化诊断,但不能覆盖最后一个有效候选,从而修复错误时不会丢失工作。
作为前端用户,我希望折叠候选工作单元调用只改变展示,而内部作业、占用、回执和物理结算证据仍可展开,从而抽象不会损害调试和审计。
作为迁移维护者,我希望旧 JSON/GraphML 的已知字段进入规范语义、未知字段无损进入兼容保留层,从而迁移不丢数据也不赋予未知数据运行权威。
作为迁移维护者,我希望无法分类的非空 data 在无损保存后仍阻止发布和启用,从而兼容不会变成静默执行。
作为迁移维护者,我希望位置来源等价时归一并告警、冲突时报告精确路径并失败,从而不会猜测真实设备位置。
作为测试维护者,我希望一个最小本地仿真夹具快速覆盖完整主链,从而日常 CI 不依赖大包或真实硬件。
作为 SZLab 维护者,我希望 129 节点真实复杂度夹具固定源 commit、原始摘要、迁移报告与双摘要,从而真实工站不会被只适用于玩具图的实现破坏。
作为发布负责人,我希望每个拥有仓提供合并 commit、测试命令与结果、文件体量审查和 Feishu revision,从而 Core 可以验证一个可回滚、可复现的 submodule 组合。
实现决策(Implementation Decisions)
候选工作单元定义(WorkCell Definition)、候选工作单元实例(WorkCell Instance)、候选启用快照(Activation Snapshot)、真实物料(Material)事实和工作流任务(WorkflowTask)执行计划保持独立身份、权威和生命周期。
候选工作单元定义模块(WorkCell Definition Module)采用深模块(Deep Module)形态。其接口(Interface)接收显式来源、固定 PackageCatalog 快照和基线 revision,返回候选图、规范 Python、完整语义 diff、source map、结构化诊断、定义摘要、公共合同摘要和兼容摘要;AST、安全检查、规范化、闭包解析、位姿与库位校验属于模块内部实现。
.py、.json、.graphml 只在输入适配器(Adapter)处不同。三个适配器之后必须进入同一个规范编译核心;不得保留第二套设备实例化、驱动导入或运行语义。
Python 适配器只接受失败关闭的 AST allowlist,不 import/exec 作者源码,不允许动态控制流、任意调用、I/O、环境读取或不稳定拓扑生成;一个启动文件必须恰好声明一个顶层 @workcell 根定义。
规范 JSON 使用 NetworkX node-link 形态,并尽量复用当前 graph/nodes/links、id/name/type/class/parent/children/pose/config/data 与连接字段。仅增加被证明必需的元数据和 config_bindings。
规范编码固定节点、连接和对象键的排序规则,但保留 children 与 config.sites[] 的语义顺序。content_digest 不包含自身、source map 或兼容保留载荷;legacy_payload_digest 单独覆盖兼容载荷,原始文件另记录字节摘要。
定义身份由 PackageCatalog fqid、单调 revision 与 content_digest 组成;成员 id 是稳定 member_id。运行实例 UUID 从根实例 namespace 与成员路径确定性派生,旧 uuid 不进入定义摘要。
v1 结构固定。公开参数只能绑定已声明初始化字段,不能选择成员 class、definition revision、父子关系、库位(Site)、导出或动作(Action)合同;optional、variant 和动态拓扑保留到未来版本化协议。
位姿/变换模块(Pose/Transform Module)唯一拥有右手 Z-up、毫米位置、度制 XYZ 欧拉输入、Rz · Ry · Rx 组合、数值规范化、父子矩阵组合和 layout_plane 投影。设备作者句柄和前端适配器(Adapter)不得复制坐标换算。
库位投影模块(Site Projection Module)统一校验 config.sites[].label/content_type/position/size、成员内稳定 key、毫米几何、容量 1、资源模板(ResourceTemplate)兼容和 sort_order 投影;拒绝任何占用者字段。
创作使用单草稿、单时刻单写模式。Python 与画布/规范 JSON 共享一个 draft_revision,保存使用 CAS;切换模式先编译、校验、显示完整 diff 并重新证明固定点,冲突必须显式 rebase。
发布生命周期固定为 Draft → Candidate → Published。只有 Published 可以被引用、启用或投影;发布定义、公共合同、source map、依赖闭包和目录投影必须原子提交。
候选启用解析器(Activation Resolver)是第二个最高测试接缝(Seam),对调用者只公开 prepare_activation(request) -> PreparedActivation | ActivationDiagnostics。文件读取、目录、Secret Provider、快照存储和格式适配器都是内部接缝。
-g/--graph 是唯一启动定义来源参数,严格按 .py/.json/.graphml 后缀分派;未知或无后缀失败,不做内容探测。--config 只配置 OS 进程,不进入候选工作单元初始化合同(WorkCell Init Contract)。
Phase 0 只实现 Python、零外部参数路径;完整 v1 才接受零个或一个封闭候选启用请求(Activation Request)。多来源、未知字段、摘要不符、必填缺失或敏感配置(Secret)明文全部在硬件副作用前失败。
OS 是候选启用快照(Activation Snapshot)的本地写权威。快照在驱动创建前原子持久化,包含固定定义/目录/请求/lowering 摘要、实例部署、最终非敏感值来源、Secret 引用版本和候选启用图(Activation Graph)摘要;Backend 只接收副本或投影。
嵌套边固定精确候选工作单元定义 revision/digest。内部成员默认 private;只有显式 exported 和显式 re_export 可以形成稳定外部寻址;候选可查看性与候选可寻址性保持分离。
工作流支持动作(Workflow-backed Action)只由显式导出产生,复用现有 node_type="workflow"、工作流合同扩展、真实 Handle、工作流输入合同(WorkflowInputContract)和工作流结果记录(WorkflowResultRecord);不新增 implementation.kind 或站级 entry/exit 模型。
调用复用组合工作流调用(CompositeWorkflowInvocation),在任务创建时由唯一执行计划构建器(ExecutionPlan Builder)静态降低为普通计划节点与工作流节点作业尝试(WorkflowNodeJobAttempt);不创建宏作业、嵌套任务、调用级互斥量或容量许可。
不同调用的内部作业允许交错。每个作业在派发前取得覆盖执行设备、全部可能改变的物料(Material)和源/目标库位(Site)的完整作业执行占用(JobExecutionClaim);动作重试策略(ActionRetryPolicy)保持 never。
前端服务层新增一个专门面向候选工作单元(WorkCell)创作的接口(Interface),沿用现有工作流创作的单 port 模式;组件不直接请求 OS/Backend,不执行 Python,不计算闭包、UUID、摘要或世界位姿。HTTP/DTO 只承载定义模块返回的规范对象和诊断,不另建前端业务真相。
前端 2D/3D 使用同一物理 pose。layout_plane 只决定显示和允许拖动的两个轴;折叠/展开只改变视图状态,不进入定义摘要、候选启用快照(Activation Snapshot)或运行权威。
旧 JSON/GraphML 永久保留为作者输入格式,但旧解析器不能直接创建运行设备。兼容适配器(Adapter)输出规范图、兼容 sidecar、迁移报告和稳定诊断;已知字段冲突及无法分类的非空 data 阻止发布/启用。
v1 对真实物料(Material)和库位占用(SiteOccupancy)保持零写入。真实物料首次预置、幂等 command_id、整批事务和持久回执推迟到 v2+。
交付按可验证能力递进:安全编译与检查模式固定点;发布与目录投影;Phase 0 Python 冷启动;完整候选启用请求与 Secret;嵌套、导出、位姿和库位投影;工作流支持动作的静态计划预览;永久兼容迁移;前端候选分支与双夹具总验收。每个切片都必须保持前述三个高层接口稳定。
OS 的每个实现切片必须从当时最新、已验收的快速功能迁移收敛头创建独立 migration/fXX-<feature-name> 分支,并记录父提交、固定 integration 供体提交和迁移范围。迁移遵循 RED → GREEN → FIX、全量测试、独立标准/规格双轴评审、文件体量审查和非 squash 合并;不得在 integration 上直接实现后再整体搬运。
候选工作单元定义模块(WorkCell Definition Module)依赖 F02 创作权威和 F03.3 包目录(PackageCatalog);发布与授权源码依赖 F04 本地来源闭包,以及 C0b2 本地模板身份、C0b3 可编辑工作流注册完成收敛。相关依赖未绿前只允许迁移 RED 测试、固定输入输出合同或无副作用适配器,不得以现有模板投影临时代替包目录(PackageCatalog)。
候选启用快照(Activation Snapshot)的持久写入依赖 G00 运行时存储路径(RuntimeStoragePaths)和显式部署 profile 形成唯一接受接口。若该协议未绿,Phase 0 可以完成纯解析和副作用前验证,但不得建立临时第二存储权威。
工作流支持动作(Workflow-backed Action)的作者侧发布和静态执行计划(ExecutionPlan)预览依赖 F06 组合工作流静态展开与 F07 不可变任务输入/执行计划。真实派发、取消、execution_unknown、投递重放(DeliveryReplay)与物理结算(PhysicalSettlement)验收进一步依赖 K12~K14 的作业执行占用(JobExecutionClaim)、派发效果(DispatchEffect)和物理结算合同;未绿前不得以旧 integration 运行时补洞。
前端候选工作单元(WorkCell)编辑器在独立候选分支开发,只有相关 OS DTO、诊断和发布接口被收敛线接受后才能并入前端 integration;真实 SSE 跨仓验收进一步依赖 F09 持久事件游标与重连。
app/main.py、resources/graphio.py、workflow/service.py 和 workflow/store.py 只保留对新深模块的最小委托,不承载候选工作单元编译、兼容分类、启用或计划构建规则。所有新增或修改函数、方法、回调、夹具和测试函数必须使用中文文档说明参数、返回值、异常、身份、权威和安全不变量;所有触及文件执行 500/800 行体量审查。
产品实现开始前,冻结设计 PR [文档] 独立候选工作单元(WorkCell)组合设计基线 #188 必须已合并;若尚未合并,交付票必须把不可变提交 8841d2714e179d3b67760e2ce02892e700fad5bf 设为临时协议锚点和显式合并门禁,不能依赖可漂移分支头。
测试决策(Testing Decisions)
测试只证明接口(Interface)可观察行为和持久不变量,不断言私有 AST visitor、内部函数调用顺序或临时数据库布局。
第一测试接缝(Seam)是纯候选工作单元定义模块(WorkCell Definition Module)。使用固定 PackageCatalog 快照验证 Python/JSON/GraphML 编译、生成、校验、完整 diff、source map、依赖闭包和结构化诊断;测试不得 import 驱动、访问网络或写运行数据库。
在第一接缝执行语义固定点:JSON → 规范图 → Python → 规范图、Python ↔ 规范 JSON/画布、workspace ↔ clean wheel ↔ cache archive 的 content_digest 必须一致;兼容往返的 legacy_payload_digest 必须一致。
第一接缝覆盖恶意/不受支持 Python、零个或多个根定义、动态控制流、父子环、缺失引用、重复 member_id、依赖漂移、位姿 NaN/Infinity、连接端口错误和库位(Site)Schema 错误,全部返回稳定诊断而非异常泄漏或部分发布。
第二测试接缝(Seam)是 prepare_activation(...)。以临时 workspace、固定目录、可替换 Secret Provider 和快照存储适配器(Adapter)覆盖零参数、全部默认、必填缺失、单一覆盖、多来源冲突、Secret 不可用、实例部署、快照复用和输入变化;失败时必须证明没有 driver import、设备构造、连接、设备注册表(Device Registry)实例或物料写入。
位姿测试使用矩阵期望值而非逐分量欧拉相加,覆盖三种 layout_plane、第三轴保持、父节点旋转、嵌套组合和 Backend relative_position 投影。
嵌套/公开边界测试覆盖 exact revision/digest、循环、private/exported/re_export、公共合同收窄、候选可查看性/候选可寻址性隔离、前端折叠固定点和双摘要。
工作流支持动作(Workflow-backed Action)测试通过既有工作流任务(WorkflowTask)与执行计划(ExecutionPlan)接口证明静态降低,不新增站级运行接口;覆盖成功、内部作业交错、占用争用、派发前/执行中取消、部分物理成功、断电、execution_unknown、投递重放(DeliveryReplay)和物理结算(PhysicalSettlement)。
第三测试接缝(Seam)是真实跨仓系统:真实 OS compiler、SQLite、SSE、设备注册表(Device Registry)、前端服务接口和本地仿真器。浏览器路由 mock 只能证明 UI 分支,不能作为端到端验收证据。
前端验收覆盖 Python/画布模式切换、完整语义 diff、结构化诊断、pose/layout_plane 编辑、发布 revision、Palette 投影、折叠/展开、旧运行证据固定和无 console.error/pageerror。
最小本地仿真夹具覆盖一个父子组合、一个库位(Site)、一条连接、物理 pose 和一个工作流支持动作(Workflow-backed Action),作为快速 CI 主路径。
SZLab 夹具固定 szlab-local-debug.json 的来源 commit、原始字节摘要、129 个节点和 11 个非空 data 清单;输出 workcell.py、规范 JSON、兼容 sidecar、迁移报告和预期双摘要。默认验收只连接本地 OPC UA 仿真端点,不连接真实硬件。
遗留数据测试分别证明:空 data 从语义层移除;测试 seed 进入独立测试夹具;运行事实被拒绝;未知非空 data 被无损保存但阻止发布/启用;旧 uuid 不污染定义摘要。
复用现有工作流创作编译器的 round-trip/恶意源码测试、OS Workflow HTTP/SQLite 集成测试、前端 Playwright 工作流 E2E 和 SZLab 本地 OPC UA 测试作为先例;新增测试应通过新的高层接缝扩展行为,而不是复制一套测试框架。
每个仓库交付必须记录精确测试命令、结果、合并 commit、触及文件行数与 Feishu 实现/测试 revision;Core 在固定 submodule pin 上重跑黄金测试后才能接受。
每个 OS 切片必须验证并记录:分支父提交是当时最新已验收收敛头、行为供体是固定提交、迁移清单不包含未声明的生产实现拷贝;CI 应拒绝以 integration 为直接实现基线或绕过已接受深模块接缝的变更。
候选工作单元(WorkCell)相关测试按依赖门分层:F02/F03.3/F04 与 C0b2/C0b3 未绿时只接受纯编译、结构化诊断和 RED 合同;G00 未绿时不接受快照持久化为完成;F06/F07 未绿时不接受工作流支持动作静态降低为完成;K12~K14 未绿时不接受真实物理运行故障路径为完成;F09 未绿时不接受真实 SSE 断线重连跨仓验收为完成。
集成测试必须同时证明新切片在收敛头全量测试通过,并对固定 integration 供体运行选定行为回归;两者行为差异必须形成显式迁移说明,不能通过直接合并供体门面消除。
范围外(Out of Scope)
v1 不支持 optional、variant、动态拓扑、循环生成或运行时改图。
v1 不生成或执行真实物料预置命令,不创建/移动真实物料(Material),不写库位占用(SiteOccupancy)。
v1 不提供候选计划生成器(Plan Generator)、live-state-sensitive planning 或 amount="all" 规划。
不允许运行时 import/exec 作者源码、trusted-exec、eval、任意 Python 回退或浏览器解释 Python。
不建立第二 PackageCatalog、第二设备注册表(Device Registry)、第二库存(Inventory)、第二工作流任务(WorkflowTask)、第二执行计划(ExecutionPlan)或第二调度器(Scheduler)权威。
不自动公开内部成员、内部动作(Action)或任意工作流(Workflow);公开表面必须显式声明。
不提供整次候选工作单元调用串行、容量 N、max_concurrency、调用级 mutex/semaphore 或持久许可。
不重定义既有工作流(Workflow)、动作(Action)、Handle、物料占位符(ResourceSlot)、任务物料准入(TaskMaterialAdmission)、作业执行占用(JobExecutionClaim)、投递重放(DeliveryReplay)或物理结算(PhysicalSettlement)合同。
不要求 Python 源码字节级往返;注释、空行、局部变量名和 import 风格可以规范化。
不在 v1 支持 catalog: 或 latest 启动引用;启动只接受 workspace/package 内显式文件。
补充说明(Further Notes)
当前实现(Current Implementation)
OS 当前图读取会直接构造 NetworkX 图与资源树集合(ResourceTreeSet),并把未知根字段移动到 config;它是需要收敛的遗留兼容路径,不满足本规格的无损分类和单一运行权威。
OS 已有纯工作流创作编译器(Authoring Compiler)、规范 JSON/Python 固定点、结构化诊断、SQLite 创作事实和 HTTP 接口,可作为模块深度与测试接缝先例,但尚未实现候选工作单元定义(WorkCell Definition)或 prepare_activation(...)。
前端已有单一工作流服务接口、Python/JSON 创作操作和真实 OS Playwright 主路径,可复用交互与服务层模式;当前尚无候选工作单元(WorkCell)专属创作接口或画布。
SZLab 真实复杂度夹具当前包含 129 个节点、0 条显式连接和 11 个非空 data,使用本地 OPC UA 仿真端点;它仍是遗留 JSON,不代表迁移已完成。
分支收敛复核(Migration Baseline Review)
本次复核固定的 OS 收敛头为 feat/fast-feature-migration-reviewed@e13ddb0d7756cfaba64245214b0485f936672b2c,产品基线为 product/durable-scheduler-kernel@cd2d409a007e233aec0e9422359bf85c5427e37b,原始行为供体为 publication/f007-integration-20260803@a1b7b77473223e696e74f08aef350eb0dad3c710。实际开工时仍必须重新读取最新已验收收敛头,不能把本次 SHA 当成永久分支名。
当前收敛头相对产品基线为 0/102,即产品基线完全是其祖先;相对复核时最新远端 integration/workflow-task-runtime@e00aa22be3ed478f9b4cd2dec2f27516c91f1d2e 为 106/742。二者共同祖先是 7bbfd38516a1b31aa9035b48baa4c9c108efad05,从共同祖先分别修改 251 和 520 个文件,交集为 101 个,已不是近邻分支。
对当前收敛头与最新远端 integration 进行非写入 git merge-tree 复核,产生 84 个文本冲突文件、603 个冲突块,集中于 unilabos/app、unilabos/workflow、unilabos/registry、图读取和相应测试。
选取 23 个候选工作单元(WorkCell)高概率实现触点比较,23/23 均分歧:14 个已经产生文本冲突,8 个深模块只存在于收敛分支,resources/graphio.py 虽可自动合并但语义仍分歧。直接在 integration 实现会针对已被收敛线替换的接口编码,后续不是普通 rebase,而是高概率重新设计与重实现。
C0b2 本地模板身份、C0b3 可编辑工作流注册及其语言标准仍处于并行收敛。它们直接触及 template_projection.py、composition.py、service.py、store.py 和来源引导,因此候选工作单元发布/来源切片应等待这些分支被接受;否则即使从当前收敛头开工,语义冲突仍为中高风险。
结论:允许现在完成规格、RED 测试设计和票据拆分;生产实现必须进入新的 migration/fXX-<feature-name> 纵向切片,并按依赖门等待相应接受接口。禁止直接在 integration 下实现。
治理与证据
Agent 上报
agent_report :
stage : implementation
reporter : Codex
execution_mode : agent
agent_product : Codex
agent_name : WorkCell Wayfinder to-spec synthesis
model : GPT-5
input_refs :
- https://github.com/Uni-Lab-OS/Uni-Lab-Core/issues/181
- https://github.com/Uni-Lab-OS/Uni-Lab-Core/issues/182
- https://github.com/Uni-Lab-OS/Uni-Lab-Core/issues/183
- https://github.com/Uni-Lab-OS/Uni-Lab-Core/issues/184
- https://github.com/Uni-Lab-OS/Uni-Lab-Core/issues/185
- https://github.com/Uni-Lab-OS/Uni-Lab-Core/issues/186
- https://github.com/Uni-Lab-OS/Uni-Lab-Core/issues/187
- Uni-Lab-OS/Uni-Lab-Core@8841d2714e179d3b67760e2ce02892e700fad5bf:docs/architecture/workcell-composition-design.md
- Feishu 协作规范 revision 15
- Feishu 协议索引 revision 4
- Feishu 工作流协议 revision 9
result : spec-re-reviewed-for-migration-lane-ticketing
human_reviewer : 待复核(昌珺涵)
问题陈述(Problem Statement)
Uni-Lab 当前使用大型启动 JSON/GraphML 同时表达设备实例、固定资源、父子关系、连接、位置、初始化配置和遗留运行
data。这种文件难以由人安全审阅,也让 AI 难以在强约束和快速反馈下完成局部修改;现有读取路径还会把未知根字段移动到config,无法证明哪些值属于定义、候选启用或运行权威。工站设计实际包含两个相互关联但生命周期不同的目标:一是确定设备、固定资源、库位(Site)、数量、选型、连接和毫米制物理布置;二是把同一固定结构绑定为可以启动的设备配置。除此之外,工站内部已验证的工作流(Workflow)还需要以公共动作(Action)形式供上层实验室工作流复用,同时保留唯一工作流任务(WorkflowTask)、执行计划(ExecutionPlan)、调度器(Scheduler)和物理结算(PhysicalSettlement)权威。
如果继续把这些目标写成任意 Python、两个相互漂移的 JSON/Python 真相,或一套新的站内运行时,就会产生不可校验源码、重复设备实例化、秘密泄漏、库存覆盖、双重调度和盲目物理重放(Blind Physical Replay)风险。
解决方案(Solution)
提供一等、可版本化、可嵌套的候选工作单元定义(WorkCell Definition)。人和 AI 可以在受限 Python、规范 NetworkX node-link JSON 和结构化画布之间进行双向语义创作;所有创作方式进入同一个纯编译、链接、校验、发布和摘要链。已发布定义只描述固定候选装配拓扑(Assembly Topology)、物理
pose、库位(Site)设计约束、公开启动合同和公共动作(Action),不拥有真实物料(Material)、库位占用(SiteOccupancy)、遥测或任务状态。启动继续使用
-g/--graph。候选启用解析器(Activation Resolver)通过唯一prepare_activation(...)接口,将精确已发布定义、零个或一个候选启用请求(Activation Request)、实例部署字段和敏感配置(Secret)引用降低为候选启用图(Activation Graph)与脱敏、内容寻址的候选启用快照(Activation Snapshot);全部验证和快照持久化在驱动导入、构造或硬件连接之前完成。内部工作流(Workflow)只有通过显式导出才能成为工作流支持动作(Workflow-backed Action)。调用继续复用组合工作流调用(CompositeWorkflowInvocation),在任务创建时静态降低到同一个工作流任务(WorkflowTask)与执行计划(ExecutionPlan);不同调用的内部作业可以交错,物理安全只由完整逐作业执行占用(JobExecutionClaim)保护。
OS 实现必须进入现有快速功能迁移收敛线(Fast Feature Migration Convergence Lane):每个切片从当时最新、已验收的
feat/fast-feature-migration-reviewed提交创建migration/fXX-<feature-name>分支,并同时冻结其父提交和行为供体提交。integration/workflow-task-runtime只作为行为、测试和不变量供体,不作为候选工作单元(WorkCell)生产实现基线,也不得整体合入。这样可以让候选工作单元(WorkCell)复用当前收敛线已经建立的深模块接缝,而不重新引入已被替换的工作流服务、存储、组合、运行时和 D1A bridge 门面。用户故事(User Stories)
@workcell文件可以直接作为-g/--graph输入,从而让定义文件与启动入口保持一致。pose,从而让测绘、设计和模型展示没有第二坐标真相。layout_plane选择XY、XZ或YZ编辑平面,从而专注于当前测绘平面并保持第三轴不变。member_id,从而局部变量重命名不会创建新的物理身份。InitParam强类型声明,从而只覆盖作者明确开放的配置,而不能通过深路径修改私有设备配置。workcell.py。SecretRef和版本进入启用过程,从而源码、日志、诊断、目录和快照都不包含明文。--check_mode在任何驱动导入、构造或硬件连接之前完成校验,从而 CI 可以安全验证包与启动文件。data在无损保存后仍阻止发布和启用,从而兼容不会变成静默执行。实现决策(Implementation Decisions)
.py、.json、.graphml只在输入适配器(Adapter)处不同。三个适配器之后必须进入同一个规范编译核心;不得保留第二套设备实例化、驱动导入或运行语义。@workcell根定义。graph/nodes/links、id/name/type/class/parent/children/pose/config/data与连接字段。仅增加被证明必需的元数据和config_bindings。children与config.sites[]的语义顺序。content_digest不包含自身、source map 或兼容保留载荷;legacy_payload_digest单独覆盖兼容载荷,原始文件另记录字节摘要。content_digest组成;成员id是稳定member_id。运行实例 UUID 从根实例 namespace 与成员路径确定性派生,旧uuid不进入定义摘要。optional、variant和动态拓扑保留到未来版本化协议。Rz · Ry · Rx组合、数值规范化、父子矩阵组合和layout_plane投影。设备作者句柄和前端适配器(Adapter)不得复制坐标换算。config.sites[].label/content_type/position/size、成员内稳定 key、毫米几何、容量 1、资源模板(ResourceTemplate)兼容和sort_order投影;拒绝任何占用者字段。draft_revision,保存使用 CAS;切换模式先编译、校验、显示完整 diff 并重新证明固定点,冲突必须显式 rebase。prepare_activation(request) -> PreparedActivation | ActivationDiagnostics。文件读取、目录、Secret Provider、快照存储和格式适配器都是内部接缝。-g/--graph是唯一启动定义来源参数,严格按.py/.json/.graphml后缀分派;未知或无后缀失败,不做内容探测。--config只配置 OS 进程,不进入候选工作单元初始化合同(WorkCell Init Contract)。private;只有显式exported和显式re_export可以形成稳定外部寻址;候选可查看性与候选可寻址性保持分离。node_type="workflow"、工作流合同扩展、真实 Handle、工作流输入合同(WorkflowInputContract)和工作流结果记录(WorkflowResultRecord);不新增implementation.kind或站级 entry/exit 模型。never。pose。layout_plane只决定显示和允许拖动的两个轴;折叠/展开只改变视图状态,不进入定义摘要、候选启用快照(Activation Snapshot)或运行权威。data阻止发布/启用。command_id、整批事务和持久回执推迟到 v2+。migration/fXX-<feature-name>分支,并记录父提交、固定integration供体提交和迁移范围。迁移遵循 RED → GREEN → FIX、全量测试、独立标准/规格双轴评审、文件体量审查和非 squash 合并;不得在integration上直接实现后再整体搬运。execution_unknown、投递重放(DeliveryReplay)与物理结算(PhysicalSettlement)验收进一步依赖 K12~K14 的作业执行占用(JobExecutionClaim)、派发效果(DispatchEffect)和物理结算合同;未绿前不得以旧integration运行时补洞。integration;真实 SSE 跨仓验收进一步依赖 F09 持久事件游标与重连。app/main.py、resources/graphio.py、workflow/service.py和workflow/store.py只保留对新深模块的最小委托,不承载候选工作单元编译、兼容分类、启用或计划构建规则。所有新增或修改函数、方法、回调、夹具和测试函数必须使用中文文档说明参数、返回值、异常、身份、权威和安全不变量;所有触及文件执行 500/800 行体量审查。8841d2714e179d3b67760e2ce02892e700fad5bf设为临时协议锚点和显式合并门禁,不能依赖可漂移分支头。测试决策(Testing Decisions)
content_digest必须一致;兼容往返的legacy_payload_digest必须一致。member_id、依赖漂移、位姿 NaN/Infinity、连接端口错误和库位(Site)Schema 错误,全部返回稳定诊断而非异常泄漏或部分发布。prepare_activation(...)。以临时 workspace、固定目录、可替换 Secret Provider 和快照存储适配器(Adapter)覆盖零参数、全部默认、必填缺失、单一覆盖、多来源冲突、Secret 不可用、实例部署、快照复用和输入变化;失败时必须证明没有 driver import、设备构造、连接、设备注册表(Device Registry)实例或物料写入。layout_plane、第三轴保持、父节点旋转、嵌套组合和 Backendrelative_position投影。private/exported/re_export、公共合同收窄、候选可查看性/候选可寻址性隔离、前端折叠固定点和双摘要。execution_unknown、投递重放(DeliveryReplay)和物理结算(PhysicalSettlement)。pose/layout_plane编辑、发布 revision、Palette 投影、折叠/展开、旧运行证据固定和无console.error/pageerror。pose和一个工作流支持动作(Workflow-backed Action),作为快速 CI 主路径。szlab-local-debug.json的来源 commit、原始字节摘要、129 个节点和 11 个非空data清单;输出workcell.py、规范 JSON、兼容 sidecar、迁移报告和预期双摘要。默认验收只连接本地 OPC UA 仿真端点,不连接真实硬件。data从语义层移除;测试 seed 进入独立测试夹具;运行事实被拒绝;未知非空data被无损保存但阻止发布/启用;旧uuid不污染定义摘要。integration为直接实现基线或绕过已接受深模块接缝的变更。integration供体运行选定行为回归;两者行为差异必须形成显式迁移说明,不能通过直接合并供体门面消除。范围外(Out of Scope)
optional、variant、动态拓扑、循环生成或运行时改图。amount="all"规划。eval、任意 Python 回退或浏览器解释 Python。max_concurrency、调用级 mutex/semaphore 或持久许可。catalog:或latest启动引用;启动只接受 workspace/package 内显式文件。补充说明(Further Notes)
当前实现(Current Implementation)
config;它是需要收敛的遗留兼容路径,不满足本规格的无损分类和单一运行权威。prepare_activation(...)。data,使用本地 OPC UA 仿真端点;它仍是遗留 JSON,不代表迁移已完成。分支收敛复核(Migration Baseline Review)
feat/fast-feature-migration-reviewed@e13ddb0d7756cfaba64245214b0485f936672b2c,产品基线为product/durable-scheduler-kernel@cd2d409a007e233aec0e9422359bf85c5427e37b,原始行为供体为publication/f007-integration-20260803@a1b7b77473223e696e74f08aef350eb0dad3c710。实际开工时仍必须重新读取最新已验收收敛头,不能把本次 SHA 当成永久分支名。0/102,即产品基线完全是其祖先;相对复核时最新远端integration/workflow-task-runtime@e00aa22be3ed478f9b4cd2dec2f27516c91f1d2e为106/742。二者共同祖先是7bbfd38516a1b31aa9035b48baa4c9c108efad05,从共同祖先分别修改 251 和 520 个文件,交集为 101 个,已不是近邻分支。integration进行非写入git merge-tree复核,产生 84 个文本冲突文件、603 个冲突块,集中于unilabos/app、unilabos/workflow、unilabos/registry、图读取和相应测试。resources/graphio.py虽可自动合并但语义仍分歧。直接在integration实现会针对已被收敛线替换的接口编码,后续不是普通 rebase,而是高概率重新设计与重实现。template_projection.py、composition.py、service.py、store.py和来源引导,因此候选工作单元发布/来源切片应等待这些分支被接受;否则即使从当前收敛头开工,语义冲突仍为中高风险。migration/fXX-<feature-name>纵向切片,并按依赖门等待相应接受接口。禁止直接在integration下实现。治理与证据
/to-tickets应把本规格拆成阻塞边明确的纵向切片,并复用而非重复这些 Epic。feature_id、contract_version和 commit。协议索引 revision 4 与工作流协议 revision 9 仍需在验收前补充候选工作单元(WorkCell)专题;revision 9 的历史success/succeeded冲突不得传播到本功能,本规格沿用当前已接受工作流任务(WorkflowTask)与调度器(Scheduler)合同。Agent 上报