首页/新闻资讯/正文详情

OpenCodex V2 加密 Agent 任务快速失败守卫解析:从 PR 283 评审否决到 `unreadable_encrypted_agent_task` 的源码落地

发布时间:2026/9/26 15:29:34 来源:云帆数科 栏目:资讯中心
OpenCodex V2 加密 Agent 任务快速失败守卫解析:从 PR 283 评审否决到 `unreadable_encrypted_agent_task` 的源码落地
【免费下载链接】opencodexUniversal provider proxy for OpenAI Codex Claude Code — use any LLM (Claude, Gemini, Grok, DeepSeek, Ollama…) with Codex CLI, App, SDK, and Claude Code项目地址https://gitcode.com/gh_mirrors/ope/opencodex点击查看免费下载导读本文围绕 OpenCodex 仓库中的一份 Sol 评审记录devlog/_fin/260723_overnight_pr_review/060_pr283_v2_agent_failfast.md完整解析 PR #283 fix(v2): fail fast on unreadable routed agent tasks 的评审否决过程以及其六条重建要求在后续源码中的最终落地形态。读完本文你将掌握v2 子代理sub-agent加密任务在跨提供者路由时为何必须快速失败、混合槽位mixed slot如何绕过守卫、结构化 Fernet 校验与先分类后变更的检测顺序以及遇到 HTTP 400unreadable_encrypted_agent_task时如何在真实部署中定位与处置。背景v2 加密任务与跨提供者委派的固有矛盾在 ChatGPT Codex 的多 Agent 架构里agent_message是 Codex 后端私有的输入项类型仅存在于 ChatGPT Codex 后端的 schema 中。OpenCodex 作为Universal provider proxy会把这个私有项降级lower成公开的message项后转发给第三方提供者xAI、Anthropic、Gemini、GLM 等。这里存在两种任务承载形态v1明文父 Agent 把子任务以普通input_text发出OpenCodex 可读、可路由任何被路由的子模型都能执行。v2加密父 AgentChatGPT 原生模型把任务放入encrypted_content槽位密文由 ChatGPT 后端用Fernet方案铸造密钥留在该后端。OpenCodex 从未持有密钥因此解密在代理侧结构性不可能——密文就是密文不是某个开关后面的明文。由此产生最典型的失败场景ChatGPT 父模型委派给被路由的第三方子模型v2 下该任务每一次都会失败因为第三方无法读取为原生后端加密的任务体。相关拓扑结论在 subagent-v1-default 指南 中有明确表格ChatGPT 父 → 路由子在 v2 下必然失败路由父 → 路由子不受影响ChatGPT 父 → ChatGPT 子也不受影响后端总能解密自己铸造的密文。真正危险的失败形态不是报错而是静默地把空指令发给子模型——密文在路由时被当作可读内容处理子模型收到一个空任务体后自信地给出错误答案。PR #283 的目标正是消除这种形态与其转发不可读的密文不如在派发前快速失败。PR #283 的评审结论为什么被否决评审记录显示PR #283作者 MathiasHeinke分支codex/v2-encrypted-task-failfast → devdraft 状态CI 全绿8/8 checks但 Sol 评审Einstein给出FAIL1 个 High、4 个 Medium最终决策为REBUILD_ON_DEV。High 1混合加密槽位绕过守卫H1评审指出sanitizeEncryptedContentInPlace()在处理混合槽位时会先把内容拆成两部分input_text控制前导文本如[CXC-...]控制段落或Message Type: NEW_TASK路由信封加encrypted_content真正的任务密文。PR 草案中的readableAgentMessagePayload()会把前导文本判定为可操作文本于是守卫返回 false即可读路由提供者被调用——但调用时任务体已经缺失。这恰好复现了该 PR 声称要阻止的失败模式子模型收到了不完整的、实际上不可读的任务。这一缺陷在后续源码中有对应的正式记录见src/server/responses/encrypted-payload.ts中stripAgentMessageCiphertextInPlace的注释引用 issue #4454一个混合了input_textencrypted_content的条目对当前任务是否可读守卫的回答是可读对是否可整体降级的回答是不可降级于是它穿过守卫、以私有agent_message类型进入原始 Responses 透传最终把私有条目和后端密文同时放到线上。4 个 Medium 问题评审同时列出四个中等问题构成了重建要求的直接输入FERNET_TOKEN_EXACT正则过松会接受结构上不可能存在的令牌信封envelope解析存在误报false-positive与漏报false-negative案例请求级全量扫描会因加密历史记录而误拒可读轮次Combo 路由可能在到达原生兼容目标之前就停下来。六条重建要求及其源码落地评审给出了六条重建要求对照当前仓库源码它们全部有对应实现。以下逐一解析。1. 在变更之前从原始内容推导语义分类评审要求从原始内容raw content中、在变更mutation之前推导语义分类。当前实现的关键顺序在 request-prepare.ts先在第 255 行调用hasUnreadableEncryptedAgentTask(body.input)得到布尔判定之后才在第 294 行对同一input调用sanitizeEncryptedContentInPlace(..., { preserveUnknownOpaqueSlots: true })做明文兼容改写。也就是说可读性判定发生在任何变异之前杜绝了先拆槽位、后判语义导致的 H1 混合槽位绕过。sanitizeEncryptedContentInPlace本身encrypted-payload.ts用显式栈遍历把encrypted_content槽位切分为input_textencrypted_content片段而判定函数hasUnreadableEncryptedAgentTask永远在它之前运行并在解析出可读文本为零时返回 true。2. 结构化 Fernet 校验不再信任宽松正则评审指出草案的FERNET_TOKEN_EXACT正则过松。当前实现用isStructurallyValidFernetTokenencrypted-payload.ts做仅依赖密钥无关的 Fernet 线格式的结构校验长度约束token.length 100 || token.length % 4 ! 0直接拒绝字母表约束必须是 base64url[A-Za-z0-9_-]{0,2}并对填充padding长度做精确匹配base64url 往返校验解码后重新编码必须与原串一致版本字节解码后decoded[0] ! 0x80拒绝Fernet 版本字节内部结构长度至少 73 字节密文长度 解码长 − 57必须 ≥ 16 且是 16 的倍数一个 AES-CBC 块。该函数刻意不校验时间戳新鲜度历史记录中的合法令牌也应当被识别也刻意不校验 HMAC 真实性代理没有密钥无法也不应验证。令牌候选正则FERNET_TOKEN_CANDIDATE /g[A-Za-z0-9_-]{97,}{0,2}/g搭配边界字符检查FERNET_TOKEN_BOUNDARY_CHAR确保只把边界完整、结构合法的令牌视为后端密文运行段run。配套的FERNET_SHAPED与looksLikeFernetTokenencrypted-payload.ts则用于区分明文文本里恰好长得像编码 blob 的内容——一个 SHA-256 摘要恰好是 64 个[A-Za-z0-9]字符若用宽松字符类判定子模型故意打印的摘要会被静默替换删除因此文本槽位采用严格匹配而encrypted_content槽位按定义即密文、一律剥离。3. 固定 canonical、mixed-hook、malformed-token、historical-message 四类 fixture重建要求固定四类测试夹具。当前测试文件 tests/server/v2-agent-message-failfast.test.ts 完整覆盖canonicalfernetFixture()构造版本(1) 时间戳(8) IV(16) 一个 AES-CBC 块(16) HMAC(32)的结构化真实 Fernet 线格式字节为合成数据不发布真实任务也不声称 HMAC 真实mixed-hook[CXC-LEAF-GUARD]、[CXC-SKILL-AFFORDANCE]、[CXC-RATE-GUARD]等 CXC 控制段落混入encrypted_content槽位的用例malformed-tokenTOO_SHORT_FERNET、INVALID_BLOCK_FERNET17 字节密文块、INVALID_VERSION_FERNET0x81 版本、截断串、去掉填充的串、前置字符污染的串全部断言不误报historical-message历史位置出现加密agent_message、当前轮次可读的用例断言判定为可读。测试中还包含信封漏报修复#3021子代理的MESSAGE回复信封原本只匹配NEW_TASK一个整段为 Fernet 令牌的MESSAGE会被判为可读并原样转发当前AGENT_MESSAGE_ROUTING_ENVELOPE同时匹配NEW_TASK|MESSAGE但恢复recovery仍仅限 NEW_TASK——在父会话无权读取的载荷上解密 MESSAGE 会构造明文预言机plaintext oracle因此检测可以放宽恢复必须收窄。4. 守卫范围限定为新投递的任务项排除展开的历史评审要求将守卫范围限定到新投递的任务项newly delivered task items而非展开后的历史。hasUnreadableEncryptedAgentTaskencrypted-payload.ts的扫描逻辑体现了这一点只从input尾部向上定位当前任务跳过compaction_trigger、additional_tools等尾部元数据后要求尾部条目类型是agent_message否则直接返回 false只有尾部的当前任务被判定历史中紧邻的加密 agent 消息不会污染它splitFernetParts对连续encrypted_content片段做拼接后再校验的联合判定并设置MAX_AGENT_TASK_ENCRYPTED_PARTS 32与MAX_AGENT_TASK_CIPHERTEXT_BYTES 2 MiB上限防止检测本身被巨型载荷拖垮判定流程是剥离控制前导AGENT_MESSAGE_CONTROL_PREAMBLE与路由信封AGENT_MESSAGE_ROUTING_ENVELOPE后若剩余可读文本长度为零且存在 Fernet 任务则判定不可读。对应测试classifies only trailing current agent messages, not encrypted history与still blocks an unreadable current task after readable history分别验证了历史豁免与尾部元数据跟随时的仍然阻断。5. Combo 路由先把候选过滤到可解密的路由再谈 400评审指出combo routing may stop before reaching a native-compatible target。当前 core-combo.ts 实现了目标过滤再次调用hasUnreadableEncryptedAgentTask判定载荷是否不可读canDecryptUnreadableAgentTask(target)通过routeConcreteModel解析目标路由并用isCanonicalOpenAiForwardProvideropenai-tiers-destination.ts判断该目标是否是能够解密原生密文的规范 ChatGPT 转发提供者payloadEligible(target)逻辑为载荷可读或没有不可读任务或目标可解密。Combo 选择pickComboTargetWithWait只在这些合格目标中挑选若不可读且没有任何合格目标才进入恢复流程recoverUnreadableEncryptedTask恢复失败才返回 400。测试 filters a combo to a decrypt-capable native target before dispatch 验证混合 ComboxAI OpenAI 原生在不可读任务下只会把请求发给chatgpt.com/backend-api/codex原生目标绝不打到api.x.aireturns the machine-readable guard error when a combo has no native target 验证无原生目标时返回 400 且fetch零调用keeps encrypted combo failover on native targets after a native failure 验证原生目标 403 后仍能在第二个原生目标上继续加密 failover。6. 机器可读错误码unreadable_encrypted_agent_task重建要求增加机器可读错误码。落地位置在 core-errors.ts{ error: { message: Routed V2 worker task is encrypted for the native ChatGPT backend and cannot be read by the selected provider. Use plaintext V2 agent-message delivery or select a native ChatGPT model., type: invalid_request_error, code: unreadable_encrypted_agent_task } }HTTP 状态 400且响应体中绝不回显密文——测试断言raw不包含FERNET_TASK也不包含gAAAA。这是刻意设计的 fail-closed转发不可读载荷等于给子模型一份空指令和一个自信的错误答案。混合槽位的第二道防线路由前的密文修复H1 的完整修复不只靠检测顺序。对可读但不可降级的混合条目encrypted-payload.ts 提供了stripAgentMessageCiphertextInPlace在派发前把agent_message中的密文替换为[encrypted content omitted]标记并保留可读的明文半区如the child finished the migration再把条目降级为公开的message。测试 repairs a mixed child result replayed behind a later user turn 验证了出站体中不含密文、不含gAAAA、不含agent_message但保留可读文本。对于纯文本槽位中内嵌的令牌textWithRunsOmitted只替换令牌本身、保留周边散文the child replied [encrypted content omitted] and stopped。与之配套的normalizeRoutedAgentMessagesadapters/routed-agent-messages.ts负责把纯可读的agent_message改写为公开message并携带 author/recipient 身份文本一旦内容里出现真正的密文或未知部件类型它保留原条目、交还给unreadable_encrypted_agent_task的 fail-closed 路径处理。需要特别注意的是authMode: forward只描述代理如何处理凭据不代表对端能解密——只有规范的 ChatGPT 后端isCanonicalOpenAiForwardProvider才拥有密钥非规范 forward 网关同样按第三方处理并执行密文剥离测试 repairs a noncanonical forward gateway 验证了这一行为。遇到该错误时的运维处置如果部署中收到unreadable_encrypted_agent_task根据 subagent-v1-default 指南 的定位与建议该错误发生在ChatGPT 原生父模型 → 被路由的第三方子模型的 v2 委派上属于结构性限制不是代理侧配置错误也没有代理侧开关能修复——OpenCodex 从未持有后端密钥OpenCodex 默认安装使用v1 子代理表面Dashboard、Models、Subagents 页面在切换到 base/v2 前都会要求确认v1 下父模型以明文发任务跨提供者委派正常工作若必须使用 v2平面并发会话工具请保证父子模型位于同一侧边界父与子都是 ChatGPT 原生或父与子都被路由需要自动化处理时可以直接依赖错误码unreadable_encrypted_agent_task做重试分流或降级到 v1 表面而不是把 400 当普通瞬时故障盲目重试。结语PR #283 的评审记录是理解 OpenCodex V2 加密 Agent 任务守卫设计动机的绝佳切片一个全部 CI 通过的 draft PR 因混合槽位绕过而被打回重建六条重建要求逐条演化为当前源码中的结构化 Fernet 校验、先判定后变更的顺序、尾部任务项限定、Combo 原生目标过滤与机器可读错误码。从 评审文档 到 加密载荷实现、请求准备链路、Combo 路由 与 测试套件可以完整复现评审发现缺陷 → 重建要求 → 源码落地 → 测试固化的全过程这也是 OpenCodex 处理安全敏感功能的典型工程闭环。赞分享【免费下载链接】opencodexUniversal provider proxy for OpenAI Codex Claude Code — use any LLM (Claude, Gemini, Grok, DeepSeek, Ollama…) with Codex CLI, App, SDK, and Claude Code项目地址https://gitcode.com/gh_mirrors/ope/opencodex点击查看免费下载相关推荐Ramda对象操作实战prop、assoc、path与lens10分钟掌握函数式对象处理Ramda对象操作实战prop、assoc、path与lens10分钟掌握函数式对象处理 Ramda 是一款实用的函数式 JavaScript 工具库Pr开发工具opencodex PR 8 评审全记录Autostart Ensure Fallback 的代码评审、问题清单与修复落地opencodex PR 8 评审全记录Autostart Ensure Fallback 的代码评审、问题清单与修复落地 导读 本文基于 opencodexTigerBeetle Node.js 客户端如何安装并连接本地集群创建第一个账户TigerBeetle Node.js 客户端如何安装并连接本地集群创建第一个账户 本文解决一个具体任务在本机启动一个单副本 TigerBeetle 集群安上一篇Terraform跨云部署教程learning-cloud项目中的AWS、Azure与GCP实现下一篇探索 React Native WebView一种强大而灵活的跨平台解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

