| name | design-council-orchestration |
| description | Convene 11 role-specialized Claude agents to debate technical decisions in parallel, with the invoking Claude acting as CEO |
| triggers | ["convene the design council","run a design debate","get the council together for this decision","council review of this architecture","spawn the design council","need a cross-functional design review","debate this with the full council","convene council to review"] |
Design Council Orchestration
Skill by ara.so — Design Skills collection.
Overview
Design Council is a Claude Code plugin that spawns 11+ independent Claude agents in parallel, each with a specialized role (principal-engineer, security-engineer, product-manager, etc.), to debate cross-cutting technical decisions. The invoking Claude acts as CEO, orchestrating the debate and writing binding decisions.
Unlike single-context reviews, each seat runs in its own context with no shared history. Disagreement is structural, not simulated. Seats argue via direct peer DMs (SendMessage), not sequential turns through the CEO.
Key difference from other patterns: This isn't prompt engineering within one context — it's multi-agent orchestration with genuine parallelism and independent reasoning.
Installation
/plugin marketplace add sjsyrek/claude-plugins
/plugin install design-council@sjsyrek
To pin a specific version:
git clone https://github.com/sjsyrek/design-council.git
cd design-council
git checkout v0.2.0
/plugin marketplace add .
/plugin install design-council@sjsyrek
When to Use
Invoke when BOTH conditions hold:
- Decision crosses ≥2 specialist domains (e.g., security + performance + UX)
- Output must survive handoff (decision log, tracker items, execution plan)
Natural trigger phrases:
- "Convene the council to review this API design"
- "Get the design council together for this architecture"
- "Council debate: pagination strategy for this endpoint"
- "Run a design review on the caching layer"
Do NOT invoke for:
- Simple bug fixes (single domain)
- Library/tool selection (→ use direct research)
- Pure exploration without deliverable
- Questions answerable by one specialist
Token economics: Expect 10–20× the cost of single-context review. The council earns its cost on decisions that would otherwise ship with blind spots.
Execution Phases
Phase 0: Plan Card (Pre-Flight)
Before any agents spawn, the CEO shows a confirmation card:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
DESIGN COUNCIL PLAN
Mode: DEBATE
Roster (8 seats):
• principal-engineer [opus]
• platform-engineer [sonnet]
• security-engineer [sonnet]
• test-engineer [sonnet]
• performance-engineer [sonnet]
• product-manager [opus]
• technical-writer [opus]
• qa-engineer [sonnet]
Budget:
~180k tokens (cached brief saves ~9k × 8)
~4–7 min wall-clock (3 debate rounds)
Opening prompt:
"Should the /search endpoint paginate with
cursor tokens or offset/limit?"
Reply: go | swap X for Y | drop X | add X | abort
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
You control the roster here:
go
swap principal-engineer for sonnet
add domain-expert
drop ui-ux-designer
abort
Phase 1: Brief Assembly
The CEO gathers constraints once into ~/.claude/councils/<slug>/brief.md:
CLAUDE.md constraints
- Referenced specs / ADRs
- Project memory (including beads if detected)
- Skill self-audit: greps auto-memory for entries about design-council itself — memory wins over skill text (real failures > documentation)
Every seat's spawn prompt points to this path → prompt cache hits across all spawns (~7–12k tokens saved per 8-seat council).
Phase 2: Parallel Spawn
CEO spawns all seats in one multi-tool-call message:
await Promise.all([
Agent({
name: "principal-engineer",
run_in_background: true,
team_name: "design-council-2026-05-17-pagination",
model: "claude-opus-4",
prompt: `You are the principal-engineer seat.
Brief: file://~/.claude/councils/pagination/brief.md
Four delivery rules:
1. Handshake: DM "READY: principal-engineer" within 10s
2. Cross-talk: SendMessage only (never Execute)
3. Final verdict: via SendMessage to CEO
4. Idle summary: <100 chars
Opening question:
Should /search paginate cursor or offset?`
}),
Agent({ name: "security-engineer", ... }),
Agent({ name: "platform-engineer", ... }),
]);
Phase 2.5: Handshake Verify
CEO counts incoming READY: <seat-name> DMs, checks for empty tmuxPaneIds (silent spawn failures), remediates, and emits:
HANDSHAKE: 8/8 ok | verdict=PROCEED
If any seat fails to spawn:
- CEO attempts one re-spawn
- On second failure: drops seat, logs it, proceeds with reduced roster
Phase 3: Opening Verdicts
Each seat posts its opening verdict via SendMessage to CEO:
From: security-engineer
To: CEO
CONCERNS
Offset pagination leaks record counts (DoS vector).
Cursor tokens must be HMAC-signed with rotation.
Need rate-limit strategy regardless of choice.
Verdicts:
APPROVE — no blocking concerns
CONCERNS — issues that need resolution
BLOCK — showstopper (requires CEO arbitration or escalation)
Phase 4: Cross-Talk (Peer DMs)
Review mode: skips cross-talk by default (seats → CEO only).
Debate mode: CEO routes disagreements to direct seat-to-seat DMs:
if (security.verdict === "CONCERNS" && platform.verdict === "APPROVE") {
SendMessage({
from: "CEO",
to: "security-engineer",
text: "DM platform-engineer: they approved offset. Argue your HMAC requirement."
});
SendMessage({
from: "CEO",
to: "platform-engineer",
text: "security-engineer has concerns about offset. Respond to their HMAC point."
});
}
Seats then argue directly:
From: security-engineer
To: platform-engineer
Your offset approval ignores enumeration risk.
Without signed cursors, scrapers can walk the
entire dataset. Do you have a mitigation?
From: platform-engineer
To: security-engineer
Rate limiting is orthogonal to pagination style.
Offset + jittered delays caps enumeration to
same ROC as cursor. Offset is simpler to cache.
Hard cap: 3 rounds. CEO forces convergence or arbitration.
Phase 5: Arbitration + Decision Log
For unresolved disagreements, CEO writes binding decisions (3–5 sentences engaging both sides):
## Decision: Cursor pagination with signed tokens
security-engineer's enumeration concern is valid
and not fully mitigated by rate limiting (jitter
still allows sequential walks). platform-engineer's
caching argument applies to both schemes via
`cache_token` param. **Adopt cursor pagination
with HMAC-SHA256 signed tokens (rotate key daily).**
Deferred: Rate limit strategy (filed as BEAD-127).
Escalations (to user):
- Strategic tradeoffs (e.g., "ship fast vs. correct")
- Budget / resourcing
- Legal / compliance
- Cross-team dependencies
CEO emits draft log to chat:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
DECISION LOG (DRAFT)
Reply: save | amend "<changes>" | discard
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Phase 6: Persist + Teardown
On save:
~/.claude/councils/2026-05-17-pagination/log.md
---
slug: pagination
date: 2026-05-17
mode: DEBATE
roster: [principal-engineer, security-engineer, ...]
primary-tracker-id: BEAD-126
linked-tracker-ids: [BEAD-127]
status: resolved
---
Should /search paginate cursor or offset?
...
...
File ownership:
- src/api/search.ts → platform-engineer context
- src/auth/tokens.ts → security-engineer context
- tests/api/search.test.ts → test-engineer context
CEO then:
- Broadcasts shutdown via
SendMessage
- Calls
TeamDelete (removes shared task list)
- Cleans up Brief artifact
Roster Configuration
Default 11 Seats (Dynamic Sizing)
core:
- principal-engineer
- platform-engineer
- integration-engineer
- test-engineer
- qa-engineer
- security-engineer
- performance-engineer
- product-manager
- ui-ux-designer
- accessibility-specialist
- technical-writer
opt-ins:
- devops-engineer
- finops-engineer
- legal-compliance
- domain-expert
- historian
Automatic pruning (Phase 0):
- No UI → drop
ui-ux-designer, accessibility-specialist
- Internal tool → drop
security-engineer, platform-engineer
- Pure backend → drop
ui-ux-designer
Adding seats in plan card:
add domain-expert
Model Assignment
Default strategy:
- Opus: synthesis-heavy (
principal-engineer, product-manager, technical-writer, historian)
- Sonnet: analytical (
test-engineer, performance-engineer, security-engineer)
Override triggers:
- "High quality bar" → all Opus
- "Ship to production" → all Opus
- Plan card manual swap:
swap security-engineer for opus
Beads Integration (Tracker System)
When beads is detected (.beads/ exists OR bd on $PATH):
Phase 1 (Brief):
bd memories
bd ready
bd show <id>
Phase 4 (Defer):
bd create \
--title "Implement rate limiting for /search" \
--type task \
--parent BEAD-126 \
--context "From design-council-2026-05-17-pagination: security-engineer raised enumeration concern"
Phase 6 (Teardown):
bd close BEAD-126 --force
primary-tracker-id: BEAD-126
linked-tracker-ids: [BEAD-127, BEAD-128]
Without beads: deferred items remain prose in decision log. Protocol is strictly additive.
Advanced Patterns
Stop Early
stop the council
CEO broadcasts shutdown, saves partial log with status: halted, cleans up.
Review Mode (No Cross-Talk)
"Council review of PR #47 (no debate)"
CEO skips Phase 4 cross-talk. Seats → CEO verdict only. Faster, cheaper, good for conformance checks.
Implementation Handoff
After decision log saves, spawn execution agents with isolation: "worktree":
await Agent({
name: "implement-cursor-pagination",
isolation: "worktree",
model: "claude-sonnet-4",
prompt: `Implement cursor pagination per design-council-2026-05-17-pagination.
Decision log: file://~/.claude/councils/2026-05-17-pagination/log.md
File ownership (avoid conflicts):
- src/api/search.ts (yours)
- tests/api/search.test.ts (yours)
DO NOT TOUCH:
- src/auth/tokens.ts (security-engineer's impl)
Brief: file://~/.claude/councils/pagination/brief.md`
});
Worktree isolation prevents merge conflicts. See references/implementation-handoff.md in the plugin source for full playbook.
Memory Self-Audit Pattern
Why it matters: If you've used design-council before and hit a failure (e.g., "security seat always blocks on offset pagination"), that failure lands in auto-memory. Phase 1 greps for design-council memories and overrides skill text with ground truth.
Example:
# In auto-memory
2026-05-10: design-council: security-engineer seat
over-indexes on HMAC signatures. For internal APIs,
skip security seat unless user data is involved.
Phase 1 brief will now include:
MEMORY OVERRIDE (from 2026-05-10):
Skip security-engineer for internal APIs unless
user data involved. Prior councils over-rotated
on HMAC signatures.
This is automatic. Memory always wins.
Observability (Split-Pane Mode)
Tmux / iTerm2: Each seat renders in its own pane. Watch debates live.
{
"teammateMode": "auto"
}
Without split-pane terminal: Seats share main pane. Cycle with Shift+Down.
This is a Claude Code harness feature, not plugin-required.
Common Issues
Silent Spawn Failures
Symptom: Phase 2.5 reports HANDSHAKE: 6/8 ok | verdict=DEGRADED
Cause: TeamCreate + Agent race on shared task list initialization.
Remediation (automatic):
- CEO retries failed seats once
- On second failure: drops seat, logs it, proceeds
User action: Check ~/.claude/councils/<slug>/log.md for degraded-roster: [security-engineer]. If critical seat dropped, re-run with add security-engineer.
Token Budget Overrun
Symptom: Debate stalls mid-round, costs spike.
Cause: Deep research by one seat (e.g., performance-engineer running benchmarks).
Fix:
- Say "stop the council"
- Review partial log
- Re-run in review mode (skips cross-talk)
Prevention: Use review mode for conformance checks, debate mode for novel decisions.
Deferred Items Lost
Symptom: Phase 5 decision says "DEFER: " but no tracker created.
Cause: No tracker system detected (no beads, no bd on $PATH).
Fix: Manually file from decision log prose:
bd create \
--title "Implement rate limiting for /search" \
--context "From design-council-2026-05-17-pagination"
Prevention: Install beads or integrate another tracker (see references/tracker-integration.md).
Prompt Cache Misses
Symptom: Token costs higher than predicted.
Cause: Brief modified between spawns (5-minute cache window).
Fix: Don't edit ~/.claude/councils/<slug>/brief.md during Phase 2 spawn.
Performance Characteristics
| Metric | Review Mode | Debate Mode (3 rounds) |
|---|
| Wall-clock | 2–3 min | 4–7 min |
| Tokens | 60–90k | 150–250k |
| Seats (typical) | 4–6 | 6–11 |
| Cache savings | ~5k × seats | ~9k × seats |
Parallelism: Wall-clock ≈ slowest seat, not sum of seats.
Configuration Files
Brief Artifact
~/.claude/councils/<slug>/brief.md
- CLAUDE.md constraints
- Referenced specs
- Memory overrides
- Beads context (if detected)
Lifecycle: Created Phase 1, read by all seats, deleted Phase 6 teardown.
Decision Log
~/.claude/councils/<yyyy-mm-dd>-<slug>/log.md
---
slug: pagination
date: 2026-05-17
mode: DEBATE
roster: [principal-engineer, ...]
primary-tracker-id: BEAD-126
status: resolved
---
Lifecycle: Persists after teardown. User artifact space.
Code Examples
Invoking from Code
Custom Seat Brief (domain-expert)
PostgreSQL query optimization. We're deciding
between materialized views vs. incremental
aggregates. Expert should eval EXPLAIN plans.
CEO injects this into domain-expert spawn prompt:
You are domain-expert (PostgreSQL query optimization).
Context: Eval materialized views vs. incremental
aggregates. Review EXPLAIN plans in brief.
Brief: file://~/.claude/councils/cache-layer/brief.md
Execution Plan Format
# Execution Plan
## Phase 1: Cursor Token Implementation
Owner: platform-engineer context
Files:
- src/api/search.ts
- src/types/pagination.ts
## Phase 2: HMAC Signing
Owner: security-engineer context
Files:
- src/auth/tokens.ts
- src/auth/rotation.ts
## Phase 3: Integration Tests
Owner: test-engineer context
Files:
- tests/api/search.test.ts
- tests/auth/tokens.test.ts
## Merge Strategy
Worktree per phase. Merge order: 1 → 2 → 3.
Conflict expected: src/api/search.ts (line 47, imports).
Resolution: Accept Phase 2 (security adds token import).
Environment Variables
No secrets required. All state in ~/.claude/councils/ (user artifact space).
If integrating a custom tracker (not beads):
export COUNCIL_TRACKER_CMD="jira"
export COUNCIL_TRACKER_CREATE_ARGS="create --project DESIGN"
See references/tracker-integration.md for adapter contract.
Version Compatibility
- Claude Code: v0.9.0+ (requires
TeamCreate, Agent.run_in_background)
- Beads: v0.3.0+ (optional, for tracker integration)
- Tmux: 3.0+ (optional, for split-pane observability)
Further Reading
- Implementation handoff playbook:
references/implementation-handoff.md in plugin source
- Tracker integration:
references/tracker-integration.md
- Changelog:
CHANGELOG.md
License: MIT
Source: https://github.com/sjsyrek/design-council