Skip to main content
A pack is a portable definition of behavior: agents, prompt templates, providers, formulas, orders, commands, doctor checks, overlays, skills, and other reusable assets. A city is the root pack plus a city.toml deployment file and machine-local .gc/ bindings. Packs separate three concerns:
  • pack.toml and pack directories define what the system is.
  • city.toml defines how this deployment runs.
  • .gc/ stores local site bindings and runtime state managed by gc.
Legacy include and pack registry fields may still load for migration compatibility, but new docs and new packs should use imports and agents/<name>/ directories.

Pack Layout

Pack structure is convention-based. Standard directories are loaded by name; opaque helper files belong under assets/.

Minimal pack.toml

Pack metadata and imports live in pack.toml. Agent definitions live in agents/<name>/.
schema = 2 is the current pack format. [agent_defaults] applies to agents discovered from agents/ unless an agent’s own agent.toml overrides a field.

Agent Directories

A minimal agent is just a directory with a prompt:
Use agent.toml for fields that differ from pack defaults:
Prompt file discovery prefers prompt.template.md. prompt.md and prompt.md.tmpl are accepted for compatibility.

Imports

Packs compose other packs with named imports. The [imports.<binding>] key is the local binding you choose; it qualifies the imported agents’ names so gastown.polecat and review.polecat coexist. See Understanding Packs for how bindings, qualified names, and collisions work — this section is about authoring the imports.
Local imports use a path relative to the importing pack. Remote imports use source plus an optional version constraint. For GitHub-hosted packs below a repository root, prefer the same /tree/<ref>/<path> URL a browser can open:
Do not write registry handles such as main:gastown into pack.toml. Registry handles are command-time lookup shortcuts; authored pack TOML stores the resolved durable source and, when needed, version.

Registry Discovery

Registries help you find packs; they never change the authored import shape. When you add a pack from a registry, pack.toml stores the resolved durable source and optional version, not the registry handle. The main registry (the public gascity-packs catalog) is configured by default:
Registry pack names are scoped as <github-owner>/<pack>. Before you publish, [pack].name must already carry that scoped name, and its scope must equal the lowercased GitHub owner of the source repository: publish submits the name pack.toml declares, and the registry compares the two byte-for-byte. Unscoped names are reserved — the registry accepts one only when it already holds a claim for it, which is what --allow-unscoped-name is for. See Public Registry Packs for the first-party catalog and cache-freshness controls (--refresh, GC_REGISTRY_FRESHNESS), and Understanding Packs for the handle-vs-source model.

City Usage

A city imports packs at the root pack level and declares deployment details in city.toml.
Machine-local rig paths are site bindings managed by gc:

Rig-Level Imports

Use rig-level imports when only one rig should receive a pack’s agents or formulas.
Rig-level imports create rig-scoped identities such as backend/gastown.polecat and backend/review.reviewer. Gas City’s built-in packs are not implicit. gc init writes explicit pinned imports into pack.toml (core, plus bd for bd-provider cities), and gc doctor --fix repairs missing or stale entries. The former maintenance pack no longer exists; its housekeeping orders ship in the bundled core pack. See System Packs for details.

Named Sessions

Packs can declare sessions that should exist independent of current work.
The template is an agent name from the same pack or an imported qualified name when needed.

Customizing Imported Agents

Use patches to modify imported agents without redefining them.
For rig-specific customization, patch under the rig:

Formula and Order Files

Formula files go in formulas/ and order files go in orders/. No [formulas].dir declaration is needed for packs.
When multiple packs provide the same formula name, the importing pack wins over its imports. Rig-level imports can override city-level formulas for that rig.

Compatibility Notes

The loader still exposes some V1 fields for migration and old city support:
  • workspace.includes
  • [[rigs]].includes
  • [packs.*]
[formulas].dir is not among them: it does not load at all. A [formulas].dir declaration is a hard parse error in city.toml, in every config fragment, and in pack.toml ([formulas].dir is no longer supported; use the well-known formulas/ directory), and gc doctor reports any remaining declaration through the fixable v2-formulas-dir check. Put formulas in the well-known formulas/ directory. Treat the listed fields as migration surfaces for your own packs. gc doctor --fix migrates root pack.toml legacy inline agent definitions into agents/<name>/agent.toml; legacy definitions inside config fragments still need a hand edit. New shareable packs should use schema = 2, [imports.*], agents/<name>/, conventional formulas/, and patches for customization.
Last modified on October 30, 2026