Skip to content

Agents

Rendered from knowledge/exobrain/agents.md — the text an agent reads.

An exobrain serves any AI coding agent — Claude Code, OpenClaw, Codex, others added later. Content is written universally by default; agent-specific bits are isolated so they never bleed into another agent’s context. This file describes that isolation.

For the skill-loading side of the same machinery, see skills.md.

Agent CLI Marker (in repo) Per-user config dir
Claude Code claude .claude/CLAUDE.md ~/.claude/
OpenClaw openclaw .openclaw ~/.openclaw/workspace/
Codex codex .codex ~/.codex/

A marker is the agent’s generated surface (or a file beside it), and its presence means “this agent is wired here — keep it maintained.” Connecting is the human act; from then on the post-merge git hook re-links each agent whose marker exists and silently skips the rest. Disconnecting an agent is removing its marker.

Every marker is therefore a gitignored file the connector generates, never a committed path like the .claude/ directory — that ships in every clone for its settings.json, so it proves the clone rather than the choice. connect-agent.sh and exobrain-healthcheck.sh test the same three paths.

Specs, skills, and docs are written so the same content works for every agent — “the agent reads SKILL.md”, not “Claude reads SKILL.md.” The universal AGENTS.md names no primitives; the per-agent sidecars translate. When a skill genuinely depends on one agent’s runtime, mark it agent: "<name>" in skills.json; the opposite-shaped skipAgents: [...] excludes specific agents. See skills.md § Agent filtering.

At any scope (the repo root, a group/person/host, or a standalone scope like seed/), three sidecar filenames are recognized alongside AGENTS.md: CLAUDE.md, CODEX.md, OPENCLAW.md. Each loads only when connect-agent.sh runs for that agent. Use them for tooling-primitive names (“use Edit, not Bash sed”), MCP registration commands, and per-agent quirks. Content that applies under all agents goes in the universal AGENTS.md at the same scope — never duplicated into each sidecar.

Scripts that depend on a specific agent’s runtime use a <name>.<agent>.sh suffix. Universal scripts have no suffix. The invoker picks the right variant; connect-agent.sh doesn’t manage these paths.

Isolation is enforced at link and fetch time, not by convention:

  • The Codex connector writes its context and skills inside the checkout and leaves personal Codex home files and symlinks untouched.
  • The linker skips CLAUDE.md / OPENCLAW.md sidecars when injecting for Codex.
  • The fetcher skips external entries tagged for another agent.
  • The generated optional-skills.md excludes any skill not visible to the running agent.

The rule: any agent-specific artifact must be invisible to other agents. If it isn’t, the agent filter is the bug.

Each agent pulls auto-loaded specs into its prompt differently; the content is identical across agents.

Agent Connected-scope specs Generated indexes
Claude Code .claude/CLAUDE.md @-imports .claude/connected-scopes.md — a manifest of @-imports to each connected scope’s live source AGENTS.md/sidecar (by reference, not copied) The same CLAUDE.md @-imports .claude/optional-skills.md, .claude/tools-index.md, .claude/knowledge-index.md
Codex The whole composition is written to an in-repo, gitignored AGENTS.override.md, read natively — it outranks AGENTS.md at the same directory level Inlined in AGENTS.override.md
OpenClaw Inlined into USER.md via a marker block (<!-- BEGIN exobrain --> … <!-- END exobrain -->) Inlined in the same block

All three deliver the same content — each connected scope’s specs (shallow→deep) plus the generated indexes — differing in delivery and in how the global scope (root AGENTS.md) arrives. Claude @-imports a manifest pointing at the live source files, so a scope edit shows up without a recompose, and lets the checked-in root CLAUDE.md load the global scope; OpenClaw and Codex get the global scope inlined: OpenClaw’s sessions start in its own workspace, whose AGENTS.md is the runtime’s conventions file, so the connector copies the root AGENTS.md into the USER.md marker block; Codex’s AGENTS.override.md replaces AGENTS.md, so the file must be self-contained.

