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".
Scanned 6/8/2026
Install via CLI
openskills install toongri/oh-my-toong-playground---
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".
---
<Role>
# 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.
</Role>
## Quick Reference
| 상황 | Council 필요? | 이유 |
|------|---------------|------|
| 아키텍처 트레이드오프 | ✅ Yes | 다양한 관점 필요 |
| 주관적 코드 품질 판단 | ✅ Yes | 명확한 정답 없음 |
| 리스크 평가 불일치 | ✅ Yes | 관점에 따라 달라짐 |
| 컴파일/문법 에러 | ❌ No | 객관적 해결책 존재 |
| 코드 스타일 | ❌ No | ktlint가 처리 |
| 명확한 스펙 요구사항 | ❌ No | 구현만 하면 됨 |
## When to Use vs When NOT to Use
```dot
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
1. Encounter uncertain decision point
2. Call council with rich context + specific question
3. Council members provide independent opinions (raw outputs)
4. **Collect**: `bun "${CLAUDE_SKILL_DIR}/scripts/job.ts" collect JOB_DIR` — polls internally; re-call if not `"done"`
5. **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.
6. **Synthesize** (you as Chairman): raw outputs → Advisory Format below
7. Make informed decision based on advisory
8. **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`.
1. **Do NOT use `sleep`.** The `collect` subcommand polls internally (5-second intervals, 150-second default timeout). External sleep is redundant and wastes time.
2. **Exactly-once job start.** The `start` subcommand runs ONCE. Polling (`collect`) may repeat. No job re-creation.
**1. Start council (Bash, timeout: 180000)**
```bash
PROMPT_FILE=$(mktemp)
cat > "$PROMPT_FILE" << 'PROMPT_EOF'
## Evaluation Criteria
[Key principles - in English]
## Project Context
[Conventions and patterns - in English]
## Target
[Code or content under review]
## Question
[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.
```bash
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:
```bash
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)**
```bash
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:
1. Extract each reviewer's core position and key reasoning
2. Overlapping positions → Consensus
3. Conflicting positions → Divergence (report ALL, not majority)
4. Unique concerns from any reviewer → include in advisory
5. 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 |
| gemini | Broad factual grounding, alternative solution discovery, edge case identification | Technology comparisons, "what are we missing?" questions, assumption challenges |
**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 gemini, 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:
```markdown
## 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:**
1. `overallState === 'done'` AND all members have terminal states?
2. 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.
3. 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"
No comments yet. Be the first to comment!