# cc-web Codex hooks 验证发现

## Initial Position

当前需验证的核心边界：

- Codex hooks 官方上属于 Codex/app-server 的生命周期能力。
- cc-web 作为平台客户端，理论上不应硬编码执行某个 skill 的 hooks。
- 需要分别验证官方文档、cc-web 实现、本地环境三个层面，避免把“配置发现”“运行时注入”“技能行为”混成一个问题。

## Findings

### 官方文档背景线程

- Codex hooks 默认开启，可用 `[features] hooks = false` 关闭。
- hooks 从 active config layers 旁边的 `hooks.json` 或 `config.toml` 内联 `[hooks]` 发现。
- 常见位置包括 `~/.codex/hooks.json`、`~/.codex/config.toml`、`<repo>/.codex/hooks.json`、`<repo>/.codex/config.toml`。
- 项目级 hooks 依赖项目 `.codex/` layer trust；未信任项目时仍可加载用户/系统 hooks。
- 非 managed command hooks 需要 review/trust；定义变化后按 hash 重新 review。
- 未找到官方文档支持 `thread/start.config.hooks.*` 作为运行时 hooks 注入机制。
- `externalAgentConfig/import` 的 `HOOKS` 是 external-agent artifacts 迁移导入，不是每轮运行时 hook 注入。

### 六项断点阶段结论

- 断点 1 `CODEX_HOME/HOME`：当前 local 模式下通。运行中 app-server 看到 `HOME=/home/hdzx`，`CODEX_HOME` 未设置，能按默认读取 `/home/hdzx/.codex`。custom 模式会把 `CODEX_HOME` 指向 `config/codex-runtime-home`，但当前未启用。
- 断点 2 `thread cwd`：通。目标会话 `00a7cbc2-d0c3-457f-a262-aa5a5859fa54` 的 `cwd=/home/cc-web`；`thread/start` 和 `thread/resume` 都使用同一个 `threadParams.cwd`。
- 断点 3 项目 `.codex` trust：通。`/home/hdzx/.codex/config.toml` 存在 `[projects."/home/cc-web"] trust_level = "trusted"`。
- 断点 5 `[features].hooks`：未发现关闭。用户级和项目级配置、cc-web thread config、app-server 启动参数均未发现 `hooks = false`。
- 断点 4 command hook review/trust：不通。app-server 只读 `hooks/list` 返回当前 `/home/cc-web/.codex/hooks.json` 的 7 条 command hook 全部 `trustStatus: "untrusted"`。
- 断点 6 marker hook：不再需要作为前置验证。既然 `hooks/list` 已确认 command hooks 未 trust，按官方语义这些非 managed command hooks 会被跳过；marker 只有在 trust 后仍不触发时才需要。

### Command Hook Trust 明细

当前项目 7 条 hook 均来自 `/home/cc-web/.codex/hooks.json`，均 `enabled: true`、`source: project`，但均 `trustStatus: "untrusted"`：

- `preToolUse`: `sha256:a3f36079079ee92b6d39f0ca263b0d23fadafdd4bd2eae8ef3982af4e446fd8b`
- `permissionRequest`: `sha256:db03c3a6c225bdb10010a5b2101d8fcb986d1ee5b2838746d8f003e952d2d08e`
- `postToolUse`: `sha256:7e6a12765c74be11e44fcfcb8f4e6534f138913fc76c539993f62b6e03da6e7a`
- `preCompact`: `sha256:73ec586017f031e8b216256e2eab41a7de8b45395643ce4461c76f212ad9a0ca`
- `sessionStart`: `sha256:b7e002f1913670e919eb42947a8b5dd7c5a9b448b07d1b0aa86bcded841109c0`
- `userPromptSubmit`: `sha256:cd4a71b110e2fdeae8eb47b47bae3e4786baa20b841f35032267cf6914567409`
- `stop`: `sha256:cd543e4852e7bc63704908c599ba9cf0bfc6662b7bd8fe2fea7738cd59d641b7`

### cc-web Codex App 接入链路线程