A single run:

  1. Resolve config — establish connected_scopes + the person id from one of four sources, in precedence order: explicit flags (--handle/--host/--scope/--guest) > existing/parent .exobrain.json > the interactive wizard > guest. Identity is name-matched (handle/hostname → a scope by leaf name); the wizard offers a checkbox menu of connectable scopes with person + host pre-checked.
  2. Resolve the skills registry — walk every skills.json in priority order into a plan.
  3. Link always-tier skills — symlink each into the agent’s skills dir as <name>.<scope-owner>/. Most agents read it from their context surface (.claude/skills, ~/.openclaw/workspace/skills); Codex scans a repo-local .agents/skills, so its skills link there — out of the global ~/.codex, scoped to this repo. OpenClaw honors a workspace skill symlink only when its target root is trusted in its config — step 8 keeps that list current.
  4. Fetch external skills — route to skills/ (always) or skills-optional/ (optional).
  5. Generate the indexes — optional-skills.md (optional-tier skills), tools-index.md (visible tool docs), knowledge-index.md (domains + their summaries, then a section per mount — mounts.md).
  6. Compose + inject — deliver each connected scope’s AGENTS.md (+ agent sidecar, shallow→deep) and the generated indexes. Claude writes .claude/connected-scopes.md — a manifest of @-imports to the live source specs — and a .claude/CLAUDE.md that @-imports that manifest plus each index; Codex writes the self-contained in-repo AGENTS.override.md (root scope and root sidecar inlined, since it replaces AGENTS.md); OpenClaw inlines the same specs and indexes into a USER.md marker block, with the root AGENTS.md and its root sidecar prepended, and gets a second marker block in its workspace .gitignore — the runtime writes raw capture into memory/ (a near-verbatim transcript per session reset, plus the dreaming sweep’s corpus and candidate logs), and a workspace with a remote would otherwise publish all of it permanently. Files already tracked need untracking by hand; the run says so.
  7. Install the git hooks — rewritten on every run, --relink included, so a template change reaches a checkout that connected long ago. What each hook runs: machinery.md § Git hooks.
  8. Reconcile the OpenClaw runtime config (openclaw only) — through openclaw config set: the real parent dir of every linked skill joins skills.load.allowSymlinkTargets, skill_workshop joins tools.deny, skills.workshop.autonomous.mode becomes off (root OPENCLAW.md § Skills are exobrain files), the bootstrap budgets (agents.defaults.bootstrapMaxChars / bootstrapTotalMaxChars) are raised to floors that hold the injected USER.md — past the per-file budget its tail, the knowledge index, is silently dropped — and memory.search.extraPaths gains this checkout’s knowledge/ and each listed mounted domain, so the runtime’s semantic recall reaches the domains and not only its own memory files. The paths are positive per-depth globs, since the indexer cannot exclude a path segment and a domain’s _raw//_meta/ must stay out; indexing sends the matched files to the runtime’s configured embedding provider. Lists are unioned, so entries the human added stay, and a larger budget stays; nothing is written when the config already matches; a missing CLI is reported and the connect carries on. OPENCLAW_BIN overrides the binary.
  9. Reconcile the scheduled jobs (openclaw only) — run scripts/openclaw-cron-sync.py --scopes <the connected chain>, so the crons.json registries of the connected scopes are what the runtime’s scheduler runs. Skipped when no scope in the chain carries a crons.json — a checkout that declares no jobs never touches the scheduler, so a relink that resolved no scopes cannot empty it — and from a linked worktree; a missing CLI or a failed sync is reported and the connect carries on.
  10. Run scope hooks — a connected scope extends the connect with setup of its own. Each scope in the chain carrying an executable scripts/connect-agent.sh (every agent) or scripts/connect-agent.<agent>.sh (that agent alone) gets it run, shallow→deep, as <hook> <agent> <target-dir> <scope-dir>; both run when both exist, universal first. The global scope is skipped — its scripts/connect-agent.sh is the connector. A hook that fails is reported and the connect carries on.

--relink repeats steps 2–10 without prompting and writes neither marker nor config (a --relink for an unmarked agent exits before any of this; --relink with no agent named runs it once per marked agent, and takes no other flag); --configure re-resolves identity (the wizard, or the identity flags); --wire-sandbox runs steps 2–6 and stops before hooks, the OpenClaw config, and scope hooks — real wiring for a throwaway copy (a test sandbox, a CI checkout), so a wire-sandboxed checkout counts as connected for claude. For openclaw the mode refuses to run unless OPENCLAW_WORKSPACE is set, so the real home workspace is never the implicit target — the guard checks that the variable is set, not where it points, so point it at a throwaway dir.

To support a fourth agent: pick a marker and a target dir, add a link/inject branch in connect-agent.sh (symlink-and-import or marker-block shape), recognize its <AGENT>.md sidecar, add it to the agent filter, and document its runtime quirks in the root <AGENT>.md. The agent-specific bits extend without touching the universal layer. Test: connect each agent in turn on a fresh clone, confirm none sees another’s content.

create-worktree.sh calls link-worktree-context.sh <main> <worktree> to inherit the generated markdown and Claude’s per-machine .claude/settings.local.json (permission allowlists, gitignored), and to create real Codex skill directories with individual skill links. In-tree skill links prefer the worktree’s own source, so a branch’s skill edits are what the agent loads there; fetched skills use the main checkout’s cache when the worktree has no copy. Existing destination files are preserved, and re-running the helper repairs missing links in an existing worktree. Mounts resolve through the main checkout (mounts.md).

Wiring Codex inside a worktree replaces the inherited AGENTS.override.md symlink with a local composition and leaves the main checkout’s file untouched. The healthcheck checks Codex’s context and resolved always-tier skills in the active checkout; connection markers and trunk freshness come from the main checkout.