Skip to content

fix(chat): redact complete custom runtime paths - #5472

Merged
huangruiteng merged 3 commits into
mainfrom
codex/release-chat-privacy
Oct 2, 2026
Merged

huangruiteng merged 3 commits into
mainfrom
codex/release-chat-privacy

Conversation

@huangruiteng

@huangruiteng huangruiteng commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

Custom runtime mounts could leak absolute paths through Chat's status response, and response redaction removed only a declared root while leaving its descendant suffix visible. Redact complete declared path tokens, reuse the existing canonical generic path detector, and include the actual selected runtime in the status redaction scope. Keep public URLs, relative paths and prefix lookalikes intact.

Validation: 174 focused Chat interaction/status/privacy tests passed; the complete existing Chat contract and real HTTP/server smoke passed; nine new privacy regressions cover custom POSIX/Windows roots, JSON escaping, long streaming paths, token boundaries and the HTTP status route. Ruff and diff checks pass. Storage, routing, UI actions and permission authority remain unchanged; the existing changed-target guard also rejects newly recognized local-path proposal targets; the packaged UI consumes the same status endpoint.

This is a runtime privacy fix. Maintainer merge is required under repository policy. Final merged-source release qualification remains pending.

@huangruiteng
huangruiteng force-pushed the codex/release-chat-privacy branch from dc5da18 to 67911a9 Compare October 2, 2026 14:43

@huangruiteng huangruiteng 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; OpenAI; runtime_reported

Approval conclusion: APPROVE for exact head 67911a9dd0583117dfd63f15f0ee9115b22821af, base 62ca35f280b51fd4a474b4380a9664570d5aa802. Runtime privacy fix: maintainer merge remains required.

动机

发布全量验证在自定义状态目录复现真实路径泄漏:回复只移除根前缀,留下私有子目录;status 保护列表遗漏实际选定 runtime。普通 /tmp fixture 会掩盖问题。规范依据 docs/public-private-boundary.md 的 Private-local-paths,固定 62ca35f280b51fd4a474b4380a9664570d5aa802。

改动思路

修复现有 Chat 脱敏 owner,复用 public_safe_text 的正式通用路径形状,以完整的显式根/后代 token 替代 substring replace。状态接口加入启动时已解析的 runtime,stream 使用同一匹配规则,保护跨 chunk 的长根和包含空格的根。

具体改动

关键代码讲解

redact_local_paths 以最长显式根优先,保留现有 project/local-path 标签和句末标点。普通文本与 JSON 转义根都匹配;根后必须是 token 边界,不能误吞 prefix lookalike 或 URL。共享 canonical 通用规则取代旧 display 根名单。Codex activity formatter 会展示项目相对后代,因此不能直接复用它的披露策略。

ChatStatusRequestMixin._status 在已有 registry/scan scope 中加入实际 server.runtime_root,仍在 JSON 回读前脱敏。VisibleResponseStreamFilter 保留有完整或未完成声明根的 token,避免长度阈值/空格切开路径。三个既有 HTTP fixture 补齐真实 startup 已有的 runtime_root 字段;没有在产品代码里放宽为静默 fallback。

语义与 CI 对齐

无新协议、状态词汇、capability 或 provider;Python 仅修已有文本/HTTP adapter,共享分类 owner 不变。权限、Todo 状态和 Turn state-machine 不改。披露规则有意变严:现有 protected target 的“脱敏后必须保持原目标”规则也会拒绝现在识别出的本地目标,不能称为所有输入逐字节兼容。默认 off/authority/domain-neutral/guidance lenses 已核验,没有新自动动作或安装指令。按 Goal 策略未查询 PR CI。

对主干的风险

同一 custom-root 输入在不可变基线保留 /private/gate.json,本 head 完整替换为 existing placeholder。9项独立隐私回归覆盖 POSIX/Windows/JSON、公共 URL/相对路径/前缀近邻、长根和空格流式分块,以及真正 HTTP route;自定义 HTTP status collector 为合成输入,完整既有 Chat server smoke 使用真实本地 HTTP/backend、合成 provider。174项相关 interaction/status/delivery review 测试和完整 contract/server smokes通过,Ruff、semantic advisory、diff 检查通过。

最大风险是过度脱敏、JSON 破坏或 streaming 早泄漏;正反用例覆盖这些分支。没有 canonical state/persistence、排序、限额或权限 side effects,delivery review 保留独立状态回读。frontend 消费同一状态/事件接口,不新增交互,不需要 companion 控件;最终安装产物仍必须在 release qualification 中回读。

我的整体评价

APPROVE。实证隐私缺陷在现有归属处完整修复,可回退,无用户目录迁移。未来修整将 completed/streamed display 规则收口到同一 matcher,没有新通用服务或控制面决策 owner。Maintainer merge 与最终提交发布资格仍待完成。

