OpenProgram Docs

统一 Agent 操作生命周期

OpenProgram 使用同一套流程处理权限判断、工具执行、失败重试、结果保存和中断恢复。保留现有 Agent 循环、权限服务、执行数据库、持久化审批等待和前端状态投影,不增加第二套工作流引擎。

完整技术契约以 英文设计为准。本页说明设计决策与实施边界。

当前实现与剩余问题

  • 近期失败表与检查点统一限制为 16 条,新增失败不会使检查点容量溢出。
  • Bash 重复判断排除只用于显示的 description,实际执行参数与其他工具字段仍参与判断。
  • auto 模式在分析命令前按工具名称拒绝 Bash;分类器只读取参数前 800 个字符,缺少可信工作目录和任务上下文。因此不能直接删除拒绝名单。
  • 审批等待在调用前同步准备,自动分类却发生在执行阶段。分类拒绝后直接弹审批会缺少可恢复的持久化等待记录。
  • 最后一次拒绝虽然有日志,但检查点异常使执行记录仍保留 dispatched,导致错误地进入操作结果待核对状态。

采用哪些已有策略

参考产品公开依据采用方式
Codex工具调度源码先审批,再选择沙箱并执行;拒绝与沙箱失败分别处理。所有工具共用调用前预检;申请额外权限必须符合策略,重试本身不授予权限。
Claude Code自动审批文档规定连续 3 次或累计 20 次分类拒绝后,交互会话恢复人工审批。采用独立的连续和累计计数,复用持久化审批。非交互任务保留拒绝并继续其他获准工作。
Claude Code权限规则区分整个工具禁用和具体操作禁止。工具可见性与实际能力一致;已生成的旧调用仍须经过最新权限检查。
Claude Code文件检查点不撤销 Bash 或远程系统操作。区分会话恢复、文件撤销与执行结果核对,不宣称任意外部操作恰好执行一次。

Codex 源码链接固定到具体版本;产品文档可变,实现前保存对应证据。Claude Code 内部失败表和结果存储机制未由这些公开资料证实。以下结果持久化方案属于 OpenProgram 自身设计。

三个独立状态

状态取值回答的问题
权限allow / ask / deny当前身份与规则是否允许这次操作开始?
执行结果not_started / succeeded / failed / unknown操作是否执行,结果是否确定?失败可能已有部分副作用。
结果交付pending / recorded / projected结果是否保存,是否同步到会话和界面?
准备 → 权限判断 → 必要的持久化审批 → 再次校验 → 执行 → 保存结果 → 检查点 → 更新界面
             ↘ 拒绝 → 保存“未执行” → 模型继续其他工作或说明阻碍

每次操作通过 execution ID、tool call ID、参数摘要、权限版本绑定。权限拒绝表示这次操作未开始,不表示整个任务完成。只有操作可能执行、结果无法确认时,才使用 reconciliation_required。

调用前预检

  1. 保留当前硬约束、身份能力、计划模式、显式 deny、ask 和精确授权的优先级,分类器不能覆盖它们。
  2. 在登记执行前异步审查完整操作。传入可信工作目录、权限范围和必要的用户要求;模型描述与仓库文本视为不可信输入。过大参数不得截断后批准。
  3. 分类器超时、服务失败、取消和明确风险拒绝分别记录。没有明确允许就不执行,也不能把“无判断结果”统计成风险结论。
  4. 仅对具备相应能力的交互式所有者创建持久化审批。硬约束和明确禁止不能变成可覆盖的审批。
  5. 执行前重新核对权限版本、参数摘要、审批身份和文件前置条件。审查期间规则改变,旧结论失效。

不要在所有拒绝结果上统一写 execution_started=false:调用前拒绝可以确定未执行,但沙箱执行后申请额外权限被拒,原操作可能已经部分执行。

失败与继续执行

  • 参数错误:返回结构化错误,允许修正实际参数。
  • 权限拒绝:说明规则和有效解决方式;未改变权限或实际条件,不因修改描述重复尝试。
  • 临时故障:只有确定未执行或具备可靠幂等支持时,才进行有次数限制的自动重试。
  • 确定失败:返回完整必要输出供模型判断;其他获准且有意义的工作继续。
  • 结果未知:保留操作证据,进入核对流程,不能直接重试。
  • 运行时故障:单独报告,不能把已知工具结果重新变成未知。

