orbotodocs
Agents & AI

The orboto mod for Claude Code

Install the orboto mod to guard edits and commits behind a claimed ticket, put the session's scope into the system prompt, and see wake events, the inbox and your claim in Claude Code itself.

Added in v0.214.0 The orboto mod is a Claude Code plugin that runs inside the Claude Code process and talks to orboto through the orboto CLI. It adds, on top of what orboto claude and the wake channel already give a session:

  • a claim guard: Edit, Write, NotebookEdit and git commands that create commits are refused until the session holds a claimed ticket;
  • the session's scope and the binding rules in the system prompt, on every request, so they survive a compaction;
  • wake events as toasts: a ticket-ready, request, error or digest message shows up on screen;
  • a status line entry with the role, scope, claimed ticket, unread mail and capacity claim;
  • the /orboto pane and the command /orboto claim.

The mod holds no credential. It never reads a token, never prints one, and redacts anything token-shaped from command output; it only runs the orboto CLI with the login your session already uses.

What you need

Claude Code 2.1.287 or later, the orboto CLI signed in, and a session that declared an orboto scope (an orboto claude start inside a connected repository does). The mod is for Claude Code only. Codex, Gemini CLI and Kimi keep the shell integration: the Stop hook, the status line command, and the wake channel or orboto messages --follow.

Install

In Claude Code:

/plugin marketplace add orboto/claude-plugins
/plugin install orboto-mod@orboto

The options appear in /config. Restart the session after a /plugin update: a reload of a marketplace install without a restart is not verified.

To try a local copy of the plugin folder, start Claude Code with it:

claude --plugin-dir path/to/orboto-mod

An interactive session watches a --plugin-dir folder and reloads the module after you save it, at the end of the turn that saved it.

Options

Option in /configValuesDefaultEffect
orboto profilea profile nameemptyThe CLI profile the mod's CLI calls run as. Empty uses ORBOTO_PROFILE, or the .orboto-profile file of the working directory.
Claim guardenforce, warn, offenforceenforce denies the guarded calls while the session holds no claimed ticket; warn only shows the toast; off disables the guard.
Paths the claim guard never blockscomma-separated prefixesemptyPrefixes inside the checkout that need no claimed ticket: relative to the repository root, absolute, or starting with ~/. Example: docs, ~/notes.
Wake events the model readsall, actionableallall passes every wake event to the model and shows it as a toast and in the pane. actionable keeps digests and info and complete mail in the toast and the pane only, so they cost no model turn.
Refresh interval30, 60, 120, 300 seconds60How often the mod reads the claim, the inbox and the capacity claims through the CLI.

The claim guard

The guard refuses a call while the session holds no claimed ticket, and names the fix in a toast: orboto claim <KEY>, with the key of the latest ticket-ready wake or of the declared ticket scope when there is one. A claim is a running timer of this session (orboto ticket claim, orboto timer) or a work session (orboto work-start).

What it recognises:

  • the tools Edit, Write and NotebookEdit;
  • the git commands commit, merge, cherry-pick, revert, am, rebase and pull in a Bash command, on any line of a multi-line command, with line continuations and multi-line messages;
  • behind env, sudo, command, nice, time, xargs, an absolute path to git, git's own options such as -C and -c, and variable assignments;
  • inside bash -c and sh -c (also with options before -c, as in bash -o pipefail -c), eval, backticks and $(...), also inside double quotes;
  • with a quoted verb such as git $'commit', in subshells, and after cd: the directory the commit runs in counts, not the session's.

What it lets through on purpose: --abort, --quit, --skip, --dry-run, merge --no-commit, revert -n, cherry-pick -n, pull --ff-only, merge-base, stash, and text that only mentions git: echo, heredoc bodies, here-strings, comments and single-quoted text.

What it does not see. A file written by Bash itself (sed -i, cat > file <<EOF, tee, a script) is not a tool call the mod can tell from a read, so it passes. A command held in a variable (g=git; $g commit) and a Python or Node wrapper around git cannot be read statically either. The Stop hook (orboto session-check) stays the line that catches unclaimed work when the turn ends, and the rule "ticket first, claim before code" applies to every write, guarded or not.

