Summary
On a system install (volute setup --system, VOLUTE_ISOLATION=user), the generated systemd unit sets RestrictSUIDSGID=yes. This is fundamentally incompatible with the shared-pages git repo, which is created with --shared=group (core.sharedRepository=group). Under that setting git calls adjust_shared_perm() — an explicit chmod that sets the setgid bit on directories and index/object temp files. RestrictSUIDSGID=yes makes that syscall return EPERM for the daemon (root), so:
- Worktree provisioning fails. On mind start,
addPagesWorktree() runs git worktree add, which chmods the new _system worktree dir setgid → fatal: could not create leading directories of '.../_system/.git': Operation not permitted. Every mind logs "_system exists but is not a worktree — shared publishing will fail" and never gets a worktree.
- Publishing/merging fails too, even if a worktree exists.
git add/commit in the shared repo hits error: unable to create temporary file: Operation not permitted → the daemon-side pagesMerge/pagesPullAndMerge cannot commit.
Net effect: shared pages (a headline feature) is completely broken on every user-isolation system install. Hit live on bardo across all 5 minds after the 0.55 upgrade.
Reproduction (confirmed on bardo)
Run a --shared=group commit under the exact unit restrictions via systemd-run:
# WITH RestrictSUIDSGID=yes -> git add: "unable to create temporary file: Operation not permitted", rc=1
systemd-run --pipe --wait -p RestrictSUIDSGID=yes -p ProtectSystem=true \
-p 'ReadWritePaths=/var/lib/volute /minds' /bin/bash -c 'cd shared-repo && git add -A && git commit -m x'
# WITHOUT it -> rc=0
The same command run outside systemd (plain sudo) succeeds, which is why manual provisioning works but the daemon path does not.
Source
src/commands/setup.ts:122 — lines.push("RestrictSUIDSGID=yes", ...) is added unconditionally to every system-install unit.
packages/extensions/pages/src/shared-pages.ts:146 — repo init uses --shared=group under isolation (correct and load-bearing for multi-user access).
Fix direction
--shared=group is required for the multi-user isolation design, so RestrictSUIDSGID=yes has to go (or be made conditional). Options:
- Drop
RestrictSUIDSGID=yes from the generated unit (simplest; small hardening loss — daemon can no longer be blocked from creating setgid files, which it legitimately needs).
- Or reconsider whether
--shared=group is needed at all: if all pages-repo git operations are performed by the daemon (root) and minds only write plaintext files into their own chowned worktree, the shared bit may be unnecessary. Worth verifying before choosing.
Existing system installs need remediation (the unit is only regenerated on setup): remove the line, systemctl daemon-reload && systemctl restart volute, and provision any missing _system worktrees.
Note
Existing installs also silently accumulate the broken state: branches get created in the repo but worktrees never provision, and every mind start re-logs the warning. An upgrade/boot self-heal (detect missing worktree + provision) would help, but is moot until the unit no longer blocks provisioning.
Summary
On a system install (
volute setup --system,VOLUTE_ISOLATION=user), the generated systemd unit setsRestrictSUIDSGID=yes. This is fundamentally incompatible with the shared-pages git repo, which is created with--shared=group(core.sharedRepository=group). Under that setting git callsadjust_shared_perm()— an explicitchmodthat sets the setgid bit on directories and index/object temp files.RestrictSUIDSGID=yesmakes that syscall returnEPERMfor the daemon (root), so:addPagesWorktree()runsgit worktree add, which chmods the new_systemworktree dir setgid →fatal: could not create leading directories of '.../_system/.git': Operation not permitted. Every mind logs"_system exists but is not a worktree — shared publishing will fail"and never gets a worktree.git add/commit in the shared repo hitserror: unable to create temporary file: Operation not permitted→ the daemon-sidepagesMerge/pagesPullAndMergecannot commit.Net effect: shared pages (a headline feature) is completely broken on every
user-isolation system install. Hit live on bardo across all 5 minds after the 0.55 upgrade.Reproduction (confirmed on bardo)
Run a
--shared=groupcommit under the exact unit restrictions viasystemd-run:The same command run outside systemd (plain
sudo) succeeds, which is why manual provisioning works but the daemon path does not.Source
src/commands/setup.ts:122—lines.push("RestrictSUIDSGID=yes", ...)is added unconditionally to every system-install unit.packages/extensions/pages/src/shared-pages.ts:146— repo init uses--shared=groupunder isolation (correct and load-bearing for multi-user access).Fix direction
--shared=groupis required for the multi-user isolation design, soRestrictSUIDSGID=yeshas to go (or be made conditional). Options:RestrictSUIDSGID=yesfrom the generated unit (simplest; small hardening loss — daemon can no longer be blocked from creating setgid files, which it legitimately needs).--shared=groupis needed at all: if all pages-repo git operations are performed by the daemon (root) and minds only write plaintext files into their own chowned worktree, the shared bit may be unnecessary. Worth verifying before choosing.Existing system installs need remediation (the unit is only regenerated on setup): remove the line,
systemctl daemon-reload && systemctl restart volute, and provision any missing_systemworktrees.Note
Existing installs also silently accumulate the broken state: branches get created in the repo but worktrees never provision, and every mind start re-logs the warning. An upgrade/boot self-heal (detect missing worktree + provision) would help, but is moot until the unit no longer blocks provisioning.