Skip to content
← Log
NiraNexus

NiraNexus Log

The operational record of building a governance-first AI platform.

Log #5

Three Rounds, One Verdict

July 21, 2026·Architecture·9 min read
Rakesh MaheswaranLogged by Rakesh Maheswaran, Founder, NiraNexus-OS

In brief

The Model Council runs a three-round adversarial pipeline. It does not vote. It cross-examines. Opening Statements produce four independent analyses with no cross-model context. Cross-Examination pairs models against specific peers. They find factual errors, logical gaps, missing perspectives. The orchestrator evaluates whether productive tension remains and gates Round 3 with a single string comparison: only CONTINUE proceeds. Claims that survive all three rounds enter the verdict with provenance labels: VERIFIED, DISPUTED, UNVERIFIED. Dissent is preserved as structured evidence, not buried. The pipeline is transparent adversarial deliberation, not infallible arbitration. Traced through a real Council deliberation with actual source code from debate-engine.ts and prompts.ts.

Contents


Key Takeaways

  • The Model Council runs a three-round adversarial pipeline. It does not vote. It cross-examines
  • Opening Statements: four independent analyses with no cross-model context. Each model receives a cognitive persona injected directly into its system prompt
  • Cross-Examination: shuffled pairings force each model to critique a specific peer. Factual errors, logical gaps, missing perspectives. Specific, targeted criticism
  • The orchestrator gates Round 3 with a single string comparison. Only CONTINUE proceeds. CONVERGED, DEADLOCKED, or anything else triggers synthesis
  • Claims that survive all three rounds enter the verdict with provenance labels: VERIFIED, DISPUTED, UNVERIFIED. Dissent is preserved as structured evidence, not buried

What actually happens in each round?

Get new entries by email

One or two emails a week. New Log entries only. No noise, unsubscribe any time.

Take a real deliberation. The prompt: "Review this system design. Identify failure modes, scaling bottlenecks, and missing operational guardrails." The user didn't attach a design. They left the placeholder [describe] in the input box. The Council ran anyway. The result is a mess, but it's instructive. Watching the engine process an underspecified prompt reveals the pipeline more clearly than a well-formed question ever could.

Round 1. Opening Statements. Four models receive the same prompt, independently. Each gets a cognitive persona assigned at engine start:

GPT-5.5 Pro  → The Synthesizer: Find patterns, use analogical reasoning
DeepSeek R1  → The Epistemologist: Distinguish known from assumed
Claude Sonnet → The Contrarian: Challenge consensus, find counterexamples  
Qwen 3.7 Max → The Systems Thinker: Second-order effects, feedback loops

These are not decorative labels. They are system prompts. The engine injects them directly into the model's instruction context. Each model sees the question, sees its role, and generates independently. No model knows what any other model wrote.

The code that runs this has a single yield point:

// src/lib/debate-engine.ts. Round 1: all models in parallel, no cross-talk
const round1Results = await Promise.allSettled(
  modelsWithPersonas.map(async (model) => {
    const systemPrompt = buildRound1Prompt(model, effectivePrompt);
    const result = await sendModelTokens(model.openRouterId, 
      [{ role: 'user', content: systemPrompt }], timeoutMs, onEvent, ...);
    // emit + persist response, accumulate citations
    return response;
  })
);

Promise.allSettled runs all four models independently. If one fails, the other three continue. No shared context. Source: MDN: Promise.allSettled. The engine fires them all at once and waits. If every model fails, the deliberation halts immediately. No point running cross-examination with nothing to cross-examine.

What the models actually produced on the [describe] prompt: GPT-5.5 Pro politely asked for the design description. R1 hallucinated a NiraNexus tech stack and ran analysis against it. Sonnet correctly observed that analyzing a missing artifact guarantees fabrication, then contradicted itself by importing the NiraNexus execution context. Qwen identified real failure modes (write amplification, quota race conditions) grounded in the actual platform.

Four opening statements. Three useful. One empty. The engine does not grade them. It stores them and moves to the next round.

Round 2. Cross-Examination. Models are paired. Each critiques a specific peer's Round 1 output. The pairings shuffle every debate:

