Build the DoE region reader + automated R/LaTeX report pipeline
Build / build-amd64-iso (push) Canceled after 0s
Build / build-aarch64-iso (push) Canceled after 0s
Build / build-riscv64-img (push) Canceled after 0s

Closes the "still open" reader-tool note from §XXXV.10: scripts/
extract_doe_region.py spools DOE-PERSIST-TRIAL's on-disk binary ring off
disk/artemis.img into a CSV -- direct file read by default, or via a real
loop device (--loop, losetup) per the literal request. Independent
Python reimplementation of doe_region.c's own ring-walk, verified
against a live 3-record write/read round trip.

analyse_multiuser_doe.R (house style, ggplot2/svglite) and
multiuser_doe_report.tex (same preamble convention as
bare_metal_doe_report.tex) auto-discover whatever data exists and
degrade gracefully to a placeholder when a campaign has 0 trials so far
-- the whole point being this can be rebuilt at any point during a
multi-day campaign, including mid-run. build_multiuser_doe_report.sh
chains extraction -> R -> svg_to_pdf.py -> pdflatex into one command.

Found and fixed a real bug while verifying: the R script's SCRIPT_DIR
detection silently wrote charts/tables/report output to the repo root
instead of the analysis directory when invoked from a different cwd --
switched to the robust commandArgs() "--file=" idiom. Verified live both
branches (0 trials and a real 3-record write), reverted synthetic test
data and incidental svg_to_pdf.py churn on ~85 unrelated committed
figures before committing. FABRIC-3.md §XXXV.11 has the full account.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BWpNjdwPtFLuVLaAq44L9K
This commit is contained in:
Robert Allan James
2026-09-17 16:59:26 -04:00
co-authored by Claude Sonnet 5
parent aaf349946f
commit c535252907
14 changed files with 10083 additions and 1 deletions
+75
View File
@@ -5642,3 +5642,78 @@ scope per §XXXV.3 was the writer only, verified here by a one-off Python script
bytes directly, not a maintained tool. Launching the first live multi-hour campaign is still a
separate, later, explicit decision -- this entry closes the persistence-writer gap, nothing more.
### XXXV.11 -- The reader tool from §XXXV.10's own "still open" note: built, plus a full
R/LaTeX report pipeline, all live-verified (2026-09-17)
Requested directly: "mount the virtual drive on a loop device... spool the csv's into a file
for the proper deeply detailed R/LaTeX report with svg charts... build that workflow script for
automated production of the PDF artifact while execution of the experiment is underway." Closes
the one item §XXXV.10 itself flagged as still missing.
**Built:**
- `scripts/extract_doe_region.py` -- standalone reader, independent reimplementation of
`doe_region.c`'s own ring-walk logic in Python (same devblock_from_top fence math, same
head/tail/record_count ring-order walk) reading `disk/artemis.img` directly. Two modes:
`--img PATH` (default, no privilege needed -- opens the image as a plain file) and `--loop`
(attaches via `losetup --read-only`, needs sudo, detaches on exit -- the literal loop-device
step requested; noted in the script's own docstring that the ring is raw binary at a fixed
offset, not a filesystem, so there is nothing to `mount` in the POSIX sense once attached, it
reads exactly like a regular file). Read-only in both modes; a torn read mid-write from a
live campaign is rejected the same way `doe_region_ctrl_read()` itself rejects a bad
magic/version -- "not yet initialized," not a crash.
- `experiments/bare_metal/analysis/analyse_multiuser_doe.R` -- new analysis script, house style
(`ggplot2`/`svglite`, same `theme_light_report()` shape as `analyse_multirep.R`), but
deliberately NOT that script's fixed-manifest pattern: auto-discovers whatever CSV or CSV
directory it's given and **degrades gracefully to a placeholder table/chart when 0 trials
exist yet**, rather than erroring -- the explicit "while execution of the experiment is
underway" requirement. Also writes an auto-generated LaTeX fragment
(`report/sections/multiuser_summary_autogen.tex`) with the actual current trial count, fail
rate, and per-cell breakdown, computed fresh every run -- the report's own numbers stay
truthful across re-runs instead of going stale.
- `experiments/bare_metal/analysis/report/multiuser_doe_report.tex` -- new self-contained
report (same preamble/colour-palette convention as `bare_metal_doe_report.tex`), every
data-dependent figure wrapped in `\IfFileExists` so the report builds correctly whether 0
trials or many have been extracted.
- `scripts/build_multiuser_doe_report.sh` -- orchestrates all of the above: extract -> R
analysis -> `svg_to_pdf.py` (existing, reused unmodified) -> `pdflatex` (twice, for
cross-references) -> `multiuser_doe_report.pdf`. `--csv PATH` skips disk extraction entirely
(smoke-testing against an arbitrary CSV); `--loop` passes through to the extractor.
**Real bug found and fixed while verifying, not left in:** the R script's original
`SCRIPT_DIR` detection (`sys.frames()[[1]]$ofile`, the same pattern `analyse_multirep.R` already
uses) silently fell back to `getwd()` when invoked from the orchestration script's own working
directory -- wrote `charts/`, `tables/`, and `report/sections/` at the repo root instead of
under `experiments/bare_metal/analysis/`, confirmed live (all three stray directories actually
appeared there on the first orchestrated run). Fixed with the robust `commandArgs()`
`"--file="` idiom, re-verified correct placement, stray directories removed. Not touched in
`analyse_multirep.R` itself -- out of scope, not verified broken there, flag only.
**Verified live, full pipeline, both branches:**
1. **No-data branch:** ran the full orchestration script against the current (post-§XXXV.10
test-write-reverted) `disk/artemis.img` -- 0 trials, placeholder chart/table/summary
generated, real 2-page PDF produced, correctly states "No trial data has been persisted to
the DoE region yet."
2. **Populated branch:** booted amd64, wrote 3 synthetic trial records via `DOE-PERSIST-TRIAL`
at the console (one deliberately with `fail=1`), clean `BYE`. `extract_doe_region.py`
round-tripped all 3 records correctly, in ring order, byte-exact. Full orchestration run
(`--csv` override, to isolate the R/LaTeX stage from the disk-extraction stage) produced a
real 4-page PDF with correct auto-generated summary text ("3 completed trial(s)... Overall
fail rate... 33.3%...") and real embedded SVG-derived charts.
3. Reverted the synthetic test write from `disk/artemis.img` afterward (same convention as
§XXXV.10) and regenerated the final on-disk report/CSV against the real, empty state before
committing -- what's in the repo now honestly reflects "no campaign has run yet," not
leftover demo numbers.
4. Reverted an unrelated side effect caught before committing: `svg_to_pdf.py` (existing,
unmodified) re-converts every SVG in the shared `charts/` directory on each run, which
touched ~85 pre-existing, unrelated committed figure PDFs with meaningless
binary/metadata-only diffs (almost certainly `rsvg-convert` version drift, not content
changes) -- reverted before staging, confirmed only the new `multiuser_*` files remain
changed.
**Not done, explicitly out of scope for this pass:** the actual multi-day campaign launch is
still a separate, deliberate decision -- this closes only the "how do we get a report out of
it" side. `--loop` mode was implemented per the literal request but not live-tested (the
default `--img` direct-file mode was what got exercised above; both modes share the same
`read_ring()` code path once handed a device/file path, so this is a thin, low-risk gap, not
an unverified core mechanism).