---
title: "Claude Code + Codex CLI 配置打架？一次收敛到 iCloud 的 9 步方案"
author: deletexiumu
pubDatetime: 2026-04-21T00:15:00+08:00
featured: false
draft: false
tags:
  - Claude Code
  - 教程
  - 效率
description: "同时用 Claude Code 和 Codex CLI，改一条规则要两次，skills 三个源怎么办？从激进合并方案到 Codex 对抗审查揪出 trust_level 陷阱，9 步收敛到 iCloud，附 30 秒回滚方案。"
---


## 0. 差点翻车那一刻

装完 Codex CLI 第二天，我就意识到一件事：两个 CLI 要同时伺候。改一条通用规则，得去 `~/.claude/rules/` 改一遍，再去 `~/.codex/rules/global/` 改一遍；引用资料 `~/.claude/refs/` 是一份，`~/.codex/` 里没有。多 CLI 协作的甜头还没尝到，维护账单先交了。

我的第一版方案很激进：rules / refs / skills 全部合并到 iCloud 单一源，一把收齐。理由也足够顺——反正 Claude 侧的 rules / refs 已经软链到 iCloud，再把 Codex 那边也拽过来，天下大同。

真正救我一命的是下一步。高风险改动我有个硬习惯：动手之前先做两轮自检——先让 Codex MCP（Codex CLI 暴露给外部程序的调用协议，可以在 Claude Code 里直接喊它做只读评审）做一次对抗审查找翻车点，再在本机跑一遍 Phase 0 前置校验，把预警挨个变成可验证的事实。这一审一校下来，Codex 精准预警了 3 个会炸的点，其中一个在 Phase 0 里真的兑现了。没这两步，今天你看到的是一篇翻车记，而不是这篇。

本文先讲方法论，再讲配置。读完你会拿到三个问题的答案：

1. 对抗审查到底发现了什么，让我从激进方案掉头？
2. Phase 0 校验为什么能实锤预警，而不是摆样子？
3. 保守方案省了什么、欠了什么，什么时候升级？

## 1. 地形：两个 CLI 的配置全景

Claude Code 和 Codex CLI 在目录结构上形神都不一样。动手前，先把 9 个维度拉开看。

```
~/.claude/                              ~/.codex/
├── CLAUDE.md   → iCloud              ├── AGENTS.md              (实体)
├── rules       → iCloud              ├── rules/
├── refs        → iCloud              │   ├── default.rules      34KB 私有格式
├── projects    → iCloud              │   └── global/            7 个 md
├── agents/     24 个 gsd-*.md        ├── skills → App/agent-skill
├── commands/   4 个 slash            ├── prompts/    4 个
├── hooks/      11 个脚本             ├── hooks/      3 个
└── settings.json, plugins/           └── config.toml

# Skills 三源并存（同一份技能库的三个副本，内容不完全重叠）
~/.agents/skills           Codex 主源
~/.codex/skills    → App/agent-skill 间接副本
iCloud/claude-sync/skills  Claude 主源
```

Claude 侧的 CLAUDE.md / rules / refs / projects 已经整体软链到 iCloud 的 `claude-sync/`（中间经一层本地替身跳转，目的地相同，不影响结论）。Codex 侧除了 `~/.codex/skills → App/agent-skill` 这一条软链，其余全是实体目录。Skills 这一块是三源并存的典型翻车区，后面 §2.1 会专门讲。

这时候有 4 条硬约束，后面决策会反复引用：

- **入口文件名不同**：`CLAUDE.md` vs `AGENTS.md`，不可整文件共享
- **Codex 对 symlink 支持不稳**：GitHub issues #11314 / #16452 / #17344 / #15149 在册
- **iCloud "Optimize Mac Storage" 风险**：冷文件可能被替换成 `.icloud` 占位
- **Codex `trust_level` 标记**：未标 `trusted` 的路径，规则存在被拦截风险

