Skip to content

Commit 9a3e2ef

Browse files
committed
feat: add work verification closeouts
1 parent c7d034b commit 9a3e2ef

7 files changed

Lines changed: 781 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7575
- `brigade handoff list/show/archive` for local Memory Handoff draft queue visibility, stale or invalid draft health, and reviewed archive records without running the ingestor.
7676
- `brigade handoff runs`, `run-show`, and `reconcile` for local handoff ingestion receipt visibility, draft outcome reconciliation, and archive outcome metadata without running the ingestor.
7777
- `brigade work review init/plan/run/runs/show/import-findings/findings/finding-show/closeout` for explicit local multi-harness code review producers, receipts, normalized findings, imported finding resolution, local closeout records, and `code-review` work inbox imports without automatic fixes or remote mutation.
78+
- `brigade work verify plan/run/runs/show` and `brigade work closeout <session-id-or-latest>` for local verification receipts and work closeout records that collect task acceptance, test command results, scanner sweep status, code review closeout state, handoff draft status, and session evidence without CI or remote mutation.
7879
- `brigade work backup init/status/doctor/import-issues` for read-only local backup health summaries and `backup-health` inbox imports.
7980
- Backup health checks for stale snapshots, failed or stale checks, failed or stale prunes, missing summaries, overdue restore rehearsals, and unsafe private summary fields.
8081
- `brigade tools init/list/show/search/describe/contracts/call plan/call queue/call list/call show/call approve/call reject/call hold/call run/runtime/policy/plan/apply/doctor/import-issues`, plus `brigade tools run list/show/latest/replay` and `brigade tools checkpoint list/show/approve/reject/resume`, for portable tool, slash command, skill, superpower, script, and MCP catalog discovery plus explicit projection writes, read-only call planning, local call approval review, explicit approved script and local MCP execution, run history inspection, replay review, checkpointed resume, runtime supervision, and host-local execution policy.

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,11 @@ brigade work review import-findings <run-id>
199199
brigade work review findings
200200
brigade work review finding-show <finding-id-or-import-id>
201201
brigade work review closeout latest
202+
brigade work verify plan
203+
brigade work verify run
204+
brigade work verify runs
205+
brigade work verify show <run-id>
206+
brigade work closeout latest
202207
brigade work sweep
203208
brigade work sweep --all
204209
brigade work sweeps
@@ -515,6 +520,15 @@ Manual session commands:
515520
- `brigade work end --note "what happened"` closes the active session and writes `end.md`.
516521
- `brigade work end --handoff` also writes a Memory Handoff.
517522

523+
Work verification and closeout commands:
524+
525+
- `brigade work verify plan` previews the local verification commands and current evidence snapshot without running anything.
526+
- `brigade work verify run` executes explicit local verification commands without a shell and writes receipts under `.brigade/work/verify-runs/`.
527+
- `brigade work verify runs` and `brigade work verify show <run-id>` inspect local verification receipts, command exit codes, summaries, and log paths.
528+
- `brigade work closeout <session-id-or-latest>` writes a local closeout receipt under `.brigade/work/closeouts/` that collects task acceptance, latest verification, scanner sweep status, code review closeout state, handoff draft status, and session evidence.
529+
530+
Verification and closeout are local gates. Brigade does not mutate CI, GitHub, reviewers, scanner promotions, handoff ingestion, daemons, or schedulers. Verification commands run only when explicitly requested.
531+
518532
### Memory And Bootstrap Health
519533

520534
Memory and bootstrap readiness are part of the same operating-system health story.

