host: fill second-class gaps (merge verify, deps, review comments, reconnect, budget, notify, state version)

This commit is contained in:
host committed 2026-10-26 00:48:27 +08:00
1 parent ed55c9651a
commit e9735d1fad
4 files changed
+935 -69

No files matched your search

+65 -1
View File
@@ -210,7 +210,6 @@ tests/ 标准库 unittest,验收命令就是 `python3 -m unittest discover -s
不常驻。
## 真实项目一轮(2026-10-26 凌晨,用户选“先在真实项目上跑一轮再打包”)
- **选项目**:没动生产敏感的 wechat-bridge(带 session 凭证),
选 codex-app-server 本身做 dogfooding——这是真实代码,不是
玩具仓。为此先把本项目初始化成 git 仓(commit b49b9cf、
@@ -330,3 +329,68 @@ tests/ 标准库 unittest,验收命令就是 `python3 -m unittest discover -s
- 审批请求的完整回包字段:各版本间字段有差异,client.py 默认
用 never 绕开审批;on-request + auto/deny 的回包是尽力而为,
生产交互客户端应以本版 protocol schema 为准再对齐一次。
## 第二类缺口补齐(2026-10-26 凌晨,用户选“继续补齐第二类所有缺口”)
- **合并后自动验测 + 回滚**:merge_task 抽成可单测函数,
默认仓库有 tests/ 就跑 unittest,验测失败 reset 回合并前
HEAD,分支/worktree 保留,任务标 merge-failed 并走失败通知。
单测覆盖验测通过清 worktree、验测失败回滚主仓 intact。
- **任务依赖 + 优先级 + 重试**:jobs 里 depends_on/priority/
max_retries,topo_sort_jobs 拓扑排序(缺依赖/成环抛错),
parallel 按波次跑,依赖失败时依赖任务标 skipped 且落盘
(修过一次 skipped 未落盘导致 discard KeyError 的 bug)。
依赖任务现在从依赖分支建 worktree(dispatch_from_branch:
先把依赖 worktree 提交到依赖分支,再从该分支建新分支),
这样依赖分支是依赖任务分支的祖先,合并时不再重复加同一段。
重试:run_task_turn_with_retry,默认 0 次行为不变,配了
max_retries 时失败后同 prompt 再跑,重试前查预算。
- **评审评论回流**:review-comment --file --line --comment
存进任务,review 时列出 open 评论,fix-review 按 open
评论逐条修,修完标 resolved。模型实测:gap2-b 的
add2_mul2 docstring 评论,第一次 fix-review 因我给的
300 秒 shell 超时被杀(turn 本身没完成,评论正确地保持
open),第二次 900 秒超时下 51 秒完成并标 resolved。
- **server 崩溃重连**:Server 抽出 _start/ensure_alive,
进程死了重拉并 resume thread(thread 在 CODEX_HOME 里),
request 遇 BrokenPipe 重试一次。单测 kill 进程后重拉 +
list 能通。
- **成本预算 + 失败通知**:配置 max_daily_turns(按 turn 数,
协议不暴露真实 token 数,这是诚实边界),超预算不派发/
不重试;失败时写 host-run.log + 跑 notify_command(本地
shell,模板 {task} {status});failures 列失败任务,doctor
列 version/备份/失败/缺失 worktree/open 评论。模型实测:
不存在的模型 + max_retries=1,跑了 2 个 turn(retry_count=1,
均为 404),status failed,notify 日志里有 gap3-fail failed。
- **多机器 state 冲突**:state 加 version/last_writer/
updated_at,保存时磁盘版本比加载时新就记 STATE-CONFLICT
日志并合并保留双方任务。单测:磁盘版本被另一写者改到 5
后再保存,合并后版本 6,双方任务都在,日志里有冲突行。
诚实边界:这只是“检测 + 不丢”,不是 ChatGPT 云端那种
中心同步,两台机器共享一个 state 文件仍不推荐。
- **模型实测 gap2/gap3(依赖 + 合并,教训最多的一轮)**:
第一轮 gap(/tmp)因 VM 回收丢了 /tmp 里的 repo 和 state,
但 home 下的 worktree 还在,证明依赖拷贝已生效(gap-b 里
有 gap-a 的 add2 且未重复定义);第二轮 gap2(state 放
home)先因 codex_home 新建后没有中转站配置 401 失败两次,
靠失败通知和依赖 skipped 门正确地没浪费后续调用,修配置
(model_provider + [model_providers.xcmapi] 两部分都要有,
只给其一时要么走 api.openai.com 401,要么报 provider not found)
后第三轮并行全通:gap2-a(优先级 5)先跑,gap2-b 依赖它且
工作区里有 add2,gap2-c 独立;评审评论 + fix-review 通;
合并时暴露两个真问题:① 依赖任务文件拷贝法建的分支没有
血缘关系,合并依赖任务时在同一位置重复加 add2,-X ours
自动解会把 mul2 整段丢掉——幸好新增行核对把它拦下来回滚
了(这是安全网的价值,不是 bug);② merge 的 git add -A
会把 __pycache__/*.pyc 提交进主仓,下次合并被 .pyc 改动
挡住。① 用“从依赖分支建 worktree”修了,② 用“合并前清
worktree 的 __pycache__/*.pyc,主仓 .pyc 改动先还原”修了;
gap3 用新方法跑依赖对 + 合并全通(add2/mul2/add2_mul2,
测试通过,值 3/6/8),gap2 的遗留分支用手动取目标文件内容
的方式解完(主仓最终 add2/mul2/add2_mul2/sub2 全有,测试通过)。
独立任务在同一文件同一位置追加时仍会冲突,这是 git 本身
的行为,host 正确的做法是 abort/回滚 + 人工解,不是自动猜。
- **回归**:tests/test_host.py 从 3 个涨到 15 个,全部通过,
包括 topo 排序、merge 验测通过/失败回滚/重复加自动解/
pyc 不入库、评审评论、重试成功/预算拦截/通知落盘、
state 版本冲突、server kill 重拉。