4 条约束里，前 3 条是外部事实，第 4 条是后面 Phase 0 实锤的关键。

## 2. 对抗审查让我掉头的三件事

我把激进版草稿扔给 Codex MCP（GPT-5.4、reasoning high、read-only 沙箱），让它以"找翻车点"的心态审一遍。回来的报告里有 3 个预警，每一个都直接改写了方案。

### 2.1 预警一：Skills 三源合并会把已有的 symlink 错误放大

Codex 预警说得很直白：`~/.agents/skills` 有 47 个、`App/agent-skill` 有 37 个、iCloud skills 有 123 个（以上为 2026-04-20 本机快照，顶层目录计数口径，不同日期会有漂移），对抗审查抽样显示同名 skill 内容并不完全一致。合并就是冲突清洗苦力，做完还得盯着。

这条预警的实锤证据，藏在本机的 Codex TUI（Codex CLI 终端界面）日志里：

```
$ grep "failed to stat" ~/.codex/log/codex-tui.log
2026-04-15T05:51:16.113564Z ERROR codex_core_skills::loader: failed to stat skills entry /Users/cookie/App/agent-skill/x-tracker (symlink): No such file or directory (os error 2)
2026-04-16T02:05:04.623223Z ERROR thread_spawn{otel.name="thread_spawn"}: codex_core_skills::loader: failed to stat skills entry /Users/cookie/App/agent-skill/x-tracker (symlink): No such file or directory (os error 2)
2026-04-16T02:05:05.880950Z ERROR codex_core_skills::loader: failed to stat skills entry /Users/cookie/App/agent-skill/x-tracker (symlink): No such file or directory (os error 2)
```

注意这是**加载现有 skills** 就已经在报的错（`stat` 是文件系统查询文件元信息的系统调用，失败意味着 Codex 的 skills 加载器根本找不到软链指向的目标）。还没合并，symlink 已经站不稳。如果再把 iCloud 的全部 skills 也软链进来，错误量只会成倍膨胀，每次启动 Codex 都要等加载器跑一轮无效查询。

决策落地：skills 这条分支整个砍掉，不合并。

### 2.2 预警二：`.system/` 是 Codex 私有运行时

Codex 预警指出，`App/agent-skill/.system/` 是 OpenAI 的内置系统 skills，属于 Codex 私有运行时产物，不在用户契约内。`.codex-system-skills.marker` 这类识别标记也是非官方约定，下次 OpenAI 升级时完全可能被整块重写。

同类的还有 `codex-primary-runtime/`。这些目录共同的特征是：**它不是给你配置的，是 Codex 自己用的**。

结论：这块地面不动。哪怕激进版的 skills 合并做成了，升级来一刀也白搭。

### 2.3 预警三：`trust_level` 可能让软链规则存在被拦截风险

Codex 建议我去翻 `~/.codex/config.toml`，确认 `claude-sync/rules` 路径是否标了 `trust_level`。当时我没当回事——Claude 侧的 `rules` 软链到 iCloud 跑了几个月，从没提过信任等级。

这条预警真正兑现是在下一章 Phase 0。先把悬念留到 §3。

### 2.4 顺手做的一次社区搜索

走完 Codex 预警，我又用 Grok 做了一次线索性搜索："社区共享 CLI 配置的常见做法"。Grok 返给我的信号：社区常见做法之一，是 Git 仓库 + symlink 的 dotfiles 模式——dotfiles 指 `~/` 下以 `.` 开头的配置文件集合，老派程序员通常把这堆配置版本化管理。这条路线本身在 Reddit dotfiles 圈和 chezmoi / stow（两种主流的 dotfiles 管理工具，前者偏模板化、后者偏软链管理）项目里都能看到原始讨论。

这信号不决定方向，只提醒我回头再问一遍：**既然社区不少人走 Git，我为什么仍选 iCloud？**

我把本机约束摊开列清楚：

