@haiyangbg/buildbeat 1.21.0 → 2.0.0-beta.2

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 (75) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.en.md +4 -4
  3. package/README.md +4 -4
  4. package/bin/buildbeat-v2.js +6 -0
  5. package/docs/BuildBeat v2/357/274/232AI /345/216/237/347/224/237/350/275/257/344/273/266/344/272/244/344/273/230/346/216/247/345/210/266/345/271/263/351/235/242.md" +2053 -0
  6. package/docs/CAPABILITY-MATRIX.md +4 -4
  7. package/docs/CLI.md +4 -4
  8. package/docs/EXECUTION-PLAN.md +1 -1
  9. package/docs/RELEASING.md +5 -5
  10. package/docs/ROADMAP.md +4 -1
  11. package/docs/V1.21-RELEASE-EVIDENCE-2026-08-25.md +55 -0
  12. package/docs/V2-D2-DECISION-CARD.md +37 -0
  13. package/docs/V2-DECISIONS.md +11 -0
  14. package/docs/V2-ITERATION-01.md +60 -0
  15. package/docs/V2-ITERATION-02.md +32 -0
  16. package/docs/V2-ITERATION-03.md +30 -0
  17. package/docs/V2-ITERATION-04.md +29 -0
  18. package/docs/V2-ITERATION-05.md +20 -0
  19. package/docs/V2-ITERATION-06.md +18 -0
  20. package/docs/V2-ITERATION-07.md +36 -0
  21. package/docs/V2-PLAN.md +333 -0
  22. package/docs/V2-PROPOSAL.md +319 -0
  23. package/docs/V2.0.0-BETA.1-RELEASE-EVIDENCE-2026-08-28.md +41 -0
  24. package/docs/v2/M1-ACCEPTANCE-2026-08-28.md +38 -0
  25. package/docs/v2/M2-DOD-2026-08-28.md +34 -0
  26. package/docs/v2/M4-CHICKAI-PILOT-2026-08-28.md +44 -0
  27. package/docs/v2/M4-EXTERNAL-PILOT-2026-08-28.md +46 -0
  28. package/docs/v2/M4-SELFHOST-2026-08-28.md +53 -0
  29. package/docs/v2/RFC-0001-product-definition.md +92 -0
  30. package/docs/v2/RFC-0002-domain-model.md +149 -0
  31. package/docs/v2/RFC-0003-workflow-policy.md +204 -0
  32. package/docs/v2/SPEC-0001-events-v1.md +98 -0
  33. package/docs/v2/guide/01-quickstart.md +92 -0
  34. package/docs/v2/guide/02-workflow-guide.md +42 -0
  35. package/docs/v2/guide/03-policy-guide.md +53 -0
  36. package/docs/v2/guide/04-adapter-guide.md +45 -0
  37. package/docs/v2/guide/05-worker-contract.md +37 -0
  38. package/docs/v2/guide/06-evidence-guide.md +38 -0
  39. package/docs/v2/guide/07-approval-guide.md +34 -0
  40. package/docs/v2/guide/08-migration-v1.md +68 -0
  41. package/docs/v2/guide/09-security-boundaries.md +28 -0
  42. package/docs/v2/guide/10-recovery.md +55 -0
  43. package/docs/v2/guide/README.md +18 -0
  44. package/example/.buildbeat/manifest.json +2 -2
  45. package/example/BUILDBEAT.md +1 -1
  46. package/package.json +4 -2
  47. package/src/constants.js +4 -1
  48. package/src/project.js +6 -1
  49. package/src/v2/adapters/mock.js +67 -0
  50. package/src/v2/adapters/shell.js +78 -0
  51. package/src/v2/cli/run.js +494 -0
  52. package/src/v2/domain/event-registry.js +100 -0
  53. package/src/v2/domain/model.js +61 -0
  54. package/src/v2/engine/reducer.js +253 -0
  55. package/src/v2/engine/risk-preset.js +48 -0
  56. package/src/v2/engine/workflow.js +201 -0
  57. package/src/v2/engine/yaml-subset.js +194 -0
  58. package/src/v2/evidence/collector.js +63 -0
  59. package/src/v2/observe/observe-config.js +194 -0
  60. package/src/v2/observe/observe-reducer.js +117 -0
  61. package/src/v2/observe/observe.js +420 -0
  62. package/src/v2/policy/policy.js +302 -0
  63. package/src/v2/presets/observe.yaml +45 -0
  64. package/src/v2/presets/policies/ui-render-gate.yaml +13 -0
  65. package/src/v2/presets/risk/controlled.yaml +39 -0
  66. package/src/v2/presets/risk/fast.yaml +19 -0
  67. package/src/v2/presets/risk/legacy-four-gates.yaml +44 -0
  68. package/src/v2/presets/risk/standard.yaml +28 -0
  69. package/src/v2/presets/software-delivery.yaml +39 -0
  70. package/src/v2/runtime/decisions.js +288 -0
  71. package/src/v2/runtime/metrics.js +140 -0
  72. package/src/v2/runtime/orchestrator.js +754 -0
  73. package/src/v2/runtime/run-record.js +55 -0
  74. package/src/v2/storage/event-ledger.js +154 -0
  75. package/src/v2/workspace/workspace-manager.js +146 -0
