@haiyangbg/buildbeat 2.0.0-beta.5 → 2.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 +30 -1
- package/README.en.md +100 -224
- package/README.md +100 -222
- package/SKILL.md +95 -27
- package/docs/CAPABILITY-MATRIX.md +37 -6
- package/docs/CLI.md +14 -3
- package/docs/README.md +37 -0
- package/docs/RELEASING.md +27 -3
- package/docs/V2-PLAN.md +2 -0
- package/docs/V2.0.0-BETA.5-RELEASE-EVIDENCE-2026-09-05.md +10 -0
- package/docs/V2.0.0-RELEASE-EVIDENCE-2026-09-05.md +11 -0
- package/docs/v2/RFC-0001-product-definition.md +2 -0
- package/docs/v2/guide/00-how-to-talk.md +3 -1
- package/docs/v2/guide/01-quickstart.md +92 -29
- package/docs/v2/guide/02-workflow-guide.md +4 -2
- package/docs/v2/guide/04-adapter-guide.md +17 -2
- package/docs/v2/guide/05-worker-contract.md +17 -6
- package/docs/v2/guide/06-evidence-guide.md +2 -1
- package/docs/v2/guide/07-approval-guide.md +22 -7
- package/docs/v2/guide/08-migration-v1.md +8 -4
- package/docs/v2/guide/09-security-boundaries.md +22 -11
- package/docs/v2/guide/10-recovery.md +4 -2
- package/docs/v2/guide/11-session-handoff.en.md +84 -0
- package/docs/v2/guide/11-session-handoff.md +84 -0
- package/docs/v2/guide/README.md +40 -21
- package/example/.buildbeat/manifest.json +1 -1
- package/package.json +10 -8
- package/src/v2/cli/run.js +26 -0
- package/templates/v2/AGENTS.md +6 -6
- package/templates/v2/BUILDBEAT.md +15 -0
- package/templates/v2/CLAUDE.md +7 -0
- package/templates/v2/envelope/prompts/builder.md +8 -0
- package/templates/v2/envelope/prompts/fixer.md +8 -0
- package/templates/v2/envelope/prompts/reviewer.md +13 -0
- package/templates/v2/envelope/worker.sh +70 -0
- package/templates/v2/run-config.example.yaml +74 -0
- package/templates/v2//346/214/207/346/214/245/345/217/260.md +7 -3
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# 跨会话接续:关掉聊天,保留工作
|
|
2
|
+
|
|
3
|
+
**简体中文** | [English](11-session-handoff.en.md)
|
|
4
|
+
|
|
5
|
+
BuildBeat 的接续依据是项目文件、Git 与运行台账。新会话读取这些事实后,判断继续执行、恢复中断、处理待批,还是开始同一 Work 的下一次 Run。接手的人可以是自己,也可以是另一位团队成员。接手不需要旧聊天全文,也不会自动保存只存在于聊天中的讨论。
|
|
6
|
+
|
|
7
|
+
## 关闭旧会话前
|
|
8
|
+
|
|
9
|
+
在当前会话中说:
|
|
10
|
+
|
|
11
|
+
> 我要换会话。把继续工作必需、但还只在聊天里的上下文落到项目文件,核对当前 Work、候选、未验证事项、待批和运行状态。
|
|
12
|
+
|
|
13
|
+
会话应完成这些核对:
|
|
14
|
+
|
|
15
|
+
- 目标、范围、验收条件与决定已有明确文件落点;补录事实时不改写既有批准,也不把未接受的想法写成已接受计划。
|
|
16
|
+
- 候选提交、工作树中的未提交改动、测试证据与下一步可定位;关键环境事实写入 Work 的 `env-facts.md`,秘密只标来源,不写入项目记录。
|
|
17
|
+
- 使用 `overview` / `inbox` / `status` 读回实况。若 Run 还在执行,说明进程是否脱离驾驶会话;无法确认就说明不确定。
|
|
18
|
+
- 需要跨机器或共享时,按已有授权提交、同步相关项目文件和候选分支;写到磁盘不等于已提交或已推送。
|
|
19
|
+
|
|
20
|
+
这些事实已落盘时,无需为每次换会话另写一篇长交接报告。关闭或删除聊天应只处理聊天记录,保留项目目录、运行台账与工作树;某些工具会连同临时工作区一起清理,先核对其实际范围。
|
|
21
|
+
|
|
22
|
+
## 新会话如何接手
|
|
23
|
+
|
|
24
|
+
在**同一项目目录**打开新会话,按所用工具的方式加载 BuildBeat Skill 和项目 `AGENTS.md`,然后说:
|
|
25
|
+
|
|
26
|
+
> 继续这个项目。先读 BuildBeat 入口和当前工作项,核对 Git、进度、验证结果和待批事项,再在已有授权范围内继续。
|
|
27
|
+
|
|
28
|
+
会话先读当前事实:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
buildbeat-v2 overview --repo .
|
|
32
|
+
buildbeat-v2 inbox --repo .
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
随后读取对应 `delivery/work/<ID>/` 的目标、计划、决定和配置;需要活动 Run 细节时运行 `status --repo . --run <RUN-ID>`。ID 从实际输出读取,不凭聊天猜。
|
|
36
|
+
|
|
37
|
+
| 读到的情况 | 下一步 |
|
|
38
|
+
|---|---|
|
|
39
|
+
| Run 仍在正常执行 | 继续观察,避免启动重复 Run 或改它的工作树 |
|
|
40
|
+
| Run 等人决定 | 展示当前待批对象与证据;新会话不会自动继承一份不存在或已过期的批准 |
|
|
41
|
+
| Runner 中断,运行台账和工作树仍在 | 按恢复手册核对现场,再 `resume --config <配置路径>`;中断步可能重跑 |
|
|
42
|
+
| 工作树脏、配置改变、批准失效或现场缺失 | 说明具体差异,按运行时要求处理,不能声称已无损恢复 |
|
|
43
|
+
| Run 已终结,Work 还需后续执行 | 基于现有工件和候选准备下一次 Run;终态 Run 不重新打开 |
|
|
44
|
+
| 工作已经合并或发布 | 回读相应 Git 或发布事实,避免因某次旧 Run 被取消而重复执行 |
|
|
45
|
+
|
|
46
|
+
恢复批准与最终合并决定是不同动作。详见 [批准指南](07-approval-guide.md) 和 [故障恢复](10-recovery.md)。
|
|
47
|
+
|
|
48
|
+
## 另一位团队成员接手
|
|
49
|
+
|
|
50
|
+
交出方将需要共享的目标、计划、决定、验收记录和下一步落到项目文件,按已有授权同步到共享仓库,并使候选提交可达。在 Work 的项目记录中说明当前由谁继续推进、原 Run 是否仍在执行及所在环境;运行状态仍以实际回读为准。
|
|
51
|
+
|
|
52
|
+
接手方取得项目访问权限后,同步相应文件和候选分支,加载项目入口,用自己的 AI 工具核对范围、证据、待批事项与环境。仍然有效的既有决定继续保留;接手不会自动获得他人的合并、发布或凭据权限。
|
|
53
|
+
|
|
54
|
+
若原 Run 尚未终结,先核对原执行环境。新机器的 `overview` 或 `inbox` 没有活动项,不代表旧机器没有活动 Run。本地锁不会协调不同机器或 Git 副本,不能据此重复启动同一份工作。需要在新环境重新执行时,先明确原 Run 的处置,再从已同步工件与候选准备后续 Run。
|
|
55
|
+
|
|
56
|
+
团队成员可以按端到端工作包分工,也可以交接同一个包。产品、全栈、测试是各成员可调用的 AI 视角(审查是 Run 内置的只读 reviewer,不是会话视角),具体接手的人与视角可以变化。访问控制依赖已有 Git 托管、执行平台和团队授权约定,BuildBeat 不另建成员账号或权限系统。
|
|
57
|
+
|
|
58
|
+
## 换工具、模型和角色
|
|
59
|
+
|
|
60
|
+
项目工件是可读文件,可由不同工具消费。新工具需要加载入口、具备必要权限并能读到同一项目;执行 Worker 还需满足命令、鉴权与输出合同。模型由外部 AI 工具选择。
|
|
61
|
+
|
|
62
|
+
产品、全栈、测试三个视角都读同一个 Work 的目标、约束与证据,按各自写入边界接手;审查由 Run 内置的只读 reviewer 承担。换视角不改变已经接受的范围,不需要把同一套事实复制成多份进度文档。当前一仓仅支持一个活动 Run。
|
|
63
|
+
|
|
64
|
+
这说明协议如何接续,不代表任意工具组合都已通过真实接力验证。已有工具证据见 [能力矩阵](../../CAPABILITY-MATRIX.md),接入要求见 [Adapter 指南](04-adapter-guide.md)。
|
|
65
|
+
|
|
66
|
+
## 换机器与运行恢复的区别
|
|
67
|
+
|
|
68
|
+
| 保留或同步的内容 | 能支撑什么 | 不能直接推出什么 |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| 已提交的 Work、决定、规范与终态记录 | 新机器读取长期项目事实 | 原始运行日志与活动检查点也已同步 |
|
|
71
|
+
| 候选分支及其提交 | 读取候选代码,核对差异与合并状态 | 普通 clone 已取到仅存在于旧机器上的分支 |
|
|
72
|
+
| 本机 runtime 与对应 worktree | 在原环境核对并恢复活动 Run | 拷文件到任意路径即可迁移正在执行的进程 |
|
|
73
|
+
|
|
74
|
+
`.buildbeat/runtime/` 保存活动台账和原始日志,`.buildbeat/worktrees/` 保存工作树,通常均排除在 Git 之外。清理 runtime 后可依据 Git 面继续项目工作,但活动 Run 的精确恢复与原始日志不再保证。终态记录中的日志 digest 也不能还原日志正文。
|
|
75
|
+
|
|
76
|
+
跨地点接手时,先同步项目事实和候选,准备工具与环境,再决定从何处执行。BuildBeat 当前不提供活动 Run 的自动跨机器迁移。
|
|
77
|
+
|
|
78
|
+
## 怎样验证一次真实接力
|
|
79
|
+
|
|
80
|
+
选一个已有验证命令的小任务。会话 A 将目标与计划落盘并执行到可识别的状态;记录 Work、候选、验证结果与待批对象。关闭旧聊天,在不携带旧聊天历史的新会话 B 中只提供项目位置和接续请求。团队场景由另一位有权限的成员同步文件和候选后,用自己的工具执行这一步。
|
|
81
|
+
|
|
82
|
+
核对 B 是否能从文件和工具回读出同样的目标、状态与下一步,并在现有授权内继续。记录工具和模型版本、读取的文件、实际命令与最后结果。跨工具、跨成员或跨机器时,每种组合分别记录;演示对话不能替代这份证据。
|
|
83
|
+
|
|
84
|
+
现有 `tests/v2-resume.test.js`、`tests/v2-approval.test.js` 与 `tests/v2-overview-stages.test.js` 覆盖恢复和状态判断机制;它们不等于真实新会话接手的模型行为验收。
|
package/docs/v2/guide/README.md
CHANGED
|
@@ -1,21 +1,40 @@
|
|
|
1
|
-
# BuildBeat v2
|
|
2
|
-
|
|
3
|
-
>
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
|
8
|
-
|
|
9
|
-
|
|
|
10
|
-
|
|
|
11
|
-
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
# BuildBeat v2 使用文档
|
|
2
|
+
|
|
3
|
+
> 规范权威在 RFC/SPEC([`RFC-0001`](../RFC-0001-product-definition.md) 产品定位 / [`RFC-0002`](../RFC-0002-domain-model.md) 域模型 / [`RFC-0003`](../RFC-0003-workflow-policy.md) workflow 与 policy / [`SPEC-0001`](../SPEC-0001-events-v1.md) 事件 schema);本目录是操作视角,与实现冲突时以 RFC/SPEC 与代码为准并回报。设计历史(V2-PLAN、迭代记录)不在本目录。
|
|
4
|
+
|
|
5
|
+
## 第一次使用
|
|
6
|
+
|
|
7
|
+
| 文档 | 一句话 |
|
|
8
|
+
|---|---|
|
|
9
|
+
| [怎么和会话说话](00-how-to-talk.md) | **给用户看的**:项目从未开始到换期,每个阶段你说什么、会话做什么、你得到什么 |
|
|
10
|
+
| [快速开始](01-quickstart.md) | 第一个 Run:装 `@latest` → 工作项与 run 配置 → accept → doctor → start → 看证据拍板;含失败分支 |
|
|
11
|
+
| [`templates/v2/`](../../../templates/v2/AGENTS.md) | 项目装载入口(AGENTS / CLAUDE / 指挥台 / BUILDBEAT 标记)、run 配置样板、信封 prompt 与 worker 包装 |
|
|
12
|
+
|
|
13
|
+
在 AI 会话里用的人只需读第 0 篇;会话读 `SKILL.md` §0.5 驾驶手册。
|
|
14
|
+
|
|
15
|
+
## 日常使用
|
|
16
|
+
|
|
17
|
+
| 文档 | 一句话 |
|
|
18
|
+
|---|---|
|
|
19
|
+
| [Human Approval 指南](07-approval-guide.md) | inbox / approve / stale;接受、批准某转换、合并决定五词各指什么;分诊门;等待要能找到人;overview |
|
|
20
|
+
| [Evidence 指南](06-evidence-guide.md) | 回读制证据、状态/等级、UNVERIFIED 文化、observe |
|
|
21
|
+
| [跨会话与团队接续](11-session-handoff.md) · [English](11-session-handoff.en.md) | 上下文落盘、关闭旧聊天、新成员接手、跨工具与跨机器边界 |
|
|
22
|
+
| [故障恢复手册](10-recovery.md) | 台账损坏、Run 中断、infra 停人、锁、runtime 全删重建、gc |
|
|
23
|
+
|
|
24
|
+
## 配置参考
|
|
25
|
+
|
|
26
|
+
| 文档 | 一句话 |
|
|
27
|
+
|---|---|
|
|
28
|
+
| [Workflow 编写指南](02-workflow-guide.md) | 步序、显式转换、readonly、terminal、预算、cache、requires |
|
|
29
|
+
| [Policy 指南](03-policy-guide.md) | 四类 Policy、8 算子、三值逻辑、强制等级 |
|
|
30
|
+
| [Adapter 指南](04-adapter-guide.md) | Shell/Mock、env 白名单与 `env:` 注入、接任意 CLI Agent、实时输出 |
|
|
31
|
+
| [Worker 合同](05-worker-contract.md) | 输入输出信封(`severity` + `summary`)、阻断语义、各角色纪律、包装脚本 |
|
|
32
|
+
| [安全与权限边界](09-security-boundaries.md) | 内核实际做到的 vs 不能由此推出的;无人值守三层前置条件 |
|
|
33
|
+
|
|
34
|
+
## 迁移
|
|
35
|
+
|
|
36
|
+
| 文档 | 一句话 |
|
|
37
|
+
|---|---|
|
|
38
|
+
| [v1 迁移指南](08-migration-v1.md) | 升级 CLI 与迁移项目状态分开;手工 runbook,单向迁移不双写 |
|
|
39
|
+
|
|
40
|
+
observe v0(探测→分层响应→Intent 草稿→人分诊)在 [快速开始 §9](01-quickstart.md) 与 [Evidence 指南](06-evidence-guide.md) 中覆盖;schema 冻结见 [`RFC-0003 §8`](../RFC-0003-workflow-policy.md)。
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haiyangbg/buildbeat",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"description": "BuildBeat:
|
|
3
|
+
"version": "2.0.1",
|
|
4
|
+
"description": "BuildBeat: Git-based AI delivery across models, tools, sessions, and people, with context in project files, build-test-review-fix loops, and human decisions.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"buildbeat": "bin/buildbeat.js",
|
|
@@ -28,8 +28,9 @@
|
|
|
28
28
|
"test:pilot": "bash tests/pilot-loop.test.sh",
|
|
29
29
|
"test:skill-only": "bash tests/skill-only.test.sh",
|
|
30
30
|
"test:plugin": "bash tests/plugin-marketplace.test.sh",
|
|
31
|
+
"test:pack-firstrun": "bash tests/pack-firstrun.test.sh",
|
|
31
32
|
"pack:check": "npm pack --dry-run",
|
|
32
|
-
"prepublishOnly": "npm test && npm run test:scripts && npm run test:pilot && npm run test:skill-only && npm run test:plugin && npm run check:docs && npm run pack:check"
|
|
33
|
+
"prepublishOnly": "npm test && npm run test:scripts && npm run test:pilot && npm run test:skill-only && npm run test:plugin && npm run test:pack-firstrun && npm run check:docs && npm run pack:check"
|
|
33
34
|
},
|
|
34
35
|
"engines": {
|
|
35
36
|
"node": ">=20"
|
|
@@ -48,13 +49,14 @@
|
|
|
48
49
|
},
|
|
49
50
|
"keywords": [
|
|
50
51
|
"ai-coding",
|
|
51
|
-
"
|
|
52
|
+
"git-workflow",
|
|
53
|
+
"project-context",
|
|
54
|
+
"session-handoff",
|
|
52
55
|
"human-in-the-loop",
|
|
53
|
-
"scaffold",
|
|
54
56
|
"software-delivery",
|
|
55
|
-
"delivery-
|
|
56
|
-
"ai-
|
|
57
|
-
"
|
|
57
|
+
"delivery-runtime",
|
|
58
|
+
"ai-agents",
|
|
59
|
+
"team-collaboration"
|
|
58
60
|
],
|
|
59
61
|
"author": "HaiYangBG",
|
|
60
62
|
"license": "MIT"
|
package/src/v2/cli/run.js
CHANGED
|
@@ -229,6 +229,26 @@ function printState(state, ledger, view = {}) {
|
|
|
229
229
|
}
|
|
230
230
|
}
|
|
231
231
|
|
|
232
|
+
function workerEnvOverrides(worker, env) {
|
|
233
|
+
if (env === undefined || env === null) {
|
|
234
|
+
return {};
|
|
235
|
+
}
|
|
236
|
+
if (typeof env !== "object" || Array.isArray(env)) {
|
|
237
|
+
throw new Error(`workers.${worker}.env must be a mapping of variable names to scalar values`);
|
|
238
|
+
}
|
|
239
|
+
const out = {};
|
|
240
|
+
for (const [key, value] of Object.entries(env)) {
|
|
241
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
|
|
242
|
+
throw new Error(`workers.${worker}.env: invalid variable name ${key}`);
|
|
243
|
+
}
|
|
244
|
+
if (value === null || typeof value === "object") {
|
|
245
|
+
throw new Error(`workers.${worker}.env.${key} must be a scalar`);
|
|
246
|
+
}
|
|
247
|
+
out[key] = String(value);
|
|
248
|
+
}
|
|
249
|
+
return out;
|
|
250
|
+
}
|
|
251
|
+
|
|
232
252
|
function loadRunConfig(flags, command) {
|
|
233
253
|
if (!flags.config) {
|
|
234
254
|
throw new Error(`${command} requires --config`);
|
|
@@ -244,11 +264,17 @@ function loadRunConfig(flags, command) {
|
|
|
244
264
|
|
|
245
265
|
const adapters = {};
|
|
246
266
|
for (const [worker, spec] of Object.entries(config.workers ?? {})) {
|
|
267
|
+
// The env posture documented in the adapter guide (allowlist by default,
|
|
268
|
+
// `inheritEnv: true` to opt out, `env:` for explicit injection) must reach
|
|
269
|
+
// the adapter through this loader, or doctor reports one posture while
|
|
270
|
+
// start runs another.
|
|
247
271
|
adapters[worker] = createShellAdapter({
|
|
248
272
|
name: `shell:${worker}`,
|
|
249
273
|
command: spec.command,
|
|
250
274
|
args: spec.args ?? [],
|
|
251
275
|
timeoutMs: spec.timeoutMs,
|
|
276
|
+
inheritEnv: spec.inheritEnv === true,
|
|
277
|
+
env: workerEnvOverrides(worker, spec.env),
|
|
252
278
|
});
|
|
253
279
|
}
|
|
254
280
|
const digestOfWorkFile = (name) => {
|
package/templates/v2/AGENTS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# AGENTS.md — <项目名> 工作区 · BuildBeat v2 协作契约
|
|
2
2
|
|
|
3
|
-
> 本文件走开放标准 `AGENTS.md
|
|
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
6
|
> **本仓运行 BuildBeat v2**(运行时 `@haiyangbg/buildbeat@<版本>`,`buildbeat-v2` 由会话调用,人不必手敲)。若由 v1 迁来:`pm/NOW.md`、当期看板、`pm/status/*` 冻结只读,**禁止双写**。
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
3. **人怎么知道该做什么**:`buildbeat-v2 overview --repo .` 回答「每件事走到哪、下一步该谁」;`inbox` 只列等人批的 Run,每条后面附可复制的下一句命令;`status --run <RUN>` 回答「还在动吗、动了多久、卡没卡」。
|
|
13
13
|
4. **上线**:生产动作是人的;`release-readback` 预设 + `release` 风险预设把「做之前回读 → 人做 → 做之后回读 → 观察 → 人关窗」记成 L4 证据,任一步失败即停人批。
|
|
14
14
|
5. **observe 盯生产**:`buildbeat-v2 observe run --config .buildbeat/observe.yaml` 一次=一轮只读体检;异常分层(落账→只读诊断→intent 草稿入队 `delivery/observe/intents/`),草稿**绝不自动执行**,人用 `observe triage` 分诊。
|
|
15
|
-
6. **拍板台账**:平台级真实决策包一行进 `pm/decisions.md
|
|
15
|
+
6. **拍板台账**:平台级真实决策包一行进 `pm/decisions.md`(纯 v2 项目也只建这一个 v1 文件,从 `templates/pm/decisions.md` 拷);Run 级批准落各 Work 的 `decisions.jsonl`;finding 裁决落 `review-findings.jsonl`。跨仓契约在 `contracts/`(单仓项目可无)。
|
|
16
16
|
7. **通知**:`.buildbeat/notify.yaml` 配一条通道(URL 只能来自环境变量),Run 停在人批 / 终态 / 疑似卡住会来找人。
|
|
17
17
|
8. **打扫**:终态 Run 留下的工作树用 `buildbeat-v2 gc --repo .` 清(默认只出计划)。工作树在仓内 `.buildbeat/worktrees/`:`.gitignore` 排除 `.buildbeat/runtime/` 与 `.buildbeat/worktrees/`,测试框架的收集范围也要排除 `**/.buildbeat/**`(vitest `exclude`、jest `testPathIgnorePatterns`、pytest `norecursedirs`),否则主干测试会把旧候选的用例一起跑。
|
|
18
|
-
9. **worker
|
|
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
|
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
|
|
30
30
|
> 🔴 **边界(按项目填写)**:<新地盘 / 老地盘 / 只读模块 / 不得借道写入的目录>。
|
|
31
31
|
> 🔴 **写者≠审者的机器化**:v2 Run 内置 fresh-context 只读 reviewer(快照强制,写入即失败落账);merge 门绑定 candidate + plan + 证据 digest,过期即 stale。
|
|
32
|
-
>
|
|
32
|
+
> **开工/收工护栏**:任意会话开工先各仓 `git pull`,再 `buildbeat-v2 overview --repo .`(活动 Work、等人的 Run、成本);收工前再跑一次 `overview` 并把 warning / unverified 原样写进收口。**只有从 v1 迁来、仓里还有 `pm/NOW.md` 的项目**才另跑 `bash scripts/bus-check.sh`(它只检查 v1 文件总线那部分:契约版本、子仓同步、幽灵 hash),纯 v2 项目没有 `pm/NOW.md` 就不装、不跑、不为了它伪造 v1 文件。生产状态问 `observe status`,不猜。
|
|
33
33
|
|
|
34
34
|
## 1.5 UI 规范摘要(非 UI 项目可删)
|
|
35
35
|
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
**① 唯一入口** —— 活动工作看 `delivery/`(`overview` / `inbox`);v1 遗留入口 `pm/NOW.md` 只读。
|
|
43
43
|
**② 契约落盘不喊话(双向)** —— 跨边界接口先改 `contracts/` 再动代码;收到协议声明独立核查再信。反向流:实现中发现契约不够用 → 不得就地消化,停下记契约缺口交产品域裁决。
|
|
44
44
|
**③ 交接靠 candidate hash + 台账** —— Run 停在合并决定时 candidate 已由 Git 回读固定;跨会话接力读 `delivery/work/<id>/` 即知全部事实,hash 不得编造。
|
|
45
|
-
**④ 护栏与不可逆动作** —— 开工 `bus-check
|
|
45
|
+
**④ 护栏与不可逆动作** —— 开工 `overview`(v1 迁来的仓另加 `bus-check`);部署/改契约/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`(本地只读)。
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
|
|
68
68
|
1. **凭据不入 git、不出本机**:文档只标位置不写值;本地 .env gitignore + 600;机器闸 = gitleaks pre-commit;v2 Worker 默认 env 白名单;通知 URL 只能来自环境变量。
|
|
69
69
|
2. **不 `git add -A`**:只 stage 当前工作包拥有的具体文件;各仓分别提交。
|
|
70
|
-
3. **不未授权部署**、不 force-push、不 `--amend` 已推送历史、不 `--no-verify`。Run
|
|
70
|
+
3. **不未授权部署**、不 force-push、不 `--amend` 已推送历史、不 `--no-verify`。Run 的合并决定只表示候选具备合并条件(`SUCCEEDED` ≠ 已合并),合并/push/发布是其后的人类动作、逐项授权。
|
|
71
71
|
4. **每次部署完必更对应仓 `CHANGELOG.md`**;部署后 `observe run` 一轮。
|
|
72
72
|
5. **写者≠审者**:Run 内置只读 reviewer 机器强制;写者转述不构成证据。
|
|
73
73
|
6. **事实分层**:代码已确认事实 / 运行时待核事实 / 拟议需求 / 已实现行为,四类严格分开;未实查一律写「待核」。
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# BUILDBEAT.md — 本项目的 BuildBeat v2 标记
|
|
2
|
+
|
|
3
|
+
**本项目运行 BuildBeat v2**:运行时 `@haiyangbg/buildbeat@<X.Y.Z>`(<yyyy-mm-dd> 首次接入;查看本机版本 `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
|
+
**v1 遗留**:<无 | `pm/NOW.md` 等已于 <yyyy-mm-dd> 冻结只读,禁止双写>
|
|
7
|
+
来源:<https://github.com/HaiYangBG1/BuildBeat>
|
|
8
|
+
|
|
9
|
+
## 升级
|
|
10
|
+
|
|
11
|
+
运行时升级只是 `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 台账不需要迁移。
|
|
12
|
+
|
|
13
|
+
## 回灌(比升级更重要)
|
|
14
|
+
|
|
15
|
+
本项目踩到 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,8 @@
|
|
|
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 末尾。
|
|
@@ -0,0 +1,8 @@
|
|
|
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 末尾。
|
|
@@ -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,74 @@
|
|
|
1
|
+
# BuildBeat v2 run 配置样板。拷到 delivery/work/<WORK-ID>/run-config.yaml 后改 work / run / allowedPaths / workers。
|
|
2
|
+
# 路径相对本文件解析。严格 YAML 子集:只有块列表与块映射,无行内 [] / {}、无锚点、注释必须独占一行。
|
|
3
|
+
# 起跑前:buildbeat-v2 doctor --config <本文件>;起跑:buildbeat-v2 start --config <本文件> --attempt new
|
|
4
|
+
repo: ../../..
|
|
5
|
+
work: WORK-X
|
|
6
|
+
# 家族名;--attempt new 自动编成 RUN-X-01/02…
|
|
7
|
+
run: RUN-X
|
|
8
|
+
# 从 $(npm root -g)/@haiyangbg/buildbeat/src/v2/presets/software-delivery.yaml 复制到本目录(digest 随项目进 Git)
|
|
9
|
+
workflow: workflow.yaml
|
|
10
|
+
# fast | standard | controlled | release(配 release-readback 预设)
|
|
11
|
+
riskPreset: standard
|
|
12
|
+
entry: build
|
|
13
|
+
# builder / fixer 只能改这些目录;越界改动不成为候选
|
|
14
|
+
allowedPaths:
|
|
15
|
+
- src
|
|
16
|
+
- tests
|
|
17
|
+
# P0/P1 finding 先过人分诊再派 fixer;不需要就删掉这行
|
|
18
|
+
reviewTriage: required
|
|
19
|
+
# 可省;run 配置 > 预设 > 默认。reviewRoundsPerWork 是跨本 Work 所有 Run 累计的 review 轮数上限(对应 intent 的止损线)
|
|
20
|
+
budgets:
|
|
21
|
+
maxAttempts:
|
|
22
|
+
review: 2
|
|
23
|
+
reviewRoundsPerWork: 6
|
|
24
|
+
# 同树 + 同命令 + 同信封已通过就复用 verify 证据
|
|
25
|
+
cache:
|
|
26
|
+
verify: tree
|
|
27
|
+
# 内核把 prompts/<worker>.md 喂给 worker($BUILDBEAT_PROMPT);模板见 templates/v2/envelope/prompts/
|
|
28
|
+
envelope:
|
|
29
|
+
prompts: ../../envelope/prompts
|
|
30
|
+
vars:
|
|
31
|
+
component: app
|
|
32
|
+
# worker 输出落成证据前按这些 JS 正则脱敏(不支持 (?i) 这类内联标志)
|
|
33
|
+
redact:
|
|
34
|
+
- "(token|secret|password|TOKEN|SECRET|PASSWORD)=\\S+"
|
|
35
|
+
# worker 以隔离 worktree 为 cwd 运行;delivery/envelope/worker.sh 已随仓库进 worktree。
|
|
36
|
+
# 换工具只改 `--` 后面的命令:codex exec … / claude -p … / 任意脚本。
|
|
37
|
+
workers:
|
|
38
|
+
builder:
|
|
39
|
+
command: bash
|
|
40
|
+
args:
|
|
41
|
+
- delivery/envelope/worker.sh
|
|
42
|
+
- builder
|
|
43
|
+
- --
|
|
44
|
+
- codex
|
|
45
|
+
- exec
|
|
46
|
+
- -s
|
|
47
|
+
- workspace-write
|
|
48
|
+
# 真实测试命令;环境不满足就 exit 75(内核当基础设施故障停人)
|
|
49
|
+
verifier:
|
|
50
|
+
command: bash
|
|
51
|
+
args:
|
|
52
|
+
- -lc
|
|
53
|
+
- npm test
|
|
54
|
+
reviewer:
|
|
55
|
+
command: bash
|
|
56
|
+
args:
|
|
57
|
+
- delivery/envelope/worker.sh
|
|
58
|
+
- reviewer
|
|
59
|
+
- --
|
|
60
|
+
- codex
|
|
61
|
+
- exec
|
|
62
|
+
- -s
|
|
63
|
+
- read-only
|
|
64
|
+
# 不能省:没配它,verify 失败 / review 阻断时 Run 停人等手修
|
|
65
|
+
fixer:
|
|
66
|
+
command: bash
|
|
67
|
+
args:
|
|
68
|
+
- delivery/envelope/worker.sh
|
|
69
|
+
- fixer
|
|
70
|
+
- --
|
|
71
|
+
- codex
|
|
72
|
+
- exec
|
|
73
|
+
- -s
|
|
74
|
+
- workspace-write
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 指挥台 — Builder 怎么驱动 v2 工作(忘了怎么开场就看这页)
|
|
2
2
|
|
|
3
|
-
> 本仓运行 BuildBeat v2
|
|
3
|
+
> 本仓运行 BuildBeat v2。会话按所用工具的方式装载 `AGENTS.md`(多数工具自动读根目录 `AGENTS.md` / `CLAUDE.md`;不自动读的,开场把它贴给会话);活动工作在 `delivery/`。你基本只需说下面这几句话,命令由会话调、不用你手敲。
|
|
4
4
|
|
|
5
5
|
## 日常六句话
|
|
6
6
|
|
|
@@ -9,12 +9,16 @@
|
|
|
9
9
|
| 看现在到哪了、该谁动 | 「当前进度」/「待办是什么」 | `buildbeat-v2 overview --repo .`(每个 Work 的阶段 + 下一步)+ `observe status` |
|
|
10
10
|
| 看有什么等我批 | 「有什么要我拍板」 | `buildbeat-v2 inbox --repo .`(每条附可复制的下一句) |
|
|
11
11
|
| 立一件新事 | 「开个 Work:〔一句话目标〕」→ 看完说「接受」 | 建 `delivery/work/<ID>/intent.md + plan.md` → `accept`(digest 绑定) |
|
|
12
|
-
| 让它干活 | 「开工」/「再来一轮」 | `buildbeat-v2 start --config … --attempt new`(自动编号、自动作废旧等待,停在合并决定) |
|
|
12
|
+
| 让它干活 | 「开工」/「再来一轮」 | 先 `buildbeat-v2 doctor --config …`(配置、intent/plan 接受状态、env 姿态、预算),再 `start --config … --attempt new`(自动编号、自动作废旧等待,停在合并决定) |
|
|
13
13
|
| 它是不是卡了 | 「怎么样了」/「卡住了吗」 | `buildbeat-v2 status --repo . --run <RUN>`(耗时、历史中位数、最后输出、STALLED) |
|
|
14
|
-
| 拍板 | 「批准 / 拒绝〔RUN-ID〕」;分诊时「这条接受,那条不算」 | `approve` / `reject` / `findings adjudicate
|
|
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`)。
|
|
17
17
|
|
|
18
|
+
## 新开一个 Work 时会话要动的文件
|
|
19
|
+
|
|
20
|
+
`delivery/work/<WORK-ID>/`:`intent.md`(为什么 + 止损线)、`plan.md`(怎么做)、`run-config.yaml`(从 `templates/v2/run-config.example.yaml` 改 work / run / allowedPaths / workers)、`workflow.yaml`(从 `$(npm root -g)/@haiyangbg/buildbeat/src/v2/presets/software-delivery.yaml` 复制)。信封与 worker 包装在仓级 `delivery/envelope/`,不用每个 Work 重写。
|
|
21
|
+
|
|
18
22
|
## 视角开场白
|
|
19
23
|
|
|
20
24
|
| AI 视角 | 在哪开(cwd) | 你的一句话 |
|