- 当前 `local` 模式下，cc-web 不主动阻断 Codex App hooks 加载：app-server 继承 `process.env`，不剥离 `HOME` / `CODEX_HOME`；`thread/start` 和 `thread/resume` 都传入会话 `cwd`。
- `codexAppThreadConfig()` 当前只组装 `mcp_servers.*`，没有 hooks/trust 注入；这符合“不走未文档化 `thread/start.config.hooks.*` 主路径”的判断。
- 当前本机 `config/codex.json` 为 `mode: "local"`，所以 `custom` 模式的 `CODEX_HOME` 隔离风险未激活。
- 风险：`custom` 模式会将 `CODEX_HOME` 指到 `config/codex-runtime-home`，该目录目前只写认证/model provider 配置，不复制 hooks 配置；如果用户级 hooks 依赖 `~/.codex/hooks.json`，custom 模式可能导致用户级 hooks 不加载。
- cc-web 当前没有 Codex App hooks/trust 诊断 UI 或日志；已有日志能看到 app-server 初始化、collaborationMode、MCP startup，但不能直接展示 hook 是否发现、是否跳过、trustStatus 是什么。
- 建议：增加只读 hooks 诊断能力，展示 app-server `hooks/list` 的 source/sourcePath/currentHash/trustStatus；custom 模式增加 `CODEX_HOME` 隔离提示或继承策略。

### hapi 对齐线程

- hapi 的 app-server 路径主要依赖 JSON-RPC 事件流、`thread/start.config["mcp_servers.hapi"]` 和 `turn/start.collaborationMode`，未看到 app-server 路径主动注入 hooks。
- hapi 的 hooks 主要用于本地 Codex CLI 路径，通过 `-c hooks.SessionStart=...` 做 transcript/session 发现；这不是 app-server `thread/start.config.hooks.*` 机制。
- hapi 因此不能作为“cc-web 应该把 hooks 注入 thread/start”的证据；它反而支持：MCP 走 `thread/start.config.mcp_servers.*`，hooks 不走未文档化的 runtime 注入。
- hapi 也不能推翻官方 hooks 机制或本机 app-server `hooks/list` 结果；它只能说明 hapi 当前产品路径没有依赖 app-server hooks。
- 对 cc-web 的结论应拆开：
  - 运行 hooks 的主权仍属于 Codex/app-server 原生 hooks 机制。
  - cc-web 不应模拟执行 hooks，也不应发明 `thread/start.config.hooks.*` 主路径。
  - cc-web 应补的是诊断/信任入口：展示 app-server `hooks/list` 的 trust 状态，并引导用户 review/trust。

### 本地 planning-with-files hooks 条件线程

- 本地 `planning-with-files` 脚本和配置本身可用：`.codex/hooks.json` 配置了 `SessionStart`、`UserPromptSubmit`、`PreToolUse`、`PermissionRequest`、`PostToolUse`、`PreCompact`、`Stop`。
- 当前项目根存在 `task_plan.md`、`findings.md`、`progress.md`，因此当前时刻满足 root active plan 条件；但这些文件是本轮验证中新建的，不能倒推出目标会话发生时也存在 active plan。
- 手动 smoke test 通过：`sh .codex/hooks/user-prompt-submit.sh` 能输出 `[planning-with-files] ACTIVE PLAN`；`pre_tool_use.py` / `post_tool_use.py` adapter 能输出预期 JSON 或 progress 提醒。
- 无 active plan 时 hook 会静默；`.planning/sessions/` 存在但当前 session 未 attached 时也会静默。
- 多数 `.sh` hook 脚本没有 `+x`，但 `.codex/hooks.json` 使用 `sh script` / `python3 script` 调用，因此执行位不是当前阻断点。
- 与断点 4 合并后的结论：本地脚本没坏，当前阻断点在 Codex command hook trust，7 条项目 command hook 均为 `untrusted`，所以正常 app-server 路径会跳过它们。
- marker 方案仍可用于 trust 后二次验证；但在 hooks 未 trust 前，marker 不出现只能证明 trust 拦截，不再是定位根因的必要步骤。
