Skip to content
4 changes: 2 additions & 2 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
{
"name": "swarm",
"source": "./plugins/swarm",
"description": "Local mixture-of-agents code review for Claude Code. Fans a diff across Claude lenses plus the codex and grok CLIs (grok-4.5), merges by mechanism with cross-family consensus, verifies solo findings, and presents one ranked report. Optional --fix / --loop applies the findings you agreed with; --pr reviews a GitHub PR diff and posts the result. Skills: /swarm:review, /swarm:agents.",
"version": "0.4.3"
"description": "Local mixture-of-agents code review for Claude Code. Fans a diff across Claude lenses plus the codex and grok CLIs (grok-4.5), merges by mechanism with cross-family consensus, verifies solo findings and all design suggestions, and presents one ranked report. Optional --fix / --loop applies the findings you agreed with; --pr reviews a GitHub PR diff and posts the result. Skills: /swarm:review, /swarm:agents.",
"version": "0.5.0"
}
]
}
2 changes: 1 addition & 1 deletion .claude/knowledge/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
- `features/herdr-tab-glyphs.md` — Task-state glyphs (`○ ● ◇ ◆ ✓`) + main-root `◉` on herdr tab labels: `states` mode in the self-contained renderer, sync-vs-`--cached` PR refresh per caller, exact-cwd rename rules, soft pr-flow shim
- `features/task-archiving-on-close.md` — `/close` archives (not deletes) the task file; adaptive commit + ff-push to main
- `features/swarm-backend-adapter.md` — Verified codex/grok CLI facts (schema-enforced JSON, effort mapping, stdin hang, model-aware grok readiness) behind `swarm`'s adapter script
- `features/swarm-review-pipeline.md` — `/swarm:review` P2 pipeline (skill↔Workflow wiring, family-consensus, minimal security) + P5 `--fix`/`--loop` (in-session orchestration between workflow runs; deterministic termination + close-out box in `loop-closeout.py`) + `--pr` (review a PR diff, post via `gh` under the user's identity so pr-flow's `claude`-author poll ignores it; publish path is deterministic `pr-post.py`: per-cell sanitizer + stale-head gate + post)
- `features/swarm-review-pipeline.md` — `/swarm:review` pipeline: skill↔Workflow wiring, family-consensus, 0.5.0 lens clusters + design-kind verify, `--fix`/`--loop` (deterministic close-out via `loop-closeout.py`), `--pr` publish via deterministic `pr-post.py`

