Skip to content

CLI reference ​

ibni · verb · “to build”
The command-line tool the agent runs to give each task its own copy of the repository, and to push only the exact code recorded as passing its checks.

You rarely run ibni yourself. The coding agent runs it at each step of a task, as /wettaq instructs. You might use a few of its subcommands now and then; they are listed below.

Why it exists. The steps that matter most, such as giving a task its own worktree and pushing its branch, should not depend on an agent saying it did them right. So ibni does them in code. It gives each task its own worktree and port, installs its dependencies and runs its verify command, recording the exact code that passed. ibni then refuses to push any other code, or to push by force. Decision 0004, decision 0006 and decision 0014 explain why.

Every subcommand prints JSON, so the agent can read the result. A few terms recur: a session is one agent conversation, a workspace is a kept worktree with its record, and a gate is a check a run must pass, such as verify. The glossary has the rest.

The agent's lifecycle ​

The agent runs these during a /wettaq run, in this order. verify runs once before the change and again whenever the committed code changes. setup runs only when adopt says the dependencies are out of date, or after a commit changes a lockfile. record runs whenever a browser check or review finishes, and publish-media only when the run has screenshots. publish brings in the latest default branch itself; the agent runs sync first when it picks up an existing pull request for a follow-up.

sequenceDiagram
  participant A as Agent
  participant I as ibni
  participant G as Git and the forge
  A->>I: prepare
  I->>G: new worktree and branch from the default branch
  Note over I: installs dependencies from the lockfile or .mexxi.json
  A->>I: verify (the baseline)
  opt follow-up on an existing pull request
    A->>I: sync
    I->>G: bring in the latest default branch
  end
  A->>I: verify (the committed change)
  Note over I: runs the verify command, remembers the exact code that passed
  A->>I: record (each browser check and review)
  A->>I: record-evidence
  A->>I: publish
  I->>G: bring in the default branch, push, never by force
  opt the run has screenshots
    A->>I: publish-media
    I->>G: screenshots to the pr-media branch
  end
  A->>G: open the pull request
  A->>I: mark-pr

ibni prepare ​

An agent working in your checkout trips over your own work and over other tasks, so each task starts in its own worktree.

text
Usage: ibni prepare --slug <name> [--prefix <prefix>]

Create an isolated worktree and branch for a new task.

Run from the repository's clean primary checkout on its default branch. Fast-forwards it,
sweeps retained workspaces whose pull requests are proven merged, then creates a locked
worktree, its evidenceDir and a free block of ports (workflow.ports in config.json), chosen under
a machine-wide lock so no two workspaces in any repository share one. port is the block's first;
portEnv is what setup and verify get: PORT, MEXXI_PORT_0..<blockSize-1>, and the variables
workflow.portVariables maps for this repository.
verifyCommand is the repository's verify command: verify in its committed .mexxi.json,
or npm run verify when that names none.
Then installs dependencies in the new worktree, without holding the repository lock: setup in
.mexxi.json, or the root lockfile's own install (package-lock.json: npm ci --prefer-offline
--no-audit --no-fund; pnpm-lock.yaml: pnpm install --frozen-lockfile --prefer-offline). With
neither, or more than one lockfile, setup.ran is false and setup.reason says why. Without a setup,
setup.warning names lockfiles below the root that the install leaves out. The log goes
to evidenceDir/setup.log. A failed setup rolls the new workspace back and prints the log's end.
After setup it copies the caches the control checkout has (.next/cache, *.tsbuildinfo, .eslintcache,
node_modules/.vite/vitest; gitignored only, never over an existing path) and reports them as warmCaches.
If .mexxi.json names a ciCheck (the CI run of its full verify command) and that
check succeeded on exactly the base commit, baseline.reused is true and baseline cites the
run, so the local baseline verify can be skipped; otherwise baseline says why it runs.
forge is github or gitlab, from the push remote's host, forge.hosts in config.json or
"forge" in .mexxi.json; null when none is known, and forgeReason then says why.
Prints sessionId, worktreePath, branch, baseSha, forge, evidenceDir, port, ports, portEnv, verifyCommand, baseline, setup, warmCaches, provisionedEnv and cleanup.

Options:
  --slug    Short task name for the branch and worktree folder.
  --prefix  Branch prefix; defaults to workflow.branchPrefix in config.json.

ibni setup ​

Each worktree needs its own dependencies, installed exactly as the repository pins them, before its checks can run.

text
Usage: ibni setup --session <id>

Install the session's dependencies in its worktree.

