Skip to content

Fix MCP adapter provenance, config preservation, and process cleanup - #8750

Open
cocolord wants to merge 1 commit into
mainfrom
codex/mcp-audit-fixes-20261114
Open

cocolord wants to merge 1 commit into
mainfrom
codex/mcp-audit-fixes-20261114

Conversation

@cocolord

@cocolord cocolord commented Nov 14, 2026 •

Copy link
Copy Markdown
Member

MCP adapters could load one LoopX release but invoke a different CLI, overwrite config edits made during dependency provisioning, detach dotfile symlinks, or leave Ark's MCP server running after its Turn ended. Reuse the existing pinned launcher and TypeScript stdio supervisor, revalidate config ownership after provisioning, and check the captured Goal instance before reading or writing a delegation stop receipt.

Also preserve complete Unicode characters at Ego extraction limits, emit Codex MCP overrides that round-trip through TOML, and refresh the current tool lists and Ego SDK pin. This adds no remote team service or new authority owner. The Kunlun install-recovery work in #8703 remains separate.

Validation:

  • Related source-checkout regression suites: 579 passed, 1 platform skip.
  • Ark package: 62 passed, including real MCP cleanup after timeout, cancellation, and hard parent exit; all three cases failed before the fix.
  • Existing delegation stop/recovery compatibility: 46 passed.
  • Real isolated Codex mcp list --json accepts ordinary and non-BMP command/argument paths.
  • Ruff and public-boundary scan pass. Standard premerge passed 18 checks and exposed three extra Any annotations; narrowing them to object restored the unchanged budget and the maintainability check passes. Final quick premerge passes on the submitted head.

Remaining audit items for review:

  • Shared synchronous FastMCP handlers delay sibling requests; a real 1-second subprocess delayed ping by 1.024 seconds. Offloading needs a shared serialization and cancellation contract.
  • Native Kunlun completion omits hard-lease claim references, and its request deadline starts after the stdin write. Journal recovery and process drain need separate qualification.
  • DSH timeout waits for descendant-held output pipes; generic KunlunCode/OpenCode2 onboarding lacks bootstrap mappings. These adjacent paths are left for a scoped follow-up rather than added to this repair.

Probes used disposable subprocesses and isolated authority state. Native browser/model sessions and Windows process cleanup were not exercised.

Cross-group review read the exact committed head e5c49144922318244b2bab8e8a825c464bf131f9 and found no additional actionable issues. It did not rerun the parent validation suites.

CI is still failing. The Windows CLI differential fails while measuring the base; the TypeScript single-owner failure identifies native_child_result_inbox.ts:109, whose blob is identical in PR base, head and current main; the aggregate gate rejects skipped TypeScript coverage. Browser failures remain unqualified in this audit. These holds are preserved, and are not reported as passed.

Signed-off-by: lusendong.6789 <[email protected]>
Signed-off-by: lusendong.6789 <[email protected]>
Co-authored-by: TRAE CLI <[email protected]>

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator

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=max

评审提交 e5c49144922318244b2bab8e8a825c464bf131f9,合并基点 1cdd9bbefd1d849ac8aa733bd3d80bc13ad0b722。

[P2] 内部标记的符号链接会覆盖无关文件。 在 Cursor 的配置目录中,LoopX 内部标记是一个指向另一份有效 JSON 的符号链接,随后执行 MCP 安装。 新实现对配置和内部标记都调用 resolve()。测试里的独立 JSON 被改成 LoopX 所有权标记,原有 user_owned 字段消失。基线相同操作保留目标内容,只替换链接本身。 仅在读取和验证过的用户配置路径上保留链接。内部标记应拒绝或按原规则替换链接本身,禁止跟随链接,且在写入实际配置之前处理异常标记。 符号链接解析 标记写入

动机 / Motivation

用户管理 Cursor 或 Kiro 的 MCP 配置时,会更新 LoopX 并继续使用已有服务器和 dotfiles。 例如用户在准备依赖时更新了其他服务器,安装结束后需要同时保留现有服务器、配置链接和无关文件。 一次错误写入会丢失用户配置,多次升级会继续覆盖链接指向的内容。 本地测试验证了常规配置链接和准备期间的编辑。带链接的内部标记仍会把所有权记录写到无关文件。 当前边界是已有 Claude/Kunlun、Cursor/Kiro、Codex、Ego 和 Ark MCP 接入与本地停止。

