Skip to content

Templates & Roles

A template defines an agent’s role — its job: purpose, instructions, and persona — as a small directory of files you can version, share, and reuse. Templates are harness-agnostic: the same code-reviewer role can run on Claude, Gemini, or any other supported harness. The harness-specific mechanics (container image, concrete model, auth) live separately in a harness-config, so a template stays portable across backends.

Templates work hand-in-hand with skills — reusable instruction snippets a template can bundle or pull from the Skill Bank. A role is the “who”; skills are the “how-to” capabilities you graft onto it.

A template is a directory. Its name is the directory name — there is no name field to keep in sync. A typical template looks like this:

code-reviewer/
├── scion-agent.yaml # role configuration (the only file Scion parses)
├── agents.md # operational instructions for the agent
├── system-prompt.md # the core persona / role definition
├── home/ # optional: portable dotfiles copied into the agent's home
│ └── .config/
│ └── my-tool.conf
└── skills/ # optional: template-mounted skills (see Skills, below)
└── review-checklist/
└── SKILL.md

Only scion-agent.yaml is required for Scion to recognize the directory as a template. Everything else is referenced from that file.

The config file drives the role. Fields that point at content — agent_instructions, system_prompt — accept either a filename (resolved relative to the template directory) or inline text. The convention is to keep prose in separate .md files:

schema_version: "1"
description: "Senior code reviewer — correctness, readability, security, performance"
agent_instructions: agents.md # file reference (or inline text)
system_prompt: system-prompt.md
default_harness_config: antigravity # harness-config to use when none is given
env:
REVIEW_STRICTNESS: high
model: large # portable size alias — see Model size aliases
skills:
- uri: "gh://scion-frontiers/agent-team/pr-code-review"

Common fields:

Field Purpose
schema_version Schema marker; use "1".
description Human-readable summary of the role.
agent_instructions Path to (or inline) operational instructions, mounted as the harness’s agent instructions file.
system_prompt Path to (or inline) the system prompt / persona.
default_harness_config The harness-config to use when the user does not pass one.
model Model size alias (small, medium, large, extra-large) — see Model size aliases.
skills Skill references to resolve at provision time — see Skills.
env Environment variables for the job’s own tools: a fallback, see Template env.
mcp_servers MCP server definitions, translated per harness.
secrets Names of the secrets the job requires (values come from user, project, hub or broker secrets).
services, max_turns, max_model_calls, max_duration, thinking_level, command_args, task_flag Further job settings.
message_mode Hub only: the initial message mode for agents created from the template.

The full field reference is Agent Configuration (scion-agent.yaml).

A template describes the job, not the environment

Section titled “A template describes the job, not the environment”

A template sets job keys: what the agent does. Where and how it runs comes from the harness-config, settings and profiles, the hub and the project. The environment keys image, resources, volumes, kubernetes, hub and telemetry are ignored in a template, with a warning (template <name> sets environment key(s) <keys>; ignored (environment comes from settings)). The template still loads, and a hub admin can list affected templates with GET /api/v1/admin/validate-resources.

You want to set Put it in
Container image The harness-config’s config.yaml image, or settings harness_configs.<name>.image / a profile harness_overrides.<name>.image
CPU, memory, disk Settings default_resources, profile resources / harness_overrides, hub agent_defaults.resources, or the project’s resource defaults
Volumes Settings harness_configs.<name>.volumes, or the harness-config
Kubernetes settings Settings runtimes and profiles
Telemetry Settings telemetry, the hub telemetry config, or project telemetry policy

A single agent can still set image, resources, volumes and kubernetes in its own inline config (--config); its inline telemetry can only turn telemetry on or off. Project defaults and the requester override a template’s job keys; hub agent_defaults fill only what the template leaves unset. See Settings Precedence.

