/artifact/h-var-… (and every other hypothesis artifact URL) regressed in
two stages:
11bbe3c4b) registered a 301 alias/hypothesis/{id} → /artifact/{id} ahead of the richhypothesis_detail() route at api.py:45534. FastAPI matches first‑declared,elif atype == "hypothesis": branch inside artifact_detail()api.py:32336) only renders a 500‑char raw‑text excerpt, four sub‑score🧪 View Full Hypothesis → link that is now circular (itPR #1354 fixed lookup for non‑prefixed IDs but did not restore any rich
content.
Inline hypothesis‑specific rich content directly into artifact_detail and
populate the existing tabs from hypothesis tables. Keep /artifact/<id> as
the single canonical URL.
api.py near _wrap_artifact_detail_tabs)_hyp_radar_svg(h) — 11‑dim weighted radar SVG (lifted fromhypothesis_detail).
_hyp_dimension_breakdown(h) — full 11‑dimension score grid with weights._hyp_predictions_panel(db, hyp_id) — falsifiable predictions list._hyp_debate_history_html(db, hyp_id, analysis_id) — debate sessions_hyp_versions_panel(db, hyp_id) — parent / siblings / children chain viahypotheses.parent_hypothesis_id, feeding the Versions tab.
_hyp_related_panel(db, h, hyp_id) — same target_gene / diseaseAll helpers are self‑contained, return strings, and tolerate missing
columns / empty results.
api.py:32336)[:500] truncation with _render_collapsible_description_hyp_extra_provenance,_hyp_extra_versions, _hyp_extra_links) initialised to "" at the topartifact_detail and merged into the corresponding tab variables right/artifact/h-var-6612521a02 renders radar SVG, 11‑dimension breakdown,[:500] truncation), debateparent_hypothesis_id exists; empty placeholder otherwise.
TestClient).
/hypothesis/{id} → /artifact/{id} redirect remains/hypothesis/{id} alias route or the now‑unreachablehypothesis_detail() function. Those can be retired in a follow‑up--- ## separators (the underlying