Identify when multiple experiments test the same claim and track whether results replicate,
conflict, or are inconclusive. This is critical for evidence quality — a replicated finding
has much higher trust than a single observation.
replication_groups table or metadata linking replicated experimentsreplicated, conflicting, single_study, inconclusiveGET /api/experiments/replication/{entity} — show replication landscapeatl-ex-04-QUAL — Need quality-filtered experiments for meaningful comparisonatl-ex-06-META — Meta-analysis builds on replication groupsq-artifact-debates — Conflicting experiments are prime debate targetsState at start: replication_groups table (80 rows), replication_clusters/replication_cluster_members tables (empty), 228/632 experiments had replication_group_id set (all via a one-off 2026-04-17 batch). No Python module for clustering, no API endpoint, no effect-size data.
Implemented:
scidex/atlas/replication_clustering.py — new module with:cluster_experiments(db, entity_filter=None): groups experiments by normalised target_gene + inferred relation_type (from experiment_type) + inferred direction (from title/primary_outcome keyword matching). Upserts replication_groups rows with experiment_ids (JSONB), replication_status, agreement_score, and effect_sizes (forest-plot data: per-experiment effect_estimate, 95% CI, weight). Applies a composite_score nudge: +0.05 for replicated, −0.05 for conflicting, +0.01 for inconclusive.get_replication_landscape(entity, db): fetches all replication groups matching an entity, annotates conflict flag, returns effect_sizes and slim experiment details. Falls back to per-experiment listing when no groups exist.api.py — added GET /api/experiments/replication/{entity} endpoint (after the existing priority-queue route). Accepts optional ?refresh=true to re-cluster on demand. Returns entity, groups, conflict_count, replicated_count, single_study_count, experiment_count, summary.scidex/agora/debate_trigger.py rule 4 (_rule4_conflicting_replication) — experiments with replication_status='conflicting' are queued as high-priority debate targets.Verified:
get_replication_landscape('TREM2') returns 3 groups, 38 experiments, effect_sizes populated.cluster_experiments(db, entity_filter='TREM2') writes 1 group, updates 19 experiments, composite_score nudged +0.05.python3 -m py_compile api.py passes.