# Codex 自主科研运行时 OpenLabs 的自动化边界按“科研判断归 Codex、状态确定性归控制面”划分。外层工作流不编码 数学路线、不枚举科研微步骤,也不根据启发式分数替 Codex 决定下一项证明操作。 ```text 管理员期望状态(project objective / resources / services) │ ▼ 短生命周期 tick:租约、资源准入、attempt 事务、机械续接/审查触发 │ ▼ 私有 campaign 副本 ├─ artifact-stage ──► attempt 私有的大型/批量 payload 暂存 ├─ .agents/skills ──► 仅协议激活的 Skill ├─ .agents/optional-methods ─► 可读但未注册生效的方法指南 ├─ .codex/hooks.json ─► 简短 SessionStart 上下文 + Stop 结果自检 └─ Codex 原生 danger-full-access runtime(本机可信账号) │ ▼ Codex 自主分析、分解、调用工具并连续跨越同角色协议阶段 │ ▼ 结果身份封装 → 契约/证据/存储边界门禁 → 内容寻址归档 → campaign 小状态原子晋升 │ └─ 失败:attempt 隔离并按策略续接 └─ 仅在角色边界、终态、阻塞或预算边界产生 next_actions ``` ## 职责边界 Codex 与领域 Skill 负责: - 阅读持久状态并判断当前科学前沿、障碍和最高信息量操作; - 在一次有界 episode 中自主完成必要的搜索、推导、计算、反例与修正; - 区分猜想、证据、证明、反证和未知,保存负结果; - 形成可恢复 checkpoint,并提出可执行的后继目标。 - 将协议阶段作为可恢复状态记录;同一权限和预算内不因阶段变化退出当前进程。 Hook 只负责: - 在会话开始时注入很短的角色、私有工作区、Skill 和结果路径上下文; - 在会话停止时检查结果 JSON 的契约与任务身份; - 最多阻止停止一次,让 Codex 自己补齐交付,而不规定补齐步骤;续接后的 Stop 必须重新 验证最终结果并写入明确的通过或终态失败回执,不能把重入本身当作成功或忽略。 这里的 Hook 是 Codex 会话安全 Hook。另有一种可选的领域 protocol lifecycle hook:它是实验室 注册的只读确定性决策程序,只能从领域状态和配置返回通用 task envelope、暂停或显式 `default`。控制面不理解其中的科学阶段和证据语义;没有选择该 protocol 的项目完全不受其 约束。 确定性 Python 代码只负责: - 租约、心跳、资源与时间上限; - 创建私有 attempt、Codex 原生沙箱策略和受信 Hook; - 绑定任务身份、验证本地证据、不可变存储和事务晋升; - 对每一种终止路径关闭 attempt,并执行 Codex 给出的 typed handoff,或在项目显式选择时执行 protocol hook 返回的 typed allocation envelope;缺少二者时只用项目原始目标重新交还科学 决策权,不在脚本里选择路线; - 阻止提交、发布、越权写入和其他不可逆外部动作。 ## 运行时不变量 1. Codex 不再套入会破坏其子进程工具调用的第二层 bubblewrap;非 Codex adapter 仍使用 外层隔离。Codex 命令由 runner 强制归一为 `danger-full-access` 与 `approval_policy=never`,允许本机账号访问文件、网络和已安装工具;attempt 目录是事务约定 和默认 cwd,不是内核写边界。聚合 systemd slice 仍强制 CPU、内存、swap 和 tasks 上限, 聚合工作区与 canonical 不得位于系统临时根。 2. `.agents` 与 `.codex` 是 attempt 临时运行时,不属于科研状态,不复制自 canonical, 也不晋升回 canonical。 3. `requested_output_path` 永远是用户任务意图;`output_path` 永远是当前 attempt 的绑定, 初始化数据库不得把后者回写到前者。 4. 通过身份校验的当前回执一旦发现结果损坏,立即终结并隔离 attempt;不等待租约过期。 5. 启动失败、结果拒绝、租约过期、取消和预算停止都必须给 attempt 写入终态。 6. 只有通过结果契约、证据门禁、协议状态验证和不可变快照的 `completed` 结果或 `needs_replan` 检查点可以原子晋升 campaign;后者不等于成功,且必须携带可执行后继动作。 7. 协议只激活 `runtime_skills` 声明的 Skill;同实验室其他 Skill 可发现但不构成 当前任务的强制规则。 8. project index、review packet/cursor 属可重建或哈希绑定的控制面元数据;它们不放在 reviewer 可写并可晋升的 campaign 树中,物化失败必须幂等重试。 9. 新 attempt 的 campaign 只承载小型、可读、可合并的知识状态;大/批量 payload 必须进入 `artifact-stage` 并在结果中逐项声明。控制面发布 payload 后只晋升引用 manifest,成功后 清理暂存,失败则完整隔离。 ## 项目与协议插件 控制面只发现 `openlabs.project.v1`,不解释项目的科学配置。项目通过 `protocol.id` 选择 实验室在 `lab.json` 注册的领域协议,协议 validator 在项目发现和 attempt 提交前分别验证 正式状态与私有修改状态。可选 protocol hook 在结果提交之后、生成下一任务之前读取正式状态, 并拥有对该协议续接的优先权,所以结果中的自由文本 `next_actions` 不能绕过策略门禁。项目 目标、workstream、Skill、优先级、连续会话策略和 `domain_config` 都可替换,无需加入领域专用 调度分支。详见 [project-protocol-architecture.zh.md](project-protocol-architecture.zh.md)。 新增故障应先判断它违反了哪一条不变量,再修改所属职责层;禁止在科研调度路径上继续堆叠 针对单个课题、单个错误字符串或单次运行的特殊分支。