Skip to content

v0.1.46

Latest

Choose a tag to compare

@github-actions github-actions released this 23 Oct 09:51
fc1578b

The jail hides the user bus

On Linux, a jailed worker could reach systemd-run --user through the session bus in $XDG_RUNTIME_DIR and start a command outside the jail. Landlock below ABI 6 does not govern connecting to a socket by path. shepherd-ai 0.3.18 (fork, pinned in pyproject.toml and uv.lock) puts bubblewrap in front of the Landlock runner and mounts an empty tmpfs over each directory where a command server keeps its socket: the runtime directory, tmux-<uid> and screen's S-<user>. The jail probe checks inside the real jail that nothing else is visible.

Without bubblewrap the worker still runs. If bubblewrap is not installed, if AppArmor denies its user namespace, or if its trial run does not finish within 10 s, the worker runs with that path open. The same goes for a user who can write to a Docker socket. The CLI prints one warning at the start naming the paths, the reason, and how to close each one: install bubblewrap, or accept running without that protection. --provider codex|grok runs under its own CLI's sandbox, which the mask does not reach, and the warning says so.

The memory limit wraps the jail

--memory-max moved out of the worker argv and now wraps the jail, so the limit covers every confined launch. A host without Landlock refuses the limit.

Host-side programs keep the user's environment

A repo's jail_env used to reach what shepherd-dev runs on the host for itself: git, cp, ps, ssh, notify, the planner's and the optimizer's claude, and the native gate's node --version and pytest lookup. Those programs now resolve once, on the user's PATH, and run with the environment shepherd-dev started with. jail_env refuses LD_*, DYLD_*, PYTHON*, SHEPHERD_DEV_*, GCONV_PATH, LOCPATH and the command servers' socket variables, and names each refused key on stderr. On Linux, the memory scope, bubblewrap and the runner also start with the user's environment; only the confined command gets the repo's values. On macOS, sandbox-exec still starts with the repo's values.

Known consequence: test command detection now answers for the user's PATH while the gate runs with the repo's. A repo that sets pytest only through jail_env should set test_cmd.

CI tests the pinned framework

The CI jobs and the release suite installed shepherd-ai from PyPI, not the pinned fork wheel. They now install uv.lock with pip install --require-hashes.

Known open item

When claude is missing from the user's PATH, the worker's provider falls back to looking it up on the live PATH, which may hold the repo's jail_env (review thread on #20).

Details for each item: docs/KNOWN_ISSUES.md.

Full Changelog: v0.1.45...v0.1.46