# Limitations
> Where ivar's guard stops, and what ivar does not isolate or coordinate for you.
Source: https://ivar.run/docs/reference/limitations

## The write guard is a guardrail

Repos you haven't promoted are guarded: ivar keeps the agent's writes inside
the feature and refuses commits on the default branch. It is a guardrail against
agent mistakes, not a security boundary. (Kernel-enforced on Linux; see
limitations below.)

The write guard is designed to catch unintended edits, wrong-directory file
creation, or agents straying outside the promoted repositories of a feature. It
does not protect against a determined process executing arbitrary local code as
your user.

## By platform and launcher

Write enforcement depends on the operating system and how the session was
launched:

- **On Linux (kernel ≥ 5.13 with Landlock):** When launched via `ivar session start`
  in a terminal (with a TTY), ivar applies an irreversible, kernel-enforced
  `Landlock` write sandbox to the harness process before execution. Writes to
  unpromoted repositories or outside allowed session roots fail directly at the
  syscall layer with `EACCES` (`Permission denied`), including writes from Bash
  subprocesses.
- **On macOS, on kernels without Landlock, and under `ivar session connect`:**
  Kernel sandboxing is unavailable. Protection relies on filesystem permissions
  where only the worktree root loses its write bits (`mode & !0o222`), and
  files in subfolders stay writable.

## Other worktrees of a promoted repo

On Linux, when a repository is promoted for a feature, Landlock grants write
access to the entire `.ivar/repos/<repo>/` directory.

This allows ivar to create worktrees and handle Git operations smoothly, but it
means that other feature worktrees and the default branch checkout of that same
promoted repo remain writable at the kernel level.

## The hook and the view dir

In sessions launched by `ivar session start`, the advisory tool guard hook
does not execute in the session's view directory. As a result, when an agent
attempts an unauthorized write under Landlock on Linux, it sees an `EACCES`
error from the kernel rather than an advisory diagnostic message naming
`ivar feature promote`.

## Shared state outside git

A Git worktree gives each feature its own working tree and files, but it does
not isolate shared external daemon state such as databases, caches, or
background services.

Two features promoting the same repository share the same local database unless
configured otherwise. To isolate services per session, use session hooks
(`.ivar/setups/<repo>.session.sh`) which run on every `ivar session start` with
`IVAR_SESSION_ID` exported:

```sh
# docker compose: unique project name per session
export COMPOSE_PROJECT_NAME="${IVAR_SESSION_ID}"
docker compose up -d

# postgres: dedicated database per session
createdb "app_${IVAR_SESSION_ID}"
export DATABASE_URL="postgres:///app_${IVAR_SESSION_ID}"
```

## Ports

A session reserves port allocations in local state, preventing two ivar
sessions from being assigned identical ports.

However, ivar does not proxy network traffic or force arbitrary background
processes to bind to their assigned port. If a process ignores its environment
configuration or crashes without releasing a socket, collisions can still occur.

## Local state is disposable

Everything stored under `.ivar/` (except versioned configuration in `.ivar/skills/`
and setups) is local derived state: bare clones, worktrees, socket reservations,
and SQLite indexes.

Deleting `.ivar/` discards no committed history or pushed branches—it requires
only re-cloning repositories and recreating active sessions. Never store
uncommitted artifacts or credentials in `.ivar/`.

## No atomic push across repos

When delivering across multiple repositories, local fast-forward merges into
the default branch are verified and coordinated locally. However, the subsequent
remote `git push` operations are executed independently against each remote.

There is no distributed transaction across distinct Git remotes. If a network
failure occurs during push, ivar reports the failure and indicates which
repositories were pushed and which remain ahead locally. Merges are not rolled
back across remotes to compensate for push failures.

## What protects the default branch

Protection for the default branch is multi-layered:

1. **Pre-commit hook:** `ivar sync` configures a worktree-local Git `pre-commit`
   hook on the default-branch worktree that rejects direct commits. (Bypassed
   only during programmatic squash delivery landings or with explicit
   `--no-verify`).
2. **Worktree root write bits:** Default branch worktrees have write permissions
   removed on the root directory to prevent accidental file creation or deletion
   at the repository root.
3. **Landlock write sandbox (on Linux):** Restricts unpromoted repository trees
   at the syscall level during `ivar session start`.
4. **Structured tool guard:** The advisory hook inspects structured edit tool
   invocations when running in supported harnesses.