近期失败表使用固定容量;完整历史保留在事件记录中。存储淘汰不重置累计拒绝计数,也不改变权限。Bash 只排除明确属于显示用途的 description,保留 command、工作目录和权限等执行字段;不能对用户工具任意删除同名字段,不能猜测任意 Shell 脚本是否等价。

交互式 auto 回退采用连续 3 次、累计 20 次分类拒绝的默认值。获准操作只清除连续计数;累计计数按定义的会话周期保存。恢复和并发调用通过操作身份避免重复计数。回退至人工审批不解除任何显式禁止。

结果保存与恢复

复用现有数据库,将权威结果记录与可选诊断、显示状态分开。结果记录绑定调用身份、结果摘要、是否开始执行和错误原因,检查点构建失败不能丢掉已知结果。

恢复时的情况处理
结果已保存,检查点未更新使用结果补齐继续执行状态,不再次调用工具。
检查点已保存,界面未更新只重放界面投影。
有执行记录,没有可信结果按原有副作用核对规则处理。

外部系统操作不能与本地 SQLite 普遍组成一个事务,因此不承诺所有副作用只执行一次。修复旧会话必须核对精确调用与可信权限事件,不能只根据一段任意工具文字猜测未执行,更不能把整个任务标成完成。

文件职责与实施顺序

顺序模块验收要求
1Agent failure_policy、循环与 continuation超过 16 条不同失败仍可保存;改描述不重置判断;旧合法检查点可读。
2agent/permissions完整命令预检;危险尾部不会被忽略;审查期间取消或撤销权限不执行。
3现有权限状态与审批等待拒绝回退有持久化等待;非交互不创建无法回答的审批;恢复不重复计数。
4production_driver 与 execution结果保存后故障,重启不重复执行写操作;真正未知的结果仍要求核对。
5工具可见性与 Web 状态投影规则撤销立即生效;界面与后端一致显示原因和有效恢复动作。

Terminal、Web、用户应用和普通工具通过现有公共入口使用同一生命周期,不建立各自的权限与重试框架。每阶段独立复现、实现、规格审查、质量审查及完整验证。紧急容量修复与权限放宽分开交付。

实现状态

权限预检和持久化拒绝回退已通过之前的独立审查与完整 Python 检查。结果恢复、宿主执行证据、工具可见性与结果显示正在进行集成验证,尚未部署或合并。

拒绝计数按会话和用户权限版本隔离。显式权限版本变化开始新的计数周期。允许的操作及经审批的回退操作只重置连续次数,累计次数在累计阈值触发的审批完成或周期变化时重置。现有 SQLite 事务内的执行事件保存准确调用身份与判断,恢复或并发调用不会重复计数。没有布尔判断的分类器故障不改变计数。回退使用已有用户审批等待,不能覆盖显式禁止。

审批接入

复用现有持久化审批等待。自动风险拒绝不占执行失败重复次数,使相同操作能够达到人工审批阈值。无有效判断的检查错误不自动授权。仅宿主在已授权实现开始前记录执行;已完成和未执行结果均先于检查点保存,不信任应用返回的执行状态。每次模型请求按适用规则过滤工具,保留已保存执行契约。实时事件和历史记录传递宿主结果状态。累计计数在累计阈值触发的审批完成或权限版本变化时重置。

Claude Code 文档提供拒绝回退策略,Codex 调度实现提供先审批后执行和受策略限制的升级。二者不构成适用于本项目数据库的通用恢复算法;结果保存使用现有事务和检查点机制。

模型请求事件

每次发出的模型请求具有唯一 request_id,并且恰好记录一次开始和结束。结束状态区分完成、失败、取消和未完整结束,覆盖传输异常及缺少终止事件的 EOF。异常与取消保持原样传播;事件记录不重放工具,也不增加模型重试。原有部分文本返回仍标为未完整结束。完成观察器不把失败请求视为成功回答。

Last updated · 2026-10-10