Guardian Review

Guardian review 是 Codex 对 on-request/granular approval 的自动审查层。它不是替代 sandbox,也不是简单规则列表;它会为具体工具动作构造一个受控的审查子会话,让专门的 reviewer model 判断是否可以自动批准。

它解决的问题

传统 agent CLI 有两种不理想的审批体验:

  1. 所有高风险动作都弹给用户,频繁打断。
  2. 给模型过大的自动权限,风险被转移到执行后。

Guardian 的折中是:当 approval policy 允许请求审批,并且 approvals_reviewer == AutoReview 时,把 approval request 先交给 guardian reviewer。它的原则是 fail closed:超时、会话失败、解析失败都会阻止执行,只有显式 allow 才放行。

路由条件

入口在 codex-rs/core/src/guardian/review.rs

matches!(
    turn.approval_policy.value(),
    AskForApproval::OnRequest | AskForApproval::Granular(_)
) && approvals_reviewer == ApprovalsReviewer::AutoReview

这意味着 Guardian 只接管本来会进入审批路径的请求。更早的 ARC、权限 profile、sandbox 仍然可以先阻断动作。

审查合同

Guardian 要返回严格 JSON,对应 GuardianAssessment

字段 含义
risk_level low/medium/high/critical
user_authorization 用户是否已授权该类操作
outcome allow/reject 等审查结果
rationale 审查理由

guardian_output_schema 会约束输出结构,parse_guardian_assessment 负责解析。如果输出 malformed,执行失败关闭。

Transcript 裁剪

Guardian 不把完整历史塞进审查 prompt,而是构造紧凑 transcript:

常量 数值 用途
GUARDIAN_MAX_MESSAGE_TRANSCRIPT_TOKENS 10_000 message transcript 总预算
GUARDIAN_MAX_TOOL_TRANSCRIPT_TOKENS 10_000 tool transcript 总预算
GUARDIAN_MAX_MESSAGE_ENTRY_TOKENS 2_000 单条 message 上限
GUARDIAN_MAX_TOOL_ENTRY_TOKENS 1_000 单条 tool 上限
GUARDIAN_MAX_ACTION_STRING_TOKENS 16_000 待执行动作描述上限
GUARDIAN_RECENT_ENTRY_LIMIT 40 最近条目数量上限

这套预算体现了安全审查里的上下文工程:要保留用户意图、近期工具结果和具体动作,但不能把审查本身拖成另一个完整 agent turn。

Trunk 与 ephemeral review

GuardianReviewSessionManager 会维护一个可复用的 trunk review session。复用条件由 GuardianReviewSessionReuseKey 决定,它包含 model/provider、context window、reasoning 配置、permissions、instructions、cwd、mcp servers、sandbox exe、features 等会影响审查行为的字段。

如果 trunk 空闲且 reuse key 一致,就复用 trunk;如果 trunk 忙,或 key 不一致,会 fork 出 ephemeral review:

session kind 使用场景
TrunkNew 首次创建 trunk
TrunkReused trunk 可复用且空闲
EphemeralForked trunk 忙或配置不匹配时的临时审查

trunk 成功完成后会刷新 fork snapshot。这样下一次 ephemeral review 可以从最近已提交的 guardian rollout 快照启动,而不是从零开始。

超时、重试和熔断

Guardian 有多个保护层:

机制 代码位置 作用
GUARDIAN_REVIEW_TIMEOUT = 90s guardian/mod.rs 审查 deadline
GUARDIAN_REVIEW_MAX_ATTEMPTS = 3 guardian/review.rs 审查失败重试上限
fail closed run_guardian_review timeout/session/parse error 都阻止执行
denial circuit breaker GuardianRejectionCircuitBreaker 同一 turn 拒绝过多时中断 turn

拒绝熔断阈值是:

常量 数值
连续拒绝 3
最近窗口拒绝 50 次审查中 10 次拒绝

熔断触发时,Codex 会发送 GuardianWarning,然后 abort 当前 turn。这个设计防止 agent 在被拒绝后不断变体尝试,形成策略绕行。

拒绝后的开发者消息

当 guardian reject 一个动作时,Codex 会生成一段明确指令:

The agent must not attempt to achieve the same outcome via workaround,
indirect execution, or policy circumvention.

这段信息作为后续模型上下文的一部分,让 agent 明确知道“不能换个写法继续做同一件事”。这比只返回工具错误更强,因为它改变了后续推理约束。

与 Review Task 的关系

codex-rs/core/src/tasks/review.rs 是用户可触发的 /review 风格任务,用 sub-agent 产出 structured review output。它和 Guardian 共享“子会话审查”的思想,但目标不同:

机制 触发 目标 权限
Guardian Review 工具审批请求 判断具体动作是否自动放行 fail closed,继承父配置并受限
Review Task 用户进入 review mode 审查代码变更并输出 findings 禁用 web search、collab、multi-agent,审批永不请求

Review Task 在退出时会把 review output 作为 developer message 记录到 rollout,确保后续 turn 能读到审查结论。

可学习的设计点

  1. 自动审批不是规则硬编码,而是“专用模型 + 严格 schema + 失败关闭”。
  2. trunk reuse 降低频繁审批的延迟,同时用 reuse key 精确失效。
  3. fork snapshot 让并发审查既能共享上下文,又不会互相污染。
  4. denial circuit breaker 把“安全拒绝”升级为“停止当前 turn”,避免策略绕行。
  5. 审查输出会转化成后续开发者上下文,而不是仅影响当前工具调用。

关键源码

主题 文件
guardian 入口与常量 codex-rs/core/src/guardian/mod.rs
approval review flow codex-rs/core/src/guardian/review.rs
review session manager codex-rs/core/src/guardian/review_session.rs
approval request formatting codex-rs/core/src/guardian/approval_request.rs
prompt/schema/parse codex-rs/core/src/guardian/prompt.rs
review task codex-rs/core/src/tasks/review.rs