Config loader
Source: ./src/config/
The main resolved runtime config is built from these layers:
- Global —
~/.guildhall/config.yaml. Machine-wide defaults and UI preferences. Overridable withGUILDHALL_CONFIG_DIR. - Workspace —
./guildhall.yamlat the workspace root. Coordinators, domains, MCP servers, hooks, models. - Agent settings —
./memory/agent-settings.yaml. Learned overrides such as coordinator addenda, ignore additions, and runtime knobs.
Project-local config is consulted more narrowly for local runtime overrides such as landingBranch and, when needed, a project-specific preferredProvider; it is not the main third layer in the resolved orchestrator config.
Provider credentials are now separate from that merge stack:
~/.guildhall/providers.yamlfor machine-scoped API keys and local-model URLs- provider-owned auth files such as
~/.claude/.credentials.jsonand~/.codex/auth.jsonfor OAuth flows preferredProviderin~/.guildhall/config.yamlfor the machine default- optional
preferredProviderin./.guildhall/config.yamlonly when one project needs an override
Public API
import {
readGlobalConfig, writeGlobalConfig,
readWorkspaceConfig, readProjectConfig,
resolveConfig,
findWorkspace, registerWorkspace, listWorkspaces,
readAgentSettings, writeAgentSettings,
} from 'guildhall/config'
const config = resolveConfig({ workspacePath })resolveConfig() returns a fully validated ResolvedConfig that the orchestrator and service accept. It reads the machine-global default first, lets project-local config override specific fields when present, then merges global defaults, ./guildhall.yaml, and ./memory/agent-settings.yaml.
WorkspaceYamlConfig schema
interface WorkspaceYamlConfig {
name: string
id: string
projectPath: string
models: ModelAssignmentConfig
coordinators: CoordinatorDomain[]
maxRevisions?: number // default 3
bootstrap?: {
commands?: string[]
successGates?: string[]
gates?: {
lint?: string
typecheck?: string
build?: string
test?: string
}
}
hooks?: Record<HookEvent, HookDefinition[]>
mcp?: { servers: Record<string, McpServerConfig> }
ignore?: string[]
tags?: string[]
}See ./guildhall.yaml reference for the user-facing field-by-field breakdown.
Registry
~/.guildhall/registry.yaml lists every registered workspace with its id and path. findWorkspace(id) resolves an id to a concrete WorkspaceYamlConfig.
Validation
All config reads go through Zod schemas (./src/config/schemas.ts). Validation errors include a pointer into the YAML (line + column) so the dashboard can surface them inline.