The repo-scoped runtime is a single Go binary, but the OS integration surface differs per platform. This page collects the caveats that bite in practice.

macOS (launchd)

LaunchAgent vs LaunchDaemon

radioactive-ralph installs a LaunchAgent (per-user), not a LaunchDaemon (system-wide). Agents run at login under your user and can access your keychain — which means they can invoke claude / codex / gemini CLIs that authenticated under your account. Daemons run as root and would need separate auth.

Plist location

~/Library/LaunchAgents/com.jbcom.radioactive-ralph.<repo-slug>.plist

<repo-slug> is derived from the repo path to disambiguate multi-repo operators. One agent per repo.

Cannot launch because macOS is asleep

launchd won’t fire a plist under RunAtLoad if the machine sleeps before login completes. On sleep-heavy laptops, expect the service to appear “stopped” after a cold boot. Fix: launchctl kickstart -k gui/$UID/com.jbcom.radioactive-ralph.<slug> or just log out/in.

SIP / code-signing

We don’t code-sign the binary (v1). The first time you run it, Gatekeeper will complain. Fix:

xattr -d com.apple.quarantine $(which radioactive_ralph)

Or right-click → Open in Finder on the binary once. Post-launch, subsequent invocations are fine.

Linux (systemd –user)

User bus vs system bus

We install a user unit, not a system unit. Requires systemd --user to be running — i.e. you’re in a graphical session or you enabled linger:

loginctl enable-linger $USER

Without linger, the user bus dies on logout and takes the unit with it.

Unit location

~/.config/systemd/user/radioactive-ralph-<repo-slug>.service

XDG_RUNTIME_DIR missing

Under SSH without loginctl enable-linger, systemctl --user fails with Failed to connect to bus. Set:

export XDG_RUNTIME_DIR=/run/user/$UID

Or use linger.

AppArmor / SELinux

If the binary fails to open the Unix socket, check kernel audit logs:

sudo journalctl -u apparmor -n 50
sudo ausearch -m AVC -ts recent

We ship no profile; fall back to writing the socket under $HOME/.local/state/radioactive-ralph/ if the confinement is tight.

Windows

Named-pipe endpoint

On Windows the control plane is a named pipe, not a Unix socket:

\\.\pipe\radioactive-ralph-<repo-slug>

Pipes are scoped to the current user’s session. That means:

  • A service installed under LocalSystem (SCM) creates a pipe that interactive users can connect to (we explicitly grant GenericRead+GenericWrite to WinInteractiveSid in the DACL; see internal/ipc/transport_windows.go)

  • A service installed under your normal user account creates a pipe that only that user can connect to (DACL grants GenericAll to the user’s SID only)

SCM install requires admin

# Elevated PowerShell required
radioactive_ralph service install

Non-elevated terminals get access denied and no service is registered.

Pipes die on reboot

Windows named pipes are per-session objects; they don’t persist across reboots. This is normal. The installed service recreates the pipe on start. Don’t confuse a post-reboot “pipe does not exist” error with a bug.

Windows Defender / SmartScreen

First run may trigger SmartScreen warning (“Windows protected your PC”). Fix: right-click the binary → Properties → Unblock. Or sign the binary (v1 doesn’t).

PowerShell execution policy

If scripts in .radioactive-ralph/ scripts fail with “running scripts is disabled on this system”:

Set-ExecutionPolicy -Scope CurrentUser RemoteSigned

(One-time, per-user.)

Windows CI vs native Windows

The CI smoke test (.github/workflows/ci.yml Test (windows-latest)) runs the service lifecycle on a GitHub-hosted runner. It’s sensitive to:

  • Process exit races — see the HasExited poll in the smoke script (not Wait-Process, which throws when the PID is already gone)

  • Named-pipe name collisions between parallel CI jobs — the pipe name includes a per-job random suffix in test mode

  • Long-running workers that exceed the default job timeout — keep integration tests under 2 minutes

If a Windows CI flake doesn’t reproduce on a real Windows machine, suspect hosted-runner instability and rerun before investigating.

WSL2

WSL2 is “Linux on Windows” from the binary’s perspective — install the Linux tarball, run the Linux systemd integration. Two caveats:

  • WSL1 is not supported. Systemd doesn’t run on WSL1.

  • Cross-filesystem ops (repo on Windows disk via /mnt/c/...) are slow. Keep repos on the WSL filesystem (~/src/) for the service to stay responsive.

Docker / containers

Untested in v1. The binary runs in Alpine + glibc containers, but the OS-service integration (launchd/systemd/SCM) doesn’t — use service start in the foreground instead. Future work: a systemd-in- container or tini-managed container mode.