<!--
Sitemap:
- [Installation](/installation)
- [Upgrading](/upgrading): Version-specific steps for upgrading an existing Bento install.
- [Concepts](/concepts)
- [Build your first pipeline](/tutorials/pipeline-args)
- [Target a specific issue or PR from a URL](/tutorials/url-targeting)
- [Keep state across runs](/tutorials/pipeline-state)
- [Fire a pipeline on a schedule or on demand](/tutorials/schedule-and-fire)
- [Deploy a box to Railway](/tutorials/deploy-to-railway)
- [Operate a hosted daemon](/tutorials/operate-a-hosted-daemon)
- [Configuration](/configuration)
- [Members](/members)
- [Knowledge base](/knowledge-base/)
- [Method and delivery](/knowledge-base/modes)
- [Config](/knowledge-base/config)
- [MCP](/knowledge-base/mcp)
- [Pipeline configuration reference](/pipelines/config)
- [Filters](/pipelines/filters)
- [Triggers](/triggers/)
- [GitHub trigger](/triggers/github)
- [Linear trigger](/triggers/linear)
- [Webhook trigger](/triggers/webhook)
- [Schedule trigger](/triggers/schedule)
- [Manual trigger](/triggers/manual)
- [Traces](/pipelines/traces)
- [Slack](/integrations/slack)
- [Public access](/public-access)
- [Context engineering](/context-engineering)
- [Best practices](/best-practices)
- [Troubleshooting](/troubleshooting)
- [Architecture](/architecture/vision)
- [Workspaces](/workspaces)
- [Authentication](/authentication)
- [Identity](/identity)
- [Security](/security)
- [References](/references)
- [Changelog](/changelog): Bento release history.
- [CLI reference](/cli/)
- [Setup](/cli/setup)
- [Secrets](/cli/secrets)
- [Lifecycle](/cli/lifecycle)
- [Sandbox image](/cli/image)
- [Sandboxes](/cli/sandbox)
- [Observability](/cli/observability)
- [Diagnostics](/cli/diagnostics)
- [Triggers](/cli/triggers)
- [Workbench](/cli/workbench)
- [Auth](/cli/auth)
- [Knowledge](/cli/knowledge)
- [Evals](/cli/evals)
- [Bento](/index)
- [Runtime wrapper](/architecture/runtime-wrapper)
- [Skill evolve](/architecture/skill-evolve)
-->

# Concepts

Bento routes an incoming event to an AI agent and manages the run. This page defines the core concepts, in the order you meet them.

## Agents

An **agent** is a persona defined in `agents/<name>/PERSONA.md`: the voice, the judgment, and the standards for a class of tasks.

## Skills