## Deployment
- `deployment/ci-structure-checks.md` — `check-structure.py` as the single automated guard for a build-less repo
99 changes: 74 additions & 25 deletions .claude/knowledge/features/swarm-review-pipeline.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: "Swarm Review Pipeline (/swarm:review)"
createdAt: 2026-07-08
updatedAt: 2026-07-17
createdFrom: "PR #24"
updatedFrom: "PR #37"
updatedFrom: "PR #35"
pluginVersion: 1.8.2
prime: false
reindexedAt: 2026-07-12
Expand All @@ -14,10 +14,55 @@ reindexedAt: 2026-07-12
P2 turns the blueprint into a working review: a **Workflow-tool script**
(`plugins/swarm/workflows/swarm-review.js`) launched by the `/swarm:review`
skill. Shape: `scope+gate → fan-out (3 voices) → merge (file,mechanism) →
verify solos → output-gated synthesis`. Three voices: Claude lenses ∥ codex ∥
grok-4.5 (see [swarm-backend-adapter](swarm-backend-adapter.md)). A fourth,
`grok-composer-2.5-fast`, was removed in swarm 0.4.3 — the grok CLI dropped the
model.
verify solos + design clusters → output-gated synthesis`. Three voices: Claude
lenses ∥ codex ∥ grok-4.5 (see [swarm-backend-adapter](swarm-backend-adapter.md)).
A fourth, `grok-composer-2.5-fast`, was removed in swarm 0.4.3 — the grok CLI
dropped the model.

## Lens set: 11 lenses in 4 clusters (swarm 0.5.0)

Grown from 5 topical lenses by importing `/code-review`'s other two
decomposition axes — methodological (HOW to look) and design quality — all
**default-on** (user directive 2026-07-15: maintainability reviewed on every
run, not opt-in). `LENS_CLUSTERS` in the workflow is the **single source of
truth** (the per-cluster externals follow-up consumes it):

| cluster | lenses | guiding question |
|---|---|---|
| `breakage` | correctness, removed-behavior, cross-file-trace | what breaks? |
| `threat` | security, adversarial | what's exploitable / which assumption fails? |
| `design` | reuse, simplification, efficiency, altitude | is this good, maintainable code? |
| `consistency` | style, conventions | does it fit the codebase? |

- **The cluster is the Claude fan-out unit** (≤4 finders); `--max` splits to
one finder per lens (≤11) — the granularity ladder is `--quick` (future) =
one broad pass → default = per-cluster → `--max` = per-lens. The **gate
stays per-lens** (a fully-pruned cluster spawns no agent); design lenses are
first-class in the gate prompt, skipped only when the diff can't pay off.
- **`kind` is derived from the lens name** (`design` vs `defect`) — no
finding-schema change, so the 3-place schema mirror is untouched. A merged
cluster's kind comes from its TAGGED members (design only when every tagged
member is design — a design suggestion merged with a real defect must not
leave the defect ranking); untagged (`unspecified`) members don't vote, and
an **all-untagged cluster is never auto-accepted** — its "consensus" is
backed by no lens, so it is verified like a solo (the `--max` dogfooding
round found exactly this hole).
- **Verify path decision: kind-aware prompt, not bypass.** Design findings are
suggestion-shaped, but each has a falsifiable applicability core (reuse
target exists? simpler form behavior-identical? claimed waste real?) — the
same 3-state verifier runs with an applicability prompt, **even for design
clusters with cross-family consensus** (agreement ≠ applicability: externals
only see the diff, so two of them can agree on a nonexistent reuse target —
the first live swarm run over this very feature caught that gap). Bypassing
into an unverified "maintainability" section would have surfaced unchecked
suggestions from precisely the noisiest lenses. Methodological lenses are
factual → normal defect verify; defect consensus stays auto-accepted.
- **Report keeps kinds apart**: defects table first, then a same-format
`Design` table (shared numbering — the workflow sorts defects first);
`balance.design` counts the subset. Lens prefixes are parsed with `[\w-]`
(hyphenated names like `removed-behavior` — plain `\w` misses them).
- Effort: design lenses run at the **same effort** as defect lenses (`xhigh`
under `--max` — user call: depth applies to design thinking too).

## The skill ↔ workflow wiring (the non-obvious parts)

Expand All @@ -40,16 +85,16 @@ model.

## Design decisions

- **Consensus counts model *families*, not voices.** A cross-family cluster
(≥2 of claude / openai / grok) is CONFIRMED without extra verify; everything
else is solo and goes through the adversarial 3-state verifier. The `FAMILY`
map (`workflows/swarm-review.js`) survives the composer removal deliberately:
with composer gone the backend→family mapping is 1:1, so *for consensus
counting* it is currently a no-op — but the fan-out is many-voices-per-family
(one Claude finder per gated lens), so the rule "same vendor agreeing with
itself is one vote, not a cross-check" is still the load-bearing invariant.
Collapsing consensus onto backends/voices would silently re-introduce
correlated self-agreement the day a second same-vendor voice returns.
- **Consensus counts model *families*, not backends.** A cross-family cluster
(≥2 of claude / openai / grok) of TAGGED defect findings is CONFIRMED without
extra verify; everything else goes through the 3-state verifier — solos
(adversarial), all design clusters (applicability — consensus included, see
the 0.5.0 lens-set section), and all-untagged clusters (no lens backs their
"consensus"). With composer removed (0.4.3) the backend→family map is 1:1, so
for consensus counting it is a no-op today — but the fan-out is
many-voices-per-family (one Claude finder per gated lens), so "same vendor
agreeing with itself is one vote, not a cross-check" stays the load-bearing
invariant the day a second same-vendor voice returns.
- **Security is intentionally minimal** (user directive: no cannons-at-sparrows).
The P1 adapter floor stays (sandbox, tool-less grok, secret scrub, env filter,
caps); P2 adds only three cheap things — **fencing** the diff as data
Expand Down Expand Up @@ -163,16 +208,20 @@ filled* — `gh pr diff <n>` (bare `--pr` resolves the current branch's PR via
Same two-tier exit as `loop-closeout.py` (operational → token + exit 0; misuse,
incl. non-list `rows`, → stderr + exit 2). Pure functions
(`sanitize_prose`/`sanitize_code`/`stale_gate`/`render_body`) keep it unit-tested.

## Future idea (P3+): per-lens external prompts

Today externals run ONE broad multi-lens review each; Claude fans out per lens.
Running externals per-lens too would add depth-per-lens + symmetry + authoritative
lens tags + let the gate prune external calls. **But** it multiplies external CLI
calls ~5× (backends × lenses) — steep cost + CLI overhead, against the efficiency
goal. Verdict: make it an **opt-in `lensMode`**, gate the external lenses when on,
and for routine depth prefer higher external `--effort` / grok `--best-of-n` (one
call, more thinking) over N calls. Not a default.
0.5.0 moved one more rule from prose to code the same way: rows carry optional
`kind`/`lens`, and the script orders defect rows before design rows and
prefixes design finding cells with `[lens]` — the caller passes findings
through verbatim, never hand-orders or hand-prefixes.

## Future idea (P3+): per-cluster external prompts

Today externals run ONE broad multi-lens review each (the prompt names all 11
lenses); Claude fans out per cluster. Running externals **per cluster** too
(re-scoped 2026-07-15 from the original per-lens idea — clusters cap the
multiplier at 4×, not 11×) would add depth + symmetry + authoritative lens tags
+ let the gate prune external calls. That is the `swarm-per-lens-externals`
follow-up task, built on `LENS_CLUSTERS`; for routine depth prefer higher
external `--effort` / grok `--best-of-n` (one call, more thinking) over N calls.

## Verified end-to-end (2026-07-05)

Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,17 @@ entries are grouped per plugin, newest first.

## swarm

### 0.5.0 — 2026-07-17
- Grow the review lens set from 5 to 11 (all default-on): methodological `removed-behavior` + `cross-file-trace` (factual, normal verify) and design-quality `reuse` / `simplification` / `efficiency` / `altitude` (suggestion-shaped, `kind: "design"`).
- Organize the lenses into 4 clusters (`LENS_CLUSTERS` — single source of truth): breakage / threat / design / consistency. Claude fan-out runs one finder per cluster by default (≤4 agents); `--max` splits to one finder per lens (≤11). The gate still prunes per-lens.
- Verify design findings with a kind-aware applicability prompt (reuse target real? simpler form behavior-identical?) through the same 3-state verifier — consensus design clusters included (agreement isn't applicability); report them in their own `Design` table so they never dilute the defect ranking (`balance.design` counts them).
- Extend the external backend prompt with the six new angles so cross-family consensus can form on design findings too.
- Harden the lens plumbing after the first dogfooding run (swarm reviewed its own diff): keep validly tagged off-cluster lens prefixes (validate against the global set, not the finder's subset), derive `CANDIDATE_LENSES` from `LENS_CLUSTERS` (one list), untagged external findings no longer re-kind a merged cluster, and `pr-post.py` owns design-row ordering + `[lens]` prefixing via new optional `kind`/`lens` row fields (unit-tested).
- Harden a second time after the `--max` dogfooding round (per-lens split, 13 voices): never auto-accept an all-untagged consensus cluster (no lens backs it — verified like a solo, via a single `needsVerify` partition); the design verifier now sees the finding's `recommendation` (the proposal it tests) and carries an escape hatch for defects mis-filed under a design lens; workflow-assigned stable `num` per finding; merge-agent lens validated against the lens set; improvement invitation scoped to design finder units; `LENS_BRIEF` startup assertion + `test_lens_sync.py` guards the lens mirrors; `REFUTED` is its own balance segment (a refuted consensus design cluster is not a solo); doc sweep of the stale "verifies solos" wording.
- Harden a third time after an external-only `--max` dogfooding round (codex + grok-4.5 + composer, no Claude lenses): the merge-supplied cluster lens is accepted only when a member actually tagged it (a globally-valid lens no member carried no longer corrupts the `[lens]` prefix / `survivingPerLens`), and `unspecified` never wins the majority tally; the design verifier's mis-filed-bug exception now reclassifies the finding to `kind: "defect"` (`reclassifyToDefect`) so a bug wearing a design lens leaves the Design table; a methodological-lens (`removed-behavior` / `cross-file-trace`) cross-family consensus with no repo-reading Claude voice is verified rather than auto-accepted (diff-only externals can't confirm a repo fact); `test_lens_sync.py` pins `METHODOLOGICAL_LENSES` to the cluster set.
- Harden a fourth time after the external-only round's fixes were re-reviewed by a full-ensemble `--max` pass (the verifier read the real repo and confirmed two regressions in the prior commit): the methodological-consensus guard now checks that a Claude voice actually *tagged* the methodological lens (member `(backend, lens)`), not mere family presence — plurality lens resolution could otherwise label a cluster `cross-file-trace` off two externals while the lone Claude member tagged `[correctness]` and never checked the claim; `needsVerify` fires on any design-tagged member so a mixed design+defect cluster still applicability-checks its proposal, and the design fence carries the proposal for all-untagged clusters too; a `reclassifyToDefect` finding now also strips its design lens (else pr-post re-buckets it to Design when the step-5 handoff drops `kind`) and drops to solo (an applicability pass alone must not mint a consensus defect); README pipeline diagram + consensus blurb corrected to the 0.5.0 verify gate (the earlier sweep missed them).
- Harden a fifth time after a full-ensemble `--max` confirmation pass (which REFUTED all re-flags of the prior round's fixes but caught fresh ones): `pr-post.py` buckets rows by `kind` ALONE — a dropped kind falls to defect (the safe bucket), the lens is no longer a design fallback that could hide a reclassified/mixed-cluster bug in the Design table (`DESIGN_LENSES` retired); the design applicability verifier redacts out-of-repo path tokens from the proposal before fencing, so a hostile `--pr` proposal naming `~/.aws/…` can't lure the verifier into an out-of-repo read; the dead `c.kind === 'design'` verify-rubric disjunct is dropped; `test_lens_sync.py` upgraded from a subset to a completeness check (`METHODOLOGICAL_LENSES == breakage − topical`); the SKILL `num`-verbatim rule is scoped to round 0 (cross-round `#` is presenter-owned) and two stale doc comments corrected.

