Unclaimed files left in the canonical checkout. Inventory: canonical-cleanup-inventory.md (commit-as-evidence groups). detect-secrets scan clean on 2026-11-02: hits are sha256 pins, git object ids, test sentinels already in tracked tests and unit-file lines.
5.4 KiB
Row 163 r1 review (Filbert): changes requested
What I reviewed:
- Candidate
4be3f6aecon580500699, base4f02486d5. - Manifest 430212299beb: all 10 files match (
sha256sum -c). - candidate.diff in packet
51f67f1f8is byte-identical togit diff 4f02486d5 4be3f6aec. - stack-release.sh blob
0053f35d13. - Base drift: nothing has landed on these files on refactor since the base.
- Brief: docs/plans/2026-10-18_stack-release.md section D2 (:271), blob
b1500d96ad. I also checked BUILD.md rulings mos-0961, mos-0962 and mos-0963, and deviations 1-7.
Tests I ran (my own worktree, 14:53-15:04Z, TMPDIR ~/fs163, totals summed by script):
- stack-release.test.mjs: 164/164
- launcher.test.mjs: 29/29
- host.test.mjs: 42/42
- session.test.mjs: 12/12
- Total: 247 pass, 0 fail.
Mutants I ran: six mutants of my own, each against the R tests (--test-name-pattern "^R[0-9]+ ", 13 tests). All six survived with 13/13 passing:
- M1:
live-config-unchangedalways passes (stack-release.sh:1215). - M2:
backup-unchangedalways passes (stack-release.sh:1214). - M3:
credential-ref-liveaccepts an env reference (stack-release.sh:1301). - M4: the
data-root-scratchcheck is dropped (stack-release.sh:1288). - M5:
no-sessionignores alaunchesdirectory (stack-release.sh:1389). - M6: there is no INT/TERM/HUP trap (stack-release.sh:1395).
Each behavior is in the brief or a ruling, and each lacks a killing test. The brief says "Mutants: one per behavior above", so I'm treating each gap as a change (decision 137: a missing test the brief requires is a change).
F1. The after-checks on the backup and the live config never fail in any test (M1, M2).
- Brief item 1: "The backup's sums are checked before and after."
- The R tests do prove the files stay byte-identical, through
untouched(e)from outside the script. But nothing makes the script's ownbackup-unchangedorlive-config-unchangedprint FAIL. - A broken compare would print PASS to the operator even when the backup or the live business file changed.
- Suggested test: a stand-in fault that makes the fixture host append to the backup's bus.sqlite, and then to the live business file. Expect
FAIL backup-unchangedandFAIL live-config-unchangedby name, plus REHEARSAL_FAIL. - The tested path could be named in the fault file, because the host only gets HOME, PATH and MOSAIC_CONFIG.
F2. Three guard and session branches have no test (M3, M4, M5).
- M3: under mos-0963,
credential-ref-liverefuses an env reference. Only the outside-placeholders file case is tested (R9). Suggested test: anownScriptrewrite that leaves one role's{env:...}reference in place. ExpectFAIL credential-ref-live: <role> <service> is env <NAME>. - M4:
data-root-scratchrefuses a scratch config that resolves somewhere other than$R/data. Suggested test: anownScriptthat pointsc.dataRootat another existing directory that isn't the live one. ExpectFAIL data-root-scratch. - M5:
no-sessionalso fails on$R/data/launches. Only thesessions.jsonhalf is tested (R4 host-launches). Suggested test: a fault that makes the stand-in host createlaunches/. ExpectFAIL no-session: found launches.
F3. Nothing tests that an interrupted rehearsal stops its host and Console (M6).
- Brief item 3 says it "stops both", and deviation 7 makes both processes children of the script.
- If the INT/TERM/HUP trap goes, a Ctrl-C at the gate leaves a host and Console running on the scratch root and the scratch port.
- Suggested test: start a rehearsal, wait for the host's "launches disabled" line in host.log, then SIGTERM the script. Expect:
FAIL signalPASS console-stoppedandPASS host-stopped- REHEARSAL_FAIL with exit 1
- neither recorded pid alive afterwards.
Nit (doesn't block):
- N1:
Registry.remove()(packages/seat/src/session.mjs:208) still calls#write()when the registry is read-only. - Its only caller is launcher.mjs:469, which runs after
add(), andadd()already refuses under read-only, so it can't be reached today. - A one-line read-only guard would make the "never writes sessions.json" contract hold for the whole class rather than only for the current callers.
Checked, nothing to report:
--no-launch: it refuses launches instart(), refuses session launch requests (with the refuse op and a record event), starts no ticker, makes the Registry read-only, and leaves an earlier host's sessions alone in recover() and close().--pmwith--no-launchis a usage error. No unit renders it (host.test).- Processes: both start under
env -i HOME PATH MOSAIC_CONFIG.scripts/mosaicexecs node, so$!is the host itself, and the copy-match and pid checks hold. The Console starts with no--send, so it can't send. - Credentials: they exist only at
roles.<instance>.credentialsandtracker.sync.credentials(packages/business/src/business.mjs:63, :111). The rewrite swaps both. Instance names passrequireId, so a placeholder filename can't escapeplaceholders/. - Ports: they're checked before anything is made. A race after the check just fails
console-up; no other port is taken. - Rehearsal directory: it and its
config/andplaceholders/are made under umask 077 (R1 checks 0700). The backup is read only throughcpand sums; the migration runs on$R/refuseand$R/data. - Hash pins: no test pins a 64-hex hash of any changed file. stack-release.sh and TOOLS.md are read only by stack-release.test.mjs.