车载以太网调试实战:从接线到TC10休眠唤醒验证
车载以太网调试实战:从接线到TC10休眠唤醒验证

车载以太网开发这几年是真热闹,但真上手做过的朋友都明白,热闹背后全是琐碎的麻烦。整车里面CAN和LIN还能用老办法挂总线分析,一到100BASE-T1这种车载以太网链路,原来的调试手段基本失灵,光是把测试设备正确接入网络、… · 2026/9/26 15:29:34

AWS Elastic Beanstalk Kotlin SDK 示例:应用与环境全生命周期实战指南
AWS Elastic Beanstalk Kotlin SDK 示例:应用与环境全生命周期实战指南

示例工程教程后端 【免费下载链接】aws-doc-sdk-examples Welcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below. 项目地… · 2026/9/26 15:29:34

ESP32-CAM图像传输实战:突破内存、供电与时序三重约束
ESP32-CAM图像传输实战:突破内存、供电与时序三重约束

1. 这不是“跑个例程就完事”的项目:ESP32-CAM图像传输到底在解决什么问题?你手头那块不到二十块钱的ESP32-CAM模块,表面看就是个带摄像头的Wi-Fi开发板,但真正用起来才发现——它根本不是Arduino那种“接线→烧录→亮灯”就能闭环… · 2026/9/26 15:29:34