ROADMAP.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ Goal: make Brigade a safe target for local automations that discover useful work
4242
- Connect local handoff ingestor outcomes back to draft review state. Status: implemented with normalized receipts under `.brigade/handoffs/ingest-runs/`, `brigade handoff runs`, `run-show`, `reconcile`, ingestion status in draft list/show, archive outcome metadata, and daily-loop warnings for stale unreconciled drafts, without running the ingestor.
4343
- Run explicit multi-harness code review producers and route findings through the scanner inbox. Status: implemented with gitignored `.brigade/reviews.toml`, `brigade work review`, local receipts under `.brigade/reviews/runs/`, normalized `code-review` findings, daily brief surfacing, and work doctor checks, without automatic fixes or remote mutation.
4444
- Close out imported review findings against downstream work. Status: implemented with `brigade work review findings`, `finding-show`, `closeout`, source-fingerprint re-review detection, task review evidence, and daily-loop warnings for unclosed review runs.
45+
- Close out completed work against local verification evidence. Status: implemented with `brigade work verify plan/run/runs/show` and `brigade work closeout`, collecting task acceptance, test command receipts, scanner sweep state, code review closeout state, handoff draft status, and session evidence without CI or remote mutation.
4546

4647
## Later Phase: Chat Surface Scanners
4748

docs/work-closeout.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Work Verification And Closeout
2+
3+
Brigade can write local verification receipts and work closeout records for completed work sessions. This gives the operator one reviewable answer for task acceptance, test command results, scanner sweep state, code review closeout state, handoff draft state, and session evidence.
4+
5+
## Commands
6+
7+
```bash
8+
brigade work verify plan
9+
brigade work verify run
10+
brigade work verify run --command "PYTHONPATH=src python3 -m pytest -q"
11+
brigade work verify runs
12+
brigade work verify show <run-id>
13+
brigade work closeout latest
14+
brigade work closeout <session-id>
15+
```
16+
17+
`verify plan` inspects the repo and proposes local verification commands. It recognizes Python test layouts and package.json projects, and it reports blockers without running anything.
18+
19+
`verify run` executes only explicit local commands, directly with `shell=False`. It supports simple leading environment assignments such as `PYTHONPATH=src`, rejects high-risk shell-like commands, captures stdout and stderr logs locally, and writes a receipt under:
20+
21+
```text
22+
.brigade/work/verify-runs/
23+
```
24+
25+
`verify runs` and `verify show` inspect those receipts.
26+
27+
`work closeout` writes a closeout record under:
28+
29+
```text
30+
.brigade/work/closeouts/
31+
```
32+
33+
The closeout includes the selected work session, task acceptance criteria when present, latest verification receipt, latest scanner sweep state, code review closeout state, handoff draft queue state, and blockers. It also stores a compact closeout reference on the session `session.json`.
34+
35+
## Ready State
36+
37+
A closeout is ready when:
38+
39+
- the work session is ended
40+
- the latest verification receipt completed
41+
- the consumed task has acceptance criteria when task evidence is present
42+
- the latest scanner sweep has no unresolved review issue
43+
- code review has no unclosed review run and no unresolved imported finding
44+
- handoff draft health has no open issue
45+
46+
Blocked closeouts are still written, so the operator has a local record of what remains.
47+
48+
## Boundary
49+
50+
Verification and closeout are local and explicit. Brigade does not mutate CI, GitHub, reviewers, scanner imports, handoff drafts, canonical memory, daemons, schedulers, or remotes. Verification commands run only when the operator asks for `brigade work verify run`.

