plan: /recipe-report skill + report.ci.commoninternet.net weekly report

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
autonomic-bot
2026-06-02 22:37:56 +00:00
parent d38f80048a
commit 81984c84da

View File

@ -0,0 +1,75 @@
# Plan — `/recipe-report` skill + report.ci.commoninternet.net
**Status:** PROPOSED. **Created:** 2026-06-02.
**Goal:** after the weekly `/upgrade-all`, generate a public HTML **"Recipe Report"** that reviews how
the upgrade went and the state of every recipe + open PR — served at **report.ci.commoninternet.net**,
one page per week, with a home-page index of all reports.
## Why it's cheap to build
The serving model already exists (dashboard): a Nix-built image → Swarm service → traefik
`Host(...)` + wildcard TLS, bind-mounting a host dir read-only. We mirror it for reports.
- **DNS:** `report.ci.commoninternet.net` already resolves (wildcard `*.ci.commoninternet.net` → the
host) — **no operator DNS step.**
- **TLS:** the same wildcard cert (`/var/lib/ci-certs/live/`) that serves ci./drone./backups. covers
`report.ci.*`**no cert step** (confirm at deploy).
- **Data:** `/upgrade-all` already writes `/srv/cc-ci/.cc-ci-logs/upgrades/upgrade-all-<date>.md`; open
PRs + CI verdicts come from the Gitea/Drone APIs (creds in `.testenv`).
## A. Serving infra — new `nix/modules/reports.nix` (cc-ci product repo)
A tiny static-file server mirroring `dashboard.nix`:
- Image: `nginx:alpine` (or reuse the dashboard's Python `http.server`), content-hash tag, deployed by a
`deploy-reports.service` reconcile oneshot (same pattern as dashboard/bridge).
- Bind-mount **`/var/lib/cc-ci-reports`** (read-only) as the web root.
- traefik labels: `Host(`report.ci.commoninternet.net`)`, entrypoint `web-secure`, `tls=true`.
- Web root layout: `index.html` + `week-<YYYY-MM-DD>.html` (one per report). **Public, unauthenticated.**
- *(Lighter alternative: add a second traefik router `Host(report.ci…)` → the existing `ccci-dashboard`
service and serve `/var/lib/cc-ci-reports` from `dashboard.py`. Recommend the separate server for clean
decoupling.)*
## B. The skill — `.claude/skills/recipe-report/` (orchestrator repo)
A SKILL.md (LLM-driven review + HTML generation) + a helper script for the deterministic survey/scaffold.
- **Runs:** right after the weekly `/upgrade-all` completes. **Recommended:** the upgrader invokes
`/recipe-report` as its final step (it has the fresh run context + the dated summary). *(Alt: a separate
`cc-ci-recipe-report` systemd service `After=` the upgrade timer.)*
- **Inputs:** the dated `upgrade-all-<date>.md` summary; open PRs per recipe (Gitea API); each recipe's
current vs latest version + CI verdict (Drone); the **previous** week's report (to note "new since last
week"). Runs from the orchestrator; writes the HTML to `cc-ci:/var/lib/cc-ci-reports` over ssh.
- **Review/judgment (the skill's job):** summarize the run (green / stale-test / failed / skipped counts,
notable regressions), then **classify** every item into:
- **Needs attention** — PRs ready to merge (GREEN), and errors/failures to investigate.
- **Routine** — minor bumps, stale-test (needs `--with-tests`), up-to-date / skipped-by-design.
## C. HTML output (per-week page + index)
Each `week-<date>.html`:
- **Title:** "The Recipe Report" · **Subtitle:** "Week of <date the report was run>".
- **① Needs attention** (top, prominent): important PRs to merge + errors to look into — short prose per
item with the PR/build link.
- **② Routine** (below): the less-important items (minor upgrades, stale-test, skipped) — compact.
- **③ Comprehensive table** (bottom): every recipe → `current → target` · upgrade status · CI verdict ·
open PR (link) · notes.
- **Footer:** generated timestamp, link to the live dashboard (ci.commoninternet.net), link back to the index.
`index.html` (home): "The Recipe Report" + a reverse-chronological list of all weekly reports (date +
one-line headline), each linking to its page. The skill **regenerates the index** each run.
Styling: self-contained, inline CSS, clean + mobile-friendly, no JS (fully static).
## D. Public-safety (unauthenticated page)
- Include only public-safe data: recipe names, version bumps, PR titles + links, CI verdicts, concise
error summaries. **No secrets, tokens, internal IPs, or raw logs** (summarize — never dump logs that
could contain generated app secrets; the build already redacts, but the report must not re-introduce).
- PR links point to the private `git.autonomic.zone` mirror — viewers need access to follow them; the
report's prose must stand on its own.
## E. Definition of Done
1. `reports.nix` deployed; `https://report.ci.commoninternet.net/` serves the index over TLS.
2. `/recipe-report` skill generates `week-<date>.html` (3 sections + full table) and regenerates `index.html`.
3. Wired to run automatically after the weekly `/upgrade-all`; produces a report end-to-end on the next run.
4. Page is public-safe (no secrets); renders cleanly on desktop + mobile.
5. NOT merged anything; the report only *reports* (read-only on PRs/CI).
## F. Open decisions
- Trigger: upgrader final step (recommended) vs separate timer.
- Static server: `nginx:alpine` new stack (recommended) vs extend the dashboard.
- Embed the dashboard's per-run summary-card images in the report, or just link them?
- Retention: keep all weekly reports indefinitely (they're tiny static HTML) — assumed yes.