Where it acts. Only inside the session's repository (the main checkout and, for a worktree created elsewhere, the worktree's own root), and only for a session that declared a scope. Paths outside it, such as a scratch directory or a separate docs repository, are never guarded. In a ticket-scoped session /orboto claim accepts exactly the declared tickets, not their siblings.

Passive, offline and slow

  • Outside a repository the mod is passive: it makes no orboto call and starts no refresh. /orboto refresh reads once when you ask. The system prompt gets one neutral line and the status line says so.
  • In a repository without a declared scope it reads once at session start, then nothing until a scope appears (orboto session-start in Bash, or /orboto refresh).
  • When the CLI is missing or the instance refuses the guard stays open, says so once in a toast, and reads again at most every 30 seconds. The status line shows orboto: offline (<reason>). The refresh backs off from 60 to 120, 240 and at most 300 seconds while the instance does not answer.
  • When the CLI is slow the guard keeps its last answer: a claim stays a claim, no claim stays a refusal. The status line says "stale" and one toast says the CLI did not answer. The guard's own read gives up after 3 seconds; when the regular refresh is already reading, the guard waits for it for up to 8 seconds. The claim is read once per turn, and a Bash orboto claim (or orboto ticket claim), work-start or close marks it stale.

Scope in the system prompt

One section is added to the system prompt, after the cache boundary: role, declared scope, the claimed ticket, the binding rules and the index of the workspace rules with their hash. It carries no counters and keeps the last good read while the instance is unreachable, so it changes only when the claim, the scope or the rules change. It names a refusal only when the claim guard is enforce. With Wake events the model reads set to actionable it also says that digests and info and complete mail stay out of the model, instead of asking the model to acknowledge mail it never sees.

Wake events and the inbox

The events of the wake channel reach the mod as channel deliveries. It turns ticket-ready, request, error and digest events into a toast and an entry in the pane. Every refresh interval it also reads the inbox, so new mail is toasted even where the channel is not running.

The inbox read uses peek: it does not mark mail delivered and records no poll wake, so the stale-mail triage still sees mail no session was handed. peek needs an instance on 0.214.0 or later. The answer decides, not the version string: the first inbox read of a session asks with peek, and an answer that confirms it keeps the read on. An answer that does not confirm it switches the inbox read off for that session, the status line says "inbox read off", and one toast names the instance's version. On an older instance that first read is an ordinary list, so it marks the listed mail delivered and records its poll wake, once per session. Like every authenticated agent request, the read carries the unread-mail header, which only records that the backlog was seen; it is no delivery.

The status line and the pane

The status line entry reads <role> <scope> · <claimed ticket> · <n> unread · <capacity claim state>, or orboto: offline (<reason>). While the mod has a reachable read and a declared scope, the native status line of orboto claude leaves scope and ticket out and keeps model, context, branch, effort and rate limits, so the scope and claim appear once. Offline, passive or outside a repository the native line shows them again.

/orboto opens the pane: scope and session, the claimed ticket with its checklist, the inbox digest and recent wake events, the link to the live session, the capacity claims and the hash of the rules. Inside it:

CommandEffect
/orboto claim <KEY>Claims the ticket. Refuses a key outside the declared scope, and refuses to replace a running claim unless you add --switch, which stops the running timer and claims the new ticket.
/orboto messagesLists the inbox like orboto messages does, and marks the mail delivered.
/orboto session-checkRuns orboto session-check and draws the result. It behaves as the command does, including releasing idle capacity claims when stopping is right.
/orboto refreshReads the claim, the inbox and the capacity claims now.

What the mod runs

Only the orboto CLI, with the session's own environment, the profile option and git rev-parse to find the repository. All of its reads are get calls and ticket reads: the claim and timer, the session and its unfinished work, the inbox (with peek), the capacity claims, the claimed ticket with its checklist, and the workspace rules every 15 minutes. The only write is orboto claim, and only when you run /orboto claim.

Headless sessions

A claude -p run loads the mod and guards the same way, but there is no screen: toasts, the status entry and the pane go nowhere, and the refusal text is the only feedback. The refresh keeps running for the life of the run.

See also Claude Code, step by step, Claude Code: the wake channel and Sessions, scope and the wake ledger.

On this page