github akitaonrails/ai-jail v1.19.3

latest release: v1.20.0
4 hours ago

Fixed

  • macOS agents installed by Homebrew can start again. The seatbelt read
    list is the counterpart of the Linux base mounts, and it never contained
    /opt. Intel Homebrew installs under /usr/local, already reachable through
    the /usr grant, so the gap was invisible on that architecture — but on
    Apple Silicon everything Homebrew installs lives under /opt/homebrew, the
    sandbox could not see it, and sandbox-exec failed the exec with
    execvp() of 'claude' failed: No such file or directory before the agent
    ever started. Reported by @commonsguy (#120).
  • An agent may now live anywhere, not just under $HOME. The read grant
    for the invoked command searched only below the home directory. That is right
    on Linux, where everything outside the private $HOME is bind-mounted
    regardless, but a seatbelt profile denies by default everywhere, so an agent
    under /Applications or /nix/store received nothing. macOS now resolves the
    command the way exec does and grants its symlink chain plus the final
    target's directory, wherever that is — still the binary and its install
    directory, never the whole prefix.
  • --inherit-env on macOS passed no environment at all. It is documented as
    handing the child the entire parent environment, secrets included. Instead the
    child got nothing — not even PATH — because the environment was cleared and
    then rebuilt from an empty list. The Linux backend reaches the documented
    result by omitting --clearenv; seatbelt now starts from the host environment
    and applies env_pass on top.
  • In-project maps are no longer refused when the project is reached through a
    symlink.
    The containment check walked past the project root: the root it
    compares against is canonicalized and the candidate path is not, so when any
    component above the root was a symlink the walk never recognised the root,
    continued upward, and rejected on that symlink — the one case it explicitly
    treats as irrelevant, since canonicalizing already resolved it. Every map with
    a not-yet-existing destination inside the project was refused. This is
    permanent on macOS, where $TMPDIR lives under /varprivate/var, and
    reachable on Linux through a symlinked home.
  • Every generated macOS profile carried a duplicate read rule, because /etc
    and /private/etc are one directory and the rules are emitted canonically.

Packaging

  • The Nix package no longer drags the Rust toolchain into its runtime closure.
    It is built with a minimal rustc/cargo instead of the aggregated
    toolchain, and store paths are remapped out of the binary, so rustfmt,
    clippy, rust-analyzer, rust-src, rust-docs and rust-std stop being
    runtime dependencies: 47 store paths down to 12. Thanks to @wtf9880 (#116).

Continuous integration

None of the above is a new class of mistake. All of it was invisible because two
checks reported success without checking what they claimed.

  • The macOS test suite had no runner. It ran on tag push until v1.18.0 split
    the release matrix and left the macOS leg building without testing.
    sandbox/seatbelt.rs is #[cfg(target_os = "macos")], so the Linux job only
    ever compiled its tests through the cross-target clippy step. Every seatbelt
    test written after that was merged unrun. ci.yml now runs the suite on
    macos-latest; its first run failed 26 tests, and the release workflow's macOS
    leg tests before building again, as it used to.
  • nix flake check never built the package. It realizes checks.* only,
    reporting the package as derivation evaluated to ...ai-jail.drv and stopping
    there, so the job added to stop NixOS regressions was verifying that nixfmt
    and treefmt pass. ci.yml now runs nix build .#default, and asserts that
    the runtime closure carries no Rust toolchain — the packaging fix above is
    otherwise invisible to every check, since reverting it still builds and still
    passes every test.

Checksums (SHA256)

31c22e3d5e85afabd63dbe0b662168a8b5b9e77ec455b9c976791a3d2ca4d791  ai-jail-linux-x86_64.tar.gz
72dc94db25ee6100cbc481b5b6f1a8436049bd90a554350a6422a7df912e74e7  ai-jail-macos-aarch64.tar.gz

Install

brew tap akitaonrails/tap && brew install ai-jail
yay -S ai-jail-bin
cargo install --locked ai-jail

Don't miss a new ai-jail release

NewReleases is sending notifications on new releases.