scooby's review flag 1 on #1242. The other three chmods warn; this one was
`|| true`. It is the one directory holding secrets, so a chmod that fails
silently there is the failure most worth a line in the output.
Comment-and-warn only. No behaviour change on the success path.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01WYgWocp36goy8hj2ui6ps1
A greenfield install cannot run `mosaic fleet init --write`. It fails with
`unsafe-permissions` on an unnamed `(directory)` and an unhandled Node throw,
and every mutating `mosaic fleet` command fails the same way. Measured on a
reverted-to-greenfield sandbox VM at CLI 0.0.50-next.2413: `~/.config/mosaic`,
`fleet/` and `credentials/` all land at 0775, and 1735 directories under the
framework root carry `mode & 022`.
Two independent causes, and fixing either one alone leaves it broken.
1. The installer inherited the caller's umask. Debian/Ubuntu ship 002, so every
`mkdir -p` produced 0775. Fedora/RHEL ship 022 and produced 0755. The
product therefore worked or did not depending on the operator's login shell,
with nothing in the install output distinguishing the two. 022 is already
what this script assumes it produces — `make_durable_snapshot` restores the
ambient umask specifically so "every later sync copy and new framework dir"
gets 0644/0755 — so pin it rather than inherit it.
2. Even at a correct 0755, three directories are rejected. The fleet code
guards its managed paths with two masks in two languages:
`assertPrivateManagedDirectory` (fleet-reconciler.js, `mode & 0o077`) covers
MOSAIC_HOME and `fleet/` and runs before the roster lock is taken;
`assert_private_directory` (tools/fleet/start-agent-session.sh, `mode & 077`)
covers `fleet/agents` and runs before a pane is spawned. Their laxer
siblings use `mode & 0o022` and accept 0755. The strict mask wins, so the
installer states 0700 outright instead of hoping a umask implies it.
The `find -perm /022 -exec chmod go-w` sweep repairs a tree installed before
this change, which the umask alone cannot reach. It strips group/other WRITE
only — never read or execute — and is scoped to directories, so it corrects the
boundary violation without changing who may traverse or read anything. It is
not sufficient for `fleet/agents`: stripping write from 0755 yields 0750 and
`mode & 077` is still non-zero, which is why that path gets its own chmod.
Reported as #1236. The `fleet/agents` half was found by scooby reading
start-agent-session.sh; the umask framing is theirs too — my first report
blamed the distro rather than the umask.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01WYgWocp36goy8hj2ui6ps1
Part of #869
Mos (id-11) Gate-16 merge: independent APPROVE @b6f36564 (8/8, verified vs real production settings template), author id2 != approver id11, clean mosaic-coder author, CI green wp1988.
Co-authored-by: jason.woltje <[email protected]>
Co-committed-by: jason.woltje <[email protected]>