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.
1 line
5.5 KiB
JSON
1 line
5.5 KiB
JSON
{"body":"**Row 163 r1 review (Filbert): changes requested**\n\n**What I reviewed:**\n- Candidate 4be3f6aec on 580500699, base 4f02486d5.\n- Manifest 430212299beb: all 10 files match (`sha256sum -c`).\n- candidate.diff in packet 51f67f1f8 is byte-identical to `git diff 4f02486d5 4be3f6aec`.\n- stack-release.sh blob 0053f35d1360.\n- Base drift: nothing has landed on these files on refactor since the base.\n- Brief: docs/plans/2026-10-18_stack-release.md section D2 (:271), blob b1500d96ad27. I also checked BUILD.md rulings mos-0961, mos-0962 and mos-0963, and deviations 1-7.\n\n**Tests I ran** (my own worktree, 14:53-15:04Z, TMPDIR ~/fs163, totals summed by script):\n- stack-release.test.mjs: 164/164\n- launcher.test.mjs: 29/29\n- host.test.mjs: 42/42\n- session.test.mjs: 12/12\n- Total: 247 pass, 0 fail.\n\n**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:\n- M1: `live-config-unchanged` always passes (stack-release.sh:1215).\n- M2: `backup-unchanged` always passes (stack-release.sh:1214).\n- M3: `credential-ref-live` accepts an env reference (stack-release.sh:1301).\n- M4: the `data-root-scratch` check is dropped (stack-release.sh:1288).\n- M5: `no-session` ignores a `launches` directory (stack-release.sh:1389).\n- M6: there is no INT/TERM/HUP trap (stack-release.sh:1395).\n\nEach 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).\n\n**F1. The after-checks on the backup and the live config never fail in any test (M1, M2).**\n- Brief item 1: \"The backup's sums are checked before and after.\"\n- The R tests do prove the files stay byte-identical, through `untouched(e)` from outside the script. But nothing makes the script's own `backup-unchanged` or `live-config-unchanged` print FAIL.\n- A broken compare would print PASS to the operator even when the backup or the live business file changed.\n- 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-unchanged` and `FAIL live-config-unchanged` by name, plus REHEARSAL_FAIL.\n- The tested path could be named in the fault file, because the host only gets HOME, PATH and MOSAIC_CONFIG.\n\n**F2. Three guard and session branches have no test (M3, M4, M5).**\n- **M3:** under mos-0963, `credential-ref-live` refuses an env reference. Only the outside-placeholders file case is tested (R9). Suggested test: an `ownScript` rewrite that leaves one role's `{env:...}` reference in place. Expect `FAIL credential-ref-live: <role> <service> is env <NAME>`.\n- **M4:** `data-root-scratch` refuses a scratch config that resolves somewhere other than `$R/data`. Suggested test: an `ownScript` that points `c.dataRoot` at another existing directory that isn't the live one. Expect `FAIL data-root-scratch`.\n- **M5:** `no-session` also fails on `$R/data/launches`. Only the `sessions.json` half is tested (R4 host-launches). Suggested test: a fault that makes the stand-in host create `launches/`. Expect `FAIL no-session: found launches`.\n\n**F3. Nothing tests that an interrupted rehearsal stops its host and Console (M6).**\n- Brief item 3 says it \"stops both\", and deviation 7 makes both processes children of the script.\n- 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.\n- Suggested test: start a rehearsal, wait for the host's \"launches disabled\" line in host.log, then SIGTERM the script. Expect:\n - `FAIL signal`\n - `PASS console-stopped` and `PASS host-stopped`\n - REHEARSAL_FAIL with exit 1\n - neither recorded pid alive afterwards.\n\n**Nit (doesn't block):**\n- N1: `Registry.remove()` (packages/seat/src/session.mjs:208) still calls `#write()` when the registry is read-only.\n- Its only caller is launcher.mjs:469, which runs after `add()`, and `add()` already refuses under read-only, so it can't be reached today.\n- 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.\n\n**Checked, nothing to report:**\n- **`--no-launch`:** it refuses launches in `start()`, 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(). `--pm` with `--no-launch` is a usage error. No unit renders it (host.test).\n- **Processes:** both start under `env -i HOME PATH MOSAIC_CONFIG`. `scripts/mosaic` execs 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.\n- **Credentials:** they exist only at `roles.<instance>.credentials` and `tracker.sync.credentials` (packages/business/src/business.mjs:63, :111). The rewrite swaps both. Instance names pass `requireId`, so a placeholder filename can't escape `placeholders/`.\n- **Ports:** they're checked before anything is made. A race after the check just fails `console-up`; no other port is taken.\n- **Rehearsal directory:** it and its `config/` and `placeholders/` are made under umask 077 (R1 checks 0700). The backup is read only through `cp` and sums; the migration runs on `$R/refuse` and `$R/data`.\n- **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.\n"} |