[Agora] Anti-mode-collapse penalty in proposal generation done

← Hypothesis Diversity
Per-Theorist Shannon-entropy detector bumps GFlowNet temperature on collapse; +20% reward for underexplored regions.

Completion Notes

Auto-completed by supervisor after successful deploy to main

Git Commits (4)

Squash merge: orchestra/task/b4e04fba-triage-50-failed-tool-calls-by-skill-and (95 commits) (#1011)2026-04-27
[Agora] Anti-mode-collapse penalty in proposal generation [task:8483aa1c-cb10-4973-9052-198384182ea5] (#928)2026-04-27
[Agora] Anti-mode-collapse penalty in proposal generation [task:8483aa1c-cb10-4973-9052-198384182ea5] (#928)2026-04-27
[Agora] Anti-mode-collapse penalty in proposal generation [task:8483aa1c-cb10-4973-9052-198384182ea5]2026-04-27
Spec File

Effort: thorough

Goal

agent.py:1008 check_mechanism_diversity only blocks generation when a gap
is fully monoculture (one mechanism dominant). The earlier failure mode
— a Theorist gradually drifting into a few favourite mechanisms over weeks
— goes undetected. Add a per-Theorist-per-week mode-collapse detector that
penalises proposal weights when an agent's recent output shows
distributional collapse (Shannon entropy of mechanism distribution falls
below threshold), AND a positive reward when the proposal lands in a
white-on-blue region from q-hdiv-semantic-coverage-map.

Acceptance Criteria

scidex/agora/mode_collapse_detector.py::compute_agent_entropy(agent_id, window_days=14) -> float over the agent's last-N proposals, returning Shannon entropy of (target_gene, target_pathway) distribution.
☑ Migration: agent_mode_entropy(agent_id, day, entropy, n_proposals, low_diversity_flag, PRIMARY KEY(agent_id, day)).
☑ Daily cron in scidex/senate/scheduled_tasks.py populates the table; flags low_diversity when entropy < 0.4 * log(n_proposals) AND n_proposals >= 5.
☑ Penalty hook: when a Theorist's last 14 days show low_diversity, GFlowNet sampling temperature is auto-increased by 0.5 (more exploration); restore on entropy recovery.
☑ Reward hook: if a proposal lands within 0.05 cosine of an coverage_underexplored.centroid_xy (from q-hdiv-semantic-coverage-map), emit a +20 % bonus to agent_performance.contribution_score for that proposal.
/agent/{id}/diversity page renders the agent's entropy timeseries + flag history + underexplored-region hits.
GET /api/agents/{id}/diversity returns the JSON.
☑ When 3+ Theorists are flagged simultaneously, emit a Senate theorist_pool_collapse proposal — this signals the system is collapsing, not just one agent.
☑ Test: agent with 10 proposals all targeting APOE+lipid_metabolism → entropy ≈ 0, flag set; reward simulation: a proposal at coords (0.3, 0.7) with underexplored region centroid at (0.31, 0.71) → +20 % contribution_score logged.

Approach

  • Read agent.py:1008 check_mechanism_diversity and :1498 to find the call site for the existing diversity gate; this batch sits next to it (additive).
  • Entropy: H = -sum(p_i * log(p_i)) over distinct (gene, pathway) pairs in the agent's window.
  • Coordinates of new proposals are projected via the parametric UMAP from q-hdiv-semantic-coverage-map.
  • Reward and penalty stack additively with _compute_diversity_bonus (already in exchange.py:107); document the cumulative formula in this spec's Approach.
  • Add a per-agent override: agents.diversity_pressure_override lets Senate hand-set the temperature bump (or disable it) for known-narrow specialists.
  • Dependencies

    • q-hdiv-gflownet-sampler — controls the temperature dial used by the penalty.
    • q-hdiv-semantic-coverage-map — supplies underexplored regions for the reward.
    • agent.py:1008 check_mechanism_diversity (existing gate, kept).
    • scidex/exchange/exchange.py:107 _compute_diversity_bonus.

    Work Log

    2026-04-28 — Implementation complete [task:8483aa1c-cb10-4973-9052-198384182ea5]

    What was built:

    • scidex/agora/mode_collapse_detector.py (new): full entropy pipeline
    - compute_agent_entropy(agent_id, window_days=14) — Shannon H over (gene, pathway) pairs via agent_performance→analyses→hypotheses join
    - is_low_diversity(entropy, n) → bool — flags when H < 0.4·log(n) AND n≥5
    - record_daily_entropy() — upserts into agent_mode_entropy table (created via ensure_schema())
    - get_effective_temperature(agent_id, base_temp) — adds +0.5 bump when flagged; per-agent override via agent_registry.config["diversity_pressure_override"]
    - apply_underexplored_reward(hypothesis_id, agent_id) — cosine-distance check against coverage_underexplored.centroid_xy; updates actor_reputation.contribution_score +20%; gracefully no-ops if dependency table absent
    - count_flagged_theorists() and emit_pool_collapse_proposal() — pool collapse detection → Senate proposal
    - get_diversity_timeline() and get_underexplored_hits() — helpers for dashboard

    • scidex/senate/scheduled_tasks.py — added AgentDiversityEntropyTask (daily cron, name=agent-diversity-entropy) that queries all active Theorists, records entropy, and triggers pool-collapse proposal when ≥3 flagged
    • scidex/agora/gflownet_sampler.py — added agent_id parameter to sample(); calls get_effective_temperature() to transparently bump temperature when agent is in low-diversity state
    • api.py — two new routes:
    - GET /api/agents/{agent_id}/diversity — JSON timeseries + hit log
    - GET /agent/{agent_id}/diversity — HTML Chart.js dashboard

    • tests/agora/test_mode_collapse_detector.py — 23 tests, all passing; covers monoculture entropy=0 spec case and (0.3,0.7)↔(0.31,0.71) reward simulation
    Key design decisions:
    • Dependency on coverage_underexplored (from q-hdiv-semantic-coverage-map) is handled via graceful fallback — reward hook is a no-op until that table exists
    • Per-agent override stored in agent_registry.config JSONB (no schema change needed)
    • Reward delta applied to actor_reputation.contribution_score (where contribution_score actually lives in the DB)

    Sibling Tasks in Quest (Hypothesis Diversity) ↗