Prune agent-swarm to a genuinely lite core

This commit is contained in:
Emil Shanaty
2026-10-28 00:33:08 +03:00
parent 32d74210e4
commit 843974a58d
15 changed files with 5 additions and 1207 deletions
+1 -5
View File
@@ -11,10 +11,7 @@ product acceptance. Тяжёлые темы вынесены в опционал
- [Описание на русском](agent-swarm/README.ru.md)
- [Инструкции скилла](agent-swarm/SKILL.md)
- [Runbook](agent-swarm/references/playbook.md)
- [Cookbook по `workflow`](agent-swarm/references/orchestration.md)
- [Domain-адаптеры](agent-swarm/references/domains.md)
- [Token economy](agent-swarm/references/token-economy.md)
- [Prerequisite gate](agent-swarm/references/prerequisites.md)
- [Product quality gates](agent-swarm/references/product-quality.md)
- [Изолированное визуальное тестирование](agent-swarm/references/visual-testing.md)
@@ -37,7 +34,6 @@ agent-swarm/
├── SKILL.md # тонкий core: режимы + инварианты
├── README.ru.md # краткое описание
├── evals/ # baseline vs with-skill, 3 задачи, scorecard
├── references/ # опциональные модули: playbook, packets, domains, quality, tokens...
├── assets/ # шаблоны, схемы, workflow-скрипты
├── references/ # только domains, prerequisites, product quality, visual testing
└── scripts/audit-scope.mjs # проверка ownership
```
+1 -5
View File
@@ -68,20 +68,16 @@ implementer + один critic обычно дают более цельный UI
Читать только по необходимости:
- `references/playbook.md` — подробный runbook для больших swarm.
- `references/packets.md` — шаблоны brief/task/verifier.
- `references/orchestration.md` — `workflow`, батчи, ретраи.
- `references/domains.md` — адаптеры для кода/research/контента/данных/дизайна/ops.
- `references/prerequisites.md` — preflight и политика установки.
- `references/token-economy.md` — бюджеты, контекст, delta-review.
- `references/visual-testing.md` — изолированные display, скриншоты, computer-use.
- `references/product-quality.md` — performance/UX/baseline/human acceptance.
- `evals/` — как проверять сам скилл (baseline vs with-skill).
## Настройка
- Шаблоны: `assets/`.
- Проверка скоупа: `node scripts/audit-scope.mjs --init` перед стартом, затем `node scripts/audit-scope.mjs`.
- Для swarm пишите brief/tasks сами; обязательных шаблонов больше нет.
- Для директорий в `plan.json` используйте glob `path/**`, включая ещё не созданные папки.
- Перед изменением скилла прочитайте `evals/README.md`; не считайте, что новая версия лучше старой
без сравнения.
+3 -8
View File
@@ -71,21 +71,16 @@ Optional, for resumability and coordination — not a requirement for every task
- `.swarm/reports/Txx.json` — structured evidence, if the lead needs to triage many workers;
- `.swarm/reviews/Vxx.md` — independent verdict and findings.
Use the batched runner in `assets/wave.workflow.js` when `workflow` exists; otherwise use `subagent`
or direct sequential work. Never relaunch an oversubscribed fan-out. Read `references/playbook.md`
for the detailed runbook, `references/packets.md` for cards and `references/orchestration.md` for
tool specifics — only when the task needs them.
Use the available concurrency directly. If `workflow`/`subagent` is unavailable, work sequentially with
the same brief and scopes; never relaunch an oversubscribed fan-out. There are no mandatory templates:
write a one-page brief and cards yourself, or use the bundled `evals/` only to test the skill.
## Optional modules
Read only what applies:
- `references/playbook.md` — detailed swarm runbook, gates, recovery.
- `references/packets.md` — brief/task/verifier templates and examples.
- `references/orchestration.md` — `workflow` patterns, retries, batching.
- `references/domains.md` — software, research, content, data, design, operations.
- `references/prerequisites.md` — preflight, install/approval policy.
- `references/token-economy.md` — budgets, context discipline, delta review.
- `references/visual-testing.md` — isolated displays, screenshots, computer-use limits.
- `references/product-quality.md` — performance/UX/baseline/human acceptance.
- `evals/` — how to test this skill itself (baseline vs with-skill, trigger checks).
-71
View File
@@ -1,71 +0,0 @@
# Swarm brief — {{TASK}}
## Goal
{{One paragraph. What must exist when the swarm is done.}}
## Success criteria
- [ ] {{Criterion}} — verified by {{check, command, artifact or citation}}
- [ ] {{Criterion}} — verified by {{check, command, artifact or citation}}
Scope is checked by the lead with the skill's `scripts/audit-scope.mjs`; workers do not run it.
## Non-goals
- {{What must not change or be attempted.}}
## Quality profile
- Profile: {{prototype / product}}
- Performance budget: {{p95 frame time / latency / startup / memory, or n/a}}
- Baseline version/scenarios: {{version + 3–5 step scenario, or none}}
- User acceptance owner: {{name / pending}}
- Release build command: {{command or n/a}}
## Domain profile
- Domain: {{software / research / content / data / design / operations}}
- Primary artifacts: {{paths, sections, datasets, renders, services}}
- Evidence type: {{command / artifact / citation / metric / render}}
- Evidence commands or sources: {{commands, URLs, access notes}}
- Approval boundaries: {{what needs human confirmation}}
## Stack and commands (when applicable)
| Action | Command |
|---|---|
| build | `{{command or n/a}}` |
| test | `{{command or n/a}}` |
| lint | `{{command or n/a}}` |
| run | `{{command or n/a}}` |
| evidence | `{{screenshot/citation/metric command}}` |
## Artifact / source map
| Path, source or artifact | Role |
|---|---|
| `{{path/url/artifact}}` | {{one line}} |
## Conventions and invariants
- {{Naming, error handling, test style, formatting.}}
- {{Data or API invariants that must not break.}}
## Hazards
- {{Generated files, migrations, flaky tests, shared ports, secrets, caches.}}
- {{Generated or vendored paths that must not be edited.}}
## Prerequisites
- Status: {{passed / needs_user / degraded}}
- Details: `.swarm/prerequisites.md`
- Missing/blocked: {{items or none}}
- User approval: {{approved/declined/pending}}
## Token / effort budget
- Hard budget: {{tokens or n/a}}; reserve {{20–30%}} for verification and integration.
- Prefer vertical slices and files under ~800 lines.
- Workers read the listed inputs/ranges, not the whole repository.
## Frozen contracts
See `.swarm/contracts.md`. Do not change an interface without returning `blocked`.
## Global forbidden actions
- No installs, repo-wide format/lint/codegen, migrations, deployments, external publishes, dev servers, or git writes without explicit scope.
- No edits outside your task's write scope.
- Do not edit `.swarm/brief.md`, `plan.*`, `contracts.md`, or another task's files or reports.
## Reporting
Write `.swarm/reports/{{ID}}.json` and return the same object. Use `.swarm/report.schema.json`.
-30
View File
@@ -1,30 +0,0 @@
# Prerequisites — {{TASK}}
Checked before dispatch. Do not print secrets.
## Required
| Item | Check command | Status | Version / error | Owner |
|---|---|---|---|---|
| {{tool/runtime}} | `{{command}}` | {{pass/missing/needs_user}} | {{version or exact error}} | lead |
## Optional / degraded
| Item | Check | Impact if missing | Decision |
|---|---|---|---|
| {{display/GPU/service}} | `{{command}}` | {{reduced scope}} | {{skip/ask/install}} |
## User approval
- Missing item: {{name}}
- Why required: {{acceptance check}}
- Proposed command/scope: `{{command}}` ({{project-local/user/system}})
- Alternatives: {{existing path / reduced scope / stop}}
- User decision: {{pending/approved/declined}}
- Recorded in `state.json`: {{passed/needs_user/degraded}}
## Baseline
- Build: `{{command}}` → {{result}}
- Tests: `{{command}}` → {{result}}
- Visual/smoke: `{{command}}` → {{result}}
-52
View File
@@ -1,52 +0,0 @@
{
"type": "object",
"properties": {
"task_id": { "type": "string" },
"status": {
"type": "string",
"enum": ["done", "partial", "blocked", "failed"]
},
"verdict": {
"type": "string",
"enum": ["pass", "pass_with_risks", "fail"]
},
"summary": { "type": "string" },
"files_changed": {
"type": "array",
"items": { "type": "string" }
},
"acceptance": {
"type": "array",
"items": {
"type": "object",
"properties": {
"check": { "type": "string" },
"result": { "type": "string", "enum": ["pass", "fail", "not_run"] },
"evidence": { "type": "string" }
},
"required": ["check", "result"]
}
},
"evidence": {
"type": "array",
"items": { "type": "string" }
},
"issues": {
"type": "array",
"items": { "type": "string" }
},
"assumptions": {
"type": "array",
"items": { "type": "string" }
},
"blocked_question": { "type": "string" }
},
"required": [
"task_id",
"status",
"summary",
"files_changed",
"evidence",
"acceptance"
]
}
-52
View File
@@ -1,52 +0,0 @@
# {{ID}} — {{title}}
Role: worker | Wave: {{n}} | Depends on: {{ids or —}} | Effort: {{S/M/L}}
## Objective
{{1–3 sentences. What must exist when done.}}
## Why
{{Which success criterion this serves.}}
## Inputs (read first)
- `.swarm/brief.md`
- `.swarm/contracts.md` §{{section}}
- `{{artifact/source}}`: {{path:start-end, URL, dataset, design file}}
## Deliverables
- `{{new or changed path/artifact}}` — {{what}}
- `{{test/evidence artifact}}` — {{what it proves}}
## Write scope (only these)
- `{{glob or exact path}}`
## Read-only
- `{{path}}`
## Contract
{{Exact signature, data shape, CLI behavior, or output format.}}
## Constraints
- {{No new dependencies, style, performance, compatibility.}}
- Context budget: read only the inputs above; if you need more than {{N}} additional files, return `blocked` instead of exploring the whole repo.
- Prerequisites are lead-owned: do not install tools, packages or system dependencies. If one is missing, return `blocked` with the exact check and error.
- Do not run the full test suite unless the card explicitly asks; run targeted checks.
## Acceptance (re-runnable)
1. `{{command or artifact path}}` → {{expected result/state}}
2. `{{citation check / metric / render at sizes}}` → {{expected result}}
3. Every criterion must have evidence a fresh verifier can reproduce.
If the quality profile is `product` and this task touches UI/interaction, also record:
- release-build p95 frame time and input latency at the target size;
- the 3–5 step user scenario;
- baseline comparison (new must not be worse).
## Report
`.swarm/reports/{{ID}}.json` per `.swarm/report.schema.json`; status `done|partial|blocked|failed`.
Keep the report to summary + evidence lines; raw logs go to `.swarm/tmp/{{ID}}/`.
## Stop conditions
- Time box: 25 minutes for S/M, 45–60 minutes for L, or 3 failed attempts at the same step.
- A load-bearing unknown, a needed file outside scope, or a broken contract → `blocked` with the exact question. Do not guess.
- If a sibling task's in-flight file causes a compile/test failure outside your scope, wait briefly and report `partial` with the exact external error; never edit that file.
-10
View File
@@ -1,10 +0,0 @@
{
"type": "object",
"properties": {
"task_id": { "type": "string" },
"verdict": { "type": "string", "enum": ["pass", "pass_with_risks", "fail"] },
"summary": { "type": "string" },
"review_file": { "type": "string" }
},
"required": ["task_id", "verdict", "summary", "review_file"]
}
-55
View File
@@ -1,55 +0,0 @@
# {{ID}} — verify {{task IDs}}
You did not write this work. Do not fix it. Do not trust worker summaries.
## Inputs
- Task cards: {{paths}}
- Changed files/artifacts or diff: {{paths or command}}
- Acceptance checks: {{commands, artifact paths, citations, metrics}}
## For each criterion
| Criterion | Evidence (command/artifact/citation/metric) | Observed | Pass/Fail |
|---|---|---|---|
| {{criterion}} | {{command, path, URL or check}} | {{observed}} | {{pass/fail}} |
For research/content, cite the exact source and date. For data, record input hash, row count and
metric. For design, record the rendered artifact and sizes. For software, record the command and
output. Evidence must be reproducible by a fresh verifier.
## Also check
- Scope: every changed file is owned by the task.
- Contracts: signatures and data shapes match `.swarm/contracts.md`.
- Tests: assert real behavior; no silent skips; no snapshot updates.
- Edge cases named in the task card.
## Freeze
Do not install tools or dependencies; prerequisites are lead-owned. If a required check cannot run,
report `not_run` with the exact missing item — do not change the environment.
The tree is frozen during verification. Do not edit product source, tests, docs or manifests. If you need a gate script that rewrites generated files, copy it/hash-check it instead of changing the tree.
## Visual checks
For GUI products, run the app in your own isolated Xvfb/display (never a shared desktop). Capture the default size, the minimum size, empty/error states and every modal. Record the screenshot path and exact command alongside each finding; a screenshot without a command is not evidence.
Computer-use (mouse/keyboard) is an optional last-resort tier: one agent, disposable desktop/VM, after deterministic checks, never parallel, never the sole evidence. Prefer app screenshot mode or scripted input.
## Product quality (product profile only)
Verify the release/optimized build, not a debug build:
- p50/p95 frame time at the target size, input-to-visible latency, startup, idle CPU/memory;
- the 3–5 step real user scenario, not just a screenshot;
- baseline comparison on the same scenario (regression = fail);
- report `not_run` if these were not measured.
A technical pass is **not** product acceptance. The user still runs the artifact and gives an explicit
verdict (usable / usable with issues / not usable). Do not mark the product gate `pass` on the user's
behalf.
## Verdict
`pass` / `pass_with_risks` / `fail` — with the top risks and exact repro commands.
For product-profile work, `pass` requires functional + measured performance + UX scenario + baseline;
otherwise use `pass_with_risks` with missing gates named, or `not_run`.
## Report
Keep the review to findings + commands + evidence (target 5–8k tokens); raw logs stay in `.swarm/tmp/`. Review the diff and affected checks, not the whole repository.
FIRST write the full review to `.swarm/reviews/{{ID}}.md`. Then return only the minimal structured verdict:
`{task_id, verdict, summary, review_file}` per `.swarm/verdict.schema.json`.
The review file is the source of truth; it must exist even if the structured reply is lost. Do not return a long findings array in the workflow schema.
-88
View File
@@ -1,88 +0,0 @@
// agent-swarm verification runner — copy into the `script` field of the workflow tool.
// args: {
// wave?: number,
// tasks: [{ id: string, review: string }], // review = .swarm/reviews/Vxx.md
// concurrency?: number // verifier slots; default 4, keep free slots
// }
//
// The detailed review is written to disk BEFORE the structured verdict is
// returned. The workflow schema is intentionally tiny: a long findings array is
// easy to get wrong and a schema miss must not destroy the verification work.
const VERDICT = {
type: "object",
properties: {
task_id: { type: "string" },
verdict: { type: "string", enum: ["pass", "pass_with_risks", "fail"] },
summary: { type: "string" },
review_file: { type: "string" }
},
required: ["task_id", "verdict", "summary", "review_file"]
};
const CONCURRENCY = Math.max(
1,
Math.min(Number(args.concurrency) || 4, 8)
);
const promptFor = (t, attempt) => [
`You are verifier ${t.id}. You did not write this work; do not fix it and do not edit product source, tests, docs or manifests.`,
`Read .swarm/brief.md, the relevant .swarm/tasks/*.md cards, .swarm/contracts.md, and the implementation.`,
`Work only in ${t.review} and .swarm/tmp/${t.id}/. Copy or hash-check generated files instead of rewriting the tree.`,
`Verify against the original acceptance criteria, not the worker's summary. Run the commands yourself and record exact commands + observed results. Findings need file:line, reproduction, expected vs actual.`,
`Freeze assumption: the tree is not being edited during this wave. If you see a stale/inconsistent build, say so; do not fix it.`,
`FIRST write the full review to ${t.review}. THEN return only {task_id, verdict, summary, review_file}; keep summary <= 2000 chars. The review file is the source of truth and must exist even if the structured reply fails.`,
`Verdict rules: "fail" for critical/major product gaps; "pass_with_risks" for minor or documented-scope risks; "pass" only when no material issue remains.`,
attempt > 1
? `The previous structured reply was unusable. Preserve the review file; return the four required fields only.`
: ""
].filter(Boolean).join("\n");
const failed = (t, why) => ({
task_id: t.id,
verdict: "fail",
summary: why,
review_file: t.review
});
async function runOne(t) {
for (let attempt = 1; attempt <= 2; attempt++) {
try {
const r = await agent(promptFor(t, attempt), {
label: t.id,
phase: `verify ${args.wave || ""}`.trim(),
schema: VERDICT
});
if (r && r.verdict) return r;
log(`${t.id}: attempt ${attempt} produced no usable verdict`);
} catch (error) {
const message = String(error && error.message ? error.message : error);
if (/(limit|spawn|could not start|active child|capacity|start a child)/i.test(message)) {
log(`${t.id}: scheduling error: ${message}`);
return failed(t, `scheduling error: ${message}`);
}
throw error;
}
}
return failed(t, "no usable structured verdict; see review file");
}
phase(`verify${args.wave ? ` ${args.wave}` : ""}`);
log(`Dispatching ${args.tasks.length} verifier(s) in batches of ${CONCURRENCY}`);
const results = [];
for (let start = 0; start < args.tasks.length; start += CONCURRENCY) {
const batch = args.tasks.slice(start, start + CONCURRENCY);
const batchResults = await parallel(batch.map((t) => () => runOne(t)));
results.push(...batchResults);
}
return {
wave: args.wave || null,
concurrency: CONCURRENCY,
total: results.length,
pass: results.filter((r) => r && r.verdict === "pass").length,
pass_with_risks: results.filter((r) => r && r.verdict === "pass_with_risks").length,
fail: results.filter((r) => !r || r.verdict === "fail").length,
results
};
-100
View File
@@ -1,100 +0,0 @@
// agent-swarm batched worker runner — copy into the `script` field of the workflow tool.
// args: {
// wave: number,
// tasks: [{ id: string, write: string[] }],
// schema: object, // paste assets/report.schema.json
// concurrency?: number // <= free active-child slots; default 6
// }
//
// The runner starts tasks in chunks instead of one giant fan-out. This matters
// because `parallel` is not a queue and the runtime active-child cap is
// host-specific; a single spawn-limit throw inside an unbounded fan-out can
// abort the whole wave. Each `agent()` call is guarded so a scheduling failure
// becomes a structured result for that task, and completed chunks are kept.
const REPORT = args.schema;
if (!REPORT) throw new Error("args.schema is required (paste assets/report.schema.json)");
const CONCURRENCY = Math.max(
1,
Math.min(Number(args.concurrency) || 6, 8)
);
const promptFor = (t, attempt) => [
`You are agent ${t.id} in a coordinated swarm.`,
`Read .swarm/brief.md, .swarm/tasks/${t.id}.md, and .swarm/contracts.md first.`,
`Write only within: ${(t.write || []).join(", ") || "(read-only task)"}, plus your own report, review, and scratch under .swarm/reports/, .swarm/reviews/, and .swarm/tmp/${t.id}/.`,
`Do not edit other tasks' files or reports; do not run installs, repo-wide format/lint/codegen, migrations, dev servers, or git writes.`,
`Run the acceptance checks and record exact commands and results.`,
`Write .swarm/reports/${t.id}.json and return the same object.`,
`If a load-bearing unknown or a needed file outside scope blocks you, return status "blocked" with blocked_question; do not guess.`,
`If you hit a compile/test failure caused by a sibling task's in-flight file, wait briefly and retry; report status "partial" with the exact external error rather than editing outside your scope.`,
attempt > 1
? `A previous attempt produced no usable report. Re-read the task and fix the cause or report the exact blocker.`
: ""
].filter(Boolean).join("\n");
const failed = (t, why, scheduling = false) => ({
task_id: t.id,
status: "failed",
summary: why,
files_changed: [],
evidence: scheduling ? [`scheduling failure: ${why}`] : [],
acceptance: [],
issues: [why],
assumptions: [],
spawn_error: scheduling
});
async function runOne(t) {
for (let attempt = 1; attempt <= 2; attempt++) {
try {
const r = await agent(promptFor(t, attempt), {
label: t.id,
phase: `wave ${args.wave}`,
schema: REPORT
});
if (r && r.status !== "failed") return r;
log(`${t.id}: attempt ${attempt} produced no usable report`);
} catch (error) {
const message = String(error && error.message ? error.message : error);
// A spawn/limit error is a scheduling problem: keep the batch, report it.
// Any other throw (bad hook option, unsupported schema) should still fail
// loudly so the script is fixed instead of silently swallowing a mistake.
if (/(limit|spawn|could not start|active child|capacity|start a child)/i.test(message)) {
log(`${t.id}: scheduling error: ${message}`);
return failed(t, `scheduling error: ${message}`, true);
}
throw error;
}
}
return failed(t, "no usable report after 2 attempts");
}
phase(`wave ${args.wave}`);
log(`Dispatching ${args.tasks.length} task(s) in batches of ${CONCURRENCY}`);
const results = [];
for (let start = 0; start < args.tasks.length; start += CONCURRENCY) {
const batch = args.tasks.slice(start, start + CONCURRENCY);
log(`Batch ${Math.floor(start / CONCURRENCY) + 1}: ${batch.map((t) => t.id).join(", ")}`);
const batchResults = await parallel(batch.map((t) => () => runOne(t)));
results.push(...batchResults);
}
const spawnErrors = results.filter((r) => r && r.spawn_error).length;
if (spawnErrors > 0) {
log(`${spawnErrors} task(s) hit a spawn/scheduling error. Dispatch only the unstarted tasks with a smaller concurrency.`);
}
return {
wave: args.wave,
concurrency: CONCURRENCY,
total: results.length,
done: results.filter((r) => r && r.status === "done").length,
partial: results.filter((r) => r && r.status === "partial").length,
blocked: results.filter((r) => r && r.status === "blocked").length,
failed: results.filter((r) => !r || r.status === "failed").length,
spawn_errors: spawnErrors,
results
};
-211
View File
@@ -1,211 +0,0 @@
# Workflow orchestration
The `workflow` tool runs one JavaScript body with top-level `await` and returns a JSON value. It is the only way to fan out dozens of agents without flooding the lead's context.
## Call shape
```json
{
"meta": {"name": "swarm-wave-1", "description": "Build wave", "phases": [{"title": "wave 1"}]},
"script": "<script body>",
"args": {
"wave": 1,
"tasks": [{"id": "T01", "write": ["src/a.ts"]}],
"schema": "<paste the contents of assets/report.schema.json>",
"concurrency": 6
},
"run_in_background": false
}
```
- `meta.phases` is optional; use one phase per wave and `phase()` inside the script.
- `args` is data, never evaluated. The script cannot read files; pass paths and small structured facts.
- Pass `args.schema` as the parsed schema object, not a path or a string.
- Pass `args.concurrency` explicitly. It must be ≤ the free active-child slots; do not rely on the engine to queue.
- The tool blocks until every child settles. Use `run_in_background` for long waves; poll with `job_output`, cancel with `job_kill`.
## agent()
`agent(prompt, opts)` starts one child and resolves with:
- its final text when no schema is passed;
- a validated object when `schema` is passed;
- `null` when the child fails, returns a non-completed stop reason, or produces no structured value.
Options: `label`, `phase`, `schema`, `provider`, `model`. Unknown or deferred options kill the script.
`agent()` can also **throw** when the runtime cannot start a child (for example `active child limit reached`). That throw is not a `null`; if it happens inside `parallel`, it can abort the whole run. Wrap each `agent()` call in `try/catch` inside the batched runner and record a scheduling failure for that task instead of losing the batch.
The child is disposed after the call; there is no follow-up message inside a workflow. Design tasks as one-shot packets.
## parallel vs pipeline
- `parallel([thunks])` — start every thunk together; await all. It is **not a queue**: it does not limit concurrency. Use it only for a chunk whose size fits the free slots.
- `pipeline(items, ...stages)` — per-item chain with no barrier. Use only when each item must pass through stages without waiting for the wave (for example, extract → summarize per source). It multiplies agent count by the number of stages.
- For more items than slots, run batches sequentially and use `parallel` inside each batch (`assets/wave.workflow.js`).
Do not use `parallel` for dependent tasks; use separate waves and let the lead inspect results.
## Schema subset
The engine validates a strict subset. Keep schemas boring:
- Object root (`"type": "object"`).
- `properties`, `required` (names must exist in `properties`), `additionalProperties` boolean.
- Arrays with `items`.
- Strings/numbers/integers/booleans/null, `enum` of scalars, `const`.
- `oneOf` only with exactly-one semantics and no sibling keywords.
- No `minItems`, `maxLength`, `pattern`, `format`, `$ref`, `anyOf`, `allOf`.
A schema miss returns `null`. Verifiers should use the **minimal** schema in `assets/verdict.schema.json`:
`{task_id, verdict, summary, review_file}`. Put the detailed findings in `.swarm/reviews/Vxx.md`; do not make a long findings array required in the workflow schema. If a schema miss happens, read the review file on disk before deciding that the verification failed, then retry with the smaller schema.
## Concurrency and caps
- **Do not hardcode a concurrency default.** The active-child cap is host/policy-specific. Some runtimes allow 14; this environment rejected 8 workers when other children were active. Treat the cap as runtime data.
- **Preflight:** read the runtime diagnostics or `list_agents`; record `slot_cap` and `active_at_dispatch` in `.swarm/state.json`. Recon, verifiers, integrators and any other active children all count.
- **Batch size:** `min(8, slot_cap - active_at_dispatch - 1)`, at least 2. If you do not know the cap, use 6. Leave at least one free slot for retries.
- Each child holds a slot for its whole life. A `parallel` call starts every thunk immediately; if the batch exceeds free slots, the spawns throw.
- Slots are FIFO; a slow task delays later ones. Keep tasks in a batch similar in size.
- `maxTotalAgents`: 1000 per run. `maxItemsPerCall`: 4096 per `parallel`/`pipeline`.
### Batched worker runner
Use `assets/wave.workflow.js`. It splits `args.tasks` into chunks of `args.concurrency`, runs one `parallel` chunk at a time, catches `agent()` throws per task, and returns a structured failure for scheduling errors instead of killing the run. If a chunk reports a limit error, rerun only the unstarted tasks with a smaller concurrency.
## Retry pattern
Full template: `assets/wave.workflow.js`. Retry only when the result is `null` or `status === "failed"`. Do not retry `blocked` — that needs a lead decision. Do not retry a spawn/limit error immediately; shrink the batch or let the lead dispatch the remainder.
```js
async function runOne(t) {
for (let attempt = 1; attempt <= 2; attempt++) {
try {
const r = await agent(promptFor(t, attempt), {
label: t.id,
phase: "wave 1",
schema: REPORT
});
if (r && r.status !== "failed") return r;
log(`${t.id}: attempt ${attempt} produced no usable report`);
} catch (error) {
const message = String(error && error.message ? error.message : error);
if (!/(limit|spawn|could not start|active child|capacity|start a child)/i.test(message)) {
throw error; // invalid options/schema must fail loudly
}
return failed(t, `scheduling error: ${message}`);
}
}
return failed(t);
}
```
On the second attempt, add one line: what failed and what to check. Do not repeat the whole brief. Catch **only** spawn/scheduling failures around `agent()`; invalid hook options or an unsupported schema should still fail loudly so you fix the script.
## Prompt assembly
Build the prompt from `args`, not from prose in the script:
```js
const promptFor = (t, attempt) => [
`You are agent ${t.id} in a coordinated swarm.`,
`Read .swarm/brief.md, .swarm/tasks/${t.id}.md, and .swarm/contracts.md first.`,
`Write only within: ${(t.write || []).join(", ") || "(read-only task)"}, plus your own report, review, and scratch under .swarm/reports/, .swarm/reviews/, and .swarm/tmp/${t.id}/.`,
`Do not edit other tasks' files or reports; do not run installs, repo-wide format/lint/codegen, migrations, dev servers, or git writes.`,
`Run the acceptance checks and record exact commands and results.`,
`Write .swarm/reports/${t.id}.json and return the same object.`,
`If a load-bearing unknown or a needed file outside scope blocks you, return status "blocked" with blocked_question; do not guess.`,
attempt > 1
? `A previous attempt produced no usable report. Re-read the task and fix the cause or report the exact blocker.`
: ""
].filter(Boolean).join("\n");
```
The task card carries the details; the prompt carries the role, scope, and protocol. Do not duplicate the card in the prompt.
## Verification runner
Use `assets/verify.workflow.js` for the verify wave (after freezing the tree). It embeds the minimal verdict schema and fetches reviews in batches:
```json
{
"script": "<contents of assets/verify.workflow.js>",
"args": {
"wave": 3,
"tasks": [{"id": "V01", "review": ".swarm/reviews/V01.md"}],
"concurrency": 4
},
"run_in_background": true
}
```
The verifier writes the review file first and returns only `{task_id, verdict, summary, review_file}`. If the workflow reports `null`/`no usable verdict`, check the review file; then re-run with the minimal schema. Code is frozen during this wave.
## Background runs
Use `run_in_background: true` when a wave may exceed ~10 minutes or you want live progress in the job list. The call returns a job id; `job_output` with `wait: true` blocks until settlement. If a wave hangs, `job_kill` cancels the run and disposes children. A background run's result arrives once, at settlement.
## Tool availability
The protocol does not require the `workflow` tool. At preflight check what exists:
- `workflow` + sufficient slots → batched runner (`wave.workflow.js`).
- `subagent` only → lead dispatches 2–5 long-lived packets directly, or runs sequentially with
structured reports.
- Neither → the lead executes the packets itself and still uses independent review/evidence; the
skill becomes a planning/verification checklist, not a parallel runtime.
The same brief, task cards, ownership map and report schema apply in all three modes. Do not
fabricate a workflow if the tool is unavailable, and do not force a full swarm for a task that a
single agent can finish.
## Archetypes
### Code
- Units: module/feature/file cluster, each with its own tests.
- Ownership: source + test files per unit; shared types and barrels are integrator-only.
- Acceptance: targeted test command, typecheck, lint on changed files.
- Verify: a fresh agent runs the tests and reads the diff; no self-review.
### Data / analysis
- Units: dataset, metric, query, notebook or chart per agent.
- Ownership: inputs read-only; one output table/report per unit.
- Acceptance: reproducible script, input hash, row counts, metric definitions.
- Verify: rerun on a sample or full data; recompute key numbers.
### Design / UX
- Units: screen/component/flow/token set per agent.
- Ownership: source design files; shared tokens are integrator-only.
- Acceptance: rendered artifact at required sizes/states, accessibility checks.
- Verify: isolated display, screenshot path, keyboard/focus/contrast notes.
### Research
- Units: one question or one source cluster per agent; output files under `research/`.
- Ownership: one file per agent; no shared notes file.
- Acceptance: source URLs resolve, claims are dated, every criterion covered.
- Verify: citation check and a consistency pass; a second agent samples claims.
### Content / documents
- Units: one section per agent, plus one editor-integrator.
- Ownership: sections are separate files; the editor owns the assembled document.
- Acceptance: section brief, word budget, terminology list, citations.
- Verify: one editor pass for voice and transitions; a fact-checker for claims.
## Verification runs
Use `assets/verify.workflow.js` with `assets/verdict.schema.json` after freezing the tree. Each verifier:
1. writes its full review to `.swarm/reviews/Vxx.md` first;
2. returns only `{task_id, verdict, summary, review_file}`;
3. reports `pass`, `pass_with_risks`, or `fail` plus evidence in the file.
If the workflow returns `null`/`no usable verdict`, check the review file before treating it as a product failure; then retry with the minimal schema or message the verifier for a concise verdict. After any fix, re-run the affected verifier and mark the old review stale.
## Failure handling
- `null` per item: ordinary child failure; retry or mark failed in the result. Do not fail the whole wave.
- Spawn/limit error inside `agent()`: catch per task, keep completed results, and rerun only unstarted tasks with a smaller batch. This is a scheduling failure, not a worker failure.
- A thrown hook error (bad option, unsupported schema, unknown hook) kills the run: fix the script. Do not hide it in a broad try/catch.
- Cancellation: stop the run, inspect partial reports on disk; do not trust the tool result.
## Cost
Each child carries the system prompt, tool schemas, packet, code reads, and its output: typically 10–25k tokens of fixed overhead before any real work. A 12-agent wave can exceed 300k tokens, and a host capped at 8 cannot run 12 at once; batching reduces peak concurrency, not total cost. Budget before dispatch and count retries, delta re-checks and reviews; stop at the token cap. Eight substantial workers are often cheaper and better than twenty tiny ones. See `references/token-economy.md`.
-150
View File
@@ -1,150 +0,0 @@
# Work packets
A packet is everything one agent needs and nothing else. The lead writes packets; workers read them. Packets live on disk so the workflow prompt stays short and every worker sees the same facts.
## The context ladder
1. `.swarm/brief.md` — shared by all tasks: goal, success criteria, domain/evidence, commands or sources, conventions, hazards, forbidden actions.
2. `.swarm/tasks/Txx.md` — one task: objective, inputs, deliverables, write scope, contract, acceptance, stop conditions.
3. `.swarm/contracts.md` — frozen interfaces; read the relevant section only.
4. Pointers — `path:line` ranges, not pasted code.
5. Examples — one short example only where the format is ambiguous.
If a worker needs the lead's conversation, the packet is incomplete. If a packet exceeds one page, split the task.
## Brief
Copy `assets/brief.md.tmpl`. Rules:
- Goal is one paragraph; success criteria are checkable.
- List the exact commands or evidence sources for the domain. Workers should not guess.
- Map only the paths a worker may need; link the rest.
- Hazards: generated files, migrations, flaky tests, shared ports, secrets. Name what not to touch.
- Global forbidden actions are identical in every packet; keep them in the brief to save prompt space.
- No solution design, no task list, no worker-specific details.
## Task card
Copy `assets/task.md.tmpl`. Rules:
- Objective: what must exist when done, in 1–3 sentences.
- Inputs: brief, contract section, and exact file/source ranges.
- Deliverables: paths, including tests.
- Write scope: globs. Everything else is read-only.
- Contract: exact signature or output shape. If it is not written, it is not frozen.
- Acceptance: 1–3 checks a verifier can re-run independently: commands, artifacts, citations, metrics or renders. "Works well" is not a check.
- GUI: acceptance includes a deterministic screenshot command, fixed window sizes and an isolated display; see `references/visual-testing.md`.
- Stop conditions: time/attempt limit (25 min for S/M, 45–60 for L) plus "ask, do not guess" for load-bearing unknowns.
- Never include another task's internal details; workers do not need the whole plan.
## Verifier card
Copy `assets/verifier.md.tmpl`. Rules:
- State plainly: you did not write this; do not fix it.
- State that the tree is frozen: no source/test/docs/manifest edits during verification.
- Give criteria, changed paths/artifacts, and evidence checks; withhold the worker's rationale.
- Require a table: criterion, evidence, observed, pass/fail.
- Ask for scope, contract, and test-quality checks.
- Require the full review file **first**, then a minimal `{task_id, verdict, summary, review_file}` return (`assets/verdict.schema.json`). The review file is the source of truth; a schema miss must not erase the verification work.
- GUI: require an isolated Xvfb/display, screenshots at default and minimum sizes, and the exact commands used; shared-desktop screenshots are not evidence.
- Product profile: require release-build performance numbers (p95 frame time, input latency, startup), the real UX scenario and a baseline comparison. A technical pass is not product acceptance; the user still gives the final verdict.
## Report
Copy `assets/report.schema.json` to `.swarm/report.schema.json` and `assets/verdict.schema.json` to `.swarm/verdict.schema.json` during bootstrap; workers/verifiers read those copies. Field discipline:
- `status`: `done` (acceptance met), `partial` (some criteria met, listed), `blocked` (needs a lead decision), `failed` (attempted, cannot proceed).
- `verdict` (verifiers only): `pass`, `pass_with_risks`, or `fail`; the detailed findings belong in the review file, not a required workflow array.
- `files_changed`: exact deliverable paths/artifacts, no globs. Coordination artifacts under `.swarm/` are implicit and may be omitted.
- `evidence`: commands, artifact paths, citations, metrics or renders with observed results, one line each.
- `acceptance`: per check, `pass|fail|not_run` plus evidence.
- `assumptions`: load-bearing assumptions the lead must confirm.
- `blocked_question`: one precise question, only when `status=blocked`.
Keep `summary` under ~300 characters. The lead reads summaries first and opens a report only for `blocked`/`failed`.
## Common mistakes
| Mistake | Fix |
|---|---|
| Pasting the whole conversation into every prompt | Write a brief; point to files |
| Vague acceptance ("works well") | A re-runnable check and an expected result |
| No non-goals | List what not to touch |
| Two tasks own one file | Serialize or merge |
| Task needs 2+ hours | Split by deliverable, not by file count |
| Worker invents an interface | Freeze it in `contracts.md` |
| Report is an essay | Schema + one-line evidence |
| No stop condition | S/M 25 min, L 45–60 min / 3 attempts, then `blocked` |
| Verifier reads the worker's summary | Give the artifact and the criteria only |
| Verifier returns prose and loses its verdict | Write review file first; minimal verdict schema |
| Source edited during verification | Freeze, then re-run the affected verifier |
| Lead re-reads every report | Read summary + evidence; open only exceptions |
## Example: code task
```markdown
# T04 — Add retry to the HTTP client
Role: worker | Wave: 1 | Depends on: T02 | Effort: M
## Objective
`fetchJson` retries idempotent GET requests up to 2 times on 5xx and network errors, with a 100 ms base delay and no retry on 4xx.
## Inputs
- `.swarm/brief.md`
- `.swarm/contracts.md` §HTTP client
- `src/http/client.ts:40-120`
- `src/http/client.test.ts:1-60`
## Deliverables
- `src/http/client.ts` — retry loop
- `src/http/client.test.ts` — 3 cases: 5xx retry, 4xx no retry, network retry
## Write scope
- `src/http/client.ts`
- `src/http/client.test.ts`
## Read-only
- `src/http/types.ts`, `package.json`
## Contract
`fetchJson(url: string, init?: RequestInit): Promise<Json>` — unchanged signature; retries only when `init.method` is absent or `GET`.
## Constraints
- No new dependencies; use the existing `sleep` helper.
- Do not change error types or messages.
## Acceptance
1. `pnpm vitest run src/http/client.test.ts` → all pass.
2. `pnpm tsc --noEmit` → no new errors.
## Stop conditions
25 minutes for S/M (45–60 for L) or 3 failed attempts at the same step; a needed change outside the write scope → `blocked`.
```
## Example: research task
```markdown
# T07 — Compare three vendors on data residency
Role: worker | Wave: 1 | Depends on: — | Effort: S
## Objective
A 400–600 word comparison of Vendor A/B/C on data residency, with a source URL for every factual claim.
## Inputs
- `.swarm/brief.md`
- `.swarm/contracts.md` §Report format
- `research/questions.md` §2
## Deliverables
- `research/vendors/data-residency.md`
## Write scope
- `research/vendors/data-residency.md`
## Acceptance
1. Every factual claim has a source URL that resolves.
2. All three vendors covered on: storage region, subprocessors, deletion policy.
3. No claims older than 18 months without a date.
## Stop conditions
If a vendor publishes nothing on a criterion, write "not disclosed" with the source checked; do not infer.
```
-264
View File
@@ -1,264 +0,0 @@
# Swarm playbook
Detailed runbook for `agent-swarm`. Read this after the fit check passes. The runbook is domain-neutral; choose an adapter from `domains.md` and put its details in `.swarm/profile.md`. Keep `.swarm/state.json` current; it is the resume point if the session restarts.
## 0. Fit check and budget
Answer these before spawning:
- **Mode.** Is this really a swarm, or does a direct run / paired critic cover the risk with less overhead?
- **Units.** Can you list 8+ deliverables that different agents can finish without waiting for each other?
- **Writes.** Can every unit get a disjoint write scope? Name the shared files now.
- **Checks.** Does every unit have a command or criterion a verifier can re-run?
- **Interfaces.** Can you freeze signatures, data shapes, and file names before dispatch?
- **Breadth.** Is the time dominated by many independent pieces, not one deep chain?
First decide the **quality profile** with the user: `prototype` (runnable spike, no performance promise) or `product` (performance, UX, baseline and human acceptance are mandatory). See `references/product-quality.md`. For UI/product work, prefer one implementer + one critic over parallel panel owners.
Budget:
- `agents ≈ units + ceil(units / 5) verifiers + 1–2 integrators + 2–4 recon`; add retries and re-verifications explicitly. Set `max_agents` only after checking available tools and slot cap.
- Tokens ≈ `agents × fixed overhead (10–25k) + context reads + output + reviews`. Treat this as an estimate, then calibrate from measured usage. A 3k-line file read by several agents can cost more than the code they write.
- Reserve **20–30%** for verification, integration and one fix round. Set a soft cap at ~70% and a hard cap; stop at the hard cap with a partial report.
- Waves ≈ `ceil(units / batch_size)` + verify + integrate, where `batch_size` comes from the **real** active-child cap, not from a documented default.
- Stop at `max_agents`, `max_waves` or the token cap, whichever comes first. Record all caps, `slot_cap`, `active_at_dispatch`, `batch_size`, measured/estimated usage per phase, retries and re-verifications in `state.json`.
- See `references/token-economy.md`; do not invent precise token numbers without measurement.
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. 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.
- Conventions: naming, error handling, test style, formatting.
- Hazards: generated files, migrations, flaky tests, shared caches, secrets.
- Prior work: existing branches, TODOs, partial implementations.
Require findings as `path:line — fact`, no proposals. Merge into `.swarm/brief.md` and `.swarm/map.md`. Cap recon at ~10% of the budget and **10–15 minutes per recon agent**; on a small repo, do it yourself.
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.
## 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
```
Write the plan before any worker starts. Keep the plan proportionate: a small domain task may need only a brief and a verifier, not a full `.swarm` tree.
**Decomposition.** One task = one deliverable, one writer, one acceptance check, at most one page. The deliverable may be a module, a research question, a document section, a dataset, a design artifact, or a runbook. Budget **5–25 minutes for S/M** and **40–60 minutes for L**; if a task is expected to produce a single source file over ~800 lines (or a very large document/dataset), split it or accept an integration-heavy task. If it needs two writers, split it; if it needs the whole repo, it is not a task.
**Vertical slices.** Prefer one end-to-end capability at a time (selection → transform → undo → save) over a big-bang layer-by-layer build. A slice has its own checkpoint, tests and independent review; it limits late integration and repeated full reviews.
**Token shape.** Estimate the fixed cost per child, the context each task must read, and the review cost. Merge tiny tasks that pay fixed overhead for little work; split giant files that force repeated large reads. The goal is quality per token, not the smallest number of agents.
**Ownership.** Every artifact/path in exactly one `write` list: files, sections, datasets, source notes, design files. Add an explicit `LEAD` task whose list contains lead/integrator-owned shared artifacts, screenshots, licenses and the final report; without it, audit-scope reports the lead's own integration edits as unowned. Shared files are integrator-only: manifests, lockfiles, indexes/barrels, schemas, shared style/token files, migrations, i18n catalogs, snapshots, generated code. If two tasks must touch one artifact, serialize them with `depends_on` or merge them.
**Contracts.** Freeze what crosses a boundary within the chosen domain: function signatures/types/file names/CLI behavior for software; source/date/citation format for research; section structure/terminology/render target for content; schema/units/definitions for data; breakpoints/states/tokens for design; approval/rollback boundaries for operations. The invariant is the same: a verifier can check the contract independently. Put it in `.swarm/contracts.md`; workers may not change it without returning `blocked`.
**Coverage matrix.** Each success criterion → task(s) → check. A criterion with no task is a hole; a task with no criterion is scope creep.
**Visual acceptance.** For a GUI or visual product, define a deterministic screenshot/artifact command before dispatch (fixed window sizes, output path, clean pointer state) and put it in the acceptance matrix. Do not rely on desktop portal capture; it is unreliable on shared sessions and under Wayland. Visual agents must use isolated displays/configs — see `references/visual-testing.md`; never let two agents share one desktop.
**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.
- [ ] The plan uses vertical slices/checkpoints for a multi-milestone product.
- [ ] Quality profile (`prototype`/`product`), performance budget, baseline scenarios and user-acceptance owner are recorded.
- [ ] For product-profile GUI work, the plan names release-build measurements and the exact user scenario.
- [ ] No path in two write scopes.
- [ ] Contracts frozen for every cross-task interface.
- [ ] Coverage matrix complete.
- [ ] `slot_cap`, `active_at_dispatch`, and `batch_size` are recorded and `batch_size` fits the available slots.
- [ ] Recon agents have stopped (or have been interrupted); no extra children hold slots.
- [ ] A `LEAD`/`INTEGRATOR` task owns shared files, screenshots, licenses and the final report.
- [ ] For a visual/GUI product, a deterministic screenshot command and sizes are in the acceptance matrix.
- [ ] `.swarm/brief.md`, `plan.json`, `plan.md`, `ownership.md`, `contracts.md`, `tasks/*.md` exist.
- [ ] `audit-scope.mjs --init` recorded the baseline.
If any box is empty, fix the plan; do not dispatch.
Minimal `plan.json` shape:
```json
{
"goal": "one line",
"budget": { "tokens": 600000, "soft_cap": 0.7, "reserved_for_verify": 0.25 },
"tasks": [
{
"id": "LEAD",
"title": "lead-owned shared files, screenshots, licenses, final report",
"wave": 0,
"status": "in_progress",
"depends_on": [],
"write": ["package.json", "docs/**", "LICENSE*"],
"read": []
},
{
"id": "T01",
"title": "short title",
"wave": 1,
"status": "pending",
"depends_on": [],
"write": ["src/feature/**"],
"read": ["src/types.ts"],
"acceptance": ["pnpm vitest run src/feature"]
}
]
}
```
`audit-scope.mjs` reads only `id` and `write`. Keep those accurate. Use `path/**` for directories, including directories the task will create.
## 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`.
Before the call:
- [ ] Task cards are on disk and reference real paths/ranges, not pasted context.
- [ ] `args.tasks` carries `{id, write}` for each task.
- [ ] The report schema is passed as `args.schema`, and `args.concurrency` is at most the free slot count.
- [ ] Every task has a stop condition and a size/effort budget.
- [ ] Workers run targeted checks, not the full suite; the lead owns the full gate.
- [ ] Baseline exists and `state.json` records the cap and token budget.
After the call:
- [ ] Record measured/estimated token usage per phase if available.
- [ ] Triage structured reports: done / partial / blocked / failed.
- [ ] Treat `spawn/runtime error` and `active child limit` results as scheduling failures, not worker failures: keep completed results and dispatch only the unstarted remainder in a smaller batch.
- [ ] Run `node <skill>/scripts/audit-scope.mjs` (the lead runs it; workers do not); revert or reassign out-of-scope changes.
- [ ] Run the build/test gate yourself; do not ask workers to fix shared breakage.
- [ ] Update `plan.json` and `state.json`.
- [ ] Decide: continue, answer blocked, re-scope, or stop.
Do not paste reports into the next prompt. Summarize decisions into the brief or contracts. Open a full report only for `blocked` and `failed`.
### Answering a blocked task
A `blocked` report is a request for a lead decision, not a failure. Fast path:
1. Read the exact `blocked_question` and the relevant contract section.
2. Make the smallest possible shared/contract change yourself (or via the integrator), and update `.swarm/contracts.md` and `state.json`.
3. `send_message` to the **same** worker with the decision and any exact signatures; ask it to continue under the same write scope.
4. Do not spawn a replacement until the original worker cannot continue, and do not retry a blocked task with the same unanswered prompt.
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.
## 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.
**Cheap gates first.** Run compile/typecheck/targeted tests/artifact checks before spending verifier tokens. A verifier does not review a red build; it reviews a green diff and evidence. Keep reviews to findings + commands + evidence (target 5–8k tokens); raw logs stay in artifacts.
For a GUI product, give each visual verifier its own Xvfb/display and project copy (see `references/visual-testing.md`). Capture at least the default size, the minimum supported size, empty/error states and every modal; a shared-desktop screenshot is not evidence. Computer-use is a final, single-agent exploratory tier on a disposable desktop/VM — never a parallel test mechanism and never the only evidence.
**Freeze before verify.** Once you start this wave, do not edit source, tests or docs. If you already started and then fixed something, mark the in-flight review stale and re-run that verifier on the new build. A verifier's verdict is only valid for the exact tree it saw.
**Technical verification is not product acceptance.** Verifiers check evidence; for product-profile work they must also measure release-build frame time/input latency, run the real UX scenario and compare with the baseline. If performance/UX was not measured, the product gate is `not_run`, not `pass`.
Use `assets/verify.workflow.js` and `assets/verdict.schema.json`, not the full worker report schema. The verifier's detailed review **must be written to `.swarm/reviews/Vxx.md` before it returns**; the workflow return is only `{task_id, verdict, summary, review_file}`. Do not treat a workflow `null`/`no usable verdict` as a product failure if the review file exists — read the file, then re-run with the minimal schema if needed.
Evidence standard: for every criterion, a command/artifact/citation/metric and its observed result. `pass` without evidence is `not_run`. Accept `pass_with_risks` only with named risks and a follow-up task. Verifiers should copy or hash-check generated files rather than rewriting the tree; if a required gate script rewrites generated artifacts, report the hash delta.
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.
## 6. Product gate
For `product`-profile work, run this before integration:
1. Build the release/optimized artifact. Debug numbers are provisional only.
2. Measure p50/p95 frame time at the target size, input-to-visible latency, startup and idle CPU/memory on a realistic scene.
3. Run the 3–5 step real user scenario, not just a screenshot.
4. Compare with the baseline version on the same scenario; a regression is a failure.
5. Give the user the artifact and ask for an explicit verdict: usable / usable with issues / not usable.
6. Record measurements and the user verdict. Do not start the next milestone until accepted or explicitly waived.
If the result is functional but laggy or visually worse than the baseline, stop and fix the slice. Do not add features to compensate. See `references/product-quality.md`.
## 7. Integrate
One integrator (two only for disjoint areas) owns:
- shared files and cross-cutting edits;
- merge conflicts and import/barrel fixes;
- one formatting/lint pass over changed files;
- the full acceptance suite.
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.
## 8. 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:
- Shipped — what exists now, with paths.
- Not shipped / deferred — and why.
- Evidence — commands and observed results.
- Risks and open questions.
- Cost — agents, waves, wall-clock.
- Artifacts — `.swarm/...` paths.
## Failure recovery
| Signal | Likely cause | Action |
|---|---|---|
| Workers edit the same file | ownership map missed a shared file | stop, reassign, serialize, re-audit |
| Many `blocked` on the same interface | contract underspecified | answer once in `contracts.md`, retry those tasks only |
| Many schema `null`s | schema too strict or prompt unclear | loosen schema, add one example to the task card |
| Wave slower than serial | units too small or too coupled | merge units, reduce batch size |
| Workflow dies with `active child limit reached` | batch sized from wrong cap; recon still active | shrink batch, interrupt finished recon, dispatch only unstarted tasks |
| `no usable verdict` but review files exist | verifier schema miss / prose return | read review files; switch to `verdict.schema.json`; re-run if stale |
| Verifier reviewed an older build | source edited during verify | freeze, re-run affected verifier, mark old review stale |
| `blocked` task with a shared-file need | contract omits an integration point | lead applies the change, messages the same worker, no replacement |
| 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 |
| Visual agents produce wrong/identical screenshots | shared desktop or portal capture | isolate per-agent Xvfb/config/project; use in-app screenshots |
| A visual "pass" has no artifact | verifier skipped the visual tier | treat as `not_run`; require screenshot path + command |
| Everything passes but the app is laggy | no performance budget; debug build used as evidence | measure release p95/input latency; fix or cut scope before features |
| New version works but feels worse than the old one | no baseline comparison | define baseline scenarios; regression = failure |
| Verifier passes, user says "not usable" | technical pass treated as product acceptance | product gate + explicit user verdict; fix before next milestone |
| Agents add M1/M2 while M0 is rough | milestone gate skipped | freeze scope; accept M0 or explicitly waive before expanding |
## Time and cost
Parallel speedup is bounded by the sequential share, the real slot cap and token cost, not by the number of tasks. Push sequential work down: recon once, contracts before dispatch, verification in parallel. A 36-unit task with 10-minute units and a 6-slot batch is ~6 batches × 10 min ≈ 60 min of agent work, plus plan, verify and integration; do not promise a 3× speedup when the host caps active children at 8 or fewer.
Token cost is dominated by fixed per-child overhead and repeated context reads. Eight substantial workers are often cheaper and better than twenty tiny ones; one delta re-check is much cheaper than a second full review. Track tokens per accepted task and per confirmed defect; optimize the ratio, not raw spend. See `references/token-economy.md`.
-106
View File
@@ -1,106 +0,0 @@
# Token economy
Quality per token beats raw token spend. The expensive part of a swarm is usually **input context and
repeated reading**, not the code a worker writes. Measure, budget, then cut redundancy — never cut
the independent checks that catch real defects.
## Measure before optimizing
Record usage per phase and per agent in `.swarm/state.json`:
```json
{
"budget": { "tokens": 600000, "soft_cap": 0.7, "reserved_for_verify": 0.2 },
"usage": [
{ "phase": "recon", "agent": "R01", "tokens_in": 18000, "tokens_out": 4000 },
{ "phase": "build", "agent": "T03", "tokens_in": 24000, "tokens_out": 9000 }
]
}
```
If the runtime does not expose usage, estimate from context size and output length and mark the value
as `estimated`. The point is a feedback loop, not accounting precision.
Useful ratios:
- tokens per accepted task;
- verifier tokens per confirmed defect;
- rework tokens caused by a missed contract;
- share of spend on recon / build / verify / integration.
## Budgets and reserves
- Set a **hard budget** for the milestone and a **soft cap** at ~70%. At the soft cap, stop expanding
scope; finish the current slice and verify.
- Reserve **20–30%** for verification, integration and one round of fixes, plus a **polish reserve**
for product-profile GUI/UX work. Do not spend the whole budget on generation.
- A budget is a ceiling, not a target. Do not stop a product task at the soft cap if the quality gate
is unmet; stop at the hard cap or when the product gate passes. Cheapness is not quality.
- Budget per phase, not only per wave: recon, build, verify, product gate, integrate.
- Stop at the cap and report partial results plus unverified areas. Silent overspend is worse than a
partial result.
- Calibrate from the first measured milestone; do not copy invented numbers from a template.
## Context discipline
The biggest savings without quality loss:
1. **Small files.** Split modules above ~800 lines (UI panels, viewport, inspector). A worker should
read 300–800 relevant lines, not 3,000. Smaller modules also compile and verify faster.
2. **Read ranges, not repositories.** Use `path:line`, symbol search and grep first. Do not read a
whole crate to change one function.
3. **Point to artifacts, do not paste them.** Task cards reference `.swarm/brief.md`,
`.swarm/contracts.md` and exact ranges; they do not duplicate them in the prompt.
4. **Cap reports and reviews.** Worker report: summary, files/artifacts, evidence, issues,
assumptions. Review: findings + commands + evidence; target 5–8k tokens, raw logs stay in files.
5. **One page per task.** If a card needs more, the task is too broad.
6. **No full-suite runs per worker.** Workers run targeted checks; the lead runs the full gate once
per wave.
7. **Fresh context only where independence matters.** The final verifier needs a clean read. A fix
re-check can be a **delta review**: diff + findings + acceptance commands, not the whole repo.
## Verification ladders
Do not spend LLM review tokens on a red build:
1. compile / typecheck / lint;
2. targeted tests;
3. artifact/render/source check;
4. independent verifier on the diff and evidence;
5. final full review once, on a frozen integrated build.
Freeze before step 4. If code changes, re-check only the affected delta; mark the old review stale.
This preserves quality while avoiding repeated full reviews.
## Orchestration shape
- **Fixed overhead dominates small tasks.** Each child carries system prompt, tools, brief and task
context. 30 small agents can cost more than 8 substantial ones.
- **Right-size:** 2–4 implementers + 1 verifier for a vertical slice; 6–10 agents for a broad
milestone; 30 only for genuinely independent breadth.
- **Model routing:** strong model for architecture, difficult fixes and final review; cheaper/faster
model for tests, docs, screenshots and mechanical edits.
- **Vertical slices:** ship one end-to-end feature at a time (selection → transform → undo → save),
with a checkpoint and verification after each. Do not generate the whole product and verify at the
end.
- **Reuse:** do not regenerate a working core, format or codegen. Extend it.
## Anti-patterns
| Pattern | Cost | Fix |
|---|---|---|
| 3k-line file edited by several agents | repeated reads, merge conflicts | split before dispatch |
| Full repo read for a one-function change | huge input | path:line + grep |
| Full re-review after every fix | duplicate verifier spend | delta review |
| Verifier runs on a failing build | wasted review | automated gate first |
| 20 tiny tasks | fixed overhead per child | merge into coherent units |
| Reports/reviews as essays | output + lead input | schema + evidence lines |
| Whole product in one wave | late integration, huge rework | vertical slices + checkpoints |
| Cutting polish to stay under budget | functional but unusable product | protect a polish reserve; stop at the hard cap, not the soft cap |
| Vague "max quality" with no budget | unbounded spend | hard/soft caps + reserve |
## Minimal operating rule
> Measure per phase, reserve for verification, keep files and packets small, verify the diff after
> fixes, and spend the saved tokens on one strong independent review rather than many redundant
> agents.