When adopt reports dependencies.current false, or after a commit changes a lockfile. Resolves
the command as prepare does: setup in the default branch's .mexxi.json, else the lockfile at HEAD. Never
reinstalls on its own. The lock is not held during the install, which gets the workspace's
portEnv, and waits for a run slot and runs in a scope like verify. Writes evidenceDir/setup.log
and prints setup (ran, command, source, passed, exitCode, durationMs, queuedMs, logPath, and logTail
when it failed). Exits 1 when the install fails.
The session's workspace is found from its metadata, so this runs from any directory, including the session's evidenceDir.

Options:
  --session  The sessionId from prepare or adopt.

ibni verify ​

A push should carry only code that passed the repository's checks, so ibni runs them itself rather than taking the agent's word.

text
Usage: ibni verify --session <id>

Run the repository's verify command on the committed tree and record the result.

Runs the session's verifyCommand from the worktree root and refuses on a dirty tree, so the
result belongs to one committed tree. Before the first commit the tree is baseSha's, so this is
the baseline run; when prepare reported baseline.reused, that CI run is recorded instead
(reused) and nothing runs. The command gets the workspace's portEnv, and ibni refuses to start it
while any port of the block is bound, so a test server never fails half-way on a taken port.
At most workflow.verifySlots setup and verify runs go at once on this machine, in any repository;
the rest wait for a free slot, listed in <worktreeRoot>/.ibni/slots/queue, and report it as queuedMs.
Where systemd-run --user works, the run is a transient scope (workflow.scope: CPUWeight, MemoryMax);
stopping it afterwards ends any server or browser the command left, and resources records the
scope's peak memory and CPU time. Elsewhere it is a plain child, and scopeReason says why.
The output goes to evidenceDir/verify-<tree>.log, never to stdout,
and the lock is held only to check and record, so it is safe to run in the background.
When the default branch has no verify command at all (no verify in .mexxi.json, no verify
script in package.json), the one this branch's .mexxi.json names runs instead, and
commandSource is branch; a branch never replaces a gate the default branch already has.
Records verification (treeSha, headSha, passed, exitCode, durationMs, queuedMs, scope, resources, logPath, ranAt) and a
verify entry for stats. A commit or edit while it runs leaves the result unrecorded.
Prints one line of JSON at the end, with logTail when it failed; exits 1 unless it passed and was recorded.
The session's workspace is found from its metadata, so this runs from any directory, including the session's evidenceDir.

Options:
  --session  The sessionId from prepare or adopt.

ibni sync ​

The default branch moves on while a task runs, so the task's branch has to catch up without losing work; on a conflict it stops and changes nothing.

text
Usage: ibni sync --session <id>

Integrate the latest default branch into the session's branch.

Rebases unpublished work, merges into published work, and aborts cleanly on conflict.
The session's workspace is found from its metadata, so this runs from any directory, including the session's evidenceDir.

Options:
  --session  The sessionId from prepare or adopt.

ibni record ​

The agent records each verify run, browser check and review as it finishes, so ibni stats and /irrifletti can show how runs went.

text
Usage: ibni record --session <id> (--verify <pass|fail> | --review <count> [--accepted <count> --reviewer <same|cross>] | --qa <count> | --before-shots <taken|skipped>)

Record a verify run, the finding count of a review or QA pass, or the before-shots decision.

One result per call; stats reports them and compares the gates with Jev's triage.
ibni verify records its own runs; --verify is for a host that runs the verify command another
way, and never satisfies the record-evidence or publish gate.
The session's workspace is found from its metadata, so this runs from any directory, including the session's evidenceDir.

Options:
  --session       The sessionId from prepare or adopt.
  --verify        Outcome of a full run of the repository's verify command: pass or fail.
  --review        Number of findings an independent review pass returned.
  --accepted      With --review: how many of those findings you accepted (fixed).
  --reviewer      With --review: same if the reviewer shares your model family, cross if it does not (cross-review delegated).
  --qa            Number of findings a rendered QA pass returned.
  --before-shots  Whether before-shots of existing UI were taken or skipped.

ibni record-evidence ​

A push should carry only code that passed the checks, so this records exactly which code that was.

text
Usage: ibni record-evidence --session <id>

Record that the committed tree passed the gates.

Required before publish; any later commit needs it again. Refuses (recorded: false,
requiresVerify: true, with a nextAction) unless ibni verify passed on exactly this tree.
The session's workspace is found from its metadata, so this runs from any directory, including the session's evidenceDir.

Options:
  --session  The sessionId from prepare or adopt.

ibni publish ​

Pushing is where an agent can do the most damage, so it happens one safe way: never forced, and only the recorded code.

