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.
3.7 KiB
3.7 KiB
Filbert review, row 87 round 4: approve.
Candidate: commit e5dbcf626 (e5dbcf6264), the design docs/plans/2026-10-18_containerized-install-design.md and the rows docs/plans/2026-10-18_containerized-install-rows.md. Every line below is at e5dbcf626's tree. No file under packages/ differs between 0f3eb25ea and e5dbcf626, so the doc's new "line numbers are at 0f3eb25ea" holds for the candidate.
Round 3 items: all answered
- The core container's lifecycle (design.md, section 3, "The core container's lifecycle"):
- Name and labels:
mosaic-<business>-core,mosaic.business,mosaic.kind=core,mosaic.store=<dataRoot>/bus,--rm. - Client death: both expected paths are stated and marked not spiked, and the design doesn't rely on them.
- Leftovers at bus start: stop, then
rm -f, underhost.lock. The fallback holds on the code:writer.lockis a plain exclusive create with no stale reclaim (packages/bus/src/store.mjs:128-135,openSync(..., 'wx'),EEXISTgiveswriter-locked), andnew Store(dataRoot)at runtime.mjs:62 runs before the socket path at :104. A surviving leftover therefore makes a second broker refuse before it opens the database or binds a socket. The close path unlinks only its own lock, matched by inode and device (store.mjs:265). - I6's tests (rows.md:454-469 and design section 9) include the host SIGKILL, record which path ended the old broker, and cover the running-leftover removal and the three
bus statuslock states.
- Name and labels:
bindLaunch'skeys()call is at broker.mjs:391-395. Sage's 391 is right and my 390 was the method line.LAUNCH_OPSis cited as process.mjs:5-20.
Checked and correct
- host.mjs:159-165 (
watchChildren), 252-257 (the start failure path kills the notifier alone, then closes the broker), 341-347 (close()takes each fork's code and returns 1 on a non-zero one), 355-364 (a fork that dies alone stops the host with exit 1) and 389-408 (hostStatuschecks the lock pid against the host's/procand readsbus/broker.sock). host.test.mjs:218-233 is the local notifier-SIGKILL test the I6 case mirrors. The forkpidsreturned at host.mjs:366 are read only by tests. - process.mjs:1-2, 81-83 (
closeop) and 108 (SIGTERM); notifier-process.mjs:1-3. The new paragraph on caps over the entry's stdout states the change honestly and puts it under B2. - The re-pinned broker cites: 328 (
#human), 465 and 468 (bindHumanand itsviacheck), 526 (thevia === 'cli'check in#protectedEnd, which starts at 523), 1569, 1719 and 1867. runtime.mjs:117 and landing.mjs:107 are unchanged. - rows.md I6 now owns
packages/cli/src/host.mjsand thebus statuslines incli.mjs, which the lifecycle andhostStatuschanges need.
Doc-only, follow-up
Neither file is read by a test (grep -rlF containerized-install packages/*/tests scripts/test-*.sh finds nothing), so under decision 137 this does not block.
- design.md:197:
docker stop -t <close timeout>. On SIGTERM the entry stops both forks "asclose()does", andclose()waits up toCLOSE_TIMEOUT_MS(20 s, host.mjs:30) for the notifier and then again for the broker (host.mjs:343, 347). A-tof one close timeout can SIGKILL a broker that is still closing, which leaveswriter.lockand makes the next start refusewriter-locked. That fails closed, but it turns a slow clean stop into an operator step. Name the value, and make it cover both waits (for example twiceCLOSE_TIMEOUT_MSplus a margin), or say why one is enough. I6 can settle it in its brief.
Not run by me
Nothing executed. This is a read of the two documents against the tree and the spike report. The spike measurements are Researcher's.
Verdict: approve e5dbcf626, with the one doc-only follow-up above.