73 lines
6.7 KiB
Markdown
73 lines
6.7 KiB
Markdown
# 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 拦截,不再是定位根因的必要步骤。
|