Skip to main content

Gas City Configuration

Schema for city.toml — the deployment file for a Gas City instance. Pack definitions live in pack.toml and conventional pack directories such as agents/, formulas/, orders/, and commands/. Use [imports.] for pack composition; legacy includes and [[agent]] fields remain visible for migration compatibility. Legacy [packs.] entries are still accepted by the runtime for migration/fetch compatibility but are intentionally omitted from this public schema.

Pack format source of truth: Public pack format and loader semantics are specified in Gas City Pack Specification.

Auto-generated — do not edit. Run go run ./cmd/genschema to regenerate.

City

City is the top-level configuration for a Gas City instance.

FieldTypeRequiredDefaultDescription
include[]stringInclude lists config fragment files to merge into this config. Processed by LoadWithIncludes; not recursive (fragments cannot include).
workspaceWorkspaceyesWorkspace holds city-level metadata (name, default provider).
providersmap[string]ProviderSpecProviders defines named provider presets for agent startup.
upstreamsmap[string]UpstreamSpecUpstreams defines named model-serving endpoint presets selectable per agent via the Upstream axis (Phase C). Each maps a name → serving env (base URL + credential refs); see UpstreamSpec.
importsmap[string]ImportImports defines named pack imports. Each key is a local binding name; the authored public contract stores a durable source plus optional version. Processed during ExpandCityPacks.
defaultsPackDefaultsDefaults holds city-level defaults that seed generated config. The canonical default-rig import table is [defaults.rig.imports].
agent[]AgentAgents lists all configured agents in this city. Pack-composed cities can compose agents through [imports.*] and ship without any [[agent]] block.
named_session[]NamedSessionNamedSessions lists canonical alias-backed sessions built from reusable agent templates.
rigs[]RigRigs lists external projects registered in the city.
patchesPatchesPatches holds targeted modifications applied after fragment merge.
storageStorageConfigStorage assigns the six semantic storage classes to immutable named bindings. Nil preserves the existing all-Work storage topology.
beadsBeadsConfigBeads configures the bead store backend.
sessionSessionConfigSession configures the session provider backend.
mailMailConfigMail configures the mail provider backend.
eventsEventsConfigEvents configures the events provider backend.
usageUsageConfigUsage configures the usage-fact sink backend.
doltDoltConfigDolt configures optional dolt server connection overrides.
formulasFormulasConfigFormulas is the legacy [formulas] table; authored [formulas].dir is rejected at config load. Formulas live in the well-known formulas/ directory.
daemonDaemonConfigDaemon configures controller daemon settings.
ordersOrdersConfigOrders configures order settings: skip list, max_timeout cap, and per-order overrides.
apiAPIConfigAPI configures the optional HTTP API server.
chat_sessionsChatSessionsConfigChatSessions configures chat session behavior (auto-suspend).
session_sleepSessionSleepConfigSessionSleep configures idle sleep policy defaults for managed sessions.
convergenceConvergenceConfigConvergence configures convergence loop limits.
doctorDoctorConfigDoctor configures gc doctor thresholds and policy toggles (worktree size warnings, nested-worktree auto-prune).
maintenanceMaintenanceConfigMaintenance configures periodic store-maintenance loops.
service[]ServiceServices declares workspace-owned HTTP services mounted on the controller edge under /svc/{name}.
webhook[]WebhookWebhooks declares inbound HTTP receivers mounted on the supervisor edge under /hook/{name}. Composed like Services (pack concatenation + SourceDir provenance + the default-closed public pack-guard).
webhooksWebhookPolicyConfigWebhookPolicy holds city-level webhook governance (the [webhooks] table, notably allow_public grants). Authored only in the root city.toml; never merged from packs or fragments so a pack cannot grant itself exposure.
githubGitHubConfigGitHub configures GitHub-facing repository monitors.
extmsgExtMsgConfigExtMsg configures the external-messaging fabric (default routes for inbound conversations with no binding).
agent_defaultsAgentDefaultsAgentDefaults provides root city defaults for agents that don't override them (canonical TOML key: agent_defaults). Pack-local defaults use the same table shape in pack.toml. The runtime currently applies provider, default_sling_formula, and append_fragments; the attachment-list fields remain tombstones, and the other fields are parsed/composed but not yet inherited automatically.
pricing[]ModelPricingPricing holds per-model cost rate overrides keyed by (provider, model). City-level entries override pack-level entries which override the defaults shipped with the pricing package. See internal/pricing for the estimation seam introduced by issue #1255 (1d).

ACPSessionConfig

ACPSessionConfig holds settings for the ACP session provider.

FieldTypeRequiredDefaultDescription
handshake_timeoutstring30sHandshakeTimeout is how long to wait for the ACP handshake to complete. Duration string (e.g., "30s", "1m"). Defaults to "30s".
nudge_busy_timeoutstring60sNudgeBusyTimeout is how long to wait for an agent to become idle before sending a new prompt. Duration string. Defaults to "60s".
output_buffer_linesinteger1000OutputBufferLines is the number of output lines to keep in the circular buffer for Peek. Defaults to 1000.

APIConfig

APIConfig configures the HTTP API server.