const pairings = shufflePairings(modelsWithPersonas);
// GPT-5.5 critiques R1, R1 critiques Sonnet, 
// Sonnet critiques Qwen, Qwen critiques GPT-5.5

Each model receives its target's full Round 1 response and a critique prompt. The instruction: find factual errors, logical gaps, and missing perspectives. Not opinion. Specific, targeted criticism.

This is where the pipeline produces its most valuable output. Qwen accused Sonnet of the exact error Sonnet warned against: "hallucinating specifics onto a blank canvas." R1 pointed out that Qwen's apocalyptic connection exhaustion analysis ignored Supabase's PgBouncer pooling layer. Sonnet caught R1 inventing failure modes from nowhere while simultaneously disclaiming fabrication.

The cross-examination loop takes what would be four siloed analyses and forces them into direct confrontation. Positions that survive Round 2 carry more weight because they were tested. Positions that fold, like R1's self-contradiction about hallucinating while hallucinating, are flagged for the verdict.

Round 3. Rebuttal (conditional). After Round 2 completes, the orchestrator runs a convergence check. Opus 4.8 reads every response and decides: continue or synthesise.

If the orchestrator returns CONTINUE, all four models receive the full debate transcript and write rebuttals. They address challenges to their original positions, concede where appropriate, sharpen where evidence supports them. If it returns SYNTHESIZE, the engine skips directly to verdict generation. Roughly half of standard debates proceed to Round 3. Document-grounded or MCP-augmented debates that run in compact mode (2 rounds) never reach it.

Why three rounds, not two or four?

Two rounds produces challenged but unrefined positions. A claim gets attacked in cross-examination, the original model never responds. The reader doesn't know whether the challenge was valid or the defence would have held. The pipeline produces noise, not signal.

Three rounds forces each attack to face a rebuttal. Weak claims are abandoned. Strong claims survive with evidence. The final synthesis works with tested, not raw, material.

Four rounds runs into diminishing returns. Models recycle arguments. New content falls below 10% of total output. The cost scales linearly while insight plateaus. Three rounds is the minimum for this dynamic to complete, confirmed across double-digit deliberation batches. This is not an arbitrary choice.

How does the orchestrator decide when to stop?

The orchestrator is a separate model. Not a timer. Not a quorum count. A model reading the complete debate transcript and answering a structured prompt:

After 2 rounds of debate, evaluate whether to continue.

Round 1 responses covered these perspectives. Round 2 critiques revealed:
[Summaries of cross-examination exchanges]

Respond with EXACTLY one word:
- "CONTINUE" if productive tension remains
- "CONVERGED" if substantial agreement reached
- "DEADLOCKED" if positions fixed with no new arguments

This is the actual prompt from src/lib/prompts.ts. The orchestrator can end a debate after Round 2 if positions are stable. It can force Round 3 if material disagreements persist. The code that evaluates its response:

const convergenceVerdict = await sendModelTokens(ORCHESTRATOR_MODEL, 
  [{ role: 'user', content: buildConvergenceCheckPrompt(r1Responses, r2Responses) }],
  timeoutMs, onEvent, ...);

// Productive tension check: Only CONTINUE forces a 3rd round.
// Everything else prioritizes synthesis speed: CONVERGED, DEADLOCKED, or
// any response that isn't exactly CONTINUE skips straight to verdict generation.
if (convergenceVerdict.content.trim().toUpperCase() === 'CONTINUE' && roundNum < maxRounds) {
  roundNum = 3;
  // Run Rebuttal round...
} else {
  // Skip to synthesis — no further rounds
}

The engine treats CONVERGED, DEADLOCKED, or any response that isn't exactly CONTINUE as a signal to synthesise. No ambiguity. No scoring. A single string comparison gates a round of deliberation that costs four model calls.

The orchestrator is not a judge. It does not evaluate correctness. It evaluates whether the deliberation has produced diminishing returns. Two rounds of genuine debate with exhausted positions beat three rounds of recycled arguments. The prompt reflects this. The decision gate is about productivity, not quality.

Convene a Council deliberation to see the three-round pipeline in operation. Every deliberation produces a public evidence record.

What survives and what gets discarded?

The synthesis step produces claims. Not all of them survive. The claim lifecycle in a 3-round deliberation follows a predictable pattern:

