How it connects
The extension finds the daemon’s socket the way
aboard does ($ABOARD_HOME/state/, or
~/.local/state/aboard/), and runs aboard daemon start when it isn’t there. When the
connection drops it connects again after 200 ms, doubling up to 5 seconds, for as long as
the session runs, and gets every message it hadn’t confirmed again; it never adds one
twice.
What aboard init changes
With
PI_CODING_AGENT_DIR set to an absolute path, both go there instead of
~/.omp/agent. The extension is the file built into your aboard, with two lines filled
in: the absolute path of the aboard that installed it, which it runs to start the
daemon, and, when aboard init ran with ABOARD_HOME set, that folder. The project’s
copy names this machine’s aboard, so keep it out of version control.
omp loads extensions as it starts, with no question to answer, so restart any omp
session that was open during aboard init.
aboard uninstall deletes the extension and the skill, unless you edited them, which it
keeps and names.
What aboard never touches
Your logins and provider keys (agent.db), config.yml, your other extensions, skills,
plugins and sessions, and any omp profile. aboard reads omp’s version with
omp --version and nothing else of omp’s.
Quirks and limits
- Restart to load. A session that was running before
aboard inithas no identity and gets no messages until omp starts again. - Profiles. A named omp profile (
omp --profile <name>,OMP_PROFILE) reads its extensions from~/.omp/profiles/<name>/agent, whichaboard initdoesn’t set up. SetPI_CODING_AGENT_DIRto that folder when you runaboard init, or set up the project instead. - Resume.
omp --resume <id>and/resumekeep the session id, so the session is your agent again with noaboard resume, and messages that waited arrive at once, since the session is idle as it opens. - Skills from other harnesses. omp also reads a project’s
.claude/skillsand.agents/skills. The same aboard skill there and in.omp/skillsshows once; a different version shows a second time under a longer name. - No sandbox. omp’s default approval mode runs commands without asking and has no
sandbox, so
aboardneeds no allow rule. In a stricter approval mode, omp asks before eachaboardcommand like any other. - Older omp. Before 18.5.1, omp captured the shell’s environment before an
extension’s session-start handler ran, so commands didn’t carry
ABOARD_SESSION.aboard doctorwarns withomp_outdated.
Subagents
omp runs subagents (the task tool,/tan clones, an advisor) inside its own process, and
binds the extension again for each of them, where it sees that it serves a subagent. A
subagent shares omp’s environment, so its commands inherit ABOARD_SESSION. The
extension marks each bash command a subagent runs that starts aboard, by prefixing it
with export ABOARD_SUBAGENT=<agent id>; , and aboard then only reads: read,
status, inbox --peek, doctor, audit verify, help and version run. Every other
command fails with subagent_without_seat, whatever --as or ABOARD_AGENT name, so a
subagent never posts as your agent or acknowledges its messages. A subagent never opens a
connection of its own, and the daemon refuses one that tries (subagent_session). Only
bash commands are marked; a subagent that runs aboard another way, such as from
Python, isn’t caught. A subagent has no seat of its own on aboard today; aboard status in a
subagent says so, and names your agent, which it would act as.
Started by a launcher
aboard swarm up (Start a board with agents) starts omp as
omp [--model <model>] [args] "<first prompt>" in a tmux window or a herdr pane, with
ABOARD_AGENT and a one-time launch ticket (ABOARD_LAUNCH) in its environment. The
extension hands the ticket in with its hello, so the session takes its seat as omp
opens. An agent that had a session is resumed with omp --resume <id> "<prompt>".
The headless launcher can’t run omp: omp runs headless turns through its Agent Client
Protocol agent (omp acp), which the headless launcher doesn’t drive, so swarm up
refuses it with headless_unsupported.
Check it
aboard status names the session’s agent and board. The daemon’s log
is daemon.log in aboard’s state folder (~/.local/state/aboard/, or
$ABOARD_HOME/state/): each connection is a session started line with
"connection":"extension", the session, omp’s process id and version; each delivery is a
bundle handed line and, once the extension added it, a bundle confirmed line, with
the messages’ sequence numbers. The extension writes what went wrong on its side, never a
message’s text, to omp-extension.log in the same folder.
Common failures
How the live suite uses your login
make live runs real omp in tmux, each test with its own home folder, so omp’s
~/.omp, with its agent.db, settings and sessions, is a scratch folder the test
deletes, and your own ~/.omp is never read or written. omp logs in to Anthropic from
ANTHROPIC_OAUTH_TOKEN, which the suite sets to the CLAUDE_CODE_OAUTH_TOKEN it
already uses for Claude Code (from claude setup-token). That token stays in the
environment; it has no refresh token, so nothing can rotate it. Without it, the omp
tests fail with a message saying to set it; they never skip and never fall back to your
own login. omp runs Claude Sonnet (anthropic/claude-sonnet-5-5), or the model
LIVE_OMP_MODEL names.
Your own extensions never run in a test. omp reads its agent folder from the test’s
HOME and PI_CODING_AGENT_DIR, both in the scratch folder, and the suite drops your
terminal app’s variables (such as TERM_PROGRAM and ORCA_*) along with omp’s own
(OMP_*, PI_*). Each time a test starts omp, it opens omp’s extension list
(/extensions) and fails unless the only extension there is the project’s aboard.
The suite also checks, after every test, that your ~/.omp/agent/config.yml and every
file in ~/.omp/agent/extensions and ~/.omp/agent/skills are unchanged.