Skip to content
WIP

This guide is a work in progress. Barry is also a work in progress.

Primitives

This page gives you one vocabulary for everything Barry does. Each entry says what a primitive is, how it relates to the others, and where to read more. Other pages and the Barry repository sometimes describe these words in slightly different ways; where they differ, this page follows the code.

The whole model fits in one sentence: an identity packs bags; traits grant what those bags provide and bounds take some of it back; a session runs a harness under that identity with the resulting policy, guided by instructions, and actions, schedules, and workers carry out work while you are away.

A bag is a bundle of capabilities. It can carry tools, connections to other MCP servers, traits, bounds, instructions, prompt contributors, skills, actions, schedules, jobs, hooks, services, stores, apps, and other bags. A local bag is a directory with a bag.yaml manifest. A remote bag is an MCP server URL. A bag that only declares things, such as traits and bounds, needs no code.

Two verbs put a bag to use:

  • Install registers and builds the bag on this machine, for every identity.
  • Pack puts an installed bag on one identity. Packing adds it to the identity’s identity.yaml, creates the stores it declares, and loads its hooks, skills, instructions, and actions for that identity.

Packing a bag doesn’t grant its tools. A packed bag’s tools reach a session only when a trait selects them, unless the identity sets bag_grant: identity.

Terminal
barry install ~/repos/my-tools
<identity> pack my-tools
barry bag show my-tools

A bag can list other bags under bags:, and its automatic trait then grants their tools too. A bag can also extend another with extends: <parent>: Barry registers it as <parent>/<name>, and it adds to its parent rather than standing on its own, so it gets no automatic trait. The base identity packs the sessions bag with one extension this way:

bags:
- sessions:
extensions: [search]

For the manifest, see Packing bags.

A trait is a named grant of tool access. It names tool namespaces (under bags:) or qualified namespace:tool ids, and an access level: read or readwrite. It can also mount skills and point at instructions, and it can include other traits.

A trait can carry restrictions too: bounds: names bounds, and bound: declares one inline. Selecting the trait applies those restrictions to the whole session, not only to the trait’s own tools.

  • Traits add. Selecting another trait never removes a grant, and when two traits grant the same namespace, the more permissive access wins.
  • A root bag that provides tools or skills gets two automatic traits: <bag>, which grants its namespaces at readwrite, and <bag>:read, which includes <bag> under the readonly bound. Service-only and action-only bags get none.
  • A trait declared in bag.yaml with the bag’s own name replaces the automatic one.
  • A tool that no selected trait grants never reaches the session.
Terminal
barry trait list
<identity> session start --traits coding,sessions

Policy resolution, linked at the end of this page, shows how traits combine into a session’s tool list.

A bound restricts what a session can do. It removes tools, write access, file paths, shell commands, network destinations, and native harness tools from what the traits granted. A bound never grants anything. When several bounds apply, Barry merges them toward more denial: denials union, allowlists intersect, and the strictest network enforcement wins.

Terminal
barry bound list
<identity> session start --bound no-network
<identity> identity bounds add readonly

Bounds lists every field, the builtin bounds, and which harnesses enforce what.

An identity is the persona a session runs as. It holds the bags packed onto it, its default traits and bounds, its harnesses and models, and references to its secrets. Each identity gets its own command on your PATH, named after it, that runs Barry as that identity.

An identity lives in a directory with an identity.yaml and a gitignored .env. The fields that shape policy:

Field Meaning
inherits The parent identity. barry identity create writes inherits: base; an identity without the key inherits nothing
bags Bags packed onto the identity
traits Traits every session of the identity gets
bounds Bounds every session of the identity carries
bag_grant session (default) or identity: whether packing alone grants a bag’s tools
adapters The harnesses the identity runs; each sets a model and a mode
vault The vault that holds the identity’s secrets

Barry ships a base identity, named base, that packs the foundational bags: actions, artifacts, bash, decisions, embeddings, events, filesystem, identities, instructions, mcp, memory, nodes, schedules, sessions, and telemetry. Its default traits, artifacts, bash, filesystem, instructions, and sessions, apply to every session unless an identity turns them off. It also ships optional bounds, such as readonly and no-network, that a session can select by name.

Every identity you create inherits from base unless it names another parent. A child starts from its parent’s bags, traits, bounds, and configuration, then layers its own on top. Any identity can be a parent, and Barry rejects cycles.

Terminal
barry identity create "B. Goode"
barry use
<identity> identity show

barry use picks the identity the general barry command acts as. Any command also accepts barry --identity <name>.

Barry isn’t only for coding, and an identity is how one Barry wears different hats. Three real shapes:

  • A domain persona. An athlete identity packs commerce bags (amazon-commerce and ebay-commerce) and keeps its own athlete vault. Its sessions sell and research, not write code.

  • A creative persona. An mc identity packs music-production bags such as ableton. Same Barry, a studio instead of a terminal.

  • An inheriting persona. A bgoode identity sets inherits: bux, so it starts from everything the bux identity already packs and configures, then adds one more bag, its own vault-backed secrets, and a bound of its own:

    name: bgoode
    inherits: bux
    vault: bgoode
    secrets:
    LINEAR_API_KEY:
    in: vault
    item: LINEAR_API_KEY
    field: password
    bounds:
    - bgoode:
    description: Keep env files and SSH keys out of reach
    files:
    deny:
    - "*.env"
    - "**/.ssh/**"

    Inheriting from bux rather than base makes bgoode a specialization of a working identity, not a fresh start. The inline bgoode bound adds a restriction that every one of its sessions carries.

