> ## Documentation Index
> Fetch the complete documentation index at: https://docs.auto.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Managed Templates

> The @auto/* template registry: import specifiers, @latest vs pinned versions, template variables, the subscription sweep that pushes updates, staleness advisories, and grant equivalence.

Managed templates are published, versioned bundles of `.auto/` files maintained in auto's template registry. The supported authoring surface has exactly two packages: `@auto/agents` for complete role entrypoints and `@auto/fragments` for reusable building blocks. You import a specific file instead of copying it into your repo, and projects that track `@latest` receive new versions automatically after every registry release.

<Warning>
  Legacy per-role and team bundle names are retired. They are absent from
  discovery and rejected at `@latest`; only exact historical pins remain
  resolvable for provenance.
</Warning>

## Importing a template

A managed-template import is any `imports:` entry starting with `@`:

```yaml .auto/agents/pr-review.yaml theme={null}
name: pr-review
imports:
  - "@auto/agents@latest/pr-review.yaml"
  - ../fragments/environments/agent-runtime-base.yaml
variables:
  repoFullName: fractal-works/auto
  githubConnection: github-fractal-works
```

The specifier grammar is `@scope/name[@version|@latest]/subpath`:

* `@scope/name` — the template's name. Scope and name may not contain `/` or `@`.
* `@version` — optional. `@latest` (or omitting the version entirely) follows the registry's newest version; an exact version such as `@1.5.0` pins.
* `/subpath` — **required**. A template is a set of files, so the import must name one: `Managed template import must include a file subpath`.

The subpath names the document that merges into your agent. An agent entrypoint such as `@auto/agents@latest/pr-review.yaml` supplies one complete role. A reusable fragment such as `@auto/fragments@latest/tasks/coordinator.yaml` layers one concern onto another agent. Your local agent file therefore stays thin: usually a `name`, one role import, `variables:`, and only genuinely tenant-specific overlays. Everything on the [Imports and fragments](/reference/imports-and-fragments) page applies to managed imports too, including the rule that later imports win the merge.

There is intentionally no whole-package import. `@auto/agents` and `@auto/fragments` are libraries, so every import must select one file. There are also no team packages: team presets live in Auto's internal catalog schema and install the same single-role entrypoints.

At apply time, the resolved version's files are injected into the compile under reserved in-bundle keys (`packages/@scope/name/<subpath>` for `@latest`, `packages/@scope/name@<version>/<subpath>` for a pin) and resolved from there like any other file. This runs identically inside every apply surface — the GitHub Sync apply and every dry run — so they fail or succeed the same way.

## The catalog

The managed authoring surface is deliberately small. The live catalog — with per-version file listings, required variables, and source links — is available from the `auto.templates.list` MCP tool ([auto tools](/runtime/auto-tools)).

| Template          | What it is                                                                                                                       |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `@auto/agents`    | Succinct, single-role entrypoints such as `pr-review.yaml`, `chief-of-staff.yaml`, `shepherd.yaml`, and `staff-engineer.yaml`.   |
| `@auto/fragments` | Shared environments, operator behavior, Shepherd composition, Chief policy, and optional Task coordinator/implementer prompting. |

<Note>
  All former per-role, team, onboarding, task, Default, and smoke-fixture
  packages are retired: they are not returned by discovery or accepted at
  `@latest`. Already-published exact versions remain resolvable as immutable
  history. The permanent `default` agent is a built-in resource; customize it
  with `.auto/agents/default.yaml`, not a managed-template import.
</Note>

## `@latest` vs pinning

An import resolves by its **track**:

* **`@latest`** (or a bare `@scope/name`) resolves to the registry's newest version — the maximum dotted-numeric version among the template's published versions. Latest-track consumers receive **push-apply**: when the registry advances, the subscription sweep re-applies your project on the new version automatically.
* **A pin** (`@auto/agents@1.0.0/pr-review.yaml`) always resolves to exactly that version's content. Pins opt out of push-apply and never receive advisories; upgrading is a deliberate edit to the specifier. A pin to a version the registry does not have fails loudly (`Agent import not found`) rather than resolving to something else.

The two tracks are fully independent, even within one project: a pinned import and a coexisting `@latest` import of the same template each resolve their own version's files (injection keys are qualified by track), so an exact pin can never be contaminated by another import's version.

Exact versions are immutable once published — a pinned import's content never changes underneath you.

## Template variables

Templates parameterize per-tenant values with `{{ $name }}` tokens — a template file's **required variables** are exactly the `{{ $name }}` references it carries. Consumers supply values through a `variables:` map on the importing agent, and GitHub Sync injects `repoFullName` and `githubConnection` automatically from the repo binding, so a forked template repo applies without edits. The full resolution and precedence rules are on [Variables and templating](/reference/variables-and-templating).

To see which variables a template requires before importing it, use `auto.templates.list` — it returns structured required-variable names and source links per version — or open the template's public source. Every template file has a stable, unauthenticated URL:

```text theme={null}
https://www.auto.sh/api/v1/templates/%40auto/agents/latest/pr-review.yaml
https://www.auto.sh/api/v1/templates/%40auto/agents/1.0.0/pr-review.yaml
```

`latest` URLs follow the registry head with short-lived caching; exact-version URLs are immutable with long-lived caching. Published YAML responses begin with a comment linking their own exact-version source, plus a second comment listing required variables when the file references any `{{ $name }}`.

## The subscription sweep

Tracking `@latest` only helps if something actually re-applies your project when a new version publishes. That is the subscription sweep.

**Subscriptions.** Every successful GitHub Sync apply records one subscription row per referenced template: the template name, the track, the concrete `lastResolvedVersion` that was injected, and an integrity hash of the resolved files. When a project has both a pinned and an `@latest` import of the same template, the `@latest` track deterministically wins the row — only latest-track rows are swept, and a pin must not silence a coexisting `@latest` consumer.

**The sweep.** A long-lived background workflow cycles every **5 minutes**, scanning up to **50** latest-track subscriptions per cycle with a rotating cursor so every row is reached fairly. For each subscription whose `lastResolvedVersion` lags the registry's current `@latest`:

* If the project has enabled [GitHub Sync](/concepts/github-sync) bindings, the sweep dispatches one **template push** per binding — a sync run that re-applies the production branch's current HEAD with the new template version. The `.auto/` files are unchanged; only the injected template content differs. The run shows up like any push apply: a "Sync apply" check on the repo, with the usual diagnostics.
* If the project has no enabled sync binding (sync since disabled or removed), the sweep records a skip (`no_sync_binding`). Applies that run outside a sync binding resolve `@latest` fresh every time anyway, so such a project picks up the new version on its next apply.

The subscription row tracks the last push outcome as `dispatched`, `failed`, or `skipped` — `dispatched` means the sweep *started* a push, not that the apply succeeded; success is observable as `lastResolvedVersion` advancing on the next apply. Deterministic workflow IDs make a re-sweep of the same drift reuse the in-flight run instead of duplicating it.

After each successful push apply, the subscription rows are reconciled: every resolved template is upserted, and rows for templates the project no longer imports are pruned — dropping an import also stops its pushes.

### Bump advisories

When a push apply moves a template to a new version, the apply surfaces what changed as non-blocking `info` diagnostics on the sync check and comment, one per importing agent:

* **`template_capability_expanded`** — the new version added files the prior version lacked: *"Template "@auto/agents" updated 1.0.0 → 1.1.0 and added 2 new files to its bundle. Review the new capabilities and set up any connections they require."*
* **`template_override_outdated`** — your project shadows a template file (the injector never overwrites a file already present at an injection key, so your copy keeps winning) and that file's content changed in the new version: *"…your versions are kept, so reconcile them to pick up the template's update."*

Neither advisory ever blocks the apply; they exist so a version bump is never silent.

### Staleness advisory

The template registry is compiled into the deployed backend, so for a short window after a new template version merges — until the backend carrying it deploys — `@latest` still resolves to the previous version. If an apply runs inside that window *and* the repo itself declares the newer version (which only happens in repos that publish templates from their own tree), the apply proceeds with the deployed version and the sync check carries a note naming both versions, so the partial rollout is visible rather than silent. Detection fails open — any inability to read the source produces no advisory and never blocks a merge. Ordinary consumer repos never see this advisory, and the sweep reconciles to the new version once it deploys.

## Grant equivalence

A template's compiled `tools` and `mounts` are its **grant surface** — what an agent built from it can touch. When a template publishes a variant entrypoint that continues an older version's behavior (for example a `-slack` entrypoint preserving a prior Slack-required flow), registry tests pin the variant's compiled `tools` and `mounts` to match the version it continues, modulo an explicitly inventoried exception list (such as read-only mount remainders and mount repositories that became `{{ $repoFullName }}` parameters, normalized against their hardcoded ancestors). Following such an entrypoint across versions does not silently widen what the agent is permitted to do.

Independent of templates, capability gating is re-checked at runtime: for example, GitHub merge and secrets tools require the corresponding mount capabilities regardless of what any template declares. See [Tools](/reference/tools) and [Mounts](/reference/mounts).
