@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
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Evidence guide
|
|
2
|
+
|
|
3
|
+
[简体中文](06-evidence-guide.md) | **English**
|
|
4
|
+
|
|
5
|
+
Authority: [`RFC-0002 §4`](../RFC-0002-domain-model.md) (Chinese); implementation: `src/v2/evidence/collector.js`, `src/v2/observe/`. Core idea: **evidence is a fact the Runner read back, not a worker's account of itself**.
|
|
6
|
+
|
|
7
|
+
## The shape of an evidence record
|
|
8
|
+
|
|
9
|
+
Every piece of evidence enters the event ledger (`EVIDENCE_RECORDED`) with: `kind` (command / screenshot / drift / runtime-health / diagnosis / …), `subject` (candidate SHA or deployment unit), `digest` (sha256 of the raw log; the runtime may be deleted, the digest lives on), `status`, `grade`, producer, start and end times. Raw logs land in the runtime plane, `.buildbeat/runtime/`; the ledger and the compacted record reference only digests.
|
|
10
|
+
|
|
11
|
+
## Status: three values, fail-closed
|
|
12
|
+
|
|
13
|
+
| status | Meaning |
|
|
14
|
+
|---|---|
|
|
15
|
+
| `passed` | Zero exit code, no timeout, not killed by a signal |
|
|
16
|
+
| `failed` | Non-zero exit / timeout / signal |
|
|
17
|
+
| `unverified` | **Could not collect**: failed to start, data missing. Never means "no problem" |
|
|
18
|
+
|
|
19
|
+
`unverified` is never treated as a pass by any gate (three-valued logic, [Policy guide](03-policy-guide.md), Chinese). Fail-closed is kernel semantics, not a convention.
|
|
20
|
+
|
|
21
|
+
## Grades L0–L4
|
|
22
|
+
|
|
23
|
+
`L0` self-report → `L1` static check → `L2` real local execution (the default grade for command readback) → `L3` post-deployment verification → `L4` production readback. Gates state their requirement with `minGrade` (for example a merge floor of L2; closing a production switch needs L4).
|
|
24
|
+
|
|
25
|
+
**Verification pyramid warning (the most expensive lesson of the thirty-round campaign)**: the marginal value of polishing a lower layer toward theoretical completeness is far below moving one layer closer to the real machine one step earlier. In practice a 7,400-line L3 suite was polished to its limit, while the four real release blockers (systemd parsing behaviour, deployment/service identity split, probe budgets calibrated against a stand-in, TLS ref format) **were all structurally invisible to L3** and were found in one evening at L4. Rule of thumb: **move up a layer as soon as the simulated layer has zero real defect classes left; do not chase theoretical completeness**. Similarly, re-running the full verify when the candidate touched only a part is pure repetition; caching or trimming by content hash belongs to the envelope layer (the campaign measured 25 → 13 minutes) and the kernel does not do it for you: cache correctness depends on assumptions about a stable environment, which the envelope owner carries.
|
|
26
|
+
|
|
27
|
+
## Preflight is not evidence
|
|
28
|
+
|
|
29
|
+
`buildbeat preflight --config <run-config> --step <id>` dry-runs one step's worker command directly in the main checkout: no worktree, no ledger, no evidence of any kind (the output carries a `PREFLIGHT (dry signal, never evidence)` banner and the environment variable `BUILDBEAT_PREFLIGHT=1`). Its purpose is a minute-scale loop that reaches the first failure boundary before entering a Run (in the campaign every harness defect cost a whole Run round; preflight mode dismantled them in one evening). **Anything preflight finds counts only once a Run reproduces it.**
|
|
30
|
+
|
|
31
|
+
## Candidate scope
|
|
32
|
+
|
|
33
|
+
Evidence is bound to the candidate through `subject`: the merge gate counts only the current candidate's evidence; records from old candidates or old review rounds are not mixed in (a real-incident regression, see the `fix-loop` eval).
|
|
34
|
+
|
|
35
|
+
## observe: production joins the evidence plane (v0)
|
|
36
|
+
|
|
37
|
+
Frozen in [`RFC-0003 §8`](../RFC-0003-workflow-policy.md) (Chinese), implemented in M5 (`src/v2/observe/`):
|
|
38
|
+
|
|
39
|
+
- **Providers** (project probes such as drift checks and live status) produce records under the same Evidence Contract into a separate observe ledger (same chain verification, `.buildbeat/runtime/observe/`); a broken probe is `unverified` (default severity warn), never silent;
|
|
40
|
+
- **Three bands** (thresholds configurable, order fixed): `log` records only → `diagnose` triggers a read-only diagnostic command and produces `diagnosis` evidence → `intent` writes an Intent **draft** into the Git plane at `delivery/observe/intents/` (never executed automatically);
|
|
41
|
+
- **Human triage**: `observe triage --action fix_now|schedule|dismiss`. After `fix_now` a human carries it into a software-delivery Run and the loop closes; `dismiss` feeds the bands back so the same fingerprint is not queued again until its severity rises (alert-fatigue protection); the triage outcome is written into the draft file itself and survives deleting the runtime (invariant 23);
|
|
42
|
+
- **Scheduling boundary in v0**: the `schedule` field is parsed and recorded but there is no built-in scheduler; periodic runs are the host's cron calling `observe run` repeatedly.
|
|
43
|
+
|
|
44
|
+
## Completeness
|
|
45
|
+
|
|
46
|
+
`buildbeat metrics` prints evidence completeness (steps with evidence / steps that should have it); the M4/M5 exit line is ≥ 95%, the pilots measured 100%.
|
|
47
|
+
|
|
48
|
+
## Live readings are not evidence
|
|
49
|
+
|
|
50
|
+
> Since 2.0.0-beta.4 (iteration 08).
|
|
51
|
+
While a step runs, the Shell Adapter streams the worker's stdout/stderr to `.buildbeat/runtime/runs/<RUN>/<step>-<n>.{stdout,stderr}.live` and keeps a `live.json` (command, start time). These are **readings**: `status` uses them to answer "is it still moving, for how long, when was the last output", and they are reclaimed as soon as the step ends; the evidence log is still produced by readback, and the digest still binds the final log. Durations likewise: per-step elapsed time and the repository's historical median (`typical step duration` in `metrics`) are derived from ledger timestamps and enter neither the ledger nor the run-record.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Evidence 指南
|
|
2
2
|
|
|
3
|
+
**简体中文** | [English](06-evidence-guide.en.md)
|
|
4
|
+
|
|
3
5
|
权威:[`RFC-0002 §4`](../RFC-0002-domain-model.md);实现:`src/v2/evidence/collector.js`、`src/v2/observe/`。核心:**证据是 Runner 回读到的事实,不是 Worker 的自述**。
|
|
4
6
|
|
|
5
7
|
## 证据记录的形状
|
|
@@ -14,7 +16,7 @@
|
|
|
14
16
|
| `failed` | 非零退出 / 超时 / 信号 |
|
|
15
17
|
| `unverified` | **采不到**:无法启动、数据缺失。永远不是"没问题" |
|
|
16
18
|
|
|
17
|
-
`unverified` 不会被任何门当作通过([Policy 指南](03-policy-guide.md)
|
|
19
|
+
`unverified` 不会被任何门当作通过([Policy 指南](03-policy-guide.md) 三值逻辑)。fail-closed 是内核语义,不是约定。
|
|
18
20
|
|
|
19
21
|
## 等级 L0–L4
|
|
20
22
|
|
|
@@ -24,7 +26,7 @@
|
|
|
24
26
|
|
|
25
27
|
## 预检 ≠ 证据
|
|
26
28
|
|
|
27
|
-
`buildbeat
|
|
29
|
+
`buildbeat preflight --config <run-config> --step <id>`:在主 checkout 直接干跑某步的 worker 命令——无 worktree、无台账、不落任何证据(输出自带 `PREFLIGHT (dry signal, never evidence)` 横幅,环境变量 `BUILDBEAT_PREFLIGHT=1`)。用途是分钟级循环打到首个失败边界再进 Run(战役里 harness 缺陷每个要烧一整轮 Run,预检模式一晚拆完);**预检发现的任何东西必须由 Run 复现才算数**。
|
|
28
30
|
|
|
29
31
|
## 候选作用域
|
|
30
32
|
|
|
@@ -41,7 +43,7 @@
|
|
|
41
43
|
|
|
42
44
|
## 完整率
|
|
43
45
|
|
|
44
|
-
`buildbeat
|
|
46
|
+
`buildbeat metrics` 输出证据完整率(有证据的步/应有证据的步);M4/M5 退出线 ≥95%,试点实测 100%。
|
|
45
47
|
|
|
46
48
|
## 运行中的读数 ≠ 证据
|
|
47
49
|
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Human approval guide
|
|
2
|
+
|
|
3
|
+
[简体中文](07-approval-guide.md) | **English**
|
|
4
|
+
|
|
5
|
+
Authority: [`RFC-0003 §5`](../RFC-0003-workflow-policy.md) (Chinese); implementation: `src/v2/runtime/decisions.js`. Principle: **a human approves a digest-bound subject, not a sentence that says "fine"**.
|
|
6
|
+
|
|
7
|
+
## What an approval binds
|
|
8
|
+
|
|
9
|
+
One approval = the quadruple `transition + candidate + planDigest + evidenceDigest`. If any of the four changes afterwards, the approval becomes `APPROVAL_STALE` on its own and the Run returns to `WAITING_HUMAN`: an old stamp never covers a new subject (zero reuse of stale approvals is an exit metric; the pilots measured zero).
|
|
10
|
+
|
|
11
|
+
## Daily commands
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
buildbeat inbox --repo . # every Run waiting for a human: transition, candidate, digest, reason
|
|
15
|
+
buildbeat status --repo . --run RUN-X # the full derived view of one Run (steps, evidence, findings)
|
|
16
|
+
buildbeat approve --repo . --run RUN-X --transition enter-wait-merge --by <name> --config <run-config>
|
|
17
|
+
buildbeat reject --repo . --run RUN-X --reason "<why>" --by <name>
|
|
18
|
+
buildbeat accept --repo . --work WORK-X --artifact plan --by <name> # artifact acceptance (digest-bound)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Decisions land in the Git plane at `delivery/work/<id>/decisions.jsonl`; the event ledger records `DECISION_RECORDED` at the same time.
|
|
22
|
+
|
|
23
|
+
## The safety semantics of approve (all tested)
|
|
24
|
+
|
|
25
|
+
1. **The transition must match** the pending request;
|
|
26
|
+
2. **Reality is re-read before stamping**: if the pending snapshot and reality disagree (the candidate moved, the plan changed), the approval is refused and a refresh is required; nothing is stamped;
|
|
27
|
+
3. **Transition gates are re-checked at the instant of stamping**: if merge-evidence-floor / ui-render-gate do not PASS right then, the approval is refused;
|
|
28
|
+
4. Approving a final decision (a pending request of the final-decision kind) means `RUN_TERMINAL SUCCEEDED` plus compacting the run-record into the Git plane.
|
|
29
|
+
|
|
30
|
+
## Five words and what each means (approving is not executing)
|
|
31
|
+
|
|
32
|
+
Sessions and documents used to mix "accept / approve / resume / succeeded / merged". The vocabulary is fixed as follows:
|
|
33
|
+
|
|
34
|
+
| Word | Command | Meaning | Is not |
|
|
35
|
+
|---|---|---|---|
|
|
36
|
+
| **Accept** | `accept --artifact intent\|plan` | A human endorses one artifact's digest; editing it makes the acceptance `stale` | Starting work; it creates no Run |
|
|
37
|
+
| **Approve a transition** | `approve --transition <t>` | Lets the Run take **this one** transition: `enter-fix` (release the fixer after triage), `resume-<step>` (run the step once more after a budget or infra stop; records `BUDGET_EXTENDED`), `enter-review` (one more review round after the Work-level cap), `enter-apply-readback` ("I have done it" on the release lane) | Approving any other transition; after a non-terminal transition is approved the Run **does not move by itself**: `resume --config <run-config>` continues it (the `next:` line printed by `approve` says so) |
|
|
38
|
+
| **Merge decision** (final approval) | `approve --transition enter-wait-merge` | The candidate is fit to merge: candidate + planDigest + evidenceDigest all hold at this instant; the Run reaches the terminal state `SUCCEEDED` and the run-record is compacted into the Git plane | Code merged, pushed or deployed: those three remain your actions outside the Runner, always |
|
|
39
|
+
| **Run SUCCEEDED** | — | The Run stopped where it should and the evidence is complete | The Work is finished. `overview` shows `MERGED` only after reading back that the candidate is on the current branch |
|
|
40
|
+
| **Reject** | `reject --reason` | The Run ends (`FAILED`, reason recorded) | The artifacts are invalidated; the acceptance state of intent/plan does not change |
|
|
41
|
+
|
|
42
|
+
Likewise, `fix_now` on an observe draft is only acceptance; a human starts the Run. Protected actions are listed under [Security boundaries](09-security-boundaries.md) (Chinese).
|
|
43
|
+
|
|
44
|
+
## Risk presets decide where humans approve
|
|
45
|
+
|
|
46
|
+
`fast`: Merge only; `standard`: Plan + Merge; `controlled`: Intent + Plan + Merge + Release. A pending request must carry the findings summary and the reason, which prevents the "rubber stamp" decay; human waiting time goes into `metrics`.
|
|
47
|
+
|
|
48
|
+
## The finding triage gate and anchored review
|
|
49
|
+
|
|
50
|
+
> Since 2.0.0-beta.3.
|
|
51
|
+
The biggest structural lesson of the thirty-round deployment campaign: **a finding is a prescription, not a fact**. A memoryless fresh reviewer writes contradictory prescriptions and overturns designs that were accepted long ago; routing a fixer automatically turns that oscillation straight into cost. Two mechanisms work together:
|
|
52
|
+
|
|
53
|
+
1. **The triage gate**: with `reviewTriage: required` in the run config, P0/P1 findings from review no longer dispatch a fixer automatically; the Run stops at `WAITING_HUMAN` (kind `finding-triage`) and the pending reason lists every finding fingerprint. A human adjudicates first, then `approve --transition enter-fix` releases the fixer (or `reject` ends the Run).
|
|
54
|
+
2. **The adjudication ledger**: every finding lands in the Git plane at `delivery/work/<id>/review-findings.jsonl` (fingerprint = hash of severity plus normalized text):
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
buildbeat findings list --repo . --work WORK-X
|
|
58
|
+
buildbeat findings adjudicate --repo . --work WORK-X --fingerprint <fp> --action dismiss --by <name> --note "<why>"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
After `dismiss`, the same fingerprint no longer blocks (raising it again is recorded visibly as `RE-RAISED`, but does not restart the loop); **a severity upgrade is a new fingerprint and blocks again on its own**: noise is suppressed, real signal is not, the same principle as observe's dismiss feedback.
|
|
62
|
+
3. **Anchor injection**: the reviewer (a readonly step) receives `anchor` in `BUILDBEAT_INPUT`, the full table of past findings and adjudications, and the envelope prompt should tell the reviewer that adjudicated conclusions must not be overturned; writing steps such as the fixer receive `findings` (last round's findings with their adjudication state), and the fixer repairs only accepted/open ones instead of guessing.
|
|
63
|
+
|
|
64
|
+
Adjudication memory lives in the Git plane; deleting the runtime does not lose it (covered by the same tests as invariant 23).
|
|
65
|
+
|
|
66
|
+
## Waiting must be able to find a person
|
|
67
|
+
|
|
68
|
+
> Since 2.0.0-beta.4 (iteration 08).
|
|
69
|
+
In the pilot workspace, 32 of 58 Runs were cancelled, most of them after hanging in `WAITING_HUMAN` for a full day; the average human wait was 7 to 12 hours. The cause was not slow people but **nobody knowing something was waiting for them**. Three things go together:
|
|
70
|
+
|
|
71
|
+
1. **What to say next**: `status` and `inbox` print the copyable command right after each wait (`approve` / `reject`, plus `findings list|adjudicate` during triage); `inbox` groups by Work and shows how long each has waited. The `--repo` in that output is a relative path inside the project and the placeholder `<repo-path>` outside it: a machine-local absolute path never enters the output.
|
|
72
|
+
2. **A new Run of the same Work supersedes the old wait**: on `start`, older Runs of the same Work that are still waiting are recorded as `SUPERSEDED` (terminal, compacted into a run-record), and the new Run's `RUN_CREATED.data.supersedes` records the lineage; the inbox keeps only live waits. Write `supersede: off` in the run config if you do not want this. RUNNING Runs are unaffected (active lock); old Runs locked by another process are skipped and reported.
|
|
73
|
+
3. **Outbound notifications**: `.buildbeat/notify.yaml` in the Git plane:
|
|
74
|
+
|
|
75
|
+
```yaml
|
|
76
|
+
kind: notify
|
|
77
|
+
version: 1
|
|
78
|
+
channels:
|
|
79
|
+
- id: owner
|
|
80
|
+
type: dingtalk # or webhook
|
|
81
|
+
urlEnv: BUILDBEAT_NOTIFY_URL # the URL comes only from an environment variable; a literal url is refused
|
|
82
|
+
events:
|
|
83
|
+
- HUMAN_REQUESTED
|
|
84
|
+
- RUN_TERMINAL
|
|
85
|
+
- STALLED
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The CLI sends when a Run stops for a human or reaches a terminal state; subscribing to `STALLED` makes `start`/`resume` spawn a detached `watch` process that watches for silent worker output (threshold `stallAfterMs`, default 15 minutes). A failed send is only logged to `runs/<RUN>/notify.log` and the screen and **never affects the Run**; the payload carries identifiers, the reason, the candidate SHA and the next command, with zero logs and zero candidate content. A DingTalk custom robot needs its keyword configured (default `BuildBeat`). `doctor` reports whether the channel and its environment variable are in place.
|
|
89
|
+
|
|
90
|
+
Notification is not an approval channel: decisions are still made only through the CLI, with digest binding unchanged.
|
|
91
|
+
|
|
92
|
+
## From "waiting for me" to "where are we": overview
|
|
93
|
+
|
|
94
|
+
> Since 2.0.0-beta.4 (iteration 08).
|
|
95
|
+
`inbox` only knows which Run waits for a human; `buildbeat overview --repo .` answers per Work "how far, whose move next": whether intent/plan are accepted (edited after acceptance means `stale`), the latest Run's state and candidate, whether the candidate is merged into the current branch, the number of unadjudicated P0/P1 findings, whether `env-facts.md` exists, each row with its next command. After the runtime is deleted, the Git-plane run-records fill in. A session runs it first, then answers "where are we".
|
|
96
|
+
|
|
97
|
+
**Stage truth corrections (iteration 09)**: once a candidate is merged into the current branch the Work is `MERGED`, even if the latest Run is CANCELLED (a pilot login Run was cancelled over a budget problem while its candidate was already in production, and overview reported `STOPPED_CANCELLED` and urged a retry); a Work whose `release-readback` lane closed successfully shows `RELEASED` instead of "nothing to merge"; merged / released / closed Works no longer report unadjudicated finding counts. Each Work in `overview` also carries a `cost:` line (see the Work-level budgets in the [Workflow guide](02-workflow-guide.md), Chinese).
|
|
98
|
+
|
|
99
|
+
## You fixed it yourself: `resume --adopt`
|
|
100
|
+
|
|
101
|
+
> Since 2.0.0-beta.5 (iteration 09).
|
|
102
|
+
When a Run stops at `enter-fix` / `resume-fix`, the driving session or a person has often already fixed the problem in the Run's worktree and committed it. Approving at that point dispatches a fixer with nothing to do and runs verify once more (a pilot frontend Run reached its 5th verify and 3rd fix this way). Use instead:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
buildbeat resume --config <run-config.yaml> --adopt <sha> --by <name>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The kernel reads the worktree back: the tree must be clean and HEAD must be exactly `<sha>` (7-character prefix or longer), otherwise it refuses; then it records `CANDIDATE_PINNED` with a human actor (`adopted: true`), records `DECISION_RECORDED` with that commit as subject (`adopted`, `resumeAt`), and continues from verify (the step after a successful fix in the preset). The ledger shows who supplied this candidate. Adoption is not accepted at the merge decision.
|
|
109
|
+
|
|
110
|
+
`doctor` now also prints whether intent / plan exist and are accepted in this repository's `delivery/work/<ID>/`, and for every policy requiring `artifact.accepted` it previews where `start` will stop; before that, doctor passed twice while start was blocked by "plan not mirrored into the sub-repository".
|
|
111
|
+
|
|
112
|
+
## Visible names are gate decisions
|
|
113
|
+
|
|
114
|
+
> Since 2.0.0-beta.4 (iteration 08).
|
|
115
|
+
The `BATCH_AT_GATE` tier of the three approval tiers explicitly includes domain names, service names, environment names, auto-stop durations, window durations: **names and parameters the owner will later see or say out loud**. Names a worker picks in passing never reach the ledger; the planner lists them in the intent with recommended values, and the human approves them in one go.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Human Approval 指南
|
|
2
2
|
|
|
3
|
+
**简体中文** | [English](07-approval-guide.en.md)
|
|
4
|
+
|
|
3
5
|
权威:[`RFC-0003 §5`](../RFC-0003-workflow-policy.md);实现:`src/v2/runtime/decisions.js`。原则:**人批的是一个 digest 绑定的对象,不是一句"可以了"**。
|
|
4
6
|
|
|
5
7
|
## 批准绑定什么
|
|
@@ -9,11 +11,11 @@
|
|
|
9
11
|
## 日常操作
|
|
10
12
|
|
|
11
13
|
```bash
|
|
12
|
-
buildbeat
|
|
13
|
-
buildbeat
|
|
14
|
-
buildbeat
|
|
15
|
-
buildbeat
|
|
16
|
-
buildbeat
|
|
14
|
+
buildbeat inbox --repo . # 所有等人的 Run:transition、candidate、digest、理由
|
|
15
|
+
buildbeat status --repo . --run RUN-X # 单个 Run 的完整派生视图(步、证据、findings)
|
|
16
|
+
buildbeat approve --repo . --run RUN-X --transition enter-wait-merge --by <名字> --config <run-config>
|
|
17
|
+
buildbeat reject --repo . --run RUN-X --reason "<为什么>" --by <名字>
|
|
18
|
+
buildbeat accept --repo . --work WORK-X --artifact plan --by <名字> # 工件接受(digest 绑定)
|
|
17
19
|
```
|
|
18
20
|
|
|
19
21
|
决定落 Git 面 `delivery/work/<id>/decisions.jsonl`,事件台账同步记 `DECISION_RECORDED`。
|
|
@@ -41,7 +43,7 @@ buildbeat-v2 accept --repo . --work WORK-X --artifact plan --by <名字> #
|
|
|
41
43
|
|
|
42
44
|
## 人批点由 Risk Preset 决定
|
|
43
45
|
|
|
44
|
-
`fast` 仅 Merge;`standard` Plan+Merge;`controlled` Intent+Plan+Merge+Release
|
|
46
|
+
`fast` 仅 Merge;`standard` Plan+Merge;`controlled` Intent+Plan+Merge+Release。待批项强制携带 findings 摘要与理由——防"秒批"退化;人批等待时长进 `metrics`。
|
|
45
47
|
|
|
46
48
|
## 发现分诊门与锚定审查
|
|
47
49
|
|
|
@@ -52,8 +54,8 @@ buildbeat-v2 accept --repo . --work WORK-X --artifact plan --by <名字> #
|
|
|
52
54
|
2. **裁决台账**:finding 全部落 Git 面 `delivery/work/<id>/review-findings.jsonl`(指纹 = 严重度+正文规范化 hash):
|
|
53
55
|
|
|
54
56
|
```bash
|
|
55
|
-
buildbeat
|
|
56
|
-
buildbeat
|
|
57
|
+
buildbeat findings list --repo . --work WORK-X
|
|
58
|
+
buildbeat findings adjudicate --repo . --work WORK-X --fingerprint <fp> --action dismiss --by <名字> --note "<为什么>"
|
|
57
59
|
```
|
|
58
60
|
|
|
59
61
|
`dismiss` 后同指纹不再阻断(重提会以 `RE-RAISED` 记账可见,但不重启循环);**严重度升级=新指纹,自动重新阻断**——压噪不压真信号,与 observe 的 dismiss 回调同一原则。
|
|
@@ -90,7 +92,7 @@ buildbeat-v2 accept --repo . --work WORK-X --artifact plan --by <名字> #
|
|
|
90
92
|
## 从「等我批」到「到哪了」:overview
|
|
91
93
|
|
|
92
94
|
> 自 2.0.0-beta.4(迭代 08)起。
|
|
93
|
-
`inbox` 只知道哪个 Run 在等人;`buildbeat
|
|
95
|
+
`inbox` 只知道哪个 Run 在等人;`buildbeat overview --repo .` 按 Work 回答「走到哪、下一步该谁」——intent/plan 是否被接受(接受后改过即 `stale`)、最新 Run 状态与候选、候选是否已合入当前分支、未裁决 P0/P1 数、是否有 `env-facts.md`,每行附下一句命令。运行时被删后由 Git 面 run-record 补足。会话开场先跑它,再回答用户「当前进度」。
|
|
94
96
|
|
|
95
97
|
**阶段判定的真相修正(迭代 09)**:候选只要合入了当前分支,Work 就是 `MERGED`,哪怕最新 Run 是 CANCELLED(试点一条应用登录 Run 因预算问题被取消,候选却已在生产,overview 曾报 `STOPPED_CANCELLED` 并催重试);`release-readback` 车道成功关窗的 Work 显示 `RELEASED`,不再说 "nothing to merge";已合并 / 已发布 / 已关闭的 Work 不再提示未裁决 finding 数。`overview` 每个 Work 还多一行 `cost:`(见 [Workflow 指南](02-workflow-guide.md) 的 Work 级预算)。
|
|
96
98
|
|
|
@@ -100,7 +102,7 @@ buildbeat-v2 accept --repo . --work WORK-X --artifact plan --by <名字> #
|
|
|
100
102
|
Run 停在 `enter-fix` / `resume-fix` 时,驾驶会话或人常常已经在 Run 的 worktree 里把问题修掉并提交了。此时再 `approve` 会派一个无事可做的 fixer,再多跑一次 verify(试点一条前端 Run 因此跑到 verify 第 5 次、fix 第 3 次)。改用:
|
|
101
103
|
|
|
102
104
|
```bash
|
|
103
|
-
buildbeat
|
|
105
|
+
buildbeat resume --config <run-config.yaml> --adopt <sha> --by <名字>
|
|
104
106
|
```
|
|
105
107
|
|
|
106
108
|
内核回读 worktree:树必须干净、HEAD 必须就是 `<sha>`(前缀 7 位起),否则拒绝;然后以人为 actor 落 `CANDIDATE_PINNED`(`adopted: true`)、以该提交为 subject 记 `DECISION_RECORDED`(`adopted`、`resumeAt`),并从 verify 继续(预设里 fix 成功后的下一步)。台账里看得出这一版候选是谁供的。合并决定处不接受 adopt。
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Recovery handbook
|
|
2
|
+
|
|
3
|
+
[简体中文](10-recovery.md) | **English**
|
|
4
|
+
|
|
5
|
+
Design premise (invariant 23 in [`V2-PLAN.md`](../../V2-PLAN.md), Chinese): **the whole `.buildbeat/runtime/` directory can be deleted at any time**. Accepted artifacts, decisions, Intent drafts with their triage, and the compacted records of finished Runs all live in the Git plane. "Delete and rebuild" is the default troubleshooting move, not the last resort.
|
|
6
|
+
|
|
7
|
+
## Symptom → action
|
|
8
|
+
|
|
9
|
+
### The ledger reports corrupted
|
|
10
|
+
|
|
11
|
+
`status`/`inbox` shows `LEDGER CORRUPTED after seq=N (<reason>)`: the ledger truncates its view at the last valid event and **refuses to append**; recovery is a human decision, nothing is repaired silently.
|
|
12
|
+
|
|
13
|
+
1. `buildbeat events --repo . --run RUN-X` shows the valid prefix; `replay` verifies the reduction;
|
|
14
|
+
2. If the broken Run is in flight: usually abandon it (the candidate in the worktree is still readable on its branch) and start a new Run;
|
|
15
|
+
3. If someone edited the ledger file by hand: rebuild the judgement from Git-plane facts; do not patch event lines by hand.
|
|
16
|
+
|
|
17
|
+
### The Run process was killed / the machine rebooted
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
buildbeat resume --config <run-config.yaml>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The in-flight step is closed as `crashed` (the fact is recorded), then **the step itself is rerun** (changed in beta.3): a dead process says nothing about the candidate; the lost attempt still counts against the step's budget, and an exhausted budget stops for a human. The earlier semantics treated a crash as a step failure and followed the failure edge; real incident (deploy-18): the host tool's timeout killed the verify worker, the crash was routed to fix, and the fixer burned a round facing zero verifier evidence. A dirty worktree still stops for a human first. Resuming with approvals re-checks candidate/plan freshness and turns `APPROVAL_STALE` over to a human if anything changed. If it cannot be recovered, delete the runtime and rerun: the candidate branch and the Git-plane records are not lost.
|
|
24
|
+
|
|
25
|
+
**Launch discipline** (the other half of the same incident): a Run longer than minutes must be launched in a way that escapes the host tool's timeout (`nohup`/`setsid`); `start` prints this reminder in an interactive shell.
|
|
26
|
+
|
|
27
|
+
### A stuck lock ("another run is active")
|
|
28
|
+
|
|
29
|
+
A Run that exited abnormally may leave the repository lock behind. Once you have confirmed that no Run is really active:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
buildbeat stop --repo . --run RUN-X --reason "crashed; releasing lock"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`stop` records the terminal state and the reason; for a mere leftover lock you may also delete `.buildbeat/runtime/` and start over.
|
|
36
|
+
|
|
37
|
+
### Abnormal worker behaviour
|
|
38
|
+
|
|
39
|
+
- **Worker infrastructure failure (iteration 09)**: a timeout, a crash, output that is not an envelope (`invalid-output`), or the worker ending itself with exit code **75** (`EX_TEMPFAIL`, "environment unavailable"): the kernel classifies it as `infra`: no failure fingerprint is recorded, no fixer is dispatched, **the step's budget is not consumed**, the Run stops at `WAITING_HUMAN` (kind `infra`, transition `resume-<step>`), notifications go out as usual. Once the backend is back, `approve --transition resume-<step>` reruns the step; `reject` ends the Run. Real incidents: a worker backend returning 404 and non-JSON output killed five Runs in two days while the driving session hand-wrote a probe every two minutes; a missing rg on PATH, a port collision and a host load of 280 each dispatched a fixer.
|
|
40
|
+
- **A failure with no transition edge** (such as `failed` on build / review / fix in the preset) no longer ends in FAILED; it stops at `resume-<step>` as well, and a human decides whether to rerun or end.
|
|
41
|
+
- Out-of-scope writes → the Run BLOCKs and no candidate is pinned: check `allowedPaths` and the scope declared in the worker prompt;
|
|
42
|
+
- Timeouts → first check whether it is the environment (`infra` already stopped for you), then adjust `timeoutMs`; an exhausted budget is a brake, not a fault: approve `resume-<step>` to grant one more attempt, or narrow the scope.
|
|
43
|
+
|
|
44
|
+
### The observe plane
|
|
45
|
+
|
|
46
|
+
- A probe stays `unverified`: fix the probe's reachability first; unverified means "could not collect", not "no problem";
|
|
47
|
+
- False alarms flooding: `observe triage --action dismiss`; the same fingerprint stays out of the queue until its severity rises;
|
|
48
|
+
- Observe cycle counts reset to zero after the runtime was deleted: normal; triage memory lives in the Git-plane drafts, and suppression keeps working (tested).
|
|
49
|
+
|
|
50
|
+
### Everything is a mess
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
rm -rf .buildbeat/runtime/
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Then start again from the Git plane. Any phenomenon where a long-term metric or a terminal-state explanation depends on the runtime is a bug; please report it.
|
|
57
|
+
|
|
58
|
+
## Diagnostic entry point
|
|
59
|
+
|
|
60
|
+
`buildbeat doctor --config <run-config>`: the config parses, the workflow has no exit loop, adapter env posture, digests can be computed, supersede and stall thresholds, whether the notification channel and its environment variable are in place. `events`/`replay`/`metrics` are all read-only and can run at any time.
|
|
61
|
+
|
|
62
|
+
## "Is it stuck?"
|
|
63
|
+
|
|
64
|
+
> Since 2.0.0-beta.4 (iteration 08).
|
|
65
|
+
Look at `buildbeat status --repo . --run <RUN>` first: the step in flight shows elapsed time, the repository's historical median, the worker command, how long ago the last output was and its last three lines. No output beyond the threshold (default 15 minutes, `--stall-after <minutes>` or `stallAfterMs` in the run config) marks `STALLED`: **marked, never killed**. How to judge:
|
|
66
|
+
|
|
67
|
+
- Output keeps coming → wait (compare against `typical` to see whether it is far beyond the median);
|
|
68
|
+
- STALLED and the worker is an agent CLI → most likely a long reasoning stretch or waiting for an interaction that never comes; `stop --reason`, then rerun by the crash recovery path (the interrupted step reruns itself);
|
|
69
|
+
- STALLED and the worker is a script → read the last three lines; usually it waits on an external resource (port, lock, network).
|
|
70
|
+
|
|
71
|
+
To avoid watching the screen, subscribe to `STALLED` notifications ([Approval guide](07-approval-guide.en.md)). `watch --repo . --run <RUN> --once true` probes once by hand.
|
|
72
|
+
|
|
73
|
+
## Cleanup: gc
|
|
74
|
+
|
|
75
|
+
> Since 2.0.0-beta.4 (iteration 08).
|
|
76
|
+
Terminal Runs leave worktrees, `run/*` branches and the occasional lock. `buildbeat gc --repo .` prints the plan by default, `--apply true` executes it:
|
|
77
|
+
|
|
78
|
+
- It touches only Runs that are **terminal and already compacted into a run-record** (the Git plane must have the record before the runtime plane is touched);
|
|
79
|
+
- Worktrees may be deleted (the commits are on the branch); a dirty worktree is left alone without `--force true`;
|
|
80
|
+
- A branch is deleted only when the candidate **is reachable from another ref** (merged / tagged / on the remote) or the Run produced no candidate; otherwise it reports "reachable only from this branch, kept": that branch is the last thread to the evidence;
|
|
81
|
+
- Leftover `locks/<RUN>.lock` of terminal Runs are cleaned; the `active-run` lock is still handled by hand as above.
|
|
82
|
+
|
|
83
|
+
gc never writes to the ledger (after the terminal state only `RUN_COMPACTED` is allowed), so it can run at any time and repeatedly.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# 故障恢复手册
|
|
2
2
|
|
|
3
|
+
**简体中文** | [English](10-recovery.en.md)
|
|
4
|
+
|
|
3
5
|
设计前提([`V2-PLAN.md`](../../V2-PLAN.md) 不变量 23):**`.buildbeat/runtime/` 整个目录随时可删**——已接受工件、Decision、Intent 草稿与分诊、已终结 Run 的压实记录全部活在 Git 面。"删了重建"是默认排障手段,不是最后手段。
|
|
4
6
|
|
|
5
7
|
## 症状 → 处置
|
|
@@ -8,14 +10,14 @@
|
|
|
8
10
|
|
|
9
11
|
`status`/`inbox` 出现 `LEDGER CORRUPTED after seq=N (<原因>)`:台账在最后一条合法事件处截断视图并**拒绝追加**——恢复是人的决定,不静默修复。
|
|
10
12
|
|
|
11
|
-
1. `buildbeat
|
|
13
|
+
1. `buildbeat events --repo . --run RUN-X` 看合法前缀;`replay` 校验归约;
|
|
12
14
|
2. 若坏的是在途 Run:通常直接废弃该 Run(worktree 里的候选仍在分支上可读),新起一个 Run;
|
|
13
15
|
3. 若人为改过台账文件:从 Git 面事实重建判断,不要手补事件行。
|
|
14
16
|
|
|
15
17
|
### Run 进程被杀 / 机器重启
|
|
16
18
|
|
|
17
19
|
```bash
|
|
18
|
-
buildbeat
|
|
20
|
+
buildbeat resume --config <run-config.yaml>
|
|
19
21
|
```
|
|
20
22
|
|
|
21
23
|
在途步会以 `crashed` 关闭(事实落账),然后**重跑该步本身**(beta.3 改):进程死掉不说明候选有问题,丢失的那次尝试照常计入该步预算,预算耗尽即停人工。此前的语义是把 crash 当步骤失败走 failure 边——真实事故(deploy-18):宿主工具超时杀掉 verify worker,crash 被路由去 fix,fixer 面对零 verifier 证据白烧一轮。工作树脏了仍然先停人工。带批准恢复时会做 candidate/plan 新鲜度检查,变了即 `APPROVAL_STALE` 转人工。恢复不了就删 runtime 重跑——候选分支与 Git 面记录不丢。
|
|
@@ -27,7 +29,7 @@ buildbeat-v2 resume --config <run-config.yaml>
|
|
|
27
29
|
上一个 Run 异常退出可能留下仓库锁:确认真的没有活动 Run 后
|
|
28
30
|
|
|
29
31
|
```bash
|
|
30
|
-
buildbeat
|
|
32
|
+
buildbeat stop --repo . --run RUN-X --reason "crashed; releasing lock"
|
|
31
33
|
```
|
|
32
34
|
|
|
33
35
|
`stop` 落终态与理由;单纯锁残留也可删 `.buildbeat/runtime/` 后重来。
|
|
@@ -55,12 +57,12 @@ rm -rf .buildbeat/runtime/
|
|
|
55
57
|
|
|
56
58
|
## 诊断入口
|
|
57
59
|
|
|
58
|
-
`buildbeat
|
|
60
|
+
`buildbeat doctor --config <run-config>`:配置可解析、workflow 无出口环、adapter env 姿态、digest 可算、supersede 与 stall 阈值、通知通道与环境变量是否就位。`events`/`replay`/`metrics` 全部只读,可随时跑。
|
|
59
61
|
|
|
60
62
|
## "是不是卡住了"
|
|
61
63
|
|
|
62
64
|
> 自 2.0.0-beta.4(迭代 08)起。
|
|
63
|
-
先看 `buildbeat
|
|
65
|
+
先看 `buildbeat status --repo . --run <RUN>`:在飞步骤有已用时间、同仓历史中位数、worker 命令、最后一次输出距今多久与末三行输出。无输出超过阈值(默认 15 分钟,`--stall-after <分钟>` 或 run 配置 `stallAfterMs`)标 `STALLED`——**只标不杀**。判断口径:
|
|
64
66
|
|
|
65
67
|
- 有输出在持续 → 等(对照 `typical` 看是否已远超中位数);
|
|
66
68
|
- STALLED 且 worker 是 Agent CLI → 多半在长推理或等一个永远不来的交互,`stop --reason` 后按崩溃恢复重跑(中断的步重跑自身);
|
|
@@ -71,7 +73,7 @@ rm -rf .buildbeat/runtime/
|
|
|
71
73
|
## 打扫卫生:gc
|
|
72
74
|
|
|
73
75
|
> 自 2.0.0-beta.4(迭代 08)起。
|
|
74
|
-
终态 Run 会留下工作树、`run/*` 分支和偶尔的锁。`buildbeat
|
|
76
|
+
终态 Run 会留下工作树、`run/*` 分支和偶尔的锁。`buildbeat gc --repo .` 默认只出计划,`--apply true` 执行:
|
|
75
77
|
|
|
76
78
|
- 只动**终态且已压成 run-record** 的 Run(Git 面有账才动运行时面);
|
|
77
79
|
- 工作树可删(提交都在分支上);脏工作树不带 `--force true` 不动;
|
|
@@ -28,8 +28,8 @@ Open a fresh session in the **same project directory**. Load the BuildBeat Skill
|
|
|
28
28
|
The session reads current facts first:
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
|
-
buildbeat
|
|
32
|
-
buildbeat
|
|
31
|
+
buildbeat overview --repo .
|
|
32
|
+
buildbeat inbox --repo .
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
It then reads the goal, plan, decisions, and configuration under the relevant `delivery/work/<ID>/`. For active Run details, use `status --repo . --run <RUN-ID>`. Read IDs from actual output rather than guessing from a conversation.
|
|
@@ -28,8 +28,8 @@ BuildBeat 的接续依据是项目文件、Git 与运行台账。新会话读取
|
|
|
28
28
|
会话先读当前事实:
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
|
-
buildbeat
|
|
32
|
-
buildbeat
|
|
31
|
+
buildbeat overview --repo .
|
|
32
|
+
buildbeat inbox --repo .
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
随后读取对应 `delivery/work/<ID>/` 的目标、计划、决定和配置;需要活动 Run 细节时运行 `status --repo . --run <RUN-ID>`。ID 从实际输出读取,不凭聊天猜。
|
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
|
|
|
@@ -31,10 +31,4 @@
|
|
|
31
31
|
| [Worker 合同](05-worker-contract.md) | 输入输出信封(`severity` + `summary`)、阻断语义、各角色纪律、包装脚本 |
|
|
32
32
|
| [安全与权限边界](09-security-boundaries.md) | 内核实际做到的 vs 不能由此推出的;无人值守三层前置条件 |
|
|
33
33
|
|
|
34
|
-
## 迁移
|
|
35
|
-
|
|
36
|
-
| 文档 | 一句话 |
|
|
37
|
-
|---|---|
|
|
38
|
-
| [v1 迁移指南](08-migration-v1.md) | 升级 CLI 与迁移项目状态分开;手工 runbook,单向迁移不双写 |
|
|
39
|
-
|
|
40
34
|
observe v0(探测→分层响应→Intent 草稿→人分诊)在 [快速开始 §9](01-quickstart.md) 与 [Evidence 指南](06-evidence-guide.md) 中覆盖;schema 冻结见 [`RFC-0003 §8`](../RFC-0003-workflow-policy.md)。
|
|
@@ -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
|