English verdict: APPROVE - exact head 67911a9. Whole declared runtime paths are withheld in Chat JSON/replies and across stream chunks; public URLs/relative/prefix cases remain intact. 174 focused tests and complete existing Chat contract/server smokes pass. Canonical state and permission authority are unchanged; stricter display/target sanitation is intentional. Maintainer merge and final release-source qualification remain required.

@huangruiteng
huangruiteng force-pushed the codex/release-chat-privacy branch from 67911a9 to a4433a4 Compare October 2, 2026 14:54

@huangruiteng huangruiteng 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; OpenAI; runtime_reported

Approval conclusion: APPROVE for exact head a4433a4de69a2441c8fc6af0f57350510d1484eb, base 1412d122975509bd2a54da9118560d95757cf0c3. Runtime privacy fix: maintainer merge remains required.

动机

发布全量验证在自定义状态目录复现真实路径泄漏:回复只移除根前缀,留下私有子目录;status 保护列表遗漏实际选定 runtime。普通 /tmp fixture 会掩盖问题。规范依据 docs/public-private-boundary.md 的 Private-local-paths,固定 1412d122975509bd2a54da9118560d95757cf0c3。

改动思路

修复现有 Chat 脱敏 owner,复用 public_safe_text 的正式通用路径形状,以完整的显式根/后代 token 替代 substring replace。状态接口加入启动时已解析的 runtime,stream 使用同一匹配规则,保护跨 chunk 的长根和包含空格的根。

具体改动

关键代码讲解

redact_local_paths 以最长显式根优先,保留现有 project/local-path 标签和句末标点。普通文本与 JSON 转义根都匹配;根后必须是 token 边界,不能误吞 prefix lookalike 或 URL。共享 canonical 通用规则取代旧 display 根名单。Codex activity formatter 会展示项目相对后代,因此不能直接复用它的披露策略。

ChatStatusRequestMixin._status 在已有 registry/scan scope 中加入实际 server.runtime_root,仍在 JSON 回读前脱敏。VisibleResponseStreamFilter 保留有完整或未完成声明根的 token,避免长度阈值/空格切开路径。三个既有 HTTP fixture 补齐真实 startup 已有的 runtime_root 字段;没有在产品代码里放宽为静默 fallback。

语义与 CI 对齐

无新协议、状态词汇、capability 或 provider;Python 仅修已有文本/HTTP adapter,共享分类 owner 不变。权限、Todo 状态和 Turn state-machine 不改。披露规则有意变严:现有 protected target 的“脱敏后必须保持原目标”规则也会拒绝现在识别出的本地目标,不能称为所有输入逐字节兼容。默认 off/authority/domain-neutral/guidance lenses 已核验,没有新自动动作或安装指令。按 Goal 策略未查询 PR CI。

对主干的风险

同一 custom-root 输入在不可变基线保留 /private/gate.json,本 head 完整替换为 existing placeholder。9项独立隐私回归覆盖 POSIX/Windows/JSON、公共 URL/相对路径/前缀近邻、长根和空格流式分块,以及真正 HTTP route;自定义 HTTP status collector 为合成输入,完整既有 Chat server smoke 使用真实本地 HTTP/backend、合成 provider。174项相关 interaction/status/delivery review 测试和完整 contract/server smokes通过,Ruff、semantic advisory、diff 检查通过。

最大风险是过度脱敏、JSON 破坏或 streaming 早泄漏;正反用例覆盖这些分支。没有 canonical state/persistence、排序、限额或权限 side effects,delivery review 保留独立状态回读。frontend 消费同一状态/事件接口,不新增交互,不需要 companion 控件;最终安装产物仍必须在 release qualification 中回读。

我的整体评价

APPROVE。实证隐私缺陷在现有归属处完整修复,可回退,无用户目录迁移。未来修整将 completed/streamed display 规则收口到同一 matcher,没有新通用服务或控制面决策 owner。Maintainer merge 与最终提交发布资格仍待完成。

English verdict: APPROVE - exact head a4433a4. Whole declared runtime paths are withheld in Chat JSON/replies and across stream chunks; public URLs/relative/prefix cases remain intact. 174 focused tests and complete existing Chat contract/server smokes pass. Canonical state and permission authority are unchanged; stricter display/target sanitation is intentional. Maintainer merge and final release-source qualification remain required.

Signed-off-by: huangruiteng <huangrt01@163.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
@huangruiteng
huangruiteng force-pushed the codex/release-chat-privacy branch from a4433a4 to cba3a5a Compare October 2, 2026 15:04

@huangruiteng huangruiteng 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; OpenAI; runtime_reported

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