A **skill** is a procedure defined in `skills/<name>/SKILL.md`: the steps, the output format, and the task-specific instructions. Bento uses the same skill definition as [Claude Code](https://code.claude.com/docs/en/skills) and the [Anthropic platform](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview), so a skill that works there works here.

An agent supports multiple skills, and a skill supports multiple agents.

For an example, take a `reviewer` agent with a single persona: it reads code critically, cites specifics, and does not hedge. That persona runs two different skills.

* `review` — read the checked-out repository, assess merge readiness, and post a GitHub review with inline comments.
* `pr-comment-review` — evaluate a single reviewer comment against `HEAD`, form a position, and emit a structured reply.

The skill separates a whole pull request review from a reply to one comment.

## Pipelines

A **pipeline** is a binding: when a trigger fires, run this agent with this skill, render this prompt, and project keyed structured results through daemon-owned handlers.

Each pipeline lives in its own file under `.bento/pipelines/`. Each pipeline has:

* A **trigger** — the event that fires it, such as a GitHub event, a Linear event, or a cron schedule.
* An **agent** — the persona that runs.
* A **skill** (optional) — the procedure the agent follows.
* An **`instructions` directive** — the task text, with `{{event.*}}` substitutions filled in from the trigger payload.
* Optional **`result` and `outputs`** — the structured terminal data and the keyed daemon-owned projections. Without `outputs`, stdout stays opaque and an actor-side write stays an agent action.

```yaml
# .bento/pipelines/pr-review.yaml
trigger:
  github:
    - pull_request.opened
    - pull_request.synchronize
agent: reviewer
skill: agentic-review
instructions: |
  Review PR #{{event.pull_request.number}} ("{{event.pull_request.title}}")
  on {{event.repository.full_name}} for merge readiness.
```

```yaml
# .bento/pipelines/deploy-notify.yaml
trigger:
  github:
    - deployment_status
  filter:
    when:
      deployment_status.state: success
agent: notifier
instructions: |
  Announce deployment of {{event.deployment.ref}} to {{event.deployment.environment}}.
result:
  schema:
    type: object
    properties:
      message:
        $ref: bento://schemas/slack/message/v1
    required: [message]
outputs:
  message:
    handler: slack.message
    config:
      bot: teamBot
      channel: "#deploys"
```

```yaml
# .bento/pipelines/morning-standup.yaml
trigger:
  schedule: "0 9 * * 1-5"   # 09:00, Monday–Friday
agent: notifier
instructions: |
  Post a short summary of yesterday's merged PRs and open review requests.
result:
  schema:
    type: object
    properties:
      message:
        $ref: bento://schemas/slack/message/v1
    required: [message]
outputs:
  message:
    handler: slack.message
    config:
      bot: teamBot
      channel: "#standup"
```

One agent or skill serves many pipelines. A `filter:` block narrows the events a pipeline matches. Use it to route an `@-mentioned` event to an editor agent and send every other event to the reviewer.

### Triggers

A **trigger** is a signal that fires a pipeline: a webhook payload, a cron tick, or an MCP tool call. A trigger matches exactly one pipeline and produces exactly one workload. See [Triggers](/triggers) for the full reference.

## Tools

A **tool** is a callable function available to an agent during a run.

Some tools belong to the **orchestrator**, a daemon-internal LLM that decides how to dispatch the work: whether to call the named agent directly, fan out in parallel, or assemble a more complex pattern. A pipeline with no `orchestrator` field runs its named agent directly. The orchestrator has built-in tools for generic task dispatch and for bounded parallel dispatch. See [Pipelines: Config](/pipelines/config) for the field reference.

## Capabilities

A **capability** is a typed specialist operation that the orchestrator selects. It binds an input schema and an output schema to an agent, an optional skill, a timeout, and an `observer` or `actor` access tier. A pipeline registers the capabilities available for one invocation.

The orchestrator composes capability calls from the request and from intermediate results. It routes to one specialist, calls specialists in sequence, dispatches independent calls in parallel, aggregates results, or repeats a generator and evaluator loop, all within the configured call and time limits. A pipeline declares none of these execution patterns as a workflow graph.

Capabilities differ from skills and companions:

* Use a skill when one agent needs procedural instructions.
* Use a companion when that same run needs additional reference material.
* Use a capability when an operation needs independent selection, schemas, authorization, execution, or tracing.

An actor capability requires actor access and an exact grant from the trigger adapter. The orchestrator never creates a grant.

## The sandbox

Every agent runs inside a container, under Podman or Docker. The daemon clones the target repository into the container, mounts the credentials for git and GitHub authentication, and starts the agent command-line interface (`claude`, `codex`, `pi`, or `opencode`) inside it. An agent never executes on the host, and it reaches only the resources you grant it. Without a configured sandbox, the daemon refuses to start an agent.

A pipeline that commits, pushes, or posts as the bot declares explicit credential mounts in `sandbox.mounts`:

```yaml
sandbox:
  mounts:
    - host: ~/.config/gh
      container: /home/node/.config/gh
    - host: ~/.gitconfig
      container: /home/node/.gitconfig
```

A pipeline without those mounts still runs the agent, but the agent holds no token for a push or a post. To enforce read-only file access in the sandbox, set `guardrails.read_only: true` instead.

## Workspaces

When a trigger names a target that carries a repository — a pull request, a branch, or a Linear issue with a linked repository — the daemon creates a persistent **workspace** directory for that target. The workspace accumulates state across triggers on the same target:

* `checkout/` — the shared Git object cache and the per-run clones that borrow from it.
* durable notes — structured signals the agent records with the MCP `submit_note` tool.
* `runs/<run_id>/meta.json` — the trigger metadata and an optional one-line run result.
* `runs/<run_id>/output.md` — the completed final reply.

Every trigger on the same target shares one workspace. A pull request that receives three pushes gets three invocations in that one workspace. A later prompt includes the notes and a compact index of earlier runs. Each index row holds the run identifier, the age, the trigger, and the recorded result when one exists. An agent can use MCP `get_run` to retrieve a prior run's full final output, result, and notes, and the CLI twin is `bento invocation get-run <run-id>`. A run that finalized before bento persisted results stays in the index without a result, and bento does not backfill it. The daemon keeps every final reply on its own side and injects none of them into a later prompt.

A trigger that names no target with a repository produces no workspace. A cron job with no `repo:` declared and a knowledge-only MCP call are two such triggers.

## The knowledge base

At startup, the daemon indexes three directories in your project:

* `wiki/` — reference material, runbooks, and team context.
* `blueprints/` — design patterns and architectural guidance.
* `recipes/` — reusable how-to procedures.

Each file carries YAML frontmatter, and the indexer reads the title, the description, and the tags from it. The daemon serves the indexed content as MCP resources, and `bento ask` searches it from the command line. During the retrieve phase, the daemon pulls the relevant entries from the knowledge base and injects them into the context of the agent.