- **单机场景**：不需要多机版本历史
- **Claude 侧已把单一源落在 iCloud**：最小迁移成本，零额外同步动作
- **Git 要多一步 `pull`**：引入新的手动同步债
- **stow / chezmoi 偏模板化 + 多机分发**：这不是当前问题

所以我给 iCloud 方案划了一条升级触发线：**一旦 iCloud 出现 `.icloud` 占位导致 CLI 读空，立即迁 Git**。这不是"没选 Git"，是"Git 不是当前问题的最优解"。

走完这三件事，方案收敛到 4 条设计原则：**单一来源、运行时隔离、CLI 私有格式不动、可回滚**。整个激进版的野心被砍掉一半，但留下来的部分每一条都有证据。

## 3. Phase 0：把对抗审查的预警落成实锤

Phase 0 不是仪式，是把 §2 的预警挨个变成能现场验证的事实。没 §2 的预警作地图，Phase 0 也不知道要查什么。

动手前我跑了 3 项现场校验：

```bash
ICLOUD="/Users/cookie/Library/Mobile Documents/com~apple~CloudDocs/claude-sync"
```

| 校验项 | 命令 | 本机结果 |
|---|---|---|
| iCloud 是否有 `.icloud` 占位 | `find "$ICLOUD" -name "*.icloud"` | 0 个，物化良好 |
| `~/.agents/skills` 实际存在 | `ls -la ~/.agents/skills` | 真目录（快照 47 个） |
| `trust_level` 标记 | `grep -A1 "claude-sync/rules" ~/.codex/config.toml` | **`untrusted`——红旗** |

symlink 历史错误那条，§2.1 已经用过，这里不重复计账；但日志里的历史记录是个"继续观察"信号，之后每次升级 Codex 版本都值得再 grep 一次。

真正的暗雷是第三项。`config.toml` 里 `claude-sync/rules` 明明白白标着 `trust_level = "untrusted"`。如果不改，后面软链建完、文件也能 `head` 出来，表面一切正常，但规则里的执行指令**存在被 Codex 信任等级拦截的风险**。

注意这里我用的是"存在被拦截风险"，不是"一定会失效"。我没拿到改前被拦截的对话 transcript 做反证，按证据强度只能说到这里。能做的是两件事：一是把 Step 1 就定成"改 `trust_level`"，二是在方案执行完后做一次行为验证（见 §4.3），反推修复后确实生效。

**Phase 0 的价值不在查到了什么，在它把"直觉上没问题"和"经过检查没问题"分开**。`trust_level = "untrusted"` 不是 Phase 0 自己发现的，是 §2 对抗审查给了线索；但如果没 Phase 0 这一轮实锤，方案文档里就只能写"Codex 说可能有风险"，执行起来轻重不分。

## 4. 9 步执行的三个决胜点

9 步里真正决定方案成败的是 3 步。剩下 6 步是常规动作，完整命令、issue 清单、配置对比表放 Blog 原文；公众号只展开这 3 个决胜点。

### 9 步总览

```
Step 1  改 Codex config.toml 的 trust_level        ← 决胜点 A
Step 2  备份 ~/.codex/rules/global
Step 3  拷 Codex 独有规则到 iCloud
Step 4  用 Codex 版覆盖 iCloud 同名规则（先备份）  ← 决胜点 B
Step 5  建立 ~/.codex/rules/global → iCloud 软链   ← 决胜点 B
Step 6  建立 ~/.codex/refs → iCloud 软链
Step 7  在 CLAUDE.md 加"按需加载规则"章节
Step 8  四项联通验证（head / ls / grep）
Step 9  Codex 行为验证：让规则真实生效            ← 决胜点 C
```

### 4.1 决胜点 A：Step 1 改 `trust_level`

这是对抗审查 → Phase 0 → 执行 三链条的终点。动作本身就一行：

```toml
# ~/.codex/config.toml
[projects."/Users/cookie/Library/Mobile Documents/com~apple~CloudDocs/claude-sync/rules"]
trust_level = "trusted"   # 原 untrusted
```