### 0.4.3 — 2026-07-17
- Remove the `grok-composer-2.5-fast` backend: grok CLI 0.2.101 dropped the model, so the composer voice (adapter path, defensive parser, workflow voice, docs) failed at runtime. `grok-4.5` is now the only grok model, and the ensemble is three voices (Claude lenses + codex + grok-4.5).
- Make grok readiness model-aware: `ready`/`list` now require `grok-4.5` to appear in `grok models`, not just auth — so a dropped or renamed model reads as "not ready" with an actionable hint instead of failing mid-review. The probe runs unjailed like the sibling `codex login status` check (a readiness check passes no untrusted diff, so it needs no sandbox and stays free of the review path's python3 profile-build), bounded by `SWARM_PROBE_TIMEOUT` (10s, `timeout -k` so a SIGTERM-ignoring CLI can't hang it; separate from the review-length `SWARM_TIMEOUT`). It falls back to the auth check — with a warning on stderr, never silently — whenever it can't produce a clean answer (no coreutils `timeout`, non-zero exit, timeout, or an empty/unparseable list), rather than dropping grok from the fan-out.
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ This is a **Claude Code plugin marketplace** (monorepo) containing plugins that
- **knowledge-system** (v1.9.x) — Knowledge management with three layers: Rules, Knowledge, Memory. Skills: `/init`, `/query`, `/curate`, `/reindex`, `/backfill-knowledge`, `/migrate`, `/statusline`
- **work-system** (v1.8.x) — Task and worktree workflow. Skills: `/define`, `/kickoff`, `/adopt`, `/continue`, `/status`, `/close`, `/list`, `/statusline`
- **pr-flow** (v1.3.x) — PR review feedback loop. Skills: `/open`, `/cycle`, `/check`, `/fix`, `/rebase`, `/merge`
- **swarm** (v0.4.x) — Local mixture-of-agents code review (external `codex`/`grok` CLIs — grok-4.5 — plus Claude lenses). P2: `/swarm:review` pipeline (scope→fan-out→merge→verify); P5: `--fix`/`--loop` apply the findings you agreed with. Skills: `/swarm:review`, `/swarm:agents`
- **swarm** (v0.5.x) — Local mixture-of-agents code review (external `codex`/`grok` CLIs — grok-4.5 — plus Claude lenses: 11 in 4 clusters). P2: `/swarm:review` pipeline (scope→fan-out→merge→verify); P5: `--fix`/`--loop` apply the findings you agreed with. Skills: `/swarm:review`, `/swarm:agents`