改动思路 / Approach

共享已有的 release 启动器和本地进程监督器有明确价值。适配器子命令可以沿用正确发行版,Ark 的本地工具进程可以跟着 Turn 结束。配置安装器也可在依赖准备结束后采用最新配置。把符号链接跟随局限于已经读取和校验的用户配置,内部记录就能保留自己的事务边界。当前边界是已有 Claude/Kunlun、Cursor/Kiro、Codex、Ego 和 Ark MCP 接入与本地停止。 启动器 Ark 进程

具体改动 / Changes

规范依据为 docs/concepts/interaction-pattern-catalog.md,修订 859a23ee9534539536343206e23452253528dd07。25 个文件中 13 个处理运行时,6 个是现有回归或夹具,6 个是文档。 安装所有权规则

  • release_provenance 已落实。Claude/Kunlun 走共享当前 release 的 argv,现有显式 CLI 选择仍在各自宿主。 启动器
  • tool_process_recovery 已落实到本地验证。执行、超时、取消、父进程退出四种真实 MCP 用例全过。Stop 的绑定先通过现有 Goal 范围校验。 Stop 监督器
  • owned_config_only 未满足。真实安装入口把内部标记链接的目标内容改成 LoopX 记录,且返回 written。 写入

对主干的风险 / Risks

PASS · 已有安装测试能保住用户在准备依赖期间更新的服务器。真实本地 Ark MCP 在完成、超时、取消和父进程退出四种情形都被回收。 五文件复测 497 项通过。Ruff 和差异检查通过。原生 Codex 也读回普通、非 BMP 和含 DEL 的命令。

FAIL · 新实现对配置和内部标记都调用 resolve()。测试里的独立 JSON 被改成 LoopX 所有权标记,原有 user_owned 字段消失。基线相同操作保留目标内容,只替换链接本身。 单独的旧 Codex 超时夹具有两次未观察到 child marker,限定复跑与基线也各观察到通过。超时波动的原因仍未查明。

UNVERIFIED · 真实安装逻辑在隔离目录执行,依赖准备使用同步夹具。Ark 四项只调用本地 stdio 与真实进程,无云端模型。原生 Codex 只验证配置枚举。Windows、浏览器会话及 Kunlun 实机流程仍未核验。 托管 CI 未查。

我的整体评价 / Verdict

REQUEST_CHANGES。安装权限越出本来应写入的两个文件会直接覆盖用户内容。仅在读取和验证过的用户配置路径上保留链接。内部标记应拒绝或按原规则替换链接本身,禁止跟随链接,且在写入实际配置之前处理异常标记。 在同一套入口里加链接目标字节的前后对比即可验证。审阅了两份 Kunlun 指南、CLI 安装结果和 MCP 配置。改动调整技术说明和既有操作路径,没有改变应用首屏或工作区布局。

English verdict: REQUEST_CHANGES at e5c4914. Preserving the user-config symlink currently also makes the installer follow links on its internal ownership marker and overwrite the target. Limit symlink handling to the validated user config and preserve unrelated files.

def _write_json_atomic(path: Path, payload: Any) -> None:
"""Replace `path` in one step, so an interrupted run cannot truncate it."""
"""Replace the effective file in one step, preserving a user's symlink."""
path = path.resolve()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[P2] 内部标记的符号链接会覆盖无关文件。 在 Cursor 的配置目录中,LoopX 内部标记是一个指向另一份有效 JSON 的符号链接,随后执行 MCP 安装。 新实现对配置和内部标记都调用 resolve()。测试里的独立 JSON 被改成 LoopX 所有权标记,原有 user_owned 字段消失。基线相同操作保留目标内容,只替换链接本身。 仅在读取和验证过的用户配置路径上保留链接。内部标记应拒绝或按原规则替换链接本身,禁止跟随链接,且在写入实际配置之前处理异常标记。

This branch has not been deployed

No deployments
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