**为什么必须第一步**：软链可以后建，规则可以后拷，但 `trust_level` 不改，后面所有动作跑完，Codex 读规则时仍**存在被拦截风险**。这一步跳过，整套方案可能就是"文件能读但规则没生效"的假胜利。

### 4.2 决胜点 B：Step 4-5 规则归并方向

iCloud 已有 `discernment.md` 和 `skill-development.md`，Codex 侧同名规则是结构化增强版（触发条件 + 流程 + 控制三段）。合并方向上不能模棱两可：**Codex 版覆盖 iCloud 版**，但先备份。

```bash
# Step 2：mv 一步原子搬运 —— Codex 原规则目录整体备份
mv ~/.codex/rules/global ~/.codex/rules/global.bak-20260420

ICLOUD="/Users/cookie/Library/Mobile Documents/com~apple~CloudDocs/claude-sync/rules"

# 先备份 iCloud 原版
cp "$ICLOUD/discernment.md"       "$ICLOUD/discernment.md.bak-20260420"
cp "$ICLOUD/skill-development.md" "$ICLOUD/skill-development.md.bak-20260420"

# Codex 版覆盖 iCloud 同名规则
cp ~/.codex/rules/global.bak-20260420/discernment.md       "$ICLOUD/discernment.md"
cp ~/.codex/rules/global.bak-20260420/skill-development.md "$ICLOUD/skill-development.md"

# 建立软链
ln -s "$ICLOUD" ~/.codex/rules/global
```

**为什么"先备份再覆盖"不是废话**：`.bak-20260420` 是 §5 那 30 秒回滚能成立的唯一前置动作。如果 Codex 版覆盖后发现里面有坑，没这两个 `.bak` 文件，我只能去 Time Machine 捞。

### 4.3 决胜点 C：Step 9 行为验证

原方案写的是"启动 Codex，让它复述 `core-lessons.md` 第一条规则"。这个验证口径过不了关——它只证明文件路径可读，不证明规则被 Codex 加载进上下文并影响行为。

真正的行为验证长这样。我给 Codex 喂了一个应该命中 `memory-testing-uat.md`（UAT 分工规则）的真实任务：

> 请做一次 UAT 分工建议。场景：刚完成一个小型 Web 后台功能——后端 3 个新 REST 接口 + 1 张数据库表；前端新增 1 个页面；涉及数据迁移脚本（回填 10 万条历史数据）。请告诉我这次 UAT 的分工应该怎么拆 ...

Codex 回复第一句就是：

> 已触发并读取全局规则：`~/.codex/rules/global/memory-testing-uat.md`

这句是 Codex 自己在回复开头声明的，不是我改写——完整对话 transcript 见 Blog 原文。注意那条路径就是 Step 5 建的软链 `~/.codex/rules/global → iCloud/claude-sync/rules`：Codex 能透软链正确读到文件，软链有效。

接下来看内容。规则原文里有三句：

```
- 后端数据、接口、联调、可自动化验证部分，优先由 Codex 执行。
- UI 页面、视觉细节、交互体感等需要人眼判断的部分，默认交由用户确认。
- 需要用户确认的内容，用中文整理成清单、步骤或截图说明，降低沟通成本。
```

Codex 的回复里，这三句被**逐条复述并应用**——后端接口判给 Codex、前端视觉判给人工、用户确认部分整理成 13 行中文清单带"执行者 / 理由"两列。不是"按类似风格"，是原文复述 + 按规则格式输出。

这才是完整的"读取 → 声明遵循 → 按规则输出"行为链，**经实测验证生效**。

Step 9 如果只验证到"文件可读"，方案其实没过关——后面可能有第二个暗雷在等。把验证口径从"可读"提升到"生效"，是这次方案能真正收工的关键动作。

完整 9 步命令、Step 9 改前改后对话 transcript、issue 状态清单，**点击阅读原文查看**。公众号正文到此收束。

