pmstack /eval-report — make your eval run shareable
You turn a /run-eval result into one self-contained HTML file a PM can
paste anywhere. /run-eval produces the numbers (summary.md, cases/,
metrics.csv); /eval-report makes them presentable and portable: a verdict
hero, the per-case PASS/FAIL table, and the metrics table — inline CSS, no
external assets, opens in any browser. The footer backlinks to pmstack, so every
share is a quiet on-ramp.
What it is (and is not)
- The presentation layer over a real run. It renders what
/run-eval
already measured. It never invents, edits, or improves the numbers.
- Filesystem / CLI, like
/run-eval: it runs bin/eval-report.py. With no
filesystem (claude.ai), there's no run to render — run the eval where the
runner lives, then report from there.
Steps
- Resolve the run. If the user gave a path (a run directory or a
summary.md), use it. Otherwise glob outputs/eval-runs/*/ and take the most
recent; if several are plausible, list them and ask. If there are none,
educate (below) — never fabricate a run.
- Generate. Run
bin/eval-report.py <run-dir>. It writes report.html next
to the run's summary.md (override with --out <path>) and prints the path.
Never hand-author the HTML — the numbers must come from the real summary.md.
- Hand it back. Say where it is and that it's a single self-contained file —
shareable in Slack, a launch doc, LinkedIn, or a PR as-is. Point out the
footer backlink: whoever opens it can click through to run their own eval.
No run yet
"/eval-report renders a real eval run into a shareable HTML page — so it needs
a run first. Run /run-eval <your-eval.yaml> to produce
outputs/eval-runs/<...>/, then /eval-report turns it into a report you can
paste anywhere. No eval yet? Start at /eval <feature>."
Hard rules
- NEVER generate a report for a run that doesn't exist, and never hand-write the
HTML — always run
bin/eval-report.py so the numbers come from the real run.
- ALWAYS keep the output self-contained — that's what makes it one-file-shareable.
- Never alter the verdict or pass-rates to look better. The report's value is
that it's the real result.
Tone
Crisp, practical — the "make it shareable" step at the end of the eval loop. Get
the PM a clean artifact and tell them exactly where it lands well.
1---2name: pmstack-eval-report3description: pmstack /eval-report — make your eval run shareable4---56# pmstack /eval-report — make your eval run shareable78You turn a `/run-eval` result into **one self-contained HTML file** a PM can9paste anywhere. `/run-eval` produces the numbers (`summary.md`, `cases/`,10`metrics.csv`); `/eval-report` makes them presentable and portable: a verdict11hero, the per-case PASS/FAIL table, and the metrics table — inline CSS, no12external assets, opens in any browser. The footer backlinks to pmstack, so every13share is a quiet on-ramp.1415## What it is (and is not)1617- The **presentation layer** over a real run. It renders what `/run-eval`18 already measured. It never invents, edits, or improves the numbers.19- **Filesystem / CLI**, like `/run-eval`: it runs `bin/eval-report.py`. With no20 filesystem (claude.ai), there's no run to render — run the eval where the21 runner lives, then report from there.2223## Steps24251. **Resolve the run.** If the user gave a path (a run directory or a26 `summary.md`), use it. Otherwise glob `outputs/eval-runs/*/` and take the most27 recent; if several are plausible, list them and ask. If there are none,28 educate (below) — never fabricate a run.292. **Generate.** Run `bin/eval-report.py <run-dir>`. It writes `report.html` next30 to the run's `summary.md` (override with `--out <path>`) and prints the path.31 Never hand-author the HTML — the numbers must come from the real `summary.md`.323. **Hand it back.** Say where it is and that it's a single self-contained file —33 shareable in Slack, a launch doc, LinkedIn, or a PR as-is. Point out the34 footer backlink: whoever opens it can click through to run their own eval.3536## No run yet3738*"`/eval-report` renders a real eval run into a shareable HTML page — so it needs39a run first. Run `/run-eval <your-eval.yaml>` to produce40`outputs/eval-runs/<...>/`, then `/eval-report` turns it into a report you can41paste anywhere. No eval yet? Start at `/eval <feature>`."*4243## Hard rules4445- NEVER generate a report for a run that doesn't exist, and never hand-write the46 HTML — always run `bin/eval-report.py` so the numbers come from the real run.47- ALWAYS keep the output self-contained — that's what makes it one-file-shareable.48- Never alter the verdict or pass-rates to look better. The report's value is49 that it's the real result.5051## Tone52Crisp, practical — the "make it shareable" step at the end of the eval loop. Get53the PM a clean artifact and tell them exactly where it lands well.