@haiyangbg/buildbeat 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.en.md +4 -4
  3. package/README.md +1 -1
  4. package/SKILL.md +8 -5
  5. package/docs/README.md +3 -2
  6. package/docs/RELEASING.md +3 -1
  7. package/docs/v2/guide/01-quickstart.en.md +165 -0
  8. package/docs/v2/guide/01-quickstart.md +7 -3
  9. package/docs/v2/guide/02-workflow-guide.md +11 -0
  10. package/docs/v2/guide/06-evidence-guide.en.md +51 -0
  11. package/docs/v2/guide/06-evidence-guide.md +2 -0
  12. package/docs/v2/guide/07-approval-guide.en.md +117 -0
  13. package/docs/v2/guide/07-approval-guide.md +16 -2
  14. package/docs/v2/guide/10-recovery.en.md +99 -0
  15. package/docs/v2/guide/10-recovery.md +22 -4
  16. package/docs/v2/guide/README.md +4 -4
  17. package/example/.buildbeat/notify.yaml +13 -0
  18. package/example/.buildbeat/observe.yaml +31 -0
  19. package/example/AGENTS.md +73 -0
  20. package/example/BUILDBEAT.md +14 -0
  21. package/example/CLAUDE.md +7 -0
  22. package/example/README.md +25 -0
  23. package/example/delivery/envelope/prompts/builder.md +10 -0
  24. package/example/delivery/envelope/prompts/fixer.md +10 -0
  25. package/example/delivery/envelope/prompts/reviewer.md +13 -0
  26. package/example/delivery/envelope/worker.sh +70 -0
  27. package/example/delivery/work/WORK-EXPORT-DATE-FILTER/decisions.jsonl +3 -0
  28. package/example/delivery/work/WORK-EXPORT-DATE-FILTER/intent.md +24 -0
  29. package/example/delivery/work/WORK-EXPORT-DATE-FILTER/plan.md +20 -0
  30. package/example/delivery/work/WORK-EXPORT-DATE-FILTER/run-config.yaml +66 -0
  31. package/example/delivery/work/WORK-EXPORT-DATE-FILTER/runs/RUN-EXPORT-01/run-record.json +108 -0
  32. package/example/delivery/work/WORK-EXPORT-DATE-FILTER/workflow.yaml +44 -0
  33. package/example/gitignore.template +20 -0
  34. package/example/package.json +13 -0
  35. package/example/pm/decisions.md +8 -0
  36. package/example/src/export.js +25 -0
  37. package/example/src/ledger.js +16 -0
  38. package/example/tests/export.test.js +35 -0
  39. package/example//346/214/207/346/214/245/345/217/260.md +40 -0
  40. package/package.json +2 -1
  41. package/src/v2/cli/run-config-check.js +223 -0
  42. package/src/v2/cli/run.js +74 -14
  43. package/src/v2/engine/reducer.js +6 -0
  44. package/src/v2/engine/yaml-subset.js +44 -9
  45. package/src/v2/runtime/decisions.js +32 -30
  46. package/src/v2/runtime/gc.js +28 -3
  47. package/src/v2/runtime/orchestrator.js +223 -96
  48. package/src/v2/storage/event-ledger.js +22 -3
  49. package/src/v2/workspace/workspace-manager.js +182 -13
  50. package/templates/v2/run-config.example.yaml +3 -1
package/CHANGELOG.md CHANGED
@@ -2,8 +2,35 @@
2
2
 
3
3
  > 本项目吃自己的狗粮(红线④:必更 CHANGELOG)。格式循 Keep a Changelog,倒序。
4
4
 
