Summary
Add first-class support for waking a session whose payload runs as a local agent OS user, while keeping the shell/zmx session owned by the caller.
This is for the Iris onboarding lane: Iris has a macOS user, but agent harness execution still runs as the human/caller user. We need a clean boundary before continuing Iris gh auth, repo publication, or commits.
Boundary decision
shell and zmx stay caller-owned. sessions owns OS-user orchestration.
Desired stack:
rikonor
sessions wake
shell run <session-name>
zmx session owned by rikonor
sessions/libexec/run-as-user --user iris -- <sessions run ...>
sessions run / harness payload as iris
So:
shell does not get --user.
zmx does not run as the agent user.
- Only the payload command inside the zmx session runs as the target OS user.
- Session ownership/list/status/attach/send/kill remain with the caller that started the session.
Proposed user-facing surface
sessions wake <session> --os-user iris --message "..."
Also support defaulting from:
Precedence:
- explicit
--os-user
$SHIMMER_OS_USER
- unset = current behavior
Wake events should record the target OS user, probably top-level:
{"type":"wake", "os_user":"iris", ...}
Internal run-as helper
Add an internal executable, not a mise task:
Contract:
libexec/run-as-user --user iris -- <cmd...>
Initial implementation should be intentionally boring:
- validate CLI shape
- validate username syntax
- optionally provide friendly checks/errors for target group membership
- use
sudo as the permission authority
- execute with an explicit target environment, not inherited caller env
Sketch:
sudo -n -H -u "$user" -- \
env -i \
HOME="$target_home" \
USER="$user" \
LOGNAME="$user" \
SHELL="$target_shell" \
PATH="$controlled_path" \
"$@"
Open question: exact controlled PATH. Initial candidate:
$HOME/.local/bin:$HOME/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
We should not inherit the invoking user environment by default.
Host policy model
Use sudoers and Unix groups first; do not introduce a custom permission system yet.
Initial local-machine model:
humans group: trusted human OS users
agents group: local agent OS users
- members of
humans may run commands as members of agents without password
Conceptual sudoers rule:
%humans ALL=(%agents) NOPASSWD: ALL
This means:
- humans → agents: allowed
- agents → humans: not allowed
- agents → agents: not allowed unless separately granted
run-as-user is convenience + environment control; sudoers is the security boundary.
Host setup commands
Add host support in sessions, initially as mise tasks or CLI-backed tasks:
sessions host:doctor --os-user iris
sessions host:fix --os-user iris --dry-run
sessions host:fix --os-user iris
Responsibilities:
- check/create
humans
- check/create
agents
- ensure current human is in
humans
- ensure target agent is in
agents
- install/validate sudoers drop-in
- validate with
visudo -c
- smoke-test:
libexec/run-as-user --user iris -- whoami
host:fix --dry-run should print exact commands/files it would apply. Normal sessions wake must never mutate host policy.
Suggested PR split
PR 1: runtime primitive + host diagnostics
- Add
libexec/run-as-user.
- Add
host:doctor.
- Add
host:fix --dry-run.
- Consider making mutating
host:fix print a clear "not implemented yet" until the dry-run surface is reviewed.
- Tests use fake
sudo/fake host commands; no real host mutation in tests.
PR 2: wake integration
- Add
sessions wake --os-user <user>.
- Add
$SHIMMER_OS_USER fallback.
- Record
os_user on wake events.
- Wrap
RUN_CMD with libexec/run-as-user --user "$OS_USER" -- ... before invoking shell run or foreground exec.
- Tests mock the wrapper and assert command construction.
Current local probe
On Or's machine as of 2026-05-10:
agents group exists and contains iris.
humans group does not exist.
iris exists and is in agents.
sudo -n -H -u iris -- ... currently fails with sudo: a password is required.
So host policy setup is required before an Iris smoke test can pass.
Summary
Add first-class support for waking a session whose payload runs as a local agent OS user, while keeping the shell/zmx session owned by the caller.
This is for the Iris onboarding lane: Iris has a macOS user, but agent harness execution still runs as the human/caller user. We need a clean boundary before continuing Iris
gh auth, repo publication, or commits.Boundary decision
shellandzmxstay caller-owned.sessionsowns OS-user orchestration.Desired stack:
So:
shelldoes not get--user.zmxdoes not run as the agent user.Proposed user-facing surface
Also support defaulting from:
Precedence:
--os-user$SHIMMER_OS_USERWake events should record the target OS user, probably top-level:
{"type":"wake", "os_user":"iris", ...}Internal run-as helper
Add an internal executable, not a mise task:
Contract:
Initial implementation should be intentionally boring:
sudoas the permission authoritySketch:
Open question: exact controlled PATH. Initial candidate:
We should not inherit the invoking user environment by default.
Host policy model
Use sudoers and Unix groups first; do not introduce a custom permission system yet.
Initial local-machine model:
humansgroup: trusted human OS usersagentsgroup: local agent OS usershumansmay run commands as members ofagentswithout passwordConceptual sudoers rule:
This means:
run-as-useris convenience + environment control; sudoers is the security boundary.Host setup commands
Add host support in
sessions, initially as mise tasks or CLI-backed tasks:Responsibilities:
humansagentshumansagentsvisudo -chost:fix --dry-runshould print exact commands/files it would apply. Normalsessions wakemust never mutate host policy.Suggested PR split
PR 1: runtime primitive + host diagnostics
libexec/run-as-user.host:doctor.host:fix --dry-run.host:fixprint a clear "not implemented yet" until the dry-run surface is reviewed.sudo/fake host commands; no real host mutation in tests.PR 2: wake integration
sessions wake --os-user <user>.$SHIMMER_OS_USERfallback.os_useron wake events.RUN_CMDwithlibexec/run-as-user --user "$OS_USER" -- ...before invokingshell runor foreground exec.Current local probe
On Or's machine as of 2026-05-10:
agentsgroup exists and containsiris.humansgroup does not exist.irisexists and is inagents.sudo -n -H -u iris -- ...currently fails withsudo: a password is required.So host policy setup is required before an Iris smoke test can pass.