diff --git a/machine-docs/REVIEW-dash.md b/machine-docs/REVIEW-dash.md index 0f83f47..5808b23 100644 --- a/machine-docs/REVIEW-dash.md +++ b/machine-docs/REVIEW-dash.md @@ -73,4 +73,34 @@ latest-100 Drone window → most recipes show 1 row. Confirmed root cause matche ## Verdicts -(none yet — awaiting Builder M1 claim in STATUS-dash.md) +### M1: PASS @2026-06-17T16:30Z (claim 3595e80, cold-verified) + +`history_for` rewritten to source per-recipe history from local `/var/lib/cc-ci-runs` artifacts +(`_local_history` scans dirs → `_results_for` → groups by recipe → sorts newest-first by `finished`, +caps at `HISTORY_CAP=30`). All checks done COLD from my own fixture (tarred the 308 real +`results.json` off the host), against my own pre-claim baseline — not the Builder's word: + +- **Count + order match host exactly.** `history_for("bluesky-pds")` → 8 rows in order + `['753','556','435','427','423','ab-bluesky-pds-oldmain','m2rr-bluesky-pds','m2r-bluesky-pds']` + — IDENTICAL to my independent timestamp-derived baseline. **The mixed numeric+named id trap is + handled correctly**: sort key is `(finished, _numeric_id)` reverse; `_numeric_id` returns -1 for + named ids (no `int()` crash); 423 (older) sorts below 427 though numerically close; named runs land + in their timestamp positions, not bunched. Total parseable grouped rows **308**, 23 recipes — match. +- **Display cap bounds AND keeps newest.** plausible 33→30, custom-html 33→30; verified + `min(finished in capped) >= max(finished dropped)` (oldest 3 dropped, not newest). +- **Malformed/empty dirs skipped, no 500.** Injected EMPTYDIR / dir-with-junit-no-json / + malformed-json dir into fixture → total stayed 308, no exception, none appear as rows + (`_results_for` returns `{}` on miss/malformed; `_local_history` skips no-recipe rows). +- **Security preserved.** `_RUN_ID_RE` rejects `../..`, `foo/..`, `a b`, `x;rm`, `..%2f`, ``, `.`, + `foo;`, `