Skip to content

Add /swarm:review local mixture-of-agents pipeline (P2) - #24

Merged
gering merged 6 commits into
mainfrom
task/swarm-p2-security-architecture
Jul 8, 2026
Merged

Add /swarm:review local mixture-of-agents pipeline (P2)#24
gering merged 6 commits into
mainfrom
task/swarm-p2-security-architecture

Conversation

@gering

@gering gering commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • Adds /swarm:review (Swarm P2): a local mixture-of-agents code review that fans one diff across four voices — Claude lenses + codex + grok-build + composer — and merges them into one ranked report.
  • composer (grok-composer-2.5-fast) joins as a fast fourth voice via a defensive-parse adapter path. Consensus counts model families, so the two grok voices agreeing is one vote — a CONSENSUS tag needs ≥2 of claude/openai/grok.
  • Security kept intentionally minimal: the diff is fenced as untrusted data, a final output gate scrubs secret-shaped content from every finding, and dropped backends are marked (error ≠ empty). The P1 adapter floor (sandbox, tool-less grok, scrub, env filter, caps) stays beneath.
  • Verified end-to-end by a real 4-voice ensemble run (0 backend errors, cross-family consensus reached) — which itself surfaced two real bugs in the new composer path, fixed in the second commit.

Changes

  • Adapter (scripts/agents.sh): composer voice via --model grok-composer-2.5-fast — strict-JSON prompt (no --json-schema/--effort), defensive parser that prefers the non-empty findings object, per-item finding.schema.json validation, argv-size guard, and an --effort-ignored note.
  • Workflow (workflows/swarm-review.js): scope+gate → 4-voice fan-out → (file, mechanism) merge with family-aware consensus → adversarial 3-state verify of solos → output-gated ranked synthesis.
  • Skill (skills/review/SKILL.md): /swarm:review [ref | --staged | pathspec] — builds the diff + fenced prompt, probes live backends, runs the workflow, renders the report.
  • Version 0.1.0 → 0.2.0 (plugin.json + marketplace.json), README, two knowledge entries.

Readiness

  • ✅ README updated (P2 status, /swarm:review, pipeline + security sections)
  • ✅ Version bumped 0.1.0 → 0.2.0 (plugin.json + marketplace.json in sync)
  • ✅ Knowledge curated (adapter entry updated + new pipeline entry)
  • check-structure.py green (0 errors)
  • ➖ Tests / lint / build: N/A (declarative plugin repo; the structure guard is the CI check)
  • ➖ Changelog: N/A (repo has none; status tracked in the plugin README)

Test plan

  • Run /swarm:review on a real diff with all backends live; confirm 4 voices, a ranked report, and a balance footer
  • Confirm a CONSENSUS tag appears only when ≥2 of claude/openai/grok agree (composer + grok-build alone stays solo)
  • Confirm a dropped backend surfaces as an error, not as "found nothing"
  • python3 scripts/check-structure.py stays green

🤖 Generated with Claude Code

https://claude.ai/code/session_017rpoJ2DokY1SMfv1dSfZwe

gering and others added 6 commits July 5, 2026 16:51
- agents.sh: add grok-composer-2.5-fast as a second grok voice via a
  defensive-parse path (strict-JSON prompt, no --json-schema/--effort);
  prefer the findings-bearing object over the first decodable one
- workflows/swarm-review.js: registered pipeline — scope+gate → 4-voice
  fan-out (Claude lenses + codex + grok-build + composer) → (file,mechanism)
  merge with family-aware consensus → verify solos → output-gated synthesis
- skills/review/SKILL.md: /swarm:review — builds diff + fenced prompt,
  probes live backends, runs the workflow, renders the ranked report
- minimal security: fence diff as data, output gate (secret scrub over all
  findings), error != empty transport marker; P1 adapter floor stays
- bump swarm 0.1.0 -> 0.2.0; update README + knowledge

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017rpoJ2DokY1SMfv1dSfZwe
Follow-up from a full 4-voice /swarm:review of the composer diff (cross-family
consensus flagged the first two):

- validate each composer finding against finding.schema.json — composer is not
  CLI-schema-enforced like codex/grok-build, so a malformed item now ERRORs
  (error != empty) instead of reaching merge/verify