APPROVE for exact head cba3a5aa6564d38e578ba11ad4ddcca843db4c60, base 9b0486dc1b891bc5254ea85d1ba06da089d22853. Runtime privacy fix: owner explicitly authorized this merge after renewed review/readiness.

动机

发布全量验证在自定义状态目录复现真实路径泄漏:回复只移除根前缀,留下私有子目录;status 保护列表遗漏实际选定 runtime。普通 /tmp fixture 会掩盖问题。规范依据 docs/public-private-boundary.md 的 Private-local-paths,固定 9b0486dc1b891bc5254ea85d1ba06da089d22853。

改动思路

修复现有 Chat 脱敏 owner,复用 public_safe_text 的正式通用路径形状,以完整的显式根/后代 token 替代 substring replace。状态接口加入启动时已解析的 runtime,stream 使用同一匹配规则,保护跨 chunk 的长根和包含空格的根。

具体改动

关键代码讲解

redact_local_paths 以最长显式根优先,保留现有 project/local-path 标签和句末标点。普通文本与 JSON 转义根都匹配;根后必须是 token 边界,不能误吞 prefix lookalike 或 URL。共享 canonical 通用规则取代旧 display 根名单。Codex activity formatter 会展示项目相对后代,因此不能直接复用它的披露策略。

ChatStatusRequestMixin._status 在已有 registry/scan scope 中加入实际 server.runtime_root,仍在 JSON 回读前脱敏。VisibleResponseStreamFilter 保留有完整或未完成声明根的 token,避免长度阈值/空格切开路径。三个既有 HTTP fixture 补齐真实 startup 已有的 runtime_root 字段;没有在产品代码里放宽为静默 fallback。

语义与 CI 对齐

无新协议、状态词汇、capability 或 provider;Python 仅修已有文本/HTTP adapter,共享分类 owner 不变。权限、Todo 状态和 Turn state-machine 不改。披露规则有意变严:现有 protected target 的“脱敏后必须保持原目标”规则也会拒绝现在识别出的本地目标,不能称为所有输入逐字节兼容。默认 off/authority/domain-neutral/guidance lenses 已核验,没有新自动动作或安装指令。按 Goal 策略未查询 PR CI。

对主干的风险

同一 custom-root 输入在不可变基线保留 /private/gate.json,本 head 完整替换为 existing placeholder。9项独立隐私回归覆盖 POSIX/Windows/JSON、公共 URL/相对路径/前缀近邻、长根和空格流式分块,以及真正 HTTP route;自定义 HTTP status collector 为合成输入,完整既有 Chat server smoke 使用真实本地 HTTP/backend、合成 provider。159项相关 interaction/status/delivery review 测试和完整 contract/server smokes通过,Ruff、semantic advisory、diff 检查通过。

最大风险是过度脱敏、JSON 破坏或 streaming 早泄漏;正反用例覆盖这些分支。没有 canonical state/persistence、排序、限额或权限 side effects,delivery review 保留独立状态回读。frontend 消费同一状态/事件接口,不新增交互,不需要 companion 控件;最终安装产物仍必须在 release qualification 中回读。

我的整体评价

APPROVE。实证隐私缺陷在现有归属处完整修复,可回退,无用户目录迁移。未来修整将 completed/streamed display 规则收口到同一 matcher,没有新通用服务或控制面决策 owner。Maintainer merge 与最终提交发布资格仍待完成。

English verdict: APPROVE - exact head cba3a5a. Whole declared runtime paths are withheld in Chat JSON/replies and across stream chunks; public URLs/relative/prefix cases remain intact. 159 focused tests and complete existing Chat contract/server smokes pass. Canonical state and permission authority are unchanged; stricter display/target sanitation is intentional. Maintainer merge and final release-source qualification remain required.

@huangruiteng
huangruiteng merged commit 8dd6e40 into main Oct 2, 2026
3 checks passed
@huangruiteng
huangruiteng deleted the codex/release-chat-privacy branch October 2, 2026 15:09
@huangruiteng

Copy link
Copy Markdown
Collaborator Author

Reviewer: model_agent; model=GPT-6; provider=OpenAI.

Post-merge audit: exact PR head cba3a5aa6564d38e578ba11ad4ddcca843db4c60, merge commit 8dd6e40727294ae8d070ddf771290f75fdb82bb5. This is a newly reproduced finding after the existing approval; it does not replace the historical review or imply that this reviewer merged the PR.

