Repository navigation
fix(chat): isolate native Codex context for workspace-only sessions - #5928
Conversation
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent | gpt-6.1-sol | OpenAI | runtime_reported | reasoning_effort=xhigh
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
Exact head: 88f330f
动机
选择 workspace-only(仅允许指定项目文件)策略的普通项目对话用户。 在仅允许项目文件的 Codex 对话中,旧版本仍把个人全局技能、进程环境和配置的 MCP 服务带入原生执行;新版为该项目及 App/操作者派生独立目录,在实际线程启动和恢复时应用隔离。 独立源码与安装包探针确认全局合成技能和环境标记被排除,项目技能仍可用,项目配置的 MCP 命令未执行,原生线程与合成历史可继续恢复。 本 PR 不启用公开群、不搬迁个人认证或历史,也不证明完整隐私、Windows、真实登录或模型回答质量。 独立原生登录、真实 App/群入口、干净公开工作区和社区 golden-query 准出仍待原有 owner 验收。 这修复了现有明确策略的原生前提;不会以测试通过宣布完整公开群可用。
改动思路
复用现有 typed project identity 决定目录身份,Python 只适配原生目录、环境与配置;相比新增 Session authority,这是修复现有调用方的较小完整边界。 本 PR 交付 workspace-only 原生启动、持久化目录和恢复隔离;完整社区发布和登录采用继续由已有验收承担。 单改技能注入开关仍允许显式技能发现,单改目录仍会继承环境和分层 MCP 配置;这组修改需要在既有原生入口一起生效。没有增加服务、执行器、Session 注册表或新的配置开关。App/操作者/项目决定认证目录,source topic 仍独立成 thread,避免每条消息重新登录。
独立规格依据:docs/architecture/rfcs/app-conversation-and-async-inbox-v0.md,不可变版本 159f00f;先读该版本,再判断本次文档变化。验收映射:workspace_only 的明确项目策略和身份持续适用;host_default 保留原默认技能/原生目录;Native Codex resume 保留原线程与工作区并检查 profile/root;community Bot isolation 仍为原发布验收的未完成边界。严格旧 Session 的新目录无法安全借用个人认证或历史,显式新建及独立登录是已披露的安全恢复成本,普通与 attached 路径不增加这一步。
具体改动
conversation_scope.ts:projectConversationIdentity(31)只在既有 workspace-only 分支返回host_store_key,复用规范化的 project/App/operator 身份。不同 workspace、binding、provider、operator 产生不同 key;同 source topic 变化保留认证目录。默认 result 不增加该字段。- 新的
native_chat/codex_context.py(14/35/51/66)负责原生目录、symlink 拒绝、环境及 MCP override;状态与权限决策继续由 TS owner 提供。process_environment使用独立 HOME/CODEX_HOME 和最小 PATH;默认环境原样保留。实际 MCP 名称与请求名称合并为enabled=false,不复制命令、环境或认证。 CodexChatAgentSession.start(575)在严格 profile 下强制 native file auth(独立目录配置为 keyring 的真实反例仍读回 file),读取有效配置后才打开/恢复 thread,核对 profile 与唯一工作区。兼容 catalog 重试接收同一隔离环境和原 base home,不会把已经派生的目录再次嵌套。CodexChatAgentError.gate类型允许既有的无 host gate 错误,没有新增权限。ChatRuntimeController的 create/guard/post-resume 使用同一派生目录,写入原 Session 的codex_home;严格旧 shared/missing home 在恢复前拒绝,原记录不变。普通 legacy Session 仍在原成功恢复后绑定;attached host 不生成 managed adapter。- 三个 Python 测试面和 typed identity 测试覆盖配置、环境、profile/root 拒绝、身份隔离、真实旧 store 语义与默认兼容;RFC 写明独立 native 登录、旧严格 Session 显式替换及剩余公开隐私边界。
正向链:host scope → typed identity → 私有 native store/env → config/read 与关闭 MCP → thread/start/profile readback → 实际原生持久化 → 同 thread/resume/read 找回原合成用户历史。反向链:旧 strict Session 缺 home/仍指 shared home → 实际 Chat store/controller 校验 → codex_home_mismatch,没有改写记录或先启动旧 thread;非法 App id、symlink、错误 profile/root 也分别拒绝。
对主干的风险
独立验证:163 项相关 Python、20 项 TS、Ruff、配置 mypy 与 helper mypy 通过;standard premerge 的 5 direct、2 catalog、8 risk、1 public-boundary 检查通过,无失败/跳过/manual hold。语义 advisory 没发现受支持的新词汇 carrier;其空结果不覆盖动态字符串,派生 key 与权限语义已另读实际 owner。
同一冻结 oracle、同一 Python 3.12.15、同一 Codex 0.160.0 在源码和独立安装 wheel 各 26/26,通过 base 159f00f 仅 10/26。具体 base 反例是全局合成技能、环境标记、MCP 命令及 shared/missing home 的后置失败/状态变化;默认全局技能与 exact resume 对照保留。安装包从准确 commit 重建,确认真实安装位置后运行同样的 native/store 流程。使用本地始终拒绝的合成 HTTP provider 建立真实原生历史;没有付费调用,也没有把此结果当成功模型回答。
初期探针问题保留:空 thread 尚未持久化不能恢复,改用实际合成 Turn 的 native 历史;额外 mcpServerStatus/list RPC 会创建另一原生配置观察上下文,该 RPC 不在这条 adapter 执行链,最终 start/技能读取/config/Turn/resume 均独立检查 MCP 命令未执行。本次不声称任意 host metadata/dynamic-tool RPC 的隔离。最初私有 rollout 检查发生在持久化前,已移至实际 native 写入后;固定 26 条判定未弱化排除/MCP/store 断言。wheel 起初被过期 frontend bundle 正确拒绝,重建既有忽略资产后通过,没有改预算或源文件。catalog 辅助探针起初使用最小 PATH 中不存在的相对命令,纠正为生产调用已经使用的 resolved absolute executable;真实 native catalog 及清理读回通过,强制重试顺序另有回归测试。
UI/默认配置没有新开关或视觉修改;这里验证的是已有严格原生调用方,真实 App 登录采用、Windows、公开群 golden queries、任意动态 host tools 和完整隐私仍未测。遵守 wait_for_ci=false,没有查询、轮询或等待 CI。权限/身份不能由这些本地通过结果扩张;旧 home 不迁移,必要时同时回退原生 IO 与 TS key,但保留持久化的 store identity。
我的整体评价
APPROVE 这个有界原生修复,没有当前 scoped adapter 路径的剩余阻塞发现。复用现有 typed project identity 决定目录身份,Python 只适配原生目录、环境与配置;相比新增 Session authority,这是修复现有调用方的较小完整边界。 本 PR 交付 workspace-only 原生启动、持久化目录和恢复隔离;完整社区发布和登录采用继续由已有验收承担。 future-facing 复核采用了将新 IO 和原 home guard 集中到现有 native_chat 边界的相关整理;TS identity 仍是唯一 key/权限 owner,未引入另一状态源或泛化框架。普通和 attached 兼容性有对照;严格旧 Session 的恢复成本与独立登录保持公开可见。公开 self-review 不能变成 GitHub formal self-approval,此 runtime PR 的合并和部署仍归维护者。
English verdict: APPROVE - 88f330f. Repairs the existing workspace-only native context in the existing typed identity/provider boundary. Independent source and Python 3.12 installed-wheel native start/history-resume/store probes passed 26/26 each versus 10/26 on the pinned base; 163 Python, 20 TS, lint/types and standard local premerge passed. Live authentication, arbitrary host metadata/dynamic tools and complete community privacy/release qualification remain open; maintainer merge required.
Goal And Delivered Outcome
An ordinary Codex conversation configured with
project_filesystem_scope=workspace_onlystill used its host's shared Codex home and inherited process environment. Its filesystem profile restricted project access, but global skills, configured MCP servers and credentials could still enter the native context.This change gives that existing opt-in policy a Core-derived, App/operator/workspace-specific native home, a minimal environment, file-only authentication and disabled configured MCP servers. The default personal conversation continues to use its existing home and permissions. Existing strict Sessions using a shared or missing home fail before resume; explicitly starting a new Session establishes the new boundary.
mainat159f00fc8ababa088e8f6cde3ef06653bc4c0511.Author Declaration
collaboration.project.session_identitysupplies the isolated store key;codex_context.pyand the native app-server caller apply it.Scope And Continuation
This is a staged repair of the existing native Codex entrypoint, with no new session authority, runner, service, configuration switch or automatic credential migration. Python adapts the Core identity to host IO. The RFC records the required new-session behavior and remaining acceptance gaps.
It does not prove all directory/network/privacy boundaries or a completed model answer. The next owner is the existing Chat/App deployment path: establish independent native authentication, connect the isolated App, then run the published community golden queries. A clean public workspace and historical-text review remain separate prerequisites.
Validation
88f330ffa5447e433d3430f0e676bd791663705d(committed after the final source checks; wheel built from this exact commit).159f00fc8ababa088e8f6cde3ef06653bc4c0511, then pass with the repair.test_chat_agent.py,test_chat_codex_home.py, andtest_chat_codex_context.py. Core conversation identity/binding/scope tests: 20 passed. An earlier 174-test run also included ordinary-project startup and Lark private-conversation regressions before the final helper extraction. Counts overlap and are not additive.The native canary exercises the changed startup/resume path and actual skill/MCP behavior. It does not waive independent authentication or the community release gate.
Frontend / Visual Evidence
Type of Change
LoopX Area
Shared-authority RFC fixture impact
N/A: no storage-authority promotion or provider-routing change. The existing typed project identity gains an optional derived host-store key for its workspace-only policy; it does not introduce another registry or session authority.
Boundary Checklist