text
Usage: ibni publish --session <id>

Sync, then push the evidenced branch without force.

Returns published: false with a nextAction when evidence is missing or stale, or when
ibni verify has not passed on the tree it would push (requiresVerify: true).
A push failing with an HTTP 5xx from the Git host is retried once.
The session's workspace is found from its metadata, so this runs from any directory, including the session's evidenceDir.

Options:
  --session  The sessionId from prepare or adopt.

ibni publish-media ​

Screenshots belong in the pull request, not in the code, so they go to a separate pr-media branch in the same repository.

text
Usage: ibni publish-media --session <id> [--files <a.png,b.gif>]

Publish screenshots and recordings from evidenceDir to the pr-media branch.

Allowed file types: .png, .jpg, .jpeg, .gif, .webp, .mp4, .webm.
Files must be inside the session's evidenceDir; returns embeddable GitHub or GitLab URLs.
The session's workspace is found from its metadata, so this runs from any directory, including the session's evidenceDir.

Options:
  --session  The sessionId from prepare or adopt.
  --files    Comma-separated paths relative to evidenceDir; defaults to every media file in it.

ibni mark-pr ​

Cleanup must never remove a worktree whose pull request is still open, so this records which pull request a worktree belongs to.

text
Usage: ibni mark-pr --session <id> --url <pull-request-url>

Record the pull request for a published session.

Cleanup only removes a workspace once its recorded pull request is merged.
The session's workspace is found from its metadata, so this runs from any directory, including the session's evidenceDir.

Options:
  --session  The sessionId from prepare or adopt.
  --url      The pull request's URL.

Commands you might run ​

You might run these yourself now and then, to see what a run left behind or to continue a pull request from a new session.

ibni list ​

Worktrees are kept for follow-up changes, so you need to see which ones exist and why.

text
Usage: ibni list

List the retained workspaces of the current repository.

unmanaged lists folders under paths.worktreeRoot that ibni did not make, such as a worktree added
by hand, which cleanup never removes. It only reports them; look before removing any, since a
workspace another prepare is still making shows here for a moment too.

ibni info ​

A later step, or you, needs a session's paths, port and pull request without guessing them.

text
Usage: ibni info --session <id>

Print one session's workspace: paths, branch, port block, verify command, PR, state and forge, plus the review tool config.json sets.

ports is the workspace's block (first, size, last) and portEnv the variables setup and verify get;
export them when starting a server by hand.
The session's workspace is found from its metadata, so this runs from any directory, including the session's evidenceDir.

Options:
  --session  The sessionId from prepare or adopt.

ibni cleanup ​

Kept worktrees take disk space once their pull requests have merged.

text
Usage: ibni cleanup [--dry-run false]

Remove workspaces whose pull requests have merged into the default branch.

A dry run by default. Keeps a workspace whose pull request is still open, whose worktree has uncommitted changes, that has no recorded pull request, or whose merge it cannot confirm.
unmanaged lists folders under paths.worktreeRoot that ibni did not make; they are reported, never removed.

Options:
  --dry-run  false to remove; anything else only reports.

ibni stats ​

You need to see where a run spent its time and how often its checks failed.

text
Usage: ibni stats --session <id>

Print the session's step timings, setup, verify attempts, finding counts and Jev triage as JSON.

The session's workspace is found from its metadata, so this runs from any directory, including the session's evidenceDir.
verify.history lists each verify run with its outcome, durationMs and queuedMs (the wait for a run slot), and, where the run had a scope, memoryPeakBytes and cpuMs, so you can see whether runs wait too long or need more memory.

Options:
  --session  The sessionId from prepare or adopt.

ibni adopt ​

When you continue a pull request from a new session, /wettaq runs this to pick up its worktree, and only when the worktree provably belongs to that pull request.

text
Usage: ibni adopt --pr <pull-request-url>

Take over the retained workspace of an open pull request from a new session.

Finds the workspace that recorded this pull request, then proves the PR is open, its head
branch is the workspace's branch, and its head commit equals the recorded publication, the
remote branch and the clean local HEAD. Only then does it print a new sessionId.
Ownership moves rather than being shared: the previous session id stops working at once.
Any failed check changes nothing.
Also reports dependencies (whether the worktree's lockfiles match the last recorded setup;
current null when it predates ibni setup) and verified (whether ibni verify passed on HEAD's
tree), each with a nextAction when not. It never reinstalls or verifies on its own.

Options:
  --pr  The pull request's URL, exactly as recorded by mark-pr.

Experimental or host-specific ​

