.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:
- Only files ending in
.yaml,.yml, or.jsonunder.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 oldkind/metadata/specenvelope 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 nokind: 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:
importspulls 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.removedrops named items inherited from imports. Exactly three targets are supported:tools,triggers, andenv.variablesdeclares{{ $name }}substitution values that resolve inside imported content. See variables and templating.
- Merge each import in listed order, each compiled recursively first. Later imports win over earlier ones, field by field.
- Apply the document’s
remove:directives to the merged import result. - Merge the document’s own body last — local fields always win.
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
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_runvalidates a bundle from inside a running session over MCP, without applying.
- 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.yamlcompiles to theconfig/projectresource, 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 ondiagnostic.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.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.