updated 1mo ago
A single brainstorm prompt returns the confident middle of the model's output distribution. This skill is a rig for testing a specific, unvalidated bet: that fanning out many cheap, radically-constrained persona agents in parallel populates the tails of that distribution, and that a lexical statistics step can cheaply separate genuine outlier signal from both dense consensus and incoherent noise — without needing embeddings.
Was kannst du mit Swarm Brainstorm machen?
name: swarm-brainstorm description: 'Fan out a swarm of cheap, persona-driven agents to brainstorm a problem, statistically filter the raw output for genuine outliers against the consensus baseline, and synthesize survivors into a baseline-vs-emergent report. Use when the user wants divergent or contrarian ideation that goes beyond a single prompt''s safe middle-of-the-distribution answers, references "swarm brainstorm" or the "Court Jester Protocol", or asks to generate a large batch of wild/adversarial ideas and extract the ones that are actually novel rather than noise.' argument-hint: "[problem statement] [size: s|m|l|xl or a number]"
Swarm Brainstorm (Court Jester Protocol)
Premise and what this skill is
A single brainstorm prompt returns the confident middle of the model's output distribution. This skill is a rig for testing a specific, unvalidated bet: that fanning out many cheap, radically-constrained persona agents in parallel populates the tails of that distribution, and that a lexical statistics step can cheaply separate genuine outlier signal from both dense consensus and incoherent noise — without needing embeddings.
This is an experiment, not a productionized creativity tool. Every run is disposable and inspectable: everything the pipeline produces lands in a run directory (see below) so a human can see exactly what happened at each stage, even when the final verdict is "no outliers found."
Do not over-trust early results. The filter (Stage 4) is validated on synthetic fixtures during its own build; whether it actually separates real swarm output is only established by the end-to-end validation run, and even that is provisional pending replication across multiple problems.
Invocation contract
Input: a problem statement (the thing to brainstorm about) and an optional requested swarm tier. If no tier is given, use the conservative default (see Cost Gate below).
Output: a run directory runs/<run-id>/ (see references/orchestration.md
for the run-id convention) containing the full audit trail, and a final
report.md presenting the conventional-wisdom baseline next to the
synthesized emergent ideas — or, if no outliers survived filtering and
retry, a coarse outcome report explaining why, with calibration and yield
context attached so a human can root-cause it.
Do not fabricate a report when the pipeline produced no synthesizable outliers. A truthful "outliers not found" report is a valid outcome for an experiment testing an unvalidated premise.
Run directory and file schemas (the inter-stage contract)
Each run creates runs/<run-id>/ (gitignored — see .gitignore). The files
below are not just logs: they are the pinned API contract between this
skill, the swarm/council Workflows, and the Python steps under scripts/.
Every stage reads its inputs from disk and writes its outputs to disk, even
though the skill is the one driving each hand-off — this is what makes a
run resumable and inspectable after the fact.
seeds.json— list of{id, persona, constraints, problem_slice, temperature, model}produced by Stage 1 seed assembly, plus a calibration-endpoint block{constraint_level, temperature, best_score, cleared}appended by the calibration loop.id(aliasedpersona_id/constraint_iddownstream) is the join key every later stage dereferences back to full persona/constraint text.modelis copied onto each seed from Stage 0's tier resolution (model_sequence[i]) — never re-derived in prose.ideas.json— the swarm Workflow's collected output, written by the skill immediately after theWorkflow(...)call returns:{ideas: [{text, persona_id, constraint_id, model}], scheduled, returned, by_model: {model: {scheduled, returned}}}.scheduledvsreturnedis yield telemetry;by_modelbreaks that same telemetry down per fleet model so a mixed opus/sonnet/haiku run's per-model yield is visible, not just the aggregate.baseline.json—{status, clusters, cluster_count, ...}:statusis"ok"(at least one consensus cluster) or"no_consensus"(the degenerate baseline marker), andclustersholds Stage 4's consensus clusters with counts. The degenerate case is distinct from the blob case below and must be reported differently.outliers.json—{status, outliers}:statusis"ok"(at least one outlier) or"no_outliers"(the explicit blob sentinel), andoutliersis Stage 4's top-N most-isolated ideas with provenance ids preserved unchanged fromideas.json.filter_detail.json— always written alongsidebaseline.json/outliers.json: one row per raw idea (input order),{index, text, persona_id, constraint_id, model, survivor_index, duplicate_of, cluster_id, disposition, isolation, surprisal, rank_score}, wheredispositionis one ofconsensus/outlier/gated/isolated_below_topn/duplicate. Feedsreport.html's data grid.ledger.json— the single per-run agent-spend counter, owned and written byscripts/estimate.py(see Agent Ledger below). Never re-derive "how many agents has this run spawned" from prose.council.json— written verbatim afterWorkflow({scriptPath: 'workflows/council.workflow.js', ...})returns, then tallied in place byscripts/council.py tally:{candidates, round1, round2, abstentions, tally, top3, method, warnings}. Seereferences/council.mdfor the full schema.report.md— the final artifact: baseline vs. synthesized emergent ideas, or the outcome report when no outliers survived.report.html— the self-contained Stage 6 run report (charts, council decision, sortable data grid), built bypython scripts/report_html.py build --run-dir <dir>from every file above. Every input is optional-tolerant — a legacy run missingmodelprovenance orcouncil.jsonrenders a "not produced this run" note, never a crash.eval.json— written only by the offlineeval/run_eval.py, never in the hot path.
Orchestration flow
The skill (this file, running as the main loop) drives every stage below in
order. It is the caller of the Workflow(...) tool and the thing that shells
out to the Python scripts under scripts/ — neither the workflow nor the
Python steps invoke each other directly.
Stage 0: Cost gate
Before generating anything, resolve the requested tier against
scripts/estimate.py's tier subcommand and get a go/no-go — see Agent
Ledger below for why this is scripted rather than reasoned about in prose.
- Tiers, not raw counts.
size:Nis gone. Request a t-shirt tier —s/small,m/medium,l/large,xl/huge— or a raw number, which resolves to whichever tier's fleet total is nearest (ties break to the smaller tier). Default, when none is given:s. - Fleet per tier (opus / sonnet / haiku / total): s = 1/3/10 (14); m = 2/6/20 (28); l = 4/12/40 (56); xl = 8/24/80 (112).
- Resolve, don't re-derive. Run
python scripts/estimate.py tier <spec>and take its JSON verbatim:{tier, fleet, total, model_sequence, gate, estimate}.model_sequenceis the per-slot model assignment Stage 1 copies onto each seed;gateis the confirm/reject verdict againsttotal;estimatenow carries per-model pricing, not one blended number. - l and xl trip the confirm threshold (their totals, 56 and 112, exceed the ~50-agent threshold) — explicit user confirmation is required before any spawning happens, same existing rule, newly reachable at those tiers. The hard per-run ceiling (~200) is unchanged.
- If the user declines to confirm, offer exactly two paths: proceed at the
default tier (
s), or abort. Never silently downgrade without saying so. - A tier that would push the per-run counter past the hard ceiling is refused outright, before any workflow launches.
- Report the projected fleet and per-model estimate before the run starts, and the actuals (including Stage 3's per-model yield) after it ends.
This gate runs once, before calibration, because calibration batches, the main swarm, and any blob retry all decrement the same per-run counter.
Stage 1: Seed Assembly (U3)
Once the cost gate has passed, assemble seeds.json before anything is
spawned. This is where R1 (distinct radical personas) and R2 (negative and
forced constraints) actually happen. Draw from references/personas.md.
Concretely, for the confirmed tier's fleet total:
- Pick that many distinct personas, inventing fresh variations in the same register when the tier exceeds the library.
- Attach constraints independently of persona — a banned-buzzword rotation, a forced material/budget/format constraint, and the length cap matching R5's one-or-two-sentence floor, rotated per seed.
- Write a fresh
problem_sliceper seed, self-contained in that persona's frame — the only problem context that seed's agent ever sees. - Vary
temperatureper seed, biased higher for further-out personas. - Assign each seed a
modelby copyingmodel_sequence[i]from Stage 0's tier resolution onto seedi, in order — scripted arithmetic, never hand-picked per persona.
Calibration's probe batch (below) stays haiku regardless of any given
seed's assigned model: a probe measures constraint-induced lexical
diversity, not model quality, and haiku is the modal fleet member at every
tier, so a constant probe model keeps escalation scores comparable across
runs. Concretely, the calibration loop slices its batch from seeds.json's
haiku-assigned seeds, not an arbitrary N-slice of the full seed list.
The result is written to seeds.json as {id, persona, constraints, problem_slice, temperature, model} objects — see personas.md's
"Assembling seeds.json" section for the exact shape and a worked example.
Seed assembly itself is pure text generation, not agent spawning, so it does not touch the per-run counter.
Calibration Loop (U6)
Once seeds.json exists, before spending the full swarm's budget, run one
small calibration batch and check whether it is actually diverse. This is
R3: measure output similarity with the same statistical engine as Stage 4
(KTD5) and tighten constraints / raise temperature until it clears a floor,
bounded by a try cap (KTD10).
The loop, each iteration:
- Launch a small calibration batch. Invoke
Workflow({scriptPath: 'workflows/swarm.workflow.js', args: {...}})with a size-N slice ofseeds.json's haiku-assigned seeds (N smaller than the full swarm — just enough ideas to read variance from; see Stage 1 above for why the slice is haiku-only). This spawn decrements the shared per-run counter exactly like any other swarm launch. - Score it. Shell out to
scripts/calibrate.pyagainst the batch's collected idea texts.calibrate.pyreports a scalar diversity score — mean isolation across the batch — composed onstats.py's primitives exactly asfilter.py's own near-duplicate collapse computes similarity. Result carries averdictof"proceed"or"tighten". - Consume a try, unconditionally, before branching on the verdict — including a degenerate batch.
- Branch:
"proceed"— exit the loop."tighten"with tries remaining — escalate constraints/temperature, regenerateseeds.jsonat the new level, go back to step 1."tighten"with no tries remaining — exit without clearing the floor; record it honestly.
On exit, append the calibration endpoint to seeds.json:
{constraint_level, temperature, best_score, cleared}.
Stage 3: Swarm generation
Once seeds have cleared calibration (or its try-cap is spent), run the
swarm via Workflow({scriptPath: 'workflows/swarm.workflow.js', args: {...}}). Every seed fans out on its own assigned model — a mixed fleet, not
one uniform model — via the workflow's resolveModel precedence: a seed's
own model field wins if it names a known fleet model, falling back to
args.model (used only when a seed lacks a valid model of its own), and
finally to haiku. The skill passes seeds.json (each seed carrying its
model), the confirmed tier's total, and the problem statement through
args — it does not regenerate the workflow script per run (see
references/orchestration.md for workflow-authoring conventions).
The swarm's collected ideas come back in-band, as the Workflow(...)
tool result. The skill's job immediately after the call returns is to
persist that result verbatim to ideas.json — this is what turns the run
into a resumable checkpoint.
Each spawned swarm agent counts against the per-run counter from Stage 0.
Stage 4: Filter
With ideas.json written, shell out to scripts/filter.py against that
file. filter.py collapses near-duplicates, extracts consensus clusters as
the baseline, and ranks the remainder by isolation — embedding-free by
default (see references/filtering.md). The skill's role is purely to
invoke the script and read back its outputs:
baseline.json— always written, even when degenerate.outliers.json— always written, even when empty (the blob case).filter_detail.json— always written; carries each idea'smodelforward fromideas.json(see Run directory schemas above).
If outliers.json is empty, do not proceed to synthesis. Hand off to blob
retry instead.
Blob Retry (U7)
On the "no_outliers" sentinel: escalate constraints/temperature,
regenerate seeds.json (re-applying the same tier's model_sequence), and
re-run the swarm + filter directly, skipping calibration. Each iteration
decrements the retry try-counter and spends the shared counter
(estimate.py spend ... --stage retry) before anything else — a spend
denial stops the loop even with tries left; full mechanics in
references/orchestration.md's Blob Retry section.
Exit on a non-empty outliers.json (hand off to Stage 5), or on exhausting
the try cap or counter. On exhaustion, skip synthesis and council, and write
the outcome report into report.md: outliers not found, which limit
stopped it, calibration's cleared flag, and the final attempt's yield
telemetry.
Synthesis Orchestration (U8)
Once Stage 4 (or Blob Retry) has produced a non-empty outliers.json, the
skill runs Stage 5: feasibility-filter the outliers, then synthesize
whatever survives into report.md. Full rubric and pinned artifact format
live in references/synthesis.md; this is the orchestration summary.
The skill reads outliers.json and baseline.json itself, then delegates
judgment to a single heavyweight agent call — coordinator roles (synthesis,
validators, aggregators, judges, council) omit model entirely and inherit
whatever model the surrounding companion/orchestrator session is already
running on, rather than pinning a tier — prompted as the harsh critic
synthesis.md specifies. This is a single delegated call, not a
Workflow(...) fan-out, since Stage 5 evaluates one outlier set as a whole
and needs its result written to disk. That call applies synthesis.md's
feasibility rubric (impossible / hallucinated / word-salad) to every
outlier before any synthesis work (R19), then synthesizes survivors
into named strategies with provenance preserved (R20). The skill then
assembles report.md in synthesis.md's pinned section order — Baseline,
Emergent Ideas, Council Decision, Discarded Outliers, Run Context (R21).
Council Stage
Once report.md's Baseline/Emergent Ideas content is assembled, the skill
runs a three-councilor, two-round deliberation over the fixed candidate set
(baseline clusters, outliers, any synthesized strategies), judged purely on
novelty and feasibility, then tallies it deterministically. Full method,
prompts, schemas, and the Borda tally live in references/council.md.
- Ledger spend-first. Before calling the workflow:
python scripts/estimate.py spend <run_dir> 6 --stage council(three councilors × two rounds). A denial skips council entirely — no workflow call — and the report must say plainly council was skipped and why. - Also skipped on blob-retry exhaustion — no outlier candidates exist to rank; skip and say so, same as Stage 5's degenerate-baseline handling.
- Invoke.
Workflow({scriptPath: 'workflows/council.workflow.js', args: {candidates, problem}}). Every councilor agent in both rounds omitsmodel(coordinator role, see Synthesis above) and inherits the active session model. - Persist, then tally. Persist
{round1, round2, abstentions}verbatim intocouncil.jsonalongside thecandidateslist, then runpython scripts/council.py tally --run-dir <dir>for the deterministic Borda tally — the workflow never scores anything;council.pynever talks to a model.
Report + Artifact
Whichever path Stage 5, Council, or blob-retry-exhaustion took, the skill's last actions:
- Build
report.html: `python scripts/report_html.py build --run-dir - Publish it via the
Artifacttool for a viewable link, best-effort — on failure, fall back to printing the file's absolute path. - Print the chat report, this exact skeleton, every number read from the run's own JSON files (never re-derived):
## Swarm Brainstorm — <problem>
**Run** `<run-id>` | Tier **<s|m|l|xl>** (<o> opus / <s> sonnet / <h> haiku) |
Yield <returned>/<scheduled> | Ledger <count>/<ceiling> agents
### Council decision (top 3)
1. **<title>** (`<id>`, Borda <n>) — <digest of councilor justifications>
…
### 10 most novel ideas
| # | Idea | Novelty | Models | Agents |
|---|------|---------|--------|--------|
| 1 | <short title> | <rank_score 2dp> | haiku×2, sonnet×1 | 3 |
**Artifacts:** [report.html](<artifact link or path>) · `report.md` · `runs/<run-id>/`
Novelty is the filter's rank_score; Models/Agents come from each
outlier's models/agent_count fields. Fewer than 10 outliers: render
what exists and say so. Council skipped: that section reads Council skipped: <reason> instead of a top-3 list.
Offline evaluation hand-off
Separately from the hot path above, a completed run can be scored by
eval/run_eval.py (built in U9) — an explicit, user-initiated follow-up,
never automatically triggered. It reads ideas.json and outliers.json
from an existing run directory and writes eval.json back into it. Mention
this hand-off once a run's report.md is ready; do not run it unprompted.
Agent ledger
The per-run agent-spend counter is arithmetic that an LLM should not be
trusted to track in prose across a multi-stage run. It is scripted in
scripts/estimate.py, exposing deterministic spend()/check() functions.
The skill calls these before every spawn — Stage 0's initial gate, each
calibration batch, the main swarm, any blob retry, the Council stage
(n=6, spent before its Workflow(...) call), and Synthesis (n=1) —
rather than reasoning about remaining budget in prose. Council's and
Synthesis's spends are new as of the tiered-fleet/council revision: a run
predating it has a smaller ledger total for the same stage sequence, and
that is expected, not a discrepancy to chase down. The running count
persists in ledger.json so it can be inspected after the fact.
Separately from the per-run counter: this skill's agent spawns also draw against the Workflow runtime's session-lifetime cap (currently 1000 agents, shared across the session). There is no persisted cross-run counter for this yet. Watch for that cap in practice and stop launching new runs as the session approaches it.
References
references/orchestration.md— workflow-authoring conventions, the run-id convention, budget-partition detail, and loop guidance referenced throughout this file.references/personas.md(U3) — persona and constraint seed library.references/filtering.md(U2) — Stage 4 filter method detail.references/synthesis.md(U8) — Stage 5 synthesis prompt and artifact format.references/council.md— Council stage method, prompts, schemas, and the deterministic Borda tally.
Installation
Swarm Brainstorm zu deinem Client hinzufügen. Wähl den, den du nutzt.
npx skills add Ekko-Coleman/skillsInstalls every skill in the repository, then prompts for which to keep.
/plugin marketplace add Ekko-Coleman/skillsAdds the repository as a plugin marketplace; install individual plugins with `/plugin install`.
git clone https://github.com/Ekko-Coleman/skills
cp -r swarm-brainstorm ~/.claude/skills/A skill is a plain directory. Copy it into `.claude/skills/` in a project or in your home directory.
Score
67 / 100
Gut