Skip to main content
Everything auto runs is declared in a .auto/ directory: agents, their runtime environments, their chat identities, and project settings. This page explains the directory layout, what a resource is, how the root-level agent facade compiles into resources, what an apply does, and how to validate changes before they take effect. Read it before authoring your first agent or debugging an apply failure.

The .auto/ directory

A .auto/ directory has four kinds of content: A small, realistic layout — this is a trimmed version of the .auto/ directory that configures auto’s own repository:
The rules the parser enforces:
  • Only files ending in .yaml, .yml, or .json under .auto/agents/ are read as resource files. Files are read in sorted path order, and one file may contain multiple YAML documents separated by ---; each document compiles independently.
  • Fragment files under .auto/fragments/ must contain exactly one document. They are validated (parse, import cycles, removal targets) but produce no resources on their own — they only exist to be imported.
  • .auto/config.yaml (or .yml) must be the only project config file. An empty file is a valid, empty config.
  • Legacy layouts are rejected loudly: .auto/sessions/ files, standalone .auto/environments/ or .auto/identities/ resources, and the old kind/metadata/spec envelope inside agent files all fail the apply with an error telling you where the content belongs now. Environments and identities are always declared inline on the agent that uses them.

What a resource is

Compiling a .auto/ directory produces resources: project-scoped records identified by kind/name. Four kinds are authorable through .auto/: Resource names are trimmed strings of 1–128 characters matching [A-Za-z0-9_.-]+. The kind/name pair — not the file path — is a resource’s identity: you can move a definition between files freely, and two files may not define the same resource differently. Sessions are not resources. An agent resource is the template; a session is a durable run of it, created at runtime by a trigger, a message, or an explicit start.

The agent facade

Agent files use a flat, root-level format — the agent facade. There is no kind: or spec: wrapper; metadata fields (name, labels, annotations) and spec fields (harness, model, systemPrompt, env, tools, mounts, triggers, and the rest) sit side by side at the top level. The full field list is in the agent file reference. Three additional keys are control fields: imports (or singular import), remove, and variables. The compiler consumes them and they never appear in the compiled resource:
  • imports pulls in other documents — relative paths to files in the bundle, or managed template specifiers like @auto/agents@latest/pr-review.yaml. See imports and fragments.
  • remove drops named items inherited from imports. Exactly three targets are supported: tools, triggers, and env.
  • variables declares {{ $name }} substitution values that resolve inside imported content. See variables and templating.
Compilation follows a strict order:
  1. Merge each import in listed order, each compiled recursively first. Later imports win over earlier ones, field by field.
  2. Apply the document’s remove: directives to the merged import result.
  3. Merge the document’s own body last — local fields always win.
After all merging, a valid agent needs exactly three things: a name, a harness, and an environment. Everything else is optional or defaulted. In practice the harness and environment usually arrive through an imported fragment or template, so a tenant file can be as small as this real one from auto’s own repository:
.auto/agents/pr-review.yaml
An agent named default is special: it receives Auto’s built-in Default base before its declared imports, so name: default alone is a complete, runnable agent. A project with no default file at all still gets the built-in one.

Inline resources compile out

environment: and identity: accept either a name (a reference to a resource defined elsewhere in the bundle) or an inline object. Inline objects are compiled out into generated resources, and the agent’s spec keeps only the name. An inline identity with no name of its own inherits the agent’s name. This agent file:
.auto/agents/ship-digest.yaml
compiles into three resources: agent/ship-digest (whose spec references environment: agent-runtime and identity: ship-digest by name), environment/agent-runtime, and identity/ship-digest. Because generated resources are shared by name, two files may declare the same inline environment — common when several agents import the same runtime fragment — as long as they compile to the same content. Identical duplicates dedupe; different content under the same kind/name fails the apply with a “Conflicting generated resource” error naming both files.

Apply semantics

An apply reconciles a project’s resources to match a compiled .auto/ bundle. It is declarative: the apply engine plans an action for every resource — create, update, archive, or unchanged — then executes the plan. You never patch a live resource; you change the files and apply again. One compile path is shared by every apply surface, so the same bundle produces the same plan (or the same error) everywhere:
  • GitHub Sync applies the .auto/ tree of a bound repository after each merge to the production branch, and plans it on every pull request.
  • auto.resources.dry_run validates a bundle from inside a running session over MCP, without applying.
Two behaviors follow from the declarative model:
  • Prune. An apply archives resources that exist in the project but are absent from the bundle — deleting a file deletes its resources. Your repository is the complete inventory, not a patch.
  • The config singleton tracks its file. .auto/config.yaml compiles to the config/project resource, so the file’s presence and the resource’s presence stay in lockstep: add the file and the resource is created, remove it and the resource is archived. The spec is currently an empty object — any key fails validation — so the file exists for forward compatibility. See project config.

Validation diagnostics

When a bundle fails to compile or validate, the error carries a machine-readable diagnostic alongside the human message. Tooling should branch on diagnostic.code, never on message text — messages can change between releases. Every diagnostic includes severity (error, warning, or info), blocking, and a safe message, and may include a location (file, line, column) and a remediation with a suggested fix. Unknown future codes must not crash a consumer — treat the set as open. Apply plans can also carry non-blocking diagnostics that are not validation errors — for example optional_connection_skipped (info) when a tool or trigger marked optional: true references a connection with no active grant, or the template bump advisories described in GitHub Sync. These render as notes on the plan rather than failing it.

Dry runs

There are two ways to see what an apply would do without doing it. Both run the identical compile-and-plan path, so a bundle that plans cleanly in one surface plans cleanly in the other:
1

Pull request sync plan

Every pull request against a synced repository’s production branch that touches .auto/ gets a Sync plan check and comment — a full dry-run apply of the PR head. This is the plan of record for what merging will change. See GitHub Sync.
2

From a session

The auto.resources.dry_run tool on the session’s Auto MCP server validates and plans resource changes in place. It accepts inline files ({ path, content } pairs, UTF-8, capped at 3,000,000 bytes per call) or typed resources — exactly one of the two. Managed template imports resolve automatically. Binary avatar assets cannot be passed inline; keep the image committed and let the full GitHub Sync apply validate its bytes.
Agents running in a sandbox get a path-first version of auto.resources.dry_run: calling it with no arguments validates the working tree’s entire .auto/ directory, and passing repository-relative paths validates a focused subset with its local imports included automatically.

Where to go next

Agent file reference

Every field of the agent facade — types, defaults, constraints.

Imports and fragments

Merge semantics, remove directives, append, and file-backed prompts.

Managed templates

Importing @auto/... templates, pinning versions, and overrides.

GitHub Sync

Applying .auto/ from your repository, CI/CD-style.