codex-plan-ledger

Codex /plan 的决策账本

代码写完,一条命令看出哪些改动超出了计划。

Codex 和你定好了计划。plan-ledger check 列出计划没提到却被改的文件;每项决策都以 decisions.json 的 diff 留在 PR 里。

hook 和 check 的输出是在仓库样例上真实运行所得;Codex 窗口按样例会话记录重绘,代码改动由脚本写入。
  • 查范围偏离。列出计划没提到却被改的文件,以及计划要改却没碰的文件。3 次埋点测试里:计划外文件 3/3 抓到,该改未改 3/3 抓到,干净时 3/3 无误报。
  • 决策进 PR。Codex 问过你的问题、计划里的待定项和默认做法写进 decisions.json,评审能看到选了什么、为什么。
  • 不打断会话。作为 Codex Stop hook 运行:不额外调用模型、不联网、从不等待。
npm i -g github:miniLV/codex-plan-ledger && plan-ledger init --write

早期原型 · v0.1 实测 3 对任务里,来回轮数没有变少(输 2、平 1)。检查只看文件列表、不读代码:计划内文件里与决策相反的改动 0/3 抓到。详情

为什么需要它

  1. 让 Codex 先计划再写代码时,它可能顺手改了你没同意过的文件。
  2. plan-ledger 在定计划时把你们商定的内容记下来(仓库里的 decisions.json)。
  3. 代码写完后,它拿改动文件对照这份记录,告诉你哪些超出了计划。它只比对文件列表,不读代码。

工作原理

时序图从上往下读:实线是调用或写入,虚线是返回,橙色是 plan-ledger 做的事。Codex 原生 Plan 模式照常用,提问仍在 Codex 里答。渲染不调用模型。

UML 时序图:开发者在 Codex /plan 里回答提问;本轮结束时 Stop hook 把问答、待定项、默认值和范围写入仓库里的 decisions.json;Codex 写代码,可能改到计划没提过的文件;plan-ledger check 读取 decisions.json 和 git diff,报出 DRIFT: src/utils/analytics.ts;PR 里带着代码和 decisions.json,评审看到每个选择和原因。
源文件:diagrams/how-it-works-zh.html,画法参考 sketchboard-diagram。
  1. Stop hook 写入账本

    计划到达时解析并写 decisions.json 与离线 HTML,本轮正常结束。从不阻塞,从不等待。

  2. 一页复核

    待定、已答、默认分开展示;改完后复制回传 JSON,粘到 Codex 下一条消息。

  3. 决策进 PR

    账本与代码在同一个 PR 里 review:选了什么,为什么。

  4. 范围偏离检查

    plan-ledger check --base main 对照改动文件与计划范围。

决策放在一页里复核

每项一张卡片:选项、推荐、默认、影响的文件。Codex 里已答的会标出;计划默认可改但不算待答。未答记为保留默认,不算同意。

  • 纯模板,不调用模型,不联网,单个文件。
  • hook 不等待。
  • 计划改版时沿用旧答,并标明是沿用的。
决策页截图:每项决策一张卡片,有选项、推荐标记、默认值和影响的文件,底部是生成回传 JSON 的按钮。
无头 Chrome 截取;内容来自仓库合成样例 fixture。

决策进 PR

账本是和代码放在一起的普通 JSON 文件。评审在同一个 diff 里看到计划范围、Codex 问过的问题和你的回答。

PR 里新增的 decisions.json:计划范围列出的文件,以及 Codex 问过的问题,记为 source codex-native、chosen a、status answered。
同一次运行里 plan-ledger hook-stop 写出的 decisions.json。节选,折叠的行已标出。

演示

这就是 hook 写出的页面,内容来自仓库自带的合成样例计划(test/fixtures/send-later.message.md),外加一个合成的“已在 Codex 里回答”的问题。选几个选项,再点底部按钮。所有操作只在你的浏览器里。

docs/plans/demo-send-later-for-drafts/plan.html

在新标签页打开演示 · 介绍视频(MP4)

范围偏离检查

对照 git diff 与各决策的 affected 文件、计划正文提到的文件,报出计划外文件与没碰到的决策。加 --strict 时有偏离就退出码 1,可用于 CI 或 pre-commit。

已知局限

只比对文件,不读计划内文件的代码内容。文件内与决策相反的实现,当前抓不到。所以叫“范围偏离检查”,不叫决策合规检查。

终端:git status 列出 5 个改动文件;plan-ledger check --base main 对计划没提到的 src/utils/analytics.ts 报出 DRIFT。
真实输出:在仓库样例生成的临时仓库上运行(路径显示为 ~/mail-app)。

现状与实测

注意

方向性数据,两轮共 n = 3 对,不是效果证据。轮数上一对都没赢(输 2、平 1)。不以省轮次为目标。

每对是同一任务上原生 Plan 与 plan-ledger 各跑 1 次,任务在 vercel/ms@2.1.3,同一模型与设置(codex-cli 0.156.0,medium)。第 2 轮换了更省的运行配置(两组相同),token 只能在同一轮内比较。
轮 / 任务定稿前轮数
原生 / plan-ledger
计划阶段 input token
原生 / plan-ledger
总 token
原生 / plan-ledger
验收
1 / strict-option1 / 2294,933 / 372,651717,487 / 586,971都通过
2 / strict-option1 / 265,931 / 83,141180,208 / 205,644都通过
2 / month-unit1 / 179,553 / 66,354179,053 / 140,020都通过

范围偏离检查(3 次 plan-ledger 运行,实现后埋入):干净树无误报 3/3;计划外新文件 3/3 抓到;该改未改 3/3 抓到;在计划内文件写与决策相反的代码 0/3 抓到,与已知局限一致。

第 1 轮 · 第 2 轮 · 实测计划