From john-skills
Spawns an Opus sub-agent for multi-turn adversarial debate to pressure-test plans, designs, or decisions. Use for second opinions or sanity checks.
How this skill is triggered — by the user, by Claude, or both
Slash command
/john-skills:phone-a-friendThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
A consultation workflow where the primary Claude Code agent pauses its work, assembles a synopsis of the current situation, and engages an Opus sub-agent ("the friend") in a back-and-forth debate. The two agents argue, critique, research, and refine until they reach one of two valid terminal states: **genuine consensus** or **a clean agree-to-disagree**. At that point the primary reports back t...
A consultation workflow where the primary Claude Code agent pauses its work, assembles a synopsis of the current situation, and engages an Opus sub-agent ("the friend") in a back-and-forth debate. The two agents argue, critique, research, and refine until they reach one of two valid terminal states: genuine consensus or a clean agree-to-disagree. At that point the primary reports back to the user.
There is no hard iteration cap. The goal is a real outcome, not a turn counter. If the user is not satisfied with the report, they can send the debate back for another round — the jury-room rule (Phase 7).
This is NOT a one-shot review. It is a multi-turn dialogue where both sides push back, ask questions, update their views, and — when they need information only the user has — pause to ask the user directly (Phase 4b).
The user will typically say something like "phone a friend", "get a second opinion on this", "sanity check this", or "debate this with another model". Do not invoke this skill proactively — wait for the explicit ask.
Follow these phases in order.
Before spinning up the friend, confirm in one sentence what the friend should debate. Offer a default based on current session context, e.g. "Phoning a friend to pressure-test the migration plan in db/schema.ts — want to narrow the question, or go broad?" Wait for the user's OK or redirection. Keep this exchange to one round; do not interrogate.
Assemble a structured synopsis. The synopsis is a self-contained briefing — the friend has zero prior context from the session. Include:
src/auth/* handles the same case", "web-search current best practices for Y as of 2026". The friend decides for itself whether to act on these.Keep the synopsis tight but complete. Aim for enough signal that the friend can form a real opinion without needing to ask clarifying questions on turn 1.
Use the Agent tool with these exact settings:
subagent_type: "general-purpose" (gives the friend access to all tools: Read, Grep, Glob, WebSearch, WebFetch, Bash, Edit, Write, etc.)model: "opus"description: "Phone a friend: <short topic>"prompt: the synopsis, framed as below.The prompt MUST:
ultrathink on its own line to trigger maximum extended thinking budget.git commit, no git push, no rm, no mv, no touch, no package installs, no migrations, no API calls that write, no config changes). Your tool use is strictly read-only: reading files, grepping, globbing, web search, web fetch, and read-only shell commands (ls, cat, git log, git diff, git status, etc.) are fine. If you believe an action should be taken, describe it in your response and let the primary agent carry it out after the user approves. Your job is to think, debate, and advise — never to act."Capture the Agent tool call's returned agent ID (the opaque hex handle, e.g. aac8d55b956cda1a4) and save it. This ID is the handle for every follow-up turn via SendMessage. Use the ID, never the name, for all subsequent SendMessage calls — see the addressing note below.
Why ID, not name — the idle-agent gotcha. A spawned agent is only addressable by name while it is actively running a task. Between debate turns the friend finishes its turn and goes idle, which unregisters its name. A
SendMessage({to: "<name>"})at that point fails with "No agent named '…' is currently addressable." The agent ID always works: the harness resumes the idle agent from its transcript. So always address the friend by its saved ID.Expected, not an error: when you SendMessage to an idle friend by ID, you may see "Agent '' had no active task; resumed from transcript in the background with your message. You'll be notified when it finishes." This is normal — the friend was idle between turns and is now processing your message. The reply arrives asynchronously via notification; wait for it before forming the next turn. Do not spawn a new Agent in response to this message.
Print the friend's Claude session ID to the user immediately after spawning, on its own line, e.g. Friend's Claude session ID: <id>. This lets the user (or a client wrapping this session) decide whether to store it somewhere for later reference or resumption. Surface it plainly; do not bury it in prose.
After turn 1, enter a dialogue loop. Each iteration:
to set to the friend's agent ID from Phase 3 — never its name (the name unregisters once the friend goes idle between turns; see the addressing note in Phase 3). Do NOT call Agent again — that would start a fresh agent with no memory of the prior turns. Always SendMessage by ID to continue. If a SendMessage reports the friend was idle and "resumed from transcript in the background," that is expected — wait for the friend's reply to arrive before proceeding.No hard iteration cap. The task is to reach a real outcome — either a genuine consensus or a clean agree-to-disagree — not to hit a turn counter. Both agents should be explicitly told: "Your job is to reach consensus or to cleanly agree to disagree. Do not stop debating just because you are tired of debating. Do not force agreement to end the dialogue. When you have genuinely exhausted the productive arguments, say so explicitly."
That said, the primary agent should use judgment about when enough is enough. Use these heuristics:
If at any point either agent is blocked by a question only the human can answer — missing context, ambiguous requirements, a values/preference call, information that is not in the codebase or on the web — pause the dialogue and surface the question to the user.
What qualifies as a human-only question:
What does NOT qualify (do not escalate these — the agents should handle them):
How to escalate:
The primary may also escalate its own questions the same way. Do not force the friend to be the one who asks.
Batch questions when possible. If the friend raises three clarifying questions at once, surface all three in a single escalation rather than one at a time.
Early stop conditions:
There are two valid terminal states. Both are acceptable outcomes to report.
Consensus requires all of these, explicitly:
Before declaring consensus, state internally: "The friend and I now agree on X, Y, Z. Disagreements remaining: none / [list]." If the list is non-empty, it is not consensus.
Do not confuse "the friend stopped objecting" with consensus. Politeness is not agreement. Explicitly ask the friend "Do you agree with the following conclusion: [conclusion]? If not, what would you change?" before calling it done.
Agree-to-disagree is equally valid and requires:
Before declaring agree-to-disagree, ask the friend explicitly: "We seem to have reached a genuine disagreement. Can you state my position fairly? And do you agree that the remaining gap is a real difference of view rather than missing information?" Only accept agree-to-disagree if the friend confirms.
Return control to the user with a report containing:
Keep the report scannable. Bullets over prose. The user should be able to read it in under a minute and decide whether to proceed, redirect, or dig in.
After delivering the report, wait for the user before acting on the conclusion. The consensus is a recommendation, not a mandate.
A stopped debate is not necessarily a finished debate. If the user reads the report and wants more — "go debate this more", "that's not enough, dig deeper", "keep arguing", "I'm not satisfied, send them back" — treat this like a judge sending a deadlocked jury back to the jury room.
To resume:
to set to the friend's original agent ID (saved from Phase 3 and reported in Phase 6) — not its name. By the time the user sends the jury back, the friend has long been idle and its name is unregistered; only the ID resolves. Do not spawn a new Agent — a fresh agent has no memory of the prior debate. Expect the "resumed from transcript in the background" message here (the friend has been idle since the last report); wait for its reply.If the agent ID from the prior run is no longer valid (the session has been compacted or the agent was cleaned up), the debate must be restarted fresh. In that case, include a summary of the prior debate's key points in the new synopsis so the new friend starts with context — but flag to the user that this is a fresh debate, not a continuation.
ls, cat, git log, git diff, git status, etc.). Disallowed: Edit, Write, NotebookEdit, and any Bash command that changes state on disk, in version control, in a database, or over the network. State this constraint explicitly in the turn-1 prompt (Phase 3) and reinforce it if the friend ever proposes to take an action itself — tell it to describe the action and the primary will carry it out after the user approves. If the friend takes a mutating action despite this instruction, immediately report it to the user.npx claudepluginhub jbdamask/john-claude-skills --plugin john-skillsFacilitates structured multi-provider AI debates between Claude and available advisors for critical decisions. Dispatches real providers via orchestrate.sh for diverse perspectives.
Orchestrates a panel of external AI models (Gemini, Codex, Qwen, GLM, Kimi) for consensus-driven reviews of code, architecture, and plans. Invoke via /council or explicit request.
Spawns 2-3 AI agent personas (reviewer, fixer, architect) to debate a topic from different perspectives. Useful for exploring tradeoffs and getting multiple expert viewpoints on a question without committing to code changes.