Add prerequisite gate before dispatch

This commit is contained in:
Emil Shanaty
2026-10-27 19:41:36 +03:00
parent c3f58ceb40
commit 2309fda7b7
9 changed files with 180 additions and 23 deletions
+35 -6
View File
@@ -23,7 +23,30 @@ Budget:
Go: a 40-file migration with per-module tests, a 30-source research report, a 20-section document with a style guide, a multi-dataset analysis, a multi-screen visual redesign, a multi-service runbook.
No-go: one failing test, one architectural decision, a detail pass where every unit touches the same artifact.
## 1. Recon (2–4 agents)
## 1. Prerequisite gate
Do this before recon and before writing task cards. A missing compiler, runtime, browser, display,
database, credential or package manager found mid-wave costs an entire wave and can leave the tree
half-changed. Full policy and the approval template: `references/prerequisites.md`.
1. Inventory required vs optional items: toolchain + pinned version, build/test/lint commands, runtime,
services, display/GPU, credentials (presence only), agent tools (`workflow`/`subagent`), disk/ports.
2. Run the documented checks yourself. Do not trust a worker's "should work".
3. Prefer existing/project-local toolchains. **Never** run `sudo`, system package managers, global
installs or `curl | sh` without explicit user approval; never change the user's global environment
as a side effect.
4. If a required item is missing and cannot be installed safely: **stop before work**, ask the user
with the exact item, command, scope (project/user/system), alternatives and impact. Do not dispatch
workers while the answer is pending.
5. After approval/install, re-run the checks and the baseline suite. Record `.swarm/prerequisites.md`
and `state.json.prerequisites` as `passed`, `needs_user` or `degraded`.
6. Optional items may be skipped only with a recorded reduced scope; mark affected acceptance checks
`not_run`. Workers never install; they return `blocked` with the exact command/output.
Do not start with "I'll install it later if needed." The gate is before recon, not after the first
failure.
## 2. Recon (2–4 agents)
Give each recon agent one question, not the whole task:
- Structure: entry points, modules, build/test commands.
@@ -35,13 +58,14 @@ Require findings as `path:line — fact`, no proposals. Merge into `.swarm/brief
Recon lifecycle matters: each recon agent writes its report and stops. It must kill GUI/probe processes it started, must not run the full test suite, and must not keep a slot while the build wave starts. If a recon agent is still active after its report exists, interrupt it; otherwise it silently consumes one of the active-child slots.
## 2. Plan gate
## 3. Plan gate
Resolve `<skill>` to the base directory reported by the skill loader. If the workspace is a git repository, add `.swarm/` to `.gitignore` before the baseline so coordination files never reach the diff. Bootstrap once:
```sh
mkdir -p .swarm/tasks .swarm/reports .swarm/reviews .swarm/tmp
cp <skill>/assets/brief.md.tmpl .swarm/brief.md
cp <skill>/assets/prerequisites.md.tmpl .swarm/prerequisites.md
cp <skill>/assets/report.schema.json .swarm/report.schema.json
cp <skill>/assets/verdict.schema.json .swarm/verdict.schema.json
node <skill>/scripts/audit-scope.mjs --init
@@ -66,6 +90,8 @@ Write the plan before any worker starts. Keep the plan proportionate: a small do
**Waves.** Topologically sort by `depends_on`, then balance effort across batches. Do **not** plan 8–12 workers from a documented default: discover the runtime active-child cap first. Compute `batch_size = clamp(slot_cap - active_children - 1, 2, 8)`; recon and any other subagents count as active children. If the cap is unknown, use 6. Put foundational or risky tasks in batch 1; verify after the last build batch.
**Gate checklist:**
- [ ] Required prerequisites are `passed` (or user-approved `degraded`), recorded in `.swarm/prerequisites.md`; no `needs_user`/`blocked` item remains.
- [ ] Baseline build/test command has been run and its result recorded.
- [ ] 8+ tasks, each with objective, inputs, write scope, acceptance, stop condition, and a token/effort budget.
- [ ] Files/modules over ~800 lines are split, or the task explicitly owns the integration cost.
- [ ] Token budget, soft cap and verification reserve are recorded; units are merged/split to avoid fixed-overhead waste.
@@ -114,7 +140,7 @@ Minimal `plan.json` shape:
`audit-scope.mjs` reads only `id` and `write`. Keep those accurate. Use `path/**` for directories, including directories the task will create.
## 3. Build wave
## 4. Build wave
Dispatch one `workflow` call per build wave (see `references/orchestration.md`). Use `assets/wave.workflow.js`, which splits tasks into batches, catches spawn errors instead of discarding the whole wave, and carries `args.concurrency`.
@@ -147,7 +173,7 @@ A `blocked` report is a request for a lead decision, not a failure. Fast path:
If the block reveals an underspecified interface shared by several tasks, update the contract once and message all affected workers. If two blocked tasks need conflicting contracts, stop and re-plan.
## 4. Verify wave
## 5. Verify wave
Choose verifiers by risk cluster, not one per task: 4–6 verifiers for 8–12 tasks, fewer for a small domain task. A verifier gets the task cards, the changed files (or diff), and the acceptance commands. It does not get the worker's rationale and does not fix anything.
@@ -163,7 +189,7 @@ Evidence standard: for every criterion, a command/artifact/citation/metric and i
On failure, create a fix task with the verifier's repro; do not send the verifier back to fix its own finding. After fixes, re-run only the affected **delta** (diff + findings + acceptance commands), not the whole repository, and mark the previous review stale; repeat until the remaining findings are minor/documented. Then run one final integrated verification pass on the frozen build.
## 5. Integrate
## 6. Integrate
One integrator (two only for disjoint areas) owns:
- shared files and cross-cutting edits;
@@ -173,7 +199,7 @@ One integrator (two only for disjoint areas) owns:
No parallel workers during integration. The integrator may read all task cards and reviews; it writes `.swarm/integration.md` with what changed and why. Freeze the tree while the final verification runs; any post-verification edit invalidates the affected evidence.
## 6. Close
## 7. Close
Final review is against the **original request**, not the plan: a fresh agent checks the success criteria, the diff, and the evidence. Then the lead writes `.swarm/final-report.md` with these sections:
@@ -199,6 +225,9 @@ Final review is against the **original request**, not the plan: a fresh agent ch
| Verifiers find the same defect | brief missing a convention | fix the brief, add a check, re-run affected tasks |
| Lead context filling up | reading full reports | read summary + evidence; open only exceptions |
| A worker hangs | no per-agent timeout exists | kill the job, split the task, add a tighter stop condition |
| Missing tool/runtime discovered mid-wave | prerequisite gate skipped | stop, run `prerequisites.md`, ask user, do not spawn replacements |
| Version mismatch with lockfile | unpinned global toolchain | use project-local pinned version; record it and re-run baseline |
| Required credential/display unavailable | not checked before dispatch | ask user for exact item/scope; degrade only with recorded reduced scope |
| Token spend explodes | huge files, too many agents, full re-reads/reviews | split files, right-size batch, delta-review, record usage |
| Verifier repeats a full review after a small fix | no delta procedure | review diff + findings + affected checks only |
| Reports/reviews dominate input | oversized prose | cap to evidence lines; logs in artifacts |
+82
View File
@@ -0,0 +1,82 @@
# Prerequisite gate
Run this **before** writing the plan or dispatching any worker. A missing compiler, runtime, browser,
display, database, credential or package manager discovered mid-wave wastes an entire wave and can
leave the workspace half-changed. Resolve required prerequisites first, or ask the user before work
starts.
## What to check
| Category | Examples | How to check |
|---|---|---|
| Toolchain | Rust/cargo, Node/pnpm, Python/uv, Go, JDK | `command -v`, `--version` |
| Project pin | `rust-toolchain.toml`, `.nvmrc`, `packageManager`, lockfiles | compare actual vs pinned |
| Build/test | build, test, lint, typecheck, codegen commands | run the documented command once |
| Runtime | browser, GUI display, GPU, emulator, container runtime | launch a smoke command |
| Services | database, cache, API, local server | connect/health check |
| Credentials | registry token, API key, SSH agent | check **presence only**, never print values |
| Workspace | writable repo, disk space, ports, git state | `df`, port check, `git status` |
| Agent tools | `workflow`, `subagent`, visual capture, screenshot mode | runtime diagnostics |
| Baseline | existing tests/gates pass before changes | run the baseline suite |
Classify each item:
- **required** — acceptance cannot run without it;
- **optional** — nice-to-have; skipping reduces scope or confidence;
- **blocked** — required and unavailable/uninstallable.
## Install policy
1. **Prefer what already exists.** Check alternate versions, project-local toolchains and documented
setup before installing anything.
2. **Use project-local, pinned installs** (rustup toolchain, `uv`, `pnpm`/corepack, virtualenv,
project venv, devcontainer) rather than global/system packages. A project-local install that
writes only inside the workspace and does not require `sudo` may be run without a separate
prompt; record the command/version.
3. **No global/system changes without approval.** Do not run `sudo`, `apt`, `dnf`, `brew`, global
npm/pip installs, or `curl | sh` without explicit user approval. Do not modify the user's global
environment as a side effect of a task.
4. **No unpinned latest.** Pin to the version required by the project; record the exact command and
resulting version.
5. **Respect offline/restricted environments.** If the network or permissions block installation,
stop and ask; do not invent a workaround that changes the host.
6. **Workers never install.** If a worker discovers a missing prerequisite, it returns `blocked`
with the exact command/output; the lead owns installation and approval.
7. **After install, re-run the check** and the baseline command. An install that does not make the
gate pass is not resolved.
## If you cannot install it
Ask the user **before starting work**, with a compact decision request:
```text
Missing prerequisite: <name/version>
Required for: <task/acceptance check>
Check: `<command>` -> <actual error>
Proposed fix: `<exact command>` (scope: project-local / user / system)
Alternatives: use <existing path/version>; skip <feature> and reduce scope; stop.
May I run the proposed fix, or which alternative do you prefer?
```
Do not ask "can I install dependencies?" without the exact package, scope and reason. Do not start
workers while the answer is pending. If the user declines, record the reduced scope and the checks
that will be `not_run`.
## Record the result
Write `.swarm/prerequisites.md` and set `state.json.prerequisites` to `passed`, `needs_user`, or
`degraded`.
```markdown
| Item | Required? | Check | Status | Version/notes |
|---|---|---|---|---|
| cargo | yes | `cargo --version` | pass | 1.85.0 |
| Playwright browser | yes (UI) | `pnpm exec playwright --version` | needs_user | not installed |
| GPU display | optional | smoke render | degraded | software renderer |
```
## Gate rule
No build or verify wave starts while a **required** prerequisite is `needs_user` or `blocked`.
Optional prerequisites may be skipped only with an explicit note in the brief and the affected
acceptance checks marked `not_run`. The lead, not a worker, owns the decision.