ivar session
Session commands — start, connect, convert, stop, prune and relay, and the read-only guard they set up.
A session is a view directory plus the agent running in it. The view directory is assembled per feature: the promoted repos mounted at its root, all on the feature's branch, with the harness config materialised for whichever provider you opened it in.
Start one
ivar session start billing-currencyOmit the feature and you get a discovery session instead: no feature bound, every repo read-only on its default branch. That is the session to open when you still need to understand a problem before committing to a change.
ivar session start--provider picks the harness when you do not want the hall's default.
--detached creates the session without launching an agent, and the view
directory persists until an explicit stop.
What the view directory looks like
Repos sit at the root, so the agent reads api/openapi.json and writes
web/src/api/billing.ts in one session, with no handoff between them. The
harness config directory — .claude/, .opencode/ or .omp/ — carries the
session's bootstrap instructions and the skills its repos ship (hall skills
are found at the hall root). A repo skill whose name the hall or the user
already uses appears as <repo>--<name>.
The guard
Repos you have not promoted have their write bits cleared: mode & ~0o222,
applied recursively. The kernel refuses the write.
A feature session's writable set includes the session's view directory, the
feature directory, its promoted repository worktrees, and all descendant
subfeatures (their feature directories and promoted worktrees). On Linux,
the Landlock sandbox grants write rights to .ivar/features/ and
.ivar/repos/<repo>/ for each promoted repository at launch, allowing
descendant feature creation and promotion mid-session. Tool-level Edit and
Write hooks restrict structured writes strictly to the feature and its
descendants. The cost: Bash inside a feature session can, at the kernel
level, write any feature's record under .ivar/features/ and any worktree of
those repos, including the read-only default-branch checkout, whose write
bits are cleared on its root only.
chmod, not a prompt
Asking an agent not to touch shared works until it does not. A cleared write
bit does not depend on the model's cooperation. The harness hook only explains
how to promote the repo if it turns out to belong in the feature.
Lifting the guard for a repo is exactly one command — the same promotion
described in ivar feature promote:
ivar feature promote billing-currency sharedReconnect and stop
ivar session connect billing-currency # or a session id prefix
ivar session stop <SESSION_ID>
ivar session pruneconnect re-binds to a live session and re-materialises its view directory,
repairing anything that drifted — repo symlinks, the read-only guards, the
provider's config directory. Use it after an agent restart rather than starting
a second session for the same feature.
stop tears the view directory down and ends the harness. With no id it
stops $IVAR_SESSION_ID, the session you are in, and fails when that is
unset. ivar session stop --all stops every session in the hall. prune removes dead
sessions: view directories that exist but whose state.json cannot be read.
Convert a discovery session
ivar session convert <SESSION_ID>Binds a discovery session to a feature and moves its view directory into that feature's session tree. Conversion keeps or derives the discovery feature name without asking for a second positional argument. It is one-way: a feature session cannot be turned back into a discovery session.
Relay to another harness
Nothing in the view directory belongs to a particular vendor — the worktrees are git, the manifest is JSON, the skills are folders of Markdown. A session relays to a different provider with the same branch and the same context, and nothing is uploaded to do it.
ivar session relay billing-currency --provider opencode--provider is required: a relay exists to switch harnesses. Both start and
connect emit the same binding keys, so whatever drives the session can read
IVAR_SESSION_ID, IVAR_FEATURE and IVAR_SESSION_PATH the same way either
way.