- prefer a non-empty findings object over an empty/preamble object that would
  otherwise mask the real answer
- guard the assembled prompt+schema argv word against MAX_ARG_STRLEN (the
  prompt cap didn't account for the appended schema on this path)
- note on stderr that --effort is ignored for grok-composer-2.5-fast

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017rpoJ2DokY1SMfv1dSfZwe
A full 4-voice /swarm:review of PR #24 surfaced real issues in the new code;
fix the confirmed/agreed ones (deferred: trusted-source path interpolation,
self-pwn pathspec, haiku-transport fundamental limit).

Security / output gate:
- SKILL.md: per-run nonce in the diff fence — a fixed marker could be forged
  by diff content to close the fence and inject reviewer instructions
- swarm-review.js: output gate scrubs ALL string fields (was missing verifier
  evidence + cluster mechanism); refuted findings now scrubbed too
- agents.sh: composer valid_item mirrors finding.schema.json exactly (exact
  key set + maxLength), not a type-only subset

Correctness:
- SKILL.md: resolve the real default branch (origin/HEAD) instead of hardcoded
  main/master; warn instead of silently narrowing to `git diff HEAD`
- SKILL.md: oversize prompt drops external voices (Claude-only) to match its
  own warning, instead of passing voices the adapter only rejects
- swarm-review.js: Claude lens failures marked error != empty; zero-member
  clusters dropped; sort comparator made antisymmetric
- agents.sh: cap composer stdout before the O(n^2) brace-scan (a multi-MB blob
  could spin past the timeout)
- external prompt requests [lens] tags so external findings map to real lenses

Presentation + docs:
- SKILL.md: encode the locked P4 report layout (model-named Agents column,
  correct severity icons, Verifier vs main-session Verdict, balance block);
  note the P5 --fix/--loop ask-on-ambiguous-fix rule
- swarm-review.js: per-backend model+count rollup for the balance Agents line
- sync CLAUDE.md + top-level README to swarm 0.2.x / P2 / /swarm:review

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017rpoJ2DokY1SMfv1dSfZwe
Round 1 of a self-review loop over the P2 branch (the prior 16 findings all
resolved, none recurred). Fix the agreed findings; option B for the schema
duplication — add the missing caps + a drift-warning comment to each mirror.

- SKILL.md: `|| true` on the DEFBR pipeline — a regression from the previous
  round where pipefail aborted the default-branch fallback loop (critical)
- swarm-review.js: merge coverage guard — recover pool findings the merge
  agent leaves unclustered as solo clusters instead of silently dropping them
- schema caps (B): add maxLength + maxItems:100 to the workflow FINDING_ITEM
  and the composer validator so all three schema copies match; drift-warning
  comment in finding.schema.json / swarm-review.js / agents.sh
- output gate: redact the whole PEM block (BEGIN..END), not just the header,
  in BOTH the JS gate and the adapter scrub; scrub backendErrors + gate text
- balance.agents: a single failed lens no longer marks the whole backend down
- SKILL.md: stop advertising --fix/--loop as runnable (P5, not built)
- docs: composer is a grok model, not a third CLI — fix plugin.json,
  marketplace.json, READMEs, CLAUDE.md

Deferred (documented residuals): verifier diff-offset line numbers, trusted
path interpolation, composer schema-append asymmetry, defensive arg defaults.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017rpoJ2DokY1SMfv1dSfZwe
A control run without Claude lenses (codex + grok-build + composer only)
surfaced real gaps the with-Claude run missed — notably a real secret-scrub
drift.

- output gate: add the explicit aws_secret_access_key rule the JS scrub was
  missing (the generic \bsecret\b rule can't match inside the underscored key
  name) — JS gate and adapter scrub now redact identically; also redact a PEM
  key truncated by a field cap (END marker optional), in both scrubs
- merge: first-wins disjoint member_indices so a finding can't be emitted twice
  or inflate consensus; CLUSTER_SCHEMA now carries FINDING_ITEM's length caps
- pool skips ok:false voices; sort tolerates unknown severity (no NaN); the
  input-guard early return returns the full result shape
- SKILL.md: default scope now includes untracked files (git diff omits them)
- workflow: add args.claude:false for an external-only control run (no Claude
  finder lenses; merge/verify still in-session), documented in the skill

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017rpoJ2DokY1SMfv1dSfZwe
Third control round (external-only: codex + grok-build + composer) caught
follow-on gaps in earlier fixes plus a few pre-existing ones.

- output gate: scrub gate.run + skip[].lens too (not just change_kind/why);
  PEM redaction now handles encrypted keys (Proc-Type/DEK-Info metadata) AND
  field-cap-truncated keys via alternation, in both JS and adapter scrubs
- gate/merge agents get a .catch — a failure degrades gracefully (gate → all
  lenses, merge → coverage guard recovers every finding) instead of rejecting
- honor an explicit empty gate run:[] as "no lenses" (was falling back to all)
- SKILL.md: untracked-file append is now flag-gated (INCLUDE_UNTRACKED) so a
  ref/--staged review doesn't pull in out-of-scope untracked files; align the
  oversize cutoff with the adapter's 122880-byte cap
- EXTERNAL_SCHEMA gains maxItems:100 to match the other schemas
- knowledge: record the claude:false control run + the per-lens external-prompt
  idea as opt-in P3 (the ~5x call cost rules it out as a default)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017rpoJ2DokY1SMfv1dSfZwe
@gering
gering merged commit f443fbb into main Jul 8, 2026
1 check passed
@gering
gering deleted the task/swarm-p2-security-architecture branch July 8, 2026 07:18
gering added a commit that referenced this pull request Jul 16, 2026
Second dogfooding round at the deepest profile (/swarm:review --max --fix:
per-lens split live — gate pruned style, 10 xhigh finders + codex
gpt-5.6-sol@xhigh + grok-4.5 + composer; 24 findings, 10 consensus).
Fixes the agreed findings:

- Never auto-accept an all-untagged consensus cluster: no tagged lens
  backs it, so it is verified like a solo. Verify/auto-accept now derive
  from ONE needsVerify predicate (structural exactly-once partition);
  kind vote in clearer every-form (#1, consensus critical; #21, #22)
- Design verifier sees the finding's recommendation — the proposal the
  applicability rubric actually tests — and carries an escape hatch:
  a genuine defect mis-filed under a design lens is not refuted away
  (#12, #3); "solo" dropped from verifier prompts (#4)
- Untagged findings from multi-lens cluster finders fall back to
  'unspecified' (safe defect bucket), not lenses[0] (#7); merge-agent
  free-text lens validated, majority-member fallback (#9)
- Improvement invitation scoped to design finder units — defect-lens
  finders stay defect-only (#8); merge prompt clusters by issue, not
  only defect (#13); schema descriptions generalized for design
  findings (#14)
- LENS_BRIEF startup assertion (#6); gate prompt interpolates
  LENS_CLUSTERS.design (#19); new test_lens_sync.py guards all lens
  mirrors: SKILL HDR prompt, LENS_BRIEF, pr-post DESIGN_LENSES (#5)
- Workflow assigns stable finding num (defects first, shared sequence);
  presenter/pr-post render it verbatim (#20)
- pr-post.py: design lens is the backup kind signal when the handoff
  drops kind (explicit defect still wins); single-pass partition (#17, #24)
- Balance: REFUTED is its own segment (refuted ⊄ solo since design
  consensus can be refuted) (#2); LOCKED design-table column precedence
  in --loop rounds clarified (#11); "verifies solos" doc sweep across
  manifests/README/knowledge (#4); cluster failure-isolation trade-off
  documented (#10); knowledge index line trimmed (#15)

Declined: #16 (JS test harness for sandbox code; lens-sync test covers
the drift class), #18 (gate-fail under --max runs all lenses — the
documented never-silently-narrower degrade), #23 (micro-opt vs readability).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0126cGxsBYxqgEFH4AcpriNk
gering added a commit that referenced this pull request Jul 17, 2026
Second dogfooding round at the deepest profile (/swarm:review --max --fix:
per-lens split live — gate pruned style, 10 xhigh finders + codex
gpt-5.6-sol@xhigh + grok-4.5 + composer; 24 findings, 10 consensus).
Fixes the agreed findings:

- Never auto-accept an all-untagged consensus cluster: no tagged lens
  backs it, so it is verified like a solo. Verify/auto-accept now derive
  from ONE needsVerify predicate (structural exactly-once partition);
  kind vote in clearer every-form (#1, consensus critical; #21, #22)
- Design verifier sees the finding's recommendation — the proposal the
  applicability rubric actually tests — and carries an escape hatch:
  a genuine defect mis-filed under a design lens is not refuted away
  (#12, #3); "solo" dropped from verifier prompts (#4)
- Untagged findings from multi-lens cluster finders fall back to
  'unspecified' (safe defect bucket), not lenses[0] (#7); merge-agent
  free-text lens validated, majority-member fallback (#9)
- Improvement invitation scoped to design finder units — defect-lens
  finders stay defect-only (#8); merge prompt clusters by issue, not
  only defect (#13); schema descriptions generalized for design
  findings (#14)
- LENS_BRIEF startup assertion (#6); gate prompt interpolates
  LENS_CLUSTERS.design (#19); new test_lens_sync.py guards all lens
  mirrors: SKILL HDR prompt, LENS_BRIEF, pr-post DESIGN_LENSES (#5)
- Workflow assigns stable finding num (defects first, shared sequence);
  presenter/pr-post render it verbatim (#20)
- pr-post.py: design lens is the backup kind signal when the handoff
  drops kind (explicit defect still wins); single-pass partition (#17, #24)
- Balance: REFUTED is its own segment (refuted ⊄ solo since design
  consensus can be refuted) (#2); LOCKED design-table column precedence
  in --loop rounds clarified (#11); "verifies solos" doc sweep across
  manifests/README/knowledge (#4); cluster failure-isolation trade-off
  documented (#10); knowledge index line trimmed (#15)

Declined: #16 (JS test harness for sandbox code; lens-sync test covers
the drift class), #18 (gate-fail under --max runs all lenses — the
documented never-silently-narrower degrade), #23 (micro-opt vs readability).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0126cGxsBYxqgEFH4AcpriNk
gering added a commit that referenced this pull request Jul 17, 2026
Second dogfooding round at the deepest profile (/swarm:review --max --fix:
per-lens split live — gate pruned style, 10 xhigh finders + codex
gpt-5.6-sol@xhigh + grok-4.5 + composer; 24 findings, 10 consensus).
Fixes the agreed findings:

- Never auto-accept an all-untagged consensus cluster: no tagged lens
  backs it, so it is verified like a solo. Verify/auto-accept now derive
  from ONE needsVerify predicate (structural exactly-once partition);
  kind vote in clearer every-form (#1, consensus critical; #21, #22)
- Design verifier sees the finding's recommendation — the proposal the
  applicability rubric actually tests — and carries an escape hatch:
  a genuine defect mis-filed under a design lens is not refuted away
  (#12, #3); "solo" dropped from verifier prompts (#4)
- Untagged findings from multi-lens cluster finders fall back to
  'unspecified' (safe defect bucket), not lenses[0] (#7); merge-agent
  free-text lens validated, majority-member fallback (#9)
- Improvement invitation scoped to design finder units — defect-lens
  finders stay defect-only (#8); merge prompt clusters by issue, not
  only defect (#13); schema descriptions generalized for design
  findings (#14)
- LENS_BRIEF startup assertion (#6); gate prompt interpolates
  LENS_CLUSTERS.design (#19); new test_lens_sync.py guards all lens
  mirrors: SKILL HDR prompt, LENS_BRIEF, pr-post DESIGN_LENSES (#5)
- Workflow assigns stable finding num (defects first, shared sequence);
  presenter/pr-post render it verbatim (#20)
- pr-post.py: design lens is the backup kind signal when the handoff
  drops kind (explicit defect still wins); single-pass partition (#17, #24)
- Balance: REFUTED is its own segment (refuted ⊄ solo since design
  consensus can be refuted) (#2); LOCKED design-table column precedence
  in --loop rounds clarified (#11); "verifies solos" doc sweep across
  manifests/README/knowledge (#4); cluster failure-isolation trade-off
  documented (#10); knowledge index line trimmed (#15)

Declined: #16 (JS test harness for sandbox code; lens-sync test covers
the drift class), #18 (gate-fail under --max runs all lenses — the
documented never-silently-narrower degrade), #23 (micro-opt vs readability).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0126cGxsBYxqgEFH4AcpriNk
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant