The current debate engine (scidex/agora/debate_replay.py,
scidex/agora/debate_trigger.py, the four-persona Theorist/Skeptic/
Expert/Synthesizer loop in scidex_orchestrator.py) is symmetric — both
sides argue and a synthesizer reconciles. That balanced posture is
unsuitable for testing whether a winner would survive a hostile
attack. This task introduces an adversarial mode in which a
strengthened Falsifier+Skeptic team is given the explicit goal of
defeating a high-Elo hypothesis, with knowledge of its prior debate
record, and we measure whether the hypothesis's score moves under
sustained pressure. Hypotheses whose composite_score collapses by more
than a threshold under adversarial debate are flagged as overrated and
their Elo is provisionally penalised pending review.
Effort: extensive
scidex/agora/adversarial_debate.py:select_targets(top_n=20, min_elo=1700) -> list[hypothesis_id]scidex/exchange/elo_ratings.py:leaderboard) that have not beenlifecycle='deprecated' orcomposite_score IS NULL.run(hypothesis_id) -> AdversarialResult — orchestrates ascidex/agora/debate.py:create_debate) withmode='adversarial' so it shows up alongside normal debatesmigrations/20260428_adversarial_debate.sql:ALTER TABLE debate_sessions ADD COLUMN IF NOT EXISTS mode TEXT
NOT NULL DEFAULT 'standard'
CHECK (mode IN ('standard','adversarial','replay'));
CREATE INDEX idx_ds_adversarial ON debate_sessions(target_artifact_id)
WHERE mode='adversarial';
CREATE TABLE adversarial_outcome (
hypothesis_id TEXT PRIMARY KEY,
last_run_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
debate_id TEXT NOT NULL,
score_before DOUBLE PRECISION,
score_after DOUBLE PRECISION,
delta DOUBLE PRECISION,
verdict TEXT NOT NULL CHECK (verdict IN
('survived','damaged','collapsed')),
new_pmids TEXT[],
run_id TEXT
);delta = score_after - score_before (re-scored via thescidex/senate/judge_arena.py).survived if |delta| < 0.05.damaged if -0.20 ≤ delta ≤ -0.05.collapsed if delta < -0.20. Collapsed hypotheses get anrecord_match against a synthetic "stress_test" opponent),under_review via the existingscidex/senate/decision_engine.py).
scidex/agora/prompts/adversarial_falsifier_v1.md) explicitlyevidence_kind: empirical | logical | mechanistic."
select_targets() once daily and spawns one one-shot[Agora] Adversarial debate <hypothesis_title> per target,GET /api/agora/adversarial/leaderboard showstests/test_adversarial_debate.py: target selectionevidence_kind parsing. (deferred — would be separate task)debate_replay.py,debate_trigger.py, scidex_orchestrator.run_debate) to confirmscidex/agora/debate.py debate-create entry point.scidex/exchange/elo_ratings.py for target selection + penalty.q-rt-falsifier-of-truth-cron — periodic re-probing.scidex/agora/adversarial_debate.py with select_targets(), run(), get_leaderboard()migrations/20260428_adversarial_debate.sql (mode column + adversarial_outcome table)scidex/agora/prompts/adversarial_falsifier_v1.md (no fabricated PMIDs, evidence_kind tagging)api_routes/agora.py (leaderboard + targets endpoints)