Repository navigation
v0.3.1
v0.3.1 发布说明(取证)
版本:
0.3.1(patch)
基线:v0.3.0→HEAD,12 笔提交 / 18 个文件 / +1540 −24 行(git log v0.3.0..HEAD生成)
主题:确认单上的「改 PRD」做成闭环 —— 改写绑定版本、在原 child 上下文里续跑、用量准确、批准语义收紧。
本文件是取证与论证;结论层见CHANGELOG.md。
1. 为什么做这一版
v0.3.0 把「确认单必须由人批准」这道闸门立起来了,但用户提出「要改」时,链路还是断的:
- 改完 PRD,上一版的批准没有失效 ⇒ 改过的 PRD 从未被批准却直接开工(issue #11,用户截图实证);
- 修成「重出确认单」后加了次数上限(2 次)⇒ 第 3 次直接拒绝,用户只能重开 run、白丢已跑的 PRD;
- 改写实现是重跑整个 PRD 子代理(新 spawn、从零读需求)⇒ 又贵又漂移:用户只要求改一处,
没提的部分也可能被顺手改写; - 放开次数后又发现:
confirmApprovedRev被模型自己写死 ⇒ PRD 永久改不动。
本版把这条链路补完整,并用真机逐环验通。
2. 变更清单(按 git 对比,逐笔归属)
| 提交 | 类型 | 内容 |
|---|---|---|
90012eb |
fix | 确认单绑 PRD 版本:改写后批准失效、必须重出单(当时含次数上限) |
c831b07 |
fix | 去掉次数上限,改为「版本号 + 上一版快照」 |
ba628a5 |
feat | 改写走 continuable 续跑(prd-revise.ts),失败回落重跑 |
ad617c0 |
fix | 批准语义:无 supplement 的 resume 必须有显式批准;记账加严 |
5ca24d9 |
fix | prdChildId 必须在摘阶段记录之前取;回落出口全部可见 |
ccd7bb0 |
fix | 续跑等待 180s→300s;回落原因拆成三条可区分诊断 |
f8988ed |
fix | 快照路径:runDocs 是相对路径,必须拼工作区 |
e93859b |
fix | 快照从任务夹移到 logs/teamflow/<runId>/(不进交付物) |
7daa91d |
fix | 阶段用量必须累计(改写多轮时前几轮 token 不能消失) |
2c5a933 |
fix | 修用量精确翻倍(prdUsageAcc 与 stage.usage 同引用 ⇒ addUsage(a,a)) |
22aa418 |
chore | 用量逐轮留痕 + 重复护栏 |
edde46e |
docs | ADR-0011 追加「快照=机器可查的落实证据」 |
3. 真机取证
工具链:dsh --profile web,插件经 deploy.mjs --sync 同步(50 文件),每条 run 均重启宿主后执行。
3.1 改写闭环(hy3)
| run | 轮数 | 结果 |
|---|---|---|
tf-mvchuuvf-j7kmzk |
5 版 | 第 4/5 版走续跑;第 5 版正确删除 --depth、保留 children 与 stdout/stderr |
tf-mvcl5m8t-0qhl8y |
5 版 | 同上;第 3 版曾因 180s 超时回落(后提到 300s) |
tf-mvdeqi60-p48r0f |
4 版 | 每版都命中续跑、零回落 |
tf-mvdhxn6h-87vnog |
3 版 | 11 条 AC 逐条对上两次要求;旧结构字段只出现在说明性语境 |
上下文累积的直接证据:PRD.v1 → v2 → PRD.md 的特征计数
(--depth 0→16、children 0→11),证明第 1 轮加参数、第 2 轮改 JSON 结构的落地情况。
3.2 续跑 vs 重跑的成本(同一子代理、按 turn 统计)
| 路由 | 轮次 | 每轮新算 input | cacheRead | 耗时 |
|---|---|---|---|---|
workbuddy/hy3 |
重跑 / 续跑 ×2 | 217,782 / 203,350 / 231,713 | 27,904 / 7,744 / 2,368 | 122s / 116s / 163s |
deepseek-account/deepseek-flash |
首版 / 续跑 ×3 | 16,168 / 14,072 / 17,877 / 18,687 | 278k → 1.47M(累计) | — / 84s / 78s |
结论:续跑的技术收益(同上下文、不漂移)与路由无关;成本收益取决于路由是否做 prompt 缓存——
真机 workbuddy/hy3 三轮 request/header 前缀 40,790 字节逐字节相同(仅末字段 initial→resume),
但 cacheWrite 恒为 0 ⇒ 服务端没做自动缓存;deepseek-flash 有 ⇒ 每轮新算降到 1.5 万量级。
判据沉淀:看
cacheWrite是否恒 0,别只看 cacheRead(cacheRead 低可能只是前缀变了)。
3.3 批准闸门(双向)
| 方向 | run | 证据 |
|---|---|---|
| 拦得住代批 | tf-mvdhxn6h-87vnog |
暂停后零人类消息 ⇒ 续跑被拒:确认单必须由用户本人批准 |
| 放得行真批准 | tf-mvdixrhs-asht1p |
用户「批准,开始吧」⇒ 放行、approvedRev == prdRev、进技术方案 |
3.4 用量(修复前后)
| journal | 子会话实际 | 结论 | |
|---|---|---|---|
修复前(tf-mvdeqi60) |
in 2,419,276 | in 1,209,638 | 精确 2 倍 |
修复后(tf-mvdhxn6h) |
in 608,144 | in 608,144 | 逐项一致 |
逐轮日志(修复后):144,949 → +260,198 = 405,147 → +202,997 = 608,144,算术正确。
4. 门禁与变异
| 新增/更新门禁 | 覆盖 |
|---|---|
test/prd-revise.test.js(38 条) |
取文本字段名、offset 切分、turn/end 结束判据、六种失败全部回落、读不到基线不投递 |
test/human-approval.test.js §5/§6 |
批准词真值表、否定优先、修改词、AUQ 答案解析、以最后一条为准、三态 |
test/orchestration.test.js |
续跑不 spawn、对原 child 投递、快照落 logs、用量累计、批准拒绝/放行 |
test/metering.test.js |
addUsage 真值表(含真机那组数) |
test/smoke.js §11/§12 |
续跑接线、回落可见性、快照落点、累计与护栏的源码锁 |
变异(每次只有一个维度被破坏,期望只有新断言变红):
| 变异 | 结果 |
|---|---|
| 禁用续跑 | orchestration 6 红 |
| 关掉显式批准闸门 | orchestration 2 红 + smoke 1 红 |
| 去掉「修改词」判定 | human-approval 2 红(第一版夹具没区分力,补「批准,但把 X 改成 Y」后才有牙) |
| usage 忽略 offset | prd-revise 1 红(夹具同样需要第一轮带 usage 才有区分力) |
夹具必须先证明它能区分正确实现与错误实现,否则测的是寂寞。
5. 已知未验
- 桌面版(宿主
0.2.0-rc.2):本插件 0.3.x 要求宿主 ≥0.2.1-alpha.2,桌面侧需等上游发版。
已 grep 确认2c5a933之前的续跑所需 API(sendMessage/observeSession/prepareContinuable)
在 rc.2 中也存在,但startActivation不存在 ⇒ 桌面目前跑不了 0.3.x。 - 重复护栏(
log.usageAccumDup)从未触发:修复后不再需要它,保留作保险,属于死路径。 - 超 5 轮改写未验:上下文会被 compaction 裁剪(窗口 192k),早期内容存在被挤掉的风险。
缓解手段是快照(文件不丢),但没有量化验证。
6. 升级指引
- 无
engines变化,无 schema / journal / 任务夹契约变更。 - 升级后必须重启
dsh --profile web(桌面版重启应用)——插件是构建产物lib/host.mjs,
进程不重启则仍加载旧代码(本版排查中曾因此误判过一次"修复无效")。 - 想验证改写是否走了续跑:看日志里
PRD 改写走**续跑**;出现回落为重跑会写明是哪一类原因。