harness-template 是一个面向长时 Codex 实现工作的开源仓库模板。它把功能选择、上下文加载、验证证据、交接记录和提交纪律都放进仓库文件中,保证一次会话中断后,下一轮仍能从明确状态继续。
这个模板刻意保持轻量:核心价值不在应用脚手架,而在根目录协议文件和 agent 启动器。
- 用
AGENTS.md和CONTEXT-GATE.md固化每轮会话协议。 - 用
feature_list.json跟踪功能队列,并约束同一时间只有一个 active feature。 - 用
claude-progress.md记录已验证状态、会话日志、blocker 和重启路径。 - 提供 feature / dispatcher / coder / reviewer runner,并通过 agent provider 注册表选择执行后端。
- 为 runner 创建独立 Git worktree,并用
result.json把子 agent 的建议状态交回主工作树统一落库。 - 在
feature_list.json中支持dependsOnDAG 依赖,dispatcher 会选择所有依赖已 passing 的可运行任务。 - 支持 dispatcher 并发池和
--max-concurrency,同时优先处理可审核的pending_reviewreviewer 池。 - 对缺失依赖、blocked 依赖和循环依赖输出明确 blocker,受影响 feature 不会被自动启动。
- 通过
init.sh、pnpm test、pnpm build留下可运行验证证据。 - 通过
evaluator-rubric.md和clean-state-checklist.md做结束前自审。
| 路径 | 作用 |
|---|---|
AGENTS.md |
每轮会话的主工作协议。 |
CONTEXT-GATE.md |
渐进式上下文加载规则和硬约束。 |
feature_list.json |
功能队列、状态、优先级和 evidence。 |
claude-progress.md |
当前已验证状态、会话日志、风险和下一步。 |
agent.ts |
TypeScript 版 agent 启动器和 dispatcher。 |
agent-providers.ts |
TypeScript 版 provider 注册表和命令构建模块。 |
agent/ |
Python 版启动器实现。 |
.harness/ |
运行时生成的 preflight、上下文缓存、runner worktree 和 result JSON。 |
init.sh |
依赖同步和基础验证入口。 |
clean-state-checklist.md |
session 结束前的干净状态检查。 |
evaluator-rubric.md |
功能验收前的自评表。 |
src/, tests/ |
最小占位应用和 smoke tests。 |
- Node.js 和
pnpm。 - 当前可执行 provider 为 Codex CLI,默认可执行名为
codex;可通过--agent-bin指定路径。 - 如果使用 Python 启动器,需要 Python 3.11+。
当前仓库在 package.json 中声明使用 pnpm@10.28.2。
安装依赖并运行基础验证:
./init.sh单独运行测试:
pnpm test运行本地 e2e dry-run 验证:
pnpm e2e构建项目:
pnpm build查看 TypeScript 启动器生成的 prompt 和 provider 命令,但不真正启动 provider:
pnpm agent -- --task "Implement the next feature" --dry-run查看 dispatcher 的自动分派结果:
pnpm agent:dispatch -- --dry-run功能以 feature_list.json 为事实来源,常见状态流转如下:
not_started -> in_progress -> pending_review -> passing
如果当前功能无法继续,使用 blocked,并在 claude-progress.md 写清楚原因、证据和下一轮重启方式。
仓库协议要求同一时间只能有一个 active feature。修改生产代码或项目文档前,应先选择或登记本轮对应的 feature,并让状态与真实证据保持一致。
启动器会读取协议文件、运行 preflight、选择 feature 上下文、在 docs/plans 下写入执行计划,然后调用当前 agent provider。
V0.1 注册的 provider 为 codex、claude、openharness、kimi、gemini。当前只有 codex 支持执行,其余 provider 会以明确的 unsupported stub 失败。
常用命令:
pnpm agent -- --task "Add README usage docs"
pnpm agent:feature -- --task "Draft an atomic feature" --dry-run
pnpm agent:coder -- --feature F001 --task "Implement the selected feature"
pnpm agent:reviewer -- --feature F001
pnpm agent:dispatch -- --dry-run
pnpm agent:dispatch -- --dry-run --max-concurrency 3
pnpm agent:loop -- --max-loop-iterations 3常用参数:
| 参数 | 说明 |
|---|---|
--feature, -f |
指定 feature id。 |
--task, -t |
指定本轮任务。 |
--runner |
选择 feature、coder、reviewer 或 dispatcher。 |
--layer2-ref |
额外加载一份 Layer 2 上下文文档。 |
--skip-init |
跳过 ./init.sh preflight。 |
--dry-run |
只写 plan 并打印 provider 命令,不启动 provider。 |
--max-concurrency |
dispatcher 每轮最多启动的 feature 数,默认 2。 |
--loop |
dispatcher 持续调度,直到没有可运行任务、遇到 blocker 或达到 guard。 |
--loop-delay-ms |
dispatcher loop 每轮之间的等待毫秒数。 |
--max-loop-iterations |
dispatcher loop 最大迭代次数;0 表示不设上限。 |
--continue, -c |
继续最近一次 provider session。 |
--resume, -r |
继续指定 provider session。 |
--agent-provider |
指定 provider,默认 codex。 |
--agent-bin |
指定 provider 可执行文件。 |
--codex-bin |
Codex provider 的 legacy alias;新用法应使用 --agent-bin。 |
Feature runner 用于登记新的 atomic feature。dry-run 会输出写入 docs/features、同步 feature_list.json、一致性检查、chore: 提交约束和前端设计源归档要求;实际写入时使用 --new-feature-id、--feature-title、--feature-priority,前端功能还需 --frontend-project --design-source <figma-or-file>。
Python 启动器也提供同样的工作流:
python3 -m agent --task "Implement the next feature" --dry-runCoder / reviewer runner 会在 .harness/worktrees/<run-id> 下创建独立 Git worktree。生成的 plan 会同步到该 worktree,provider 也在这个隔离目录中执行,避免多个 agent 共享同一个工作目录。
Runner worktree 不共享主工作树的 node_modules。这样 worktree 内的 ./init.sh / pnpm install 会按 lockfile 自己准备依赖,不会尝试重置主 checkout 的依赖目录。
子 agent 不直接落库 feature_list.json 状态或 claude-progress.md 最终进度,而是在 .harness/runs/<run-id>/result.json 写入建议状态、验证证据和 blocker 信息。agent.ts 校验 result JSON 后,把非 tracker 文件的 patch 应用回主工作树,再统一更新功能状态和进度日志。成功的 worktree 会清理;失败或 blocked 的 worktree 会保留用于排查。
Dispatcher 并发模式下,多个 runner worktree 可以同时执行 provider;所有 provider 成功返回后,主工作树会按 dispatcher pool 顺序串行汇总 result JSON、回放 patch、更新 tracker 和进度日志,避免多个 runner 同时写 feature_list.json 或 claude-progress.md。
feature_list.json 的 feature 可以声明 dependsOn:
{
"id": "HT-006",
"status": "not_started",
"dependsOn": ["HT-005"]
}dependsOn 缺省时按空数组处理。Dispatcher 会先检测依赖缺失、依赖 blocked 和循环依赖;有依赖 blocker 的 feature 不会进入执行池。
自动调度时,dispatcher 会优先选择依赖已满足的 pending_review feature 进入 reviewer 池;如果没有 reviewer work,则选择所有 not_started 且依赖已全部 passing 的 feature 进入 coder 池,并按 --max-concurrency 截断本轮并发数量。--dry-run 会按顺序打印 ready pool、依赖状态和计划路径,不创建永久 worktree;真实运行会并发启动这些 worktree,并在全部 provider 完成后串行落库。
每轮 session 从最少必要上下文开始:
- 用
pwd确认仓库根目录。 - 读取
CONTEXT-GATE.md。 - 用
git log --oneline -5查看最近提交。 - 运行
./init.sh。 - 读取
claude-progress.md中的当前已验证状态和最近一次 session。 - 只读取
feature_list.json中每个 feature 的{id, title, status, priority}。 - 只加载当前 feature 路由到的 Layer 2 文档。
- 检查基础 smoke path 是否仍然可用。
这个流程用于避免一次性加载过多无关上下文,也避免在没有验证证据时把功能标记为完成。
完成功能前,运行任务要求的检查和仓库结束门槛。通常至少包括:
pnpm test
pnpm e2e
pnpm buildGitHub Actions 会在 push 和 pull request 上运行 .github/workflows/e2e.yml。该 workflow 复用本地 pnpm e2e 脚本,覆盖默认 Codex provider dry-run、显式 Codex provider dry-run 和 feature agent dry-run,不依赖 Playwright、Docker 服务或外部 API。
结束 session 前:
- 更新
claude-progress.md,记录改了什么、为什么、验证输出、风险和下一步。 - 更新
feature_list.json的 status 和 evidence。 - 读取并应用
evaluator-rubric.md。 - 读取并应用
clean-state-checklist.md。 pnpm build通过后提交;如果pnpm test失败,仍可提交,但必须在 commit message 和进度日志中注明。
- 让
AGENTS.md和CONTEXT-GATE.md保持简短、明确、权威。 - 只为项目真正需要的主题增加 Layer 2 文档。
- 把
feature_list.json和claude-progress.md当作跨会话连续性的事实来源。 - 不要通过删除测试、削弱验证或改写清单来制造“完成”的假象。