From cbb99de748244421a65f5db0881c57684ca832c5 Mon Sep 17 00:00:00 2001
From: Jammy2211
Date: Thu, 8 Oct 2026 12:02:22 +0100
Subject: [PATCH] fix: standardize dashboard controls and remove redundant
chrome
---
agents/conductors/cortex/AGENTS.md | 11 ++++---
agents/conductors/cortex/_cortex.py | 50 ++++-------------------------
board/_board.py | 7 ++--
board/_theme.py | 6 +++-
docs/board-orchestration.md | 9 +++++-
tests/test_board.py | 6 ++--
tests/test_board_theme.py | 3 +-
tests/test_cortex_conductor.py | 7 ++--
8 files changed, 36 insertions(+), 63 deletions(-)
diff --git a/agents/conductors/cortex/AGENTS.md b/agents/conductors/cortex/AGENTS.md
index 4d769578..7ff4c7c0 100644
--- a/agents/conductors/cortex/AGENTS.md
+++ b/agents/conductors/cortex/AGENTS.md
@@ -31,7 +31,7 @@ note`).
| `checkin [--dry-run \| --apply] [--push \| --no-push] [--project KEY]` | **Where is my science?** | the door — the sequence below, ending in a summary keyed by project; reaches no cluster; exit **1** when the tree does not check |
| `census [--json]` | What is the Cortex holding? | per project: status, summary, runs by state, log length, last update; totals (active projects, runs open, runs running); the check-in stamp; the problems `cortex.py check` would report |
| `dashboard --check` | Are the committed pages current? | exit 0 current · **1 stale** · 2 no checkout · 3 unreadable tree |
-| `dashboard --apply` | — | writes `dashboard.md` + `dashboard.html` + `state.json` — the organ-cockpit feed (`board/_state.py` v1): red on `cortex.py check` problems, yellow while a run is running or the check-in is stale (the page script's 180-min rule, judged at render), items carry `checkin_payload` / `resume_payload`; `--check` ignores its `updated` |
+| `dashboard --apply` | — | writes `dashboard.md` + `dashboard.html` + `state.json` — the organ-cockpit feed (`board/_state.py` v1): red on `cortex.py check` problems, yellow while a run is running or the check-in is stale (the feed's 180-min rule, judged at render), items carry `checkin_payload` / `resume_payload`; `--check` ignores its `updated` |
| `issue [--project KEY] [--apply]` | What sits at the top of each project's issue? | the fenced ledger block (`cortex.py`'s `issue_block`) per project with an `Issue:`; `--apply` writes it into the issue body through `gh` (replacing the block between the markers, or prepending it); never creates an issue; exit **1** without `gh` |
```
@@ -78,8 +78,8 @@ The page opens on the door: a counts table (`Running`, `Open`, `Projects` —
what `board/_board.py` reads for the Brain board's Cortex strip), the
**check-in chip** — two lines, because the check-in has two halves that do
not run on the same machine: `pyauto-brain cortex pull` on the laptop, then
-`pyauto-brain cortex checkin --apply --push` anywhere — and the **last
-check-in** stamp under it. Then **Summary**: one row per active project, four
+`pyauto-brain cortex checkin --apply --push` anywhere — and the shared
+**Last updated / Update** footer. Then **Summary**: one row per active project, four
narrow columns (`Project | Running | Open | Last update`) so it fits a phone.
Then **Projects**: a `### — ` card per project with a ledger —
active first in `projects.yaml` order, then planned/dormant, with the retired
@@ -98,8 +98,9 @@ chips anywhere — retiring is `scripts/cortex.py retire`, a typed verb.
**`checkin.yaml`** is the one-key file (`refreshed: `) the
door writes before rendering. `census()` reads it into `c["checkin"]`;
missing means "never checked in", unparseable is a `problems` line. The
-stamp means *last check-in*, never last render, and the HTML twin computes
-its age on the **viewer's** clock and reddens it once stale.
+stamp means *last check-in*, never last render. The cockpit feed keeps its
+180-minute check-in freshness rule; the HTML uses the shared panel refresh
+footer and omits the old standalone check-in widget.
`--check` compares the pages with the generation comment **and** the visible
`Last updated` banner stripped, so a re-render on a new date is not drift.
diff --git a/agents/conductors/cortex/_cortex.py b/agents/conductors/cortex/_cortex.py
index 78b7b3ec..b194d074 100644
--- a/agents/conductors/cortex/_cortex.py
+++ b/agents/conductors/cortex/_cortex.py
@@ -595,39 +595,11 @@ def render_dashboard(c: dict) -> str:
"table.map{width:100%;border-collapse:collapse;font-size:.95em}"
"table.map th{text-align:left;color:var(--muted);font-weight:600}"
"table.map td,table.map th{border-bottom:1px solid var(--line);padding:.4rem .5rem .4rem 0;vertical-align:top}"
- ".checkin{display:flex;gap:.9rem;align-items:center;padding:.9rem 1.2rem;border:2px solid var(--line);border-radius:.6rem;margin:.2rem 0 1.4rem}"
- ".checkin .mark{font-size:2rem;line-height:1}"
- ".checkin .label{display:block;font-size:.75rem;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}"
- ".checkin time{font-size:1.6rem;font-weight:700;font-variant-numeric:tabular-nums;display:block}"
- ".checkin .note{font-size:.85rem;color:var(--muted)}"
- ".checkin.fresh-ok{border-color:var(--ok);background:color-mix(in srgb,var(--ok) 12%,transparent)}"
- ".checkin.fresh-ok .mark{color:var(--ok)}"
- ".checkin.fresh-bad{border-color:var(--bad);background:color-mix(in srgb,var(--bad) 12%,transparent)}"
- ".checkin.fresh-bad .mark{color:var(--bad)}"
".project h3{font-size:1.35rem;font-weight:700;padding-bottom:.2rem;border-bottom:2px solid var(--accent);letter-spacing:.01em;margin-top:1.6rem}"
".pathchip{display:inline-block;background:var(--accent);color:#fff;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.88em;padding:.12em .5em;border-radius:.3rem;overflow-wrap:anywhere}"
"@media(prefers-color-scheme:dark){.pathchip{background:color-mix(in srgb,var(--accent) 55%,#000)}}"
".stale{color:var(--bad);font-weight:600}")
-# The page is static, so a stamp is never stale *at render* — it is stale on
-# the reader's clock, 3 h later, on a different day. So the age is computed
-# on load, here, and nowhere else: the box is neutral until this runs.
-_CHECKIN_JS = (
- "(function(){var e=document.getElementById('checkin'),"
- "b=document.getElementById('checkin-box'),"
- "m=document.getElementById('checkin-mark'),"
- "n=document.getElementById('checkin-note');if(!e||!b)return;"
- "var t=e.getAttribute('datetime'),d=t?new Date(t):null;"
- "if(!d||isNaN(d.getTime())||(Date.now()-d.getTime())/60000>"
- f"{CHECKIN_FRESH_MINUTES}){{"
- "b.classList.add('fresh-bad');e.classList.add('stale');"
- "if(m)m.textContent='✗';"
- "if(n)n.textContent=t?'stale, paste the check-in':'never checked in';"
- "}else{b.classList.add('fresh-ok');if(m)m.textContent='✓';"
- "var a=Math.round((Date.now()-d.getTime())/60000);"
- "if(n)n.textContent='fresh · '+(a<60?a+' min':Math.round(a/60)+' h')"
- "+' ago';}})();")
-
def render_dashboard_html(c: dict) -> str:
"""The one-tap-copy twin GitHub Pages serves — same content, real buttons."""
@@ -656,32 +628,23 @@ def render_dashboard_html(c: dict) -> str:
{"label": "Running", "href": "#summary", "count": n["running"]},
{"label": "Open", "href": "#summary", "count": n["open"]},
{"label": "Projects", "href": "#projects", "count": n["active"]},
- {"label": "Check in", "href": "#checkin-box"},
+ {"label": "Check in", "href": "#orchestration-cortex"},
]),
orchestration_panel(
"cortex", "Check in on the science",
"Review projects and runs together, then record what you have learned.",
- checkin_payload(c), work_links=work_links, copy_label=CHECKIN_LABEL, organ="cortex",
+ checkin_payload(c), work_links=work_links, organ="cortex",
refreshed_at=c.get("refreshed_at") if not c.get("problems") else None,
refresh_url=home + "/actions/workflows/dashboard_refresh.yml" if home else None),
]
if home:
H.append(f'