## Plugin Anatomy

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ PR review feedback loop. Create PRs with readiness checks, commit + push + trigg

### Swarm

Local mixture-of-agents code review. Fans out one review across Claude lens subagents plus the `codex` and `grok` CLIs (grok-4.5), merges and verifies their findings, and presents a single ranked report — before anything is pushed. With `--fix` / `--loop` it also applies the findings you agreed with (only Claude edits; the external agents stay review-only). `--pr [<number>]` runs the same ensemble against a GitHub PR's diff and posts the gated result as a PR comment (via your own `gh` auth, after one confirmation) — no CI or API-token setup. Complementary to PR Flow's GitHub-side loop. *(Phase 5: `/swarm:review` pipeline + fix loop + PR posting.)*
Local mixture-of-agents code review. Fans out one review across Claude lens subagents (11 lenses in 4 clusters — breakage, threat, design, consistency) plus the `codex` and `grok` CLIs (grok-4.5), merges and verifies their findings, and presents a single ranked report — defects and design suggestions kept apart — before anything is pushed. With `--fix` / `--loop` it also applies the findings you agreed with (only Claude edits; the external agents stay review-only). `--pr [<number>]` runs the same ensemble against a GitHub PR's diff and posts the gated result as a PR comment (via your own `gh` auth, after one confirmation) — no CI or API-token setup. Complementary to PR Flow's GitHub-side loop. *(Phase 5: `/swarm:review` pipeline + fix loop + PR posting.)*

**Commands:** `/swarm:review [--fix | --loop[=N]] [--max]`, `/swarm:review --pr [<number>]`, `/swarm:agents` *(more to come: `/swarm:adversarial`, `/swarm:style`, `/swarm:security`)*
**Commands:** `/swarm:review [--fix | --loop[=N]] [--max]`, `/swarm:review --pr [<number>]`, `/swarm:agents` *(planned: `/swarm:adversarial`, `/swarm:style`, `/swarm:security` — thin subset presets of the default lens set)*

[Documentation →](plugins/swarm/)

Expand Down
Loading
Loading