5
+ ## v3.1.0 — 2026-09-26(运行时修复:预算误报、锁残留、台账并发、配置与 YAML 校验)
6
+
7
+ - YAML 子集解析器不再绊倒常见写法:空的 `[]` / `{}` 可用(非空行内集合仍拒绝,报错提示改成每项一行);列表项可与所属键同缩进;不带引号的 `- http://x` 按字符串解析,含 `": "` 且前半截不是合法键的项(如 `- echo a: b`)不猜、报错要求加引号;开头的 BOM 被忽略;`007` 这类前导零保留为字符串;「has no value」报错给出改法。修改前的解析器冻结在 `tests/support/yaml-subset-v1.js`,测试断言仓库内它能解析的每个 YAML 新旧结果完全一致;SKILL.md、快速上手(中英)与 run-config 样板同步。
8
+
9
+ - run-config 在做任何事之前整体校验并一次列出全部问题:必填键、未知顶层键与 worker / envelope 未知字段(给最接近的拼写)、类型与取值(`inheritEnv: yes` 不再静默当 false)、worker 名须被工作流用到、`stopAt` / `entry` 须是工作流步骤、`work` / `run` 的字符与类型(`run: 007` 要求加引号)。缺 `repo` 不再报 Node 内部错误 `paths[1]`。`start` / `resume` / `doctor` / `preflight` / `approve --config` 统一经由它;仓库内全部 run-config 有测试兜底兼容。Workflow 指南与恢复手册(中英)同步。
10
+
11
+ - 修复会话手修交回时丢额度:`resume --adopt <sha>` 回答一次带 `grants` 的预算停车时,候选虽换成新提交,仍继承请求上的 grants(计划未变的前提下),重验后直接进入下一轮 review,不再在同一轮第二次停 `resume-review`。普通批准仍要求 subject 一致,刷新过的请求仍不继承。抢锁测试在断言失败时也会结束子进程、不再挂住测试进程。
12
+
13
+ - 修复并发写台账把台账写坏:批准 / 拒绝 / `--adopt` / `stop` / `resume` / 自动取代改为拿到 Run 锁之后才读台账,并在锁内基于新读到的状态判断与写入(此前先读后锁,两个会话几乎同时操作同一 Run 时,后写者会写出重复 seq、断开哈希链,台账从此判定损坏)。台账写入另加兜底:文件在读取后被别人写过就拒绝写入(`changed on disk since it was read`),不写任何字节,重试即可。确定性交错测试在旧代码上复现「hash chain broken」,修复后通过;另有真实多进程并发测试;恢复手册(中英)同步。
14
+
15
+ - 修复驱动进程被杀后锁残留把 Run 卡死:锁记录持有者(pid、主机、获取时间、命令),`resume` / `stop` / `start` 拿锁时若持有者在本机且进程已不存在即自动回收(锁目录在接管期间始终存在,接管者以「死者世代」命名的独占 claim 竞争、只有一个能赢,赢家再原子替换持有者记录;接管中途死掉的接管者不会把锁卡死;普通拿锁方在此期间一律看到「已被持有」,不会出现两个持有者);持有者存活、在别的主机或没有记录时不回收,报错写明持有者与下一步。`gc` 同样回收持有者已死的 `active-run` 锁。被 SIGKILL 的真实驱动可直接 `resume` 走崩溃恢复(有集成测试);恢复手册(中英)同步。
16
+
17
+ - 修复 `resume --config` 找不到自动编号 Run:精确台账优先,否则选择家族唯一未终态 Run;新增 `--run <RUN-ID>` 显式选择,无候选或多候选时提供诊断。非终态批准提示使用 `buildbeat resume` 并带真实 Run ID,帮助与中英文指南同步;只读步预算提示改为每轮计费。
18
+
19
+ - 修复预算误停车:非只读步成功不扣次数,真失败与只读 review 轮次继续消耗预算;增加总 attempt 的 3 倍兜底,防止成功循环失控。
20
+ - review 到顶且发现阻断问题时提前在 `enter-fix` 一次批准修复、重验、再审;Run/Work review 上限同时放行,过期请求不继承扩额。预算提示显示实际用量、真失败次数及批准/拒绝的含义。
21
+ - 事件仅增加可选 `free` / `grants` 字段,旧台账回放保持兼容;默认预算数值不变。放行计划钉在第一条 `BUDGET_EXTENDED` 上,放行中途进程被杀后 `resume` 按原计划补齐。停车提示为英文、带「已用/上限/真失败次数」与批准、拒绝的含义。
22
+
23
+ ## v3.0.1 — 2026-09-09(补丁:示例项目、英文指南)
24
+
25
+ > **发布状态**:`@haiyangbg/buildbeat@3.0.1` 已于 2026-09-09 从 `main`(PR #41,merge commit `c322ce9`,tag `v3.0.1`)经 OIDC Trusted Publishing 发布到 dist-tag **`latest`**(run 34370800960,双 job 一次 success;所有者授权「发 3.0.1」)。独立回读(直连 npmjs.org):`latest` = 3.0.1、integrity 与本地 dry-run 一致、attestation、隔离安装、包内 `example/` 与四篇英文指南在位全过,GitHub Release v3.0.1 标 Latest,证据见 [`docs/V3.0.1-RELEASE-EVIDENCE-2026-09-09.md`](docs/V3.0.1-RELEASE-EVIDENCE-2026-09-09.md)。
26
+
27
+ - **英文指南补齐四篇**:快速开始、Human Approval、Evidence、故障恢复各加 `.en.md`(与中文逐节对应,互相加语言切换行);指南索引、docs 总入口、英文 README 指向英文版。快速开始安装注释里的 `BuildBeat v2 runtime` 改为 3.0.0 实际打印的 `BuildBeat runtime`,信封存在性说明去掉版本号。
28
+ - **示例项目回来了**:`example/` 现在是虚构单仓项目「简账」跑完一个 Work 的快照——填好的 `AGENTS.md` / `指挥台.md` / `BUILDBEAT.md` / `pm/decisions.md`、通知与 observe 配置样例、带项目环境事实的信封、完整的 `delivery/work/WORK-EXPORT-DATE-FILTER/`(intent / plan / run-config / workflow 副本)以及运行时真跑一遍得到的 `decisions.jsonl` 与 `run-record.json`,外加应用本体与真实 `npm test`。随 npm 包与 Claude 插件分发;`tests/example-firstrun.test.js` 锁住工件一致性并把原样拷贝再跑到合并决定。README、docs 索引、SKILL §8.3 指向它。
29
+
5
30
  ## v3.0.0 — 2026-09-09(大版本:只剩一个产品,v1 移除)
6
31
 
32
+ > **发布状态**:`@haiyangbg/buildbeat@3.0.0` 已于 2026-09-09 从 `main`(PR #37,merge commit `0289415`,tag `v3.0.0`)经 OIDC Trusted Publishing 发布到 dist-tag **`latest`**(run 34362068004;publish 一次成功,verify 因 npm 异步处理约 6 分钟才可见而首次超时、版本可见后重跑成功;所有者授权「合并,然后发 3.0.0」)。独立回读(直连 npmjs.org):`latest` = 3.0.0、integrity 与本地 dry-run 一致、attestation、隔离安装只有 `buildbeat` 一个可执行文件、裸调用零写入、包内无 v1 面全过,GitHub Release v3.0.0 标 Latest,证据见 [`docs/V3.0.0-RELEASE-EVIDENCE-2026-09-09.md`](docs/V3.0.0-RELEASE-EVIDENCE-2026-09-09.md)。
33
+
7
34
  > **3.0.0(破坏性变更)**:v1 已移除。需要 v1 文件总线或 `buildbeat doctor/init/adopt/upgrade` 的项目请停留在 2.0.2;3.0.0 起仓库与包只描述一个产品。
8
35
 
9
36
  - **可执行文件只剩 `buildbeat`**:它就是运行时(原 `buildbeat-v2`);`buildbeat-v2` 与 `solobaton` 两个入口删除。新增 `buildbeat --version`。所有文档、模板、信封、`overview` / `inbox` / 通知里可复制的下一句命令统一改名。
package/README.en.md CHANGED
@@ -7,7 +7,7 @@ Context in files. Collaboration through Git. Work keeps moving.
7
7
 
8
8
  BuildBeat is a Git-based AI delivery workflow for humans and AI sessions. Goals, plans, decisions, and delivery records stay in the project, providing a basis for continuing when models, tools, sessions, or the person doing the work change. A build, verify, review, and fix loop moves execution forward; progress and evidence are read back by the kernel from Git and real commands, never taken from a session's own account; key decisions remain human.
9
9
 
10
- [User guides (Chinese)](docs/v2/guide/README.md) · [Session handoffs](docs/v2/guide/11-session-handoff.en.md) · [npm](https://www.npmjs.com/package/@haiyangbg/buildbeat) · [CI](https://github.com/HaiYangBG1/BuildBeat/actions/workflows/ci.yml) · [MIT](LICENSE)
10
+ [Quickstart](docs/v2/guide/01-quickstart.en.md) · [Session handoffs](docs/v2/guide/11-session-handoff.en.md) · [npm](https://www.npmjs.com/package/@haiyangbg/buildbeat) · [CI](https://github.com/HaiYangBG1/BuildBeat/actions/workflows/ci.yml) · [MIT](LICENSE)
11
11
 
12
12
  ## Let go of that irreplaceable chat
13
13
 
@@ -37,7 +37,7 @@ Git manages project facts that need to last. Local files hold execution state. B
37
37
  | `.buildbeat/runtime/` | In-flight events, checkpoints, locks, and raw logs | Local and excluded from Git; needed to recover an active Run |
38
38
  | `.buildbeat/worktrees/` | Each Run's isolated working tree | Preserves candidate code and the working state; keep it when clearing chats |
39
39
 
40
- Filesystem storage does not mean every file belongs in Git. Secrets stay in a protected local environment. Terminal records retain evidence digests and references; retain raw logs separately when the project requires them. See the [evidence guide (Chinese)](docs/v2/guide/06-evidence-guide.md).
40
+ Filesystem storage does not mean every file belongs in Git. Secrets stay in a protected local environment. Terminal records retain evidence digests and references; retain raw logs separately when the project requires them. See the [evidence guide](docs/v2/guide/06-evidence-guide.en.md).
41
41
 
42
42
  ## Different ways to continue the same work
43
43
 
@@ -105,7 +105,7 @@ npm install --global @haiyangbg/buildbeat@latest
105
105
 
106
106
  > Set up BuildBeat for this project. Inspect the code and existing constraints first, then prepare context and execution configuration for the first piece of work.
107
107
 
108
- The session inspects the project and prepares a goal, plan, verification commands, and Worker configuration. Execution starts after your acceptance. See the [quickstart](docs/v2/guide/01-quickstart.md) (Chinese).
108
+ The session inspects the project and prepares a goal, plan, verification commands, and Worker configuration. Execution starts after your acceptance. See the [quickstart](docs/v2/guide/01-quickstart.en.md) and the [example project](example/README.md) (Chinese).
109
109
 
110
110
  **3. Try a handoff.** Once work records are saved, close the old session and open one without its chat history. Or synchronize the records and candidate so another authorized teammate can take over with their own tool:
111
111
 
@@ -148,6 +148,6 @@ Teams collaborate through a shared Git repository and project agreements. BuildB
148
148
 
149
149
  - [Documentation index](docs/README.md): current guides, specifications, and historical records (Chinese).
150
150
  - [Capability matrix](docs/CAPABILITY-MATRIX.md): manual protocol, runtime, plugin, and verification scope (Chinese).
151
- - [Session handoffs](docs/v2/guide/11-session-handoff.en.md) · [Run recovery](docs/v2/guide/10-recovery.md) · [Approval and triage](docs/v2/guide/07-approval-guide.md) (last two in Chinese).
151
+ - [Session handoffs](docs/v2/guide/11-session-handoff.en.md) · [Run recovery](docs/v2/guide/10-recovery.en.md) · [Approval and triage](docs/v2/guide/07-approval-guide.en.md) · [Evidence](docs/v2/guide/06-evidence-guide.en.md).
152
152
  - [Skill](SKILL.md): how a session uses BuildBeat; [lessons](lessons.md): the real incidents behind its mechanisms (Chinese).
153
153
  - [CHANGELOG](CHANGELOG.md) (Chinese) · [Contributing](CONTRIBUTING.md) · [MIT license](LICENSE).
package/README.md CHANGED
@@ -105,7 +105,7 @@ npm install --global @haiyangbg/buildbeat@latest
105
105
 
106
106
  > 用 BuildBeat 接管这个项目。先检查代码和现有约束,为第一项工作准备上下文与运行配置。
107
107
 
108
- 会话先检查项目,补齐目标、计划、验证命令和执行配置;你接受后再启动。完整步骤见 [快速开始](docs/v2/guide/01-quickstart.md)。
108
+ 会话先检查项目,补齐目标、计划、验证命令和执行配置;你接受后再启动。完整步骤见 [快速开始](docs/v2/guide/01-quickstart.md);填好之后长什么样,看 [示例项目](example/README.md)。
109
109
 
110
110
  **3. 试一次接力。** 在工作记录落盘后关闭旧会话,打开一个没有旧聊天历史的新会话;也可以同步记录与候选,让另一位有权限的成员用自己的工具接手:
111
111
 
package/SKILL.md CHANGED
@@ -31,7 +31,7 @@ description: BuildBeat —— 面向人和 AI 会话的工程交付工作流,上
31
31
  | 「开个 Work:〔目标〕」 | 写 `delivery/work/<ID>/intent.md`(为什么做 + **止损线**:最多几个 Run / 几轮 review / 几小时,越线先问人)+ `plan.md`(怎么做)+ `run-config.yaml`(`budgets.reviewRoundsPerWork` 对应止损线);给用户看摘要 | 「看完说接受」;用户说「接受」→ `accept --artifact intent` / `--artifact plan`(digest 绑定) |
32
32
  | 「开工」「再来一轮」 | 先 `buildbeat doctor --config <run-config.yaml>`(会报本仓 intent/plan 是否存在且已接受、哪条 policy 会把 start 挡在哪步、每步预算),再 `start --config <run-config.yaml> --attempt new`(自动编号 RUN-X-01/02…,自动作废同 Work 的旧等待;**用 nohup/setsid 脱离启动**) | 「已起 RUN-X-02,停在合并决定时会通知/我会告诉你」 |
33
33
  | 「怎么样了」「卡住了吗」「正常吗」 | `buildbeat status --repo . --run <RUN>` | 一句:在跑第几步、跑了多久、历史通常多久、最后一次输出几分钟前;`STALLED` 就说「疑似卡住,建议停/等」;停在 kind `infra` 就说「worker 环境/后端故障,不是代码问题,恢复后我重跑,预算不扣」 |
34
- | 「批准 RUN-X」「拒绝,原因…」 | 先看 `inbox` 该 Run 等的是哪条 transition,再 `approve --transition <t> --by <用户名>` / `reject --reason`;非终态转换(`enter-fix` / `resume-<step>` / `enter-review`)批准后再 `resume --config <cfg>` 续跑 | 说清批的是哪一步:「放行 fixer,续跑中」/「再跑一次,续跑中」/「合并决定已落,候选 <sha> 具备合并条件;合并/push/部署要你另说」。`SUCCEEDED` 不等于已合并 |
34
+ | 「批准 RUN-X」「拒绝,原因…」 | 先看 `inbox` 该 Run 等的是哪条 transition,再 `approve --transition <t> --by <用户名>` / `reject --reason`;非终态转换(`enter-fix` / `resume-<step>` / `enter-review`)批准后再 `resume --config <cfg>` 续跑;用 `--attempt new` 自动编号时会选择该家族唯一未终态 Run,也可 `--run <RUN-ID>` 指定;多个候选或没有未终态 Run 时按报错处理 | 说清批的是哪一步:「放行 fixer,续跑中」/「再跑一次,续跑中」/「合并决定已落,候选 <sha> 具备合并条件;合并/push/部署要你另说」。`SUCCEEDED` 不等于已合并 |
35
35
  | 会话自己在 Run 的 worktree 里把 finding 修完并提交了(Run 停在 enter-fix / resume-fix) | `resume --config <cfg> --adopt <sha> --by <会话名>`(跳过 fixer,从 verify 续跑;树必须干净、HEAD 必须是该 sha) | 「我已手修并提交 <sha>,验证重跑中」;**不要**为了让 fixer 空跑而 approve enter-fix |
36
36
  | 「这条 finding 不算,那条接受」 | `findings list` / `findings adjudicate --action dismiss|accept` → `approve --transition enter-fix` | 裁决结果一句 |
37
37
  | 「上线」「做生产动作」 | 用 `release-readback` 预设 + `riskPreset: release` 开 Run:preflight 回读 → 停 `enter-apply-readback` | 「回读全绿,现在轮到你做〔动作〕;做完说一声」→ 用户说「做完了」→ `approve enter-apply-readback` → 回读+观察 → 停关窗 |
@@ -65,7 +65,8 @@ allowedPaths:
65
65
  - tests
66
66
  # P0/P1 先过人分诊再派 fixer
67
67
  reviewTriage: required
68
- # 可省;run 配置 > 预设 > 默认。预算耗尽停人时,批准 resume-<step> 即多给一次;
68
+ # 可省;run 配置 > 预设 > 默认。非只读步成功不扣次数;review 仍按轮计费。
69
+ # review 到顶时在 enter-fix 一次批准修复、重验、再审;Run/Work 上限同时放行;
69
70
  # reviewRoundsPerWork 跨本 Work 所有 Run 累计 review 轮数,超了新 Run 起跑前先问人
70
71
  budgets:
71
72
  maxAttempts:
@@ -126,7 +127,7 @@ workers:
126
127
  - workspace-write
127
128
  ```
128
129
 
129
- (严格 YAML 子集:只有块列表与块映射,没有行内 `[]` / `{}`,**注释必须独占一行**;上面这份可原样解析,机器验证在 `tests/v2-templates-firstrun.test.js`。**`fixer` 不能省**:没配它,verify 失败或 review 阻断时 Run 停 `WAITING_HUMAN` 等人手修,不会自动修。完整样板 [templates/v2/run-config.example.yaml](templates/v2/run-config.example.yaml),信封 [templates/v2/envelope/](templates/v2/envelope/worker.sh)。)通知通道另放 `.buildbeat/notify.yaml`(URL 只能来自环境变量),见 [docs/v2/guide/07-approval-guide.md](docs/v2/guide/07-approval-guide.md);指南索引 [docs/v2/guide/README.md](docs/v2/guide/README.md)。
130
+ (严格 YAML 子集:只有块列表与块映射,行内只允许空的 `[]` / `{}`,列表项可与键同缩进,**注释必须独占一行**;上面这份可原样解析,机器验证在 `tests/v2-templates-firstrun.test.js`。**`fixer` 不能省**:没配它,verify 失败或 review 阻断时 Run 停 `WAITING_HUMAN` 等人手修,不会自动修。完整样板 [templates/v2/run-config.example.yaml](templates/v2/run-config.example.yaml),信封 [templates/v2/envelope/](templates/v2/envelope/worker.sh)。)通知通道另放 `.buildbeat/notify.yaml`(URL 只能来自环境变量),见 [docs/v2/guide/07-approval-guide.md](docs/v2/guide/07-approval-guide.md);指南索引 [docs/v2/guide/README.md](docs/v2/guide/README.md)。
130
131
 
131
132
  **第一次为一个项目写 run-config 时,会话要多问用户一句**:「Run 停下来等你批、跑完、或疑似卡住时,要不要推到钉钉/webhook?给我一个只放在环境变量里的 URL 就行」——试点一直没启用通知,一张合并卡就绪后隔夜等了 9.5 小时。用户说不要就记一句「通知未启用,等待只在 inbox 里」。
132
133
 
@@ -239,7 +240,9 @@ worker prompt 里要写清三条环境事实(模板 AGENTS 第 ⑨ 条):沙箱
239
240
  | `controlled` | intent + plan 接受 + 合并决定 + 上线 | 契约变更、大改、不可逆副作用 |
240
241
  | `release` | 配 `release-readback` 预设:preflight 回读 → 人做 → apply 回读 → 关窗 | 生产动作 |
241
242
 
242
- 机器闸(gitleaks pre-commit)、证据制与合并候选一次核查任何预设都不跳;高风险 delta 不得借 `fast` 绕过独立核查。预算(每步 `maxAttempts`、Work 级 `reviewRoundsPerWork`)耗尽是停人不是失败,人批 `resume-<step>` 即多给一次;基础设施故障(超时 / 崩溃 / 非 JSON / exit 75)判 `infra` 停人、不派 fixer、不扣预算。
243
+ 机器闸(gitleaks pre-commit)、证据制与合并候选一次核查任何预设都不跳;高风险 delta 不得借 `fast` 绕过独立核查。预算耗尽是停人不是失败。非只读步(build / verify / fix)成功不扣 `maxAttempts`,只读步仍按尝试次数计费,review 按轮计费;基础设施故障(超时 / 崩溃 / 非 JSON / exit 75)判 `infra` 停人、不派 fixer、不扣预算。真失败到顶仍停 `resume-<step>`,批准多给一次。同一步总 attempt 达到有效预算上限(配置值 + 人批扩额)的 3 倍后,下一次执行前以 kind `budget` 兜底停人,防止成功循环失控;退款不抬高该兜底上限。
244
+
245
+ **一轮一问**:review 发现阻断问题且下一轮会超 Run 或 Work 上限时,提前停 `enter-fix`;有分诊用 `finding-triage`,无分诊用 `budget`。批准覆盖「修复 + 重新验证 + 再审一轮」,所需扩额随请求的可选 `grants` 落账,Run/Work 同时到顶只问一次;拒绝结束本 Run,由人按现有证据决定是否合并。批准旧的 `enter-review` / `resume-review` 预算停车时也同时放行已到顶的另一层上限。新候选或过期批准不能沿用旧请求的 grants。默认上限不变。
243
246
 
244
247
  ## 6. 三个仪式(防腐烂的关键,缺了机制必朽)
245
248
 
@@ -390,7 +393,7 @@ worker prompt 里要写清三条环境事实(模板 AGENTS 第 ⑨ 条):沙箱
390
393
  - [ ] 8. 收尾一屏:生成了什么 / 默认拿主意的项 / 首跑停在哪、证据在哪 / 下一步由谁做(合并是人的动作)
391
394
  ```
392
395
 
393
- > 可核对的样例:`tests/v2-templates-firstrun.test.js` 用脚本 worker 代替真实模型,从上面的模板走到合并决定(含一次 verify 失败→fixer→重验)。它证明包内路径、配置、信封、提交机制、reviewer 信封连得上;不证明某个真实模型能完成业务任务。
396
+ > 各文件「填好之后长什么样」,参照 [example/](example/README.md)(虚构「简账」项目跑完一个 Work 的快照)。可核对的样例:`tests/v2-templates-firstrun.test.js` 与 `tests/example-firstrun.test.js` 用脚本 worker 代替真实模型,从上面的模板走到合并决定(含一次 verify 失败→fixer→重验)。它证明包内路径、配置、信封、提交机制、reviewer 信封连得上;不证明某个真实模型能完成业务任务。
394
397
 
395
398
  ## 8.5 接管存量项目(10→N 入口:先摸底、划边界、补验证)
396
399
 
package/docs/README.md CHANGED
@@ -7,11 +7,12 @@
7
7
  | 你要做什么 | 读 |
8
8
  |---|---|
9
9
  | 第一次用,在 AI 会话里 | [`v2/guide/00-how-to-talk.md`](v2/guide/00-how-to-talk.md) → 会话读 [`SKILL.md`](../SKILL.md) §0.5 |
10
- | 第一次用,自己敲命令核对 | [`v2/guide/01-quickstart.md`](v2/guide/01-quickstart.md) |
10
+ | 第一次用,自己敲命令核对 | [`v2/guide/01-quickstart.md`](v2/guide/01-quickstart.md) · [English](v2/guide/01-quickstart.en.md) |
11
11
  | 指南索引(日常 / 配置) | [`v2/guide/README.md`](v2/guide/README.md) |
12
12
  | 关闭旧会话后继续,或由其他成员/工具接手 | [`跨会话接续`](v2/guide/11-session-handoff.md) · [English](v2/guide/11-session-handoff.en.md) |
13
13
  | 三个可用面各能做什么(Skill-only / 运行时 / 插件) | [`CAPABILITY-MATRIX.md`](CAPABILITY-MATRIX.md) |
14
14
  | 项目装载入口与信封模板 | [`../templates/v2/`](../templates/v2/AGENTS.md) |
15
+ | 填好之后长什么样:一个 Work 跑到合并决定的快照 | [`../example/`](../example/README.md) |
15
16
 
16
17
  ## 现行:规范与维护
17
18
 
@@ -26,7 +27,7 @@
26
27
 
27
28
  | 类别 | 文件 |
28
29
  |---|---|
29
- | 发布证据 | `V2.0.2-RELEASE-EVIDENCE-2026-09-09.md`(当前 `latest`)、`V2.0.1-RELEASE-EVIDENCE-2026-09-06.md`、`V2.0.0-RELEASE-EVIDENCE-2026-09-05.md`、`V2.0.0-BETA.1~5-RELEASE-EVIDENCE-*.md`、`V1.21-RELEASE-EVIDENCE-2026-08-25.md`、`WP4.3-RELEASE-EVIDENCE-2026-08-25.md` |
30
+ | 发布证据 | `V3.0.1-RELEASE-EVIDENCE-2026-09-09.md`(当前 `latest`)、`V3.0.0-RELEASE-EVIDENCE-2026-09-09.md`、`V2.0.2-RELEASE-EVIDENCE-2026-09-09.md`、`V2.0.1-RELEASE-EVIDENCE-2026-09-06.md`、`V2.0.0-RELEASE-EVIDENCE-2026-09-05.md`、`V2.0.0-BETA.1~5-RELEASE-EVIDENCE-*.md`、`V1.21-RELEASE-EVIDENCE-2026-08-25.md`、`WP4.3-RELEASE-EVIDENCE-2026-08-25.md` |
30
31
  | 规划与决策(2026-08) | [`V2-PLAN.md`](V2-PLAN.md)(执行基线,已交付)、[`V2-PROPOSAL.md`](V2-PROPOSAL.md)、[`V2-DECISIONS.md`](V2-DECISIONS.md)、[`V2-D2-DECISION-CARD.md`](V2-D2-DECISION-CARD.md)、[《BuildBeat v2:AI 原生软件交付控制平面》](BuildBeat%20v2%EF%BC%9AAI%20%E5%8E%9F%E7%94%9F%E8%BD%AF%E4%BB%B6%E4%BA%A4%E4%BB%98%E6%8E%A7%E5%88%B6%E5%B9%B3%E9%9D%A2.md) |
31
32
  | 迭代与里程碑记录 | `V2-ITERATION-01~08.md`、[`v2/`](v2/) 下的 M1/M2/M4 验收与试点记录 |
32
33
  | 早期版本史 | [`../CHANGELOG-v1.md`](../CHANGELOG-v1.md)(2026-06 ~ 2026-08 的条目原文;当前条目在根 [`CHANGELOG.md`](../CHANGELOG.md)) |
package/docs/RELEASING.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  This runbook governs BuildBeat's public npm distribution. The canonical package is `@haiyangbg/buildbeat` in `HaiYangBG1/BuildBeat`; the only executable is `buildbeat`. No other package name or executable alias receives publications.
4
4
 
5
- Release evidence at source package version `@haiyangbg/buildbeat@3.0.0`; latest independently verified BuildBeat npm distribution `@haiyangbg/buildbeat@2.0.2` (dist-tag `latest`; `next` stays `2.0.0-beta.5`), anchored by annotated tag `v2.0.2` at commit `a077367`, workflow run [34351668694](https://github.com/HaiYangBG1/BuildBeat/actions/runs/34351668694), and archived in [`V2.0.2-RELEASE-EVIDENCE-2026-09-09.md`](V2.0.2-RELEASE-EVIDENCE-2026-09-09.md). The 2.0.1 chain (`latest` from 2026-09-06 until 2.0.2 took over on 2026-09-09) stays archived in [`V2.0.1-RELEASE-EVIDENCE-2026-09-06.md`](V2.0.1-RELEASE-EVIDENCE-2026-09-06.md). The 2.0.0 chain (`latest` from 2026-09-05 until 2.0.1 took over on 2026-09-06) stays archived in [`V2.0.0-RELEASE-EVIDENCE-2026-09-05.md`](V2.0.0-RELEASE-EVIDENCE-2026-09-05.md). The beta.5 chain stays archived in [`V2.0.0-BETA.5-RELEASE-EVIDENCE-2026-09-05.md`](V2.0.0-BETA.5-RELEASE-EVIDENCE-2026-09-05.md). The beta.4 chain stays archived in [`V2.0.0-BETA.4-RELEASE-EVIDENCE-2026-09-03.md`](V2.0.0-BETA.4-RELEASE-EVIDENCE-2026-09-03.md); the beta.3 chain in [`V2.0.0-BETA.3-RELEASE-EVIDENCE-2026-09-01.md`](V2.0.0-BETA.3-RELEASE-EVIDENCE-2026-09-01.md). The beta.2 chain stays archived in [`V2.0.0-BETA.2-RELEASE-EVIDENCE-2026-08-28.md`](V2.0.0-BETA.2-RELEASE-EVIDENCE-2026-08-28.md); the beta.1 chain stays archived in [`V2.0.0-BETA.1-RELEASE-EVIDENCE-2026-08-28.md`](V2.0.0-BETA.1-RELEASE-EVIDENCE-2026-08-28.md). Earlier distributions and the retired legacy package name are archived in the dated evidence files under `docs/`.
5
+ Release evidence at source package version `@haiyangbg/buildbeat@3.1.0`; latest independently verified BuildBeat npm distribution `@haiyangbg/buildbeat@3.0.1` (dist-tag `latest`; `next` stays `3.0.0`), anchored by annotated tag `v3.0.1` at commit `c322ce9`, workflow run [34370800960](https://github.com/HaiYangBG1/BuildBeat/actions/runs/34370800960), and archived in [`V3.0.1-RELEASE-EVIDENCE-2026-09-09.md`](V3.0.1-RELEASE-EVIDENCE-2026-09-09.md). The 3.0.0 chain (`latest` from 2026-09-09 until 3.0.1 took over the same day; the first version without the removed generation) stays archived in [`V3.0.0-RELEASE-EVIDENCE-2026-09-09.md`](V3.0.0-RELEASE-EVIDENCE-2026-09-09.md). The 2.0.2 chain (`latest` from 2026-09-09 until 3.0.0 took over the same day; the last version carrying the removed generation) stays archived in [`V2.0.2-RELEASE-EVIDENCE-2026-09-09.md`](V2.0.2-RELEASE-EVIDENCE-2026-09-09.md). The 2.0.1 chain (`latest` from 2026-09-06 until 2.0.2 took over on 2026-09-09) stays archived in [`V2.0.1-RELEASE-EVIDENCE-2026-09-06.md`](V2.0.1-RELEASE-EVIDENCE-2026-09-06.md). The 2.0.0 chain (`latest` from 2026-09-05 until 2.0.1 took over on 2026-09-06) stays archived in [`V2.0.0-RELEASE-EVIDENCE-2026-09-05.md`](V2.0.0-RELEASE-EVIDENCE-2026-09-05.md). The beta.5 chain stays archived in [`V2.0.0-BETA.5-RELEASE-EVIDENCE-2026-09-05.md`](V2.0.0-BETA.5-RELEASE-EVIDENCE-2026-09-05.md). The beta.4 chain stays archived in [`V2.0.0-BETA.4-RELEASE-EVIDENCE-2026-09-03.md`](V2.0.0-BETA.4-RELEASE-EVIDENCE-2026-09-03.md); the beta.3 chain in [`V2.0.0-BETA.3-RELEASE-EVIDENCE-2026-09-01.md`](V2.0.0-BETA.3-RELEASE-EVIDENCE-2026-09-01.md). The beta.2 chain stays archived in [`V2.0.0-BETA.2-RELEASE-EVIDENCE-2026-08-28.md`](V2.0.0-BETA.2-RELEASE-EVIDENCE-2026-08-28.md); the beta.1 chain stays archived in [`V2.0.0-BETA.1-RELEASE-EVIDENCE-2026-08-28.md`](V2.0.0-BETA.1-RELEASE-EVIDENCE-2026-08-28.md). Earlier distributions and the retired legacy package name are archived in the dated evidence files under `docs/`.
6
6
 
7
7
  ## Channels and branches
8
8
 
@@ -118,6 +118,8 @@ gh workflow run publish.yml --ref main -f tag=vX.Y.Z
118
118
  gh run watch --exit-status
119
119
  ```
120
120
 
121
+ npm now processes a publish asynchronously (`npm publish` prints "being processed and may take a few minutes"); the verify job waits up to ten minutes for the exact version, the dist-tag and the provenance to read back. If it still fails **only** on readback, wait for `npm view` to show the version and re-run the failed job (`gh run rerun <run-id> --failed`); never publish again. Real incident: 3.0.0 became readable about six minutes after `npm publish` returned.
122
+
121
123
  The workflow waits for exact registry-version readback, requires `dist.attestations` to expose an npm attestation URL with the SLSA v1 provenance predicate, installs the public package into a clean temporary prefix, checks its executable version, and runs `npm audit signatures`. The release operator must still repeat the isolated-install and read-only `doctor` check independently before publishing the matching GitHub Release. Never use `workflow_dispatch` to bypass the repository's human merge or tag Gate.
122
124
 
123
125
  Trusted Publishing removes the long-lived write token and automatically emits provenance for supported public GitHub repositories. Configure the exact owner, repository, workflow filename, allowed `npm publish` action, and the exact `npm-publish` environment on npmjs.com. A GitHub Environment without the matching npm-side environment binding is not sufficient evidence. See npm's [Trusted Publishing](https://docs.npmjs.com/trusted-publishers/) and [provenance](https://docs.npmjs.com/generating-provenance-statements/) documentation.
@@ -0,0 +1,165 @@
1
+ # Quickstart: your first Run
2
+
3
+ [简体中文](01-quickstart.md) | **English**
4
+
5
+ Goal: in a real Git repository, let the Runner drive Build → Verify → Review to completion and **stop at the merge decision**, which you make with the evidence in front of you. The order is fixed: install → prepare the Work → write the run config → accept the plan → doctor → start → read the evidence and decide. Every step says what success looks like. How long it takes depends on your workers and the task; this page promises no numbers.
6
+
7
+ > People who use BuildBeat inside an AI session never type these commands: `SKILL.md` §0.5 is the driving manual the session reads, and you just say "start", "where are we", "approve". This page shows what runs behind the session so you can check it.
8
+
9
+ ## 0. Install
10
+
11
+ ```bash
12
+ npm install --global @haiyangbg/buildbeat@latest
13
+ buildbeat | head -3 # printing "BuildBeat runtime" plus the usage means the install worked
14
+ ```
15
+
16
+ Stable releases live on `@latest`; there is exactly one executable, `buildbeat` (the runtime this page uses). `@next` is only for pre-releases. Requirements: Node ≥ 20, Git, bash, zero runtime dependencies.
17
+
18
+ > Before continuing, confirm that `$(npm root -g)/@haiyangbg/buildbeat/templates/v2/envelope/` exists. If it does not, reinstall with `npm install --global @haiyangbg/buildbeat@latest`.
19
+
20
+ ## 1. Prepare the Work (Git plane)
21
+
22
+ In the target repository, create the Work directory and write the intent and the plan (their digests get bound into the approval subject), copy the official workflow preset next to the Work (copy, do not reference the install directory: the workflow file's digest is recorded in the Run and travels with the project in Git), then copy the envelope templates (worker wrapper script plus three prompts) into the repository-level `delivery/envelope/`:
23
+
24
+ ```bash
25
+ BB="$(npm root -g)/@haiyangbg/buildbeat"
26
+ mkdir -p delivery/work/WORK-DEMO-1
27
+ printf "# Intent\nAdd date filtering to the CSV export.\nStop-loss: at most 3 Runs, 4 review rounds.\n" > delivery/work/WORK-DEMO-1/intent.md
28
+ printf "# Plan\n1. Add from/to parameters in src/export.js; 2. add boundary cases under tests/.\n" > delivery/work/WORK-DEMO-1/plan.md
29
+ cp "$BB/src/v2/presets/software-delivery.yaml" delivery/work/WORK-DEMO-1/workflow.yaml
30
+ cp -R "$BB/templates/v2/envelope" delivery/envelope
31
+ git add delivery && git commit -qm "buildbeat: work WORK-DEMO-1 + envelope"
32
+ ```
33
+
34
+ The envelope must be committed: workers run in an isolated worktree and only see committed files. `delivery/envelope/worker.sh <role> -- <tool command…>` takes care of "exit 75 when the tool is not on PATH, append the prompt as the last argument, commit mechanically after a writing step, capture stdout as the envelope for a read-only step"; the three prompts only need the project's environment facts added ([Worker contract](05-worker-contract.md), Chinese).
35
+
36
+ ## 2. Write the run config
37
+
38
+ `delivery/work/WORK-DEMO-1/run-config.yaml`. Paths resolve relative to **this file**; the YAML is a strict subset: block lists and block maps only (list items may sit at their key's indentation), inline only for the empty `[]` / `{}`, no anchors, comments on their own line; quote a list item that contains `": "`. The config below parses as-is (machine-checked by `tests/v2-templates-firstrun.test.js`); the full sample and the envelope templates are in [`templates/v2/`](../../../templates/v2/run-config.example.yaml).
39
+
40
+ ```yaml
41
+ repo: ../../..
42
+ work: WORK-DEMO-1
43
+ run: RUN-DEMO
44
+ workflow: workflow.yaml
45
+ riskPreset: standard
46
+ entry: build
47
+ allowedPaths:
48
+ - src
49
+ - tests
50
+ reviewTriage: required
51
+ envelope:
52
+ prompts: ../../envelope/prompts
53
+ workers:
54
+ builder:
55
+ command: bash
56
+ args:
57
+ - delivery/envelope/worker.sh
58
+ - builder
59
+ - --
60
+ - codex
61
+ - exec
62
+ - -s
63
+ - workspace-write
64
+ verifier:
65
+ command: bash
66
+ args:
67
+ - -lc
68
+ - npm test
69
+ reviewer:
70
+ command: bash
71
+ args:
72
+ - delivery/envelope/worker.sh
73
+ - reviewer
74
+ - --
75
+ - codex
76
+ - exec
77
+ - -s
78
+ - read-only
79
+ fixer:
80
+ command: bash
81
+ args:
82
+ - delivery/envelope/worker.sh
83
+ - fixer
84
+ - --
85
+ - codex
86
+ - exec
87
+ - -s
88
+ - workspace-write
89
+ ```
90
+
91
+ - `workers.<role>` is any CLI: to switch tools, change only what follows `--` (`claude -p`, any script), see the [Adapter guide](04-adapter-guide.md) (Chinese); the reviewer's output format is in the [Worker contract](05-worker-contract.md) (Chinese) and already spelled out in the prompt template.
92
+ - **`fixer` is not optional**: without it, a failed verify or a blocking review stops the Run at `WAITING_HUMAN` (reason `no adapter configured for worker fixer`) waiting for you to fix by hand; nothing gets fixed automatically.
93
+ - Worker subprocesses receive only `PATH HOME LANG LC_ALL TMPDIR TERM USER SHELL` by default; inject anything else by name with `env:` ([Adapter guide](04-adapter-guide.md), Chinese).
94
+ - `reviewTriage: required` routes P0/P1 findings through you before a fixer is dispatched; delete the line if you do not want that.
95
+
96
+ ## 3. Accept the plan
97
+
98
+ The `standard` preset requires the plan to be an accepted artifact before build (`controlled` also requires the intent). Acceptance is digest-bound: edit the plan after accepting it and the acceptance expires on its own; `doctor` reports `stale`.
99
+
100
+ ```bash
101
+ buildbeat accept --repo . --work WORK-DEMO-1 --artifact plan --by <your name>
102
+ ```
103
+
104
+ Success: it prints `accepted plan as A-WORK-DEMO-1-<n>` and `digest: sha256:…`.
105
+
106
+ ## 4. doctor: read what start will read, before starting
107
+
108
+ ```bash
109
+ buildbeat doctor --config delivery/work/WORK-DEMO-1/run-config.yaml
110
+ ```
111
+
112
+ Check section by section: declared versus actual enforcement for each entry under `policies`; whether each worker under `worker isolation` is `env allowlist` or `WARNING inherit`; `push protection`; the per-step budgets; under `work artifacts`, whether intent and plan exist, are accepted, are stale, and the preview of where `start` will stop. A `WARNING` does not mean you cannot run, but you should know what it means; exit code 0 does not mean everything is ready.
113
+
114
+ ## 5. Start the Run; it stops for a human
115
+
116
+ ```bash
117
+ buildbeat start --config delivery/work/WORK-DEMO-1/run-config.yaml --attempt new
118
+ ```
119
+
120
+ `--attempt new` numbers the run automatically (`RUN-DEMO-01/02…`) and supersedes older Runs of the same Work that are still waiting for a human. The Runner will: open an isolated worktree (branch `run/RUN-DEMO-01`, pushing to the configured remote is blocked) → the builder produces a commit and the candidate is pinned → the verifier really runs the tests (the exit code is read back as evidence) → the reviewer produces structured findings read-only → the Run reaches `WAITING_HUMAN`.
121
+
122
+ When starting from inside an AI session, detach the process (`nohup` / `setsid`); otherwise the host session's timeout kills the Run.
123
+
124
+ **What success looks like**: the output ends with `status: WAITING_HUMAN`, and `waiting on human:` is followed by `enter-wait-merge` (the merge decision) or `enter-fix` (triage). **Stopping with `infra` is an environment problem, not a code problem**: timeouts, crashes, non-JSON envelopes and exit code 75 all count; fix the worker or the environment, then `approve --transition resume-<step>` to continue. No budget is consumed.
125
+
126
+ ## 6. Read the evidence, decide
127
+
128
+ ```bash
129
+ buildbeat overview --repo . # where each Work is, whose move is next, what it has cost
130
+ buildbeat inbox --repo . # Runs waiting for you, each with the copyable next command
131
+ buildbeat status --repo . --run RUN-DEMO-01 # steps, durations, evidence, findings, the reason it waits
132
+ ```
133
+
134
+ Before approving, look at: the candidate SHA, the verify exit code and log, every review finding. Then run the line `inbox` gives you, usually:
135
+
136
+ ```bash
137
+ buildbeat approve --repo . --run RUN-DEMO-01 --transition enter-wait-merge --by <your name> --config delivery/work/WORK-DEMO-1/run-config.yaml
138
+ ```
139
+
140
+ **Be clear about which step you are approving** ([Approval guide](07-approval-guide.en.md)): `enter-wait-merge` is the merge decision; the Run reaches the terminal state `SUCCEEDED`, meaning the candidate is fit to merge. The actual merge, push and release are always your actions outside the Runner. `enter-fix` / `resume-<step>` are non-terminal transitions: after approving them, `resume --config …` lets the Run continue. When findings block, the Run routes fix → verify → review on its own; when the budget is exhausted or a failure fingerprint repeats, it stops and hands back to you ([Recovery](10-recovery.en.md)).
141
+
142
+ After `start --attempt new` numbers a Run, `resume --config <run-config.yaml>` resumes the family’s only non-terminal Run and prints its ID. Use `--run <RUN-ID>` to select the configured Run itself or `<family>-NN` explicitly (at least two digits). An existing ledger for the exact configured ID takes precedence. Multiple non-terminal Runs are listed with a request to select one using `--run`; if none remain, the error reports the latest ID and terminal status, or states that no ledgers were found.
143
+
144
+ ## 7. Walk the failure branch once
145
+
146
+ To see the automatic repair loop, commit a failing test case under `tests/` and `start --attempt new` again: verify fails → the fixer repairs with the failure summary → verify reruns → review. `status` shows `step fix: SUCCEEDED` and a second `verify`. To route findings through your hands first: `reviewTriage: required` together with `findings list` / `findings adjudicate` adjudicates fingerprint by fingerprint; a dismissed fingerprint no longer blocks.
147
+
148
+ ## 8. Recovery, notifications, cleanup
149
+
150
+ - Process killed / machine rebooted: `resume --config <run-config.yaml>`, see [Recovery](10-recovery.en.md).
151
+ - You fixed the problem yourself in the worktree and committed it: `resume --config … --adopt <sha> --by <name>` skips the fixer and continues from verify.
152
+ - Not watching the screen: configure one DingTalk / webhook channel in `.buildbeat/notify.yaml` (the URL comes only from an environment variable) and the Run finds you when it stops ([Approval guide](07-approval-guide.en.md)).
153
+ - Worktrees left by terminal Runs: `gc --repo .` prints the plan first, `--apply true` cleans.
154
+ - To dry-run a single step before a real Run: `preflight --step <id>` (main checkout, minute-scale, produces no evidence); declare the envelope's environment dependencies with `requires:` so they are checked fail-closed before start ([Workflow guide](02-workflow-guide.md), Chinese).
155
+
156
+ ## 9. observe: let the system watch production (v0)
157
+
158
+ ```bash
159
+ cp "$(npm root -g)/@haiyangbg/buildbeat/src/v2/presets/observe.yaml" .buildbeat/observe.yaml # replace with the project's real probes
160
+ buildbeat observe run --config .buildbeat/observe.yaml # one invocation = one cycle; leave scheduling to cron
161
+ buildbeat observe status --repo .
162
+ buildbeat observe triage --repo . --intent delivery/observe/intents/INTENT-<fp>.md --action fix_now --by <you>
163
+ ```
164
+
165
+ A probe fails or cannot collect → evidence `failed` / `unverified` → bands escalate (record → read-only diagnosis → Intent draft queued). Drafts are **never executed automatically**; `dismiss` feeds the threshold back so the same fingerprint stays quiet until its severity rises. Details in the [Evidence guide](06-evidence-guide.en.md) §observe.
@@ -1,5 +1,7 @@
1
1
  # 快速开始:第一个 Run
2
2
 
3
+ **简体中文** | [English](01-quickstart.en.md)
4
+
3
5
  目标:在一个真实 Git 仓库里,让 v2 Runner 驱动 Build→Verify→Review 自动跑完,**停在合并决定**,由你带着证据拍板。下面的顺序是固定的:安装 → 准备工作项 → 写 run 配置 → 接受计划 → doctor → start → 看证据、拍板。每一步都写了"成功是什么样"。耗时取决于你的 worker 与任务,本文不给承诺数字。
4
6
 
5
7
  > 在 AI 会话里用 BuildBeat 的人不需要手敲这些命令:`SKILL.md` §0.5 是给会话读的驾驶手册,你说「开工 / 当前进度 / 批准」即可。本文给的是会话背后跑的东西,方便你核对。
@@ -8,12 +10,12 @@
8
10
 
9
11
  ```bash
10
12
  npm install --global @haiyangbg/buildbeat@latest
11
- buildbeat | head -3 # 打印 "BuildBeat v2 runtime" 与用法即安装成功
13
+ buildbeat | head -3 # 打印 "BuildBeat runtime" 与用法即安装成功
12
14
  ```
13
15
 
14
16
  稳定版走 `@latest`,可执行文件只有一个:`buildbeat`(本文用的运行时)。预发布才用 `@next`。要求 Node ≥ 20、Git、bash,零运行时依赖。
15
17
 
16
- > 下文用到的 `templates/v2/envelope/` 与 run 配置 `env:` 透传修复自 2.0.1 起随包分发。装好后确认 `$(npm root -g)/@haiyangbg/buildbeat/templates/v2/envelope/` 存在再继续;不存在说明装到的是 2.0.0,先 `npm install --global @haiyangbg/buildbeat@latest` 更新。
18
+ > 继续之前确认 `$(npm root -g)/@haiyangbg/buildbeat/templates/v2/envelope/` 存在;不存在就重新 `npm install --global @haiyangbg/buildbeat@latest`。
17
19
 
18
20
  ## 1. 准备工作项(Git 面)
19
21
 
@@ -33,7 +35,7 @@ git add delivery && git commit -qm "buildbeat: work WORK-DEMO-1 + envelope"
33
35
 
34
36
  ## 2. 写 run 配置
35
37
 
36
- `delivery/work/WORK-DEMO-1/run-config.yaml`。路径相对**本文件**解析;YAML 是严格子集:只有块列表与块映射,没有行内 `[]` / `{}`、没有锚点、注释必须独占一行。下面这份可以原样解析(机器验证在 `tests/v2-templates-firstrun.test.js`);完整样板与信封模板在 [`templates/v2/`](../../../templates/v2/run-config.example.yaml)。
38
+ `delivery/work/WORK-DEMO-1/run-config.yaml`。路径相对**本文件**解析;YAML 是严格子集:只有块列表与块映射(列表项可与键同缩进),行内只允许空的 `[]` / `{}`,没有锚点,注释必须独占一行;含 `": "` 的列表项要加引号。下面这份可以原样解析(机器验证在 `tests/v2-templates-firstrun.test.js`);完整样板与信封模板在 [`templates/v2/`](../../../templates/v2/run-config.example.yaml)。
37
39
 
38
40
  ```yaml
39
41
  repo: ../../..
@@ -137,6 +139,8 @@ buildbeat approve --repo . --run RUN-DEMO-01 --transition enter-wait-merge --by
137
139
 
138
140
  **批的是哪一步要分清**([Approval 指南](07-approval-guide.md)):`enter-wait-merge` 是合并决定,Run 进终态 `SUCCEEDED`,表示候选具备合并条件——真正的合并、push、发布永远是你在 Runner 之外的动作;`enter-fix` / `resume-<step>` 是非终态转换,批准后要 `resume --config …` 让它续跑。被 findings 阻断时会自动路由 fix→verify→review 重走,超预算或失败指纹重复则停下交还给你([Recovery](10-recovery.md))。
139
141
 
142
+ 使用 `start --attempt new` 自动编号时,`resume --config <run-config.yaml>` 会续跑该家族唯一未终态的 Run,并打印选中的 ID;也可用 `--run <RUN-ID>` 显式指定配置中的 Run 本身或 `<家族>-NN`(数字至少两位)。配置本身已有台账时优先使用该精确 ID。多个未终态 Run 会列出候选并要求用 `--run` 选择;没有未终态 Run 会报告最新一次的 ID 和终态,没有台账则明确说明。
143
+
140
144
  ## 7. 走一次失败分支
141
145
 
142
146
  想看自动修复闭环,把一条会失败的用例提交进 `tests/`,再 `start --attempt new`:verify 失败 → fixer 带着失败摘要修 → verify 重跑 → review。`status` 会显示 `step fix: SUCCEEDED` 与第二次 `verify`。想让 finding 先过你的手:`reviewTriage: required` 配套 `findings list` / `findings adjudicate` 逐指纹裁决,dismiss 后同指纹不再阻断。
@@ -37,6 +37,17 @@ terminal:
37
37
 
38
38
  run 配置里 `entry` 可覆盖 workflow 的 `entry`(例如从 `build` 起步、跳过 intent/plan 步——digest 仍会绑进批准对象);`stopAt` 指定停点。workflow 文件整体做 sha256 → `RUN_CREATED.workflowDigest`,事后可证明当时跑的是哪份流程。
39
39
 
40
+ **写错时的报错形态**:`start` / `resume` / `doctor` / `preflight` / `approve --config` 读 run 配置时先整体校验,做任何事之前**一次列出全部问题**:
41
+
42
+ ```text
43
+ error: run config delivery/work/WORK-X/run-config.yaml has 3 problem(s):
44
+ - stopat: unknown key (did you mean stopAt?)
45
+ - repo: required and missing
46
+ - workers.reviwer: no step of the workflow uses this worker (did you mean reviewer?); workers in this workflow: planner, builder, verifier, reviewer, fixer
47
+ ```
48
+
49
+ 校验范围:必填键(`repo` `work` `run` `workflow` `workers`);未知顶层键与 worker / envelope 的未知字段(给最接近的拼写);类型与取值(正整数、列表、`inheritEnv` 只能是 `true` / `false`);worker 名必须被工作流步骤用到;`stopAt` / `entry` 必须是工作流步骤;`work` / `run` 只允许字母、数字、`.` `_` `-`,写成数字要加引号。
50
+
40
51
  run 配置还可声明(beta.3,皆来自三十轮部署战役的真实事故):
41
52
 
42
53
  - **`requires:` 环境契约**——信封隐式依赖的二进制与最低版本,Run 启动前 fail-closed 全量核验,一次报清所有问题(真实事故:`rg` 只在某会话 vendored PATH、`/bin/bash` 3.2、新 shell 解析到 Node 14,各烧掉整轮 Run 才见真因):
@@ -0,0 +1,51 @@
1
+ # Evidence guide
2
+
3
+ [简体中文](06-evidence-guide.md) | **English**
4
+
5
+ Authority: [`RFC-0002 §4`](../RFC-0002-domain-model.md) (Chinese); implementation: `src/v2/evidence/collector.js`, `src/v2/observe/`. Core idea: **evidence is a fact the Runner read back, not a worker's account of itself**.
6
+
7
+ ## The shape of an evidence record
8
+
9
+ Every piece of evidence enters the event ledger (`EVIDENCE_RECORDED`) with: `kind` (command / screenshot / drift / runtime-health / diagnosis / …), `subject` (candidate SHA or deployment unit), `digest` (sha256 of the raw log; the runtime may be deleted, the digest lives on), `status`, `grade`, producer, start and end times. Raw logs land in the runtime plane, `.buildbeat/runtime/`; the ledger and the compacted record reference only digests.
10
+
11
+ ## Status: three values, fail-closed
12
+
13
+ | status | Meaning |
14
+ |---|---|
15
+ | `passed` | Zero exit code, no timeout, not killed by a signal |
16
+ | `failed` | Non-zero exit / timeout / signal |
17
+ | `unverified` | **Could not collect**: failed to start, data missing. Never means "no problem" |
18
+
19
+ `unverified` is never treated as a pass by any gate (three-valued logic, [Policy guide](03-policy-guide.md), Chinese). Fail-closed is kernel semantics, not a convention.
20
+
21
+ ## Grades L0–L4
22
+
23
+ `L0` self-report → `L1` static check → `L2` real local execution (the default grade for command readback) → `L3` post-deployment verification → `L4` production readback. Gates state their requirement with `minGrade` (for example a merge floor of L2; closing a production switch needs L4).
24
+
25
+ **Verification pyramid warning (the most expensive lesson of the thirty-round campaign)**: the marginal value of polishing a lower layer toward theoretical completeness is far below moving one layer closer to the real machine one step earlier. In practice a 7,400-line L3 suite was polished to its limit, while the four real release blockers (systemd parsing behaviour, deployment/service identity split, probe budgets calibrated against a stand-in, TLS ref format) **were all structurally invisible to L3** and were found in one evening at L4. Rule of thumb: **move up a layer as soon as the simulated layer has zero real defect classes left; do not chase theoretical completeness**. Similarly, re-running the full verify when the candidate touched only a part is pure repetition; caching or trimming by content hash belongs to the envelope layer (the campaign measured 25 → 13 minutes) and the kernel does not do it for you: cache correctness depends on assumptions about a stable environment, which the envelope owner carries.
26
+
27
+ ## Preflight is not evidence
28
+
29
+ `buildbeat preflight --config <run-config> --step <id>` dry-runs one step's worker command directly in the main checkout: no worktree, no ledger, no evidence of any kind (the output carries a `PREFLIGHT (dry signal, never evidence)` banner and the environment variable `BUILDBEAT_PREFLIGHT=1`). Its purpose is a minute-scale loop that reaches the first failure boundary before entering a Run (in the campaign every harness defect cost a whole Run round; preflight mode dismantled them in one evening). **Anything preflight finds counts only once a Run reproduces it.**
30
+
31
+ ## Candidate scope
32
+
33
+ Evidence is bound to the candidate through `subject`: the merge gate counts only the current candidate's evidence; records from old candidates or old review rounds are not mixed in (a real-incident regression, see the `fix-loop` eval).
34
+
35
+ ## observe: production joins the evidence plane (v0)
36
+
37
+ Frozen in [`RFC-0003 §8`](../RFC-0003-workflow-policy.md) (Chinese), implemented in M5 (`src/v2/observe/`):
38
+
39
+ - **Providers** (project probes such as drift checks and live status) produce records under the same Evidence Contract into a separate observe ledger (same chain verification, `.buildbeat/runtime/observe/`); a broken probe is `unverified` (default severity warn), never silent;
40
+ - **Three bands** (thresholds configurable, order fixed): `log` records only → `diagnose` triggers a read-only diagnostic command and produces `diagnosis` evidence → `intent` writes an Intent **draft** into the Git plane at `delivery/observe/intents/` (never executed automatically);
41
+ - **Human triage**: `observe triage --action fix_now|schedule|dismiss`. After `fix_now` a human carries it into a software-delivery Run and the loop closes; `dismiss` feeds the bands back so the same fingerprint is not queued again until its severity rises (alert-fatigue protection); the triage outcome is written into the draft file itself and survives deleting the runtime (invariant 23);
42
+ - **Scheduling boundary in v0**: the `schedule` field is parsed and recorded but there is no built-in scheduler; periodic runs are the host's cron calling `observe run` repeatedly.
43
+
44
+ ## Completeness
45
+
46
+ `buildbeat metrics` prints evidence completeness (steps with evidence / steps that should have it); the M4/M5 exit line is ≥ 95%, the pilots measured 100%.
47
+
48
+ ## Live readings are not evidence
49
+
50
+ > Since 2.0.0-beta.4 (iteration 08).
51
+ While a step runs, the Shell Adapter streams the worker's stdout/stderr to `.buildbeat/runtime/runs/<RUN>/<step>-<n>.{stdout,stderr}.live` and keeps a `live.json` (command, start time). These are **readings**: `status` uses them to answer "is it still moving, for how long, when was the last output", and they are reclaimed as soon as the step ends; the evidence log is still produced by readback, and the digest still binds the final log. Durations likewise: per-step elapsed time and the repository's historical median (`typical step duration` in `metrics`) are derived from ledger timestamps and enter neither the ledger nor the run-record.
@@ -1,5 +1,7 @@
1
1
  # Evidence 指南
2
2
 
3
+ **简体中文** | [English](06-evidence-guide.en.md)
4
+
3
5
  权威:[`RFC-0002 §4`](../RFC-0002-domain-model.md);实现:`src/v2/evidence/collector.js`、`src/v2/observe/`。核心:**证据是 Runner 回读到的事实,不是 Worker 的自述**。
4
6
 
5
7
  ## 证据记录的形状