env: in a template is for the tools the job ships with. Each variable is a fallback:

  • It applies only when no other source sets the key: settings and harness-config env, hub, project and user env, request env, secrets, and the auth, harness and telemetry env the runtime adds all win over it.
  • Values are literal. ${VAR} is not expanded, and an empty value is not filled from the broker host.
  • SCION_* keys are ignored.
  • No key the harness-config’s auth metadata lists (its required_env, required_files alternative and autodetect env keys) is ever filled from a template. Supply credentials as secrets or hub env.
  • Edits take effect on the agent’s next start: the broker reads the template’s current env on every start, and never stores it in the agent’s config.
  • A template TZ is not applied to Hub-dispatched agents; see Times and Timezones.

You reference a template by name (or by path/URI) with the --type / -t flag:

Terminal window
# Provision and launch an agent from the code-reviewer template
scion start my-review my task... --type code-reviewer
# Explicitly choose the harness-config as well
scion start my-review --type code-reviewer --harness-config gemini
# Provision without starting (writes the agent dir + prompt.md for later)
scion create my-review my task... --type code-reviewer
# ...then start it
scion start my-review

--type also accepts an absolute path or a remote URI, so you can run a template straight from a repository without importing it first:

Terminal window
# Run a role directly from GitHub (deep path into the agent-team repo)
scion start coord --type gh://scion-frontiers/agent-team/templates/coordinator
# Run from a locally cloned checkout
scion start coord --type ./templates/coordinator

When you do not pass --harness-config, Scion resolves it in this order:

  1. CLI flag — --harness-config (alias --harness).
  2. Project default — the project’s scion.io/default-harness-config setting.
  3. Template default — default_harness_config in the template’s scion-agent.yaml, else its harness_config. When both are set, default_harness_config wins.
  4. Hub default — agent_defaults.default_harness_config on the hub.
  5. System default — default_harness_config in the active profile, then in settings.yaml.

Every non-default template automatically inherits the default template as a base layer. When an agent is provisioned, Scion builds a chain — default first, then your template — and layers them:

  • Config is merged field-by-field (MergeScionConfig): your template’s values override the base, maps like env and mcp_servers are unioned, and skills are appended (so base skills are kept and yours are added). Environment keys are dropped from every template in the chain before the merge, and the chain’s env becomes the template env fallback.
  • Content references (agents.md, system-prompt.md) are resolved by walking the chain from most-specific to least-specific, so a file inherited from the base is still found even if your template doesn’t redefine it.
  • home/ files from the base are copied first, then overlaid by your template’s home/.

This is why a minimal template only needs a scion-agent.yaml plus the files it wants to override — common dotfiles and defaults come from default for free.

To ensure consistent and reliable agent execution across the platform, Scion enforces a mandatory instruction preamble injection mechanism during the provisioning pipeline:

  • What it is: Scion automatically loads all Markdown files from an embedded boilerplate filesystem (mandatory_boilerplate/) and prepends them directly to the final agent_instructions file inside the agent’s home directory.
  • Why it exists: This guarantees that every provisioned agent — regardless of template, role, or harness choice — is seeded with critical platform contracts before starting.
  • Embedded contents:
    • Workspace Orientation: Clear explanations of SCION_WORKSPACE_MODE (shared-plain, worktree-per-agent, clone-per-agent, empty-per-agent), SCION_WORKSPACE_GIT, and how directories/shared volumes are mounted.
    • Agent Status Signals: Exact protocols directing the agent to explicitly declare its execution states via sciontool status (e.g. sciontool status ask_user "<question>", sciontool status blocked "<reason>", or sciontool status task_completed "<task>"). This prevents false stall timeouts, handles notifications routing, and tracks progress.
  • Template Isolation: Because this preamble is injected programmatically by the Hub or CLI, it cannot be overridden, removed, or bypassed by custom templates, securing baseline platform behaviors across all agents.

The final composition layers on top of the chosen harness-config:

  1. Harness-config base layer — runtime mechanics (image, model aliases, auth, base tool files).
  2. Template overlay — the role (config, prompts, instructions, skills).
  3. Runtime overrides — CLI flags and per-agent tweaks.