Claim Lifecycle: from proposed through challenged to refined

A proposed claim that no model challenges enters the verdict directly. A claim with one dissenter carries a DISPUTED label but is preserved. The dissent is not buried. A claim that the proposer retracts under cross-examination is discarded entirely. The verdict includes both surviving claims and surviving dissent, assigned to specific source models.

Disputed status is the operational output of the dissent preservation protocol. A claim faced resistance but remained standing. Dissent is the panel position itself. A claim can be DISPUTED without dissent being unanimous, and dissent can exist on claims that ultimately appear VERIFIED in the verdict.

This is the pipeline's core differentiation from averaging or voting architectures. Disagreement is structured evidence, not noise to be filtered out. The evidence basis labels (VERIFIED, DISPUTED, UNVERIFIED) come from this lifecycle. This is the architectural distinction between adversarial deliberation and model voting — cross-examination produces falsifiable claims, not correlated averages.

Where does this architecture fail?

Honest limitations. Three are documented and mechanically mitigated but still real.

Correlated training data. All four models are frontier LLMs trained on overlapping internet-scale corpora. When all models agree on a factual claim, that agreement may reflect shared training data, not independent verification. The Consilium Protocol independently confirmed this. RLHF alignment creates measurable, domain-specific epistemic blind spots. The MCP research pipeline partially addresses this. Web search introduces external evidence. But for non-MCP debates, model agreement is convergent training, not verified truth.

Anchoring effects. A confident wrong model in Round 1 can influence all subsequent rounds. Other models spend their critique tokens addressing the wrong claim rather than searching for the right one. The random pairing in Round 2 helps: no model can systematically anchor every peer. But a single persuasive error in Round 1 carries weight through the full pipeline.

Synthesis collapse. The orchestrator reduces 12+ model responses (4 per round × 3 rounds) into a structured verdict. Nuance is compressed. Minority positions with strong evidence but weak rhetoric can be overshadowed by majority positions with confident delivery. The dissent section preserves these, but only if the synthesis model correctly identifies them as dissent rather than noise. The engine tracks dissent counts. If a model dissents on more than 40% of claims, the verdict carries a warning flag. This has triggered in production.

The three-mode comparison in Log #6 confirms the pattern. Claude Sonnet 4.6 held an identical unrebutted position across all three execution architectures: Standard, Extended, Graph. Same model. Same concern. Nobody engaged it.

Log #7: The Roster Problem explains how that same model earned its seat. Six selection axes. Zero benchmarks. The roster is a maintenance contract, not a one-time choice.

Log #8: The Green Checkmark Lie covers the failure this pipeline exists to prevent: a single model grading its own output.


Provenance

Frequently Asked Questions

+Does the Council actually vote on claims?

No. The orchestrator produces claims from the full transcript. Each claim is mapped to which models agreed or disagreed. The mapping is traceable. Any reader can see exactly which model took which position on which claim. No majority threshold. Surviving claims and surviving dissent.

+What happens if all four models agree?

The claim enters the verdict with full concurrence. The engine treats this as convergent model output, not verified truth. When MCP tools are enabled, web search results can override unanimous model agreement. The evidence basis labels distinguish between model consensus and external verification.

+Can I skip to the verdict without watching all three rounds?

No. The engine runs the full pipeline. The public evidence layer shows every round, every response, every claim. Skipping rounds breaks the adversarial guarantee. The verdict depends on claims tested under cross-examination before synthesis.

+Why does the orchestrator sometimes end after two rounds?

Because continuing to Round 3 when positions are exhausted adds cost without adding insight. The orchestrator is a cost-control mechanism as much as a quality mechanism. The convergence prompt asks whether genuine disagreement remains. When the answer is no, the engine stops.

+What stops the orchestrator from being wrong?

Nothing guarantees correctness. The orchestrator can misjudge convergence, collapse nuance, miss dissent. The engine provides mechanical oversight: dissent tracking, confidence scoring, public deliberation records. These create an audit trail. They do not create certainty. Transparency, not infallibility.

Get new entries by email

One or two emails a week. New Log entries only. No noise, unsubscribe any time.

Three Rounds, One Verdict : Log