| name | agent-council |
| description | Use when facing trade-offs, subjective judgments, uncertain decisions, or when diverse viewpoints would improve judgment quality. Triggers include "council", "๋ค๋ฅธ ์๊ฒฌ", "perspectives", "what do others think". |
Agent Council
Advisory body providing multiple AI perspectives on uncertain decisions. When all members are unavailable, falls back to in-session single-voice advisory using the in-session fallback framework.
Council provides opinions. The caller makes the final decision.
Quick Reference
| ์ํฉ | Council ํ์? | ์ด์ |
|---|
| ์ํคํ
์ฒ ํธ๋ ์ด๋์คํ | โ
Yes | ๋ค์ํ ๊ด์ ํ์ |
| ์ฃผ๊ด์ ์ฝ๋ ํ์ง ํ๋จ | โ
Yes | ๋ช
ํํ ์ ๋ต ์์ |
| ๋ฆฌ์คํฌ ํ๊ฐ ๋ถ์ผ์น | โ
Yes | ๊ด์ ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง |
| ์ปดํ์ผ/๋ฌธ๋ฒ ์๋ฌ | โ No | ๊ฐ๊ด์ ํด๊ฒฐ์ฑ
์กด์ฌ |
| ์ฝ๋ ์คํ์ผ | โ No | ktlint๊ฐ ์ฒ๋ฆฌ |
| ๋ช
ํํ ์คํ ์๊ตฌ์ฌํญ | โ No | ๊ตฌํ๋ง ํ๋ฉด ๋จ |
When to Use vs When NOT to Use
digraph council_decision {
rankdir=TB;
node [shape=box, style=rounded];
start [label="Decision needed?", shape=diamond];
objective [label="Objective answer exists?", shape=diamond];
skip [label="Skip council\nDecide directly"];
use [label="Use council"];
start -> objective [label="yes"];
start -> skip [label="no decision"];
objective -> skip [label="yes (compile error, lint)"];
objective -> use [label="no (trade-offs, judgment)"];
}
Use Council:
- Architectural trade-offs (monolith vs microservice, sync vs async)
- Subjective code quality decisions
- Multiple valid approaches exist
- Risk assessment disagreements
Skip Council:
- Compilation/syntax errors (objective fix)
- Code style (ktlint handles)
- Clear spec requirements (just implement)
- Time-critical simple fixes
Process
- Encounter uncertain decision point
- Call council with rich context + specific question
- Council members provide independent opinions (raw outputs)
- Collect:
bun "${CLAUDE_SKILL_DIR}/scripts/job.ts" collect JOB_DIR โ polls internally; re-call if not "done"
- Read each member's output file via the Read tool
5a. Completeness gate (Chairman judgment):
done does NOT mean semantically complete. A member can exit cleanly yet return a non-answer โ a plan, framing, or "I'll answer once X arrives" response. Read each member's content and judge: did it actually answer the asked question? Also check: is any member in awaiting_resume state? For any member that is awaiting_resume OR whose content is a non-answer (narrative-only / incomplete / waiting pattern), call resume-member BEFORE proceeding. clean is destructive (it deletes the jobDir, and resume-member <jobDir> requires that jobDir) โ so clean is ALWAYS the last step, only after completeness is confirmed.
- Synthesize (you as Chairman): raw outputs โ Advisory Format below
- Make informed decision based on advisory
- Cleanup:
bun "${CLAUDE_SKILL_DIR}/scripts/job.ts" clean JOB_DIR
Context Synchronization
Council members do not share the caller's session context. The caller must explicitly provide:
- Evaluation Criteria: Key principles from the review/validation rules
- Project Context: Conventions and patterns discovered during session
- Target Content: Code, spec, or artifact under review
- Specific Question: Points where judgment is needed
Include context richly. Council members should judge with the same context as the caller.
How to Call
Execute bun "${CLAUDE_SKILL_DIR}/scripts/job.ts" from the project root:
Note: Always write the council prompt in English for consistent cross-model communication.
Host Agent Context (Claude Code)
For programmatic use within Claude Code sessions:
CRITICAL: Always set timeout: 180000 on every Bash tool call.
Hard Constraints:
0. Each Bash call MUST run in FOREGROUND. All subcommands (start, collect) run synchronously. No background execution. No run_in_background.
- Do NOT use
sleep. The collect subcommand polls internally (5-second intervals, 150-second default timeout). External sleep is redundant and wastes time.
- Exactly-once job start. The
start subcommand runs ONCE. Polling (collect) may repeat. No job re-creation.
1. Start council (Bash, timeout: 180000)
PROMPT_FILE=$(mktemp)
cat > "$PROMPT_FILE" << 'PROMPT_EOF'
[Key principles - in English]
[Conventions and patterns - in English]
[Code or content under review]
[Specific points needing judgment - in English]
PROMPT_EOF
JOB_DIR=$(bun "${CLAUDE_SKILL_DIR}/scripts/job.ts" start --stdin < "$PROMPT_FILE")
Output: JOB_DIR path (one line on stdout).
Important: Write prompts in English for consistent cross-model communication.
2. Collect results (Bash, timeout: 180000)
collect polls internally every 5 seconds until all members complete or its internal timeout (default 150s) expires. No external sleep needed.
bun "${CLAUDE_SKILL_DIR}/scripts/job.ts" collect "$JOB_DIR"
- If response shows
"overallState": "done" โ proceed to Step 3.
- Otherwise (
"running", "queued", etc.) โ call collect again (same command, foreground, timeout: 180000).
3. Read raw outputs
Use the Read tool to read each member's outputFilePath from the manifest.
Only read entries where outputFilePath is non-null (null = infrastructure failure; see Degradation Policy).
4. Completeness gate โ resume-member if needed (Chairman judgment)
done does NOT mean semantically complete. Read each member's content. If any member is in awaiting_resume state OR returned a non-answer (narrative-only / incomplete / waiting pattern / "I'll answer once X arrives"), call resume-member before proceeding:
bun "${CLAUDE_SKILL_DIR}/scripts/job.ts" resume-member "$JOB_DIR" <name> "Please answer the question directly."
The prompt is written by the Chairman LLM for the specific situation. The example above is illustrative only.
Cap: max 3 resumes per member. After cap exhaustion โ partial-accept (include what was received) OR escalate the entire job. The Chairman judges which applies based on the situation.
WARNING: clean is destructive โ it deletes the jobDir permanently, and resume-member <jobDir> ... requires that jobDir to exist. clean is ALWAYS the last step, called only after completeness is confirmed for all members.
5. Synthesize (caller responsibility)
You as the Chairman must synthesize raw outputs into the Advisory Format (see below). The council does NOT produce a synthesized advisory automatically.
6. Cleanup (Bash, timeout: 180000)
bun "${CLAUDE_SKILL_DIR}/scripts/job.ts" clean "$JOB_DIR"
CLI Flags โ Chairman Inclusion
--include-chairman / --include-chairman=true: Force-include the chairman as a member regardless of config.
--exclude-chairman / --exclude-chairman=true: Force-exclude the chairman from members.
--exclude-chairman=false: Explicitly request the chairman BE included (value-respecting).
- Without any flag: falls back to
exclude_chairman_from_members in config. The semantic default is true (chairman excluded) when the config key is absent; shipped configs override this to false to include the chairman as a member.
Flag values are respected (value-respecting parsing). --exclude-chairman=false does NOT exclude the chairman โ it explicitly keeps them.
When both --include-chairman and --exclude-chairman are passed simultaneously, --exclude-chairman wins (override precedence).
Synthesis Protocol
When synthesizing raw outputs:
- Extract each reviewer's core position and key reasoning
- Overlapping positions โ Consensus
- Conflicting positions โ Divergence (report ALL, not majority)
- Unique concerns from any reviewer โ include in advisory
- On divergence: consult Model Characteristics table to inform weighting. Cite the table when weighting one model's opinion higher.
Model Characteristics (Synthesis Weighting)
Last verified: 2026-02 (review quarterly as models update)
When synthesizing, weight each model's opinion based on the question domain:
| Member | Primary Strengths | Weight Higher When |
|---|
| claude | Nuanced trade-off reasoning, instruction coherence across long context, risk/impact assessment | Architecture decisions, requirement ambiguity resolution, risk evaluation |
| codex | Code-level feasibility analysis, implementation cost/complexity estimation, API contract design | "Is this buildable?" questions, implementation approach choices, technical debt evaluation |
| glm | Independent reasoning from a different model lineage, alternative solution discovery, assumption challenges | Technology comparisons, "what are we missing?" questions, cross-checking consensus |
Application rules:
- On consensus: model strengths are irrelevant โ report agreement as-is
- On divergence: reference the table above. If the question is about implementation feasibility and codex disagrees with claude and glm, state: "Codex's position carries additional weight here as an implementation feasibility question (see Model Characteristics)"
- On contradiction with table: if a model gives a strong argument outside its listed strengths, the argument's quality overrides the table. Strengths are tie-breakers, not vetoes
- Never discard a model's opinion solely because the domain doesn't match its listed strengths
<Output_Format>
Advisory Output Format
Chairman synthesizes council opinions into:
## Council Advisory
### Consensus
[Points where council members agree]
### Divergence
[Points where opinions differ + summary of each position]
### Recommendation
[Synthesized advice. When model opinions diverge, note which model's expertise is most relevant to this domain and why โ referencing Model Characteristics table]
</Output_Format>
Result Utilization
Strong Consensus โ Adopt recommendation with confidence
Clear Divergence โ Options:
- Flag as "Clarification Needed"
- Choose majority position, noting dissent
- Use divergence to identify edge cases
Mixed Signals โ Weigh perspectives based on relevance
Partial Results โ Apply Degradation Policy. Synthesize from available responses, note missing perspectives.
Common Mistakes
| Mistake | Why It's Wrong | Fix |
|---|
| ์ปดํ์ผ ์๋ฌ์ council ํธ์ถ | ๊ฐ๊ด์ ํด๊ฒฐ์ฑ
์์, ์๊ฐ ๋ญ๋น | ์ง์ ์์ |
| context ์์ด ์ง๋ฌธ๋ง ์ ๋ฌ | ๋งฅ๋ฝ ์์ด ํ๋จ ๋ถ๊ฐ | ํ๊ฐ ๊ธฐ์ค, ํ๋ก์ ํธ ์ปจํ
์คํธ ํฌํจ |
| council ๊ฒฐ์ ์ ๊ทธ๋๋ก ์์ฉ | council์ ์๋ฌธ, ๊ฒฐ์ ์ ํธ์ถ์ | ์๊ฒฌ ์ฐธ๊ณ ํ ์ง์ ๊ฒฐ์ |
| ๋ชจ๋ ๊ฒฐ์ ์ council ํธ์ถ | ๋ถํ์ํ ์ค๋ฒํค๋ | ํธ๋ ์ด๋์คํ/์ฃผ๊ด์ ํ๋จ์๋ง ์ฌ์ฉ |
| ํ๊ตญ์ด๋ก council ํธ์ถ | ๋ชจ๋ธ ๊ฐ ์ผ๊ด์ฑ ์ ํ | ์์ด๋ก ํ๋กฌํํธ ์์ฑ |
Red Flags - STOP Before Calling Council
| Red Flag | Reality |
|---|
| "๋นจ๋ฆฌ ๊ฒฐ์ ํด์ผ ํด์ council ์๋ต" | ์ค์ํ ๊ฒฐ์ ์ผ์๋ก ๋ค์ํ ๊ด์ ํ์ |
| "๋ด ํ๋จ์ด ๋ง์ผ๋๊น ํ์ธ๋ง" | ํ์ธ ํธํฅ - council์ ๋ฐ๋ก ์ ๋ค์ผ๋ ค๊ณ ์ฐ๋ ๊ฒ |
| "์๋ฌ ๋ฉ์์ง๊ฐ ๋ญ์ง ๋ชจ๋ฅด๊ฒ ์ด์" | ๊ฐ๊ด์ ๋ฌธ์ ๋ council ๋์ ์๋ |
| "council์ด ๊ฒฐ์ ํด์ค ๊ฑฐ์ผ" | Council์ ์กฐ์ธ, ๊ฒฐ์ ์ฑ
์์ ํธ์ถ์ |
Degradation Policy
Council members may fail due to CLI unavailability, timeout, or errors. This is NOT the same as quorum logic.
Critical distinction:
- PROHIBITED quorum logic: "2/3 responded, that's enough, skip the third" โ this is giving up on a working member
- PERMITTED degradation: "2/3 responded, third member's CLI crashed (missing_cli/timed_out/error state)" โ this is handling infrastructure failure
Decision tree:
overallState === 'done' AND all members have terminal states?
- Check each member's state and output content:
missing_cli โ CLI not installed. Degradation applies (infra failure โ unrecoverable).
timed_out โ CLI exceeded timeout. Degradation applies (infra failure โ unrecoverable).
error (non-zero exit) โ CLI failed. Degradation applies (infra failure โ unrecoverable).
canceled โ Manually stopped. Degradation applies (infra failure โ unrecoverable).
awaiting_resume โ Member paused mid-turn waiting for continuation. Recoverable โ call resume-member (see completeness gate above). This is distinct from infra failure; the member is alive and can continue.
done but content is a non-answer โ Member exited cleanly but returned framing / a plan / a waiting pattern instead of actually answering the question. Recoverable โ call resume-member. The runner marks it done based on exit reason, not semantic completeness; the Chairman judges semantic completeness by reading the content.
- After all recoverable states are resolved (or resume cap exhausted), synthesize from members with substantive answers.
If start exits non-zero or returns an empty $JOB_DIR, skip Steps 2โ4 (no collect/clean) and fall back to in-session advisory: READ prompts/default.md and apply the framework defined there IN-SESSION. You become the in-session advisor for the remainder of this skill invocation โ no manifest exists to read. When the cause is the no-members guard โ stderr contains to dispatch โ enter the fallback silently (expected path: empty/all-filtered members config). For any other non-zero exit (an unexpected failure โ disk/permission, spawn error, a bug), first surface the failure reason (include the stderr line) in your output, then proceed with the in-session fallback.
Synthesis by response count:
| Responses | Action | Output Modification |
|---|
| 3/3 | Full synthesis | Standard advisory format |
| 2/3 | Partial synthesis | Prepend: "โ ๏ธ Partial advisory (2/3 respondents). [failed_member] unavailable: [state]. The following synthesis lacks [failed_member]'s perspective ([see Model Characteristics for what this model typically contributes])." |
| 1/3 | Single response report | Prepend: "โ ๏ธ Limited advisory (1/3 respondents). [failed_members] unavailable. Presenting single response from [available_member] without synthesis. Treat as individual opinion, not council advisory." |
| 0/3 | In-session fallback | READ prompts/default.md and deliver in-session advisory. When all members failed due to infrastructure errors (not the no-members guard), surface a one-line failure summary before proceeding. |
Partial synthesis rules:
- Use "partial consensus (N/3 respondents)" when reporting agreement
- In Divergence section, note: "Note: [missing_member]'s perspective is absent. Based on Model Characteristics, this model typically contributes [strength area] โ this gap may affect the advisory's completeness in that domain."
- Do NOT extrapolate what the missing model "would have said"