Skip to content

fix(chat): isolate native Codex context for workspace-only sessions - #5928

Merged
huangruiteng merged 2 commits into
mainfrom
codex/workspace-only-codex-context-20261008
Oct 8, 2026
Merged

huangruiteng merged 2 commits into
mainfrom
codex/workspace-only-codex-context-20261008

Conversation

@loopx-agent

Copy link
Copy Markdown
Collaborator

Goal And Delivered Outcome

An ordinary Codex conversation configured with project_filesystem_scope=workspace_only still 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.

  • Outcome basis: repair the existing workspace-only execution boundary; intended base is main at 159f00fc8ababa088e8f6cde3ef06653bc4c0511.
  • Observable before → after: two focused regressions fail on that base; the candidate excludes a synthetic global skill, keeps a workspace skill, prevents a configured MCP command from running, and resumes the same native thread with its original synthetic history.

Author Declaration

Criterion Disposition Owner / validation
Explicit workspace-only host policy implemented Existing typed collaboration.project.session_identity supplies the isolated store key; codex_context.py and the native app-server caller apply it.
Default workspace writes and explicit read-only compatibility implemented Existing permission profiles remain authoritative; ordinary/default and attached-host paths retain their prior home behavior. Focused agent/home tests and chat-agent smoke cover the changed callers.
Session identity and resumption implemented Persist and check the derived home before native resume. Core namespace and host-store regressions plus real native history resume cover this boundary.
Complete community execution/privacy qualification deferred Independent native login, the live App owner and the existing community golden-query release gate remain required; this patch does not qualify public group entry.

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

  • Tested revision: 88f330ffa5447e433d3430f0e676bd791663705d (committed after the final source checks; wheel built from this exact commit).
  • Run state: finished.
  • Input classes: synthetic.
Check kind Result Public-safe evidence / limitation
regression_parity passed Two behavior assertions fail on base 159f00fc8ababa088e8f6cde3ef06653bc4c0511, then pass with the repair.
unit passed Latest focused Python run: 123 tests across test_chat_agent.py, test_chat_codex_home.py, and test_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.
static passed Changed Python files pass Ruff; the configured mypy target passes (19 source files), as does the new helper independently. A broader optional scan of old runtime files has existing errors reproduced on the pinned base; it is not claimed green.
integration passed Semantic vocabulary smoke, chat-agent/model-catalog compatibility smoke, and standard diff-derived local premerge pass: 5 direct checks plus 11 selected checks. An initial runtime-size rejection was repaired by moving the existing home check into the provider helper; no ceiling was relaxed.
real_entrypoint passed Real native Codex app-server from source and an isolated Python 3.12 wheel installation: private global skill absent; workspace skill available; filesystem profile correct; configured synthetic MCP server disabled and its command never executed; file-only auth; same upstream thread and original synthetic history preserved after resume. Empty native-home startup also passes. Disabled MCP entries can remain in metadata; zero entries is not the oracle.
real_backend blocked Independent native authentication is absent. A synthetic model Turn is recorded, but times out without an assistant answer. No successful model execution or live community golden query is claimed.
manual not_run No production service/configuration change or group message replay was performed for this candidate. CI was not consulted.

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

  • UI impact: none; no frontend or presentation changes.
  • Before / After / States and viewports: N/A.
  • Source data: none.
  • Attention review: N/A.

Type of Change

  • Bug fix
  • Documentation update
  • Test update

LoopX Area

  • Host or runtime integration
  • Capability or extension

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

  • Diff and publication contain no private state, credentials, raw traces, internal links or local machine paths.
  • No duplicate benchmark work.
  • Scope remains the existing workspace-only host boundary.
  • UI impact is none.
  • The commit has a DCO sign-off.

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 路径不增加这一步。

具体改动

  1. conversation_scope.ts:projectConversationIdentity(31)只在既有 workspace-only 分支返回 host_store_key,复用规范化的 project/App/operator 身份。不同 workspace、binding、provider、operator 产生不同 key;同 source topic 变化保留认证目录。默认 result 不增加该字段。
  2. 新的 native_chat/codex_context.py(14/35/51/66)负责原生目录、symlink 拒绝、环境及 MCP override;状态与权限决策继续由 TS owner 提供。process_environment 使用独立 HOME/CODEX_HOME 和最小 PATH;默认环境原样保留。实际 MCP 名称与请求名称合并为 enabled=false,不复制命令、环境或认证。
  3. CodexChatAgentSession.start(575)在严格 profile 下强制 native file auth(独立目录配置为 keyring 的真实反例仍读回 file),读取有效配置后才打开/恢复 thread,核对 profile 与唯一工作区。兼容 catalog 重试接收同一隔离环境和原 base home,不会把已经派生的目录再次嵌套。CodexChatAgentError.gate 类型允许既有的无 host gate 错误,没有新增权限。
  4. ChatRuntimeController 的 create/guard/post-resume 使用同一派生目录,写入原 Session 的 codex_home;严格旧 shared/missing home 在恢复前拒绝,原记录不变。普通 legacy Session 仍在原成功恢复后绑定;attached host 不生成 managed adapter。
  5. 三个 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.

@huangruiteng
huangruiteng merged commit 62acd67 into main Oct 8, 2026
7 of 9 checks passed
@huangruiteng
huangruiteng deleted the codex/workspace-only-codex-context-20261008 branch October 8, 2026 09:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants