Extend quest_engine.py:discover_gaps() with five mission-pipeline gap detectors that balance the queue toward feature flow, not just data backfill. Today the engine only reseeds data-backfill gaps; these detectors let the engine balance its own outputs toward flow by detecting stuck stages, throughput imbalances, and missing connector tasks.
stuck_stage_gap: any pipeline stage where N >= 10 items are aged-out → spawns 'unblock <stage>' task at pri 88low_landscape_to_gap_throughput: if landscapes added in last 14d > gaps spawned * 2 → seed 'extract gaps from N recent landscapes' at pri 87low_gap_to_debate_throughput: if quality-scored gaps > debates_run * 3 → seed 'fan out debates for N high-q gaps' at pri 87low_hypothesis_to_action_throughput: if top-ranked hypotheses (composite_score >= 7) > (challenges + experiment_proposals) → seed 'create N challenges or proposals' at pri 87missing_bridge: if a connector spec exists in docs/planning/specs/mission_*.md but no corresponding task is open or done → seed task referencing specGap dataclass shape and lives in discover_gaps()tests/quest_engine/test_mission_pipeline_gaps.pyExisting gap detectors in quest_engine.py:discover_gaps() follow this pattern:
scalar(conn, sql) to get a countGap(...) objectkey, layer, priority, count, title, summary, acceptance, approach, requiresAdd five new gap detectors before the return sorted(gaps, ...) line at line ~1546:
stuck_stage_gap
mission_pipeline_observability.md:status='open', last_debated_at IS NULL, > 30d oldnum_hypotheses_generated=0, completed_at IS NOT NULL, > 3d since completioncomposite_score < 0.5, > 14d oldcomposite_score >= 0.5, no challenge linked, > 30d oldstatus='open', no linked experiments, > 45d old
low_landscape_to_gap_throughput
low_gap_to_debate_throughput
low_hypothesis_to_action_throughput
composite_score >= 0.7, status NOT archivedmissing_bridge
docs/planning/specs/mission_*.md files for connector specsCreate tests/quest_engine/test_mission_pipeline_gaps.py:
get_scidex_db() with fixture DBquest_engine.py — discover_gaps(), Gap dataclass, scalar()scidex.core.database — get_db_readonly()docs/planning/specs/mission_*.mdmission_pipeline_observability.md — stage/stuck definitionsdiscover_gaps()tests/quest_engine/test_mission_pipeline_gaps.pypython3 scripts/unblock_stuck_gap_debates.py --limit 10: reconciled 2 completed debates with existing hypotheses, recovered 4 archived analyses back to completed with 16 total hypotheses, closed 3 irrecoverable debates with explicit failure reasons, and confirmed 1 older archived parse-error case was already closed.gap_analysis backlog dropped from 17 to 11, and the corrected detector query returned 0 active stuck mission-pipeline debates.target_debate sessions with no analysis_id and 17 real gap_analysis sessions.gap_analysis sessions with no linked hypotheses and non-archived analyses count as stuck debates.scripts/unblock_stuck_gap_debates.py to reconcile stale debate counters, recover analyses with valid synthesizer payloads, and carry forward explicit closure rationale for irrecoverable sessions.