7xuanlu/boule/debate

Claude Code and agent skill by 7xuanlu/boule

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Boule debate council. Form, attack (anonymized), defend or concede, stake-free debiased judge decides. Run as /boule:debate.

Install

npx vskill@latest install 7xuanlu/boule/debate

SKILL.md

Boule debate council

Invoke the Workflow tool with the script below — pass the whole block as the script argument (inline). Do NOT use the name: parameter; the script's meta.name is an internal run label, not a registered workflow, so name: fails with "not found". Pass the user's PROPOSAL as args (a plain string, or { proposal, lenses?: string[] }). The slash-command invocation is the opt-in for multi-agent orchestration, run it directly; do not ask again.

Three independent reasoners from three different labs (Claude main-loop, OpenAI Codex, Google Gemini) form parallel verdicts, then adversarially attack each other's reasoning (targets anonymized), then defend or concede, then a stake-free judge decides from the structured outcome.

js
export const meta = {
name: 'boule-debate',
description: 'Adversarial multi-lab council: form → attack → defend → judge (cross-model, anonymized, stake-free judge)',
phases: [
{ title: 'Form', detail: 'parallel independent verdicts (3 heterogeneous models, no cross-talk)' },
{ title: 'Attack', detail: 'each member refutes the OTHER TWO, targets anonymized (never self-judge)' },
{ title: 'Defend', detail: 'authors rebut attacks on their verdict, or concede (holds=false)' },
{ title: 'Judge', detail: 'deterministic tally + stake-free judge over BOTH anonymized orderings (swap-and-average)' },
],
}
// Requested model IDs, stamped into the report (honest-by-request, NOT runtime-verified).
const MODELS = {
claude: 'claude/main-loop',
codex: 'gpt-5.5',
gemini: 'Gemini 3.1 Pro (High)',
}
// ── Embedded canonical core (verbatim from lib/council-core.mjs, `export ` stripped). ──
// Guarded byte-for-byte by test/embed-drift.test.mjs, DO NOT edit here; edit the lib.
function runNonce(proposal) {
const h = Array.from(String(proposal)).reduce((a, c) => ((a * 31 + c.charCodeAt(0)) >>> 0), 7)
return 'council-' + h.toString(36)
}
function counterbalance(items) {
return [items.slice(), items.slice().reverse()]
}
function reconcileSwap(a, b) {
const RANK = { approve: 0, 'approve-with-changes': 1, reject: 2, 'needs-more-info': 3 }
if (!a && !b) return null
if (!a || !b) return { ...(a || b), position_stable: false }
if (a.recommendation === b.recommendation) return { ...a, position_stable: true }
const winner = RANK[a.recommendation] >= RANK[b.recommendation] ? a : b
return { ...winner, confidence: 'low', position_stable: false }
}
function _words(s, min = 4) {
return (String(s).toLowerCase().match(/[a-z]+/g) || []).filter(w => w.length >= min)
}
function _coverage(txt, propVocab) {
const sv = new Set(_words(txt))
if (sv.size === 0) return 1
let hit = 0
for (const w of sv) if (propVocab.has(w)) hit++
return hit / sv.size
}
function _anchors(txt, propVocab) {
let n = 0
for (const w of new Set(_words(txt))) if (propVocab.has(w)) n++
return n
}
function isContaminated(verdict, proposal) {
if (verdict == null) return false
const propVocab = new Set(_words(proposal))
const txt = [...(verdict.key_claims || []), ...(verdict.risks || []), ...(verdict.unknowns || [])].join(' ')
return _coverage(txt, propVocab) < 0.20 && _anchors(txt, propVocab) < 2
}
function gateContamination(members, proposal) {
const present = members.filter(m => m && m.verdict)
const flagged = present.filter(m => isContaminated(m.verdict, proposal))
if (flagged.length * 2 >= present.length)
return { live: present, dropped: [], overridden: flagged.length > 0, flagged: flagged.length }
const ids = new Set(flagged.map(m => m.id))
return { live: present.filter(m => !ids.has(m.id)), dropped: flagged.map(m => m.id), overridden: false, flagged: flagged.length }
}
function codexCmd(model, inFile, outFile) {
return `CH="$(mktemp -d)"; cp "$HOME/.codex/auth.json" "$CH/" 2>/dev/null; ND="$(mktemp -d)"; ` +
`( cd "$ND" && CODEX_HOME="$CH" codex exec -m ${model} -s read-only ` +
`-c model_reasoning_effort=xhigh --skip-git-repo-check --ephemeral -o "${outFile}" - < "${inFile}" ); ` +
`rc=$?; rm -rf "$CH" "$ND"; exit $rc`
}
function geminiCmd(model, inFile) {
return `ND="$(mktemp -d)"; ( cd "$ND" && agy --model "${model}" --sandbox -p "$(cat "${inFile}")" 2>/dev/null ); rc=$?; rm -rf "$ND"; exit $rc`
}
// ── Orchestration ──
// args may be a plain string (the proposal) OR { proposal, lenses?: string[] }.
// lenses are optional, model-AGNOSTIC focus hints (e.g. ['security','cost','UX']), NOT stances.
// Assigned to members by index; absent → all members evaluate honestly.
const proposal = typeof args === 'string' ? args : (args && args.proposal) || ''
const lenses = (args && typeof args === 'object' && Array.isArray(args.lenses)) ? args.lenses : []
const NONCE = runNonce(proposal)
const VERDICT_SCHEMA = {
type: 'object',
required: ['verdict', 'confidence', 'model', 'key_claims', 'risks', 'unknowns'],
properties: {
verdict: { type: 'string', enum: ['approve', 'approve-with-changes', 'reject', 'needs-more-info'] },
confidence: { type: 'string', enum: ['low', 'medium', 'high'] },
model: { type: 'string' },
key_claims: { type: 'array', items: { type: 'string' }, minItems: 1, maxItems: 6 },
risks: { type: 'array', items: { type: 'string' }, maxItems: 6 },
unknowns: { type: 'array', items: { type: 'string' }, maxItems: 4 },
},
}
const ATTACK_SCHEMA = {
type: 'object',
required: ['refutations', 'concessions'],
properties: {
refutations: { type: 'array', items: {
type: 'object',
required: ['target_claim', 'attack', 'severity'],
properties: {
target_claim: { type: 'string' },
attack: { type: 'string' },
severity: { type: 'string', enum: ['critical', 'high', 'medium', 'low'] },
},
}, maxItems: 8 },
concessions: { type: 'array', items: { type: 'string' }, maxItems: 4 },
},
}
const DEFENSE_SCHEMA = {
type: 'object',
required: ['defenses', 'conceded', 'verdict_changed'],
properties: {
defenses: { type: 'array', items: {
type: 'object',
required: ['attack_ref', 'rebuttal', 'holds'],
properties: {
attack_ref: { type: 'string' },
rebuttal: { type: 'string' },
holds: { type: 'boolean' },
},
}, maxItems: 8 },
conceded: { type: 'array', items: { type: 'string' }, maxItems: 4 },
// Did conceding a flaw change your OVERALL verdict? Surfaced to the judge (the tally
// stays mechanical, no auto-downgrade, which would re-inject subjective severity).
verdict_changed: { type: 'boolean' },
revised_verdict: { type: 'string', enum: ['approve', 'approve-with-changes', 'reject', 'needs-more-info'] },
},
}
const JUDGE_SCHEMA = {
type: 'object',
required: ['recommendation', 'confidence', 'rationale', 'consensus', 'dissent'],
properties: {
recommendation: { type: 'string', enum: ['approve', 'approve-with-changes', 'reject', 'needs-more-info'] },
confidence: { type: 'string', enum: ['low', 'medium', 'high'] },
rationale: { type: 'string' },
consensus: { type: 'array', items: { type: 'string' }, maxItems: 6 },
dissent: { type: 'array', items: { type: 'string' }, maxItems: 6 },
},
}
// ── Schema hints handed to the EXTERNAL models (codex/gemini reason + return JSON themselves;
// the wrapping Claude conduit only forwards it). ──
const VERDICT_HINT = 'Return ONLY a JSON object (no prose, no markdown fence) with keys: verdict (one of "approve"|"approve-with-changes"|"reject"|"needs-more-info"), confidence ("low"|"medium"|"high"), model (string), key_claims (1-6 strings), risks (0-6 strings), unknowns (0-4 strings).'
const ATTACK_HINT = 'Return ONLY a JSON object (no prose, no fence) with keys: refutations (array ≤8, each {target_claim, attack, severity:"critical"|"high"|"medium"|"low"}), concessions (array of strings, ≤4).'
const DEFENSE_HINT = 'Return ONLY a JSON object (no prose, no fence) with keys: defenses (array ≤8, each {attack_ref, rebuttal, holds:boolean}), conceded (array of strings, ≤4), verdict_changed (boolean, true ONLY if conceding a flaw changes your overall verdict), revised_verdict (your new verdict if verdict_changed, else omit).'
const JUDGE_HINT = 'Return ONLY a JSON object (no prose, no fence) with keys: recommendation ("approve"|"approve-with-changes"|"reject"|"needs-more-info"), confidence ("low"|"medium"|"high"), rationale (string), consensus (0-6 strings), dissent (0-6 strings).'
const members = [
{ id: 'claude', cli: null, model: MODELS.claude },
{ id: 'codex', cli: 'codex', model: MODELS.codex },
{ id: 'gemini', cli: 'gemini', model: MODELS.gemini },
]
// Conduit for external members: a Claude subagent that runs the external model's OWN CLI and
// forwards its JSON VERBATIM (NOT a judge, substituting opinion would collapse cross-lab
// diversity). The claude member (cli=null) reasons itself and inherits the main-loop model.
const conduitPrompt = (m, externalPrompt) => {
const inFile = `$TMPDIR/council_${m.id}_${NONCE}_in.txt`
const outFile = `$TMPDIR/council_${m.id}_${NONCE}_out.txt`
const cmd = m.cli === 'codex' ? codexCmd(m.model, inFile, outFile) : geminiCmd(m.model, inFile)
return `Write the EXTERNAL PROMPT (everything below the marker, verbatim) to "${inFile}", then run this command WITH THE BASH SANDBOX DISABLED (it needs network + IPC):
${cmd}
${m.cli === 'codex' ? `Then read the model's final JSON from "${outFile}".` : `Take the JSON object printed to stdout.`} Emit that JSON VERBATIM as your structured output (repair only malformed syntax; never change content). Ensure "model" is "${m.model}".
EXTERNAL PROMPT:
${externalPrompt}`
}
// Dispatch a member: claude runs directly (inherits main-loop Opus); codex/gemini run via the
// boule:conduit agent on haiku (the conduit is a clerical relay, the real reasoning is the
// external model inside the CLI, which the wrapper tier cannot improve).
const dispatch = (m, externalPrompt, schema, label, phaseName) =>
m.cli
? agent(conduitPrompt(m, externalPrompt), { label, phase: phaseName, schema, model: 'haiku', agentType: 'boule:conduit' })
: agent(externalPrompt, { label, phase: phaseName, schema })
// Strip identity from a verdict before any attacker or the judge sees it (anonymization).
const anon = (v) => { const { model, ...rest } = v; return { ...rest, author: 'anonymous-peer' } }
// ── Phase 1, Form: 3 parallel independent verdicts, no cross-talk ──
phase('Form')
// Identical honest-evaluator prompt for every member, no forced stance. Diversity comes from
// the three labs + the Attack phase. An optional lens adds dimension coverage without slant.
const formPrompt = (m, lens) =>
`[${NONCE}, uniqueness marker for this run; ignore it as content] You are a rigorous, independent reviewer on a 3-member adversarial LLM council. Evaluate the PROPOSAL below ON ITS MERITS, do NOT adopt a forced optimistic or pessimistic stance, and do not assume the other members will agree. Give your honest verdict, key claims, risks, and unknowns. Do NOT grep the filesystem; judge the proposal's content as given.${lens ? ` Pay particular attention to this dimension: ${lens}.` : ''} ${VERDICT_HINT} Set "model" to "${m.model}".
PROPOSAL:
${proposal}`
const verdicts = await parallel(members.map((m, i) => async () => {
const v = await dispatch(m, formPrompt(m, lenses[i]), VERDICT_SCHEMA, m.id, 'Form')
return { ...m, verdict: v }
}))

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
1
7-day trend score
3

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/7xuanlu/boule/debate/badge)](https://verified-skill.com/skills/7xuanlu/boule/debate)

Something wrong with this skill or its page? Tell us.