src/brigade/cli.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,30 @@ def _build_parser() -> argparse.ArgumentParser:
243243
p_work_sweep_review.add_argument("sweep_id", help="Sweep id, unique prefix, or latest.")
244244
p_work_sweep_review.add_argument("--target", "-t", type=Path, default=Path("."), help="Repo or workspace to inspect.")
245245
p_work_sweep_review.add_argument("--json", action="store_true", help="Print machine-readable JSON.")
246+
p_work_verify = work_sub.add_parser("verify", help="Plan and run local work verification.")
247+
verify_sub = p_work_verify.add_subparsers(dest="verify_command", metavar="<verify-command>")
248+
verify_sub.required = True
249+
p_work_verify_plan = verify_sub.add_parser("plan", help="Plan local verification without running commands.")
250+
p_work_verify_plan.add_argument("--target", "-t", type=Path, default=Path("."), help="Repo or workspace to inspect.")
251+
p_work_verify_plan.add_argument("--command", dest="verify_commands", action="append", default=None, help="Verification command. May be repeated.")
252+
p_work_verify_plan.add_argument("--json", action="store_true", help="Print machine-readable JSON.")
253+
p_work_verify_run = verify_sub.add_parser("run", help="Run local verification commands and write a receipt.")
254+
p_work_verify_run.add_argument("--target", "-t", type=Path, default=Path("."), help="Repo or workspace to update.")
255+
p_work_verify_run.add_argument("--command", dest="verify_commands", action="append", default=None, help="Verification command. May be repeated.")
256+
p_work_verify_run.add_argument("--timeout", type=int, default=900, help="Timeout per command in seconds.")
257+
p_work_verify_run.add_argument("--json", action="store_true", help="Print machine-readable JSON.")
258+
p_work_verify_runs = verify_sub.add_parser("runs", help="List local work verification receipts.")
259+
p_work_verify_runs.add_argument("--target", "-t", type=Path, default=Path("."), help="Repo or workspace to inspect.")
260+
p_work_verify_runs.add_argument("--limit", type=int, default=20, help="Maximum runs to list.")
261+
p_work_verify_runs.add_argument("--json", action="store_true", help="Print machine-readable JSON.")
262+
p_work_verify_show = verify_sub.add_parser("show", help="Show one local work verification receipt.")
263+
p_work_verify_show.add_argument("run_id", help="Run id, unique prefix, or latest.")
264+
p_work_verify_show.add_argument("--target", "-t", type=Path, default=Path("."), help="Repo or workspace to inspect.")
265+
p_work_verify_show.add_argument("--json", action="store_true", help="Print machine-readable JSON.")
266+
p_work_closeout = work_sub.add_parser("closeout", help="Write a local work closeout receipt.")
267+
p_work_closeout.add_argument("session_id", help="Work session id, unique prefix, or latest.")
268+
p_work_closeout.add_argument("--target", "-t", type=Path, default=Path("."), help="Repo or workspace to update.")
269+
p_work_closeout.add_argument("--json", action="store_true", help="Print machine-readable JSON.")
246270
p_work_inbox = work_sub.add_parser("inbox", help="Review scanner-ready work imports.")
247271
p_work_inbox.add_argument("--target", "-t", type=Path, default=Path("."), help="Repo or workspace to inspect.")
248272
p_work_inbox.add_argument("--json", action="store_true", help="Print machine-readable JSON.")
@@ -1280,6 +1304,24 @@ def main(argv=None) -> int:
12801304
return work_cmd.sweep_show(target=args.target, sweep_id=args.sweep_id, json_output=args.json)
12811305
if args.work_command == "sweep-review":
12821306
return work_cmd.sweep_review(target=args.target, sweep_id=args.sweep_id, json_output=args.json)
1307+
if args.work_command == "verify":
1308+
if args.verify_command == "plan":
1309+
return work_cmd.verify_plan(target=args.target, commands=args.verify_commands, json_output=args.json)
1310+
if args.verify_command == "run":
1311+
return work_cmd.verify_run(
1312+
target=args.target,
1313+
commands=args.verify_commands,
1314+
timeout=args.timeout,
1315+
json_output=args.json,
1316+
)
1317+
if args.verify_command == "runs":
1318+
return work_cmd.verify_runs(target=args.target, limit=args.limit, json_output=args.json)
1319+
if args.verify_command == "show":
1320+
return work_cmd.verify_show(target=args.target, run_id=args.run_id, json_output=args.json)
1321+
parser.error(f"unknown verify command: {args.verify_command}")
1322+
return 2
1323+
if args.work_command == "closeout":
1324+
return work_cmd.closeout(target=args.target, session_id=args.session_id, json_output=args.json)
12831325
if args.work_command == "inbox" and getattr(args, "inbox_command", None):
12841326
if args.inbox_command == "doctor":
12851327
return work_cmd.inbox_doctor(target=args.target, json_output=args.json)

0 commit comments

Comments
 (0)