6.7 KiB
Row 56, runs and releases reader, round 1 review (Darkwing)
Issue #1545, packet comment 27109, request comment 27113, queue revs
343-347. Brief: docs/plans/2026-10-10_design-implementation.md, section
"Runs and releases reader module". Base dc96f87b. Candidate manifest
sha256 ed3c5392ae43e1c3541c6bab6a2f25826514124f5f68536e5cc330a39cc5d7a3,
build.patch sha256 dd7b469b…. Both match comment 27109, and the
packet manifest checks clean.
Verdict: approve. The module reads and never writes, nothing it
returns comes from outside the data root, and list and show print the
same bytes as before on Rocko's seeded data root. Every suite is green.
Nothing blocks. The notes below are test gaps and README wording, plus
one disagreement with the packet: mutant M31 is not equivalent.
Method
- I read the whole patch: the five
src/files, the three test files, the README, themosaic-task.mjschange, and Rocko'sseed.sh,byte-check.shanddelta-check.sh. I compared the pointer and log readers againstscripts/release.sh(append_log, theactivateprintf,rollback's log scan andstatus). - Detached worktrees at
dc96f87b:baseunchanged,candwithgit apply --index build.patch, thensha256sum -con the manifest, 15 OK. A third worktree, built the same way, for mutants. It checks 15 OK after the runs (r1/mut/manifest-after.txt). grepfor any write, mkdir, rename, unlink, chmod, open or symlink call inpackages/runs/src: none. The patch touches no Q14-frozen path.- Rocko's
byte-check.shanddelta-check.sh, base against candidate, with work directories in my scratch rather than/tmp. - 22 mutants of my own (
r1/mut/mutate.py, exact text that must match once), each run against thepackages/runssuite. - Six probes for cases the packet doesn't cover (
r1/probes.sh, output inr1/mut/probes.txt), run against base, candidate and a candidate carrying mutant D01.
Node v26.8.1, TMPDIR=~/darkwing-scratch/r56a/tmp. gate.sh with
DOCKER_HOST=unix:///nonexistent.sock ran 16:55:29Z to 16:57:50Z.
Mutants ran 16:57:19Z to 16:57:40Z in the other worktree, then probes,
then test-release with Docker, which finished at 16:58:33Z.
Suites
| Suite | Result |
|---|---|
| packages/runs (node) | 37/0 |
| test-auth | 15/0 |
| test-conductor | 17/0 |
| test-config | 24/0 |
| test-discord | 66/0 |
| test-extension-package | 18/0 |
| test-foundation | 44/0 |
| test-queue | 27/0 |
| test-release | 4/0 without Docker, 14/0 with it (test-release-docker.txt) |
| test-task, Docker unreachable | 26/0, four skip lines |
| byte-check.sh | 16 cases identical, data root unchanged |
| delta-check.sh | same output as Rocko's apart from the scratch path in one stack trace |
I didn't run test-task with real Docker, because it makes live model
calls. Rocko's gate ran it at 98/0, and the change to mosaic-task.mjs is
limited to list and show, which the package's CLI tests and the byte
check cover.
Mutants
17 of 22 killed (r1/mut/summary.txt). The five survivors:
| Mutant | Change | Observable? |
|---|---|---|
| D01 | the CLI's isRunId check before loadConfig removed (Rocko's M31) |
yes, probe P1 |
| D10 | isInside treats a path equal to the data root as outside |
only when a link resolves to the data root itself |
| D17 | listRunRecords reads through readRunDocument, which checks the id |
yes, probe P3: list exits 4 on a run named r- |
| D20 | listRunIds keeps isRunId names only |
yes, probe P3: list hides r- and r-.bad |
| D22 | a log entry without imageTag accepted |
yes, by reading the log |
Probes
| Probe | Base | Candidate |
|---|---|---|
P1 show ../x with no config file |
exit 4, invalid run id |
the same. With D01: exit 3, configuration problem |
P2 show of a run directory with mode 000 |
prints two lines, then a stack trace, exit 1 | cannot read ...: EACCES, exit 4 |
P3 list with runs named r- and r-.bad |
lists both | the same |
P4 runs/ a link inside the data root, plus a run linked to . |
lists both | the same |
P5 state/ linked out, no files there |
not in base | pointer null, log empty. With active.json there: refuses, exit 4 |
P6 log lines with an extra key, and a numeric imageTag |
not in base | both counted in malformed |
Notes (not blocking)
- M31 isn't equivalent. The
isRunIdcheck inshowRunis the only id check that runs beforeloadConfig, so it decides the exit code and message when the config is bad (P1: 4 against 3). The candidate keeps the base order, so nothing regresses, but a test ofshow ../xwithMOSAIC_CONFIGpointing at a missing file would pin it. I agree that M04 can't be reached on POSIX. - No test lists a run whose name starts with
r-but isn't a valid id, so D17 and D20 survive.runs.mjssays such names are still listed, and base does list them. OnelistRunRecordscase withr-orr-.badwould kill both. logEntryaccepts an entry with noimageTag(D22). The malformed cases test a wrong type, a nullnoteand an extra key, but not a missing key.- README wording, three places:
- "
runs/orstate/resolving outside refuses" holds forruns/. Forstate/, the module resolves only the file, so astate/link out with no files behind it reads as no release and an empty log (P5). Nothing outside is read, so the invariant holds and only the sentence is wrong. - "the way
release.sh rollbackskips them": rollback skips only lines that don't parse. P6's two lines would still be used by rollback and are counted malformed here.append_logwrites only the five keys, so real logs don't hit this. The stricter reader is fine. The comparison in the README and instate.mjsisn't accurate. - The delta table has no row for P2.
showof a run directory it can't read used to crash after printing two lines. It now refuses with exit 4. That's an improvement and the package test covers it, butdelta-check.shdoesn't record it.
- "
- D10 needs no test. It matters only for a link that resolves to the data root itself, which is inside by any reading.
- The
padEndcrash inlistthat Rocko reported is still there and still predates this row. Sage files it as a follow-up.
Files
r1/candidate-manifest.sha256: copy of Rocko's.r1/gate.sh,r1/out/: suite runs,summary.txt, byte and delta checks, test-release with Docker.r1/mut/: mutant definitions, runner, diffs, outputs,summary.txtand the manifest check after the runs.r1/probes.sh,r1/mut/probes.txt: the six probes. In that run the third tree (mutwt) carries D01, and the D17 and D20 runs of P3 follow at the end.