Trae 免费额度 vs Cursor 强大功能:TaoToken 统一 Key 接入 settings.json 配置对比
Trae 免费额度 vs Cursor 强大功能:TaoToken 统一 Key 接入 settings.json 配置对比

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 16:00:04

用 vscode-jenkins-pipeline-linter-connector 与 TaoToken 统一 Key 校验 Jenkinsfile:LLMs 配置实战
用 vscode-jenkins-pipeline-linter-connector 与 TaoToken 统一 Key 校验 Jenkinsfile:LLMs 配置实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 16:00:04

AI Agent Harness轻量化部署:边缘节点方案与TaoToken配置骨架
AI Agent Harness轻量化部署:边缘节点方案与TaoToken配置骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 16:00:04

Oracle library cache lock 排查:version_count 飙高时用 TaoToken 统一 Key 管理诊断脚本配置
Oracle library cache lock 排查:version_count 飙高时用 TaoToken 统一 Key 管理诊断脚本配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 16:00:04

【AI】Claude Code 长时间重复任务操作手册:TaoToken 统一 Key 接入与 continue_task.sh 配置实战
【AI】Claude Code 长时间重复任务操作手册:TaoToken 统一 Key 接入与 continue_task.sh 配置实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 16:00:04

superpowers-zh 系统化调试技能实战:四阶段根因驱动方法论与配套辅助技术全解
superpowers-zh 系统化调试技能实战:四阶段根因驱动方法论与配套辅助技术全解

AI 技能AI 插件人工智能开发工具 【免费下载链接】superpowers-zh 🦸 AI 编程超能力 中文增强版 — superpowers(250k ⭐)完整汉化 4 个中国原创 skills,让 Claude Code / Copilot CLI / Hermes Agent / Cursor / Windsurf / Ki… · 2026/9/26 15:59:57

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21

OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40

向下兼容与向上兼容:接口设计中的兼容性策略与工程实践
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践

一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码