FieldTypeRequiredDefaultDescription
portintegerPort is the TCP port to listen on. Defaults to 9443; 0 = disabled.
bindstringBind is the address to bind the listener to. Defaults to "127.0.0.1".
allow_mutationsbooleanAllowMutations overrides the default read-only behavior when bind is non-localhost. Set to true in containerized environments where the API must bind to 0.0.0.0 for health probes but mutations are still safe.
write_auth_verify_keystringWriteAuthVerifyKey, when set, requires every mutating request to an already-registered city — the per-city routes under /v0/city/{cityName} — to carry a signed write grant from a configured trusted authority. It gates all per-city writes (beads, mail, sessions, agents, and config), not only config edits. City registry creation (POST /v0/city) is not covered: a grant binds a path-resident city name, which a not-yet-created city lacks, so creation stays governed by the supervisor-registry guards. Built-in callers (the bundled gc API client and dashboard SPA) send only the CSRF header and mint no grant, so enabling this gate turns their direct city mutations away with a clear 401; such deployments front mutations through the trusted authority that mints grants instead. The value is one or more "kid:base64-ed25519-pubkey" entries, comma separated. The GC_CITY_WRITE_PUBKEY env var overrides this. Grant revocation via an epoch floor is an ops-plane control set only through the GC_CITY_WRITE_EPOCH_FLOOR env var; it has no config field. On hosted multi-tenant deployments the GC_CITY_WRITE_CID env var (ops-plane only, no config field) additionally binds the gate to the controller's own city id: every grant must then carry that exact cid claim, failing closed on a mismatching or missing cid.
write_auth_requiredbooleanWriteAuthRequired makes a missing or empty WriteAuthVerifyKey a startup error instead of silently disabling the gate, so a config that intends to gate writes fails closed if the key is ever dropped. The GC_CITY_WRITE_REQUIRED=1 env var has the same effect.
write_auth_allow_unverifiedbooleanWriteAuthAllowUnverified acknowledges running a non-loopback bind with allow_mutations and NO write-auth verify key — an unauthenticated write plane fronted only by the network. Without it, that combination is a fail-closed startup error (gate G10) so a hardened deployment cannot boot wide open by omission. Set it (or GC_CITY_WRITE_ALLOW_UNVERIFIED=1) only for a network-fronted deployment that intentionally trusts its perimeter.
read_auth_verify_keystringReadAuthVerifyKey, when set, requires every read (GET/HEAD) of an already-registered city on the typed per-city API — the routes under /v0/city/{cityName} — to carry a signed read grant from a configured trusted authority. It is the read-side twin of WriteAuthVerifyKey, adding in-process, grant-based admission control to the typed city read surface (beads, mail, sessions, agent transcripts) instead of trusting network position. Scope boundary: this gate covers ONLY the typed /v0/city/{cityName} read routes. It does NOT cover other surfaces on the same listener that can also expose per-city data: the supervisor-scope aggregate event feed (/v0/events and /v0/events/stream, which multiplex every running city's events), the default-on dashboard host plane (/api/, including its /api/city/{cityName}/ samplers, run detail, run diff, and config reads), and the supervisor-scope routes /v0/cities, /health, /v0/readiness, /v0/provider-readiness, the OpenAPI document, and the dashboard SPA shell. On a non-localhost bind, the only complete mitigation is to front the whole listener with the grant-minting authority/edge (the intended deployment), which protects every surface above. Disabling the dashboard host plane with GC_SUPERVISOR_DASHBOARD=0 is additive, not a substitute: it closes /api/* only, while the supervisor-scope event feed /v0/events and /v0/events/stream stays readable by network position until the follow-up supervisor-scope grant lands. Gating those feeds is tracked as that follow-up work. Built-in callers (the bundled gc API client and dashboard SPA) mint no grant, so enabling this gate turns their direct /v0/city reads away with a clear 401; such deployments front reads through the authority that mints grants. The value is one or more "kid:base64-ed25519-pubkey" entries, comma separated. The GC_CITY_READ_PUBKEY env var overrides this. Grant revocation via an epoch floor is an ops-plane control set only through the GC_CITY_READ_EPOCH_FLOOR env var; it has no config field.
read_auth_requiredbooleanReadAuthRequired makes a missing or empty ReadAuthVerifyKey a startup error instead of silently disabling the gate, so a config that intends to gate reads fails closed if the key is ever dropped. The GC_CITY_READ_REQUIRED=1 env var has the same effect.

Agent

Agent defines a configured agent in the city.

FieldTypeRequiredDefaultDescription
namestringyesName is the unique identifier for this agent.
descriptionstringDescription is a human-readable description shown in MC's session creation UI.
dirstringDir is the identity prefix for rig-scoped agents and the default working directory when WorkDir is not set.
work_dirstringWorkDir overrides the session working directory without changing the agent's qualified identity. Relative paths resolve against city root and may use the same template placeholders as session_setup.
tmux_aliasstringTmuxAlias overrides the tmux session_name for pool and factory-created manual sessions of this agent. When unset, sessions fall back to the universal derivation ("s-<beadID>" for ad-hoc sessions, "<basename>-<beadID>" for pool sessions). When set, it is expanded as a Go text/template using the same PathContext fields as work_dir / session_setup (Agent, AgentBase, Rig, RigRoot, CityRoot, CityName, DefaultBranch), sanitized for tmux, and validated as an explicit session name. For pool sessions, a live-name collision appends the bead ID as a deterministic suffix. For manual gc session new sessions, tmux_alias becomes the explicit session_name and takes precedence over --alias, which remains the command/mail alias; duplicate explicit names fail closed. Configured named sessions keep their named-session runtime name instead of using tmux_alias. When no --alias is supplied, work_dir templates that use {{.Agent}} see the resolved tmux_alias as the concrete session identity.
scopestringScope defines where this agent is instantiated: "city" (one per city) or "rig" (one per rig). Omit the field for an unscoped agent instantiated in both city and rig expansion contexts. Only meaningful for pack-defined agents; inline agents in city.toml use Dir directly. Enum: city, rig
suspendedbooleanSuspended prevents the reconciler from spawning this agent. Toggle with gc agent suspend/resume.
pre_start[]stringPreStart is a list of shell commands run before session creation. Commands run on the target filesystem: locally for tmux, inside the pod/container for exec providers. Template variables same as session_setup. On failure, the last 4 KiB of the command's stdout/stderr is included in the error and may appear in controller and reconciler logs; avoid set -x or echoing secrets in setup commands.
prompt_templatestringPromptTemplate is the path to this agent's prompt template file. Relative paths resolve against the city directory.
nudgestringNudge is text typed into the agent's session after startup. Used for CLI agents that don't accept command-line prompts. For a known pool session whose trigger remains unclaimed after the 90-second recovery grace period, an empty or whitespace-only Nudge does not opt out: it sends "Run gc hook --claim --drain-ack --json now; if it returns work, execute it immediately." This fallback applies only to the initial stalled-claim recovery; continuation-claim recovery remains configured-only. Unknown templates receive no fallback.
sessionstringSession overrides the session transport for this agent. "" (default) uses the city-level session provider (typically tmux). "acp" uses the Agent Client Protocol (JSON-RPC over stdio). The agent's resolved provider must have supports_acp = true. Enum: acp
providerstringProvider names the provider preset to use for this agent.
upstreamstringUpstream selects the model-serving endpoint (a key in [upstreams]) for this agent — WHO serves the model. "" (default) falls back to agent_defaults.upstream; if still empty, no upstream env is injected (ambient behavior). Switching it relaunches the agent in the warm box.
start_commandstringStartCommand overrides the provider's command for this agent.
lifecyclestringLifecycle controls runtime lifetime semantics. Empty uses the default long-lived session lifecycle; "one_shot" means the command is expected to do bounded work and exit cleanly. Enum: one_shot
args[]stringArgs overrides the provider's default arguments.
prompt_modestringargPromptMode controls how prompts are delivered: "arg", "flag", or "none". Enum: arg, flag, none
prompt_flagstringPromptFlag is the CLI flag used to pass prompts when prompt_mode is "flag".
ready_delay_msintegerReadyDelayMs is milliseconds to wait after launch before considering the agent ready.
ready_prompt_prefixstringReadyPromptPrefix is the string prefix that indicates the agent is ready for input.
process_names[]stringProcessNames lists process names to look for when checking if the agent is running.
emits_permission_warningbooleanEmitsPermissionWarning indicates whether the agent emits permission prompts that should be suppressed.
envmap[string]stringEnv sets additional environment variables for the agent process.
option_defaultsmap[string]stringOptionDefaults overrides the provider's effective schema defaults for this agent. Keys are option keys, values are choice values. Applied on top of the provider's OptionDefaults (agent keys win). Example: option_defaults = { permission_mode = "plan", model = "sonnet" }
max_active_sessionsintegerMaxActiveSessions is the agent-level cap on concurrent sessions. Nil means inherit from rig, then workspace, then unlimited. Replaces pool.max.
min_active_sessionsintegerMinActiveSessions is the minimum number of sessions to keep alive. Agent-level only. Counts against rig/workspace caps. Replaces pool.min. This controls pool sessions independently of [[named_session]] mode="always"; both produce sessions, and gc doctor reports accidental combinations.
scale_checkstringScaleCheck is a shell command template whose output reports new unassigned session demand. In bead-backed reconciliation this is additive: assigned work is resumed separately, and ScaleCheck reports only how many new generic sessions to start, still bounded by all cap levels. Legacy no-store evaluation continues to treat the output as the desired session count. If it contains Go template placeholders, gc expands them using the same PathContext fields as work_dir and session_setup (Agent, AgentBase, Rig, RigRoot, CityRoot, CityName, DefaultBranch) before running the command.
drain_timeoutstring5mDrainTimeout is the maximum time to wait for a session to finish its current work before force-killing it during scale-down. Duration string (e.g., "5m", "30m", "1h"). Defaults to "5m".
on_bootstringOnBoot is a shell command template run once at controller startup for this agent. If it contains Go template placeholders, gc expands them using the same PathContext fields as work_dir and session_setup (Agent, AgentBase, Rig, RigRoot, CityRoot, CityName, DefaultBranch) before running the command.
on_deathstringOnDeath is a shell command template run when a session dies unexpectedly. If it contains Go template placeholders, gc expands them using the same PathContext fields as work_dir and session_setup (Agent, AgentBase, Rig, RigRoot, CityRoot, CityName, DefaultBranch) before running the command.
namepoolstringNamepool is the path to a plain text file with one name per line. When set, sessions use names from the file as display aliases.
work_querystringWorkQuery is the shell command template to find available work for this agent. If it contains Go template placeholders, gc expands them using the same PathContext fields as work_dir and session_setup (Agent, AgentBase, Rig, RigRoot, CityRoot, CityName, DefaultBranch) before probe, hook, and prompt-context execution. Used by gc hook and available in prompt templates as {{.WorkQuery}}. If unset, Gas City uses a three-tier default query: 1. in_progress work assigned to this session/alias (crash recovery) 2. ready work assigned to this session/alias (pre-assigned work) 3. ready unassigned work with gc.routed_to=<qualified-name> When the controller probes for demand without session context, only the routed_to tier applies. Override to integrate with external task systems.
sling_querystringSlingQuery is the command template to route a bead to this session config. If it contains Go template placeholders, gc expands them using the same PathContext fields as work_dir and session_setup (Agent, AgentBase, Rig, RigRoot, CityRoot, CityName, DefaultBranch) before replacing {} with the bead ID. Used by gc sling to make a bead visible to the target's work_query. The placeholder {} is replaced with the bead ID at runtime. Default for all agents: "bd update {} --set-metadata gc.routed_to=<qualified-name>". Routing is metadata-based; sling stamps the target template and the reconciler/scale_check paths decide when sessions are created. Custom sling_query and work_query can be overridden independently.
idle_timeoutstringIdleTimeout is the maximum time an agent session can be inactive before the controller kills and restarts it. Duration string (e.g., "15m", "1h"). Empty (default) disables idle checking.
max_session_agestringMaxSessionAge is the maximum wall-clock lifetime of a single runtime session before the controller preemptively restarts it. Duration string (e.g., "5h"). Empty (default) disables preemptive restarts. The restart is idle-gated: sessions with a pending interaction or an in-progress assigned work bead are left alone until they settle. Motivation: provider SDKs that cache credentials at session start (e.g., Claude Code via Bedrock) can wedge when the underlying token expires if the SDK doesn't re-chain providers. Cycling long-running sessions before the token-expiry window prevents that failure mode without requiring upstream provider fixes.
max_session_age_jitterstringMaxSessionAgeJitter bounds random jitter added to MaxSessionAge on a per-session basis so a fleet of identically-configured agents doesn't synchronize restarts. Duration string (e.g., "15m"). Empty or 0 disables jitter (every session restarts at exactly MaxSessionAge). Ignored when MaxSessionAge is unset.
assigned_work_defer_limitintegerAssignedWorkDeferLimit bounds how many consecutive reconciler ticks the idle-timeout ladder may defer on the same assigned-work bead (DecideIdleTimeout's AssignedWorkHas rung) before the reconciler overrides the defer and forces a stop via DecideAssignedWorkExhausted. Nil means use the built-in default. Without this backstop a session anchored to a bead that never clears assigned-work (e.g. a bead stuck open due to an upstream status-mapping bug) would defer indefinitely, reproducing the unbounded wake/idle-kill treadmill ga-3ox7rk fixed at the single-tick level. The counter resets whenever the anchor bead changes or the session is not idle-kill-eligible; see sessionHasAwakeAssignedWorkForReachableStore's caller in session_reconciler.go.
sleep_after_idlestringSleepAfterIdle overrides idle sleep policy for this agent. Accepts a duration string (e.g., "30s") or "off".
install_agent_hooks[]stringInstallAgentHooks overrides workspace-level install_agent_hooks for this agent. When set, replaces (not adds to) the workspace default.
skills[]stringSkills is a tombstone field retained for v0.15.1 backwards compatibility. Accepted during parse for migration visibility, but attachment-list fields are accepted but ignored by the active materializer.
mcp[]stringMCP is a tombstone field retained for v0.15.1 backwards compatibility. Accepted during parse for migration visibility, but attachment-list fields are accepted but ignored by the active materializer.
hooks_installedbooleanHooksInstalled overrides automatic hook detection. Set to true when hooks are manually installed (e.g., merged into the project's own hook config) and auto-installation via install_agent_hooks is not desired. When true, the agent is treated as hook-enabled for startup behavior: no prime instruction in beacon and no delayed nudge. Interacts with install_agent_hooks — set this instead when hooks are pre-installed.
session_setup[]stringSessionSetup is a list of shell commands run after session creation. Each command is a template string supporting placeholders: {{.Session}}, {{.Agent}}, {{.AgentBase}}, {{.Rig}}, {{.RigRoot}}, {{.CityRoot}}, {{.CityName}}, {{.WorkDir}}, {{.DefaultBranch}}. {{.DefaultBranch}} is the rig's configured default_branch (empty for city-scoped agents and rigs that record none); it is never probed from git, so scripts should keep their own origin/HEAD fallback. Commands run in gc's process (not inside the agent session) via sh -c. On failure, the last 4 KiB of the command's stdout/stderr is included in the error and may appear in controller and reconciler logs; avoid set -x or echoing secrets in setup commands.
session_setup_scriptstringSessionSetupScript is the path to a script run after session_setup commands. Relative paths resolve against the declaring config file's directory (pack-safe). Paths prefixed with "//" resolve against the city root. The script receives context via environment variables (GC_SESSION plus existing GC_* vars). On failure, the last 4 KiB of the script's stdout/stderr is included in the error and may appear in controller and reconciler logs; avoid set -x or echoing secrets in setup scripts.
session_live[]stringSessionLive is a list of shell commands that are safe to re-apply without restarting the agent. Run at startup (after session_setup) and re-applied on config change without triggering a restart. Must be idempotent. Typical use: tmux theming, keybindings, status bars. Same template placeholders as session_setup. On failure, the last 4 KiB of the command's stdout/stderr is included in the error and may appear in controller and reconciler logs; avoid set -x or echoing secrets in setup commands.
overlay_dirstringOverlayDir is a directory whose contents are recursively copied (additive) into the agent's working directory at startup. Existing files are not overwritten. Relative paths resolve against the declaring config file's directory (pack-safe).
default_sling_formulastringDefaultSlingFormula is the formula name automatically applied via --on when beads are slung to this agent, unless --no-formula is set. Example: "mol-polecat-work"
inject_fragments[]stringInjectFragments lists named template fragments to append to this agent's rendered prompt. Fragments come from shared template directories across all loaded packs. Each name must match a {{ define "name" }} block.
append_fragments[]stringAppendFragments is the V2 per-agent alias for prompt fragment injection. It layers after InjectFragments and before inherited/default fragments.
inject_assigned_skillsbooleanInjectAssignedSkills controls whether gc appends an "assigned skills" appendix to the agent's rendered prompt. The appendix lists every skill visible to this agent, partitioned into (assigned-to-you, shared-with-every-agent), so agents sharing a scope-root sink can tell which skills are their specialization vs which are the city-wide set. Pointer tri-state: nil -> inherit: inject when the agent has a vendor sink *true -> explicitly inject (equivalent to the default) *false -> disable; the template is responsible for rendering any skill guidance itself
attachbooleanAttach controls whether the agent's session supports interactive attachment (e.g., tmux attach). When false, the agent can use a lighter runtime (subprocess instead of tmux). Defaults to true.
depends_on[]stringDependsOn lists agent names that must be awake before this agent wakes. Used for dependency-ordered startup and shutdown. Validated for cycles at config load time.
resume_commandstringResumeCommand is the full shell command to run when resuming this agent. Supports {{.SessionKey}} template variable. When set, takes precedence over the provider's ResumeFlag/ResumeStyle. Example: "claude --resume {{.SessionKey}} --dangerously-skip-permissions"
wake_modestringWakeMode controls context freshness across sleep/wake cycles. "resume" (default): reuse provider session key for conversation continuity. "fresh": start a new provider session on every wake (polecat pattern). Enum: resume, fresh
mouse_modestringMouseMode controls whether tmux mouse mode is preserved for this agent. "on" leaves the session's mouse setting alone for human-attached sessions; "off" or empty preserves the SDK's default mouse-off startup behavior for headless sessions. Enum: on, off

AgentDefaults

AgentDefaults provides agent defaults declared via [agent_defaults] in city.toml or pack.toml.

FieldTypeRequiredDefaultDescription
providerstringProvider is the default provider name for agents that do not set their own provider. It also counts as a configured provider for implicit agent injection.
modelstringModel is the parsed/composed default model name for agents (e.g., "claude-sonnet-4-6"), but it is not yet auto-applied at runtime. Agents with their own model override would take precedence.
upstreamstringUpstream is the default model-serving endpoint (a key in [upstreams]) for agents that do not set their own upstream (Phase C — the Upstream axis). Applied to agents with an empty Upstream by ApplyAgentDefaults.
wake_modestringWakeMode is the parsed/composed default wake mode ("resume" or "fresh"), but it is not yet auto-applied at runtime. Enum: resume, fresh
default_sling_formulastringDefaultSlingFormula is the default formula used for agents that inherit [agent_defaults]. Explicit agents only receive this value when agent_defaults.default_sling_formula is set; implicit multi-session configs are seeded with "mol-do-work" elsewhere when no explicit default is set.
allow_overlay[]stringAllowOverlay is parsed and composed as a config-level allowlist for session overlays, but it is not yet inherited onto agents automatically at runtime.
allow_env_override[]stringAllowEnvOverride is parsed and composed as a config-level allowlist for session env overrides, but it is not yet inherited onto agents automatically at runtime. Names must match ^[A-Z][A-Z0-9_]{0,127}$.
append_fragments[]stringAppendFragments lists named template fragments to auto-append to .template.md prompts after rendering. Legacy .md.tmpl prompts are still supported during the transition; plain .md remains inert. V2 migration convenience — replaces global_fragments/inject_fragments for config-wide defaults.
skills[]stringSkills is a tombstone field retained for v0.15.1 backwards compatibility. Parsed and composed for migration visibility, but attachment-list fields are accepted but ignored by the active materializer.
mcp[]stringMCP is a tombstone field retained for v0.15.1 backwards compatibility. Parsed and composed for migration visibility, but attachment-list fields are accepted but ignored by the active materializer.

AgentOverride

AgentOverride modifies a pack-stamped agent for a specific rig.

FieldTypeRequiredDefaultDescription
agentstringyesAgent is the name of the pack agent to override (required).
dirstringDir overrides the stamped dir (default: rig name).
work_dirstringWorkDir overrides the agent's working directory without changing its qualified identity or rig association.
tmux_aliasstringTmuxAlias overrides the tmux session name template (see Agent.TmuxAlias for semantics).
scopestringScope overrides the agent's scope ("city" or "rig").
suspendedbooleanSuspended sets the agent's suspended state.
poolPoolOverridePool overrides legacy [pool] fields that map to session scaling.
envmap[string]stringEnv adds or overrides environment variables.
env_remove[]stringEnvRemove lists env var keys to remove.
pre_start[]stringPreStart overrides the agent's pre_start commands.
prompt_templatestringPromptTemplate overrides the prompt template path. Relative paths resolve against the declaring config file's directory (pack-safe). Paths prefixed with "//" resolve against the city root.
sessionstringSession overrides the session transport ("acp").
providerstringProvider overrides the provider name.
upstreamstringUpstream overrides the model-serving endpoint selection (Phase C).
args[]stringArgs overrides the provider's default arguments. Leave unset to keep the pack-defined args; set to an empty list to clear them; set to a populated list to replace them entirely (full replace, not append).
start_commandstringStartCommand overrides the start command.
lifecyclestringLifecycle overrides the runtime lifecycle ("one_shot" or empty). Enum: one_shot
nudgestringNudge overrides the nudge text.
idle_timeoutstringIdleTimeout overrides the idle timeout duration string (e.g., "30s", "5m", "1h").
max_session_agestringMaxSessionAge overrides the max session age. Duration string (e.g., "5h"). Empty disables preemptive restart.
max_session_age_jitterstringMaxSessionAgeJitter overrides the jitter added on top of MaxSessionAge. Duration string (e.g., "15m"). Empty disables jitter.
assigned_work_defer_limitintegerAssignedWorkDeferLimit overrides Agent.AssignedWorkDeferLimit (see that field for semantics).
sleep_after_idlestringSleepAfterIdle overrides idle sleep policy for this agent. Accepts a duration string (e.g., "30s") or "off".
install_agent_hooks[]stringInstallAgentHooks overrides the agent's install_agent_hooks list.
skills[]stringSkills is a tombstone field retained for v0.15.1 backwards compatibility. Parsed for migration visibility, but attachment-list fields are accepted but ignored by the active materializer.
mcp[]stringMCP is a tombstone field retained for v0.15.1 backwards compatibility. Parsed for migration visibility, but attachment-list fields are accepted but ignored by the active materializer.
hooks_installedbooleanHooksInstalled overrides automatic hook detection.
inject_assigned_skillsbooleanInjectAssignedSkills overrides Agent.InjectAssignedSkills (see that field for semantics).
session_setup[]stringSessionSetup overrides the agent's session_setup commands.
session_setup_scriptstringSessionSetupScript overrides the agent's session_setup_script path. Relative paths resolve against the declaring config file's directory (pack-safe). Paths prefixed with "//" resolve against the city root.
session_live[]stringSessionLive overrides the agent's session_live commands.
overlay_dirstringOverlayDir overrides the agent's overlay_dir path. Copies contents additively into the agent's working directory at startup. Relative paths resolve against the declaring config file's directory (pack-safe). Paths prefixed with "//" resolve against the city root.
default_sling_formulastringDefaultSlingFormula overrides the default sling formula.
inject_fragments[]stringInjectFragments overrides the agent's inject_fragments list. Leave this field unset to keep inherited fragments; JSON callers may send null for the same no-op. Set an empty list to clear fragments; set a populated list to replace fragments.
append_fragments[]stringAppendFragments appends named template fragments to this agent's rendered prompt. It is the V2 spelling for per-agent fragment selection.
pre_start_append[]stringPreStartAppend appends commands to the agent's pre_start list (instead of replacing). Applied after PreStart if both are set.
session_setup_append[]stringSessionSetupAppend appends commands to the agent's session_setup list.
session_live_append[]stringSessionLiveAppend appends commands to the agent's session_live list.
install_agent_hooks_append[]stringInstallAgentHooksAppend appends to the agent's install_agent_hooks list.
skills_append[]stringSkillsAppend is a tombstone field retained for v0.15.1 backwards compatibility. Parsed for migration visibility, but attachment-list fields are accepted but ignored by the active materializer.
mcp_append[]stringMCPAppend is a tombstone field retained for v0.15.1 backwards compatibility. Parsed for migration visibility, but attachment-list fields are accepted but ignored by the active materializer.
attachbooleanAttach overrides the agent's attach setting.
depends_on[]stringDependsOn overrides the agent's dependency list.
resume_commandstringResumeCommand overrides the agent's resume_command template.
wake_modestringWakeMode overrides the agent's wake mode ("resume" or "fresh"). Enum: resume, fresh
mouse_modestringMouseMode overrides whether tmux mouse mode is preserved ("on" or "off"). Enum: on, off
inject_fragments_append[]stringInjectFragmentsAppend appends to the agent's inject_fragments list.
max_active_sessionsintegerMaxActiveSessions overrides the agent-level cap on concurrent sessions.
min_active_sessionsintegerMinActiveSessions overrides the minimum number of sessions to keep alive.
scale_checkstringScaleCheck overrides the shell command whose output reports new unassigned session demand for bead-backed reconciliation.
option_defaultsmap[string]stringOptionDefaults adds or overrides provider option defaults for this agent. Keys are option keys, values are choice values. Merges additively (override keys win over existing agent keys). Example: option_defaults = { model = "sonnet" }

AgentPatch

AgentPatch modifies existing agents identified by rig scope and Name.

FieldTypeRequiredDefaultDescription
dirstringDir is the legacy targeting key for rig identity. Empty means city-scoped. New configs should set Rig instead; Dir remains the canonical resolved identity that both keys feed into.
rigstringRig is new targeting key for rig identity (replaces Dir). "*" matches all rigs + city. Empty means city-scoped unless Dir is set.
namestringyesName is the targeting key (required). Must match an existing agent's name.
work_dirstringWorkDir overrides the agent's session working directory.
tmux_aliasstringTmuxAlias overrides the tmux session name template (see Agent.TmuxAlias for semantics).
scopestringScope overrides the agent's scope ("city" or "rig").
suspendedbooleanSuspended overrides the agent's suspended state.
poolPoolOverridePool overrides legacy [pool] fields that map to session scaling.
envmap[string]stringEnv adds or overrides environment variables.
env_remove[]stringEnvRemove lists env var keys to remove after merging.
pre_start[]stringPreStart overrides the agent's pre_start commands.
prompt_templatestringPromptTemplate overrides the prompt template path. Relative paths resolve against the declaring config file's directory (pack-safe). Paths prefixed with "//" resolve against the city root.
sessionstringSession overrides the session transport ("acp" or "tmux").
providerstringProvider overrides the provider name.
upstreamstringUpstream overrides the model-serving endpoint selection (Phase C).
args[]stringArgs overrides the provider's default arguments. Leave unset to keep the pack-defined args; set to an empty list to clear them; set to a populated list to replace them entirely (full replace, not append).
start_commandstringStartCommand overrides the start command.
lifecyclestringLifecycle overrides the runtime lifecycle ("one_shot" or empty). Enum: one_shot
nudgestringNudge overrides the nudge text.
idle_timeoutstringIdleTimeout overrides the idle timeout. Duration string (e.g., "30s", "5m", "1h").
max_session_agestringMaxSessionAge overrides the max session age. Duration string (e.g., "5h").
max_session_age_jitterstringMaxSessionAgeJitter overrides the max session age jitter. Duration string (e.g., "15m").
assigned_work_defer_limitintegerAssignedWorkDeferLimit overrides Agent.AssignedWorkDeferLimit (see that field for semantics).
sleep_after_idlestringSleepAfterIdle overrides idle sleep policy for this agent. Accepts a duration string or "off".
install_agent_hooks[]stringInstallAgentHooks overrides the agent's install_agent_hooks list.
skills[]stringSkills is a tombstone field retained for v0.15.1 backwards compatibility. Deprecated: removed in v0.16. Tombstone — accepted but ignored. See engdocs/proposals/skill-materialization.md
mcp[]stringMCP is a tombstone field retained for v0.15.1 backwards compatibility. Deprecated: removed in v0.16. Tombstone — accepted but ignored. See engdocs/proposals/skill-materialization.md
skills_append[]stringSkillsAppend is a tombstone field retained for v0.15.1 backwards compatibility. Deprecated: removed in v0.16. Tombstone — accepted but ignored. See engdocs/proposals/skill-materialization.md
mcp_append[]stringMCPAppend is a tombstone field retained for v0.15.1 backwards compatibility. Deprecated: removed in v0.16. Tombstone — accepted but ignored. See engdocs/proposals/skill-materialization.md
hooks_installedbooleanHooksInstalled overrides automatic hook detection.
inject_assigned_skillsbooleanInjectAssignedSkills overrides per-agent appendix injection (see Agent.InjectAssignedSkills).
session_setup[]stringSessionSetup overrides the agent's session_setup commands.
session_setup_scriptstringSessionSetupScript overrides the agent's session_setup_script path. Relative paths resolve against the declaring config file's directory (pack-safe). Paths prefixed with "//" resolve against the city root.
session_live[]stringSessionLive overrides the agent's session_live commands.
overlay_dirstringOverlayDir overrides the agent's overlay_dir path. Copies contents additively into the agent's working directory at startup. Relative paths resolve against the declaring config file's directory (pack-safe). Paths prefixed with "//" resolve against the city root.
default_sling_formulastringDefaultSlingFormula overrides the default sling formula.
inject_fragments[]stringInjectFragments overrides the agent's inject_fragments list. Leave this field unset to keep inherited fragments; JSON callers may send null for the same no-op. Set an empty list to clear fragments; set a populated list to replace fragments.
append_fragments[]stringAppendFragments overrides the agent's append_fragments list.
attachbooleanAttach overrides the agent's attach setting.
depends_on[]stringDependsOn overrides the agent's dependency list.
resume_commandstringResumeCommand overrides the agent's resume_command template.
wake_modestringWakeMode overrides the agent's wake mode ("resume" or "fresh"). Enum: resume, fresh
mouse_modestringMouseMode overrides whether tmux mouse mode is preserved ("on" or "off"). Enum: on, off
pre_start_append[]stringPreStartAppend appends commands to the agent's pre_start list (instead of replacing). Applied after PreStart if both are set.
session_setup_append[]stringSessionSetupAppend appends commands to the agent's session_setup list.
session_live_append[]stringSessionLiveAppend appends commands to the agent's session_live list.
install_agent_hooks_append[]stringInstallAgentHooksAppend appends to the agent's install_agent_hooks list.
inject_fragments_append[]stringInjectFragmentsAppend appends to the agent's inject_fragments list.
max_active_sessionsintegerMaxActiveSessions overrides the agent-level cap on concurrent sessions.
min_active_sessionsintegerMinActiveSessions overrides the minimum number of sessions to keep alive.
scale_checkstringScaleCheck overrides the command template whose output reports new unassigned session demand for bead-backed reconciliation. Supports the same Go template placeholders as Agent.scale_check.
option_defaultsmap[string]stringOptionDefaults adds or overrides provider option defaults for this agent. Keys are option keys, values are choice values. Merges additively (patch keys win over existing agent keys). Example: option_defaults = { model = "sonnet" }

BeadPolicyConfig

BeadPolicyConfig holds storage and retention defaults for a named bead use.

FieldTypeRequiredDefaultDescription
storagestringStorage selects the intended persistence tier: "history", "no_history", or "ephemeral". Creation paths apply this incrementally as they opt in. Enum: history, no_history, ephemeral
delete_after_closestringDeleteAfterClose deletes matching GC-owned beads after they have been closed for this duration. Accepts Go duration syntax plus whole-day "d" units, e.g. "7d" or "1d12h". ApplyBeadPolicyDefaults fills in a non-empty default for recognized policy types (order_tracking: "7d"), so this field is populated after config load even when the city.toml omits it.

BeadsConfig

BeadsConfig holds bead store settings.

FieldTypeRequiredDefaultDescription
providerstringbdProvider selects the bead store backend: "bd" (default, Dolt-backed), "file", or "exec:<script>" for a user-supplied script. The "sqlite", "sqlite-cgo", and "coordstore" coordination-store providers were removed and now hard-error; migrate to "doltlite" or remove the setting.
backendstringBackend selects the bd storage engine when Provider is "bd". Empty defaults to "dolt"; T3Code uses "doltlite" for local dev stores.
event_hooksbooleantrueEventHooks controls installation of the bead event-forwarding hooks (.beads/hooks/on_create,on_update,on_close) that shell out to gc event emit on every bead write. Defaults to true. Set to false once the controller's native cache-events already observe bead changes (the bd_hooks doctor gate): the lifecycle then removes the event hooks (leaving git hooks untouched) and stops reinstalling them, clearing the per-write churn and the native-store gate.
bd_compatibilitystringBDCompatibility selects the bd CLI semantics Gas City may rely on. Empty defaults to "bd-1.0.4", which keeps claimable work history-backed and avoids bd ready/list flags that are unavailable or incomplete in bd 1.0.4. Enum: bd-1.0.4, bd-1.0.5
conditional_writesstringConditionalWrites selects the bead-write discipline: "off" (legacy, byte-identical), "auto" (compare-and-swap where the store is capable, loud degrade otherwise), or "require" (CAS or a typed refusal). Empty defaults to "off". Any other value fails config load. Enum: off, auto, require
guarded_releasestringGuardedRelease selects the ownership-release discipline for work beads: "off" (legacy, owner-blind bd update/unclaim), "auto" (fence-guarded release verbs where the bd binary is capable, loud degrade otherwise), or "require" (guarded release or a typed refusal). Empty defaults to "off". Any other value fails config load. Enum: off, auto, require
policiesmap[string]BeadPolicyConfigPolicies defines per-bead-use storage and garbage-collection defaults. Policy names are interpreted by higher-level systems; unknown names are preserved so packs can stage future policy classes without breaking load.

ChatSessionsConfig

ChatSessionsConfig configures chat session behavior.

FieldTypeRequiredDefaultDescription
idle_timeoutstringIdleTimeout is the duration after which a detached chat session is auto-suspended. Duration string (e.g., "30m", "1h"). 0 = disabled.
grace_periodstringGracePeriod is the duration after creation during which a manual session is protected from idle-sleep scale-to-zero. Duration string (e.g., "10m"). Empty = use default (10m). "0" = disabled.

ConvergenceConfig

ConvergenceConfig holds convergence loop limits.

FieldTypeRequiredDefaultDescription
max_per_agentinteger2MaxPerAgent is the maximum number of active convergence loops per agent in each bead store scope. City/HQ and each bound rig enforce the limit independently. 0 means use default (2).
max_totalinteger10MaxTotal is the maximum total number of active convergence loops. 0 means use default (10).

DaemonConfig

DaemonConfig holds controller daemon settings.

FieldTypeRequiredDefaultDescription
formula_v2booleantrueFormulaV2 enables formula compiler v2 workflow infrastructure: compiler-v2 workflow compilation, batch graph-apply bead creation, and routing to the core pack's control-dispatcher worker. Requires bd with --graph support. Default: ENABLED. A nil pointer means the default-on behavior and is OMITTED from generated configs (so auto-generated city.toml files never pin the default and never accidentally write formula_v2=false); an explicit formula_v2=false (or the deprecated graph_workflows=false alias) is preserved as a non-nil false. Read the effective value via FormulaV2Enabled(), never the field.
graph_workflowsbooleanGraphWorkflows is the deprecated predecessor of FormulaV2. Retained for backwards compatibility as an alias. Explicit formula_v2 wins.
patrol_intervalstring30sPatrolInterval is the health patrol interval. Duration string (e.g., "30s", "5m", "1h"). Defaults to "30s".
max_restartsinteger5MaxRestarts is the maximum number of agent restarts within RestartWindow before the agent is quarantined. 0 means unlimited (no crash loop detection). Defaults to 5.
restart_windowstring1hRestartWindow is the sliding time window for counting restarts. Duration string (e.g., "30s", "5m", "1h"). Defaults to "1h".
session_circuit_breakerbooleanSessionCircuitBreaker enables the named-session respawn circuit breaker. When enabled, the controller suppresses no-progress named-session respawns after the configured restart threshold is exceeded.
session_circuit_breaker_max_restartsinteger5SessionCircuitBreakerMaxRestarts overrides MaxRestarts for the named-session respawn circuit breaker. Nil reuses MaxRestartsOrDefault. 0 disables the circuit breaker even when SessionCircuitBreaker is true.
session_circuit_breaker_windowstring1hSessionCircuitBreakerWindow overrides RestartWindow for the named-session respawn circuit breaker. Empty reuses RestartWindowDuration.
session_circuit_breaker_reset_afterstringSessionCircuitBreakerResetAfter is the cooldown before an open named-session breaker resets automatically. Empty defaults to 2 * SessionCircuitBreakerWindowDuration.
shutdown_timeoutstring5sShutdownTimeout is the time to wait after sending Ctrl-C before force-killing agents during shutdown. Duration string (e.g., "5s", "30s"). Set to "0s" for immediate kill. Defaults to "5s".
dolt_stop_timeoutstring30sDoltStopTimeout is the SIGTERM→SIGKILL grace period for the managed dolt subprocess during stop, unregister, restart, and startup/recovery cleanup. Independent of ShutdownTimeout (which gates agent drain) so a slow session drain cannot steal dolt's flush window. Duration string (e.g., "30s", "1m"). A too-short value risks SIGKILL during a journal index update or manifest rotation, which corrupts dolt's chunk journal (see gastownhall/gascity#2090). Defaults to "30s", which absorbs the longest observed flush window on commodity SSDs without unduly delaying unregister. Set to "0s" for immediate SIGKILL with no grace. Negative values are rejected at config load. Note: when a city is stopped via the controller (gc stop while a controller is running), the standalone controller-stop wait budget is shutdown_timeout + 15s (20s at the default shutdown_timeout of "5s"); a dolt_stop_timeout larger than that budget can be cut short on that path even though the direct stop/unregister path always honors the full grace.
dolt_start_address_in_use_retry_windowstring30sDoltStartAddressInUseRetryWindow is how long the managed dolt start path waits on the originally requested port when bind fails with "address already in use" before falling back to a higher port. The common cause is a TIME_WAIT socket left by an abrupt stop of a sibling dolt subprocess (external SIGTERM, supervisor restart, OOM kill); on Linux the listening-socket slot typically frees within ~30s. Falling back immediately publishes the rebound port to provider state, after which recoverManagedDoltShouldReuseExisting keeps accepting the rebound instance as canonical and consumers hardcoded to the original port stay broken until the orphan is killed. Duration string (e.g., "30s", "1m"). Set to "0s" to disable the retry (legacy fall-back- immediately behavior). Defaults to "30s". Each port is waited on at most once per startManagedDoltProcessWithOptions invocation, so the worst-case wall time per startup is bounded by (DoltStartAddressInUseRetryWindow + per-attempt-startup) × min(5, distinct-ports-tried) rather than DoltStartAddressInUseRetryWindow × 5. Negative values are rejected at config load.
wisp_gc_intervalstringWispGCInterval is how often the garbage collector for wisps runs. A wisp is an ephemeral bead produced by a v1 formula run; this knob controls how often the closed ones are swept. Duration string (e.g., "5m", "1h"). Wisp GC is disabled unless both WispGCInterval and WispTTL are set.
wisp_ttlstringWispTTL is how long a closed wisp (an ephemeral v1 formula-run bead) survives before being purged. Duration string (e.g., "24h", "7d"). Wisp GC is disabled unless both WispGCInterval and WispTTL are set.
drift_drain_timeoutstring2mDriftDrainTimeout is the maximum time to wait for an agent to acknowledge a drain signal during a config-drift restart. If the agent doesn't ack within this window, the controller force-kills and restarts it. Duration string (e.g., "2m", "5m"). Defaults to "2m".
observe_paths[]stringObservePaths lists extra directories to search for Claude JSONL session files (e.g., aimux session paths). The default search path (~/.claude/projects/) is always included.
probe_concurrencyinteger8ProbeConcurrency bounds the number of concurrent bd subprocess probes issued by the pool scale_check and work_query paths. bd serializes on a shared dolt sql-server, so unbounded parallelism causes contention. Nil (unset) defaults to 8. Set higher for workspaces with a fast dedicated dolt server, or lower to reduce contention on slow storage.
max_wakes_per_tickinteger5MaxWakesPerTick caps how many sessions the reconciler may start in a single tick. Fresh generic pool session-bead creation uses the same budget so the controller does not materialize more ordinary pool sessions than it can wake. Bounded dependency-floor prerequisites are exempt. Nil (unset) defaults to 5. Values <= 0 are treated as the default — set a positive integer to override.
nudge_dispatcherstringlegacyNudgeDispatcher selects how queued nudges get delivered to running sessions. "legacy" (default) auto-spawns a per-session gc nudge poll process that polls the file-backed queue every 2s. "supervisor" runs the delivery loop inside the city runtime instead, with a unix-socket wake fast path triggered by enqueue, eliminating the per-session bd shellout storm. Enum: legacy, supervisor
auto_restart_on_driftbooleantrueAutoRestartOnDrift controls whether gc start automatically restarts the supervisor when it detects the running supervisor's binary or pack snapshot has drifted from on-disk state. Nil (unset) defaults to true — operators get the correct-by-default behavior. Set to false as a global kill switch (e.g., for production cities where a rebuild on the host should not auto-restart the supervisor).
auto_reap_closed_bead_worktreesbooleanfalseAutoReapClosedBeadWorktrees controls whether the reconciler patrol automatically removes per-bead git worktrees once their associated work bead reaches closed status. Only worktrees with a clean working tree, no stashes, and no commits that removal would orphan — commits reachable from no branch, tag, or remote-tracking ref — are removed; push state is deliberately not the test, since git worktree remove deletes the checkout and not refs/heads. Unsafe worktrees are logged as warnings and left in place for operator review. Session home directories (agent template directories) are never touched. Defaults to false. Set to true to enable automated worktree cleanup.
auto_reap_closed_bead_worktrees_dry_runbooleanfalseAutoReapClosedBeadWorktreesDryRun makes the reconciler patrol run the full worktree-reap classification each tick — discovery, closed-bead match, liveness gate, and git-safety probes — but emit bead.worktree.reap_skipped events describing what it WOULD reap and what it protected, without removing anything. This is the safe staged-rollout surface: an operator enables dry-run first, confirms via gc events that no live worktree appears in the would-reap set, then enables AutoReapClosedBeadWorktrees for real removal. Those events are edge-triggered: each worktree is reported when the patrol first classifies it and again whenever its verdict changes, not once per tick, so the would-reap set is complete right after dry-run is enabled rather than reprinted every sweep. Dry-run has no effect when AutoReapClosedBeadWorktrees is already true (real removal supersedes it). Defaults to false.
auto_reap_closed_bead_worktrees_min_age_minutesinteger10AutoReapClosedBeadWorktreesMinAgeMinutes is the minimum worktree age, in minutes, before a closed-bead worktree becomes eligible for reap classification at all (borrow-veto scan and beyond). This quarantines a worktree against the race between its creation and its owning bead's gc.work_dir/work_dir metadata being stamped by the next reconcile pass — without it, a just-created worktree could look unclaimed to the borrow-veto scan before the metadata that would protect it has been written. Nil (unset) defaults to DefaultAutoReapClosedBeadWorktreesMinAgeMinutes. Zero disables the quarantine entirely (every closed-bead worktree is immediately eligible for the rest of the gate chain, regardless of age).
start_ready_timeoutstring5mStartReadyTimeout is how long gc start and gc register wait for the supervisor to report the city as Running. Cities with many registered or adopted sessions take longer to start because the per-tick wake budget (max_wakes_per_tick) throttles startup: wall time to wake N sessions is roughly ceil(N / max_wakes_per_tick) * patrol_interval. At the defaults (5 wakes / 30s), ~40 sessions need ~4 minutes. Duration string (e.g., "5m", "10m"). Defaults to DefaultStartReadyTimeout (5m). When set, this value replaces the default start/register budget; [session].startup_timeout may still extend the effective wait for a slow single session.
tick_debouncestringTickDebounce coalesces bursty event-driven ticks (pokeCh, controlDispatcherCh) within this window. A first event in a quiet period arms a timer; subsequent events arriving before the timer fires are dropped (the single delayed tick re-reads authoritative state covering all collapsed events). Zero (the default) disables debouncing — each event fires its own tick, matching pre-existing behavior. Duration string (e.g., "250ms", "500ms"). Trade-off: adds tick latency up to this value when set.
auto_prune_worker_dirbooleantrueAutoPruneWorkerDir controls whether the reconciler removes a pool-managed session's worker_dir (agent worktree) after the session bead is closed. Removal is gated on: path lives under the city's .gc/worktrees/ tree, clean working tree, no unpushed commits, no stashed work. Nil (unset) defaults to true so pool worktrees do not accumulate without bound across pool recycles. Set to false to retain worktrees for post-session diagnostics.

DoctorConfig

DoctorConfig holds settings for the gc doctor surface.

FieldTypeRequiredDefaultDescription
worktree_rig_warn_sizestring10GBWorktreeRigWarnSize is the per-rig warning threshold for the total disk footprint under .gc/worktrees/<rig>/. Reported by the worktree-disk-size check. Go-style human size string ("10GB", "500MB"). Empty or unparseable falls back to the default (10 GB).
worktree_rig_error_sizestring50GBWorktreeRigErrorSize is the per-rig error threshold. When any rig exceeds this, the worktree-disk-size check reports an error rather than a warning. Empty or unparseable falls back to the default (50 GB).
nested_worktree_prunebooleanfalseNestedWorktreePrune escalates the nested-worktree-prune check from warning to error severity when safely-prunable nested worktrees are present, so CI / scripted doctor runs fail until the operator runs gc doctor --fix. Actual removal still requires --fix; this flag does not auto-prune. Safety is enforced by mechanical checks (no uncommitted changes, no unpushed commits, no stashes) — never by role identity.
check[]LocalDoctorCheckChecks holds city-local inline doctor checks declared via [[doctor.check]] in city.toml.

DoltConfig

DoltConfig holds optional dolt server overrides.

FieldTypeRequiredDefaultDescription
portinteger0Port is the dolt server port. 0 means use ephemeral port allocation (hashed from city path). Set explicitly to override.
hoststringlocalhostHost is the dolt server hostname. Defaults to localhost.
archive_levelinteger0ArchiveLevel controls Dolt's auto_gc archive aggressiveness. 0 disables archive compaction (lower CPU on startup). 1 enables archive compaction (higher CPU on startup). nil (omitted) defaults to 0.
auto_gc_enabledbooleantrueAutoGCEnabled toggles Dolt's incremental auto-GC on the managed sql-server. Auto-GC bounds the noms journal so it never reaches GB scale, which shrinks both the unclean-stop corruption window and the recovery blast radius. nil (omitted) defaults to true.
max_connectionsinteger256MaxConnections overrides the managed Dolt listener max_connections. 0 means use the managed default.
read_timeout_millisinteger120000ReadTimeoutMillis overrides the managed Dolt listener read_timeout_millis. 0 means use the managed default.
write_timeout_millisinteger300000WriteTimeoutMillis overrides the managed Dolt listener write_timeout_millis. 0 means use the managed default.
wait_timeout_secondsinteger30WaitTimeoutSeconds overrides the managed server's wait_timeout system variable. Despite the name, wait_timeout does not currently reap idle connections -- measured inert on dolt 2.2.3 for #5383 (see DefaultDoltWaitTimeoutSeconds); read_timeout is the only reaper. The knob is kept and still emitted regardless: it is harmless, and becomes correct the moment dolt implements it. Before this field existed the only way to set it was GC_DOLT_WAIT_TIMEOUT in the supervisor's process environment, which no city.toml could express and no shell-invoked restart inherited — so a restart from an operator shell silently rewrote the value. 0 (omitted) means use the managed default.
dolt_lock_release_timeoutstring1mDoltLockReleaseTimeout is how long managed-dolt lifecycle operations wait for dolt's on-disk exclusive store locks (the root-level &lt;data_dir&gt;/.dolt/noms/LOCK and per-database &lt;data_dir&gt;/&lt;db&gt;/.dolt/noms/LOCK forms) to be released by a prior server process before failing closed. The start path refuses to launch a second dolt sql-server against a data_dir whose lock is still held — a prior instance that is shutting down holds the lock until its chunk journal is flushed, and binding before release corrupts the journal (see gastownhall/gascity#3174). The stop path uses the same window to wait for lock release after process exit before reporting success. Duration string (e.g., "1m", "90s"). Defaults to "1m", which covers the flush window of multi-GB journals on commodity SSDs. Set to "0s" to probe once with no wait (still fail-closed when held). Negative values are rejected at config load. The managed lifecycle also projects this value into the gc-beads-bd.sh shell fallback as GC_DOLT_LOCK_RELEASE_TIMEOUT_MS (milliseconds), so both paths honor the configured window.

DoltMaintenance

DoltMaintenance configures the periodic Dolt store maintenance loop.

FieldTypeRequiredDefaultDescription
enabledbooleanEnabled toggles the maintenance loop. Defaults to false (opt-in).
intervalstring168hInterval is the cadence between maintenance runs as a duration string (e.g., "168h"). Defaults to 168h (weekly).
alert_tostringAlertTo is the agent identity to mail on failure (e.g., "gascity/mayor"). Empty disables alert mail.
gc_timeoutstring10mGCTimeout is the ceiling for CALL DOLT_GC() as a duration string. Defaults to 10m.

EventsConfig

EventsConfig holds events provider settings.

FieldTypeRequiredDefaultDescription
providerstringProvider selects the events backend: "fake", "fail", "exec:<script>", or "" (default: file-backed JSONL).
rotationEventsRotationConfigRotation configures file-backed JSONL rotation. Defaults are applied by EventsRotationConfig helper methods when this table is absent.

EventsRotationConfig

EventsRotationConfig holds file-backed events rotation settings.

FieldTypeRequiredDefaultDescription
enabledbooleantrueEnabled controls automatic size-triggered rotation. Defaults to true.
max_size_bytesinteger268435456MaxSizeBytes is the active events.jsonl size threshold. Defaults to DefaultEventsRotationMaxSizeBytes.
check_interval_recordsinteger1024CheckIntervalRecords is the number of records between size checks. Defaults to DefaultEventsRotationCheckIntervalRecords.
check_interval_secondsinteger60CheckIntervalSeconds is the time backstop between size checks. Defaults to DefaultEventsRotationCheckIntervalSeconds.
archive_retain_agestringArchiveRetainAge is an optional Go duration. Empty keeps all archives.

ExtMsgConfig

ExtMsgConfig configures the external-messaging fabric.

FieldTypeRequiredDefaultDescription
default_route[]ExtMsgDefaultRouteDefaultRoutes map inbound conversations that have no binding and no group route to a configured agent, keyed by provider and optionally narrowed to one adapter account. The first matching inbound message binds the conversation to the agent (an agent-name binding), so the route is sticky until rebound or unbound.

ExtMsgDefaultRoute

ExtMsgDefaultRoute routes unbound inbound conversations from one external messaging provider (and optionally a single adapter account) to a configured agent.

FieldTypeRequiredDefaultDescription
providerstringyesProvider is the external messaging provider name as registered by the adapter (e.g. "telegram"). Required.
account_idstringAccountID narrows the route to one adapter account. Empty matches every account of the provider that has no account-specific route.
agentstringyesAgent is the configured agent identity to route to. It must resolve to a configured named session so the delivery layer can cold-wake a session for it.

FormulasConfig

FormulasConfig is the legacy [formulas] table with no supported fields: authored [formulas].dir is rejected at config load (use the well-known formulas/ directory instead), and gc doctor flags any declaration as a fixable v2-formulas-dir error.

GitHubConfig

GitHubConfig groups GitHub-facing repository monitor declarations.

FieldTypeRequiredDefaultDescription
pr_monitor[]GitHubPRMonitorPRMonitors declares GitHub pull-request readiness monitors.

GitHubPRMonitor

GitHubPRMonitor declares how one repository/base-branch set is monitored and where durable repair work should be routed when readiness fails.

FieldTypeRequiredDefaultDescription
namestringyesName is the stable monitor identity used by patches and diagnostics.
ownerstringyesOwner is the GitHub repository owner or organization.
repostringyesRepo is the GitHub repository name.
base_branches[]stringyesBaseBranches lists the base branches this monitor owns.
rigstringyesRig is the Gas City rig that owns repair work for this repository.
notify[]stringNotify lists session or mail recipients for readiness notifications.
repair_routestringyesRepairRoute is the operator-supplied route target for repair work.
repair_workflowstringRepairWorkflow is the formula attached to repair beads created for this monitor. Empty defaults to the standard polecat repair workflow so routed repair work carries the branch/test/push/refinery steps instead of sitting as a raw routed task.
webhook_secret_envstringWebhookSecretEnv is the environment variable containing the webhook HMAC secret. The secret value itself must not be stored in city.toml.
webhook_secret_keystringWebhookSecretKey is an optional stable key for identifying the webhook secret during rotation. When omitted, WebhookSecretEnv is the key.
poll_intervalstringPollInterval optionally enables bounded polling/backfill cadence.
merge_queuestringMergeQueuePolicy controls merge-queue signal handling. Empty defaults to "observe"; valid values are "ignore", "observe", and "repair". Enum: ignore, observe, repair

GitHubPRMonitorPatch

GitHubPRMonitorPatch modifies an existing GitHub PR readiness monitor by name.

FieldTypeRequiredDefaultDescription
namestringyesName is the monitor identity to patch.
ownerstringOwner overrides the GitHub repository owner or organization.
repostringRepo overrides the GitHub repository name.
base_branches[]stringBaseBranches replaces the monitored base branch list. An empty list clears the field and will fail validation unless another patch fills it.
rigstringRig overrides the owning rig.
notify[]stringNotify replaces notification recipients. An empty list clears recipients.
notify_append[]stringNotifyAppend appends notification recipients after Notify replacement.
repair_routestringRepairRoute overrides the repair route target.
repair_workflowstringRepairWorkflow overrides the formula attached to repair beads.
webhook_secret_envstringWebhookSecretEnv overrides the env var containing the webhook secret.
webhook_secret_keystringWebhookSecretKey overrides the stable webhook secret key.
poll_intervalstringPollInterval overrides the optional polling cadence.
merge_queuestringMergeQueuePolicy overrides merge-queue signal handling. Enum: ignore, observe, repair

Import

Import defines a named import of another pack.

FieldTypeRequiredDefaultDescription
sourcestringyesSource is the durable authored pack location: a local path, a remote git URL, or a dereferenceable GitHub tree URL for a pack below a repository root, such as "https://github.com/org/repo/tree/main/packs/foo". Registry handles are lookup-only in this release wave; authored [imports.*] entries store the resolved source plus optional version.
versionstringVersion is an optional semver constraint for git-backed imports (e.g., "^1.2"). Empty for local paths. "sha:<hex>" pins a specific commit.

K8sConfig

K8sConfig holds native K8s session provider settings.

FieldTypeRequiredDefaultDescription
namespacestringgcNamespace is the K8s namespace for agent pods. Default: "gc".
imagestringImage is the container image for agents.
contextstringContext is the kubectl/kubeconfig context. Default: current.
cpu_requeststring500mCPURequest is the pod CPU request. Default: "500m".
mem_requeststring1GiMemRequest is the pod memory request. Default: "1Gi".
cpu_limitstring2CPULimit is the pod CPU limit. Default: "2".
mem_limitstring4GiMemLimit is the pod memory limit. Default: "4Gi".
prebakedbooleanPrebaked skips init container staging and EmptyDir volumes when true. Use with images built by gc build-image that have city content baked in.

LocalDoctorCheck

LocalDoctorCheck is a city-local doctor check declared inline in city.toml via [[doctor.check]].

FieldTypeRequiredDefaultDescription
namestringyesName is the bare check name. The SDK injects the "local:" prefix; do not include it here.
scriptstringyesScript is the path to the check script, relative to the city root. Execution registration enforces containment within the city directory.
descriptionstringDescription is optional human-readable text shown in verbose output.
fixstringFix is the optional path to a remediation script, relative to the city root.

MailConfig

MailConfig holds mail provider settings.

FieldTypeRequiredDefaultDescription
providerstringProvider selects the mail backend: "fake", "fail", "exec:<script>", or "" (default: beadmail).
retention_ttlstringRetentionTTL is how long read messages are retained before purge. Empty or "0" disables read-message retention.

MaintenanceConfig

MaintenanceConfig groups periodic store-maintenance subsections.

FieldTypeRequiredDefaultDescription
doltDoltMaintenanceDolt configures the weekly Dolt store maintenance loop (CALL DOLT_GC + backup snapshot).

ModelPricing

ModelPricing is a complete pricing entry for a (Provider, Model) pair.

FieldTypeRequiredDefaultDescription
providerstringyesProvider is the LLM provider label (e.g. "claude", "codex", "gemini").
modelstringyesModel is the provider-specific model identifier (e.g. "claude-opus-4-8").
tierTieryesTier holds the per-token-type rates.
last_verifiedstringyesLastVerified is the date these rates were confirmed (YYYY-MM-DD).

NamedSession

NamedSession defines a canonical persistent session backed by an agent template.

FieldTypeRequiredDefaultDescription
namestringName is the configured public session identity. When omitted, Template remains the compatibility identity.
templatestringyesTemplate is the referenced agent template name. Root declarations may target imported agents via "binding.agent".
scopestringScope defines where this named session is instantiated in pack expansion: "city" (one per city) or "rig" (one per rig). Omit the field for an unscoped session instantiated in both city and rig expansion contexts. Enum: city, rig
dirstringDir is the identity prefix for rig-scoped named sessions after pack expansion. Empty means city-scoped.
modestringMode controls when the controller ensures this named session is live. "on_demand" (default): reserve identity and materialize when work or an explicit reference requires it. "always": keep the canonical session controller-managed. Note: mode="always" is independent of min_active_sessions; both produce sessions, and gc doctor reports accidental duplicate-pool combinations. Enum: on_demand, always

NamedSessionPatch

NamedSessionPatch modifies an existing named session identified by canonical name or, for compatibility, by an unambiguous template.

FieldTypeRequiredDefaultDescription
dirstringDir is the targeting key. Empty targets a city-scoped named session.
namestringName is the canonical named-session identity. Use this to disambiguate sessions that share the same template.
templatestringTemplate is a compatibility targeting key when Name is omitted.
modestringMode overrides the named-session controller mode ("on_demand" or "always"). Enum: on_demand, always

OptionChoice

OptionChoice is one allowed value for a "select" option.

FieldTypeRequiredDefaultDescription
valuestringyesValue is the choice identifier matched against ProviderOption.Default and the user's selection (e.g. "opus-4.8").
labelstringyesLabel is the human-readable choice name shown in tooling.
flag_args[]stringyesFlagArgs are the CLI arguments injected when this choice is selected. json:"-" is intentional: FlagArgs must never appear in the public API DTO (security boundary — prevents clients from seeing internal CLI flags).
flag_aliases[]arrayFlagAliases are equivalent CLI argument sequences stripped from legacy provider args. Like FlagArgs, they stay server-side only.

OrderOverride

OrderOverride modifies a scanned order's scheduling fields and exec env.

FieldTypeRequiredDefaultDescription
namestringyesName is the order name to target (required).
rigstringRig scopes the override to a specific rig's order. Empty matches city-level orders.
enabledbooleanEnabled overrides whether the order is active.
triggerstringTrigger overrides the trigger type.
gatestringGate is a deprecated alias for Trigger accepted during the gate->trigger migration. Parsed inputs are normalized to Trigger.
intervalstringInterval overrides the cooldown interval. Go duration string.
schedulestringSchedule overrides the cron expression.
checkstringCheck overrides the condition trigger check command.
onstringOn overrides the event trigger event type.
poolstringPool overrides the target session config.
timeoutstringTimeout overrides the per-order timeout. Go duration string.
check_timeoutstringCheckTimeout overrides the condition trigger's check-command deadline. Go duration string. Lets a deployment tune check_timeout for a scanned shared-pack order (e.g. a slow-store queue check) without editing the pack source.
idempotentbooleanIdempotent overrides whether the order's dispatch is safe to repeat. Idempotent orders fail open when the open-work gate times out (#2893).
envmap[string]stringEnv adds or overrides environment variables exported into an exec order's child process.

OrdersConfig

OrdersConfig holds order settings for orders discovered from flat TOML files (one file per order) in the orders/ directory beside each formula layer (packs, the city directory, and rig-local layers).

FieldTypeRequiredDefaultDescription
skip[]stringSkip lists order names to exclude from scanning.
max_timeoutstringMaxTimeout is an operator hard cap on the per-order dispatch timeout: no order's dispatched exec/formula runs longer than this. Go duration string (e.g., "60s"). Empty means uncapped (no override). This bounds the dispatch timeout only; a condition trigger's check_timeout is a separate probe deadline and is not capped here.
max_dispatches_per_tickintegerMaxDispatchesPerTick caps how many orders the supervisor dispatches per tick. Unset keeps the built-in default of 4; set to 1 to drain overdue cooldown orders one-per-tick at cold start instead of firing several concurrent goroutines at once.
overrides[]OrderOverrideOverrides apply per-order field overrides after scanning. Each override targets an order by name and optionally by rig.

PackDefaults

PackDefaults holds [defaults] entries used to seed generated rig configuration.

FieldTypeRequiredDefaultDescription
rigPackRigDefaults

PackRigDefaults

PackRigDefaults holds the [defaults.rig] block — defaults applied to rigs created from this pack.

FieldTypeRequiredDefaultDescription
importsmap[string]Import

Patches

Patches holds all patch blocks from composition.

FieldTypeRequiredDefaultDescription
agent[]AgentPatchAgents targets agents by rig scope + name.
named_session[]NamedSessionPatchNamedSessions targets configured named sessions by (dir, template).
rigs[]RigPatchRigs targets rigs by name.
providers[]ProviderPatchProviders targets providers by name.
github_pr_monitor[]GitHubPRMonitorPatchGitHubPRMonitors targets GitHub PR readiness monitors by name.

PoolOverride

PoolOverride modifies legacy [pool] fields that map to session scaling.

FieldTypeRequiredDefaultDescription
minintegerMin overrides the minimum number of sessions.
maxintegerMax overrides the maximum number of sessions. 0 means no sessions can claim routed work.
checkstringCheck overrides the session scale check command template. Supports the same Go template placeholders as Agent.scale_check.
drain_timeoutstringDrainTimeout overrides the drain timeout. Duration string (e.g., "5m", "30m", "1h").
on_deathstringOnDeath overrides the on_death command template. Supports the same Go template placeholders as Agent.on_death.
on_bootstringOnBoot overrides the on_boot command template. Supports the same Go template placeholders as Agent.on_boot.

ProviderOption

ProviderOption declares a single configurable option for a provider.

FieldTypeRequiredDefaultDescription
keystringyesKey is the option identifier (e.g. "model"); also the merge key for options_schema_merge = "by_key".
labelstringyesLabel is the human-readable option name shown in tooling.
typestringyes"select" only (v1)
defaultstringyesDefault is the Value of the choice selected when the user makes none.
choices[]OptionChoiceyesChoices are the allowed values; selecting one injects its FlagArgs into the agent command line (how the Model axis renders to a harness CLI flag).
omitbooleanOmit is the removal sentinel for options_schema_merge = "by_key". When set on a child layer's entry, the matching Key inherited from a parent layer is pruned from the resolved schema.

ProviderPatch

ProviderPatch modifies an existing provider identified by Name.

FieldTypeRequiredDefaultDescription
namestringyesName is the targeting key (required). Must match an existing provider's name.
basestringBase overrides the provider's inheritance parent (presence-aware). Pointer to a pointer so the patch can distinguish "no change" (double-nil) from "clear to inherit default" (single-nil value in outer pointer) from "set to explicit empty opt-out" (value "" in inner pointer) from "set to <name>". Callers use: nil = patch does not touch Base &(*string)(nil) = patch clears Base to absent &(&"") = patch sets Base = "" (explicit opt-out) &(&"builtin:codex") = patch sets Base to that value
commandstringCommand overrides the provider command.
acp_commandstringACPCommand overrides the provider command for ACP transport sessions.
args[]stringArgs overrides the provider args.
acp_args[]stringACPArgs overrides the provider args for ACP transport sessions.
args_append[]stringArgsAppend overrides the provider args_append list.
options_schema_mergestringOptionsSchemaMerge overrides the options_schema merge mode.
prompt_modestringPromptMode overrides prompt delivery mode. Enum: arg, flag, none
prompt_flagstringPromptFlag overrides the prompt flag.
ready_delay_msintegerReadyDelayMs overrides the ready delay in milliseconds.
accept_startup_dialogsbooleanAcceptStartupDialogs overrides startup dialog acceptance behavior.
envmap[string]stringEnv adds or overrides environment variables.
env_remove[]stringEnvRemove lists env var keys to remove.
_replacebooleanReplace replaces the entire provider block instead of deep-merging.

ProviderSpec

ProviderSpec defines a named provider's startup parameters.

FieldTypeRequiredDefaultDescription
basestringBase names the parent provider this spec inherits from. Supported forms: "<name>" - custom first (self-excluded), then built-in "builtin:<name>" - force built-in lookup "provider:<name>" - force custom lookup "" - explicit standalone opt-out nil - field absent; no explicit declaration
args_append[]stringArgsAppend accumulates extra args after each layer's Args replacement.
options_schema_mergestringOptionsSchemaMerge controls OptionsSchema merge mode across the chain: "replace" (default) or "by_key". Enum: replace, by_key
display_namestringDisplayName is the human-readable name shown in UI and logs.
commandstringCommand is the executable to run for this provider.
args[]stringArgs are default command-line arguments passed to the provider. The built-in Kiro provider defaults to ["chat", "--no-interactive", "--agent", "gascity", "--trust-all-tools"]; remove or replace "--trust-all-tools" by defining [providers.kiro].args explicitly in city.toml.
prompt_modestringargPromptMode controls how prompts are delivered: "arg", "flag", or "none". Enum: arg, flag, none
prompt_flagstringPromptFlag is the CLI flag used when prompt_mode is "flag" (e.g. "--prompt").
ready_delay_msintegerReadyDelayMs is milliseconds to wait after launch before the provider is considered ready.
ready_prompt_prefixstringReadyPromptPrefix is the string prefix that indicates the provider is ready for input.
process_names[]stringProcessNames lists process names to look for when checking if the provider is running.
emits_permission_warningbooleanEmitsPermissionWarning is tri-state: nil = inherit, &true = enable, &false = explicit disable.
accept_startup_dialogsbooleanAcceptStartupDialogs is tri-state: nil = default startup dialog handling, &true = force dialog acceptance, &false = suppress it for providers that handle permissions entirely through launch flags.
envmap[string]stringEnv sets additional environment variables for the provider process.
path_checkstringPathCheck overrides the binary name used for PATH detection. When set, lookupProvider and detectProviderName use this instead of Command for exec.LookPath checks. Useful when Command is a shell wrapper (e.g. sh -c '...') but we need to verify the real binary is installed.
supports_acpbooleanSupportsACP indicates the binary speaks the Agent Client Protocol (JSON-RPC 2.0 over stdio). When an agent sets session = "acp", its resolved provider must have SupportsACP = true.
supports_hooksbooleanSupportsHooks indicates the provider has an executable hook mechanism (settings.json, plugins, etc.) for lifecycle events.
instructions_filestringInstructionsFile is the filename the provider reads for project instructions (e.g., "CLAUDE.md", "AGENTS.md"). Empty defaults to "AGENTS.md".
resume_flagstringResumeFlag is the CLI flag for resuming a session by ID. Empty means the provider does not support resume. Examples: "--resume" (claude), "resume" (codex)
resume_stylestringResumeStyle controls how ResumeFlag is applied: "flag" → command --resume <key> (default) "subcommand" → command resume <key>
resume_commandstringResumeCommand is the full shell command to run when resuming a session. Supports only the {{.SessionKey}} template variable. When set, takes precedence over ResumeFlag/ResumeStyle. When schema-managed defaults are inserted, the resolver tokenizes and re-emits the command; for subcommand-style resume it inserts after the ResumeFlag token that precedes {{.SessionKey}}. Example: "claude --resume {{.SessionKey}} --dangerously-skip-permissions" Schema-managed defaults missing from a subcommand-style resume command are inserted before {{.SessionKey}} during provider resolution.
session_id_flagstringSessionIDFlag is the CLI flag for providers that support creating a fresh session with a caller-supplied ID. Empty means fresh starts cannot receive a preselected provider session ID; resume metadata must come from the provider after startup.
fork_flagstringForkFlag is the CLI flag that forks a resumed conversation into a new branch (claude's "--fork-session"). With ResumeFlag + SessionIDFlag it forms the fork-launch command (resume a parent brain session, fork off it, bind gc's own session id). Empty means the provider has no fork verb, in which case a launch carrying a parent sid fails loud rather than silently degrading to a fresh session.
permission_modesmap[string]stringPermissionModes maps permission mode names to CLI flags. Example: {"unrestricted": "--dangerously-skip-permissions", "plan": "--permission-mode plan"} This is a config-only lookup table consumed by external clients (e.g., real-world app) to populate permission mode dropdowns. Launch-time flag substitution is planned for a follow-up PR — currently no runtime code reads this field.
option_defaultsmap[string]stringOptionDefaults overrides the Default value in OptionsSchema entries without redefining the schema itself. Keys are option keys (e.g., "permission_mode"), values are choice values (e.g., "unrestricted"). city.toml users set this to customize provider behavior without touching Args or OptionsSchema.
options_schema[]ProviderOptionOptionsSchema declares the configurable options this provider supports. Each option maps to CLI args via its Choices[].FlagArgs field. Serialized via a dedicated DTO (not directly to JSON) so FlagArgs stays server-side.
upstream_envUpstreamEnvBindingUpstreamEnv is this harness's serving-env contract (Phase C — the Upstream axis): the env-var NAMES this CLI reads for the model-serving base URL and credential. It lets the resolver render an abstract [upstreams.<name>] onto the right names for this harness, so an upstream preset is portable across harnesses (claude → ANTHROPIC_, codex → OPENAI_).
print_args[]stringPrintArgs are CLI arguments that enable one-shot non-interactive mode. The provider prints its response to stdout and exits. When empty, the provider does not support one-shot invocation. Examples: ["-p"] (claude, gemini), ["exec"] (codex), ["--quiet", "--prompt"] (kimi)
title_modelstringTitleModel is the OptionsSchema model key used for title generation. Resolved via the "model" option in OptionsSchema to get FlagArgs. Defaults to the cheapest/fastest model for each provider. Examples: "haiku" (claude), "o4-mini" (codex), "gemini-2.5-flash" (gemini)
acp_commandstringACPCommand overrides Command when the session transport is ACP. When empty, Command is used for both tmux and ACP transports.
acp_args[]stringACPArgs overrides Args when the session transport is ACP. When nil, Args is used for both tmux and ACP transports.

Rig

Rig defines an external project registered in the city.

FieldTypeRequiredDefaultDescription
namestringyesName is the unique identifier for this rig.
pathstringPath is the absolute filesystem path to the rig's repository.
prefixstringPrefix overrides the auto-derived bead ID prefix for this rig.
default_branchstringDefaultBranch is the rig repository's mainline branch (e.g. "main", "master", "develop"). When set, routing formulas use this as the default merge target instead of probing origin/HEAD at sling time. Captured by gc rig add from the rig's git config; set manually for rigs whose mainline isn't reachable via origin/HEAD.
suspendedbooleanSuspended is the deprecated pre-runtime-state suspension flag. Parsed for backwards compatibility and treated as an alias for SuspendedOnStart by [Rig.EffectiveSuspendedOnStart], so existing cities with suspended = true continue to start their rigs suspended after upgrade. Live suspend/resume commands no longer write this field. gc doctor flags it and offers --fix to rename to suspended_on_start.
suspended_on_startbooleanSuspendedOnStart is the rig's desired suspension state at city start. When true and no explicit entry exists for this rig in .gc/runtime/suspension-state.json, the rig is treated as suspended. Once the user has explicitly suspended or resumed the rig via gc rig suspend/resume, the runtime state wins.
formulas_dirstringFormulasDir is a rig-local formula directory — the highest-priority formula layer, above city pack formulas, the city formulas/ directory, and rig pack formulas. Overrides pack formulas for this rig by filename. Relative paths resolve against the city directory.
includes[]stringIncludes lists pack directories or URLs for this rig (V1 mechanism). Each entry is a local path, a git source//sub#ref URL, or a GitHub tree URL.
importsmap[string]ImportImports defines named pack imports for this rig (V2 mechanism). Each key is a binding name; agents from these imports get qualified names like "rigName/bindingName.agentName".
max_active_sessionsintegerMaxActiveSessions is the rig-level cap on total concurrent sessions across all agents in this rig. Nil means inherit from workspace (or unlimited).
overrides[]AgentOverrideOverrides are per-agent patches applied after pack expansion. V2 renames this to "patches" for consistency with [[patches.agent]]. Both TOML keys are accepted during migration.
patches[]AgentOverridePatches is the V2 name for rig-level agent overrides. Takes precedence over Overrides if both are set.
default_sling_targetstringDefaultSlingTarget is the agent qualified name used when gc sling is invoked with only a bead ID (no explicit target). Resolved via resolveAgentIdentity. Example: "rig/polecat"
default_sling_targets[]stringDefaultSlingTargets is the plural form of DefaultSlingTarget. When set, targetless gc sling picks one entry at random each dispatch. Takes precedence over DefaultSlingTarget when non-empty. Each entry is resolved the same way as DefaultSlingTarget. Example: default_sling_targets = ["rig/polecat-a", "rig/polecat-b"]
session_sleepSessionSleepConfigSessionSleep overrides workspace-level idle sleep defaults for agents in this rig.
dolt_hoststringDoltHost overrides the city-level Dolt host for this rig's beads. Use when the rig's database lives on a different Dolt server (e.g., shared from another city).
dolt_portstringDoltPort overrides the city-level Dolt port for this rig's beads. When set, controller commands (scale_check, work_query) prefix their shell invocations with BEADS_DOLT_SERVER_PORT=<port> so bd connects to the correct server instead of the city-level default.
formula_varsmap[string]stringFormulaVars provides rig-scoped defaults for formula vars. Keys match var names declared in formula [vars.&lt;name&gt;] blocks. Values are used when a formula runs in this rig and the caller did not pass an explicit --var override. Takes precedence over formula-level defaults but loses to --var flags.

RigPatch

RigPatch modifies an existing rig identified by Name.

FieldTypeRequiredDefaultDescription
namestringyesName is the targeting key (required). Must match an existing rig's name.
pathstringPath overrides the rig's filesystem path.
prefixstringPrefix overrides the bead ID prefix.
default_branchstringDefaultBranch overrides the rig's recorded mainline branch.
suspendedbooleanSuspended is the deprecated, pre-runtime-state suspension override. Parsed for backwards compatibility; gc doctor surfaces it as a warning and recommends the rename to SuspendedOnStart. No behavioral code path reads it.
suspended_on_startbooleanSuspendedOnStart overrides the rig's desired suspension state at city start. Mirrors Rig.SuspendedOnStart.
formula_varsmap[string]stringFormulaVars adds or overrides rig-scoped formula var defaults. Additive merge: patch keys win over existing rig keys, unspecified keys are preserved.

Service

Service declares a workspace-owned HTTP service mounted under /svc/.

FieldTypeRequiredDefaultDescription
namestringyesName is the unique service identifier within a workspace.
kindstringKind selects how the service is implemented. Enum: workflow, proxy_process
publish_modestringPublishMode declares how the service is intended to be published. v0 supports private services and direct reuse of the API listener. Enum: private, direct
state_rootstringStateRoot overrides the managed service state root. Defaults to .gc/services/{name}. The path must stay within .gc/services/.
publicationServicePublicationConfigPublication declares generic publication intent. The platform decides whether and how that intent becomes a public route.
workflowServiceWorkflowConfigWorkflow configures controller-owned workflow services.
processServiceProcessConfigProcess configures controller-supervised proxy services.

ServiceProcessConfig

ServiceProcessConfig configures a controller-supervised local process that is reverse-proxied under /svc/.

FieldTypeRequiredDefaultDescription
command[]stringCommand is the argv used to start the local service process.
health_pathstringHealthPath, when set, is probed on the local listener before the service is marked ready.

ServicePublicationConfig

ServicePublicationConfig declares platform-neutral publication intent.

FieldTypeRequiredDefaultDescription
visibilitystringVisibility selects whether the service is private to the workspace, available publicly, or gated by tenant auth at the platform edge. Enum: private, public, tenant
hostnamestringHostname overrides the default hostname label derived from service.name.
allow_websocketsbooleanAllowWebSockets permits websocket upgrades on the published route.

ServiceWorkflowConfig

ServiceWorkflowConfig configures controller-owned workflow services.

FieldTypeRequiredDefaultDescription
contractstringContract selects the built-in workflow handler.

SessionConfig

SessionConfig holds session provider settings.

FieldTypeRequiredDefaultDescription
providerstringProvider selects the session backend: "fake", "fail", "subprocess", "acp", "exec:<script>", "k8s", or "" (default: tmux).
k8sK8sConfigK8s holds Kubernetes-specific settings for the native K8s provider.
acpACPSessionConfigACP holds settings for the ACP (Agent Client Protocol) session provider.
setup_timeoutstring10sSetupTimeout is the per-command/script timeout for session setup and pre_start commands. Duration string (e.g., "10s", "30s"). Defaults to "10s".
setup_max_timeoutstringSetupMaxTimeout enables an activity-aware budget for session setup and pre_start commands. When set (e.g. "10m"), a setup command is no longer killed after setup_timeout of wall clock; instead setup_timeout bounds how long it may run without producing output (idle budget) and setup_max_timeout bounds its total runtime regardless of output (the runaway ceiling). A slow but healthy command — a large worktree checkout streaming progress — survives, while a hung one still dies after setup_timeout of silence. Duration string. Empty (the default) keeps the fixed setup_timeout deadline.
nudge_ready_timeoutstring10sNudgeReadyTimeout is how long to wait for the agent to be ready before sending nudge text. Duration string. Defaults to "10s".
nudge_retry_intervalstring500msNudgeRetryInterval is the retry interval between nudge readiness polls. Duration string. Defaults to "500ms".
nudge_poll_intervalstring2sNudgePollInterval is the cycle interval for the per-session nudge poller sidecar (gc nudge poll). Each cycle observes the session and checks the queued-nudge state, so on hosts running many sessions a longer interval trades nudge-delivery latency for less standing load. Duration string. Unset means the poller's built-in default (2s).
nudge_lock_timeoutstring30sNudgeLockTimeout is how long to wait to acquire the per-session nudge lock. Duration string. Defaults to "30s".
debounce_msinteger500DebounceMs is the default debounce interval in milliseconds for send-keys. Defaults to 500.
display_msinteger5000DisplayMs is the default display duration in milliseconds for status messages. Defaults to 5000.
startup_timeoutstring60sStartupTimeout is how long to wait for each agent's Start() call before treating it as failed. Duration string (e.g., "60s", "2m"). Defaults to "60s".
progress_stall_timeoutstringProgressStallTimeout, when set, enables progress-aware session recycling: a desired, alive, claim-less session on a healthy provider whose last provider-reported activity is older than this duration is restarted fresh. Such a session has likely parked (e.g. its turn ended on a provider auth error) and will not self-recover. Set this above the longest legitimate alive-idle period for the city; values below 5m are clamped to 5m. Duration string (e.g. "30m"). Unset/zero disables it.
claim_holder_stall_timeoutstringClaimHolderStallTimeout, when set, enables progress-aware recycling of a desired, alive session that holds in-progress work but has stopped making progress. Because recycling a claim-holder interrupts work, set this above the longest legitimate quiet period. Values below 5m are clamped to 5m. Duration string (e.g. "20m"). Unset/zero disables it.
socketstringSocket specifies the tmux socket name for per-city isolation. When set, all tmux commands use "tmux -L <socket>" to connect to a dedicated server. When empty, defaults to the city name (workspace.name) — giving every city its own tmux server automatically. Set explicitly to override.
remote_matchstringRemoteMatch is a substring pattern for the hybrid provider to route sessions to the remote (K8s) backend. Sessions whose names contain this pattern go to K8s; all others stay local (tmux). Overridden by the GC_HYBRID_REMOTE_MATCH env var if set.

SessionSleepConfig

SessionSleepConfig configures default idle sleep policies by session class.

FieldTypeRequiredDefaultDescription
interactive_resumestringInteractiveResume applies to attachable sessions using wake_mode=resume. Accepts a duration string or "off".
interactive_freshstringInteractiveFresh applies to attachable sessions using wake_mode=fresh. Accepts a duration string or "off".
noninteractivestringNonInteractive applies to sessions with attach=false. Accepts a duration string or "off".

StorageBindingConfig

StorageBindingConfig selects one compiled storage provider and its typed, secret-free configuration; the SQLite provider accepts path (default .gc/store), while every other provider accepts an opaque config_ref that provider resolves.

FieldTypeRequiredDefaultDescription
providerstringyesProvider is the exact ID of a provider compiled into this gc binary.
pathstring.gc/storePath is the SQLite binding root, relative to the city unless absolute. Empty defaults to ".gc/store".
config_refstringConfigRef is an opaque, secret-free reference resolved by the provider that owns the binding, within the city that declares it.
urlstringURL is the http or https endpoint a remote beads workspace is served from, for a binding whose workspace backend does not live on this disk. It carries no credentials, query, or fragment; a path prefix is allowed because an edge may mount the service below the root. Empty means the workspace named by config_ref is local, which is the default.
authstringAuth is a reference to the credential for URL, never the credential itself: "gasworks" mints one through the configured credential-provider command, and "env:NAME" reads one from an environment variable.

StorageClasses

StorageClasses is the closed set of semantic storage assignments; when [storage] is authored, all six fields are required after fragment layering, while omission assigns every class to work.

FieldTypeRequiredDefaultDescription
workstringyesWork selects the binding for the shareable work ledger.
graphstringyesGraph selects the binding for formula graph state.
sessionsstringyesSessions selects the binding for session lifecycle and durable waits.
messagingstringyesMessaging selects the binding for mail and external-message state.
ordersstringyesOrders selects the binding for order-run state.
nudgesstringyesNudges selects the binding for the durable nudge queue.

StorageConfig

StorageConfig assigns each semantic storage class to a named binding and defines every nonreserved binding used by those assignments; omitting [storage] keeps every class on the reserved work binding.

FieldTypeRequiredDefaultDescription
classesStorageClassesyesClasses contains the complete class-to-binding assignment.
bindingsmap[string]StorageBindingConfigBindings defines named provider-backed bindings. The reserved work binding is synthesized and must not appear here.

Tier

Tier defines per-token-type rates in USD per 1 million tokens.

FieldTypeRequiredDefaultDescription
prompt_usd_per_1mnumberyes
completion_usd_per_1mnumberyes
cache_read_usd_per_1mnumberyes
cache_creation_usd_per_1mnumberyes

UpstreamEnvBinding

UpstreamEnvBinding is a harness's serving-env contract: the env-var NAMES this CLI reads for the model-serving endpoint and credential.

FieldTypeRequiredDefaultDescription
base_urlstringBaseURL is the env var name the harness reads for the serving base URL.
api_keystringAPIKey is the env var name the harness reads for the API key.
auth_tokenstringAuthToken is the env var name the harness reads for a bearer auth token.

UpstreamSpec

UpstreamSpec is a named model-serving endpoint preset (Phase C — the Upstream axis: WHO serves+resolves the model).

FieldTypeRequiredDefaultDescription
descriptionstringDescription is a human-readable summary shown in tooling.
base_urlstringBaseURL is the abstract serving endpoint, rendered onto the harness's base_url env var name (UpstreamEnvBinding.BaseURL).
api_keystringAPIKey is the abstract credential, rendered onto the harness's api_key env var name. May be a $VAR ref so the secret stays out of config.
auth_tokenstringAuthToken is an abstract bearer-token credential (an alternative to APIKey for harnesses/upstreams that use a token), rendered onto the harness's auth_token env var name.
base_url_envstringBaseURLEnv/APIKeyEnv/AuthTokenEnv override the HARNESS binding's env-var name for the corresponding abstract field. Needed for GATEWAY harnesses — one CLI (e.g. opencode) fronting many upstreams where the credential env var is upstream-dependent (GROQ_API_KEY, CEREBRAS_API_KEY, …), so the HARNESS has no single binding and the UPSTREAM names its own target. Precedence per field: this override > the harness binding > error.
api_key_envstringAPIKeyEnv overrides the harness binding's api_key env-var name for this upstream (see BaseURLEnv for when this is needed).
auth_token_envstringAuthTokenEnv overrides the harness binding's auth_token env-var name for this upstream (see BaseURLEnv).
envmap[string]stringEnv is a harness-specific escape hatch: raw env keys merged AFTER the abstract fields render. Values may use $VAR refs.

UsageConfig

UsageConfig holds usage-fact sink settings.

FieldTypeRequiredDefaultDescription
providerstringProvider selects the usage sink backend: - "discard" / "fake" → drop all facts - "exec:<script>" → user-supplied script (JSON fact per line on stdin) - "" / "local" → durable file-backed JSONL at .gc/usage.jsonl (default)

Webhook

Webhook declares a city- or rig-scoped inbound HTTP receiver mounted under /v0/city//hook/.

FieldTypeRequiredDefaultDescription
namestringyesName is the unique webhook identifier and mount segment.
scopestringScope selects city- or rig-scoped dispatch semantics, mirroring Order.Scope. Empty defaults to city. Enum: city, rig
rigstringRig is the authoritative rig binding for a rig-scoped webhook (Scope=="rig"). It is REQUIRED when scope="rig" and forbidden otherwise: the receiver copies it into the dispatch scope so the sink constrains delivery to this rig (R4), and a rule that names any other rig is refused. Without it a rig-scoped webhook fails closed (it can target no rig). Leave unset for city scope.
publicationServicePublicationConfigPublication declares generic publication intent, reusing the service publication contract. Pack/fragment-contributed public webhooks are capped to tenant unless the city grants them via [webhooks].allow_public.
verifyWebhookVerifyVerify declares the signature verification scheme and its inputs.
rule[]WebhookRuleRules maps verified provider events to dispatch targets.
max_per_minuteintegerMaxPerMinute is an optional per-webhook self-imposed sustained request ceiling for the E8 rate limiter. SECURITY: a [[webhook]] block may be pack-contributed, and a pack must never be able to weaken the operator's flood defense, so this value may only LOWER a webhook's effective limit — it is min-clamped to the operator-owned ceiling and can never raise it (see WebhookPolicyConfig.EffectiveRateLimit). Leave unset to inherit the operator default/override.

WebhookAllowPublic

WebhookAllowPublic is one operator-authored public-exposure grant.

FieldTypeRequiredDefaultDescription
namestringyesName is the webhook name being granted public exposure.
sourcestringyesSource is the pack/fragment provenance the grant is scoped to. Matched against the webhook's stamped SourceDir.
digeststringDigest pins the content digest of the granted webhook's security-relevant fields (see WebhookContentDigest). It is REQUIRED for the grant to honor public exposure: applyWebhookPackGuard recomputes the digest at load and caps the webhook to tenant when the grant has no digest or the digest no longer matches (R3 content-scoped consent), so a content-swap upgrade of a public hook auto-downgrades until the operator re-consents to the new digest. The downgrade warning names the digest to pin.

WebhookJWTPolicy

WebhookJWTPolicy is one operator-owned jwt-jwks trust anchor.

FieldTypeRequiredDefaultDescription
namestringyesName is the webhook this policy applies to (matched against Webhook.Name).
issuerstringyesIssuer is the required "iss" claim, pinned exactly.
audiencestringyesAudience is the required "aud" claim.
jwks_urlstringyesJWKSURL is the https endpoint publishing the signing keys.

WebhookPolicyConfig

WebhookPolicyConfig holds city-level webhook governance authored in the root city.toml under [webhooks].

FieldTypeRequiredDefaultDescription
allow_public[]WebhookAllowPublicAllowPublic lists {name, source} grants that permit a pack/fragment webhook to keep publication.visibility="public". Default-closed: a pack/fragment public webhook with no matching grant is capped to tenant.
jwt_policy[]WebhookJWTPolicyJWTPolicies pins the operator-owned trust anchor for each jwt-jwks webhook, keyed by webhook name. Per security review R1, a jwt-jwks webhook's issuer, audience, and JWKS URL are operator-owned and must come from here (the root city.toml [webhooks] block), never from a pack-authored [webhook.verify] table — otherwise a pack could point the trust root at an attacker-controlled issuer/JWKS. The receiver (E3) reads this, not WebhookVerify.Issuer/etc., when constructing the jwt-jwks verifier.
rate_limitWebhookRateLimitConfigRateLimit holds the operator-owned E8 per-webhook rate-limit governance: the fleet default plus optional per-webhook overrides. Because the whole [webhooks] table is never merged from packs or fragments, a pack cannot touch these values — it can only LOWER its own limit via Webhook.MaxPerMinute (clamped in EffectiveRateLimit). This is the trust boundary for the flood defense: the operator sets the ceiling; packs may only self-restrict below it. A pointer so an absent [webhooks].rate_limit round-trips cleanly (a zero-value nested table is not suppressed by BurntSushi's omitempty); nil means "use the built-in defaults".

WebhookRateLimitConfig

WebhookRateLimitConfig is the operator-owned rate-limit policy authored under the root city.toml [webhooks].rate_limit table.

FieldTypeRequiredDefaultDescription
per_minuteintegerPerMinute is the default sustained request ceiling applied to every webhook that declares no lower self-limit. 0 uses defaultWebhookRateLimitPerMinute.
burstintegerBurst is the token-bucket burst allowance. 0 uses defaultWebhookRateLimitBurst.
override[]WebhookRateLimitOverrideOverrides pins an operator-chosen limit for a specific webhook by name. Operator authority: an override may raise OR lower that webhook's limit — it is the operator, not a pack, declaring it. A pack's own MaxPerMinute can then only clamp further downward, never above the override.

WebhookRateLimitOverride

WebhookRateLimitOverride is one operator-authored per-webhook rate-limit pin.

FieldTypeRequiredDefaultDescription
namestringyes
per_minuteinteger
burstinteger

WebhookRule

WebhookRule maps one verified provider event to a dispatch target.

FieldTypeRequiredDefaultDescription
eventstringyesEvent is the provider event type this rule matches (e.g. pull_request).
matchmap[string]stringMatch is an exact-equality dotted-path predicate over the payload.
orderstringOrder is the target order name for target="order" rules.
rigstringRig optionally scopes the dispatched order to a rig.
targetstringTarget selects the dispatch sink: "order" (default) or "conversation". Enum: order, conversation
argsmap[string]stringArgs maps declared order params to {{payload.path}} projections.

WebhookVerify

WebhookVerify declares how an inbound delivery is authenticated.

FieldTypeRequiredDefaultDescription
schemestringScheme selects the built-in verifier (see knownWebhookSchemes).
secret_envstringSecretEnv names the environment variable holding the HMAC/shared secret.
secret_keystringSecretKey is an optional stable rotation-slot identifier. Empty defaults to SecretEnv.
signature_headerstringSignatureHeader overrides the request header carrying the signature for generic HMAC schemes (e.g. X-Plane-Signature).
event_headerstringEventHeader names the request header carrying the provider event type.
dedup_headerstringDedupHeader names the request header whose value is surfaced as the delivery id on webhook.received events for observability. It does NOT key at-least-once dedup for the signature-only schemes (github-hmac-sha256, hmac-sha256, slack-v0, discord-ed25519): those dedup on a hash of the signed body, because an unsigned or coarse header cannot safely key dedup — a captured valid delivery could be replayed under a fresh header id to re-fire the order. Only jwt-jwks keys dedup directly, on its signed per-delivery-unique "jti". As a consequence two deliveries with byte-identical signed bodies inside the dedup window collapse to one dispatch, so a source that must resend an identical payload has to carry a unique value inside the signed body.
timestamp_headerstringTimestampHeader optionally names a request header carrying a signed timestamp for replay defense.
replay_windowstringReplayWindow bounds the accepted signed-timestamp skew (Go duration).
issuerstringIssuer, JWKSURL, and Audience pin the jwt-jwks trust anchor. Per the security review (R1) these are operator-owned and must be declared in city.toml, never in pack TOML.
jwks_urlstring
audiencestring
bearer_envstringBearerEnv optionally names an env var holding an additional per-source bearer token checked alongside the signature.
allowed_cidrs[]stringAllowedCIDRs optionally restricts accepted source addresses (e.g. the GitHub webhook CIDR allowlist).

Workspace

Workspace holds city-level metadata and optional defaults that apply to all agents unless overridden per-agent.

FieldTypeRequiredDefaultDescription
namestringName is the legacy checked-in city name. Runtime identity now resolves from site binding (.gc/site.toml workspace_name), declared config, and basename precedence instead; gc init writes the machine-local name to site.toml and omits it from city.toml.
prefixstringPrefix overrides the auto-derived HQ bead ID prefix. When empty, the prefix is derived from the city Name via DeriveBeadsPrefix.
providerstringProvider is the default provider name used by agents that don't specify one.
timezonestringTimezone is the city-default IANA time zone (e.g. "America/New_York") in which cron order schedules are evaluated when an order does not set its own tz. Empty means the controller's process-local zone. Invalid names fail order discovery loudly rather than falling back silently.
start_commandstringStartCommand overrides the provider's command for all agents.
suspendedbooleanSuspended is the deprecated pre-runtime-state city suspension flag. Parsed for backwards compatibility and treated as an alias for SuspendedOnStart by [Workspace.EffectiveSuspendedOnStart], so existing cities with suspended = true continue to start suspended after upgrade. Live suspend/resume commands no longer write this field. gc doctor flags it and offers --fix to rename to suspended_on_start.
suspended_on_startbooleanSuspendedOnStart is the city's desired suspension state at start. When true and no explicit entry exists in .gc/runtime/suspension-state.json, the city is treated as suspended. Once the user has explicitly suspended or resumed via gc suspend/resume, the runtime state wins.
max_active_sessionsintegerMaxActiveSessions is the workspace-level cap on total concurrent sessions. Nil means unlimited. Agents and rigs inherit this if they don't set their own.
session_templatestringSessionTemplate is a template string supporting placeholders: {{.City}}, {{.Agent}} (sanitized), {{.Dir}}, {{.Name}}. Controls tmux session naming. Default (empty): "{{.Agent}}" — just the sanitized agent name. Per-city tmux socket isolation makes a city prefix unnecessary.
install_agent_hooks[]stringInstallAgentHooks lists provider names whose hooks should be installed into agent working directories. Agent-level overrides workspace-level (replace, not additive). Supported: "claude", "codex", "gemini", "antigravity", "kiro", "opencode", "mimocode", "groq", "cerebras", "copilot", "cursor", "pi", "omp", "kimi".
global_fragments[]stringGlobalFragments lists named template fragments injected into every agent's rendered prompt. Applied before per-agent InjectFragments. Each name must match a {{ define "name" }} block from a pack's prompts/shared/ directory.
includes[]stringIncludes is the legacy city.toml pack-composition list. Deprecated: use root pack.toml [imports.*] instead. Run gc doctor to inspect; gc doctor --fix handles the safe mechanical rewrites available in this release wave. Each entry is a local path, a git source//sub#ref URL, or a GitHub tree URL.
default_rig_includes[]stringDefaultRigIncludes is the legacy city.toml default-rig pack list. Deprecated: use city.toml [defaults.rig.imports.<binding>] instead. Run gc doctor to inspect; gc doctor --fix handles the safe mechanical rewrites available in this release wave.
envmap[string]stringEnv defines workspace-wide environment variables applied to every managed session. Lowest config-precedence — overridden by provider, agent, and patch env. Use for cross-cutting variables like GC_TARGET_BRANCH that every agent should inherit.