@haiyangbg/buildbeat 3.0.0 → 3.0.1
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.
- package/CHANGELOG.md +7 -0
- package/README.en.md +4 -4
- package/README.md +1 -1
- package/SKILL.md +1 -1
- package/docs/README.md +3 -2
- package/docs/RELEASING.md +3 -1
- package/docs/v2/guide/01-quickstart.en.md +163 -0
- package/docs/v2/guide/01-quickstart.md +4 -2
- package/docs/v2/guide/06-evidence-guide.en.md +51 -0
- package/docs/v2/guide/06-evidence-guide.md +2 -0
- package/docs/v2/guide/07-approval-guide.en.md +115 -0
- package/docs/v2/guide/07-approval-guide.md +2 -0
- package/docs/v2/guide/10-recovery.en.md +83 -0
- package/docs/v2/guide/10-recovery.md +2 -0
- package/docs/v2/guide/README.md +4 -4
- package/example/.buildbeat/notify.yaml +13 -0
- package/example/.buildbeat/observe.yaml +31 -0
- package/example/AGENTS.md +73 -0
- package/example/BUILDBEAT.md +14 -0
- package/example/CLAUDE.md +7 -0
- package/example/README.md +25 -0
- package/example/delivery/envelope/prompts/builder.md +10 -0
- package/example/delivery/envelope/prompts/fixer.md +10 -0
- package/example/delivery/envelope/prompts/reviewer.md +13 -0
- package/example/delivery/envelope/worker.sh +70 -0
- package/example/delivery/work/WORK-EXPORT-DATE-FILTER/decisions.jsonl +3 -0
- package/example/delivery/work/WORK-EXPORT-DATE-FILTER/intent.md +24 -0
- package/example/delivery/work/WORK-EXPORT-DATE-FILTER/plan.md +20 -0
- package/example/delivery/work/WORK-EXPORT-DATE-FILTER/run-config.yaml +66 -0
- package/example/delivery/work/WORK-EXPORT-DATE-FILTER/runs/RUN-EXPORT-01/run-record.json +108 -0
- package/example/delivery/work/WORK-EXPORT-DATE-FILTER/workflow.yaml +44 -0
- package/example/gitignore.template +20 -0
- package/example/package.json +13 -0
- package/example/pm/decisions.md +8 -0
- package/example/src/export.js +25 -0
- package/example/src/ledger.js +16 -0
- package/example/tests/export.test.js +35 -0
- package/example//346/214/207/346/214/245/345/217/260.md +40 -0
- package/package.json +2 -1
package/docs/v2/guide/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
| 文档 | 一句话 |
|
|
8
8
|
|---|---|
|
|
9
9
|
| [怎么和会话说话](00-how-to-talk.md) | **给用户看的**:项目从未开始到换期,每个阶段你说什么、会话做什么、你得到什么 |
|
|
10
|
-
| [快速开始](01-quickstart.md) | 第一个 Run:装 `@latest` → 工作项与 run 配置 → accept → doctor → start → 看证据拍板;含失败分支 |
|
|
10
|
+
| [快速开始](01-quickstart.md) · [English](01-quickstart.en.md) | 第一个 Run:装 `@latest` → 工作项与 run 配置 → accept → doctor → start → 看证据拍板;含失败分支 |
|
|
11
11
|
| [`templates/v2/`](../../../templates/v2/AGENTS.md) | 项目装载入口(AGENTS / CLAUDE / 指挥台 / BUILDBEAT 标记)、run 配置样板、信封 prompt 与 worker 包装 |
|
|
12
12
|
|
|
13
13
|
在 AI 会话里用的人只需读第 0 篇;会话读 `SKILL.md` §0.5 驾驶手册。
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
|
|
17
17
|
| 文档 | 一句话 |
|
|
18
18
|
|---|---|
|
|
19
|
-
| [Human Approval 指南](07-approval-guide.md) | inbox / approve / stale;接受、批准某转换、合并决定五词各指什么;分诊门;等待要能找到人;overview |
|
|
20
|
-
| [Evidence 指南](06-evidence-guide.md) | 回读制证据、状态/等级、UNVERIFIED 文化、observe |
|
|
19
|
+
| [Human Approval 指南](07-approval-guide.md) · [English](07-approval-guide.en.md) | inbox / approve / stale;接受、批准某转换、合并决定五词各指什么;分诊门;等待要能找到人;overview |
|
|
20
|
+
| [Evidence 指南](06-evidence-guide.md) · [English](06-evidence-guide.en.md) | 回读制证据、状态/等级、UNVERIFIED 文化、observe |
|
|
21
21
|
| [跨会话与团队接续](11-session-handoff.md) · [English](11-session-handoff.en.md) | 上下文落盘、关闭旧聊天、新成员接手、跨工具与跨机器边界 |
|
|
22
|
-
| [故障恢复手册](10-recovery.md) | 台账损坏、Run 中断、infra 停人、锁、runtime 全删重建、gc |
|
|
22
|
+
| [故障恢复手册](10-recovery.md) · [English](10-recovery.en.md) | 台账损坏、Run 中断、infra 停人、锁、runtime 全删重建、gc |
|
|
23
23
|
|
|
24
24
|
## 配置参考
|
|
25
25
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# 通知通道样例。URL 只能来自环境变量(这里是 BUILDBEAT_NOTIFY_URL),永远不写进 Git;
|
|
2
|
+
# 变量没设置就静默跳过、不影响 Run(fail-open)。【BOOTSTRAP】决策:简账先不接通知,
|
|
3
|
+
# 所以所有者没有 export 这个变量,等待只在 inbox 里;要开就 export 一个 webhook 地址。
|
|
4
|
+
kind: notify
|
|
5
|
+
version: 1
|
|
6
|
+
channels:
|
|
7
|
+
- id: owner-webhook
|
|
8
|
+
type: webhook
|
|
9
|
+
urlEnv: BUILDBEAT_NOTIFY_URL
|
|
10
|
+
events:
|
|
11
|
+
- HUMAN_REQUESTED
|
|
12
|
+
- RUN_TERMINAL
|
|
13
|
+
- STALLED
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# observe 配置样例:一次 `buildbeat observe run --config .buildbeat/observe.yaml` = 一轮只读体检。
|
|
2
|
+
# 简账没有线上环境,这里只挂一个"测试还绿吗"的探针,示范 provider 的形状;真实项目换成部署平台的只读查询。
|
|
3
|
+
kind: workflow
|
|
4
|
+
version: 1
|
|
5
|
+
name: observe
|
|
6
|
+
providers:
|
|
7
|
+
- id: tests-green
|
|
8
|
+
command: bash
|
|
9
|
+
args:
|
|
10
|
+
- -lc
|
|
11
|
+
- npm test
|
|
12
|
+
schedule: manual
|
|
13
|
+
evidence:
|
|
14
|
+
kind: health
|
|
15
|
+
subject: jianzhang-tests
|
|
16
|
+
severity:
|
|
17
|
+
failed: error
|
|
18
|
+
unverified: warn
|
|
19
|
+
bands:
|
|
20
|
+
- level: log
|
|
21
|
+
when: "severity >= info"
|
|
22
|
+
- level: diagnose
|
|
23
|
+
when: "severity >= error"
|
|
24
|
+
- level: intent
|
|
25
|
+
when: "severity >= error"
|
|
26
|
+
triage:
|
|
27
|
+
actions:
|
|
28
|
+
- fix_now
|
|
29
|
+
- schedule
|
|
30
|
+
- dismiss
|
|
31
|
+
dismissFeedback: bands
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# AGENTS.md — 简账 工作区 · BuildBeat 协作契约
|
|
2
|
+
|
|
3
|
+
> 本文件走开放标准 `AGENTS.md`,由工作区下的会话按各工具自己的方式装载(Claude Code / Codex / Cursor / Gemini CLI / Aider / Zed 等多数会自动读根目录 `AGENTS.md` 或 `CLAUDE.md`;不自动读的工具由人开场贴给会话——用哪个工具就按它的文档核对一次,不要假设)。目的:每个会话开工即知道「当前工作在哪 / 我是什么视角 / 读哪 / 写哪 / 该调哪条命令」,不靠人转述上下文。
|
|
4
|
+
> **层叠规则**(标准语义):会话从被编辑文件所在目录向上收集沿途所有 `AGENTS.md` 合并,**离得越近优先级越高**。本文件只写全局的(路由 / 协作规则 / 红线),各代码子仓的局部细节写进**该仓自己的 `AGENTS.md`**。
|
|
5
|
+
> 根目录 `CLAUDE.md` 只是一行指针(兼容只认该文件名的工具),内容单点在本文件。单仓项目,没有 `ARCHITECTURE.md` 与 `contracts/`。
|
|
6
|
+
> **本仓运行 BuildBeat**(运行时 `@haiyangbg/buildbeat@3.0.0`,`buildbeat` 由会话调用,人不必手敲)。
|
|
7
|
+
|
|
8
|
+
## 0. 工作怎么发生(一页流程)
|
|
9
|
+
|
|
10
|
+
1. **工作项**:每件事一个 `delivery/work/<WORK-ID>/`(`intent.md` 为什么做 + **止损线**(最多几个 Run / 几轮 review / 几小时,越线先问所有者"继续还是砍")+ `plan.md` 怎么做,可选 `env-facts.md` 记踩出来的环境事实);被 digest 绑定接受(`buildbeat accept`)前只是草稿、不产生义务。`overview` 的 `cost:` 行就是止损线的读数。
|
|
11
|
+
2. **代码工作跑 Run**:`buildbeat start --config <run-config.yaml> --attempt new` → 隔离 worktree 内 Build→Verify→Fix→Review 自动闭环 → **停在合并决定**。push、合并、部署永远是人批之后的人类动作。
|
|
12
|
+
3. **人怎么知道该做什么**:`buildbeat overview --repo .` 回答「每件事走到哪、下一步该谁」;`inbox` 只列等人批的 Run,每条后面附可复制的下一句命令;`status --run <RUN>` 回答「还在动吗、动了多久、卡没卡」。
|
|
13
|
+
4. **上线**:生产动作是人的;`release-readback` 预设 + `release` 风险预设把「做之前回读 → 人做 → 做之后回读 → 观察 → 人关窗」记成 L4 证据,任一步失败即停人批。
|
|
14
|
+
5. **observe 盯生产**:`buildbeat observe run --config .buildbeat/observe.yaml` 一次=一轮只读体检;异常分层(落账→只读诊断→intent 草稿入队 `delivery/observe/intents/`),草稿**绝不自动执行**,人用 `observe triage` 分诊。
|
|
15
|
+
6. **拍板台账**:平台级真实决策包一行进 `pm/decisions.md`(从 `templates/pm/decisions.md` 拷,`pm/` 下只有这一个文件与可选的 `adr/`);Run 级批准落各 Work 的 `decisions.jsonl`;finding 裁决落 `review-findings.jsonl`。单仓项目没有 `contracts/`。
|
|
16
|
+
7. **通知**:`.buildbeat/notify.yaml` 配一条通道(URL 只能来自环境变量),Run 停在人批 / 终态 / 疑似卡住会来找人。
|
|
17
|
+
8. **打扫**:终态 Run 留下的工作树用 `buildbeat gc --repo .` 清(默认只出计划)。工作树在仓内 `.buildbeat/worktrees/`:`.gitignore` 排除 `.buildbeat/runtime/` 与 `.buildbeat/worktrees/`,测试框架的收集范围也要排除 `**/.buildbeat/**`(vitest `exclude`、jest `testPathIgnorePatterns`、pytest `norecursedirs`),否则主干测试会把旧候选的用例一起跑。
|
|
18
|
+
9. **worker 信封**:`delivery/envelope/`(从 `templates/v2/envelope/` 拷)放 `worker.sh` 与 builder / reviewer / fixer 的 prompt,run 配置 `envelope.prompts` 指向它;换工具只改 run 配置里 `--` 后的命令。**worker 环境事实(写进 prompt)**:worker 的沙箱通常**不能监听端口**,需要起服务或绑定 loopback 的集成测试交给 verify 步,worker 只跑单测与静态检查,不要反复尝试;PATH 只认 POSIX 工具(`grep -E` 不用 `rg`,`find` 不用 `fd`)或在 `requires:` 里声明;verify / 包装脚本发现环境不满足(命令不在 PATH、端口被占、后端 404)就 `exit 75`,内核会当基础设施故障停人、不派 fixer、不扣预算。
|
|
19
|
+
|
|
20
|
+
## 1. 工作包路由 —— Builder 端到端负责,会话按 AI 视角隔离
|
|
21
|
+
|
|
22
|
+
> 协作单元是需求/功能工作包(= Work)。一个 Builder 对工作包的产品判断、实现、测试、合并与发布证据端到端负责;下表是可调用的 AI 专业视角和文件写边界,不是人类岗位或固定交接流水线。共享事实走 Git(`delivery/` 与 Run 台账)。
|
|
23
|
+
|
|
24
|
+
| AI 视角 | cwd | 可写(拥有) | 只读 | 开工先读 |
|
|
25
|
+
|---|---|---|---|---|
|
|
26
|
+
| **产品**(规格/编排) | 仓根 | `delivery/**`、`pm/decisions.md` | 全仓 | `buildbeat overview --repo .` |
|
|
27
|
+
| **全栈**(实现) | 仓根 | `src/**`、`tests/**`(Run 内受 `allowedPaths` 机器约束) | `delivery/*` | 所属 Work 的 intent/plan + `run-config.yaml` |
|
|
28
|
+
| **测试**(独立核验) | 仓根 | `tests/**`、独立核验报告(落所属 Work 目录) | 实现 + 规格 | 所属 Work |
|
|
29
|
+
|
|
30
|
+
> 🔴 **边界**:新地盘 `src/export.js` 与 `tests/`;`src/ledger.js` 是记账核心,只维护、改动一律先问人;不得借道写入 `delivery/work/*/runs/`(内核写)。
|
|
31
|
+
> 🔴 **写者≠审者的机器化**:Run 内置 fresh-context 只读 reviewer(快照强制,写入即失败落账);merge 门绑定 candidate + plan + 证据 digest,过期即 stale。
|
|
32
|
+
> **开工/收工护栏**:任意会话开工先各仓 `git pull`,再 `buildbeat overview --repo .`(活动 Work、等人的 Run、成本);收工前再跑一次 `overview` 并把 warning / unverified 原样写进收口。生产状态问 `observe status`,不猜。
|
|
33
|
+
|
|
34
|
+
## 1.5 UI 规范摘要(非 UI 项目可删)
|
|
35
|
+
|
|
36
|
+
- 延用既定设计语言与 token;每个可见界面处理加载 / 空 / 错误 / 移动端四态。
|
|
37
|
+
- **界面零元注释**:上线的可见界面不得出现给"做的人"看的文字;每次上线核查门必查。
|
|
38
|
+
- UI 交付的拍板对象必须含可渲染证据(真渲染入口 + 截图 digest);静态描述不构成拍板对象。
|
|
39
|
+
|
|
40
|
+
## 2. 协作规则
|
|
41
|
+
|
|
42
|
+
**① 唯一入口** —— 活动工作看 `delivery/`(`overview` / `inbox`);不另建进度文件、状态文件或看板,进度由内核从台账与 Git 回读。
|
|
43
|
+
**② 接口先落盘再动手** —— 单仓项目没有跨边界契约;对外导出格式(CSV 列序、日期格式)的变化先写进所属 Work 的 plan 并被接受,再动代码。
|
|
44
|
+
**③ 交接靠 candidate hash + 台账** —— Run 停在合并决定时 candidate 已由 Git 回读固定;跨会话接力读 `delivery/work/<id>/` 即知全部事实,hash 不得编造。
|
|
45
|
+
**④ 护栏与不可逆动作** —— 开工 `overview`;部署/改契约/migration 等不可逆动作前再核一次并走人批;exit 0 不消除 `warning/unverified`。
|
|
46
|
+
**⑤ 风险分轨** —— Risk Preset:`fast`(仅 merge 人批)/ `standard`(plan+merge,默认)/ `controlled`(intent+plan+merge+release)/ `release`(上线回读车道)。
|
|
47
|
+
**⑥ 核查门** —— Run 内 reviewer 只读、结构化 findings;`reviewTriage: required` 时 P0/P1 先过人分诊再派 fixer;review 每 Run 默认 2 轮封顶。**完成 = hash + 可核验证据**;标准轨最低 L3,上线必须 L4。`UNVERIFIED` 永不当作通过。
|
|
48
|
+
**⑦ 状态单点** —— 事实进 Run 证据与 Work 记录;进度看 `overview`,度量看 `metrics`(本地只读)。
|
|
49
|
+
**⑧ 视觉问题带图对比** —— 提 UI bug 必附『实现截图 ⟷ 设计稿截图』并排 + 标注差异点。
|
|
50
|
+
**⑨ 单点事实** —— 线上版本只信实查(`observe status` / 部署平台);任何文档不写「当前线上 vX」;每个收敛后的真实决策包只在 `pm/decisions.md` 记一行;历史台账不回改。
|
|
51
|
+
**⑩ 真渲染拍板** —— 有 UI 的拍板对象必须是真渲染证据。
|
|
52
|
+
**⑪ 所有者可见命名进决策卡** —— 域名、服务名、环境名、自停时长、窗口时长等**所有者以后要看见或要念出来的名字与参数**,不由 worker 顺手定:进 intent 或门前决策卡(`BATCH_AT_GATE`),给推荐值和理由(用业务上听得懂的名字,不用内部术语)。
|
|
53
|
+
|
|
54
|
+
## 2.5 任务包与人批节奏
|
|
55
|
+
|
|
56
|
+
**任务包信封** —— 开工时从用户目标与活动 Work 明确 `objective / in_scope / terminal_condition`(即 Work 的 intent/plan)。默认一个工作包覆盖多个子项;每个会话同时只认领一个。只要仍有安全、可逆、在范围内且能推进目标的工作,会话就继续做,不因子产物完成交还接力棒。
|
|
57
|
+
|
|
58
|
+
**域回复格式** —— 面向用户收口、交接或回复明确检查点时,统一写「已做 → 未做 → 下一步」;已做/未做默认各总结成一句,不习惯性 1234 分条;只有事项性质差异大时才列举,每条仍是"结果+证据"。
|
|
59
|
+
|
|
60
|
+
**审批三级**:`STOP_NOW`(跨发布门 / 扩范围 / 改冻结契约 / 不可逆外部动作 / 接受风险);`BATCH_AT_GATE`(冻结前可逆取舍、默认值、阈值、可见命名——攒到门前一次批 2~5 个);`NO_APPROVAL`(能实查的事实、派生约束、文档归档、普通 P2)。
|
|
61
|
+
|
|
62
|
+
**人批预算** —— 每个工作包、每道门默认 1 个 `BATCH_AT_GATE` 请求;待批项必须带 findings 摘要与风险声明。
|
|
63
|
+
|
|
64
|
+
> **元原则:能实查的不问人** —— 查代码 / 配置 / 部署平台 / `overview` / `status` / `observe status` 能得到的事实,不拿去问用户、不信文档、不信上游转述。
|
|
65
|
+
|
|
66
|
+
## 3. 红线(每个会话受约束)
|
|
67
|
+
|
|
68
|
+
1. **凭据不入 git、不出本机**:文档只标位置不写值;本地 .env gitignore + 600;机器闸 = gitleaks pre-commit;Worker 默认 env 白名单;通知 URL 只能来自环境变量。
|
|
69
|
+
2. **不 `git add -A`**:只 stage 当前工作包拥有的具体文件;各仓分别提交。
|
|
70
|
+
3. **不未授权部署**、不 force-push、不 `--amend` 已推送历史、不 `--no-verify`。Run 的合并决定只表示候选具备合并条件(`SUCCEEDED` ≠ 已合并),合并/push/发布是其后的人类动作、逐项授权。
|
|
71
|
+
4. **每次部署完必更对应仓 `CHANGELOG.md`**;部署后 `observe run` 一轮。
|
|
72
|
+
5. **写者≠审者**:Run 内置只读 reviewer 机器强制;写者转述不构成证据。
|
|
73
|
+
6. **事实分层**:代码已确认事实 / 运行时待核事实 / 拟议需求 / 已实现行为,四类严格分开;未实查一律写「待核」。
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# BUILDBEAT.md — 本项目的 BuildBeat 标记
|
|
2
|
+
|
|
3
|
+
**本项目运行 BuildBeat**:运行时 `@haiyangbg/buildbeat@3.0.0`(2026-09-09 首次接入;查看本机版本 `npm ls -g @haiyangbg/buildbeat`,查看最新 `npm view @haiyangbg/buildbeat@latest version`)
|
|
4
|
+
**装载方式**:会话读根目录 `AGENTS.md`(`CLAUDE.md` 是一行指针);驾驶手册在 BuildBeat Skill `SKILL.md` §0.5
|
|
5
|
+
**活动工作**:`delivery/work/<WORK-ID>/`(intent / plan / run-config / decisions.jsonl / runs/);信封与 worker 包装在 `delivery/envelope/`
|
|
6
|
+
来源:<https://github.com/HaiYangBG1/BuildBeat>
|
|
7
|
+
|
|
8
|
+
## 升级
|
|
9
|
+
|
|
10
|
+
运行时升级只是 `npm install --global @haiyangbg/buildbeat@latest`,对项目文件零改动;升级后更新上面的版本行。模板(`AGENTS.md` / `指挥台.md` / `delivery/envelope/`)对照上游 [CHANGELOG.md](https://github.com/HaiYangBG1/BuildBeat/blob/main/CHANGELOG.md) 中「模板」条目手工同步,拿不准就让会话对比上游 `templates/v2/` 与本项目对应文件。事件 schema 只增不改,旧 Run 台账不需要迁移。
|
|
11
|
+
|
|
12
|
+
## 回灌(比升级更重要)
|
|
13
|
+
|
|
14
|
+
本项目踩到 BuildBeat **没覆盖的新坑**(新反模式 / 机制漏洞)→ 回上游 `lessons.md` 登记一条(症状 → 根因 → 解药),提 issue / PR 或直接改上游仓。只回灌真实事故,不回灌猜想。
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# CLAUDE.md — 指针(🔴 勿在此处写内容)
|
|
2
|
+
|
|
3
|
+
本工作区的会话路由、协作规则、红线,**单点在同目录的 [`AGENTS.md`](AGENTS.md)** —— 请立即读取那份。
|
|
4
|
+
|
|
5
|
+
> 本文件只为兼容「只认 `CLAUDE.md` 这个文件名的工具」而存在,**永远保持这几行**。
|
|
6
|
+
> 往这里复制任何规则 = 两份文档必然漂移(上游 `lessons.md` 第 1 条:SSOT 腐烂)。
|
|
7
|
+
> 也不要改成符号链接:Windows 上 git 默认 `core.symlinks=false`,clone 出来会静默退化成一个内容是路径字符串的普通文件,装载即失效。
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# example/ —— 可直接拷的示例:虚构项目「简账」跑完一个 Work 的快照
|
|
2
|
+
|
|
3
|
+
> 这是一个**单仓、无 UI、一个 Builder 端到端**的最小项目,展示 `templates/` 填好项目事实之后长什么样,以及一个 Work 从立项、接受、Run、合并决定到合并之后,仓库里留下哪些文件。项目、人物、决策全部虚构。
|
|
4
|
+
|
|
5
|
+
## 里面是什么
|
|
6
|
+
|
|
7
|
+
| 路径 | 是什么 | 来源 |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| `AGENTS.md` / `CLAUDE.md` / `指挥台.md` / `BUILDBEAT.md` | 会话装载入口、一行指针、给人看的操作卡、运行时版本标记 | `templates/v2/` 填好项目名、边界、视角路由 |
|
|
10
|
+
| `gitignore.template` | 拷入后改名 `.gitignore`(npm 包不带点文件,所以这里不带点) | `templates/gitignore.template` |
|
|
11
|
+
| `pm/decisions.md` | 平台级拍板台账:接入时的【BOOTSTRAP】决策包和本 Work 的【EXPORT-1】决策包各一行 | `templates/pm/decisions.md` |
|
|
12
|
+
| `.buildbeat/notify.yaml` / `observe.yaml` | 通知通道(URL 只走环境变量)与只读体检配置的样例 | 按 [Approval 指南](../docs/v2/guide/07-approval-guide.md) / [Evidence 指南](../docs/v2/guide/06-evidence-guide.md) |
|
|
13
|
+
| `delivery/envelope/` | worker 包装脚本 + builder / reviewer / fixer 三份 prompt,末尾补了本项目的环境事实 | `templates/v2/envelope/` |
|
|
14
|
+
| `delivery/work/WORK-EXPORT-DATE-FILTER/` | 一个完整的 Work:`intent.md`(为什么 + 止损线)、`plan.md`、`run-config.yaml`、`workflow.yaml`(官方预设的逐字副本)、`decisions.jsonl`、`runs/RUN-EXPORT-01/run-record.json` | 前四份人写;后两份是运行时产出(见下) |
|
|
15
|
+
| `src/` / `tests/` / `package.json` | 应用本体:`ledger.js` 是"老地盘"(只维护),`export.js` 是本 Work 加了日期筛选之后的样子,`npm test` 是 verify 步跑的真实命令 | 虚构 |
|
|
16
|
+
|
|
17
|
+
## 快照的时点与哪些是机器写的
|
|
18
|
+
|
|
19
|
+
快照 = **所有者批准合并决定并合并候选之后**的仓库。`decisions.jsonl` 里的三条(接受 intent、接受 plan、合并决定)和 `runs/RUN-EXPORT-01/run-record.json` 不是手写的:它们是把本目录放进一个一次性 Git 仓库、用脚本 worker 代替 `codex exec` 真跑一遍 `accept → doctor → start → approve` 得到的原始输出,只在拷出时去掉了本机路径(运行时本来就不输出绝对路径)。因此 run-record 里的 `candidate` / `base` 两个 commit 指向那个一次性仓库,在你拷出的仓库里查不到——真项目里它们必须可以 `git cat-file -t` 查到。review 的那条 P2 finding 也是脚本 worker 按 reviewer 合同返回的样例。
|
|
20
|
+
|
|
21
|
+
`tests/example-firstrun.test.js` 锁住两件事:这些工件彼此一致(plan 的 digest 与批准对象一致、无绝对路径),以及把本目录原样拷进一个新仓库后,用脚本 worker 能再起一个 Run(`RUN-EXPORT-02`)跑到合并决定,verify 步跑的是本项目真实的 `npm test`。它不证明某个真实模型能完成任务。
|
|
22
|
+
|
|
23
|
+
## 怎么用它起自己的项目
|
|
24
|
+
|
|
25
|
+
不要整目录照抄——项目名、边界、视角、验证命令都是简账的。按 [SKILL.md](../SKILL.md) §8 的"自查 → 少量提问 → 一屏确认 → 生成"走,让会话从 `templates/` 生成;本目录只用来对照"填好之后应该长什么样"。想手动核对命令,按 [快速开始](../docs/v2/guide/01-quickstart.md):把 `run-config.yaml` 里 `--` 后面的 `codex exec …` 换成你实际用的工具,`accept` 之后 `doctor`,再 `start --attempt new`。
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
你是本 Run 的 builder,在一个隔离的 git worktree 里工作(当前目录)。
|
|
2
|
+
|
|
3
|
+
1. 读环境变量 `BUILDBEAT_INPUT`(JSON):`workId` / `runId` / `step` / `attempt`。目标与计划在 `delivery/work/<workId>/intent.md` 与 `plan.md`——只做 plan 里写的,plan 没写的记到 `delivery/work/<workId>/notes.md` 交给人,不要顺手做。
|
|
4
|
+
2. 只改 run 配置 `allowedPaths` 列出的目录(通常是 `src` 与 `tests`);越界改动不会成为候选。
|
|
5
|
+
3. 不要 `git commit`、不要 `git push`、不要改分支:提交由包装脚本机械完成,push 已被封禁。
|
|
6
|
+
4. 沙箱通常不能监听端口:需要起服务的集成测试交给 verify 步,你只跑单测与静态检查;PATH 只认 POSIX 工具(`grep -E` 不用 `rg`)。
|
|
7
|
+
5. 所有者以后要看见或念出来的名字与参数(域名、服务名、环境名、时长)不由你定:写进 `delivery/work/<workId>/notes.md` 给推荐值与理由,等人批。
|
|
8
|
+
6. 改完自检一次能跑的测试;把做了什么、没做什么、下一步各一句写到 stdout 末尾。
|
|
9
|
+
|
|
10
|
+
本项目(简账)的环境事实:Node ≥ 20,测试命令 `npm test`(`node --test tests/*.test.js`),零依赖、不用装包;沙箱不能监听端口,本项目也没有需要端口的测试;`src/ledger.js` 是老地盘,只维护、不重构;PATH 只认 POSIX 工具。
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
你是本 Run 的 fixer,在隔离的 git worktree 里工作(当前目录)。你只修被指出的问题,不做别的。
|
|
2
|
+
|
|
3
|
+
1. 读环境变量 `BUILDBEAT_INPUT`(JSON):
|
|
4
|
+
- 有 `findings[]`:这是上一轮 review 的结论及裁决状态,**只修 `adjudication` 为 `accepted` 或 `open` 的条目**,`dismissed` 的不碰;
|
|
5
|
+
- 没有 `findings`:说明是 verify 失败进来的。失败日志在主仓 `.buildbeat/runtime/runs/<runId>/logs/verify-<n>.log`(`<n>` 是最近一次 verify 的 attempt;从 worktree 找主仓:`cd "$(git rev-parse --git-common-dir)/.."`),里面有命令、退出码、stdout / stderr。先读日志,再改代码。
|
|
6
|
+
2. 只改 run 配置 `allowedPaths` 列出的目录;不要 `git commit` / `git push`(提交由包装脚本完成,push 已封禁)。
|
|
7
|
+
3. 修不了或问题不在代码(环境缺工具、端口被占、后端 404):不要绕,`exit 75`,内核会当基础设施故障停人。
|
|
8
|
+
4. 改完跑一次相关测试;把修了哪条、没修哪条及原因各一句写到 stdout 末尾。
|
|
9
|
+
|
|
10
|
+
本项目(简账)的环境事实:Node ≥ 20,测试命令 `npm test`(`node --test tests/*.test.js`),零依赖、不用装包;沙箱不能监听端口,本项目也没有需要端口的测试;`src/ledger.js` 是老地盘,只维护、不重构;PATH 只认 POSIX 工具。
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
你是本 Run 的 reviewer,只读:不要改任何文件、不要跑会写盘的命令(写入会被快照比对捕获并按失败落账)。
|
|
2
|
+
|
|
3
|
+
1. 读环境变量 `BUILDBEAT_INPUT`(JSON)。若有 `lastReviewed.range`,只审 `git diff <range>` 的增量;否则审本分支相对 base 的全部改动(`git log --oneline` 与 `git diff HEAD~1` 起步,按需扩大)。
|
|
4
|
+
2. `BUILDBEAT_INPUT.anchor` 是历史 finding 与人的裁决:**已裁决(accepted / dismissed)的结论不得翻案**;同一问题不要换措辞重提。
|
|
5
|
+
3. 对照 `delivery/work/<workId>/plan.md`:做了 plan 没写的事、引入了未经批准的可见命名(域名 / 服务名 / 环境名)→ 记 P2。
|
|
6
|
+
4. 严重度:P0 数据丢失 / 安全 / 不可逆;P1 功能错误或测试未覆盖计划要求的行为;P2 可维护性、命名、边界;P3 建议。只有 P0 / P1 会阻断。
|
|
7
|
+
5. **最后只输出一个 JSON 对象,不要别的文字**(可以裹一层 ```json 代码栏):
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{"status": "succeeded", "findings": [{"severity": "P1", "summary": "一句话,稳定、可复述、不带时间戳"}]}
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
没有问题就 `"findings": []`。每条必须有 `severity`(P0–P3)和 `summary`;缺字段或不是 JSON 会被当成 worker 故障停人,而不是候选缺陷。
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# BuildBeat v2 worker 包装:把任意 CLI Agent 接进 Runner 的信封合同。
|
|
3
|
+
#
|
|
4
|
+
# bash delivery/envelope/worker.sh <role> -- <tool command...>
|
|
5
|
+
# role: builder | fixer | planner(写入步) reviewer(只读步)
|
|
6
|
+
#
|
|
7
|
+
# 做的事(每一条都对应 docs/v2/guide/05-worker-contract.md 的一条合同):
|
|
8
|
+
# 1. 工具不在 PATH → exit 75(EX_TEMPFAIL):内核判基础设施故障停人,不派 fixer、不扣预算;
|
|
9
|
+
# 2. 有 $BUILDBEAT_PROMPT 就把 prompt 文本作为最后一个参数追加给工具(codex exec / claude -p 都吃位置参数);
|
|
10
|
+
# 3. 写入步:工具返回后若工作树有改动,机械地 git add -A && git commit(提交动作不交给模型);
|
|
11
|
+
# 4. 只读步:工具的 stdout 落到 $BUILDBEAT_OUTPUT(工具自己写了该文件则不覆盖);不 commit;
|
|
12
|
+
# 5. 工具退出码原样透传;本脚本自己不判断候选好坏——那是 verify 与 review 的事。
|
|
13
|
+
# cwd 已由内核设为该步的隔离 worktree;不要 cd。
|
|
14
|
+
set -uo pipefail
|
|
15
|
+
|
|
16
|
+
role="${1:-}"
|
|
17
|
+
shift || true
|
|
18
|
+
if [ "${1:-}" = "--" ]; then
|
|
19
|
+
shift
|
|
20
|
+
fi
|
|
21
|
+
if [ -z "$role" ] || [ "$#" -eq 0 ]; then
|
|
22
|
+
echo "usage: worker.sh <builder|fixer|planner|reviewer> -- <tool command...>" >&2
|
|
23
|
+
exit 64
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
tool="$1"
|
|
27
|
+
if ! command -v "$tool" >/dev/null 2>&1; then
|
|
28
|
+
echo "worker.sh: tool not found in PATH: $tool (exit 75 = infrastructure, not a candidate defect)" >&2
|
|
29
|
+
exit 75
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
input="${BUILDBEAT_INPUT:-{}}"
|
|
33
|
+
run_id="$(printf '%s' "$input" | sed -n 's/.*"runId":"\([^"]*\)".*/\1/p')"
|
|
34
|
+
attempt="$(printf '%s' "$input" | sed -n 's/.*"attempt":\([0-9]*\).*/\1/p')"
|
|
35
|
+
|
|
36
|
+
args=("$@")
|
|
37
|
+
if [ -n "${BUILDBEAT_PROMPT:-}" ] && [ -f "$BUILDBEAT_PROMPT" ]; then
|
|
38
|
+
args+=("$(cat "$BUILDBEAT_PROMPT")")
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
case "$role" in
|
|
42
|
+
builder|fixer|planner)
|
|
43
|
+
"${args[@]}"
|
|
44
|
+
status=$?
|
|
45
|
+
if [ -n "$(git status --porcelain 2>/dev/null)" ]; then
|
|
46
|
+
git add -A
|
|
47
|
+
git -c user.name="${GIT_AUTHOR_NAME:-buildbeat-worker}" -c user.email="${GIT_AUTHOR_EMAIL:-worker@buildbeat.local}" \
|
|
48
|
+
commit -q -m "${role}: ${run_id:-run} attempt ${attempt:-?}" || status=$?
|
|
49
|
+
fi
|
|
50
|
+
exit "$status"
|
|
51
|
+
;;
|
|
52
|
+
reviewer)
|
|
53
|
+
if [ -n "${BUILDBEAT_OUTPUT:-}" ]; then
|
|
54
|
+
captured="$(mktemp "${TMPDIR:-/tmp}/bb-review.XXXXXX")"
|
|
55
|
+
"${args[@]}" | tee "$captured"
|
|
56
|
+
status=${PIPESTATUS[0]}
|
|
57
|
+
if [ ! -s "$BUILDBEAT_OUTPUT" ]; then
|
|
58
|
+
cp "$captured" "$BUILDBEAT_OUTPUT"
|
|
59
|
+
fi
|
|
60
|
+
rm -f "$captured"
|
|
61
|
+
exit "$status"
|
|
62
|
+
fi
|
|
63
|
+
"${args[@]}"
|
|
64
|
+
exit $?
|
|
65
|
+
;;
|
|
66
|
+
*)
|
|
67
|
+
echo "worker.sh: unknown role: $role" >&2
|
|
68
|
+
exit 64
|
|
69
|
+
;;
|
|
70
|
+
esac
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
{"ts":"2026-09-09T15:09:50.301Z","decisionRef":"A-WORK-EXPORT-DATE-FILTER-1","decision":"approved","transition":"accept-intent","subject":{"artifact":"intent","digest":"sha256:4e0d96de3ff7c5a1fffc8af268ce91784a515ebcc92e6d5ea035d67ef118da92"},"by":"小周"}
|
|
2
|
+
{"ts":"2026-09-09T15:09:50.350Z","decisionRef":"A-WORK-EXPORT-DATE-FILTER-2","decision":"approved","transition":"accept-plan","subject":{"artifact":"plan","digest":"sha256:4f770dd7b20f14c3e64371ec475ea18f0b82e052fba1f3b8649b04d3ac7ec07a"},"by":"小周"}
|
|
3
|
+
{"ts":"2026-09-09T15:09:51.628Z","run":"RUN-EXPORT-01","decisionRef":"D-RUN-EXPORT-01-1","decision":"approved","transition":"enter-wait-merge","subject":{"candidate":"be7e4f9c4d3d5dcd26132f98f660f9e217c47a97","planDigest":"sha256:4f770dd7b20f14c3e64371ec475ea18f0b82e052fba1f3b8649b04d3ac7ec07a","evidenceDigest":"sha256:7c00d8d23d7d1b3f56006f4686a99bd8b3cc0839f105b524cabadd50dfa04f67"},"by":"小周"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Intent:导出加日期筛选(WORK-EXPORT-DATE-FILTER)
|
|
2
|
+
|
|
3
|
+
## 为什么做
|
|
4
|
+
|
|
5
|
+
月底对账只想看当月流水,现在的 CSV 导出是全量的,用户得在表格里再筛一遍。
|
|
6
|
+
|
|
7
|
+
## 目标
|
|
8
|
+
|
|
9
|
+
`exportCsv(ledger, { from, to })` 支持含端点的日期区间,两端都可以省略;导出格式(列序、金额两位小数)不变。
|
|
10
|
+
|
|
11
|
+
## 非目标
|
|
12
|
+
|
|
13
|
+
- 不动 `src/ledger.js`(老地盘);
|
|
14
|
+
- 不做界面,没有 UI 交付;
|
|
15
|
+
- 不改 CSV 的列和编码。
|
|
16
|
+
|
|
17
|
+
## 止损线
|
|
18
|
+
|
|
19
|
+
最多 2 个 Run、3 轮 review、总计 1 小时 worker 时间;越线先问所有者"继续还是砍"。
|
|
20
|
+
|
|
21
|
+
## 验收条件
|
|
22
|
+
|
|
23
|
+
- `npm test` 全绿,且新增用例覆盖:无边界、单边界、双边界、区间外为空、坏格式、from>to;
|
|
24
|
+
- review 无 P0/P1。
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Plan:导出加日期筛选(WORK-EXPORT-DATE-FILTER)
|
|
2
|
+
|
|
3
|
+
## 修改范围
|
|
4
|
+
|
|
5
|
+
`src/export.js`、`tests/export.test.js`(allowedPaths:`src`、`tests`)。
|
|
6
|
+
|
|
7
|
+
## 实现顺序
|
|
8
|
+
|
|
9
|
+
1. `exportCsv` 增加第二个参数 `options = {}`,读 `from` / `to`;
|
|
10
|
+
2. 两个边界都按 `YYYY-MM-DD` 校验,坏格式抛 `bad date bound`,`from > to` 抛 `is after`(【EXPORT-1】拍板:不静默);
|
|
11
|
+
3. 用字符串比较做含端点筛选(ISO 日期字符串可直接比大小);
|
|
12
|
+
4. `tests/export.test.js` 补:无边界、单边界、双边界、区间外为空、坏格式、from>to。
|
|
13
|
+
|
|
14
|
+
## 测试方法
|
|
15
|
+
|
|
16
|
+
verify 步跑 `npm test`(`node --test tests/*.test.js`),退出码回读为证据。
|
|
17
|
+
|
|
18
|
+
## 风险与回滚
|
|
19
|
+
|
|
20
|
+
只加参数、默认行为不变,老调用方不受影响;候选不合并即无影响,Run 的工作树可整体 `gc`。
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# 简账 · WORK-EXPORT-DATE-FILTER 的 run 配置。路径相对本文件解析。
|
|
2
|
+
# 起跑前:buildbeat doctor --config <本文件>;起跑:buildbeat start --config <本文件> --attempt new
|
|
3
|
+
repo: ../../..
|
|
4
|
+
work: WORK-EXPORT-DATE-FILTER
|
|
5
|
+
run: RUN-EXPORT
|
|
6
|
+
# 从 $(npm root -g)/@haiyangbg/buildbeat/src/v2/presets/software-delivery.yaml 复制到本目录
|
|
7
|
+
workflow: workflow.yaml
|
|
8
|
+
riskPreset: standard
|
|
9
|
+
entry: build
|
|
10
|
+
allowedPaths:
|
|
11
|
+
- src
|
|
12
|
+
- tests
|
|
13
|
+
reviewTriage: required
|
|
14
|
+
# 对应 intent 的止损线:3 轮 review
|
|
15
|
+
budgets:
|
|
16
|
+
maxAttempts:
|
|
17
|
+
review: 2
|
|
18
|
+
reviewRoundsPerWork: 3
|
|
19
|
+
cache:
|
|
20
|
+
verify: tree
|
|
21
|
+
envelope:
|
|
22
|
+
prompts: ../../envelope/prompts
|
|
23
|
+
vars:
|
|
24
|
+
component: export
|
|
25
|
+
redact:
|
|
26
|
+
- "(token|secret|password|TOKEN|SECRET|PASSWORD)=\\S+"
|
|
27
|
+
requires:
|
|
28
|
+
- command: node
|
|
29
|
+
min: "20"
|
|
30
|
+
# 换工具只改 -- 后面的命令
|
|
31
|
+
workers:
|
|
32
|
+
builder:
|
|
33
|
+
command: bash
|
|
34
|
+
args:
|
|
35
|
+
- delivery/envelope/worker.sh
|
|
36
|
+
- builder
|
|
37
|
+
- --
|
|
38
|
+
- codex
|
|
39
|
+
- exec
|
|
40
|
+
- -s
|
|
41
|
+
- workspace-write
|
|
42
|
+
verifier:
|
|
43
|
+
command: bash
|
|
44
|
+
args:
|
|
45
|
+
- -lc
|
|
46
|
+
- npm test
|
|
47
|
+
reviewer:
|
|
48
|
+
command: bash
|
|
49
|
+
args:
|
|
50
|
+
- delivery/envelope/worker.sh
|
|
51
|
+
- reviewer
|
|
52
|
+
- --
|
|
53
|
+
- codex
|
|
54
|
+
- exec
|
|
55
|
+
- -s
|
|
56
|
+
- read-only
|
|
57
|
+
fixer:
|
|
58
|
+
command: bash
|
|
59
|
+
args:
|
|
60
|
+
- delivery/envelope/worker.sh
|
|
61
|
+
- fixer
|
|
62
|
+
- --
|
|
63
|
+
- codex
|
|
64
|
+
- exec
|
|
65
|
+
- -s
|
|
66
|
+
- workspace-write
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
{
|
|
2
|
+
"run": "RUN-EXPORT-01",
|
|
3
|
+
"work": "WORK-EXPORT-DATE-FILTER",
|
|
4
|
+
"workflow": "software-delivery",
|
|
5
|
+
"terminal": {
|
|
6
|
+
"status": "SUCCEEDED",
|
|
7
|
+
"reason": "final decision approved; the external action (merge) stays manual"
|
|
8
|
+
},
|
|
9
|
+
"events": {
|
|
10
|
+
"from": 1,
|
|
11
|
+
"to": 31,
|
|
12
|
+
"lastDigest": "sha256:fb0aad2e3f356dd8cdd3d12c70421536c9033b6bfdac80808023a49df4509dc8"
|
|
13
|
+
},
|
|
14
|
+
"startedAt": "2026-09-09T15:09:50.530Z",
|
|
15
|
+
"finishedAt": "2026-09-09T15:09:51.628Z",
|
|
16
|
+
"attempts": {
|
|
17
|
+
"build": 1,
|
|
18
|
+
"verify": 1,
|
|
19
|
+
"review": 1
|
|
20
|
+
},
|
|
21
|
+
"budgets": {
|
|
22
|
+
"attempts": {
|
|
23
|
+
"consumed": 3,
|
|
24
|
+
"remaining": 1
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"cost": {
|
|
28
|
+
"reviewRounds": 1,
|
|
29
|
+
"humanWaits": 1,
|
|
30
|
+
"infraFailures": 0,
|
|
31
|
+
"workerMs": 853
|
|
32
|
+
},
|
|
33
|
+
"workspaces": {
|
|
34
|
+
"RUN-EXPORT-01": {
|
|
35
|
+
"repo": ".",
|
|
36
|
+
"branch": "run/RUN-EXPORT-01",
|
|
37
|
+
"worktreePath": ".buildbeat/worktrees/RUN-EXPORT-01",
|
|
38
|
+
"base": "8f4ef5d4a4bd75c7765fbec860c3f5cbf1e0d02f",
|
|
39
|
+
"candidate": "be7e4f9c4d3d5dcd26132f98f660f9e217c47a97"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"evidence": [
|
|
43
|
+
{
|
|
44
|
+
"ref": ".buildbeat/runtime/runs/RUN-EXPORT-01/logs/build-1.log",
|
|
45
|
+
"kind": "command",
|
|
46
|
+
"subject": "be7e4f9c4d3d5dcd26132f98f660f9e217c47a97",
|
|
47
|
+
"digest": "sha256:1192f1c2a9a09f23c69d2c3935d2f7a0b3945f2b8aab979f811dd508183755c2",
|
|
48
|
+
"status": "passed",
|
|
49
|
+
"grade": "L2"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"ref": ".buildbeat/runtime/runs/RUN-EXPORT-01/logs/verify-1.log",
|
|
53
|
+
"kind": "command",
|
|
54
|
+
"subject": "be7e4f9c4d3d5dcd26132f98f660f9e217c47a97",
|
|
55
|
+
"digest": "sha256:603a7dd74be408af1575dca2c5a79bc5b211b9de3366812fb70603aa6121fc99",
|
|
56
|
+
"status": "passed",
|
|
57
|
+
"grade": "L2",
|
|
58
|
+
"cacheKey": "sha256:4425cad04706cc2c7f45e5306c573bf756d39d7aa0815d46406810331592e0ea"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"ref": ".buildbeat/runtime/runs/RUN-EXPORT-01/logs/review-1.log",
|
|
62
|
+
"kind": "command",
|
|
63
|
+
"subject": "be7e4f9c4d3d5dcd26132f98f660f9e217c47a97",
|
|
64
|
+
"digest": "sha256:65b9474c69d677a43341ee0af9f6865ca66a6c620d0ca71e7c1d61e6b806913e",
|
|
65
|
+
"status": "passed",
|
|
66
|
+
"grade": "L2"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"ref": ".buildbeat/runtime/runs/RUN-EXPORT-01/outputs/review-1.json",
|
|
70
|
+
"kind": "review",
|
|
71
|
+
"subject": "be7e4f9c4d3d5dcd26132f98f660f9e217c47a97",
|
|
72
|
+
"digest": "sha256:7c00d8d23d7d1b3f56006f4686a99bd8b3cc0839f105b524cabadd50dfa04f67",
|
|
73
|
+
"status": "passed",
|
|
74
|
+
"grade": "L2",
|
|
75
|
+
"findings": [
|
|
76
|
+
{
|
|
77
|
+
"severity": "P2",
|
|
78
|
+
"summary": "日期区间用字符串比较依赖 YYYY-MM-DD 格式,已有校验兜底,但可以在 export.js 顶部注释里写明这个前提"
|
|
79
|
+
}
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
],
|
|
83
|
+
"decisions": [
|
|
84
|
+
{
|
|
85
|
+
"decision": "approved",
|
|
86
|
+
"transition": "enter-wait-merge",
|
|
87
|
+
"subject": {
|
|
88
|
+
"candidate": "be7e4f9c4d3d5dcd26132f98f660f9e217c47a97",
|
|
89
|
+
"planDigest": "sha256:4f770dd7b20f14c3e64371ec475ea18f0b82e052fba1f3b8649b04d3ac7ec07a",
|
|
90
|
+
"evidenceDigest": "sha256:7c00d8d23d7d1b3f56006f4686a99bd8b3cc0839f105b524cabadd50dfa04f67"
|
|
91
|
+
},
|
|
92
|
+
"decisionRef": "D-RUN-EXPORT-01-1"
|
|
93
|
+
}
|
|
94
|
+
],
|
|
95
|
+
"approvals": [
|
|
96
|
+
{
|
|
97
|
+
"decisionRef": "D-RUN-EXPORT-01-1",
|
|
98
|
+
"transition": "enter-wait-merge",
|
|
99
|
+
"subject": {
|
|
100
|
+
"candidate": "be7e4f9c4d3d5dcd26132f98f660f9e217c47a97",
|
|
101
|
+
"planDigest": "sha256:4f770dd7b20f14c3e64371ec475ea18f0b82e052fba1f3b8649b04d3ac7ec07a",
|
|
102
|
+
"evidenceDigest": "sha256:7c00d8d23d7d1b3f56006f4686a99bd8b3cc0839f105b524cabadd50dfa04f67"
|
|
103
|
+
},
|
|
104
|
+
"stale": false
|
|
105
|
+
}
|
|
106
|
+
],
|
|
107
|
+
"unverified": []
|
|
108
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Official software-delivery preset per docs/v2/RFC-0003-workflow-policy.md §2.
|
|
2
|
+
# Step order defines the happy path (each step chains to the next on
|
|
3
|
+
# "succeeded"); fix sits off-path at the end and is reached only via the
|
|
4
|
+
# explicit failure/findings transitions.
|
|
5
|
+
kind: workflow
|
|
6
|
+
version: 1
|
|
7
|
+
name: software-delivery
|
|
8
|
+
entry: intent
|
|
9
|
+
steps:
|
|
10
|
+
- id: intent
|
|
11
|
+
worker: planner
|
|
12
|
+
- id: spec
|
|
13
|
+
worker: planner
|
|
14
|
+
optional: true
|
|
15
|
+
requiredWhen: ui-delivery
|
|
16
|
+
- id: plan
|
|
17
|
+
worker: planner
|
|
18
|
+
- id: build
|
|
19
|
+
worker: builder
|
|
20
|
+
- id: verify
|
|
21
|
+
worker: verifier
|
|
22
|
+
- id: review
|
|
23
|
+
worker: reviewer
|
|
24
|
+
readonly: true
|
|
25
|
+
- id: wait-merge
|
|
26
|
+
- id: fix
|
|
27
|
+
worker: fixer
|
|
28
|
+
transitions:
|
|
29
|
+
- from: verify
|
|
30
|
+
on: failed
|
|
31
|
+
to: fix
|
|
32
|
+
- from: fix
|
|
33
|
+
on: succeeded
|
|
34
|
+
to: verify
|
|
35
|
+
- from: review
|
|
36
|
+
on: findings-blocking
|
|
37
|
+
to: fix
|
|
38
|
+
terminal:
|
|
39
|
+
- wait-merge
|
|
40
|
+
# Review rounds are capped by default (deploy-campaign charter: two review
|
|
41
|
+
# rounds per run, then a human). Override per project via budgets.maxAttempts.
|
|
42
|
+
budgets:
|
|
43
|
+
maxAttempts:
|
|
44
|
+
review: 2
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# 拷入新项目根后改名为 .gitignore(模板文件名不带点,避开 cp 通配符丢点文件的坑)
|
|
2
|
+
|
|
3
|
+
# macOS
|
|
4
|
+
.DS_Store
|
|
5
|
+
|
|
6
|
+
# 凭据 / 本地环境(红线①:凭据不入 git)
|
|
7
|
+
*.env
|
|
8
|
+
.env
|
|
9
|
+
.env.*
|
|
10
|
+
*.local
|
|
11
|
+
*.key
|
|
12
|
+
*.pem
|
|
13
|
+
|
|
14
|
+
# BuildBeat v2 运行时面与隔离工作树(可随时整删重建;不入 git)
|
|
15
|
+
# 同时让 rg / 尊重 .gitignore 的工具不再走进旧工作树;vitest / jest 等要另配 exclude,见 docs/v2/guide/02-workflow-guide.md
|
|
16
|
+
.buildbeat/runtime/
|
|
17
|
+
.buildbeat/worktrees/
|
|
18
|
+
|
|
19
|
+
# 单仓项目:没有子仓
|
|
20
|
+
node_modules/
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# decisions — 拍板台账(全工作区唯一决策单点)
|
|
2
|
+
|
|
3
|
+
> **规则(AGENTS ⑨ 单点事实)**:一个真实决策包收敛后,**第一动作 = 在此追加一行**(倒序),然后才去回写受影响的 SSOT(intent/plan/设计稿);「回写」列登记落点,没回写完 = 欠账可见。Run 级批准不进这里,它们由内核落在各 Work 的 `decisions.jsonl`。
|
|
4
|
+
|
|
5
|
+
| 日期 | 拍板人 | 决策包 | 回写(落点 → 状态) |
|
|
6
|
+
|---|---|---|---|
|
|
7
|
+
| 2026-09-09 | 小周 | 【EXPORT-1】导出日期筛选:from/to 含端点;两端都可省;格式只认 `YYYY-MM-DD`,坏格式和 from>to 直接报错不静默;金额列保持两位小数、不加币种 | `delivery/work/WORK-EXPORT-DATE-FILTER/plan.md` → ✅ |
|
|
8
|
+
| 2026-09-09 | 小周 | 【BOOTSTRAP】接入 BuildBeat:单仓、长期做;一个 Builder 端到端;`src/ledger.js` 为老地盘只维护;无 UI;worker 用 `codex exec`;通知先不接(等待只在 inbox 里);`standards/` 不生成 | `AGENTS.md` §1 边界、`delivery/envelope/prompts/*`、`run-config.yaml` → ✅ |
|