## 5. 30 秒回滚：安全网长什么样

```bash
# 删软链
rm ~/.codex/rules/global ~/.codex/refs

# 还原 Codex rules/global
mv ~/.codex/rules/global.bak-20260420 ~/.codex/rules/global

# 还原 iCloud 两个被覆盖的规则
ICLOUD="/Users/cookie/Library/Mobile Documents/com~apple~CloudDocs/claude-sync/rules"
mv "$ICLOUD/discernment.md.bak-20260420"       "$ICLOUD/discernment.md"
mv "$ICLOUD/skill-development.md.bak-20260420" "$ICLOUD/skill-development.md"

# 还原 trust_level（手工编辑 config.toml 改回 untrusted）
```

4 条命令、30 秒以内全部退回原状。

一个小细节：备份后缀我用 `.bak-20260420`（日期），不是 `.bak`。多轮迭代时按日期排序能精准定位"是哪一次备份"；`.bak` 这种无日期命名在连续做两次改动后基本等同于埋雷。

任何共享配置的改动，都应该能在两分钟内说清楚回滚路径。说不清就是给未来的自己埋雷。

## 6. 保守方案的账单：省了什么、欠了什么

激进版砍掉了一半，保守方案落地后，正面账和负面账都要摆出来。只讲省了什么的方案，说服力打一半的折。

### 6.1 省了什么

- **rules / refs 走 iCloud 单一源**：改一处两 CLI 同时生效，再不用两边同步
- **回滚锚点完整**：`global.bak-20260420` 和两个 iCloud `.bak` 都在
- **Codex `default.rules`（34KB 私有格式）未动**：下次 Codex 升级时该文件归 OpenAI 负责，和我无关

### 6.2 欠了什么

- **Skills 三源分叉照旧**：`~/.agents/skills` / `App/agent-skill` / iCloud skills 三套（快照数字见 §2.1），未来同名分叉要继续人工对齐，没一键合并
- **`AGENTS.md` 仍用 `~/.claude/refs/*.md` 做跨 CLI 引用**：Codex 入口文件引用的是 Claude 目录里的 refs 路径。这条属于后续优化项，改成 `~/.codex/refs/*.md` 更自洽（反正指向同一 iCloud 路径），但我暂时没动
- **iCloud Offload 风险一直挂着**：macOS "Optimize Mac Storage" 会把冷文件替换成 `.icloud` 占位以腾磁盘，需要手动对 `claude-sync` 文件夹右键"始终保留在此设备上"，不是一次性解决

### 6.3 什么时候从保守升到激进

升级触发条件我事先写死，省得下次头脑一热又跳回激进方案：

- **触发 A**：iCloud 出现 `.icloud` 占位导致 CLI 读空 → 立即迁 Git
- **触发 B**：Codex 官方修复 symlink 加载问题，且**release note 明确写出修复**、本机复测无 loader 报错 → 再考虑 skills 合并。注意 GitHub issue 关闭（closed / not planned / duplicate）都不等于已修复，别拿关闭状态当升级门槛
- **触发 C**：出现第二台机器或团队协作 → 迁 Git，换版本历史 + 多机同步

保守不是"我懒得合并"，是"在当前成本函数下合并不划算"。**明确写出升级触发条件，才叫工程决策**；否则就是拖延症套一层"保守"的壳。

## 7. 迁移框架：不用 iCloud 也能照搬

方案底盘不是 iCloud，是"对抗审查 + Phase 0 + 可回滚"这套流程。如果你用 Dropbox / Git / NFS，把下面这三步套进去就能复刻。

### 第一步：共享对象分类

| 类型 | 例子 | 处理 |
|------|------|------|
| 纯文本知识 | rules / refs / markdown memory | 适合单一源 |
| 运行时资产 | skills / hooks / agents / slash 命令 | 按 CLI 隔离 |
| CLI 私有配置 | `config.toml` / `settings.json` / `default.rules` | 不共享 |