These run only in some setups: an experiment that is off by default, a step only Claude Code uses, and one that needs the browser check's suggestions.

ibni triage ​

Experimental: it tests whether an outside decision model would choose a task's checks better than the agent, without letting it change anything.

text
Usage: ibni triage --session <id> --request-file <file> --contract-file <file>

Ask Jev which gates the change needs, and record the answers (shadow: nothing changes).

Sends one batched request to OpenRouter (jev.endpoint, jev.model) with the request text, the
task contract, the changed paths and diff stats against baseSha; never file contents, diffs,
logs, env files or command output. Secrets are redacted first, and the request stays below
jev.maxPayloadBytes by shortening the path list, then the request, then the contract.
Runs only when jev.enabled is true, the push remote's github.com repository is listed in
jev.repositories and owned by one of jev.owners, and OPENROUTER_API_KEY is set.
Always exits 0 once the session is found: a skip, timeout, 429 (retried once), HTTP error or
malformed answer prints outcome skipped or failed with a reason, and the run carries on.
Prints the outcome only; the answers go to session metadata, where stats reports them
beside the agent's own gate choices.
The session's workspace is found from its metadata, so this runs from any directory, including the session's evidenceDir.

Options:
  --session        The sessionId from prepare or adopt.
  --request-file   File holding the user's request text.
  --contract-file  File holding the active task contract.

ibni cross-review ​

A reviewer from the builder's own model family shares its blind spots.

text
Usage: ibni cross-review --session <id> --mode <discovery|confirmation> --background <file> --target <text>

Run the code-reviewer through codex exec in a read-only sandbox (Claude Code only).

For Claude Code, whose implementer and reviewer would otherwise share a model family. Runs the
shared code-reviewer instructions with models.claude.crossFamilyReviewer as the Codex model,
writes the reviewer's final message to evidenceDir/cross-review-<mode>.md and prints it as review.
Prints delegated: false with a reason when no model is configured or codex is not installed;
then use the code-reviewer subagent and state the reason in the pull request's Evidence.
The session's workspace is found from its metadata, so this runs from any directory, including the session's evidenceDir.

Options:
  --session     The sessionId from prepare or adopt.
  --mode        discovery or confirmation, as for code-reviewer.
  --background  The background file the reviewer reads first (requirements, and for confirmation the ledger and fixes).
  --target      The review target, such as workspace changes against HEAD or a branch range.

ibni file-qa-checks ​

A browser check that keeps finding the same kind of problem should become an automated test, not be repeated by hand.

text
Usage: ibni file-qa-checks --session <id> --from <file>

File rendered QA's suggested checks as qa-check issues, skipping duplicates.

The file lists one check per line (a leading list marker is dropped); each is an issue title.
Creates the qa-check label if the repository lacks it, then an issue per check whose title
(case-insensitive) is not already open or closed under that label. Safe to repeat.
Prints created (title, url) and skipped titles. Needs an authenticated gh (GitHub) or glab (GitLab).
The session's workspace is found from its metadata, so this runs from any directory, including the session's evidenceDir.

Options:
  --session  The sessionId from prepare or adopt.
  --from     File of checks, one per line.

Every subcommand ​

The tool's own overview, from ibni --help:

text
Usage: ibni <command> [options]

Isolated worktrees per task, through to a published pull request. Output is JSON.

Commands:
  prepare          Create an isolated worktree and branch for a new task.
  setup            Install the session's dependencies in its worktree.
  verify           Run the repository's verify command on the committed tree and record the result.
  sync             Integrate the latest default branch into the session's branch.
  record-evidence  Record that the committed tree passed the gates.
  publish          Sync, then push the evidenced branch without force.
  publish-media    Publish screenshots and recordings from evidenceDir to the pr-media branch.
  mark-pr          Record the pull request for a published session.
  file-qa-checks   File rendered QA's suggested checks as qa-check issues, skipping duplicates.
  cross-review     Run the code-reviewer through codex exec in a read-only sandbox (Claude Code only).
  adopt            Take over the retained workspace of an open pull request from a new session.
  info             Print one session's workspace: paths, branch, port block, verify command, PR, state and forge, plus the review tool config.json sets.
  list             List the retained workspaces of the current repository.
  record           Record a verify run, the finding count of a review or QA pass, or the before-shots decision.
  triage           Ask Jev which gates the change needs, and record the answers (shadow: nothing changes).
  stats            Print the session's step timings, setup, verify attempts, finding counts and Jev triage as JSON.
  cleanup          Remove workspaces whose pull requests have merged into the default branch.

Run ibni <command> --help for its options.

Old name: implementation-workspace.