claim(3 U4): YunoHost-style dashboard grid LIVE — per-recipe cards (level badge + status + version + app screenshot + history link) + /recipe/<name> history; mirrors results.json (never greener); R5 + R3 satisfied; deployed cc-ci-dashboard:7b34ec8761df == source
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
22
machine-docs/ADVERSARY-INBOX.md
Normal file
22
machine-docs/ADVERSARY-INBOX.md
Normal file
@ -0,0 +1,22 @@
|
||||
# ADVERSARY-INBOX (Builder → Adversary)
|
||||
|
||||
## 2026-05-31T10:00Z — U4 CLAIMED (Dashboard polish); artifact map
|
||||
|
||||
U4 is claimed in STATUS-3 (`claim(3 U4)`); full WHAT/HOW/EXPECTED/WHERE there. Pointers:
|
||||
|
||||
- **Live grid:** `https://ci.commoninternet.net/` — YunoHost-style cards for **custom-html** (level 4,
|
||||
run #7) and **uptime-kuma** (level 4, run #12), each with level badge + status + version + app
|
||||
screenshot thumbnail (→ `/runs/<n>/summary.png`) + clean-teardown/no-leak flags + `history →`.
|
||||
- **History:** `https://ci.commoninternet.net/recipe/custom-html` (runs #7/#4/#3/#1) and
|
||||
`…/recipe/uptime-kuma` (#12 success **+ #11 failure shown honestly**: level —, no card — it failed at
|
||||
`fetch_recipe` on a bogus ref I passed, wrote no results.json; the grid faithfully shows fail).
|
||||
- **Fidelity check:** every card field == `/runs/<n>/results.json` (level/version/status). Never greener.
|
||||
- **Heads-up (not a verdict ask):**
|
||||
- To populate a 2nd recipe card I direct-triggered uptime-kuma via the Drone API (RECIPE=uptime-kuma,
|
||||
no REF → catalogue version) — a real recipe-CI run (#12), not a PR. #11 was my earlier bogus-REF
|
||||
failed attempt (kept in history as an honest failure row).
|
||||
- Dashboard rolled via the **module reconcile** (`nixos-rebuild build` non-activating +
|
||||
`cc-ci-reconcile-dashboard`), NOT `nixos-rebuild switch` (migration-host caveat, DECISIONS P3/U2).
|
||||
- The U4 build needed the **`?submodules=1`** git-flake form (`nixos-rebuild build --flake
|
||||
'git+file:///etc/cc-ci?submodules=1#cc-ci'`) — a plain path flake omits the `secrets` submodule
|
||||
(missing `secrets.yaml`). Recorded so your own cold rebuild doesn't trip on it.
|
||||
@ -56,10 +56,15 @@ Milestones U0–U5 (plan §5); each ends with an Adversary gate. DoD items R1–
|
||||
== results.json (no inflation), no secrets, deployed bridge == source. R2 satisfied; no VETO.
|
||||
|
||||
### U4 — Dashboard polish (R5)
|
||||
- [ ] U4.1 — Overview grid like `ci-apps.yunohost.org`: per-recipe level badge, latest pass/fail,
|
||||
last-tested version, app screenshot/thumbnail, link to history.
|
||||
- [ ] U4.2 — Regenerated on build completion; reads results.json artifacts.
|
||||
- GATE U4: matches reality across several runs; mirrors the underlying results.json.
|
||||
- [x] U4.1 — Overview grid like `ci-apps.yunohost.org`: per-recipe level badge, latest pass/fail,
|
||||
last-tested version, app screenshot/thumbnail, link to history (`/recipe/<name>`). `render_overview`
|
||||
+ `_card` (dashboard.py @e1d837e).
|
||||
- [x] U4.2 — Regenerated on build completion; reads results.json artifacts (`_results_for`,
|
||||
`_build_row`; 30s cache + live render over the RO-bind-mounted runs dir).
|
||||
- GATE U4: **CLAIMED** (awaiting Adversary) — live 2-card grid (custom-html L4 + uptime-kuma L4) +
|
||||
per-recipe history; mirrors results.json (never greener; honest failure row for uptime-kuma #11);
|
||||
deployed `cc-ci-dashboard:7b34ec8761df` == source; 9 unit tests. (R3 now fully satisfied — card
|
||||
embedded in comment (U3) + dashboard (U4); R5 satisfied.)
|
||||
|
||||
### U5 — Badges + docs + hardening (R6, R7, R8)
|
||||
- [ ] U5.1 — Embeddable per-recipe latest-level badge documented for README embedding.
|
||||
|
||||
@ -225,8 +225,62 @@ The cardinal U3 invariant: ONE comment per PR, refreshed in place; the embedded
|
||||
faithful never-greener projection of the run; image-gen failure degrades to text and never blocks the
|
||||
run or the verdict.
|
||||
|
||||
## Gate: U4 — CLAIMED, awaiting Adversary (Dashboard polish; R5, + R3 "in dashboard")
|
||||
|
||||
**WHAT.** The overview at `https://ci.commoninternet.net/` is now a **YunoHost-CI-style grid**: one
|
||||
card per enrolled recipe showing a **level badge** (coloured by level), latest **pass/fail** status,
|
||||
last-tested **version**, an **app screenshot thumbnail** (the run's `screenshot.png`, clickable →
|
||||
the full `summary.png` card), the clean-teardown/no-secret-leak flags, and a **history** link. A new
|
||||
per-recipe **history page** `/recipe/<name>` lists every run of that recipe (newest first): run #,
|
||||
status, level, version, when, and a per-run card link. Every field is read from the run's
|
||||
**`results.json`** (level/version/screenshot/flags) so the grid mirrors the artifact and is
|
||||
**never greener than the run** (cardinal guardrail). It re-renders live each request (30s cache +
|
||||
auto-refresh), i.e. "regenerated on build completion". DoD **R5** satisfied; **R3** now also embedded
|
||||
in the dashboard (was U3-verified in the comment) → R3 fully satisfied.
|
||||
|
||||
**WHERE (commits / files).**
|
||||
- `e1d837e` `dashboard/dashboard.py` — `level_color`, `_results_for` (traversal-guarded results.json
|
||||
reader), `_custom_recipe_builds` (cached, shared by overview+history), `_build_row` (Drone build +
|
||||
results.json → display row), `latest_per_recipe` (augmented), `history_for`, `render_overview`
|
||||
(grid), `render_history`, `/recipe/<name>` route. `tests/unit/test_dashboard.py` (9 tests).
|
||||
- **Deployed:** `cc-ci-dashboard:7b34ec8761df` (== `sha256(dashboard.py)` first-12, confirmed live),
|
||||
rolled via the dashboard **module reconcile** only (`nixos-rebuild build` non-activating →
|
||||
`cc-ci-reconcile-dashboard` = `docker load` + `docker stack deploy`). NOT `nixos-rebuild switch`
|
||||
(the `#cc-ci` config targets the migration host — DECISIONS Phase-3/U2; reconcile = zero host-config
|
||||
impact, reversible).
|
||||
|
||||
**HOW to verify (cold, from your clone / the VM).**
|
||||
1. **Unit tests** (on cc-ci): `cc-ci-run -m pytest tests/unit/test_dashboard.py -q` → `9 passed`.
|
||||
2. **Deployed == source:** `ssh cc-ci 'sha256sum /etc/cc-ci/dashboard/dashboard.py | cut -c1-12'` →
|
||||
`7b34ec8761df`; `docker service ls | grep ccci-dashboard` shows that tag.
|
||||
3. **Live grid:** `curl -s https://ci.commoninternet.net/` (200) → two recipe cards: **custom-html**
|
||||
(level 4, success, `db9a95024e9d`, thumbnail `/runs/7/screenshot.png` linking `/runs/7/summary.png`,
|
||||
✔ teardown / ✔ no-leak, `history →` `/recipe/custom-html`) and **uptime-kuma** (level 4, success,
|
||||
`dfed87a39f8a`, `/runs/12/...`).
|
||||
4. **Live history:** `curl -s https://ci.commoninternet.net/recipe/custom-html` (200) → rows #7/#4/#3/#1
|
||||
each L4/success/version + per-run `card` link to `/runs/<n>/summary.png`; `…/recipe/uptime-kuma` →
|
||||
#12 (success L4) **and #11 (failure, level —, no card)** — a real failed run shown honestly (it
|
||||
failed at `fetch_recipe` on a bogus ref, wrote no results.json → grid shows failure/level —).
|
||||
5. **No inflation (cardinal):** each card's level/status/version == `/runs/<n>/results.json`
|
||||
(`curl -s https://ci.commoninternet.net/runs/7/results.json` → custom-html level 4 all-pass;
|
||||
`/runs/12/results.json` → uptime-kuma level 4 all-pass). A failed/absent run shows `level —` +
|
||||
the failure pill + the "no screenshot" placeholder — never a level/screenshot it didn't earn.
|
||||
6. **No secrets (R7):** scan the grid + both history pages → only the `title="no secret leak"` flag
|
||||
label matches `secret`; embedded thumbnails are the U1-verified secret-safe landing pages.
|
||||
7. **HEAD parity:** `curl -sI https://ci.commoninternet.net/` and `…/recipe/custom-html` → 200 (the
|
||||
`do_HEAD`/`_route` share with GET; A3-1 stays closed).
|
||||
|
||||
**EXPECTED.** (1) `9 passed`. (2) tag `7b34ec8761df` both places. (3) grid 200 with the two cards as
|
||||
described; (4) history 200 with the run rows + card links incl. the honest uptime-kuma failure row;
|
||||
(5) card fields == results.json (custom-html L4, uptime-kuma L4); (6) zero real secret hits; (7) HEAD 200.
|
||||
|
||||
The cardinal U4 invariant: the grid + history are a faithful, never-greener projection of each run's
|
||||
`results.json`; a failed/levelless run is shown as such (no inflated level, no screenshot it didn't
|
||||
produce); rendering is read-only over the RO-bind-mounted artifacts.
|
||||
|
||||
## In flight
|
||||
(none — U3 claimed; U4 dashboard polish next, unblocked work can start while parked at the U3 gate)
|
||||
(none — U4 claimed; while parked at the gate I'll start U5 unblocked work: docs/ ladder + badge
|
||||
embedding, per-recipe latest-level badge endpoint, render-kill degradation proof, broad leak scan.)
|
||||
|
||||
## Blocked
|
||||
(none)
|
||||
|
||||
Reference in New Issue
Block a user