Prune agent-swarm to a genuinely lite core
This commit is contained in:
@@ -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
|
||||
```
|
||||
|
||||
@@ -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`; не считайте, что новая версия лучше старой
|
||||
без сравнения.
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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`.
|
||||
@@ -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}}
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
@@ -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.
|
||||
@@ -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"]
|
||||
}
|
||||
@@ -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.
|
||||
@@ -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
|
||||
};
|
||||
@@ -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
|
||||
};
|
||||
@@ -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`.
|
||||
@@ -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.
|
||||
```
|
||||
@@ -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`.
|
||||
@@ -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.
|
||||
Reference in New Issue
Block a user