Spaces:
Sleeping
Prompt β merge "GP's top programs" + "Coordinated modules" into ONE sortable "Groups the engine explored" table
Replace the two overlapping panels with a single table of the groups the GP explored, sortable by four lenses: GP fitness (the engine's own pick order), Combined AUROC, Coherence, Synergy. Drop the separate "GP's top programs" block. This supersedes PROMPT_synergy_lens.md and the top-10 panel from PROMPT_gp_top10_groups.md. Read the named code first; verified line refs below. Airgap unchanged. pytest + tsc after.
GUIDING IDEA: the groups in this table ARE the GP's explored groups (harvested from the population). "GP fitness" sort = the engine's own preference (its picks); the other three are re-score lenses. One table, same groups, selectable lens β this dissolves the "is this from the GP or not" confusion.
Part 1 β API: add GP fitness per module
In api/app.py _compute_module_ranking (~line 1244): it already harvests distinct gene-sets from the run's population (run.log candidates), and each candidate carries fitness. While harvesting, record per gene-set the max GP fitness among candidates with that set; add gp_fitness: float | None to each module dict in the payload. No other endpoint change. (Airgap unchanged β fitness is a number, no gene names.)
web/lib/api.ts: addgp_fitness?: number | nullto the module type (ModuleRankingper-module entry, nearcombined_holdout~line 295).
Part 2 β Frontend: one merged table (enhance ModuleRankingPanel, ~3521-4100)
- Sorts (four). Extend
SortKey(currently"combined" | "coherence",3940) to add3975-3984) and the sort-button row (~4089-4098). Labels: "GP fitness", "Combined AUROC", "Coherence", "Synergy". Default sort ="gp_fitness"and"synergy". Wire all four into the sort comparator (gp_fitness(so the default view is the engine's own preference order β what the old top-programs panel showed). - Columns. Add GP fitness (from the new field) and Synergy columns alongside the existing Combined AUROC / Coherence / Size / Genes / Survives.
synergy = m.combined_holdout β max(g.single_gene_metric over m.per_gene); guard nulls β "β" and sort to the bottom (both fields already on the row). - Keep everything the panel already does: winner badge (
isWinnerSet, ~3596) on the winner's gene-set row; SurvivalChips (preβpostfull β subgroup); inline gene symbols (auto-revealed per page); expand β per-gene single-gene AUROC + rank; pagination. - Retitle + caption (plain English): title e.g. "Groups the engine explored". Caption: "Every gene group the engine tried during the search. Sort by GP fitness (what the engine itself preferred β its picks), Combined AUROC (the group's average score on held-out patients), Coherence (how tightly the genes move together), or Synergy (how much the group beats its best single gene). The winning program is badged. The Survives flags show whether a group still separates HPV under the confound checks."
- "?" tooltip: explain the four lenses plainly, and keep the winner's-curse caveat for the re-score lenses: "Combined AUROC / Coherence / Synergy re-score ~2,900 groups on the same small held-out set, so their very top values are optimistically biased β the GP fitness order (and the badged winner) is the engine's own, cross-validated pick; trust it as the reliable choice."
Part 3 β remove the now-duplicate "GP's top programs" block
In ResultPanel (~line 1983): remove the "The GP's top programs" block (the top-10-by-fitness list added previously). Its job is now done by sorting the merged table by GP fitness, with per-gene ranks available on expand and the winner badged. Keep the metric cards (Held-out, Permutation p, Nodes, Genes) as the headline. Add one line under the cards pointing down: "The winning program is badged in Groups the engine explored below." Remove any fetches in ResultPanel that existed only to feed the deleted block (the merged table fetches its own data); leave the rest intact.
Part 4 β leave the other panels alone
- "Known-marker recovery" (single-gene markers-only diagnostic) is unchanged.
- No engine/GP-search change; this is presentation + one additive API field.
CONSTRAINTS
- Airgap absolute: module payload stays opaque-ID + scores +
gp_fitness+ survival; symbols revealed only for displayed rows (bounded, as today). Engine/GP search untouched (detection unaffected). - Defaults: colorectal + non-HNSC behaviour unchanged; existing tests + airgap tests green.
Checkpoint
- One "Groups the engine explored" table with four sorts (GP fitness default), GP-fitness + Synergy columns added, winner badged, survival chips, expand-for-per-gene-ranks, pagination.
- Sorting by GP fitness reproduces the engine's preference order (the old top-programs list); sorting by Synergy sinks ZFR2+passenger groups and surfaces additive ones.
- The separate "GP's top programs" block is gone; Result cards keep the headline + a pointer to the table.
pytestgreen,tscclean, airgap untouched.