三类混在一起是大多数激进方案翻车的起点。

### 第二步：运行时是否容忍 symlink

- **容忍**（如 Claude Code）→ symlink 方案可选
- **不稳定**（如 Codex CLI 0.121.0 历史日志有错误）→ 要么 `cp` 同步、要么接受偶发错误并保留回滚
- **不容忍** → 只能 `cp`

这一步通常被跳过，但决定了方案形态——不容忍 symlink 的工具直接否掉 iCloud / Dropbox 的单一源路线。

### 第三步：同步层选型

| 场景 | 推荐 | 理由 |
|------|------|------|
| 单机 + Apple 生态 | iCloud | 最小迁移、零额外同步动作 |
| 多机 + 需版本历史 | Git 仓库 + symlink | 版本、回滚、多机 |
| 强 dotfiles 模板化 | stow / chezmoi | 模板 + 多机分发 |
| 企业 NFS / 共享盘 | NFS + symlink | 组内共享，注意权限 |

载体可换，流程不变。回到开头那句：**对抗审查把我从激进方案里拽出来，Phase 0 把预警变成实锤，可回滚让所有动作都有退路**。换成 Dropbox 或 Git，这三件事照样做。

## 8. 小结

回到开头的三个问题：

- **对抗审查到底发现了什么？** 三件事：skills 合并会放大已在的 symlink 错误、`.system/` 是 Codex 私有运行时不能动、未标 `trusted` 的 `trust_level` 会让软链规则存在被拦截的风险。每一件都改写了激进方案。
- **Phase 0 校验为什么能实锤？** 因为它不是走流程，是把 §2 的预警挨个落到本机命令上。`trust_level = "untrusted"` 本机实锤这一下，是方案里最值钱的 30 秒。
- **保守方案账单长什么样？** 省掉了 skills 合并的爆炸半径和跨 CLI 维护债的一半，留下了三源分叉、AGENTS.md 跨引用、iCloud Offload 三笔账，对应 3 条升级触发条件。

对跨 CLI 配置真正值钱的三件事：

1. **Discernment 门禁**：高风险改动强制对抗审查，哪怕是"看似人畜无害"的配置整合
2. **Phase 0 实锤**：预警不是查完就完了，要在本机跑命令把每一条变成现场证据
3. **可回滚优先**：每一步留 `.bak-日期`，30 秒能退回

按你当前的场景取用：

- 同时用两个 CLI → 直接抄 §4 三个决胜点
- 只用一个 CLI → 把这三件事沉淀到工程习惯里
- 团队场景 → 跳 §7 迁移框架，走 Git 路径

完整 9 步命令、issue 清单、配置对比表、Step 9 完整对话 transcript 都在 Blog 原文。**点击阅读原文查看完整命令与对话 transcript**。

## 9. 参考资料

完整 Codex 官方文档 URL、symlink 相关 GitHub issue（#11314 / #16452 / #17344 / #15149）、Apple iCloud Drive "Optimize Mac Storage" 官方说明、社区 dotfiles 与 chezmoi / stow 项目的原始讨论链接，均收录在 Blog 原文。

---

## 相关阅读

- [Claude Code 会话卫生手册：5 种策略 + 3 问 5 选 1 决策卡片](/posts/claude-code-session-hygiene/) — 同属 Claude Code 工程化方法论，一个聊"会话怎么管"，一个聊"配置怎么合"。
- [Claude Code 安装后必做的 9 项设置](/posts/claude-code-essential-settings/) — 9 项设置打底，9 步收敛进阶；单 CLI 读者可先看前者再判断是否需要本文的双 CLI 方案。
- [GSD 工作流完整实战：从会话驱动到阶段化工程](/posts/gsd-workflow-practice/) — 本文反复提到的 Discernment 门禁，就是 GSD 工作流里的对抗审查环节，完整方法论见这篇。