[P1] Long declared roots containing spaces still leak through answer.delta. In loopx/chat.py:157–169, whitespace is selected using only complete path matches. A partially received declared root is not such a match, and the whitespace branch executes before partial_root can withhold it. A legitimate long work directory containing private state, delivered in two chunks with the first ending at character 170, therefore releases a root fragment and its private descendant. The completed response is correctly [project], but the earlier events already disclosed the path. I reproduced this with the actual ClaudeCodeAdapter.start_turn subprocess/event path, a synthetic executable supplying only raw upstream deltas, and no mocked redaction. The Dashboard forwards answer.delta to its display callback. Existing tests separately cover a short spaced root and a long root without spaces, which misses their combination.

Minimum repair: protect incomplete declared-root spans before choosing any flush boundary, including preceding ordinary prose and whitespace inside a partial root. Add a regression using the provider event sink and multiple chunk boundaries; assert that no intermediate delta exposes any private descendant and that streaming agrees with final redaction. This is an unresolved case of the original privacy defect, not a claim that every privacy behavior regressed.

动机

自定义 runtime 路径原来会从 status 和回答中泄漏,根前缀替换还会留下后代路径。这个修复有明确价值,但“最终回答已脱敏”不能证明流式过程安全。规范依据 docs/public-private-boundary.md,固定于不可变基线 9b0486dc1b891bc5254ea85d1ba06da089d22853;验收条目采用原文标题 Local Paths 和 Example Boundaries。后者满足:测试使用合成目录,没有实际用户材料;前者仍未完整满足:真实 provider 的中间事件泄漏私有后代。

改动思路

归属合理:扩展现有 Chat 展示脱敏,复用 public_safe_text.py::LOCAL_PATH_SURFACE_PATTERN,没有另建控制面或路径权限 owner。_protected_path_replacements 收集普通和 JSON 转义拼写;_local_path_pattern 约束 token 边界;redact_local_paths 替换整个匹配并保留句末标点。ChatStatusRequestMixin._status 加入启动时已选定的 runtime scope;VisibleResponseStreamFilter 尝试在安全边界输出文本。

具体改动

完整六文件 diff 为 +141/-14:两处产品代码、一个九用例隐私测试,以及三个 HTTP/server fixture 的 runtime 字段补齐。没有改变存储、路由、按钮或 canonical state。声明根按最长优先匹配,避免吞掉 prefix lookalike;公共 URL、相对路径和 JSON 仍有正反例。动作准入保留既有 _ABSOLUTE_LOCAL_PATH,展示规则有意变严;既有“脱敏前后 target 必须一致”的 guard 也会拒绝新识别的本地 target,不能把这一点描述成全部输入逐字节兼容。

未来修整检查认为应在现有 matcher/buffer 收口完整及不完整路径跨度,而不是再加一套 provider 专用 denylist。frontend 的 src/data/chat.ts:617 消费同一 status 接口,:1212 展示同一 delta;没有新增控件,修复必须在事件产生前完成。本次未宣称打包 UI 已安装,也未调用收费模型。

对主干的风险

在当前 exact head,170 项相关测试及完整现有 Chat contract/server smoke 通过。相同九项隐私 fixture 在历史基线全部失败、原评审 head 全部通过;真实 HTTP 例子证明 status 的自定义 runtime 根及后代完整遮蔽。基线到当前 PR base 的相关 owner/caller 字节未变,旧基线证据保留了来源;当前 head 又重新执行了完整测试、真实本地 HTTP/server smoke 和 provider 反例。

独立 provider 反例在基线和当前 head 都失败:当前最终回答已修复,中间 delta 仍泄漏。真实 subprocess 和过滤器未替换,只有上游模型输出是合成输入;这不是现场部署或真实模型质量证据。Ruff、完整 diff 检查与语义 advisory 已通过;无共享状态词汇新增,未查询 CI。准备阶段错误的测试文件名已纠正并运行完整集合,没有把缺文件记成产品问题。

主要风险是过度脱敏或流式提前泄漏;本次确认的是后者。回滚可恢复此前实现但会重新暴露已修复的 status 缺陷,建议在同一 owner 有界修复并回归,不新增协议、权限或迁移。

我的整体评价

当前审计结论为 REQUEST_CHANGES,合并后应补修上述 P1。路径与 status 的多数分支确实改善,范围也合理;完整流式隐私验收尚未闭合。没有新增 opt-in、Actor 生命周期、quota 或机器义务,domain-neutral、authority、default-off 与 guidance/obligation 检查不引入额外门禁。原有 APPROVE 记录保留,本评论只追加新证据与修复要求。

English verdict: REQUEST_CHANGES - exact head cba3a5a. A long declared root containing spaces leaks through actual provider answer.delta events although the final message is redacted. 170 focused tests and complete contract/server smokes pass; the independent real-subprocess streaming counterexample fails. Repair incomplete-root boundary handling and test intermediate events. This is a post-merge audit, not a merge decision.

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.

1 participant