diff --git a/heart/dashboard.py b/heart/dashboard.py
index de3f2e9..ebe220b 100644
--- a/heart/dashboard.py
+++ b/heart/dashboard.py
@@ -2397,7 +2397,13 @@ def _render_html(board: Board) -> str:
refreshed_at=board.refreshed_at,
refresh_url=(f"https://github.com/{gh_owner}/{repo_name}/actions/workflows/heart-health.yml"
if gh_owner else None))
- return f"""
+ observed_states = {section.state for section in board.sections}
+ observed_status = ("red" if FAIL in observed_states else
+ "yellow" if WARN in observed_states else
+ "stale" if board.stale else
+ "unknown" if UNOBS in observed_states or not observed_states else
+ "green" if OK in observed_states else "unknown")
+ return t_.section_layout(f"""
PyAutoHeart Dashboard — {word}
@@ -2428,7 +2434,8 @@ def _render_html(board: Board) -> str:
{_boards_nav_html()}
-"""
+""", {"observed-checks": {"status": observed_status,
+ "label": "Observed: " + observed_status, "count": len(board.sections)}})
def to_dict(board: Board) -> dict[str, Any]:
diff --git a/tests/test_dashboard_disclosures.py b/tests/test_dashboard_disclosures.py
index 1143311..e58a364 100644
--- a/tests/test_dashboard_disclosures.py
+++ b/tests/test_dashboard_disclosures.py
@@ -173,3 +173,26 @@ def test_repair_rows_copy_exact_prompts_without_toggling_prompt_disclosures():
assert next(details.find('pre')).text() == plan['prompt']
assert button.text() == '' and list(button.find('svg'))
assert any(p.attrs.get('aria-live') == 'polite' for p in section.find('p'))
+
+
+def test_observed_summary_uses_check_states_not_release_verdict():
+ cases = [
+ ([dashboard.OK], False, 'green'),
+ ([dashboard.OK, dashboard.WARN], False, 'yellow'),
+ ([dashboard.WARN, dashboard.FAIL, dashboard.UNOBS], True, 'red'),
+ ([dashboard.OK], True, 'stale'),
+ ([dashboard.OK, dashboard.UNOBS], False, 'unknown'),
+ ([], False, 'unknown'),
+ ]
+ for states, stale, expected in cases:
+ board = dashboard.build_board(make_snapshot(), make_verdict(), now=FRESH_NOW)
+ board.stale = stale
+ board.sections = [dashboard.Section(str(i), 'Check', state, 'Summary')
+ for i, state in enumerate(states)]
+ root = Page(dashboard._render_html(board)).root
+ section = next(root.find('details', 'board-section'))
+ summary = next(section.find('summary'))
+ assert 'Observed checks' in summary.text()
+ assert 'Observed: ' + expected in summary.text()
+ assert next(summary.find(cls='section-status-' + expected))
+ assert 'open' not in section.attrs