C01 / Control
Configuration reference
Guild Stack settings: one settings.json file, seven-source inheritance, closed-key validation, model tiers, dispatch mode, security, and MCP pins.Page evidence and guidance
Guild Stack behavior resolves from one file: .guild/settings.json. You can run with no config, then add settings when you need to tune rigor, review posture, dispatch backend, model tiering, host roles, indexing, or security gates.
The contract is simple:
| Rule | Meaning |
|---|---|
| One authoring file | .guild/settings.json is the human-authored project config. |
| Seven-source inheritance | Workspace, project, local, rigor, and CLI layers deep-merge into one resolved config. |
| CLI wins | Flags override every file layer. |
| Closed-key validation | Unknown keys are rejected by raw validation; typos do not silently change behavior. |
| Run snapshot freezes behavior | Full lifecycle runs write .guild/runs/run-id/resolved-settings.json; later phases read that snapshot. |
Try it: /guild:config show --sources prints every resolved setting and which layer set it.
/guild:config init
/guild:config show --sources
/guild:config show --render
/guild:config validate
/guild:config validate --effective
/guild:config set <key> <value> --scope workspace|project|local
/guild:config role <host|advisory|adversarial> <host_id|null> --scope workspace|project|local
/guild:config ui <list|get|sources|set>
/guild:config reconcile <check|sync|repair>
/guild:config providers detect
/guild:config update-mcp-hashes --tools <json-file> --scope workspace|project|local
Inheritance Ladder
Control · precedence
map / active Seven sources resolve into one frozen snapshot
- P1Built-indeep merge
- P2Workspacedeep merge
- P3Workspace localdeep merge
- P4Projectdeep merge
- P5Project localdeep merge
- P6Rigordeep merge
- P7CLI flagshighest authority
Resolved terminus: .guild/runs/<run-id>/resolved-settings.json. Later phases read the snapshot, not live settings.
Schema
.guild/settings.json
One authoring file. Seven sources deep-merge into the resolved config; CLI flags always win.
workspace- <workspace>/.guild/settings.json — shared defaults for child projects.
workspace.local- <workspace>/.guild/settings.local.json — machine-local, gitignored.
project- <project>/.guild/settings.json — project-specific behavior.
project.local- <project>/.guild/settings.local.json — machine-local, gitignored.
rigor- quick, standard, or deep expansion — fills unset loop/review keys only.
cli- /guild:<verb> --flag — highest priority.
A full lifecycle run freezes the resolved shape at .guild/runs/<run-id>/resolved-settings.json; later phases read that snapshot, not live settings.
Settings resolve from least to most authoritative:
built-in defaults
< workspace .guild/settings.json
< workspace .guild/settings.local.json (gitignored)
< project .guild/settings.json
< project .guild/settings.local.json (gitignored)
< --rigor profile expansion
< CLI flags
Path map:
| Layer | File or source | Notes |
|---|---|---|
| Built-in | plugin/src/modules/config/workflows/config-defaults.ts | Zero-config behavior. |
| Workspace | workspace/.guild/settings.json | Shared defaults for child projects. |
| Workspace local | workspace/.guild/settings.local.json | Machine-local, gitignored. |
| Project | project/.guild/settings.json | Project-specific behavior. |
| Project local | project/.guild/settings.local.json | Machine-local, gitignored. |
| Rigor profile | quick, standard, or deep expansion | Fills unset loop/review keys only. |
| CLI flags | /guild:verb --flag | Highest priority. |
Deep merge applies to nested blocks. A child project can set defaults.team.size without replacing workspace-level defaults.quality.budget.
Two keys have special inheritance:
| Key | Rule |
|---|---|
workspace.mode | Root detection only; a child project never inherits the workspace root’s classification. |
initiative_default | Inherits workspace to child only when the named initiative has scope: workspace; otherwise the child resolves its own value or null. |
Closed-Key Validation
Closed-key callout: validate raw settings before trusting a new key. Unknown keys fail raw
config validate, and runtime resolution sparse-drops unrecognized keys from the effective config.
Path map:
| Concern | Source |
|---|---|
| Defaults | plugin/src/modules/config/workflows/config-defaults.ts |
| Resolver core | plugin/src/modules/config/workflows/settings-reader.ts |
| Trace wrapper | plugin/src/modules/config/workflows/settings-resolver.ts |
| Validators and scaffold text | plugin/scripts/lib/core/config-cli.ts |
| Command implementation | plugin/scripts/config-cmd.ts |
| Typed schema registry | plugin/scripts/lib/config-schema.ts |
Use the two validation modes differently:
| Command | What it checks |
|---|---|
/guild:config validate | Raw file shape and unknown keys. Use this to catch typos. |
/guild:config validate --effective | The resolved config after inheritance and sparse-drop. Use this to audit the runtime shape. |
Absolute rejections:
| Rejected setting | Why |
|---|---|
| Unknown key or sub-key | A typo must surface. |
defaults.wiki.autopromote: true | Agents emit candidates only; humans promote knowledge. |
defaults.adversarial: "off" during Guild Stack self-build | Self-build keeps adversarial review on. |
Removed defaults.agent_team | v2 uses top-level agent_mode. |
Dispatch And Review Keys
Path map:
| Concern | Source |
|---|---|
| Config surface | docs/v2/config-surfaces.md |
| Dispatch semantics | docs/v2/dispatch-execution.md |
| Host adaptability | docs/v2/host-adversarial-adaptability.md |
| Config module reference | docs/v2/architecture/modules/config.md |
| Dispatch module reference | docs/v2/architecture/modules/dispatch.md |
| Key | Type | Default | Description |
|---|---|---|---|
rigor | "quick" | "standard" | "deep" | "standard" | Expands unset loops, loop_cap, and review values. Explicit settings or flags still win. |
auto_approve | string[] | [] | Soft-gate autonomy: spec, plan, build, qa, all. There is no ops token. Destructive, network, spend, and production-sensitive work still asks. |
review | "local" | "cross" | "off" | "local" | Review posture. Cross-host review is strongest; same-host or skipped review is weaker and recorded. |
host | canonical dispatch-selectable host id or "auto" | "auto" | Dispatch selector for the authoring host. Legacy aliases normalize where supported; typos are rejected. |
initiative_default | string | null | null | Default initiative attachment target, with the workspace-to-child restriction described above. |
agent_mode | "team" | "agent" | "subagent" | "auto" | "auto" | Dispatch backend selector. auto chooses the strongest available rung and records downgrade. |
workspace | { "mode": "auto" | "on" | "off" } | { "mode": "auto" } | Workspace federation detection. Depth is fixed at immediate children. |
loops | string | null | null | Loop scope override: none, spec, plan, implementation, all, or a comma-separated subset. |
loop_cap | integer | 16 | Maximum rounds for L-loop cycles. |
codex_cap | integer | 5 | Maximum rounds for the Codex adversarial review gate. |
record_status_runs | boolean | true | Whether /guild:status writes lightweight run records. |
codex_skip_enforcement | "warn" | "block" | "warn" | How Codex-skip enforcement surfaces at gates. |
statusline | boolean | false | Enables the Guild Stack status-line pane (--statusline flag / statusline-guild.sh). See Status Line. |
Rigor expansion:
rigor | loops | loop_cap | review |
|---|---|---|---|
quick | none | no cap | off |
standard | spec,plan | 16 | local |
deep | all | 16 | cross, with recorded fallback when cross-host review is unavailable |
Agent-Mode Dispatch Ladder
Path map:
| Concern | Source |
|---|---|
| Backend classes | docs/v2/architecture/modules/dispatch.md |
| Run preflight snapshot | docs/v2/architecture/modules/lifecycle.md |
| Host capability manifests | docs/v2/architecture/modules/host-runtime.md |
agent_mode: "auto" resolves at run start and is frozen in resolved-settings.json.
| Priority | Condition | Backend posture |
|---|---|---|
| 1 | $TMUX is set | Team mode in the current session. |
| 2 | tmux is installed | Team mode in a fresh detached session. |
| 3 | Host supports independent or in-process agents | Agent mode. |
| 4 | Fallback path | Subagent path; serial floor is a forward-prep contract, not the normal resolver result. |
Pinning agent_mode: "team" on a host without tmux warns and downgrades; it does not silently pretend team mode ran.
{ "agent_mode": "auto" }
Model Tiers
- cheaproutine, low-risk work
- midmulti-file reasoning
- powerfulhigh ambiguity or risk
- lane scoretask signals
- host model idconfigured mapping
- resolved settingsfrozen evidence
Tier keys stay portable. Exact model ids belong to host configuration.
Path map:
| Concern | Source |
|---|---|
| Tier defaults and value union | plugin/src/modules/config/workflows/tier-model.ts |
| Score thresholds | .guild/settings.json models.thresholds |
| Dispatch tier axis | docs/v2/dispatch-execution.md |
| Cost-tiering detail | /docs/cost-and-tiering |
Tier names are stable routing keys. They are not a fixed provider ladder, and this reference does not hard-code evergreen model ids.
| Key | Type | Default | Description |
|---|---|---|---|
models.enabled | boolean | true | Master switch for model tiering. |
models.tiers | { cheap, mid, powerful } | built-in map | Host-agnostic tier-to-model map. Each host slot may be a string model id, an object with model params, or null. |
models.scoreWeights | Record<string, number> | built-in weights | Auto-score rubric for work type, blast radius, dependencies, security, and prior escalation. |
models.thresholds | { mid: int, powerful: int } | { mid: 1, powerful: 3 } | Score bands: below mid routes cheap, below powerful routes mid, otherwise powerful. |
models.advisorRounds | integer | 2 | Max advisor consults per lane before recording inconclusive. |
models.escalationMarkers | string[] | built-in phrases | Phrases that trigger advisor escalation. |
models.recallBeforeRead | boolean | true | Query project memory before opening broad source files. |
models.recallScoreThreshold | number | 0.4 | Minimum recall score for skipping a full file read. |
models.structuredOutputRequired | boolean | true | Reject non-structured agent returns where the handoff contract requires structure. |
models.shortOutputThreshold | object | {} | Optional O-3 calibration buckets; empty means dormant. |
models.ingestSimilarityGate | number (0-1) | 0.80 | The wiki-ingest BM25 anomaly gate: minimum similarity before an ingested source is treated as a near-duplicate. |
models.knowledge.* | closed-key object | maxDepth 8, maxBranching 12, minTopicImportance 0.4, relMinConf 0.5, maxFiles 3000, maxTokens 1_000_000, batchSize 20 | Knowledge-tier (learn) build knobs: graph traversal depth/branching, topic-importance and relation-confidence floors, and the file/token/batch caps for the deep knowledge pass. Writable via config set. |
Example with placeholder model ids:
{
"models": {
"tiers": {
"cheap": { "claude-code-cli": { "model": "<cheap-model-id>", "effort": "low" } },
"mid": { "claude-code-cli": { "model": "<mid-model-id>", "effort": "medium" } },
"powerful": { "codex-cli": { "model": "<powerful-model-id>", "reasoning": "high" } }
}
}
}
If a host has no model for a tier, leave that host slot null; dispatch should record the degraded or unavailable path instead of inventing parity.
Security And Secrets
Path map:
| Concern | Source |
|---|---|
| Security design | docs/v2/security.md |
| Security module reference | docs/v2/architecture/modules/security.md |
| Config validators | plugin/scripts/lib/core/config-cli.ts |
| Key | Type | Default | Description |
|---|---|---|---|
security.bypass_permissions_policy | "deny" | "audit" | "allow" | "audit" | How Guild Stack-managed runs behave under host bypass-permissions mode. Outside bypass mode, capability-scope violations still ask. |
secrets_policy.env_allowlist | string[] | [] | Env vars allowed into agent context. All others are redacted. |
secrets_policy.redaction_patterns | string[] | [] | Additional regex scrubbers after the built-in scrubber. |
secrets_policy.fail_mode_durable | "closed" | "open" | "closed" | Durable shared artifacts block on scrub failure by default. |
secrets_policy.fail_mode_telemetry | "open" | "closed" | "open" | Local telemetry warns/proceeds by default. |
Example:
{
"security": { "bypass_permissions_policy": "deny" },
"secrets_policy": {
"env_allowlist": ["GITHUB_TOKEN"],
"redaction_patterns": ["sk-[A-Za-z0-9]{32,}"],
"fail_mode_durable": "closed",
"fail_mode_telemetry": "open"
}
}
MCP Description Pinning
Path map:
| Concern | Source |
|---|---|
| MCP trust surface | docs/v2/security.md |
| Config command | /guild:config update-mcp-hashes |
| Key | Type | Default | Description |
|---|---|---|---|
mcp.tool_description_hashes | Record<string, string> | {} | Optional SHA-256 pins over MCP tool descriptions. Drift warns and gates approval when populated. |
No hashes are pinned automatically. Use update-mcp-hashes only after reviewing a description change.
Defaults Block
Path map:
| Concern | Source |
|---|---|
| Defaults source | plugin/src/modules/config/workflows/config-defaults.ts |
| Config schema | plugin/scripts/lib/config-schema.ts |
| Quality phase | /docs/quality-and-operations |
| Project memory | /docs/wiki-pattern |
| Key | Type | Default | Description |
|---|---|---|---|
defaults.auto_learn | boolean | false | Whether /guild:init runs the learn subset at bootstrap unless overridden. |
defaults.adversarial | "on" | "off" | "on" | Default adversarial posture; "off" is rejected for Guild Stack self-build. |
defaults.team.size | integer or null | null | Team size cap. null applies the normal 3-4 rule; values cap at 6 unless overridden. |
defaults.team.always_include | string[] | [] | Specialists always included when valid for the team. |
defaults.review_workflow | "standard" | "cross" | "minimal" | "standard" | Default lane review depth. |
defaults.skill_policy | "standard" | "conservative" | "standard" | Skill usage posture. |
defaults.gates.auto_approve | string[] | [] | Default approval-gate posture. qa is PASS-only; there is no ops token. |
defaults.wiki.share_mode | "team" | "private" | "team" | Wiki sharing posture. Raw traces and payloads stay local regardless. |
defaults.wiki.autopromote | boolean | false | Must stay false; true is rejected. |
defaults.quality.budget.per_class_minutes | integer | 10 | Per-check-class QA budget. |
defaults.quality.budget.total_minutes | integer | 30 | Whole QA phase budget. |
defaults.reporting | "standard" | "quiet" | "verbose" | "standard" | Progress reporting verbosity. |
defaults.capability_manifest_ttl_s | integer > 0 | 3600 | Host capability-manifest freshness TTL in seconds. |
defaults.update.mode | "notify" | "auto" | "off" | "notify" | Update-check behavior. notify prints the SessionStart signal. auto stages the Claude marketplace apply only on the Claude host, effective next session. Wrapper hosts apply with guild-run update; install.sh --update re-renders and reinstalls every receipted host. Development and symlink installs are excluded. off disables the check. |
defaults.update.cadence_hours | integer > 0 | 24 | Machine-level cache TTL for the update probe. The SessionStart path never blocks on the network — it reads ~/.guild/update-check.json and only refreshes in the background when the cache is older than this. |
defaults.allowed_tools | string[] | [] | Project-wide baseline tool allow-list. OR-expands the per-lane capability_scope — a tool matching any baseline rule is permitted even when out of the lane’s scope; empty or absent means no baseline expansion. |
SQLite Index Thresholds
Path map:
| Concern | Source |
|---|---|
| Knowledge contract | docs/v2/knowledge-memory.md |
| State/index module | docs/v2/architecture/modules/state.md |
| Config defaults | plugin/src/modules/config/workflows/config-defaults.ts |
.guild/index.sqlite is a rebuildable cache. These keys decide when it is populated.
| Key | Type | Default | Description |
|---|---|---|---|
defaults.index.enabled | boolean | true | Master switch. false keeps direct parse and avoids index writes. |
defaults.index.kg_node_threshold | integer | 2000 | Populate graph tables past this node count. |
defaults.index.kg_size_threshold_mb | number | 1 | Populate graph tables past this file size. |
defaults.index.links_edge_threshold | integer | 2000 | Populate knowledge-link edge tables past this count. |
defaults.index.runs_threshold | integer | 20 | Populate run provenance projection past this run count. |
defaults.index.wiki_file_threshold | integer | 500 | Populate wiki FTS past this file count. |
Example:
{
"defaults": {
"index": { "enabled": false }
}
}
Cross-Host Routing
Path map:
| Concern | Source |
|---|---|
| Host model | docs/v2/host-adversarial-adaptability.md |
| Dispatch model | docs/v2/dispatch-execution.md |
| Host-runtime module | docs/v2/architecture/modules/host-runtime.md |
| Key | Type | Default | Description |
|---|---|---|---|
defaults.cross_host.enabled | boolean | false | Enables mixed-host routing and teams. The env override GUILD_CROSS_HOST_ENABLED=1 wins when set. |
defaults.cross_host.hosts | Record<string, HostEntry> | {} | SSH endpoint config keyed by host id. Entries allow address, optional port, and optional user only. |
Never put secrets, passwords, private keys, or key paths in a host entry. The validator rejects unknown host-entry keys.
{
"defaults": {
"cross_host": {
"enabled": true,
"hosts": {
"codex-worker-1": {
"address": "192.168.1.50",
"port": 2222,
"user": "guild"
}
}
}
}
}
Minimal Example
{
"agent_mode": "auto",
"rigor": "standard",
"review": "local",
"codex_cap": 5,
"loop_cap": 16,
"models": {
"enabled": true,
"thresholds": { "mid": 1, "powerful": 3 },
"advisorRounds": 2,
"recallScoreThreshold": 0.4,
"importanceGate": 3
},
"security": {
"bypass_permissions_policy": "audit"
},
"defaults": {
"auto_learn": false,
"adversarial": "on",
"wiki": { "share_mode": "team", "autopromote": false },
"index": { "enabled": true },
"cross_host": { "enabled": false, "hosts": {} }
}
}
Migration From v1
The v2 runtime no longer reads .guild/config.yml. Convert with /guild:migrate, then scaffold or reconcile .guild/settings.json.
v1 config.yml key | v2 settings.json key |
|---|---|
loops | loops |
loop_cap | loop_cap |
codex_cap | codex_cap |
codex_review: true | review: "cross" |
auto_approve: spec-and-plan | auto_approve: ["spec", "plan"] |
auto_approve: all | auto_approve: ["all"] |
auto_approve: implementation | auto_approve: ["build"] |
defaults.agent_team | removed; use top-level agent_mode |