Templates and skills are complementary: a template gives an agent its role, and skills give it reusable, harness-agnostic capabilities that are mounted into the harness’s skills directory at provision time. There are two ways a template delivers skills.

Commit skill folders directly inside the template’s skills/ directory. They travel with the template and need no Hub:

web-builder/
├── scion-agent.yaml
├── agents.md
└── skills/
├── gcs-static-site/
│ └── SKILL.md
└── gcs-auth-proxy/
├── SKILL.md
└── scripts/
└── main.go

When the template chain is provisioned, Scion collects the skills from each template and mounts them into the harness-specific location:

Harness Skills directory
Claude .claude/skills/
Gemini .gemini/skills/

When multiple templates are chained, skills from later templates overlay earlier ones.

Instead of bundling files, declare skills by URI in the skills: list. These are resolved at provision time from the Skill Bank (a Hub-backed registry) or a federated source such as GitHub:

templates/coordinator/scion-agent.yaml
schema_version: "1"
description: "Project coordinator — delegates implementation, drives progress"
agent_instructions: agents.md
system_prompt: system-prompt.md
skills:
- uri: "gh://scion-frontiers/agent-team/agent-recovery"
- uri: deploy-checklist # bare name → latest, default search order
- uri: "skill://scion/global/notes@^1.2" # semver range
- uri: "gh://my-org/skills/linting" # federated GitHub source
as: lint-rules # mount under a different name
- uri: "skill://scion/user/alice/scratch"
optional: true # skip (with a warning) if it can't be resolved or installed

Each entry supports uri (required), as (mount under a different name), and optional (continue provisioning if it can’t be resolved or installed; the skipped skill is logged as a warning). For the full URI grammar, scopes, versioning, and the scion skills publishing workflow, see Skills — Authoring & Publishing and Skill Registry & Federation.

Scion ships a built-in team-creation skill for generating coordinated multi-agent template sets. It scaffolds orchestrator-worker patterns with best-practice guidance for agent-to-agent communication and template structure — a fast way to bootstrap a whole team of roles rather than hand-writing each template.

  • default — the built-in template shipped inside the Scion binary. It seeds common home/ dotfiles and the baseline agents.md status-signaling instructions, and it is the base layer every other template inherits. Your local copy is protected: scion templates delete refuses to delete the local default, and scion templates update-default refreshes it from the binary (--force to overwrite an existing copy). The Hub copy can be deleted, and a deleted Hub copy is not re-created when the Hub restarts; see Recovering a deleted built-in to bring it back.
  • Custom templates — anything you create, clone, or import. They live in one of two scopes.
Scope Location
Project .scion/templates/<name>/ (in the current project)
Global ~/.scion/templates/<name>/ (your machine)

When you reference a template by bare name, Scion searches in this order and uses the first match:

  1. Remote URI (GitHub URL / deep path, archive, or rclone) — fetched and cached.
  2. Absolute path to a template directory.
  3. Project templates (.scion/templates/).
  4. Global templates (~/.scion/templates/).

When connected to a Hub, templates resolve from the Hub across three scopes. If a name matches in several locations, the CLI prompts you to choose; the --local, --hub, and --global flags narrow the search.

When connected to a Hub, templates exist across three scopes with strict isolation:

  • User Scope: Personal templates strictly isolated to your user account. These are managed via the Web UI Profile page, the Hub store listing, or the CLI. Scion enforces strict authorization ownership (via ScopeID) on list and create operations to guarantee scope isolation and prevent cross-user access or template poisoning.
  • Project Scope: Shared templates bound to a specific Hub project, available to all members of that project.
  • Global Scope: Hub-wide templates managed by administrators and available to everyone.

In the Web Dashboard’s New Agent creation form, templates are automatically clustered and ordered by scope in the dropdown:

