github akitaonrails/ai-jail v3.3.0

one hour ago

v3.3.0

Linked Git worktrees can now share one saved policy, and five fixes make the
onboarding and launch paths stop producing states that cannot launch.

Backward compatible: without the new setting, every project keeps its own
policy exactly as before, and existing profiles keep working.

Added

  • project_strategy = "repo-root" shares policy across linked worktrees
    (#218, closes #219).
    By default the saved policy is keyed by the launch
    directory, so each git worktree add was a new project that had to be
    onboarded again. With this trusted, global-only setting, the root of a
    linked worktree resolves to its main repository's saved policy: the mounted
    project stays the worktree, and only the approval, identity, onboarding
    state, directory grants, and forge bindings are shared. The worktree's
    repository metadata passes the same structural validation as
    --worktree (GHSA-w976-gw52-hvx2) before it can select a policy; refused
    metadata, a missing main checkout, and bare repositories fall back to the
    launch directory, and a store inside either checkout is refused. The
    configure header and status --json (project.policy_path) name the policy
    actually in use, and a launch that ignores a directory's own saved policy
    says so. Restrictions always merge into the shared document, so one
    checkout cannot drop what another saved. docs/SECURITY.md records the
    remaining boundary: repository-authored metadata is not user-authored, so
    an agent that can write a repository's git directory can select that
    repository's policy. Only worktree roots resolve today — subdirectories
    still onboard per directory, and the user guide says so explicitly,
    including where this differs from ai-memory's marker setting of the same
    name. Thanks @xico42.

Fixed

  • Mostly open no longer saves a profile that cannot launch (#221, closes
    #220).
    The preset enabled unrestricted network and still recorded the
    model API host as a filtered destination, and the launcher refuses
    --network combined with filtered hosts. The API host is now omitted
    whenever unrestricted network is on. A profile saved in the broken shape
    fixes itself the next time it is saved.

  • Pending wrapper requests block the launch even when the harness is
    unknown (#222).
    The pending-request check lived on the branch that
    resolved a harness, so a launch whose command was not a known harness
    started with an unapproved request still pending. It now runs before the
    launch path in every noninteractive case, with status, --dry-run, and
    --init still reporting instead of blocking.

  • status ignores SSH key drift for a selected-key agent that will not
    run (#223).
    A launch disables the restricted agent when SSH is turned off,
    under --lockdown, or when full SSH applies; the status blockers now apply
    the same condition instead of reporting a changed key that the launch would
    never use.

  • Redirected stdin is handed to the child instead of the PTY proxy (#224).
    With terminal output and piped or file stdin, the proxy claimed stdin,
    applied raw mode to a non-terminal, and could fail before the workload
    started. stdin now stays inherited with its natural EOF, and only a real
    terminal enters raw mode and is proxied.

  • Saving UI preferences no longer rewrites the global policy document
    (#225).
    The save path rebuilt the whole file from a typed structure that
    deliberately omits credential fields, so a status-bar preference could drop
    env_pass, env_from_file, and secret_hosts. It now patches the two
    preference keys in the existing document and verifies the result round-trips
    to the intended policy before writing, leaving credential fields, command
    tables, and project_strategy intact.

Notes

  • New test coverage: a project_strategy integration suite over the real CLI,
    a piped-stdin PTY suite, wrapper-contract coverage for the unknown-harness
    case, and a migration test that proves a preference save preserves shared
    policy. The linked-worktree fixture now hands out canonical paths (macOS
    temp roots sit behind /var), and launch tests skip when the platform
    sandbox cannot start, so the suite also passes inside a Nix build sandbox.

See the user guide for the linked-worktree walkthrough
and the security model for the boundary it documents.

Checksums (SHA256)

02df4b7471ba9babe53ef330dd3388929432262b700a75e0ffd2d4071e756a19  ai-jail-linux-x86_64.tar.gz
533852db188f4bd01184b4e969aaa94e99257040599d1750ce3617671116e981  ai-jail-macos-aarch64.tar.gz
e8ab5208666951d06343e11cf3dc74ba50e7b8c75e685061091ae44b15ecfcf5  ai-jail_3.3.0_amd64.deb

Install

brew tap akitaonrails/tap && brew install ai-jail
yay -S ai-jail-bin
cargo install --locked ai-jail
# Debian/Ubuntu: download the .deb below, then
sudo apt install ./ai-jail_*_amd64.deb

Don't miss a new ai-jail release

NewReleases is sending notifications on new releases.