Reference

Agent config

Every field, default, and constraint in agent config YAML files.

The field-by-field reference for Ellipsis agent YAML files. The canonical path is agents/*.yaml; .agents/, ellipsis/, and .ellipsis/ are also accepted, including any subdirectory under them. The machine-readable source of truth is GET /agents/schema.

Every config file must declare a top-level ellipsis: mapping. Its presence is what identifies the file as an Ellipsis agent config: a .yaml/.yml file in a config directory without an ellipsis: block is treated as unrelated YAML and ignored.

For how agents deploy and sync, see Agents as code; for trigger behavior, the schedule, react, and mention guides; for spend, Budgets. This page documents the fields.

Top-level fields

The shape of an agent file. Every field has a default; a useful agent sets a `trigger` and a `claude.system` prompt (mention agents need neither).

FieldTypeDefaultDescription
ellipsisobjectrequiredEllipsis namespace: schema version, name/description, organizational metadata, and the enabled/interactive/ide flags. Its presence marks the file as an agent config.
claudeobject{}Claude runtime config: the system prompt, model, reasoning effort, turn cap, and an optional Claude Code settings file. Optional for mention-only agents.
triggertrigger object | nullnullHow the agent runs automatically. One trigger of type cron, react, or mention. Omit for a manual-only agent.
sandboxobject{}The sandbox the agent runs in: which repositories are checked out, which stored environment variables are injected, exposed ports, compute sizing, image customization, lifecycle hooks, and the scope of its GitHub token.
skillslist of skill objects[]Claude Code skills installed for the session beyond what the sandbox repositories already provide. Skills checked into a cloned repository's .claude/skills/ load automatically and need no entry here.
structured_outputobject | nullnullJSON Schema contract for machine-readable run output.
budgetobjectall nullPer-session and trailing spend caps for this agent, in US dollars.

ellipsis

The Ellipsis namespace: schema version, identity, organizational metadata, and the enabled/interactive/ide flags. Its presence is what marks a YAML file as an agent config; a config-path file without it is ignored.

FieldTypeDefaultDescription
versionstringv1Config schema version. Bumped only on a breaking shape change; an unsupported value fails validation. v1 is the only supported version today.
namestring | nullnullDisplay name. Dashboard-created files slug this into the file path.
descriptionstring | nullnullShort summary shown in product surfaces.
enabledbooleantrueWhen false, cron, react, and mention starts are skipped. Manual runs still work.
interactivebooleantrueWhen true, a human can `agent session connect` to a live session and inject messages into it over the CLI relay, and an on-demand session stays warm as a durable conversation after its first turn. Set false for fire-and-forget automations. React and cron sessions are always single-turn regardless.
idebooleantrueWhen true, a human can open an editor or a port URL into the running sandbox.
metadataobject{}Freeform labels and annotations. Does not affect how the agent runs; excluded from the config content identity.

ellipsis.metadata

Freeform organization, modeled on Kubernetes labels and annotations. It has no effect on how the agent runs and is excluded from the config content identity.

FieldTypeDefaultDescription
labelslist of strings[]Flat string tags for grouping and filtering.
annotationsobject{}Arbitrary key-value pairs.

claude

FieldTypeDefaultDescription
systemstring | {file} | list of both""The agent's instructions: inline text, a {file: ...} reference to a repository file, or an ordered list interleaving both, joined into one prompt at run start and appended to Claude Code's default system prompt (never replacing it). Required (non-empty) for cron, react, and manual agents; ignored for mention agents, whose reply is built from the conversation.
system[].filestringrequiredPath of a UTF-8 text file in the repository the config lives in, relative to the repository root (no leading /, no ..). Read at run start at the run's commit; 64 KiB max per file and for the composed prompt.
modelstringclaude-opus-4-8Model passed to Claude Code. Omit unless Ellipsis gave your account explicit guidance.
effortenum | nullnullReasoning effort passed to Claude Code. Higher effort trades latency and cost for depth. Omit to use the model default.
fallback_modelstring | nullnullModel Claude Code falls back to when the primary model is overloaded. Omit for no fallback.
max_turnsinteger | nullnullHard cap on the number of agent turns. Must be a positive integer. The session budget bounds the run independently; use this to stop a loop by turn count.
settingsobject | nullnullPoint the session at a Claude Code settings.json in a repository. It is applied below Ellipsis-managed settings, so it customizes behavior (permissions, commit co-author trailer, status line) but cannot weaken a managed setting; hooks stay disabled. Environment keys that would redirect the model off the Ellipsis proxy (ANTHROPIC_*, ELLIPSIS_*, provider routing, apiKeyHelper) are rejected; use sandbox.variables for your own environment variables.
settings.pathstringrequiredPath of the settings.json, relative to the repository root (no leading /, no ..). Read at session start; must be a UTF-8 JSON object, 64 KiB max.
settings.repositoryobject | nullnullWhere path resolves. Omitted: the repository this config lives in, at the session's checkout when that repository is in the sandbox, otherwise at the head of the config's branch. Set: the named repository, which may be any repository of your installation or a public repository from another owner (external private repositories are rejected).
settings.repository.namestringrequiredThe repository name, without the owner.
settings.repository.ownerstring | nullthe config accountGitHub owner (organization or user login). Defaults to the account the config belongs to.
settings.repository.refstring | nulldefault-branch headBranch, tag, or commit SHA to fetch the settings file at. When the repository is cloned into the session's sandbox the checkout SHA wins; otherwise an omitted ref resolves the default-branch head at session start.

Allowed effort values:

ValueLevels
lowFastest, cheapest.
mediumModerate reasoning.
highMore reasoning for harder tasks.
xhighVery high reasoning.
maxMaximum reasoning; slowest.

settings is applied below Ellipsis-managed settings and cannot weaken them. An unresolvable settings file (missing, not a JSON object, over 64 KiB, or setting a protected environment key) fails the session before the agent starts.

System prompts from repository files

system takes three shapes: inline text, a single file reference, or an ordered list interleaving both. A file reference points at a UTF-8 text file in the repository the config lives in, by a path relative to the repository root:

claude:
  system:
    file: .agents/prompts/release-notes.md

A list composes the prompt from its parts in order. Each part is trimmed, and parts are joined with a blank line:

ellipsis:
  version: v1
  name: Linear issue implementer
  description: Implements Linear issues as pull requests

claude:
  system:
    - file: .agents/prompts/engineering-standards.md
    - |
      Implement the Linear issue this session was started for. Open a
      pull request and link the issue in its description.

trigger:
  type: react
  linear_issue:
    on: [opened]

sandbox:
  repositories:
    - name: splitshift-api
    - name: splitshift-web

Referenced files are read at session start, at the commit the session has the config's repository checked out at, so prompt and code always move together. Every agent that references .agents/prompts/engineering-standards.md picks up an edit to it on its next session: no config change, no sync. When the config's repository is not in the session's sandbox, files resolve at the head of the branch the config syncs from.

Constraints:

  • A path must be relative to the repository root and normalized: no leading /, no \, no .. escaping the root.
  • A referenced file must exist at the resolved commit, be valid UTF-8, be non-empty, and decode to at most 64 KiB. The composed prompt is capped at 64 KiB total.
  • A file reference must not point at another agent config file.

Sync and pull request validation check every referenced file at the pushed commit. A file that breaks a constraint at session start (deleted, emptied, grown past the limit) fails the session: status is error, with the reason in the session's status_reason.

Settings file

claude.settings points the session at a Claude Code settings.json in a repository, so a team can reuse the settings file it runs locally instead of re-encoding it. Ellipsis passes it to Claude Code as --settings, which applies below Ellipsis-managed settings: it can set permissions, the commit co-author trailer, a status line, and other Claude Code options, but cannot override a managed setting, and hooks stay disabled.

claude:
  system: Review the push and draft release notes.
  settings:
    path: .claude/settings.json

Omit repository to resolve the path in the repository the config lives in, at the session's checkout when that repository is in the sandbox. Set it to pull a shared file from another repository of your installation or a public repository:

claude:
  system: Review the push and draft release notes.
  settings:
    path: claude/settings.json
    repository:
      name: platform-config

Constraints:

  • The file is read at session start, must be a UTF-8 JSON object, and decodes to at most 64 KiB.
  • Environment keys that would redirect the model off the Ellipsis proxy (ANTHROPIC_*, ELLIPSIS_*, provider-routing variables, apiKeyHelper) are rejected. Use sandbox.variables for your own environment variables.
  • An unresolvable settings file (missing, not a JSON object, over the limit, or setting a protected key) fails the session before the agent starts: status is error, with the reason in status_reason.

triggers

An agent can declare zero or more triggers; each independently decides when the agent runs. A config with no triggers still runs on demand from the CLI, API, or dashboard.

Cron trigger

Run the agent on a schedule. See Spawn an agent session on a cron schedule.

Run the agent on a schedule.

FieldTypeDefaultDescription
type"cron"requiredSelects the cron trigger shape.
schedulestringrequiredFive-field cron, or an EventBridge cron(...), rate(...), or at(...) expression. Five-field cron is converted to EventBridge format.

EventBridge Scheduler cannot restrict both day-of-month and day-of-week in one expression.

React trigger

Run the agent when a pull request, issue, push, Linear, Sentry, or Slack event happens. For the pull request surfaces, see Spawn an agent session in response to Pull Request lifecycle events; the fields below cover every surface.

Run the agent in response to a repository, issue, Sentry, or Slack event. A react trigger sets exactly one surface block (pull_request, push, code_review, issue, linear_issue, sentry, or slack_channel); each block carries its own action list and filters.

FieldTypeDefaultDescription
type"react"requiredSelects the react trigger shape.
pull_requestobject | nullnullReact to pull-request lifecycle actions. Filters: repositories, base, head, draft, labels, paths, for.
pull_request.onlist of pull-request actionsrequiredPull-request actions that can start the agent.
pushobject | nullnullReact to branch pushes. Action-less. Filters: repositories, branch, paths, for.
code_reviewobject | nullnullReview the unreviewed delta on every head advance of a matched PR, never re-commenting reviewed lines. Action-less; reuses the pull_request filters minus on: repositories, base, head, draft, labels, paths, for.
issueobject | nullnullReact to GitHub issue actions. Filters: repositories, labels, for.
issue.onlist of issue actionsrequiredGitHub issue actions that can start the agent.
linear_issueobject | nullnullReact to Linear issue actions. Filter: for.
linear_issue.onlist of Linear issue actions[opened]Linear issue actions that can start the agent.
sentryobject | nullnullReact to Sentry alerts. Filter: projects (Sentry project slugs; empty matches every project in the connected Sentry org).
sentry.onlist of Sentry actionsrequiredSentry alert kinds that can start the agent.
slack_channelobject | nullnullReact when a new public channel is created in your Slack workspace. Takes no fields.
repositorieslist of strings[]Repository name filter (pull_request, push, code_review, issue). Empty matches every repository of the installation.
baselist of strings[]Base-branch filter (pull_request, code_review). Exact names or prefixes ending in *. Empty matches any base.
headlist of strings[]Head-branch filter (pull_request, code_review). Exact names or prefixes ending in *. Empty matches any head.
branchlist of strings[]Branch filter for push. Exact names or prefixes ending in *. Empty matches every branch.
draftboolean | nullnullDraft filter (pull_request, code_review). true matches only draft PRs, false only non-draft; null matches both.
labelslist of strings[]Label filter (pull_request, code_review, issue). Empty matches regardless of labels.
pathslist of strings[]Changed-path glob filter (pull_request, push, code_review). Empty matches regardless of paths.
projectslist of strings[]Sentry project slugs to react to (sentry). Empty matches every project in the connected Sentry org.
foraudience object{users: true}Who may trigger the surface, classified on the stable entity author (the pusher for push). An author matches if in the include set (users/bots) and in no exclude set.
for.userslist of strings | booleantrueHuman authors. true is all humans, a list is specific logins, [] or false is none.
for.botslist of strings | booleanfalseBot authors. true is all bots, a list is specific logins, [] or false is none.
for.exclude_userslist of strings[]Human logins to exclude, applied after the include set.
for.exclude_botslist of strings[]Bot logins to exclude, applied after the include set.

Allowed pull_request.on values:

ValueFires for
openedPR opened or marked ready.
pushedNew commits pushed to the PR.
mergedPR merged.
closedPR closed without merge.
review_submittedA review was submitted on the PR.
commentedA comment was added to the PR.

Allowed issue.on values:

ValueFires for
openedIssue opened.
closedIssue closed.
commentedComment added to the issue.

Allowed linear_issue.on values:

ValueFires for
openedLinear issue opened.

Allowed sentry.on values:

ValueFires for
issue_alertA Sentry issue alert rule fired (via the Ellipsis alert rule action).
metric_alertA Sentry metric alert entered critical status.

Exactly one surface block may be set on a react trigger.

Mention trigger

Route @ellipsis mentions to this agent instead of the built-in responder. See Spawn an agent session by mentioning @ellipsis.

Route @ellipsis mentions to this agent instead of the built-in responder.

FieldTypeDefaultDescription
type"mention"requiredSelects the mention trigger shape.
platformslist of platform strings[]Surfaces this agent answers @ellipsis on. Empty means all of them.

Allowed platforms values:

ValueCovers
github@ellipsis in GitHub PR and issue comments and reviews.
slack@ellipsis messages and app mentions in Slack.
linear@ellipsis in Linear issue comments.

One agent answers per platform. If two configs claim the same platform the oldest one wins; the rest are ignored. With no claimant, the built-in Ellipsis responder answers.

sandbox

The sandbox the agent runs in. See The sandbox for the environment and Inject credentials with sandbox variables for variables.

The sandbox the agent runs in. Each repository entry takes name (required), owner (defaults to the config account), and ref (defaults to the default-branch head).

FieldTypeDefaultDescription
repositorieslist of repository objects[]Repositories checked out in the sandbox. Each takes name (required), owner, and ref.
repositories[].namestringrequiredThe repository name, without the owner.
repositories[].ownerstringthe config accountGitHub owner (organization or user login). Defaults to the account the config belongs to. Public repositories from other owners work; private repositories outside the owning account are rejected.
repositories[].refstringdefault-branch headPins the checkout: fetched and checked out verbatim (git fetch origin <ref> && git checkout <ref>), so use a commit SHA for a reproducible checkout. When omitted, the default branch head at session start.
variableslist of variable objects[]Environment variables injected into the sandbox (an allowlist — only the variables named here reach this agent). Each entry takes a name and an optional value.
portslist of integers[3000, 5173, 8000, 8080]TCP ports exposed from the sandbox for IDE and port-URL access.
variables[].namestringrequiredThe environment variable name. Must be a valid shell name (letters, digits, underscores; not starting with a digit).
variables[].valuestring | nullnullA literal value injected as-is — use for non-secret config like a log level or API base URL. Omit it to resolve the value by name from your sandbox-variables store (dashboard or PUT /sandboxes/variables) at run time, keeping secrets out of YAML.
imageobject{}Customizes the container image. Ellipsis owns the base image (FROM, user, entrypoint, and preinstalled tooling); you contribute appended layers (dockerfile_append) and a build-time script (setup).
image.dockerfile_appendstring | nullnullRUN instructions appended onto the base image, e.g. installing a CLI. Runs when the image is assembled, before any repository exists. Only RUN is supported — FROM, USER, WORKDIR, ENTRYPOINT, and COPY are not. Changing it rebuilds and re-caches the image.
image.setupstring | nullnullA shell script run once at image-build time, after your repositories are checked out and before the snapshot that becomes the cached image. Use it for dependency installs (npm install, poetry install): later runs start with the results already on disk, and a new commit re-runs it on top of the previous build (installing only the delta). Runs as the sandbox user with the sandbox variables available. Environment variables are not captured by the snapshot, but files are, so it must never write secrets to disk. A non-zero exit fails the run; capped at 10 minutes.
hooksobject{}Shell scripts run on every run, before the agent starts, each as the sandbox user with the sandbox variables available. Their output is never cached; a dependency install whose result should be reused across runs belongs in image.setup. A hook that exits non-zero fails the run.
hooks.post_startstring | nullnullRuns after the container starts, before any repository is cloned. Use for repo-independent setup such as authenticating a CLI (e.g. doppler setup). Must not depend on repository contents.
hooks.post_clonestring | nullnullRuns after all repositories are cloned and checked out, before the agent starts. Use for per-run, repo-dependent setup such as code generation or anything that touches run-scoped credentials. For dependency installs, prefer image.setup so the result is cached.
computeobject{}Sandbox compute sizing. Every field is optional; an omitted field uses the platform default. A value outside the allowed range fails config validation, it is never clamped. Compute is billed on the requested allocation over the sandbox lifetime, so a bigger or longer sandbox costs proportionally more.
compute.cpunumber | null1vCPU cores, 0.125 to 16. Fractional values are allowed (e.g. 0.5).
compute.memorystring | object | null4GBMemory allocation, 512MB to 64GB. Either a size string ("16GB", "512MB"; units are binary, so 1GB is 1024MB) or an object with gb / mb keys. Omit to use the default.
compute.timeoutstring | object | null1hMaximum session wall clock, 60s to 1h. Either a duration string ("15m", "1h", "90s", or combined like "1h30m") or an object with hours / minutes / seconds keys. One hour is both the default and the maximum (a sandbox and its GitHub token live at most one hour), so this only shortens a session. A session that reaches the timeout has its sandbox killed and fails.
github_tokenobject{}Scopes the GitHub installation token injected into the sandbox as GH_TOKEN (the credential git and gh authenticate with). By default the token carries the full permissions of your installation, scoped to the repositories in the sandbox. Narrowing is enforced by GitHub itself: the token is minted with the reduced scope, so nothing running in the sandbox can exceed it.
github_token.permissions'read_only' | map | nullnullWhat the token may do. read_only grants read access to contents, issues, metadata, and pull_requests. A map requests an explicit level per GitHub App permission scope (for example contents: read, pull_requests: write) and can only reduce what the installation granted: requesting an ungranted permission fails the session with exit status missing_token_permissions. Omit for full installation permissions.
github_token.repositorieslist of strings | nullnullRepository names the token may touch, narrowing the default (the sandbox repositories owned by your account). Names must belong to the installation; a name it lacks access to fails the session with exit status missing_repo_access. Public repositories from other owners are never in the token scope.

Ellipsis clones repositories available to the account installation, and can clone public repositories from other owners. It rejects private repositories outside the owning account. A variable with no value and no stored value fails the run, so define it before referencing it. A lifecycle hook that exits non-zero fails the run.

skills

Claude Code skills installed for the session, beyond the .claude/skills/ directories the sandbox repositories already provide. See Share skills across your team's agents and repositories.

Claude Code skills installed for the session. Skills checked into a sandbox repository's .claude/skills/ load automatically at that session's checkout; a skills entry brings in skills those clones don't provide: another repository of your installation, a public repository, or a session with no repositories at all. Each entry names a repository directory containing a SKILL.md; it is fetched at session start and installed at the sandbox's personal skill level (~/.claude/skills/<directory name>/), where it overrides a same-named repository skill.

FieldTypeDefaultDescription
pathstringrequiredDirectory containing the SKILL.md, relative to the repository root (no leading /, no ..; not the root itself). The last path segment becomes the installed skill name, so it must be unique across the skills list.
repositoryobject | nullnullWhere path resolves. Omitted: the repository this config lives in, at the session's checkout when that repository is in the sandbox, otherwise at the head of the config's branch. Set: the named repository, which may be any repository of your installation or a public repository from another owner (external private repositories are rejected).
repository.namestringrequiredThe repository name, without the owner.
repository.ownerstring | nullthe config accountGitHub owner (organization or user login). Defaults to the account the config belongs to.
repository.refstring | nulldefault-branch headBranch, tag, or commit SHA to fetch the skill at. When the repository is cloned into the session's sandbox the checkout SHA wins, so skill and code move together; otherwise an omitted ref resolves the default-branch head at session start.

At most 10 skills per config; each skill at most 50 files and 512 KiB total, 64 KiB per file, UTF-8 text only. A skill that cannot be resolved (missing SKILL.md, unreachable repository, over a limit) fails the session before the agent starts.

structured_output

FieldTypeDefaultDescription
type"json_schema""json_schema"Structured output type.
json_schemaobjectrequiredJSON Schema the agent output must satisfy.

When present, Ellipsis passes this schema to the Claude Code runtime for the run's output.

limits

Per-session and trailing spend limits, in US dollars. See Budgets for defaults and ceilings.

Validation and sync behavior

CaseResult
File has no top-level ellipsis: blockNot an agent config: ignored entirely, even at a config path.
ellipsis.version is unsupportedValidation fails. Only v1 exists.
YAML is emptyRejected: an empty config has no claude.system.
claude.system is empty on a non-mention agentValidation fails. Inline text or a file reference satisfies the requirement.
A system file path is absolute, unnormalized, or escapes the repository rootValidation fails.
A system file is missing, empty, or over 64 KiB at the validated commitValidation fails at sync and on config pull requests. At session start it fails the session instead.
system is an empty listValidation fails; a list needs at least one text part or file reference.
Cron expression is invalidValidation fails before anything is stored or scheduled.
branches is set on a non-push react eventValidation fails.
A sandbox.compute value is out of range or unparseableValidation fails; values are never clamped. Bounds: cpu 0.125 to 16 vCPU, memory 512MB to 64GB, timeout 60s to 1h. memory is a size string (8GB, 512MB; binary, 1GB = 1024MB) or an object with gb/mb keys; timeout is a duration string (30m, 1h, 90s) or an object with hours/minutes/seconds keys.
sandbox.github_token.permissions names an unknown scope or an invalid levelValidation fails. The value is read_only or a map of GitHub App permission scopes to read/write.
sandbox.github_token.permissions requests a permission the installation was not grantedThe session fails at sandbox creation with exit status missing_token_permissions.
sandbox.github_token.repositories is empty, has duplicates, or names a repository the installation cannot accessAn empty list or duplicates fail validation. An inaccessible name fails the session with exit status missing_repo_access.
A skills path is absolute, unnormalized, escapes the repository root, or is the root itselfValidation fails.
A skills path points at an agent config fileValidation fails; a skill is a directory containing a SKILL.md.
More than 10 skills entries, or two entries whose paths end in the same directory nameValidation fails; the last path segment is the installed skill name.
A skills entry without repository: has no SKILL.md, or unparseable frontmatter, at the validated commitValidation fails at sync and on config pull requests. Entries with repository: are checked at session start.
A skill cannot be resolved at session start (missing SKILL.md, unreachable repository, over a size limit, not UTF-8)The session fails before the agent starts: status is error, with the reason in status_reason.
New file is invalidThe sync reports the error and does not create an agent.
Existing file becomes invalidThe sync records the error and keeps the last good config.
File is removedThe agent is soft-deleted and its schedules removed.