User Templates > Project Templates > Global Templates

Visual separators clearly segment these categories, ensuring your personal, customized templates are always at the top of the dropdown for fast access.

The command group is scion templates (singular scion template is an accepted alias).

Terminal window
# List available templates (local, and Hub when connected), grouped by scope
scion templates list
# Show a template's resolved configuration
scion templates show code-reviewer
# Create a new template (seeded from the default template)
scion templates create my-new-role
# Create in global scope instead of the project
scion --global templates create my-new-role
# Clone an existing template (local or Hub source) to a new local one
scion templates clone code-reviewer my-custom-reviewer
# Delete a template (alias: rm)
scion templates delete my-old-role
# Refresh the built-in default template from the binary
scion templates update-default --force

scion templates import converts agent definitions into Scion templates and writes them into your project (or global) templates directory. It understands Claude Code sub-agents (.claude/agents/*.md), Gemini CLI agents (.gemini/agents/*.md), and existing Scion templates (copied directly, no conversion):

Terminal window
# Import a single Claude sub-agent
scion templates import .claude/agents/code-reviewer.md
# Auto-discover and import everything under a project root
scion templates import --all .
# Import Scion templates from another repo (deep GitHub path)
scion templates import --all https://github.com/scion-frontiers/agent-team/tree/main/templates
# Preview without writing
scion templates import --dry-run .claude/agents/code-reviewer.md

Useful flags: --all (import every discovered agent), --harness/-H (force claude/gemini detection), --name (rename a single import), --force (overwrite), --dry-run (preview).

When a Hub is enabled, these commands move templates between the local filesystem and the Hub:

Terminal window
# Upload a local template to the Hub (creates or updates; only changed files upload)
scion templates sync code-reviewer # alias: scion templates push
# Sync every local project template at once
scion templates sync --all
# Sync to global scope, or under a different Hub name
scion --global templates sync code-reviewer
scion templates sync code-reviewer --name team-reviewer
# Download a Hub template to the local filesystem
scion templates pull code-reviewer --to .scion/templates/code-reviewer
# Compare local vs Hub (synced / out of date / local-only / hub-only)
scion templates status

sync is content-aware: it hashes files and uploads only what changed, and templates carry a content hash for traceability (visible in scion templates list, scion templates show, and the Web UI). Syncing an existing template mirrors the local directory: files deleted locally are removed from the Hub copy, and sync lists them as it removes them.

On the Hub, a template’s files are stored as content-addressed blobs, and each commit swaps the template’s file manifest in one compare-and-swap step. If another commit changes the same template first, the losing commit gets 409 template_conflict and nothing is written; scion templates sync re-diffs against the new version and retries once (see the API Reference). Templates stored in the older layout keep working and move to blobs on their next commit. Blobs that are no longer referenced by any template are removed by a background collector after a grace period (24 hours by default), so an agent download that started from an older version still finds its files.

Beyond the CLI, project templates are a fully managed Hub-level resource with full CRUD, SDK, and Web UI support. A connected Hub can import a whole repository of templates server-side via the Load Templates action in the Web UI, and imported templates can be browsed, edited, and deleted directly within the dashboard.

A template the Hub imported from a GitHub folder URL remembers that source URL, and can be refreshed from it later. A refresh replaces the template’s files with the current content of the source folder (a full overwrite, no merge):

Terminal window
# Refresh one Hub template from its stored source URL
scion templates update code-reviewer
# Refresh from a different GitHub folder; it becomes the stored source URL if the refresh succeeds
scion templates update code-reviewer --url https://github.com/myorg/templates/tree/main/code-reviewer
# Refresh every Hub template that has a GitHub source URL
scion templates update --all
# Choose a scope when the same name exists in several
scion templates update code-reviewer --scope project

Inside a project, templates update considers global and user templates plus the current project’s templates (use --project to pick another project); outside a project it considers every template you can see. A failed refresh makes the command exit non-zero, in both text and JSON output.

Refreshing works only for sources in a GitHub repository: a folder on a branch (https://github.com/<owner>/<repo>/tree/<branch>/<path>), a branch’s root (https://github.com/<owner>/<repo>/tree/<branch>), or https://github.com/<owner>/<repo>[/<path>] on branch main. As a --url override, a bare repository URL (https://github.com/<owner>/<repo> or github.com/<owner>/<repo>) is read as that repository’s .scion/templates folder on branch main, the same as when importing. Folder names may contain letters, digits, spaces and . _ @ + -, and branch names letters, digits and . _ -. Built-in templates and templates created without a source URL cannot be refreshed: --all skips them, and the Web UI does not offer a refresh for them. The Hub checks the source URL each time, refuses URLs that include a username or password, and limits how large the download and the extracted folder may be and how many entries the folder may contain (directories count toward this limit as well as files). A refresh writes only into the named template, even when the source folder holds several: it uses the one folder named after the template’s name or slug, refuses a source with none or more than one such folder, and never creates a new template. A refresh does not touch harness-configs: a harness-configs/ folder inside the template’s source is stored as part of the template’s files, but no Hub harness-config is created or updated from it. It needs the same permission as importing a template into that scope. A source in a private repository needs a repository credential in the template’s scope, the same one importing would use (see Template and Harness-Config Imports). With --all, each template’s refresh has its own time limit.

The Web UI offers the same action as Refresh from Source on a template’s detail page, and Refresh All from Source on the templates list, which refreshes a few templates at a time. The detail page shows the stored source without any username or password; sources that are not web URLs are shown as “non-web source”.

For the condensed command list, see the CLI reference.

A harness-config is the counterpart to a template: it holds the runtime mechanics a template deliberately omits, so roles stay harness-agnostic. Harness-configs live in ~/.scion/harness-configs/ (global), .scion/harness-configs/ (project), or a template’s own harness-configs/<name>/ directory (see precedence). Each contains:

  • config.yaml — runtime parameters (container image, model aliases, auth type).
  • home/ — base files copied into the agent’s home directory (e.g. .claude.json, .gemini/settings.json).

Templates should express model choice with abstract size aliases — small, medium, large, extra-large — rather than provider model names. The shorthand tiers s, m, l, and xl are accepted too, case-insensitively (so L means large). Each harness-config maps those aliases to real models:

~/.scion/harness-configs/claude/config.yaml
harness: claude
image: scion-claude:latest
model_aliases:
small: haiku
medium: sonnet
large: opus
~/.scion/harness-configs/gemini-cli/config.yaml
harness: gemini-cli
image: scion-gemini-cli:latest
model_aliases:
small: gemini-flash-lite
medium: gemini-flash
large: gemini-pro

A template that sets model: large then resolves to opus under Claude and gemini-pro under Gemini — the same role, portable across harnesses. Concrete model names still pass through unchanged (for backward compatibility) but tie the template to one harness.

Edit the files in a harness-config directory to change defaults (for example, remap large to a newer model, or add a persistent CLI flag in home/.gemini/settings.json). Copy the directory to make a variant:

Terminal window
cp -r ~/.scion/harness-configs/gemini ~/.scion/harness-configs/gemini-experimental
scion start test-agent --type default --harness-config gemini-experimental

If you break a stock harness-config, restore the factory defaults:

Terminal window
scion harness-config reset gemini

A template is just a directory, so sharing is straightforward:

  • Version it in a repo. Commit templates under .scion/templates/ (or a dedicated repo like scion-frontiers/agent-team) and reference them by gh:// URI or import them with scion templates import.
  • Publish to a Hub. scion templates sync uploads a template so teammates on the same Hub can create agents from it by name.
  • Bundle capabilities as skills. Pull shared behavior out into skills — either template-mounted or published to the Skill Bank — so multiple roles can reuse them.