A session is one run of an agent. It has a durable record, with its transcript and history, and while it runs, a handle to the harness running it. Barry stores sessions the same way whichever harness produced them, so you can list, search, and resume them later.

Terminal
<identity> session start --traits coding
<identity> session list

A harness is the agent program a session runs. The supported harnesses are Antigravity, Claude Code, Codex, Cursor, OpenCode, and Pi. A session adapter is the package that binds one harness to Barry: it launches the harness with Barry’s tools and hooks and reports what the harness can enforce. Other adapter kinds wrap model calls: completion, embedding, and decision adapters.

See Adapters for choosing a harness and model.

A mode says how much of a session Barry controls. In hosted mode Barry drives the harness and holds the session. How it gates the harness’s own tools depends on the harness: some ask Barry before each call, some gate through hooks, and hosted Cursor runs a few native tools without a ruling. In instrumented mode you drive the harness’s own interface and Barry opens side doors at launch. In guest mode Barry learns what happened from the transcript the harness leaves behind. Session modes and guarantees, linked at the end of this page, compares them per harness.

An instruction is standing guidance the agent reads: a markdown file under a bag’s or an identity’s instructions/ directory. Its mode is always, which joins the system prompt, or on-demand, which costs only its description until the agent fetches the body with the get_instructions tool. An identity’s instruction wins a name collision with a bag’s.

A prompt contributor computes text instead. A bag declares one under prompts: and Barry runs it in a separate process at session start, within a time and size budget. Barry skips a contributor that fails, with a warning, and the session starts anyway.

Terminal
barry new instruction my-guidance --mode on-demand

An action is a reusable procedure with typed inputs, optional typed output, requirements, and a recorded run. It lives at actions/<name>/action.yaml in a bag. An agent carries out its prompt, or Barry runs its run: command itself; an action declares exactly one of the two. Sessions discover actions with the find_actions tool and start one with begin_action. The actions bag owns the full contract.

Terminal
barry new action triage-report
<identity> action runs

A schedule runs an action on a trigger: an interval (every), a cron expression (cron), a single time (at, an ISO-8601 time), or each time the machine starts (at: login). A bag declares schedules in bag.yaml, and each one’s ID is <bag>/<name>. One scheduler service runs every schedule.

Terminal
<identity> schedule list
<identity> schedule show sessions/reaper

The schedules: schema lives in schedule-manifest.ts.

A job is a unit of background work a bag declares under jobs:. A workflow is the durable computation that runs it: Barry’s workflow runtime records each step’s history in SQLite, so a run survives restarts and a failed step retries under its retry policy. Durable workflows explains the engine.

A worker is another Barry installation that joined this one to run its workflow steps. The installation that owns the workflows keeps their history and decides which worker takes each step, and a step runs on a worker only when that worker can enforce the step’s credentials, workspace, runtime, and bounds. Eligible scripts and agent actions run there with credentials provisioned for the worker or a narrowly scoped delegated credential. The owner never copies its instance secret, its stores, or an identity’s whole environment to a worker, and a running session never moves between machines. Every installation also acts as its own worker.

Terminal
barry workers invite mac
barry workers join <token>

Schedules and workers walks through linking a machine.

A service is a long-running process a bag ships, such as the MCP server that serves tools to a harness, the sessions API, or the scheduler. launchd starts services at login and keeps them up.

A store is a bag’s own SQLite database, with forward-only migrations. Every bag that keeps state gets one under Barry’s home directory.

Terminal
barry service status
barry store list

Services and stores covers both, and the rule for which process may call which.

An app is a native program a bag ships under apps:, such as a menu-bar helper or a window an agent opens. Barry builds and registers it with the bag. See Package an app.

Terminal
barry app list

A secret is a credential a tool needs. A tool declares it by name, never by value. An identity binds each secret to a source: its vault, its .env file, or the macOS Keychain. A daemon running as a separate operating-system user serves the vault’s encrypted storage. The tool that declared a secret receives it; treat a secret as readable by the session you hand it to. See Manage secrets.

Terminal
<identity> vault add LINEAR_API_KEY

An event is an append-only record of something that happened: agent progress, a notification, a session finishing, or a system alert. An event can link to a session or stand alone. After Barry writes an event, only its read state and delivery attribution change.

Terminal
<identity> events list --unread

A hook runs a script of a bag’s when something happens. A bag declares hooks in bag.yaml under hooks:, in two kinds:

  • agent: hooks fire on the harness’s own lifecycle: session-start, session-end, user-prompt, stop, pre-tool, and post-tool. The harness invokes them.
  • barry: hooks fire when Barry creates a record. The one such trigger is event-created, and Barry invokes these itself.

Read Policy resolution next to see how an identity’s traits and bounds become one session’s tool list, then Session modes and guarantees for what each harness lets Barry enforce.