@@ -0,0 +1,92 @@
1
+ # RFC-0001:BuildBeat v2 产品定位
2
+
3
+ > 状态:`FINAL`(2026-08-28 项目所有者定稿,`V2-D3`;M0 随三份 RFC 与 [`SPEC-0001-events-v1.md`](SPEC-0001-events-v1.md) 定稿退出)
4
+ > 日期:2026-08-28
5
+ > 上游:[`V2-PLAN.md`](../V2-PLAN.md)(执行基线,`V2-D0=B`);内核范围:完整内核(`V2-D2=A`,[`V2-DECISIONS.md`](../V2-DECISIONS.md))
6
+ > 需求来源:M-1 试点记录——[`pilot/metrics.md`](../../pilot/metrics.md)(能力矩阵 + 卡点 1–5)、[`pilot/evidence/2026-08-28-m1-runtime-gap.md`](../../pilot/evidence/2026-08-28-m1-runtime-gap.md)(F5/F6)、[`V2-ITERATION-01.md`](../V2-ITERATION-01.md)
7
+
8
+ ---
9
+
10
+ ## 1. 定义
11
+
12
+ > **BuildBeat v2 是一个工件驱动的 AI 交付闭环。确定性内核按 Workflow 与 Policy 推进状态,外部 Agent 作为 Worker 执行计划、构建、验证、修复与审查;一切完成以 Runner 回读的真实证据为准;人只在不可委托的判断点被请求最小决策。协议(工件 + 证据 + 决策)永远人机可读、落在 Git——Runner 是引擎,不是协议存在的前提。**
13
+
14
+ 对外定位词可用"AI 原生交付控制面 / 交付闭环"([`V2-PLAN.md`](../V2-PLAN.md) 裁决 #9、D1);**产品之魂是协议**:厂商 runtime 正在被商品化,协议 + 参考实现才是可防守的位置。
15
+
16
+ MVP 核心承诺:
17
+
18
+ > **给 BuildBeat 一个已批准的目标和计划,它会自动完成 Build–Verify–Fix–Review 循环,并携带完整证据停在合并决定前。**
19
+
20
+ ## 2. 是什么 / 不是什么
21
+
22
+ | 是 | 不是 |
23
+ |---|---|
24
+ | 工件协议(Intent/Spec/Plan/Candidate/Evidence/Review/Decision,Git 中,人机可读) | 一个 AI Coding 工具或模型路由平台 |
25
+ | 厂商中立的确定性内核:状态机 / 事件 / Policy,不解释自然语言 | 某家 Agent runtime 的包装层或竞争性 orchestrator |
26
+ | 可恢复的 Agent Loop 运行时(调度 / 重试 / 预算 / 恢复) | 无人值守的自动合并 / 自动部署系统(MVP 停在合并前) |
27
+ | 证据台账:完成以 Runner 回读为准,自然语言声明不算证据 | 效能考核、遥测或排行榜产品(度量本地只读) |
28
+ | 人类升级机制:最小决策请求 + 精确绑定的 Approval | 多人 RBAC / SSO / Web 后台(MVP 之外) |
29
+
30
+ MVP 明确不做的完整清单以报告 B §19.2 为准(多仓、多 Run 并发、后台 daemon、自动 merge/deploy、远程共享等)。
31
+
32
+ ## 3. 用户
33
+
34
+ 第一阶段:使用 Claude Code / Codex / Cursor 等 AI Coding 工具的个人开发者;一人同时驱动多个 AI Worker、希望把 Build–Verify–Fix–Review 连成自动闭环、但保留合并与发布权的场景。后续扩展(远程 Runner、PR/CI 驱动、多仓)不进入 MVP 承诺。
35
+
36
+ ## 4. Runner 的地位
37
+
38
+ Runner 是**引擎**:调度、重试、恢复、预算、staleness 检测只存在于 Runner。但 Runner 不是协议存在的前提——工件是 markdown/YAML,任何 AI 工具无需安装 BuildBeat 即可消费与产出工件。
39
+
40
+ M-1 的核心教训(卡点 1、卡点 5):协议工件齐备但没有 Runner 时,**人仍是节拍器**——三次真实任务自动激活率 `0/3`,"人记得调用薄脚本"不能兑现自动闭环。因此 v2 的 Runner 不是可选增强,而是自动化承诺的唯一载体。
41
+
42
+ ## 5. 手工模式的地位
43
+
44
+ v1 的"Skill-only 完整等价"拆成两个承诺([`V2-PLAN.md`](../V2-PLAN.md) §5):
45
+
46
+ | 承诺 | v2 处置 |
47
+ |---|---|
48
+ | **协议等价** | **保留**。工件人手可写可读;attended 会话(人开任意 AI 工具推进某一步)产出的工件与 headless run 不可区分;任何工具无需安装即可参与 |
49
+ | **自动化等价** | **取消**。手工模式没有调度 / 重试 / 恢复 / 预算 / stale 检测,不假装有 |
50
+
51
+ ## 6. v1 的地位
52
+
53
+ v1 进入 `v1-maintenance` 维护线,只修安全与严重缺陷;npm `latest` 留 v1,`next` 发 v2 预发布;Beta 前 `latest` 不指向 v2。v1 迁移采用半天手工 runbook(装机量 N=1),`migrate-v1` importer 已裁掉(收尾修正三)。旧概念的保留/转换/删除逐项见 [`RFC-0002`](RFC-0002-domain-model.md) §8。
54
+
55
+ ## 7. 自研面与组装面(逐项自研理由)
56
+
57
+ 原则(收尾修正二):**能由厂商 runtime + 薄脚本组装出来的能力一律不自研**;自研只保留厂商结构性不会做的部分。`V2-D2=A` 选择完整内核,不改变这一原则——它只把 M-1 证实"薄脚本做不到"的部分纳入自研面。每一项标注理由与 M-1 证据:
58
+
59
+ ### 7.1 自研面(完整内核范围)
60
+
61
+ | # | 组件 | 自研理由(= 厂商结构性不做) | M-1 证据 |
62
+ |---|---|---|---|
63
+ | 1 | **Run 登记与状态机**(Run/Step 通用状态、转换裁决) | 厂商的"任务"绑定自家会话与账号体系;没有厂商会为跨工具、跨仓的工件协议维护中立状态机 | 卡点 1、卡点 5:无 Run 登记入口,三次任务全部绕过脚本 |
64
+ | 2 | **事件台账 + reducer + 终态压实**(events.jsonl、state 重建、run-record) | 厂商日志是私有格式、随会话消亡、不落 Git;工具中立、可重放、可审计的交付台账没有厂商会提供 | 卡点 1:attempts/token/费用无统一 ledger;度量表全列 `UNVERIFIED` |
65
+ | 3 | **中断恢复**(checkpoint、resume、恢复点裁决) | 厂商的 session resume 只恢复自家会话上下文,不恢复跨 Worker 的交付状态(该继续 Verify、回 Build 还是废弃候选) | F5 = `RECOVERY_MISSING`:重开只能 fail-closed,需人读现场 |
66
+ | 4 | **Approval 对象与 stale 检测**(transition + candidate + planDigest + evidenceDigest 绑定) | 厂商审批是工具内 UI 动作,不产生持久化、跨工具、绑定 digest 的审批对象,更不会在对象变化时自动失效 | F6 = `APPROVAL_STALE_MISSING`;卡点 3:单阶段生产滚动 P1 正是"审批未绑定 rollout plan"的真实事故形态 |
67
+ | 5 | **Policy/Gate 语义检查器 + 强制等级报告**(四类 Policy、`doctor` 报告实际强制等级) | 厂商各有权限系统,但没人会检查"你声称的规则实际达到哪级强制"并跨工具编译到 hook/CI | 边界节:提示词禁令只算 `ADVISORY`;ChickAI 会话始终持有生产能力,未被机器剥离 |
68
+ | 6 | **多 Workspace 绑定**(一个 Work 绑定多仓 candidate 到同一 Decision) | 厂商 Workspace 即"当前打开的仓";跨 meta 仓 + 代码仓的原子绑定是协议层需求 | 卡点 2、卡点 4:ChickAI 与 AI 底座均为 meta+代码多仓,单仓 loop 无法原子关联 |
69
+ | 7 | **统一 Evidence Contract**(回读制证据、grade L0–L4、manifest digest) | 厂商各自产出日志与测试结果,但"什么算证据、谁回读、怎么分级"的合同必须工具中立 | 能力矩阵"证据来源、digest 与未验证范围"= PARTIAL:事后人工汇总、截图无 digest |
70
+
71
+ ### 7.2 组装面(一律不自研)
72
+
73
+ | 能力 | 组装来源 |
74
+ |---|---|
75
+ | Agent 执行本身(计划/编码/修复/审查) | Claude Code / Codex / Cursor 等,经 Shell Adapter 配置化驱动(裁决 #5,不绑厂商) |
76
+ | 测试 / 构建 / lint | 项目自己的命令,Verify 步只回读退出码与报告 |
77
+ | `SERVER_ENFORCED` 强制 | 分支保护、CI、部署平台(BuildBeat 只报告,不重造) |
78
+ | 工具层 hook(`LOCAL_ENFORCED` 的一部分) | 由 gates 配置**编译生成**厂商 hook(如 Claude Code hooks),不自研 hook 机制 |
79
+ | 隔离原语 | git worktree / branch;BuildBeat 只做其上的锁与 candidate 回读 |
80
+ | 触发入口 | 尽量复用宿主机制(git hook / cron / CI 触发调用 `run start`);自研的是 Run 登记与状态,不是定时器 |
81
+
82
+ ## 8. M0 退出核对(本 RFC 承担的部分)
83
+
84
+ - [x] BuildBeat 是什么 / 不是什么 / 谁使用:§1–3
85
+ - [x] Runner 是否核心:§4(引擎,非协议前提;自动化承诺的唯一载体)
86
+ - [x] 手工模式地位:§5(协议等价保留,自动化等价取消)
87
+ - [x] v1 是否继续演进:§6(维护线,不演进)
88
+ - [x] 自研逐项标注"厂商结构性不做":§7
89
+
90
+ ---
91
+
92
+ _核心名词与旧概念处置见 [`RFC-0002`](RFC-0002-domain-model.md);Workflow/Policy/审批语义见 [`RFC-0003`](RFC-0003-workflow-policy.md);事件格式见 [`SPEC-0001-events-v1.md`](SPEC-0001-events-v1.md)。_
@@ -0,0 +1,149 @@
1
+ # RFC-0002:BuildBeat v2 领域模型
2
+
3
+ > 状态:`FINAL`(2026-08-28 项目所有者定稿,`V2-D3`)
4
+ > 日期:2026-08-28
5
+ > 上游:[`V2-PLAN.md`](../V2-PLAN.md) §3–4;报告 B §6 / §13 / §14(经基线裁决修订)
6
+ > 需求来源:[`pilot/metrics.md`](../../pilot/metrics.md) 卡点 1–5;[`pilot/evidence/2026-08-28-m1-runtime-gap.md`](../../pilot/evidence/2026-08-28-m1-runtime-gap.md)
7
+
8
+ ---
9
+
10
+ ## 1. 十三实体
11
+
12
+ | 实体 | 定义 | 权威存放 |
13
+ |---|---|---|
14
+ | **Project** | 项目配置、仓库、Workflow、Policy 和 Adapter 集合 | Git(`.buildbeat/project.yaml`) |
15
+ | **Work** | 一个要达成的用户级结果,生命周期可跨多个 Run | Git(`delivery/work/<id>/work.yaml`) |
16
+ | **Run** | 对一个 Work 的一次具体执行,可失败、重试或被替代 | Runtime(进行中)→ Git(终态压实为 run-record) |
17
+ | **Workflow** | Step、Transition 和默认执行顺序的声明 | Git(`.buildbeat/workflows/`) |
18
+ | **Step** | 一次可调度执行单元(如 plan、build、verify) | Workflow 定义;执行状态在 Runtime |
19
+ | **Worker** | 具有某种能力的逻辑执行者(如 builder、reviewer) | Git(`.buildbeat/workers/`) |
20
+ | **Adapter** | 将 Worker 映射到 Claude / Codex / Shell 或其他执行环境 | Git(`.buildbeat/adapters/`) |
21
+ | **Artifact** | Worker 产生或消费的版本化工件 | Git(`delivery/work/<id>/`) |
22
+ | **Evidence** | 对某个声明进行证明的机器或人工证据 | Git(manifest)+ Runtime(原始日志) |
23
+ | **Policy** | 判断某次转换或动作是否允许的规则 | Git(`.buildbeat/policies/`) |
24
+ | **Decision** | 人类对精确工件或状态转换作出的决定 | Git(`decisions.jsonl`)+ Event |
25
+ | **Event** | Run 中发生的不可变事实记录 | Runtime(events.jsonl);终态摘要压实进 Git |
26
+ | **Workspace** | 某个 Worker 实际工作的隔离目录、分支或 worktree | Runtime 元数据 + git worktree |
27
+
28
+ **Work 与 Run 分离**:一个 Work 可多次 Run,只有一个最终 accepted candidate。M-1 卡点 2/4 的补充要求:**一个 Work 可显式绑定多个 Workspace**(meta 仓 + 代码仓),全部 candidate 由同一 Run 绑定到同一 Decision;MVP 运行时先只支持单仓执行,但领域模型自 day-1 保留多 Workspace 绑定位,防止后续 schema 破坏性变更。
29
+
30
+ ## 2. 状态模型
31
+
32
+ 内核**阶段无关**:只认下列通用状态,`plan/build/review` 等业务阶段由 Workflow 定义。
33
+
34
+ ```text
35
+ Work: OPEN → COMPLETED | CANCELLED
36
+ Run: CREATED → QUEUED → RUNNING → (WAITING_HUMAN | BLOCKED)*
37
+ → SUCCEEDED | FAILED | CANCELLED | SUPERSEDED
38
+ Step: PENDING → READY → RUNNING → SUCCEEDED | FAILED | SKIPPED | CANCELLED
39
+ ```
40
+
41
+ 规则:
42
+
43
+ - Run 终态(SUCCEEDED/FAILED/CANCELLED/SUPERSEDED)默认不可逆,不能被普通事件重新打开(不变量 11);
44
+ - 状态一律由事件派生(reducer),任何手写状态文件不得成为权威来源(不变量 21);
45
+ - 每次状态转换必须对应一个 Event(不变量 5);
46
+ - Worker 永远不能直接修改 Run 状态,其 `suggestedAction` 只是建议(不变量 2)。
47
+
48
+ ## 3. Gate 统一结果(GateResult)
49
+
50
+ ```text
51
+ PASS / RETRY / ROUTE / WAIT_HUMAN / BLOCK / UNVERIFIED
52
+ ```
53
+
54
+ `UNVERIFIED` 永不隐式当作 `PASS`(不变量 7)。语义与转换规则见 [`RFC-0003`](RFC-0003-workflow-policy.md) §3。
55
+
56
+ ## 4. Evidence Contract
57
+
58
+ 字段(报告 B §13 + 基线追加 `grade`):
59
+
60
+ | 字段 | 含义 |
61
+ |---|---|
62
+ | `kind` | test / build / review / screenshot / deployment 等 |
63
+ | `subject` | 所证明的 Artifact 或 candidate |
64
+ | `producer` | Runner / Worker / 外部系统 / 人 |
65
+ | `command` / `exitCode` | 实际执行命令与退出码(适用时) |
66
+ | `startedAt` / `finishedAt` | 执行时间 |
67
+ | `digest` | 证据内容摘要 |
68
+ | `location` | 本地路径或外部权威引用 |
69
+ | `coverage` | 已覆盖和未覆盖范围 |
70
+ | `status` | passed / failed / unverified |
71
+ | `adapter` | 证据来源 Adapter |
72
+ | `grade` | **L0–L4**,v1 证据分级语义原样保留,Policy 可引用最低门槛(如"标准轨合并最低 L3") |
73
+
74
+ 铁律:**Worker 的自然语言总结永远不能单独作为通过证据**;candidate、工作树、测试结果、截图一律由 Runner 回读(M-1 能力矩阵"证据来源"行 PARTIAL 的直接回应:事后人工汇总、截图无 digest 在 v2 结构上不可能)。
75
+
76
+ ## 5. Approval 合同
77
+
78
+ 人批绑定精确对象:
79
+
80
+ ```yaml
81
+ decision: approved | rejected
82
+ transition: review-to-ready-for-merge
83
+ subject:
84
+ candidate: <commit>
85
+ planDigest: sha256:...
86
+ evidenceDigest: sha256:...
87
+ approvedBy: <human>
88
+ approvedAt: <ISO-8601>
89
+ ```
90
+
91
+ 任一受保护输入变化 → `APPROVAL_STALE`,Run 回到 `WAITING_HUMAN`(不变量 3/4/16)。M-1 卡点 3 的追加要求:涉及部署的 Approval subject 还必须能绑定 image digest、rollout plan 与 rollback floor(字段随 `subject` 扩展,additive)。审批动作同时落 `Decision` 事件与 Git 决策记录。
92
+
93
+ ## 6. 存储双平面与终态压实
94
+
95
+ - **Git 平面**:定义类(Workflow/Policy/Worker/standards)、工件类(Intent/Spec/Plan、accepted candidate 引用、Review 报告、Decision、Evidence manifest、Work 摘要)、以及每个终态 Run 的不可变 `run-record.json`。
96
+ - **Runtime 平面**(`.buildbeat/runtime/`,gitignored):events.jsonl(append-only,唯一权威)、state.json(可丢弃重建的加速快照)、锁、会话、临时日志。
97
+
98
+ **终态压实合同**:Run 进入终态后、允许清理 runtime 前,Runner 必须生成 `delivery/work/<id>/runs/<run-id>/run-record.json`,至少固化:事件区间与 digest、起止时间、attempts/budget、终止原因、base/candidate、Evidence manifest digest、Decision/Approval 引用、未验证范围。压实失败不得宣称已归档,也不得清理其 Event Ledger。
99
+
100
+ **硬约束**(不变量 23):删除整个 runtime 目录只损失进行中的 Run 与未承诺保留的原始日志,不损失任何已接受事实或已压实的终态记录;`state.json` 损坏不影响 events.jsonl。
101
+
102
+ ## 7. 核心名词表(消歧)
103
+
104
+ | 名词 | 唯一含义 | 常见误用(禁止) |
105
+ |---|---|---|
106
+ | **candidate** | Workspace 中由 Git 回读固定的候选 commit | ≠ "最新代码";未固定即无 candidate |
107
+ | **accepted** | 经 Decision 明确接受的工件版本 | ≠ "写完了";无 Decision 不算 accepted |
108
+ | **base / baseline** | Run 开始时校验过的基线 commit | ≠ 分支名 |
109
+ | **oracle** | 冻结的验收判据(如 `ACCEPT_CMD`),必须在基线先失败 | ≠ 事后补写的测试 |
110
+ | **evidence** | 满足 §4 合同、由回读产生的记录 | ≠ Worker 的文字总结 |
111
+ | **ledger** | append-only 的 events.jsonl(唯一运行态权威) | ≠ 任何手写日志 |
112
+ | **run-record** | 终态 Run 压实进 Git 的不可变摘要 | ≠ 进行中状态 |
113
+ | **approval** | 绑定 digest 的持久化审批对象 | ≠ 聊天里的"可以" |
114
+ | **stale** | 受保护输入变化导致审批自动失效 | ≠ 超时过期 |
115
+ | **UNVERIFIED** | 无法安全判断,需升级/补证/暂停 | ≠ 默认通过 |
116
+
117
+ ## 8. v1 概念处置表(保留 / 转换 / 删除)
118
+
119
+ 报告 B §17.1 经基线裁决修订后的最终版:
120
+
121
+ | v1 概念 | 处置 | v2 去向 |
122
+ |---|---|---|
123
+ | Evidence-based completion | 保留 | 升级为 Evidence Contract(§4,含 grade L0–L4) |
124
+ | 独立 reviewer(fresh-context、固定 candidate、只读、closure) | 保留 | 升级为标准 Reviewer Worker(M2 迁入) |
125
+ | fail-closed / `UNVERIFIED` | 保留 | 内核化为 GateResult 语义 |
126
+ | Git 版本化事实 | 保留 | 但不承载运行态(双平面,§6) |
127
+ | `AGENTS.md` | 保留 | 项目规则入口;不再承载状态/调度/handoff |
128
+ | `standards/`(STACK/CODE/REVIEW/DESIGN) | 保留 | Policy 输入工件 |
129
+ | 证据分级 L0–L4 | 保留 | Evidence `grade` 字段 |
130
+ | decisions.md | 转换 | Decision 事件 + `decisions.jsonl` + 导出视图 |
131
+ | 固定 Gate1–Gate4 | 转换 | `legacy-four-gates` 迁移预设(非核心) |
132
+ | 产品/全栈/测试三视角 | 转换 | 可选 Worker Preset(非默认) |
133
+ | `pm/changes/` | 转换 | Work + Artifact |
134
+ | `bus-check.sh` | 转换 | 拆为确定性 Evidence Provider + Policy Check |
135
+ | `verify-status.sh` / `drift-check.sh` / `live-status` | 转换 | Evidence Provider(observe 预设,schema 见 RFC-0003 §8) |
136
+ | 三轨(快/标准/重) | 转换 | 三个 Risk Preset(fast/standard/controlled) |
137
+ | `NOW.md` / 当期看板 / `pm/status/{视角}.md` | 删除 | 状态由事件派生;只提供 `*.generated.md` 只读视图 |
138
+ | Skill-only 完整等价 | 拆分 | 协议等价保留、自动化等价取消(RFC-0001 §5) |
139
+ | CLI 不调用 Agent | 删除 | Kernel 确定性、Runner 可调用外部 Agent |
140
+ | `migrate-v1` importer | 删除 | 半天手工 runbook(收尾修正三,装机量 N=1) |
141
+
142
+ ## 9. M0 退出核对(本 RFC 承担的部分)
143
+
144
+ - [x] 十三实体定义与权威存放无歧义:§1
145
+ - [x] 状态模型与派生规则:§2–3
146
+ - [x] Evidence / Approval 合同:§4–5
147
+ - [x] 存储边界(Artifact vs Runtime):§6(报告 B §27 要求 M0 定案的决策点)
148
+ - [x] 核心名词无歧义:§7
149
+ - [x] 旧概念全部标记保留/转换/删除:§8
@@ -0,0 +1,204 @@
1
+ # RFC-0003:BuildBeat v2 Workflow 与 Policy
2
+
3
+ > 状态:`FINAL`(2026-08-28 项目所有者定稿,`V2-D3`;§8 observe/bands schema 已随定稿冻结)
4
+ > 日期:2026-08-28
5
+ > 上游:[`V2-PLAN.md`](../V2-PLAN.md) §3.2–3.7;报告 B §8–11 / WP1.4–1.5 / WP4.3–4.5
6
+ > 需求来源:[`pilot/metrics.md`](../../pilot/metrics.md) 卡点 3/5、故障矩阵 F1–F6;[`pilot/evidence/2026-08-28-m1-runtime-gap.md`](../../pilot/evidence/2026-08-28-m1-runtime-gap.md)
7
+
8
+ ---
9
+
10
+ ## 1. Workflow 文件模型
11
+
12
+ 内核不写死阶段;Workflow 是 Git 中的 YAML 声明(用户配置 YAML,内部以 JSON Schema 校验,schema 文件 M1 WP1.1 落地)。形状 v1:
13
+
14
+ ```yaml
15
+ kind: workflow
16
+ version: 1
17
+ name: software-delivery
18
+ entry: intent
19
+ steps:
20
+ - id: intent
21
+ worker: planner
22
+ - id: spec
23
+ optional: true # 见 §2 spec 规则
24
+ requiredWhen: ui-delivery
25
+ worker: planner
26
+ - id: build
27
+ worker: builder
28
+ - id: verify
29
+ worker: verifier
30
+ # ...
31
+ transitions:
32
+ - from: verify
33
+ on: failed
34
+ to: fix
35
+ - from: review
36
+ on: findings.maxSeverity >= P1
37
+ to: fix
38
+ - from: review
39
+ on: passed
40
+ to: wait-merge # WAITING_HUMAN 终点
41
+ terminal: [wait-merge]
42
+ policies: # 引用 .buildbeat/policies/ 中的定义
43
+ - ref: default
44
+ - ref: protected-actions
45
+ budgets:
46
+ maxAttempts: { build: 4, fix: 4, review-fix: 2 }
47
+ maxSameFailure: 2
48
+ stepTimeout: project-config
49
+ runBudget: project-config
50
+ ```
51
+
52
+ 约束:`entry` 唯一;`terminal` 至少一个;transition 图不得含无出口的非终态环(M1 loop detection);未知字段拒绝加载(fail-closed)。
53
+
54
+ ## 2. 官方预设 `software-delivery`
55
+
56
+ ```text
57
+ Intent → [Spec] → Plan → Build → Verify ⇄ Fix → Independent Review ⇄ Fix → WAIT_HUMAN(merge)
58
+ ```
59
+
60
+ - **Spec 步默认可选;识别到 UI/视觉/交互交付时强制**,且其 Approval subject 必须包含可渲染入口 + 截图 digest(不变量 22;v1 lessons #3 的 v2 化,经 [`V2-PLAN.md`](../V2-PLAN.md) 裁决 #3)。
61
+ - 各步执行规则照报告 B §8.1:Builder 只写授权 Workspace;Fixer 输入必须含失败命令/退出码/日志摘要/candidate/允许范围,不接受泛化的"再检查一下";Reviewer fresh-context、默认只读、不改代码、产出结构化 findings(不变量 9)。
62
+ - MVP 到 merge 决定即暂停,不自动合并(不变量 20)。
63
+
64
+ ## 3. GateResult 语义
65
+
66
+ ```text
67
+ PASS → 进入下一 Step
68
+ RETRY → 重跑当前 Step 或指定修复 Step(受预算约束)
69
+ ROUTE → 转交另一 Worker
70
+ WAIT_HUMAN → 持久化状态并暂停(产生 HUMAN_REQUESTED 事件)
71
+ BLOCK → 确定性终止当前转换
72
+ UNVERIFIED → 无法安全判断;按 Policy 升级、补证或暂停,绝不隐式当 PASS
73
+ ```
74
+
75
+ ## 4. Policy 四类、算子与强制等级
76
+
77
+ ### 4.1 四类
78
+
79
+ | 类型 | 判断 | 例 |
80
+ |---|---|---|
81
+ | 前置(pre) | Step 能否启动 | Plan 已接受、Workspace 干净、依赖工件齐全、预算充足 |
82
+ | 后置(post) | Step 是否真正完成 | 测试通过、Evidence 齐全且达到最低 grade、candidate 已固定 |
83
+ | 转换(transition) | 下一状态 | Verify 失败→Fix;Review P1→Fix;Review 通过→WAIT_HUMAN |
84
+ | Action | Worker 内部危险动作 | merge / push / deploy / publish / migration / 删远端资源 / 改生产配置 |
85
+
86
+ ### 4.2 求值算子 v1(M1 WP1.5 实现集)
87
+
88
+ ```text
89
+ all / any / not
90
+ evidence.exists # 可带 { kind, minGrade }
91
+ artifact.accepted
92
+ attempts.lt
93
+ budget.remaining
94
+ candidate.clean
95
+ human.approved
96
+ finding.maxSeverity
97
+ ```
98
+
99
+ Policy 文件形状:
100
+
101
+ ```yaml
102
+ kind: policy
103
+ version: 1
104
+ name: merge-evidence-floor
105
+ type: transition
106
+ appliesTo: review-to-ready-for-merge
107
+ enforcement: LOCAL_ENFORCED
108
+ rule:
109
+ all:
110
+ - evidence.exists: { kind: test, minGrade: L3 }
111
+ - human.approved: { transition: review-to-ready-for-merge }
112
+ ```
113
+
114
+ ### 4.3 强制三等级
115
+
116
+ | 等级 | 手段 |
117
+ |---|---|
118
+ | `ADVISORY` | prompt / 规则提示 Worker(M-1 边界节确认:提示词禁令只算这一级) |
119
+ | `LOCAL_ENFORCED` | Runner 关卡、Workspace 写路径限制、git hook、工具层 hook(由 gates 配置编译生成,如 Claude Code hooks) |
120
+ | `SERVER_ENFORCED` | 分支保护、CI、部署平台 |
121
+
122
+ `buildbeat doctor` 报告每条 Policy **实际达到**的强制等级,不宣称未强制的规则已被强制(不变量 18)。Protected Actions 的最可靠实现不是提示词,而是不给 Worker 相应凭据与能力(B WP4.4;M-1 能力矩阵"无生产能力"行 PARTIAL 的回应)。
123
+
124
+ ## 5. Approval 与 stale
125
+
126
+ 对象合同见 [`RFC-0002`](RFC-0002-domain-model.md) §5。流程:
127
+
128
+ ```text
129
+ 转换 Policy 判 WAIT_HUMAN
130
+ → HUMAN_REQUESTED 事件(携带 subject digest + findings 摘要 + 风险声明)
131
+ → 人 approve/reject(CLI 展示当前状态、精确对象、candidate、Evidence、风险、批准后动作)
132
+ → DECISION_RECORDED 事件 + Git 决策记录
133
+ → 受保护输入任一变化 → APPROVAL_STALE 事件 → Run 回 WAITING_HUMAN
134
+ ```
135
+
136
+ 秒批率进 metrics(防止人批退化成盖章)。F6 的关闭以本节 + [`SPEC-0001`](SPEC-0001-events-v1.md) 事件为准,验收在 M2。
137
+
138
+ ## 6. Loop 终止条件与 MVP 默认值
139
+
140
+ 任一条件触发即停(报告 B §10 全表采纳):maxAttempts、连续两次相同失败指纹(step + command + exitCode + 错误摘要 + diff digest)、candidate 无实质变化(无进展)、越 Scope 即 `BLOCK`、预算/超时、Workspace 不干净或锁冲突、证据不完整记 `UNVERIFIED`、Adapter 不支持必要强制能力则降级或阻断、人拒绝即 `CANCELLED`。
141
+
142
+ MVP 默认值:
143
+
144
+ ```text
145
+ build/fix 最大尝试:4
146
+ review 修复轮次:2
147
+ 连续相同失败:2
148
+ 单 Step 超时 / 总 Run 预算:项目配置
149
+ ```
150
+
151
+ ## 7. Risk Preset
152
+
153
+ 三个官方预设 + 一个迁移预设(都是 Preset,不是核心固定 Gate):
154
+
155
+ | Preset | 人批点 |
156
+ |---|---|
157
+ | `fast` | 仅 Merge |
158
+ | `standard` | Plan、Merge |
159
+ | `controlled` | Intent、Plan、Merge、Release |
160
+ | `legacy-four-gates` | v1 四 Gate 完整形态(迁移用) |
161
+
162
+ ## 8. observe 预设与 bands schema(随本 RFC 冻结,实现 M5)
163
+
164
+ 裁决 #6:**接口现在冻结,实现推后**。冻结内容为以下 schema 形状与语义;M5 前不实现,但 M1 起任何内核设计不得与之冲突(尤其:Evidence Provider 产出的记录必须能进入同一 Evidence Contract 与事件台账)。
165
+
166
+ ```yaml
167
+ kind: workflow
168
+ version: 1
169
+ name: observe
170
+ providers: # v1 探测器重组为 Evidence Provider
171
+ - id: drift-check
172
+ command: <项目配置>
173
+ schedule: <cron 或 interval>
174
+ evidence: { kind: drift, subject: <deploy-unit> }
175
+ - id: live-status
176
+ command: <项目配置>
177
+ schedule: <cron 或 interval>
178
+ evidence: { kind: runtime-health, subject: <deploy-unit> }
179
+ bands: # 分层响应;层级固定为三层,阈值可配
180
+ - level: log # 层1:只记录事件
181
+ when: <severity 表达式>
182
+ - level: diagnose # 层2:触发只读诊断 Worker
183
+ when: <severity 表达式>
184
+ - level: intent # 层3:生成 Intent 草稿入队(不自动执行)
185
+ when: <severity 表达式>
186
+ triage: # 人分诊
187
+ actions: [fix_now, schedule, dismiss]
188
+ dismissFeedback: bands # dismiss 回调 bands 阈值
189
+ ```
190
+
191
+ 语义冻结点:
192
+
193
+ 1. Provider 输出必须满足 Evidence Contract(含 `status` / `coverage`;采不到即 `UNVERIFIED`);
194
+ 2. bands 只有 log / diagnose / intent 三层,`intent` 层只产生**草稿**入队,接受后才进入 `software-delivery`,闭环成立;
195
+ 3. dismiss 必须回调 bands 阈值(防止告警疲劳单向累积);
196
+ 4. 以上字段 additive-only 演进,破坏性修改需新 `version`。
197
+
198
+ ## 9. M0 退出核对(本 RFC 承担的部分)
199
+
200
+ - [x] GateResult / 转换顺序 / retry / route / block / unverified:§1、§3、§6
201
+ - [x] Human Approval 与 stale:§5
202
+ - [x] Policy 四类 + 算子 + 强制等级:§4
203
+ - [x] Risk Preset 与 legacy 迁移预设:§7
204
+ - [x] observe 与 bands schema 冻结:§8
@@ -0,0 +1,98 @@
1
+ # SPEC-0001:Event Ledger 格式 v1(冻结)
2
+
3
+ > 状态:**FROZEN**(2026-08-28 项目所有者定稿,`V2-D3`;[`V2-PLAN.md`](../V2-PLAN.md) 裁决 #8:格式 day-1 冻结,此后 additive-only)
4
+ > 日期:2026-08-28
5
+ > 冻结范围:**信封字段、通用规则、损坏处理、reducer 合同、初始事件类型注册表的语义**。文件摆放位置、快照格式、CLI 展示均为非规范内容,可变。
6
+ > 演进规则:一切修改 **additive-only**(新增可选字段、新增事件类型);破坏性变更必须升 `v` 并提供旧版读取器。
7
+ > 需求来源:[`pilot/metrics.md`](../../pilot/metrics.md) 卡点 1(无统一 ledger)、卡点 5(无 Run 登记);F5/F6 见 [`pilot/evidence/2026-08-28-m1-runtime-gap.md`](../../pilot/evidence/2026-08-28-m1-runtime-gap.md)
8
+
9
+ ---
10
+
11
+ ## 1. 载体
12
+
13
+ - 每个 Run 一个 ledger:append-only JSONL,UTF-8,每行一个 JSON 对象,`\n` 结尾;
14
+ - 建议路径 `.buildbeat/runtime/runs/<run-id>/events.jsonl`(非规范);
15
+ - 只允许追加,永不改写或删除已有行;追加必须原子(单次 `O_APPEND` 写入完整行);
16
+ - `state.json` 只是加速快照:可丢弃,必须能从 ledger 完整重建(不变量 12/13)。
17
+
18
+ ## 2. 信封(frozen)
19
+
20
+ ```json
21
+ {
22
+ "v": 1,
23
+ "seq": 42,
24
+ "ts": "2026-08-28T04:12:33.201Z",
25
+ "run": "RUN-001",
26
+ "work": "WORK-001",
27
+ "type": "STEP_FINISHED",
28
+ "actor": { "kind": "kernel", "id": "orchestrator" },
29
+ "data": { },
30
+ "prev": "sha256:…",
31
+ "digest": "sha256:…"
32
+ }
33
+ ```
34
+
35
+ | 字段 | 必填 | 规则 |
36
+ |---|---|---|
37
+ | `v` | 是 | 信封版本,本规格恒为 `1`;读取器遇到未知 `v` 必须拒绝,不得猜测 |
38
+ | `seq` | 是 | 每个 Run ledger 内单调递增整数,自 `1` 起,**无间隙** |
39
+ | `ts` | 是 | ISO-8601 UTC,毫秒精度 |
40
+ | `run` / `work` | 是 | 所属 Run / Work ID |
41
+ | `type` | 是 | UPPER_SNAKE,取自 §4 注册表(注册表 additive 扩展) |
42
+ | `actor` | 是 | `kind ∈ {kernel, worker, human, adapter, provider}` + `id` |
43
+ | `data` | 是 | 类型专属载荷(§4);载荷演进 additive-only,破坏性语义变化必须用新 `type` |
44
+ | `prev` | 是 | 前一行事件的 `digest`;首行取 `"sha256:GENESIS"` |
45
+ | `digest` | 是 | 本行除 `digest` 字段外按规范化 JSON(键排序、无空白)序列化后的 sha256 |
46
+
47
+ 未知**信封**字段:读取器必须忽略(向前兼容);未知 `type`:reducer 必须原样保留并跳过,不得报错丢弃(后写的读取器可能认识)。
48
+
49
+ ## 3. 损坏处理(frozen)
50
+
51
+ 1. 逐行校验 `digest` 与 `prev` 链;
52
+ 2. 首个校验失败行即截断点:其后所有行视为不可信,读取器必须显式报告"ledger 在 seq=N 后损坏",不得静默丢弃;
53
+ 3. 截断后的恢复决策升级给人(`WAIT_HUMAN` 语义),内核不得猜测丢失区间;
54
+ 4. 快照与 ledger 冲突时,**ledger 永远是权威**(不变量 21 的运行态版本)。
55
+
56
+ ## 4. 初始事件类型注册表 v1
57
+
58
+ 语义冻结;`data` 列出的字段为该类型的必填最小集,可 additive 扩展。
59
+
60
+ | type | actor | data 最小集 | 语义 |
61
+ |---|---|---|---|
62
+ | `RUN_CREATED` | kernel | `workflowRef, workflowDigest, base, riskPreset` | Run 登记(卡点 5 的回应:没有本事件的工作不得计入 v2 闭环) |
63
+ | `RUN_STARTED` | kernel | —— | 进入 RUNNING |
64
+ | `WORKSPACE_BOUND` | kernel | `workspaceId, repo, branch, worktreePath, base` | 一个 Run 可多次(多仓绑定,卡点 2/4) |
65
+ | `STEP_STARTED` | kernel | `step, attempt, worker, adapter, workspaceId` | Step 开跑 |
66
+ | `STEP_FINISHED` | kernel | `step, attempt, status ∈ {succeeded,failed,blocked,invalid-output,timeout,crashed}, exitCode?` | Adapter 异常退出也必须落此事件(不变量 15) |
67
+ | `CANDIDATE_PINNED` | kernel | `workspaceId, base, candidate` | candidate 由 Git 回读后固定 |
68
+ | `EVIDENCE_RECORDED` | kernel/provider | `evidenceRef, kind, subject, digest, status, grade` | 指向满足 Evidence Contract 的记录 |
69
+ | `POLICY_EVALUATED` | kernel | `policy, phase ∈ {pre,post,transition,action}, result ∈ GateResult, enforcement, reason` | 每次 Policy 裁决可解释 |
70
+ | `TRANSITION` | kernel | `from, to, cause` | 每次状态转换一条(不变量 5) |
71
+ | `FAILURE_FINGERPRINT` | kernel | `step, command, exitCode, errorDigest, diffDigest` | 无进展/相同失败检测的输入 |
72
+ | `BUDGET_CONSUMED` | kernel | `kind ∈ {attempts,tokens,cost,time}, amount, remaining` | 预算台账(卡点 1:token/费用不再 `UNVERIFIED`) |
73
+ | `HUMAN_REQUESTED` | kernel | `transition, subject{candidate,planDigest,evidenceDigest}, reasons` | 进入 WAITING_HUMAN |
74
+ | `DECISION_RECORDED` | human | `decision ∈ {approved,rejected}, transition, subject, decisionRef` | 同步落 Git 决策记录 |
75
+ | `APPROVAL_STALE` | kernel | `approvalRef, changed ⊆ {candidate,plan,evidence}` | F6 的机器化 |
76
+ | `CHECKPOINT` | kernel | `resumePoint{step,attempt}, workspaceStates[]` | F5 的机器化:恢复只允许从最近 CHECKPOINT 或安全推导点继续 |
77
+ | `RUN_INTERRUPTED` | kernel | `cause` | 尽力而为;崩溃时允许缺失,恢复逻辑不得依赖其存在 |
78
+ | `RUN_TERMINAL` | kernel | `status ∈ {SUCCEEDED,FAILED,CANCELLED,SUPERSEDED}, reason` | 终态默认不可逆(不变量 11) |
79
+ | `RUN_COMPACTED` | kernel | `runRecordRef, runRecordDigest` | 终态压实完成;无此事件不得清理 ledger |
80
+
81
+ ## 5. Reducer 合同(frozen)
82
+
83
+ - 确定性:同一 ledger 任意次 replay 必须得到相同状态(Run/Step 状态、attempts、budgets、当前 candidate、待批请求、evidence coverage);
84
+ - 非法转换在 append 前拒绝(写侧校验),reducer 遇到历史非法序列必须报告而非修补;
85
+ - 恢复流程:读 ledger → 校验链 → replay → 定位最近 `CHECKPOINT` / 安全推导点 → 继续或 `WAIT_HUMAN`。不存在"读会话记忆"这一步(F5 = `RECOVERY_MISSING` 的结构性关闭)。
86
+
87
+ ## 6. 示例(一次 Verify 失败进 Fix)
88
+
89
+ ```json
90
+ {"v":1,"seq":7,"ts":"2026-08-28T04:10:01.000Z","run":"RUN-001","work":"WORK-001","type":"STEP_FINISHED","actor":{"kind":"kernel","id":"orchestrator"},"data":{"step":"verify","attempt":1,"status":"failed","exitCode":1},"prev":"sha256:aa…","digest":"sha256:bb…"}
91
+ {"v":1,"seq":8,"ts":"2026-08-28T04:10:01.050Z","run":"RUN-001","work":"WORK-001","type":"FAILURE_FINGERPRINT","actor":{"kind":"kernel","id":"orchestrator"},"data":{"step":"verify","command":"npm test","exitCode":1,"errorDigest":"sha256:cc…","diffDigest":"sha256:dd…"},"prev":"sha256:bb…","digest":"sha256:ee…"}
92
+ {"v":1,"seq":9,"ts":"2026-08-28T04:10:01.100Z","run":"RUN-001","work":"WORK-001","type":"POLICY_EVALUATED","actor":{"kind":"kernel","id":"orchestrator"},"data":{"policy":"default.verify-failed","phase":"transition","result":"RETRY","enforcement":"LOCAL_ENFORCED","reason":"verify failed, attempts 1/4"},"prev":"sha256:ee…","digest":"sha256:ff…"}
93
+ {"v":1,"seq":10,"ts":"2026-08-28T04:10:01.120Z","run":"RUN-001","work":"WORK-001","type":"TRANSITION","actor":{"kind":"kernel","id":"orchestrator"},"data":{"from":"verify","to":"fix","cause":"policy:default.verify-failed"},"prev":"sha256:ff…","digest":"sha256:gg…"}
94
+ ```
95
+
96
+ ---
97
+
98
+ _M1 WP1.2 按本规格实现 Event Store;`event.schema.json`(WP1.1)以本规格为唯一来源。任何实现与本规格冲突时,先改实现;确需改规格,走 additive 或升 `v`。_
@@ -0,0 +1,92 @@
1
+ # 快速开始(5 分钟)
2
+
3
+ 目标:在一个真实 Git 仓库里,让 v2 Runner 驱动 Build→Verify→Review 自动跑完,**停在合并决定**,由你带着证据拍板。
4
+
5
+ ## 0. 安装
6
+
7
+ ```bash
8
+ npm install -g @haiyangbg/buildbeat@next
9
+ ```
10
+
11
+ Beta 期 `latest` 仍指向 v1;v2 CLI 是独立入口 `buildbeat-v2`(源码检出等价于 `node src/v2/cli/run.js`)。要求 Node ≥ 20,零运行时依赖。
12
+
13
+ ## 1. 准备工作项(Git 面)
14
+
15
+ 在目标仓库建工作项目录并写下意图与计划(它们的 digest 会绑进批准对象):
16
+
17
+ ```bash
18
+ mkdir -p delivery/work/WORK-DEMO-1
19
+ printf "# 意图\n修复 X。\n" > delivery/work/WORK-DEMO-1/intent.md
20
+ printf "# 计划\n1. 改 A;2. 测 B。\n" > delivery/work/WORK-DEMO-1/plan.md
21
+ ```
22
+
23
+ ## 2. 写 run 配置
24
+
25
+ `delivery/work/WORK-DEMO-1/run-config.yaml`(路径相对本文件解析;YAML 为严格子集,无行内 `{}`/`[]`、无锚点):
26
+
27
+ ```yaml
28
+ repo: ../../..
29
+ work: WORK-DEMO-1
30
+ run: RUN-DEMO-1
31
+ workflow: <buildbeat安装目录>/src/v2/presets/software-delivery.yaml
32
+ riskPreset: standard
33
+ entry: build
34
+ allowedPaths:
35
+ - src
36
+ - tests
37
+ workers:
38
+ builder:
39
+ command: codex
40
+ args:
41
+ - exec
42
+ - -s
43
+ - workspace-write
44
+ - 按 delivery/work/WORK-DEMO-1/plan.md 实施,改动后 git commit
45
+ verifier:
46
+ command: bash
47
+ args:
48
+ - -lc
49
+ - npm test
50
+ reviewer:
51
+ command: codex
52
+ args:
53
+ - exec
54
+ - -s
55
+ - read-only
56
+ - 只读审查本分支相对 base 的改动,把 JSON 信封写入 $BUILDBEAT_OUTPUT
57
+ ```
58
+
59
+ Worker 是任意 CLI(codex / claude / 脚本),见 [Adapter 指南](04-adapter-guide.md) 与 [Worker 合同](05-worker-contract.md)。
60
+
61
+ ## 3. 起 Run,停在人批
62
+
63
+ ```bash
64
+ buildbeat-v2 start --config delivery/work/WORK-DEMO-1/run-config.yaml
65
+ ```
66
+
67
+ Runner 会:开隔离 worktree(分支 `run/RUN-DEMO-1`,push 已被物理封禁)→ builder 产出提交并固定 candidate → verifier 真实跑测试(退出码回读为证据)→ reviewer 只读出结构化 findings → 到达 `WAITING_HUMAN`。`standard` 预设下 build 前还要求 plan 是已接受工件:
68
+
69
+ ```bash
70
+ buildbeat-v2 accept --repo . --work WORK-DEMO-1 --artifact plan --by <你的名字>
71
+ ```
72
+
73
+ ## 4. 看证据、拍板
74
+
75
+ ```bash
76
+ buildbeat-v2 inbox --repo .
77
+ buildbeat-v2 status --repo . --run RUN-DEMO-1
78
+ buildbeat-v2 approve --repo . --run RUN-DEMO-1 --transition enter-wait-merge --by <你的名字> --config delivery/work/WORK-DEMO-1/run-config.yaml
79
+ ```
80
+
81
+ 批准即 merge-ready;合并/推送/发布永远是你的动作,Runner 不代劳。被 findings 阻断时会自动路由 fix→verify 重走,超预算或指纹重复则停下交还给你([Approval 指南](07-approval-guide.md)、[Recovery](10-recovery.md))。
82
+
83
+ ## 5. observe:让系统盯生产(v0)
84
+
85
+ ```bash
86
+ cp <buildbeat>/src/v2/presets/observe.yaml .buildbeat/observe.yaml # 改成项目真实探针
87
+ buildbeat-v2 observe run --config .buildbeat/observe.yaml # 一次=一个周期;周期化交给 cron
88
+ buildbeat-v2 observe status --repo .
89
+ buildbeat-v2 observe triage --repo . --intent delivery/observe/intents/INTENT-<fp>.md --action fix_now --by <你>
90
+ ```
91
+
92
+ 探针失败/采不到 → 证据 `failed`/`unverified` → bands 分层(记录→只读诊断→Intent 草稿入队)。草稿**绝不自动执行**;`dismiss` 会回调阈值,同指纹在严重度升级前不再打扰。详见 [Evidence 指南](06-evidence-guide.md) §observe。