@haiyangbg/buildbeat 2.0.2 → 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 +25 -301
- package/README.en.md +9 -22
- package/README.md +6 -19
- package/SKILL.md +169 -220
- package/bin/buildbeat.js +14 -2
- package/docs/CAPABILITY-MATRIX.md +13 -55
- package/docs/README.md +13 -14
- package/docs/RELEASING.md +10 -9
- package/docs/v2/RFC-0001-product-definition.md +2 -0
- package/docs/v2/RFC-0003-workflow-policy.md +2 -0
- package/docs/v2/guide/00-how-to-talk.md +3 -3
- package/docs/v2/guide/01-quickstart.en.md +163 -0
- package/docs/v2/guide/01-quickstart.md +15 -13
- package/docs/v2/guide/03-policy-guide.md +1 -1
- package/docs/v2/guide/06-evidence-guide.en.md +51 -0
- package/docs/v2/guide/06-evidence-guide.md +5 -3
- package/docs/v2/guide/07-approval-guide.en.md +115 -0
- package/docs/v2/guide/07-approval-guide.md +12 -10
- package/docs/v2/guide/10-recovery.en.md +83 -0
- package/docs/v2/guide/10-recovery.md +8 -6
- package/docs/v2/guide/11-session-handoff.en.md +2 -2
- package/docs/v2/guide/11-session-handoff.md +2 -2
- package/docs/v2/guide/README.md +4 -10
- package/example/.buildbeat/notify.yaml +13 -0
- package/example/.buildbeat/observe.yaml +31 -0
- package/example/AGENTS.md +67 -13
- package/example/BUILDBEAT.md +8 -11
- package/example/CLAUDE.md +1 -1
- package/example/README.md +17 -67
- 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 +3 -15
- 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/lessons.md +52 -71
- package/package.json +3 -7
- package/src/v2/cli/run.js +33 -23
- package/src/v2/engine/risk-preset.js +1 -1
- package/src/v2/runtime/notify.js +5 -5
- package/src/v2/runtime/overview.js +7 -7
- package/templates/ARCHITECTURE.md +1 -1
- package/templates/contracts/PROTOCOL.md +2 -10
- package/templates/gitignore.template +0 -3
- package/templates/pm/adr/README.md +1 -1
- package/templates/pm/decisions.md +4 -5
- package/templates/standards/CODE.md +1 -1
- package/templates/standards/DESIGN.md +1 -1
- package/templates/standards/REVIEW.md +2 -2
- package/templates/standards/STACK.md +2 -8
- package/templates/v2/AGENTS.md +18 -18
- package/templates/v2/BUILDBEAT.md +2 -3
- package/templates/v2/CLAUDE.md +1 -1
- package/templates/v2/run-config.example.yaml +1 -1
- package/templates/v2//346/214/207/346/214/245/345/217/260.md +6 -6
- package/bin/buildbeat-v2.js +0 -18
- package/bin/solobaton.js +0 -6
- package/docs/CHECKS.md +0 -326
- package/docs/CLI.md +0 -245
- package/docs/LEGACY-V1.16-MIGRATION.md +0 -54
- package/docs/v2/guide/08-migration-v1.md +0 -72
- package/example/.buildbeat/manifest.json +0 -45
- package/example/ARCHITECTURE.md +0 -39
- package/example/contracts/PROTOCOL.md +0 -38
- package/example/pm/NOW.md +0 -22
- package/example/pm/adr/ADR-0001-local-first-sqlite.md +0 -25
- package/example/pm/adr/README.md +0 -7
- package/example/pm/archive//344/270/200/346/234/237/evidence/gate1.md +0 -5
- package/example/pm/archive//344/270/200/346/234/237/evidence/gate2.md +0 -5
- package/example/pm/archive//344/270/200/346/234/237/evidence/gate3.md +0 -5
- package/example/pm/archive//344/270/200/346/234/237/evidence/gate4.md +0 -5
- package/example/pm/archive//344/270/200/346/234/237/evidence/implementation.md +0 -5
- package/example/pm/status//344/272/247/345/223/201.md +0 -20
- package/example/pm/status//345/205/250/346/240/210.md +0 -15
- package/example/pm/status//346/265/213/350/257/225.md +0 -15
- package/example/pm//344/270/200/346/234/237-/347/234/213/346/235/277.md +0 -97
- package/example/standards/CODE.md +0 -18
- package/example/standards/DESIGN.md +0 -34
- package/example/standards/REVIEW.md +0 -16
- package/example/standards/STACK.md +0 -31
- package/src/cli.js +0 -323
- package/src/constants.js +0 -202
- package/src/doctor.js +0 -267
- package/src/planner.js +0 -251
- package/src/project.js +0 -844
- package/src/upgrader.js +0 -1249
- package/src/v2/presets/risk/legacy-four-gates.yaml +0 -44
- package/src/writer.js +0 -534
- package/templates/.claude/agents/reviewer.md +0 -62
- package/templates/AGENTS.md +0 -85
- package/templates/BUILDBEAT.md +0 -13
- package/templates/CLAUDE.md +0 -7
- package/templates/pm/NOW.md +0 -26
- package/templates/pm/changes/README.md +0 -44
- package/templates/pm/status/README.md +0 -32
- package/templates/pm//345/275/223/346/234/237/347/234/213/346/235/277.md +0 -62
- package/templates/scripts/bus-check.sh +0 -1875
- package/templates/scripts/design-preview.sh +0 -44
- package/templates/scripts/drift-check.sh +0 -112
- package/templates/scripts/pre-commit.sh +0 -74
- package/templates/scripts/verify-status.sh +0 -105
- package/templates//346/214/207/346/214/245/345/217/260.md +0 -58
|
@@ -193,25 +193,25 @@ export function computeOverview(repoRoot, { work = null, repoLabel = "." } = {})
|
|
|
193
193
|
stage = intent.accepted ? "INTENT_ACCEPTED" : "INTENT_DRAFT";
|
|
194
194
|
next = intent.accepted
|
|
195
195
|
? `write delivery/work/${workId}/plan.md, then accept it`
|
|
196
|
-
: `buildbeat
|
|
196
|
+
: `buildbeat accept --repo ${repoLabel} --work ${workId} --artifact intent --by <you>`;
|
|
197
197
|
} else if (!plan.accepted) {
|
|
198
198
|
stage = plan.stale ? "PLAN_STALE" : "PLAN_DRAFT";
|
|
199
|
-
next = `buildbeat
|
|
199
|
+
next = `buildbeat accept --repo ${repoLabel} --work ${workId} --artifact plan --by <you>${plan.stale ? " # plan changed since acceptance" : ""}`;
|
|
200
200
|
} else {
|
|
201
201
|
stage = "READY_TO_RUN";
|
|
202
202
|
const configs = readdirSync(workDir).filter((name) => /^run-config.*\.ya?ml$/.test(name));
|
|
203
203
|
next =
|
|
204
204
|
configs.length > 0
|
|
205
|
-
? `buildbeat
|
|
205
|
+
? `buildbeat start --config delivery/work/${workId}/${configs[0]} --attempt new`
|
|
206
206
|
: `no run-config in delivery/work/${workId}: write one, or close it with a decisions.jsonl row {"transition":"close-work","decision":"closed","subject":{"result":"..."}} if it was doc-only`;
|
|
207
207
|
}
|
|
208
208
|
} else if (latest.status === "RUNNING") {
|
|
209
209
|
stage = "RUNNING";
|
|
210
|
-
next = `buildbeat
|
|
210
|
+
next = `buildbeat status --repo ${repoLabel} --run ${latest.id}`;
|
|
211
211
|
} else if (latest.status === "WAITING_HUMAN") {
|
|
212
212
|
stage = latest.pendingHuman?.kind === "final-decision" ? "MERGE_DECISION" : "WAITING_HUMAN";
|
|
213
213
|
const replies = latest.state ? nextReply({ repoLabel, state: latest.state }) : [];
|
|
214
|
-
next = replies[0] ?? `buildbeat
|
|
214
|
+
next = replies[0] ?? `buildbeat inbox --repo ${repoLabel}`;
|
|
215
215
|
} else if (latest.status === "SUCCEEDED" && isReleaseLane(latest)) {
|
|
216
216
|
// A release-readback lane that reached wait-close and was approved is
|
|
217
217
|
// a closed release window, not "nothing to merge".
|
|
@@ -220,7 +220,7 @@ export function computeOverview(repoRoot, { work = null, repoLabel = "." } = {})
|
|
|
220
220
|
} else if (merged) {
|
|
221
221
|
stage = "MERGED";
|
|
222
222
|
next =
|
|
223
|
-
`candidate ${mergedRun.candidate.slice(0, 7)} (${mergedRun.id}) is on ${mainRef}; release/deploy stays a human action; then buildbeat
|
|
223
|
+
`candidate ${mergedRun.candidate.slice(0, 7)} (${mergedRun.id}) is on ${mainRef}; release/deploy stays a human action; then buildbeat gc --repo ${repoLabel}` +
|
|
224
224
|
(latest.status !== "SUCCEEDED" ? ` # latest run ${latest.id} ended ${latest.status} after the merge` : "");
|
|
225
225
|
} else if (latest.status === "SUCCEEDED") {
|
|
226
226
|
stage = "MERGE_READY";
|
|
@@ -230,7 +230,7 @@ export function computeOverview(repoRoot, { work = null, repoLabel = "." } = {})
|
|
|
230
230
|
} else {
|
|
231
231
|
stage = `STOPPED_${latest.status}`;
|
|
232
232
|
next = plan.accepted
|
|
233
|
-
? `decide: retry (buildbeat
|
|
233
|
+
? `decide: retry (buildbeat start ... --attempt new) or close the work`
|
|
234
234
|
: `plan not accepted (${plan.exists ? "draft" : "missing"}); fix that before another run`;
|
|
235
235
|
}
|
|
236
236
|
rows.push({
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
```
|
|
22
22
|
<项目根>/
|
|
23
|
-
├── AGENTS.md / ARCHITECTURE.md / 指挥台.md /
|
|
23
|
+
├── AGENTS.md / ARCHITECTURE.md / 指挥台.md / BUILDBEAT.md / contracts/ / delivery/ / pm/decisions.md
|
|
24
24
|
├── <代码仓1>/ # ★ <说明>;详见其 AGENTS.md
|
|
25
25
|
└── <代码仓2>/ # ★ <说明>
|
|
26
26
|
```
|
|
@@ -6,17 +6,9 @@
|
|
|
6
6
|
> 同仓内部的"前后端"接口优先用**共享类型/schema 由编译器强制**,不进本文件;本文件只管跨服务、跨语言、跨部署单元的边界。
|
|
7
7
|
|
|
8
8
|
**契约快照对应版本:`<vX.Y.Z>`**(<上线日期>)。
|
|
9
|
-
> 🔴 **线上实况唯一查询口 = `
|
|
9
|
+
> 🔴 **线上实况唯一查询口 = `buildbeat observe status --repo .` 与部署平台实查**;本行只标「本快照写就时对应的版本」,其它文档一律不写「当前线上 vX」(AGENTS ⑨)。
|
|
10
10
|
|
|
11
|
-
>
|
|
12
|
-
|
|
13
|
-
<!-- buildbeat-multirepo-map:v1
|
|
14
|
-
repo=<代码子仓1>|contract=contracts/PROTOCOL.md|deployment=<bus-baseline.json app 名或 n/a>
|
|
15
|
-
-->
|
|
16
|
-
<!-- map 行格式:repo=<子仓路径>|contract=<contracts/*.md 或 n/a>|deployment=<bus-baseline.json app 名或 n/a>[|changelog=<该仓内模块 CHANGELOG 路径>]
|
|
17
|
-
· changelog= 给多模块仓用(根下没有 CHANGELOG,由某个模块 CHANGELOG 承载契约版本);缺省 <repo>/CHANGELOG.md。
|
|
18
|
-
· contract=n/a 表示该仓没有契约版本域(如只读存量前端、npm 包 semver 与契约版本不同域),只登记不核对;不得拿它掩盖真实的契约关系。
|
|
19
|
-
· 被核对的 CHANGELOG 首个已发布 H2 须以契约快照版本开头,如 `## [v1.3 · Deployed 2026-09-05 · <sha> · <流水线>]`。 -->
|
|
11
|
+
> 多仓项目在 §1 按边界逐一列出参与的仓与部署单元;版本对齐由 `release-readback` 车道在上线前后回读,不靠目录名或自然语言猜。
|
|
20
12
|
|
|
21
13
|
---
|
|
22
14
|
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
# decisions — 拍板台账(全工作区唯一决策单点)
|
|
2
2
|
|
|
3
|
-
> **规则(
|
|
4
|
-
> 验收项先分成「人必须取舍的独立变量」与「由已选变量/现有契约推导的约束」:只记录前者;后者直接回写并随候选验收。`3/14 → 11/14 → 14/14`
|
|
5
|
-
>
|
|
6
|
-
> 重轨变更照走 `changes/` delta 提案,此处一行指向提案,不重复正文。
|
|
3
|
+
> **规则(AGENTS ⑨ 单点事实)**:一个真实决策包收敛后,**第一动作 = 在此追加一行**(倒序),然后才去回写受影响的 SSOT(契约/设计稿/intent/plan);「回写」列登记落点,没回写完 = 欠账可见。单个独立决定也可以是一项决策包。Run 级批准不进这里,它们由内核落在各 Work 的 `decisions.jsonl`。
|
|
4
|
+
> 验收项先分成「人必须取舍的独立变量」与「由已选变量/现有契约推导的约束」:只记录前者;后者直接回写并随候选验收。`3/14 → 11/14 → 14/14` 之类部分进度只留在 Work 的 intent/plan 草稿或门前决策卡里,不得制造三条永久拍板。
|
|
5
|
+
> 决策单元沿用决策卡的包ID;用户分轮回答或要求解释时不换号,直到整包收敛后在本表出现一次。
|
|
7
6
|
> 改变核心技术栈、跨仓架构、关键数据模型或长期难回退约束时,按 pm/adr/README.md 建独立 ADR;本表仍追加一行 ADR 索引与实际回写落点。未启用 ADR 目录时不因此报错。
|
|
8
|
-
> 「拍板人」单人项目就固定写你的名/代号;多人或要审计时(
|
|
7
|
+
> 「拍板人」单人项目就固定写你的名/代号;多人或要审计时(合并决定与上线关窗未必同一人批),谁批的由此可查。
|
|
9
8
|
|
|
10
9
|
| 日期 | 拍板人 | 决策包 | 回写(落点 → 状态) |
|
|
11
10
|
|---|---|---|---|
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
- `REVIEW-MUST-003`: 核对受影响自动化测试、真渲染走查和 evidence;完成声明必须可追溯到候选与证据。
|
|
12
12
|
- `REVIEW-MUST-004`: 核对 Secret、鉴权、租户、输入、持久化、依赖与不可逆副作用风险。
|
|
13
13
|
- `REVIEW-SHOULD-001`: 识别不必要复杂度、重复抽象、不可维护分支和缺少回滚路径的设计。
|
|
14
|
-
- `REVIEW-SHOULD-002`:
|
|
14
|
+
- `REVIEW-SHOULD-002`: 核对 intent / plan、decisions 与交付候选一致,不把旧报告复用于变化后的候选。
|
|
15
15
|
|
|
16
16
|
## 项目增量
|
|
17
17
|
|
|
18
18
|
<项目特有 Review 条件>
|
|
19
19
|
|
|
20
|
-
review
|
|
20
|
+
review 何时跑、跑几轮、哪些 finding 阻断,以 run 配置(`reviewTriage`、`budgets`)与 `AGENTS.md` 为准,本文件不新建第二套流程。
|
|
@@ -16,15 +16,9 @@
|
|
|
16
16
|
| CI 与测试 | <CI 与测试命令> | CI workflow / 测试配置 |
|
|
17
17
|
| 供应链 | <许可证 / 供应链约束> | LICENSE / lockfile / 安全策略 |
|
|
18
18
|
|
|
19
|
-
##
|
|
19
|
+
## 可核对事实
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
<!-- buildbeat-stack-baseline:v1
|
|
24
|
-
nodeConstraint=<.nvmrc / engines.node 的精确值;多值重复本行;无则 n/a>
|
|
25
|
-
lockfileKind=<lockfile 文件名;多类重复本行;无则 n/a>
|
|
26
|
-
dockerFromImage=<Dockerfile FROM 镜像;多值重复本行;无则 n/a>
|
|
27
|
-
-->
|
|
21
|
+
上表每一行都要能指回一个仓库事实(`.nvmrc` / `engines.node`、lockfile 文件名、Dockerfile `FROM` 镜像等)。不确定的值保留占位符或标 `n/a`,不猜。Run 配置里的 `requires:`(command / probe)是这些事实的可执行形态,起跑前 fail-closed。
|
|
28
22
|
|
|
29
23
|
## Rules
|
|
30
24
|
|
package/templates/v2/AGENTS.md
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
# AGENTS.md — <项目名> 工作区 · BuildBeat
|
|
1
|
+
# AGENTS.md — <项目名> 工作区 · BuildBeat 协作契约
|
|
2
2
|
|
|
3
3
|
> 本文件走开放标准 `AGENTS.md`,由工作区下的会话按各工具自己的方式装载(Claude Code / Codex / Cursor / Gemini CLI / Aider / Zed 等多数会自动读根目录 `AGENTS.md` 或 `CLAUDE.md`;不自动读的工具由人开场贴给会话——用哪个工具就按它的文档核对一次,不要假设)。目的:每个会话开工即知道「当前工作在哪 / 我是什么视角 / 读哪 / 写哪 / 该调哪条命令」,不靠人转述上下文。
|
|
4
4
|
> **层叠规则**(标准语义):会话从被编辑文件所在目录向上收集沿途所有 `AGENTS.md` 合并,**离得越近优先级越高**。本文件只写全局的(路由 / 协作规则 / 红线),各代码子仓的局部细节写进**该仓自己的 `AGENTS.md`**。
|
|
5
5
|
> 根目录 `CLAUDE.md` 只是一行指针(兼容只认该文件名的工具),内容单点在本文件。全栈总图见 `./ARCHITECTURE.md`,按需读。
|
|
6
|
-
> **本仓运行 BuildBeat
|
|
6
|
+
> **本仓运行 BuildBeat**(运行时 `@haiyangbg/buildbeat@<版本>`,`buildbeat` 由会话调用,人不必手敲)。
|
|
7
7
|
|
|
8
|
-
## 0.
|
|
8
|
+
## 0. 工作怎么发生(一页流程)
|
|
9
9
|
|
|
10
|
-
1. **工作项**:每件事一个 `delivery/work/<WORK-ID>/`(`intent.md` 为什么做 + **止损线**(最多几个 Run / 几轮 review / 几小时,越线先问所有者"继续还是砍")+ `plan.md` 怎么做,可选 `env-facts.md` 记踩出来的环境事实);被 digest 绑定接受(`buildbeat
|
|
11
|
-
2. **代码工作跑 Run**:`buildbeat
|
|
12
|
-
3. **人怎么知道该做什么**:`buildbeat
|
|
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
13
|
4. **上线**:生产动作是人的;`release-readback` 预设 + `release` 风险预设把「做之前回读 → 人做 → 做之后回读 → 观察 → 人关窗」记成 L4 证据,任一步失败即停人批。
|
|
14
|
-
5. **observe 盯生产**:`buildbeat
|
|
15
|
-
6. **拍板台账**:平台级真实决策包一行进 `pm/decisions.md
|
|
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
16
|
7. **通知**:`.buildbeat/notify.yaml` 配一条通道(URL 只能来自环境变量),Run 停在人批 / 终态 / 疑似卡住会来找人。
|
|
17
|
-
8. **打扫**:终态 Run 留下的工作树用 `buildbeat
|
|
17
|
+
8. **打扫**:终态 Run 留下的工作树用 `buildbeat gc --repo .` 清(默认只出计划)。工作树在仓内 `.buildbeat/worktrees/`:`.gitignore` 排除 `.buildbeat/runtime/` 与 `.buildbeat/worktrees/`,测试框架的收集范围也要排除 `**/.buildbeat/**`(vitest `exclude`、jest `testPathIgnorePatterns`、pytest `norecursedirs`),否则主干测试会把旧候选的用例一起跑。
|
|
18
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
19
|
|
|
20
20
|
## 1. 工作包路由 —— Builder 端到端负责,会话按 AI 视角隔离
|
|
21
21
|
|
|
22
|
-
> 协作单元是需求/功能工作包(=
|
|
22
|
+
> 协作单元是需求/功能工作包(= Work)。一个 Builder 对工作包的产品判断、实现、测试、合并与发布证据端到端负责;下表是可调用的 AI 专业视角和文件写边界,不是人类岗位或固定交接流水线。共享事实走 Git(`delivery/` 与 Run 台账)。
|
|
23
23
|
|
|
24
24
|
| AI 视角 | cwd | 可写(拥有) | 只读 | 开工先读 |
|
|
25
25
|
|---|---|---|---|---|
|
|
26
|
-
| **产品**(规格/编排) | 工作区根 | `delivery/**`、`pm/decisions.md`、根规划文档、`contracts/**` | 全仓 | `buildbeat
|
|
26
|
+
| **产品**(规格/编排) | 工作区根 | `delivery/**`、`pm/decisions.md`、根规划文档、`contracts/**` | 全仓 | `buildbeat overview --repo .` |
|
|
27
27
|
| **全栈**(实现,含运维) | `<代码仓>/` | `<代码仓>/**`(Run 内受 `allowedPaths` 机器约束) | `delivery/*`、契约 | 所属 Work 的 intent/plan + `run-config.yaml` |
|
|
28
28
|
| **测试**(契约验证·E2E) | 工作区根 | `tests/**`、独立核验报告(落所属 Work 目录) | 实现 + 规格 + 契约 | 所属 Work + 契约 |
|
|
29
29
|
|
|
30
30
|
> 🔴 **边界(按项目填写)**:<新地盘 / 老地盘 / 只读模块 / 不得借道写入的目录>。
|
|
31
|
-
> 🔴 **写者≠审者的机器化**:
|
|
32
|
-
> **开工/收工护栏**:任意会话开工先各仓 `git pull`,再 `buildbeat
|
|
31
|
+
> 🔴 **写者≠审者的机器化**:Run 内置 fresh-context 只读 reviewer(快照强制,写入即失败落账);merge 门绑定 candidate + plan + 证据 digest,过期即 stale。
|
|
32
|
+
> **开工/收工护栏**:任意会话开工先各仓 `git pull`,再 `buildbeat overview --repo .`(活动 Work、等人的 Run、成本);收工前再跑一次 `overview` 并把 warning / unverified 原样写进收口。生产状态问 `observe status`,不猜。
|
|
33
33
|
|
|
34
34
|
## 1.5 UI 规范摘要(非 UI 项目可删)
|
|
35
35
|
|
|
@@ -37,17 +37,17 @@
|
|
|
37
37
|
- **界面零元注释**:上线的可见界面不得出现给"做的人"看的文字;每次上线核查门必查。
|
|
38
38
|
- UI 交付的拍板对象必须含可渲染证据(真渲染入口 + 截图 digest);静态描述不构成拍板对象。
|
|
39
39
|
|
|
40
|
-
## 2.
|
|
40
|
+
## 2. 协作规则
|
|
41
41
|
|
|
42
|
-
**① 唯一入口** —— 活动工作看 `delivery/`(`overview` / `inbox
|
|
42
|
+
**① 唯一入口** —— 活动工作看 `delivery/`(`overview` / `inbox`);不另建进度文件、状态文件或看板,进度由内核从台账与 Git 回读。
|
|
43
43
|
**② 契约落盘不喊话(双向)** —— 跨边界接口先改 `contracts/` 再动代码;收到协议声明独立核查再信。反向流:实现中发现契约不够用 → 不得就地消化,停下记契约缺口交产品域裁决。
|
|
44
44
|
**③ 交接靠 candidate hash + 台账** —— Run 停在合并决定时 candidate 已由 Git 回读固定;跨会话接力读 `delivery/work/<id>/` 即知全部事实,hash 不得编造。
|
|
45
|
-
**④ 护栏与不可逆动作** —— 开工 `overview
|
|
45
|
+
**④ 护栏与不可逆动作** —— 开工 `overview`;部署/改契约/migration 等不可逆动作前再核一次并走人批;exit 0 不消除 `warning/unverified`。
|
|
46
46
|
**⑤ 风险分轨** —— Risk Preset:`fast`(仅 merge 人批)/ `standard`(plan+merge,默认)/ `controlled`(intent+plan+merge+release)/ `release`(上线回读车道)。
|
|
47
47
|
**⑥ 核查门** —— Run 内 reviewer 只读、结构化 findings;`reviewTriage: required` 时 P0/P1 先过人分诊再派 fixer;review 每 Run 默认 2 轮封顶。**完成 = hash + 可核验证据**;标准轨最低 L3,上线必须 L4。`UNVERIFIED` 永不当作通过。
|
|
48
48
|
**⑦ 状态单点** —— 事实进 Run 证据与 Work 记录;进度看 `overview`,度量看 `metrics`(本地只读)。
|
|
49
49
|
**⑧ 视觉问题带图对比** —— 提 UI bug 必附『实现截图 ⟷ 设计稿截图』并排 + 标注差异点。
|
|
50
|
-
**⑨ 单点事实** —— 线上版本只信实查(`
|
|
50
|
+
**⑨ 单点事实** —— 线上版本只信实查(`observe status` / 部署平台);任何文档不写「当前线上 vX」;每个收敛后的真实决策包只在 `pm/decisions.md` 记一行;历史台账不回改。
|
|
51
51
|
**⑩ 真渲染拍板** —— 有 UI 的拍板对象必须是真渲染证据。
|
|
52
52
|
**⑪ 所有者可见命名进决策卡** —— 域名、服务名、环境名、自停时长、窗口时长等**所有者以后要看见或要念出来的名字与参数**,不由 worker 顺手定:进 intent 或门前决策卡(`BATCH_AT_GATE`),给推荐值和理由(用业务上听得懂的名字,不用内部术语)。
|
|
53
53
|
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
|
|
66
66
|
## 3. 红线(每个会话受约束)
|
|
67
67
|
|
|
68
|
-
1. **凭据不入 git、不出本机**:文档只标位置不写值;本地 .env gitignore + 600;机器闸 = gitleaks pre-commit;
|
|
68
|
+
1. **凭据不入 git、不出本机**:文档只标位置不写值;本地 .env gitignore + 600;机器闸 = gitleaks pre-commit;Worker 默认 env 白名单;通知 URL 只能来自环境变量。
|
|
69
69
|
2. **不 `git add -A`**:只 stage 当前工作包拥有的具体文件;各仓分别提交。
|
|
70
70
|
3. **不未授权部署**、不 force-push、不 `--amend` 已推送历史、不 `--no-verify`。Run 的合并决定只表示候选具备合并条件(`SUCCEEDED` ≠ 已合并),合并/push/发布是其后的人类动作、逐项授权。
|
|
71
71
|
4. **每次部署完必更对应仓 `CHANGELOG.md`**;部署后 `observe run` 一轮。
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
# BUILDBEAT.md — 本项目的 BuildBeat
|
|
1
|
+
# BUILDBEAT.md — 本项目的 BuildBeat 标记
|
|
2
2
|
|
|
3
|
-
**本项目运行 BuildBeat
|
|
3
|
+
**本项目运行 BuildBeat**:运行时 `@haiyangbg/buildbeat@<X.Y.Z>`(<yyyy-mm-dd> 首次接入;查看本机版本 `npm ls -g @haiyangbg/buildbeat`,查看最新 `npm view @haiyangbg/buildbeat@latest version`)
|
|
4
4
|
**装载方式**:会话读根目录 `AGENTS.md`(`CLAUDE.md` 是一行指针);驾驶手册在 BuildBeat Skill `SKILL.md` §0.5
|
|
5
5
|
**活动工作**:`delivery/work/<WORK-ID>/`(intent / plan / run-config / decisions.jsonl / runs/);信封与 worker 包装在 `delivery/envelope/`
|
|
6
|
-
**v1 遗留**:<无 | `pm/NOW.md` 等已于 <yyyy-mm-dd> 冻结只读,禁止双写>
|
|
7
6
|
来源:<https://github.com/HaiYangBG1/BuildBeat>
|
|
8
7
|
|
|
9
8
|
## 升级
|
package/templates/v2/CLAUDE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# CLAUDE.md — 指针(🔴 勿在此处写内容)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
本工作区的会话路由、协作规则、红线,**单点在同目录的 [`AGENTS.md`](AGENTS.md)** —— 请立即读取那份。
|
|
4
4
|
|
|
5
5
|
> 本文件只为兼容「只认 `CLAUDE.md` 这个文件名的工具」而存在,**永远保持这几行**。
|
|
6
6
|
> 往这里复制任何规则 = 两份文档必然漂移(上游 `lessons.md` 第 1 条:SSOT 腐烂)。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# BuildBeat v2 run 配置样板。拷到 delivery/work/<WORK-ID>/run-config.yaml 后改 work / run / allowedPaths / workers。
|
|
2
2
|
# 路径相对本文件解析。严格 YAML 子集:只有块列表与块映射,无行内 [] / {}、无锚点、注释必须独占一行。
|
|
3
|
-
# 起跑前:buildbeat
|
|
3
|
+
# 起跑前:buildbeat doctor --config <本文件>;起跑:buildbeat start --config <本文件> --attempt new
|
|
4
4
|
repo: ../../..
|
|
5
5
|
work: WORK-X
|
|
6
6
|
# 家族名;--attempt new 自动编成 RUN-X-01/02…
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
# 指挥台 — Builder
|
|
1
|
+
# 指挥台 — Builder 怎么驱动工作(忘了怎么开场就看这页)
|
|
2
2
|
|
|
3
|
-
> 本仓运行 BuildBeat
|
|
3
|
+
> 本仓运行 BuildBeat。会话按所用工具的方式装载 `AGENTS.md`(多数工具自动读根目录 `AGENTS.md` / `CLAUDE.md`;不自动读的,开场把它贴给会话);活动工作在 `delivery/`。你基本只需说下面这几句话,命令由会话调、不用你手敲。
|
|
4
4
|
|
|
5
5
|
## 日常六句话
|
|
6
6
|
|
|
7
7
|
| 你想干什么 | 说什么 | 会话背后调什么 |
|
|
8
8
|
|---|---|---|
|
|
9
|
-
| 看现在到哪了、该谁动 | 「当前进度」/「待办是什么」 | `buildbeat
|
|
10
|
-
| 看有什么等我批 | 「有什么要我拍板」 | `buildbeat
|
|
9
|
+
| 看现在到哪了、该谁动 | 「当前进度」/「待办是什么」 | `buildbeat overview --repo .`(每个 Work 的阶段 + 下一步)+ `observe status` |
|
|
10
|
+
| 看有什么等我批 | 「有什么要我拍板」 | `buildbeat inbox --repo .`(每条附可复制的下一句) |
|
|
11
11
|
| 立一件新事 | 「开个 Work:〔一句话目标〕」→ 看完说「接受」 | 建 `delivery/work/<ID>/intent.md + plan.md` → `accept`(digest 绑定) |
|
|
12
|
-
| 让它干活 | 「开工」/「再来一轮」 | 先 `buildbeat
|
|
13
|
-
| 它是不是卡了 | 「怎么样了」/「卡住了吗」 | `buildbeat
|
|
12
|
+
| 让它干活 | 「开工」/「再来一轮」 | 先 `buildbeat doctor --config …`(配置、intent/plan 接受状态、env 姿态、预算),再 `start --config … --attempt new`(自动编号、自动作废旧等待,停在合并决定) |
|
|
13
|
+
| 它是不是卡了 | 「怎么样了」/「卡住了吗」 | `buildbeat status --repo . --run <RUN>`(耗时、历史中位数、最后输出、STALLED) |
|
|
14
14
|
| 拍板 | 「批准 / 拒绝〔RUN-ID〕」;分诊时「这条接受,那条不算」 | `approve` / `reject` / `findings adjudicate`;会话说清批的是哪一步(放行 fixer / 再跑一次 / 合并决定),非终态批准后 `resume` 续跑;合并决定只表示候选够格合并,合并/push/部署逐项另说 |
|
|
15
15
|
|
|
16
16
|
其他:生产报警看 `delivery/observe/intents/` 草稿 → 「fix_now / schedule / dismiss」;上线用 `release-readback` 预设开一个 Run,「我做完了」就是批准 `enter-apply-readback`;「打扫卫生」= `gc --repo .`(先看计划再 `--apply true`)。
|
package/bin/buildbeat-v2.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// v2 runtime CLI entry. The v1 `buildbeat` bin stays frozen on src/cli.js;
|
|
4
|
-
// v2 ships as a separate entry until it takes over `latest`.
|
|
5
|
-
//
|
|
6
|
-
// Guard before loading any module: the kernel uses Node>=20 syntax, and on a
|
|
7
|
-
// machine whose default node drifted older the raw SyntaxError stack hides
|
|
8
|
-
// the actual problem (real incident: default node v14 during the meta pilot).
|
|
9
|
-
const major = Number(process.versions.node.split(".")[0]);
|
|
10
|
-
if (major < 20) {
|
|
11
|
-
console.error(
|
|
12
|
-
`buildbeat-v2 needs Node >= 20; this shell resolved v${process.versions.node}.\n` +
|
|
13
|
-
"Check `which node` / nvm default, then rerun (e.g. `nvm use 23`).",
|
|
14
|
-
);
|
|
15
|
-
process.exit(1);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
import("../src/v2/cli/run.js");
|