Config reference

orch.yaml keys, machine-home files, and ORCH_* environment variables.

orch.yaml config reference

Generated by go run ./cmd/orch-docs by reflecting over config.Config populated with config.Defaults(), with doc comments parsed from source (go/ast). 182 keys across 35 top-level sections.

agents#

yaml key type default meaning
agents.default_cmd string ""
agents.default_preset string "" lookup in Cmds when default_cmd empty
agents.timeout_sec int 600 hard cap per agent run; 0 → default
agents.idle_timeout_sec int 0 IdleTimeoutSec kills a headless agent that produced no stdout/stderr for this long — a frozen worker, as opposed to a dead one the reaper sees. 0 = the built-in default (dispatch.DefaultIdleTimeoutSec), negative = off; timeout_sec stays the outer wall-clock bound.
agents.result_grace_sec int 0 ResultGraceSec is how long a stream-json worker may stay silent after its final result event before Orchemax ends it as a clean finish. 0 = 20, negative = off (the idle timeout alone applies).
agents.post_exit_bound_sec int 0 PostExitBoundSec is how long a worker's supervisor may take between the agent's exit and the start of the seal before the session is sealed failed naming the step. 0 = 120.
agents.stall_after_min int 0 StallAfterMin is how long a running worker whose supervisor has no child process may wait before task_wait and orch evidence --wait report it stalled. 0 = 10.
agents.claude_resumes int 0 ClaudeResumes caps how many times a headless claude run that ended its turn with work pending (dirty checkout, "will notify") is resumed in the same worktree (R24 item 141g). 0 = the built-in default (2), negative = off.
agents.no_deadline_notices bool false NoDeadlineNotices turns off the half-way and late deadline notices a headless pi worker gets at its next turn boundary (default: on).
agents.pi_turn_retries int 0 PITurnRetries caps how many times a pi worker's turn that stopped on a transient provider error (dropped connection, 5xx/408/429, cooling) is retried with a continue prompt (R24 item 141c). 0 keeps the default schedule (5 retries), negative disables the mechanism.
agents.cmds map[string]string {} headless overrides only (else DefaultAgentCmds)
agents.interactive map[string]string {} TUI overrides only (else DefaultAgentInteractiveCmds / PATH)
agents.notify map[string]config.AgentNotify {} bus delivery overrides (else DefaultAgentNotifyConfigs)
agents.transport map[string]string null Transport picks how a headless preset is driven: "subprocess" (default — the agents.cmds template, output scraped from the pipe) or "acp" (the agent runs as an Agent Client Protocol server and orch speaks JSON-RPC to it, which is what makes tool calls and permissions visible).
agents.acp map[string]string {} ACP is the invocation that puts a preset into ACP server mode. Defaults cover the CLIs that ship it; a preset with no entry cannot use transport acp.
agents.agent_log *bool nil (unset) interactive disk transcript; default false (workshop .orch/logs only)
agents.gateway_route *bool nil (unset) GatewayRoute: when true (default), dispatch injects gateway URL + virt key for token crush.
agents.auth map[string]string null Auth: credential mode per preset, "account" or "gateway" (see ResolveAgentAuth).
agents.auth_default string "" AuthDefault is the fallback when agents.auth. and CLI --auth/--login are unset. Empty → launch mode decides (interactive = account, headless = gateway). Never a hardcoded agent-name list — BYO CLIs stay agent-agnostic.
agents.route map[string]string null Route: which model config the preset's own CLI reads — "gateway" lets orch hand it an orch-owned config pointed at the local proxy, "native" leaves the CLI its own. Unset resolves per preset (see ResolveAgentRoute).
agents.workers []config.WorkerSlot [] Workers is the Chair's preferred cheap-worker roster (agent + model). Order = preference. Live spawn still respects orch.agents.concurrent. Empty list / omitted key / template placeholders (your-*-here) = off — Chair falls back to its own agent. SaveWithAgentExamples seeds two teaching rows (plan-login vs gateway+model); replace or delete them.
agents.model_ladder string "" ModelLadder is the verdict when a dispatch runs on the top model although a cheaper roster rung of the same agent exists: warn (default) | refuse.
agents.worker_cli string "" WorkerCLI is the lightweight worker CLI the owner picked at setup, one of WorkerCLICandidates(). Choosing is not installing: install stays lazy and opt-in, when a seat actually needs the binary. Empty = never asked.
agents.disable_mouse config.MouseMode "" DisableMouse is off | clicks | all (bool true→all, false→off). Default off: agent keeps its own fullscreen/mouse. clicks/all = Claude-family classic scrollback + DISABLE_MOUSE (OpenCode never gets OPENCODE_DISABLE_MOUSE). ORCH_ENABLE_AGENT_MOUSE=1 → off; ORCH_AGENT_MOUSE=clicks|all|off overrides.
agents.seat_scroll map[string]string null SeatScroll names who owns the wheel for one preset, overriding the catalog: "child" leaves the agent's own fullscreen TUI and mouse alone, "host" gives the scrollback to Orchemax's terminal host and turns the agent's mouse off. A CLI whose TUI fights the host wrapper is fixed here, by name, instead of changing the default for every agent that shares its family.
agents.seat_host *bool nil (unset) SeatHost wraps interactive agents in Orchemax's ConPTY/PTY host with its own scrollback (wheel/PgUp). nil → on for Windows (mouse scroll over chat), off elsewhere; set false for native TUI attach. ORCH_SEAT_HOST=0|1 overrides.

ai#

yaml key type default meaning
ai.mode string stub Mode: off | stub | live. Empty → stub.
ai.ollama.host string "" e.g. http://127.0.0.1:11435 (never :11434 — client apps)
ai.ollama.model string "" e.g. llama3.2
ai.providers []config.ProviderEntry null BYO OpenAI-compat endpoints (OmniRoute-style)
ai.passthrough.anthropic.base_url string ""
ai.passthrough.anthropic.api_key string ""
ai.passthrough.anthropic.api_key_env string ""
ai.budget_tokens_day int64 0 BudgetTokensDay caps gateway spend metering (0 = unlimited). UTC day key.
ai.budget_usd_day float64 0 BudgetUSDDay caps priced gateway spend per UTC day (0 = unlimited), taken before dispatch against rates fetched from the owner's own providers. With no fetched rate for a model the call is refused, never metered at $0.
ai.probe_interval_sec int 0 ProbeIntervalSec refreshes /v1/models from upstream (0 = probe once at gateway start).
ai.model_fallback string "" ModelFallback: rotate (default) answers a named model whose routes all failed from the rest of the rotate chain; strict refuses (R24 item 69).

ask#

yaml key type default meaning
ask.escalate_after_sec int 0 EscalateAfterSec is how long an ask may sit unanswered before orch fires the needs_answer event at whatever notify sinks are configured. Stays well under the ask timeout so the human still has time to reply. 0 = 60 seconds.

backup#

yaml key type default meaning
backup.keep int 0 Keep is how many newest bundles per project survive pruning (default 20); bundles younger than 7 days are kept whatever Keep says.

budget#

yaml key type default meaning
budget.workspace_tokens_per_day int64 0 WorkspaceTokensPerDay caps the whole project's measured tokens per local day (input+output+cache_creation). 0 = unlimited.
budget.seat_tokens_per_day int64 0 SeatTokensPerDay caps one dispatching agent id's tokens per local day. 0 = unlimited.
budget.warn_at float64 0 WarnAt is the fraction of a cap (0-1) that adds a warning note instead of denying. 0 or out of range defaults to 0.8.

bus#

yaml key type default meaning
bus.retain_acked string 24h e.g. 24h
bus.retain_unread string 168h e.g. 168h (7d)
bus.max_acked *int 200 hard cap on acked rows; 0 = unlimited
bus.log_max_bytes *int64 524288 bus.log rotate; 0 = unlimited
bus.notices_retain string 24h *.delivered age
bus.surfaced_retain string 48h hook-surfaced/*.ids age
bus.body_externalize_bytes *int 2048 BodyExternalizeBytes is the body size at which a send stores a ctxstore marker instead of the text (ledger R16 item 6). 0 = never externalize.

chair#

yaml key type default meaning
chair.guidance.entry_chair *bool true
chair.guidance.multiphase_tasks *bool true
chair.guidance.workers_no_fanout *bool true
chair.guidance.bus_only *bool true
chair.guidance.lock_shared *bool true
chair.guidance.disk_memory *bool true
chair.guidance.clarify_before_spawn *bool true

context#

yaml key type default meaning
context.guidance.crush *bool true
context.guidance.externalize *bool true
context.guidance.auto_gateway *bool true
context.guidance.live_zone *bool true only crush/externalize last message (prefix-freeze)
context.guidance.mcp_tools *bool true
context.guidance.protect_tools []string null ProtectTools: tool/function message names that must not be lossy-crushed (Headroom protect-tool-results). Enforced by ctxstore.PrepareTool and gateway prepareMessages against the chat message's tool/function name — a match passes the message through byte-for-byte, uncrushed and un-externalized. Empty → default coding tools list (DefaultProtectTools).
context.guidance.compact_step_bytes *int nil (unset) CompactStepBytes is gateway.compact_step_bytes (item 150j): when a request's content bytes cross the next multiple of this step, every tool result older than the last CompactKeepTurns turns is elided to a stub in one batch — the provider cache breaks once per step instead of every turn. Unset or negative = default 96 KB; 0 = compaction off.
context.guidance.compact_keep_turns *int nil (unset) CompactKeepTurns is gateway.compact_keep_turns: how many recent turns stay byte-intact regardless of size. Unset or negative = default 6; 0 is raised to 1.
context.guidance.defer_tools []string null DeferTools are tool names kept OUT of tools/list and reachable through tools_search instead. Measured on this workshop: the tool catalogue is 98% of what every turn costs (15545 of 15776 bytes), and it is paid again on each one — see orch usage --injected (R17 item 1, R19 item 17). Empty by design. Which tools an agent may stop seeing changes what it can discover, and that is the owner's decision about their own work, not one Orchemax gets to make for them. orch usage --injected --defer <names> prints what a given choice would save before they make it, and --defer-suggest derives the list instead of asking for one: every offered tool the workspace's injected doctrine does not name by name, on the rule that a tool the doctrine names will be reached for by that name. Measured here, 18 of 56 named: 15776 B per turn becomes 7236 B. It prints, never writes.
context.threshold_bytes int 4096 default 4096
context.dir string .orch/context default .orch/context (defaultOrchHomePaths)
context.ttl_minutes int 30 CCR blob TTL; default 30
context.hooks.post_tool bool false
context.hooks.pre_compact bool false

daemon#

yaml key type default meaning
daemon.socket string .orch/orch.sock
daemon.addr string 127.0.0.1:0 TCP listen; empty → 127.0.0.1:0
daemon.reap_interval_sec *int nil (unset) ReapIntervalSec is how often the daemon reaps dead sessions and frees their locks, tasks and checkouts. Unset → 60s; an explicit 0 turns the loop off (pointer like gateway_route: "off" and "unset" are not the same).

db#

yaml key type default meaning
db.path string .orch/orch.db

dispatch#

yaml key type default meaning
dispatch.auto_fix_rounds int 0 AutoFixRounds is how many automatic fix rounds a failed seal gets: a worker-owned failure (failed tests, red-before not shown) re-dispatches once on the same branch on the cheapest roster rung of the same agent family. 0 (default) = off; only 0 and 1 are honoured.

evidence#

yaml key type default meaning
evidence.attach_to_pr *bool nil (unset) AttachToPR: include the bundle summary in a gh-created PR body when worktree_promote is called with pr:true. nil -> true (see AttachToPREnabled) — the bundle summary always lands in the promote message either way, this flag only gates the PR body.

gateway#

yaml key type default meaning
gateway.addr string 127.0.0.1:8788 default 127.0.0.1:8788
gateway.cache.ttl_sec int 0 0 = disabled
gateway.cache.max_entries int 0 0 → 256
gateway.cooldown_wait_ms int 0 CooldownWaitMs caps the delay a request may absorb waiting for a route whose cooldown is about to expire, instead of being refused. 0 = router default (30s), negative = never wait.
gateway.counterfactual_sample int 0 CounterfactualSample asks the provider, on 1 request in N, what the SAME prompt costs uncrushed, so the saving figure is measured instead of estimated (R19 item 13). 0 = off, and off is the default: the probe is a second billed request, and nobody spends money without saying yes.

guard#

yaml key type default meaning
guard.profile string "" Profile: strict (default when unset) | lite | shared | bring | none
guard.dup.mode string "" Mode: block (default, denies the write) | advisory (warn only) | off.
guard.dup.window int 0 Window is the rolling-hash window in tokens (default 40).
guard.dup.min_tokens int 0 MinTokens is the shortest clone worth reporting (default 60).
guard.dup.max_files int 0 MaxFiles caps repo files compared per call (default 5000).
guard.ddl.seeder_globs []string null
guard.ddl.repository_globs []string null
guard.ddl.migration_globs []string null
guard.tracker bool false Tracker opts into the TRACKER.md convention even before the project has written one yet — without it, a fresh workspace with no TRACKER.md gets no "code staged without TRACKER.md" note (item 117; that note otherwise fires only once a TRACKER.md already exists somewhere in the tree).
guard.code_lang_strict bool false CodeLangStrict also flags English inside identifiers (item 130). Off by default: APIs, stdlib names and keywords are English by convention.
guard.private_names []string null PrivateNames are words no versioned file of this workshop may carry; the commit hook, orch guard explain and the seal judge them. Empty = the word rule is off (machine-path shapes are judged regardless).
guard.private_names_exempt []string null PrivateNamesExempt are repo-relative paths allowed to carry them; a path ending in "/" exempts the tree under it.
guard.gate_test_cmd string "" GateTestCmd is the command that proves this repo's OWN gates still work, run at every seal even when the change did not touch them (R17 item 6). A seal already runs the tests of the packages a change touched, so a worker editing a gate is covered. What was not covered is the reverse: a change elsewhere that breaks a gate, where nothing in the touched set notices. Empty falls back to the repo's own internal/guardrails package when it has one, and to nothing when it does not — a workshop with no gate tests is not told it failed to run tests it never wrote.
guard.sandbox_days int 0 SandboxDays is how long the reaper keeps files under a project's .sandbox// before sweeping them. 0 -> 14. Separate from this: at each task's own close, any file THAT task created under its seat matching the temp-name shape (tmp/temp-prefixed, or ending .log/.out/.tmp) is removed right away, whatever SandboxDays says — this setting only bounds how long everything else in the seat survives.
guard.gocache_max_gb int 0 GocacheMaxGB is the size the Go build cache may reach before Orchemax trims it while no worker, seal or land builds. 0 -> 20.
guard.wire string "" Wire is where the hooks of a seat Orchemax launched live: session (default) passes them on that seat's own argv/env, so a bare agent gets nothing from Orchemax; disk writes the project files orch guard wire writes. See GuardWireMode.
guard.merge_preview *bool nil (unset) MergePreview: false turns off the seal's merge preview (R24 item 168a) — the worker's branch merged with the current base tip in a temporary worktree, conflicts and new test breakage named before anyone merges. nil -> on.
guard.merge_preview_tests []string null MergePreviewTests are the integration checks the preview runs beside the touched packages' tests, each " [go test args]" relative to a module root (e.g. "./internal/db -run TestUsageKeysAccountedFor"). Empty -> DefaultMergePreviewTests; a path the repo lacks is skipped.
guard.merge_preview_budget_sec int 0 MergePreviewBudgetSec bounds the whole preview. 0 -> 360.
guard.seal_budget_max_sec int 0 SealBudgetMaxSec is the ceiling on any one seal's (and merge preview's) package-test budget, however many packages or slow a history says. 0 -> 1800.
guard.seal_full_suite string "" SealFullSuite: queue (default) -> a round seal runs the tests the branch added or changed (plus those its brief's Done-means names) and only compiles the rest of each touched package; the train runs whole packages and -race. round -> the seal runs whole touched packages, as before.
guard.seal_shard_above_sec int 0 SealShardAboveSec: orch land runs a package whose recorded p90 is at least this long as several test-binary processes at once. 0 -> 300.
guard.seal_stall_start_sec int 0 SealStallStartSec cuts a land/seal package whose test binary printed nothing this long after it started, reported as "stalled: start". 0 -> 300.
guard.seal_stall_silence_sec int 0 SealStallSilenceSec cuts a running package that printed no test output this long, reported as "stalled: run". 0 -> 600.

harness#

yaml key type default meaning
harness.consent map[string]bool null Consent records a yes/no answer already given for a USER-scope wiring action (a machine-global adapter with no per-workspace form — agy's MCP config today), keyed "_user" (e.g. "agy_user"), so orch setup asks once and remembers the answer instead of re-prompting every run. PROJECT-scope adapters never need this: they default on.

land#

yaml key type default meaning
land.regenerate []string null Regenerate commands run in the train worktree after the merges; whatever they change is committed as one "regenerate" commit.
land.verify []string null Verify commands run in the train worktree after regenerating; one failing stops the landing before main moves.
land.build string "" Build is the command orch land --install runs in the landed checkout.
land.install string "" Install is the path (relative to the checkout) of the binary Build makes.
land.budget_sec int 0 BudgetSec is the time orch land gives the whole-package run; 0 means guard.seal_budget_max_sec (default 1800).
land.fast_wait_min int 0 FastWaitMin is how many minutes queued fast-lane branches wait for company before landing; 0 means 10.
land.ci_workflow string "" CIWorkflow is the remote CI workflow orch land --push reads before landing (gh run list --workflow); empty means the remote CI is not checked.
land.ci_wait_sec int 0 CIWaitSec is how long land waits for a running remote CI; 0 means 600.

learn#

yaml key type default meaning
learn.probation_greens int 0 default 3
learn.probation_harms int 0 default 2
learn.expire_days *int nil (unset) ExpireDays (R24 11a): a lesson not injected for this many days turns dormant; nil -> 60, 0 = never.
learn.propose string "" Propose is off|shadow|on: after a worker-owned failed seal, the cheapest gateway rung proposes a lesson and a deterministic promoter validates it. shadow logs proposals without writing. Empty = off.

memory#

yaml key type default meaning
memory.enabled *bool nil (unset) nil → true
memory.brief_on_dispatch *bool nil (unset) nil → true; inject .orch/MEMORY_BRIEF.md
memory.brief_limit int 8 default 8
memory.horizon_days int 14 brief/inject window; default 14
memory.retention_days map[string]int null type → days; 0/omit = never
memory.okf_dir string .orch/memory/okf default .orch/memory/okf
memory.chair_lessons_max_bytes int 0 ChairLessonsMaxBytes caps the lessons a Chair seat starts with; default 1800.

notify#

yaml key type default meaning
notify.webhooks []config.WebhookCfg null
notify.telegram.bot_token_env string ""
notify.telegram.chat_allowlist []int64 null
notify.telegram.events []string null
notify.slack.webhook_url_env string ""
notify.slack.events []string null
notify.idle_digest_min int 0 IdleDigestMin is how many minutes must pass since the last hook drain for a seat before notify.DrainForHook injects a "while you were away" summary ahead of the unread bus messages. Default 10 (applyDefaults).
notify.chair_idle_min int 0 ChairIdleMin is how many minutes a handoff may wait unread on an idle Chair before its owner is alerted once. Default 10 (applyDefaults).
notify.desktop *bool nil (unset) Desktop raises an OS toast on every event (Windows toast, macOS osascript, Linux notify-send). Unset = on wherever a display exists.
notify.sound string "" Sound is on|off|questions for the toast's audio: a distinct sound per event kind so the ear tells a question from a finish. Empty = on.

parsers#

yaml key type default meaning
parsers config.Parsers null ext → lang; empty → DefaultParsers

paths#

yaml key type default meaning
paths.shared string ""
paths.agents string .orch/agents
paths.worktrees string .orch/agents/worktrees
paths.data string .orch

plan#

yaml key type default meaning
plan.enforce *bool nil (unset) Enforce nil means default true (enforced). ORCH_PLAN_ENFORCE env overrides this at the process level; see plancap.Enforced.

policy#

yaml key type default meaning
policy.mode string "" solo (default) | allowlist
policy.actors []string null allowed actors when mode=allowlist

project#

yaml key type default meaning
project.name string workspace
project.root string .

projects#

yaml key type default meaning
projects []config.ProjectEntry null Projects are registered units inside the workspace (quota counts these).

promote#

yaml key type default meaning
promote.require_approval bool false RequireApproval, when true, makes a completed seal emit needs_approval instead of auto-eligible-to-merge; default false (today's behaviour).

review#

yaml key type default meaning
review.enabled bool false
review.reviewer string "" Reviewer is the preset the review worker runs on. Empty (or equal to the writer's own preset) falls back to the next different headless preset the workspace has configured (agents.cmds).
review.on []string null On lists the triggers a review fires on. Only "write" exists today (a sealed task with changed files); empty defaults to ["write"].
review.block_on_reject bool false BlockOnReject makes worktree_promote (and the Telegram /approve command) refuse a session whose review verdict is request_changes.
review.require_verdict bool false RequireVerdict makes promote refuse any seal, completed included, with no accept verdict recorded for its current head.
review.timeout_sec int 0 TimeoutSec caps the review worker's run. 0 -> 180.

scheduler#

yaml key type default meaning
scheduler.max_load float64 0 MaxLoad queues a dispatch while CPU busy fraction (0-1) is above this. 0 = off.
scheduler.min_free_mem_mb int 0 MinFreeMemMB queues a dispatch while free memory is under this many MB. 0 = off.
scheduler.min_free_commit_mb int 0 MinFreeCommitMB queues a dispatch while commit headroom (RAM + pagefile or swap) is under this many MB. 0 = off.
scheduler.max_loads int 0 MaxLoads is the ceiling of heavy loads at once (mandate 4); the host's free RAM / commit can lower it. 0 = 5.
scheduler.load_mb int 0 LoadMB is the memory one heavy load takes; free RAM (and commit) divided by it bounds the loads. 0 = 2500 once max_loads or load_mb is set.
scheduler.max_wait_sec int 0 MaxWaitSec caps how long a queued dispatch waits before failing with a scheduler timeout. 0 = the dispatch's own timeout (agents.timeout_sec / ORCH_AGENT_TIMEOUT_SEC / --timeout).

server#

yaml key type default meaning
server.url string "" e.g. https://api.example.com
server.token_path string .orch/device.token relative path for device/user token; default data/server.token

shared#

yaml key type default meaning
shared map[string][]string {} Shared maps language → absolute or workspace-relative paths (do not mix langs in one path).

telemetry#

yaml key type default meaning
telemetry.work string "" Work: off | on | auto. Empty → auto (push when server linked). Free/unlinked stays local-only.

ui#

yaml key type default meaning
ui.addr string 127.0.0.1:8790 default 127.0.0.1:8790

verify#

yaml key type default meaning
verify.nightly.start string ""
verify.nightly.end string ""

webhook#

yaml key type default meaning
webhook.secret_env string "" SecretEnv names the env var holding the HMAC signing secret every route's own scheme signs against (custom header for /task, GitHub's X-Hub-Signature-256, Slack's v0 signing string).
webhook.allow []string null Allow lists the enabled routes: task|github|slack. Empty = all three.
webhook.require_approval *bool nil (unset) RequireApproval gates dispatch: nil/true means a request that asks to dispatch without approve:true only creates the task and emits needs_approval; false lets a validly signed request dispatch right away.
webhook.templates map[string]config.WebhookTemplate null Templates map a short name to a reusable task shape so a caller (a GitHub comment, a Slack slash command, an n8n node) can send a name instead of spelling out agent+prompt+project every time.

workspace#

yaml key type default meaning
workspace.name string workspace
workspace.root string .
workspace.primary_languages []string null
workspace.locale string "" Locale is the language Orchemax and the agents ADDRESS THE USER in (en, es, …). It decides nothing about what a file on disk is written in — that is docs_lang, which is what orch guard lang reads. Empty = unset.
workspace.roles []config.RoleRule null Roles maps a path prefix to what that folder is for: code, shared, web, tests, sandbox, deploy, docs, vendor, generated. Gates judge by role instead of guessing from a file extension, which is what lets a .ps1 be correct under tests/ and litter under internal/. Ordered; first match wins, and a declared rule beats every built-in default.
workspace.docs_lang string "" DocsLang is the language this repo's own pages are written in, and the key orch guard lang enforces. Empty = en: everything on disk defaults to English whatever language the user is addressed in (locale). orch setup asks for both.
workspace.code_lang string "" CodeLang is identifiers + user-visible shipping strings (orch guard code-lang). Init default: en. Empty = code-lang gate off.
workspace.comment_lang string "" CommentLang is the preferred language for code comments. Init default: en. Empty = treat as CodeLang, then en.
workspace.address string "" Address is T-V form in chat (any language): informal | formal | vos. Init default: informal. Aliases (any tongue) normalize via NormalizeAddressForm. vos = Rioplatense only (skips orch guard voseo).
workspace.banned_stacks []config.BannedStack null BannedStacks are dependency/import names the owner ruled out, each paired with the line explaining why — quoted verbatim when orch guard banned-stack denies it (anti-LLM-fashion, DEV_PRACTICES.md:65-66, item 19). Empty = the gate says nothing; an old orch.yaml with no key parses to a nil slice, same as today.
workspace.ledger_dir string "" LedgerDir is where this workshop keeps its Chair ledgers, relative to the repo root. Searched before the built-in homes (.workflow/ and every .sandbox/<seat>/workflow/), which keep working. Rooted or climbing paths are ignored: one workshop must not read another's plans (R17 item 5).
workspace.brief_dir string "" BriefDir is the folder of the Chair's dispatch briefs, relative to the workspace root: orch chair next lists open ledger items with no file there.

Referenced types#

Struct shapes that only appear as a map value or slice element above (no single default — it varies per key/index).

config.RoleRule#

field type meaning
path string
role string

config.BannedStack#

field type meaning
name string Name is matched case-insensitively as a whole import/dependency path segment (e.g. "react" matches import x from 'react' and a package.json "react" dependency, not "react-dom").
reason string Reason is the owner's own line, quoted verbatim in the deny message.

config.ProjectEntry#

field type meaning
id string
path string
kind string
lang string Lang is the project's language id (the symbol indexer's ids); empty = detected from its files. User gates with lang run on a match only.
docs string Docs is this project's docs folder (relative to Path), asked once by orch project add / orch init (item 144). Empty = none chosen; the litter guard still treats "docs" as the default hint either way.
keep []string Keep lists path globs (relative to Path, "**" supported) that the litter guard never flags on an existing file, whatever its name shape — for a script or doc you want left alone without renaming it. Empty = none; unset by default, orch init never prompts for it.
tests []config.TestSuite Tests are the suites the seal runs for a non-Go change (item 160a).
land.regenerate []string Regenerate commands run in the train worktree after the merges; whatever they change is committed as one "regenerate" commit.
land.verify []string Verify commands run in the train worktree after regenerating; one failing stops the landing before main moves.
land.build string Build is the command orch land --install runs in the landed checkout.
land.install string Install is the path (relative to the checkout) of the binary Build makes.
land.budget_sec int BudgetSec is the time orch land gives the whole-package run; 0 means guard.seal_budget_max_sec (default 1800).
land.fast_wait_min int FastWaitMin is how many minutes queued fast-lane branches wait for company before landing; 0 means 10.
land.ci_workflow string CIWorkflow is the remote CI workflow orch land --push reads before landing (gh run list --workflow); empty means the remote CI is not checked.
land.ci_wait_sec int CIWaitSec is how long land waits for a running remote CI; 0 means 600.
chair_goal string ChairGoal is the Chair goal file (relative to Path): a new Chair seat of this project opens with its latest section without a seat report.
visibility string Visibility is "public" or "private"; empty = undeclared. Only a public project is judged by the publish guard, at pre-commit, pre-push and the seal; a project with no visibility is never judged, whatever Publish holds.
publish.allow []string Allow is the path globs ("*" within a directory, "**" across them, forward slashes, relative to the project root) a public project may add or modify; a path no glob matches is refused. Empty = nothing is allowed.
publish.deny_text []string DenyText is regexes (Go syntax) that no allowed file's content may match; an invalid regex refuses the push (it never silently skips).
publish.allow_binary []string AllowBinary is the file extensions (".png") a binary in an allowed path may have; a binary (a NUL byte in its first 8 KB) is not readable for deny_text, so any other binary is refused. Empty = no binary passes.

config.TestSuite#

field type meaning
name string
dir string Dir is the suite's folder, relative to the project; empty = tests/.
lang string Lang names the adapter in the seal counters; empty = read from Dir.
match []string Match lists path globs ("**" supported) whose change selects the suite; empty = Dir plus, for Delphi, the units its .dpr names with in '…'.
run string Run is the command; {suite} is Name, {xml} a temp result file.
shell string Shell is pwsh | bash | cmd; empty = pwsh on Windows, bash elsewhere.
parse string Parse is nunit-xml | junit-xml | trx | exit-code; empty = exit-code.
skip string

config.AgentNotify#

field type meaning
mode string http|shell|file|none
method string
url string
body string HTTP body or file contents
headers map[string]string
cmd string shell template
path string file path template
steps []config.AgentNotifyStep http chain; if set, ignores single url/body

config.AgentNotifyStep#

field type meaning
method string
url string
body string
headers map[string]string

config.WorkerSlot#

field type meaning
agent string
model string Model is the default LLM for this slot. Account: vendor id. Gateway: gateway id.
name string
tier string Tier hints humans/Chair and, when Auth is empty, maps to credential mode via AuthFromWorkerTier (account vs gateway).
auth string Auth is optional account|gateway. Wins over Tier when set.
grade string Grade is optional strong|standard|cheap (R24 item 147e): which rung of the roster this row is. Only WorkerForRisk reads it; a row without a grade is never chosen by risk.
role string Role, Strengths and Avoid (R24 item 101) tell the Chair what to staff this slot with: a one-word role plus task tags it is good at and tags to keep off it.
strengths []string
avoid []string

config.ProviderEntry#

field type meaning
name string
base_url string
api_key string optional; prefer api_key_env
api_key_env string e.g. OPENAI_API_KEY
model string
tier string local|free|cheap|paid
priority int lower = tried first
enabled *bool nil → true
prices_url string PricesURL is this provider's own catalogue of rates, used by orch gateway prices refresh. Orchemax names no provider of its own: the endpoints belong to the owner, like the keys. Empty means derive <base>/models from BaseURL, which some catalogues answer with prices and others do not — a catalogue that answers none is refused, never guessed around.

config.WebhookCfg#

field type meaning
url string
events []string sealed|failed|promoted|needs_approval
secret_env string

config.WebhookTemplate#

field type meaning
agent string
prompt string
project string
timeout_sec int

Machine-home files#

Outside any workspace, per user (internal/acctstore.MachineHome: ORCH_HOME, else %LOCALAPPDATA%\Orchemax, else $XDG_CONFIG_HOME/orchemax, else ~/.config/orchemax).

file meaning
ai.yaml user-wide LLM/gateway catalog (config.UserAI); see orch gateway setup
keys.env API key placeholders/ring for gateway providers (config.LookupAPIKey); secrets, never committed
account.json cached non-secret account profile after orch init login (acctstore.Account)
device.token device token path resolved by orch home / server auth (acctstore.FileDevice)

ORCH_* environment variables#

168 found across client/internal (grep for os.Getenv("ORCH_).

var file / symbol meaning
ORCH_ACP_FAKE_ENVDUMP internal/acp/acptest/fake.go serve
ORCH_ACTOR internal/dispatch/dispatch.go prepareSeat machine was denied on their own CLI.
ORCH_ACTOR internal/dispatch/dispatch.go pushRunUsage
ORCH_AGENT internal/cli/cli_bus.go cmdNotifyHook
ORCH_AGENT internal/cli/cli_guard.go recordPrecommitGuardEvents
ORCH_AGENT internal/cli/cli_guard.go recordShellCheckGuard
ORCH_AGENT internal/cli/cli_guard_workercommit.go workerCommitGates
ORCH_AGENT internal/dispatch/ensure_runtime.go EnsureSeatDefaults
ORCH_AGENT internal/dispatch/ensure_runtime.go defaultRuntimeMarkdown
ORCH_AGENT internal/harness/destructive_audit.go AuditDestructive
ORCH_AGENT internal/harness/guard_events.go guardEvents.record
ORCH_AGENT internal/mcp/ask.go Server.callAsk
ORCH_AGENT internal/mcp/savings.go Server.recordSaving
ORCH_AGENT internal/mcp/verify.go Server.callVerifyReport
ORCH_AGENT internal/notify/hook.go DrainForHook
ORCH_AGENT internal/notify/notice_route.go seatFromEnv
ORCH_AGENT_CMD internal/config/config.go Config.ResolveAgentCmd
ORCH_AGENT_CMD internal/config/config.go Config.ResolveInteractiveCmd
ORCH_AGENT_CMD internal/dispatch/ensure_pi.go PreflightPiProvider
ORCH_AGENT_CMD internal/dispatch/ensure_pi.go ensurePiPath
ORCH_AGENT_LOG internal/dispatch/agent_log.go wantAgentLog
ORCH_AGENT_MOUSE internal/dispatch/mouse_env.go resolveMouseMode
ORCH_AGENT_PRESET internal/config/config.go Config.ResolveInteractiveCmd
ORCH_AGENT_PRESET internal/dispatch/dispatch.go prepareSeat
ORCH_AGENT_PRESET internal/mcp/seat.go Server.callSeatTool
ORCH_AGENT_TIMEOUT_SEC internal/dispatch/dispatch.go resolveTimeoutSec
ORCH_AGENT_TRANSPORT internal/config/config.go Config.TransportACP
ORCH_ALLOW_UNLINKED internal/onboard/onboard.go AllowSkipSetup
ORCH_BUDGET_NOTE_FILE internal/sched/budget.go AssertWithinBudget
ORCH_BUS_NO_PUSH internal/bus/messages.go pushOff
ORCH_CLOSE_SYNC internal/dispatch/dispatch.go runState.finish
ORCH_CONFIG internal/cli/cli_existing_workshop.go guardExistingWorkshop
ORCH_CONFIG internal/config/resolve.go EnvConfigClash
ORCH_CONFIG internal/config/resolve.go ResolvePath
ORCH_CONFIG internal/dispatch/ensure_runtime.go EnsureSeatDefaults
ORCH_CONFIG internal/dispatch/ensure_runtime.go defaultRuntimeMarkdown
ORCH_CONFIG internal/dispatch/sealadapters.go sealConsumersFor
ORCH_CONFIG internal/onboard/workspace.go CurrentWorkspace the walk first made workspace name a different workshop (R24 197d).
ORCH_DISABLE_AGENT_MOUSE internal/dispatch/mouse_env.go resolveMouseMode
ORCH_ENABLE_AGENT_MOUSE internal/dispatch/mouse_env.go resolveMouseMode
ORCH_FORCE_COLOR internal/onboard/ansi.go NewPalette
ORCH_GATEWAY_BYPASS internal/dispatch/gateway_route.go shouldRouteGateway
ORCH_GIT_BASE internal/cli/worktree_cmd.go worktreeManager
ORCH_GUARD_CHAIR_WRITES internal/harness/ide.go gateSilla
ORCH_GUARD_TIMING internal/guardrails/timing.go (package)
ORCH_HOME internal/acctstore/machine.go LegacyMachineHome
ORCH_HOME internal/acctstore/machine.go MachineHome
ORCH_HOME internal/acctstore/testhome.go IsolateMachineHomeForTest
ORCH_LAND_HOLDER internal/sched/heavy.go HeavyHeldByEnv
ORCH_LEASE_PUBLIC_KEY internal/serverclient/entitlements.go PinDevLeaseKeysForTest
ORCH_LEDGER_DUP_OK internal/cli/cli_guard.go ledgerDupRefused
ORCH_LEDGER_FORCE internal/dispatch/dispatch.go spawnGate
ORCH_LEDGER_FORCE internal/mcp/spawn.go Server.forceFromArgs
ORCH_LEGACY_SKILLS internal/chair/protocol.go LegacySkillsEnv
ORCH_LESSON_OK internal/cli/cli_guard_lesson_enforce.go lessonEnforceAction
ORCH_LESSON_OK internal/cli/cli_guard_lesson_enforce.go lessonEnforceRefused
ORCH_LESSON_OK internal/harness/ide.go IDEHook
ORCH_MSYS_TMP internal/scratch/msys.go msysTmp
ORCH_NAME internal/dispatch/ensure_runtime.go defaultRuntimeMarkdown
ORCH_NOTIFY_DESKTOP_OFF internal/notify/desktop.go (package) supervisors: testing.Testing() is false inside them.
ORCH_NOTIFY_URL internal/dispatch/dispatch.go prepareSeat
ORCH_NOTIFY_URL internal/notify/notify.go PlanJSONForSession
ORCH_NOTIFY_URL internal/notify/notify.go ResolveNotifyBase
ORCH_NOTIFY_URL internal/notify/notify.go buildVars
ORCH_NO_SPIN internal/cli/spin.go spinEnabled
ORCH_NO_SPIN internal/dispatch/seat_progress.go seatProgressEnabled
ORCH_OLLAMA_HOST internal/gateway/providers.go resolveOllamaHost
ORCH_OLLAMA_MODEL internal/gateway/providers.go resolveOllamaModel
ORCH_OPENCLAUDE_COMPACT_MODEL internal/dispatch/openclaude_settings.go resolveOpenClaudeCompactModelWant
ORCH_PI_PREFIX internal/config/pi.go privatePiPrefixes
ORCH_PI_QUIET_MS internal/dispatch/pi_rpc.go piQuietDwell
ORCH_PI_RETRY_MS internal/dispatch/pi_rpc.go piTurnRetryWait
ORCH_PLAN_ENFORCE internal/dispatch/ensure_runtime.go mcpServerEnv one the dispatch ran under, not the default.
ORCH_PLAN_ENFORCE internal/plancap/plancap.go Enforced
ORCH_PLAN_MODE internal/harness/ide.go planModeDeny
ORCH_PRESENCE_LOCK internal/presence/instance.go instanceLockPath
ORCH_QUIET internal/dispatch/chair_archive_495.go chairStartClose
ORCH_QUIET internal/dispatch/close_background.go runState.handOffClose
ORCH_QUIET internal/dispatch/close_status.go newCloseStatus
ORCH_QUIET internal/dispatch/launch_banner.go launchBannerValues
ORCH_QUIET internal/dispatch/seat_progress.go seatProgressEnabled
ORCH_REQUIRE_LEASE internal/serverclient/entitlements.go Entitlements.RequireStrictLease
ORCH_RESUME_REF internal/agentscan/resume.go ResumeRefFromEnv
ORCH_ROLE internal/cli/cli_bus.go cmdNotifyHook
ORCH_ROLE internal/db/guard_events.go ResolveGuardSession
ORCH_ROLE internal/dispatch/dispatch.go spawnGate
ORCH_ROLE internal/dispatch/ensure_runtime.go EnsureSeatDefaults
ORCH_ROLE internal/dispatch/ensure_runtime.go defaultRuntimeMarkdown
ORCH_ROLE internal/dispatch/liveness.go InLiveSession
ORCH_ROLE internal/guardrails/workerrules.go WorkerRole
ORCH_ROLE internal/harness/ide.go chairSession
ORCH_ROLE internal/mcp/reply.go Server.roleEnv
ORCH_ROLE internal/mcp/server.go Server.isChair
ORCH_ROLE internal/mcp/server.go Server.registerMCPOnlyChair
ORCH_ROLE internal/mcp/spawn.go Server.denyWorkerFanout
ORCH_ROLE internal/notify/hook.go DrainForHook
ORCH_ROLE internal/notify/notice_route.go seatFromEnv
ORCH_ROLE internal/notify/prompt_lessons.go PromptLessonBlock
ORCH_ROLE internal/notify/seat_orient.go MergePromptLessons R24 327b: what the unattended cycle tick moved reaches the next prompt once.
ORCH_ROLE internal/notify/seat_orient.go SeatStartOrientation
ORCH_SANDBOX internal/dispatch/proofplan_seat.go SeatProofDir
ORCH_SCRATCH_ROOT internal/scratch/scratch.go ResolveRoot
ORCH_SCRATCH_STALE_HOURS internal/scratch/scratch.go StaleAfter
ORCH_SEAT_BUS internal/dispatch/seatbus.go CapabilityFor
ORCH_SEAT_HOST internal/config/config.go Agents.SeatHostEnabled
ORCH_SEAT_HOST_CHILD internal/dispatch/dispatch.go wantSeatHostForPreset
ORCH_SESSION internal/bus/messages.go ResolveSender
ORCH_SESSION internal/cli/cli_audit.go cmdAuditStart
ORCH_SESSION internal/cli/cli_bus.go cmdMsg
ORCH_SESSION internal/cli/cli_bus.go cmdNotifyHook
ORCH_SESSION internal/cli/cli_bus.go cmdUsage
ORCH_SESSION internal/cli/cli_cycle.go chairCycleError
ORCH_SESSION internal/cli/cli_guard.go cmdGuardHooks
ORCH_SESSION internal/cli/cli_guard.go commitMsgGate
ORCH_SESSION internal/cli/cli_guard.go recordPrecommitGuardEvents
ORCH_SESSION internal/cli/cli_guard.go sessionAskCount
ORCH_SESSION internal/cli/cli_hook.go cmdHookSessionEnd
ORCH_SESSION internal/cli/cli_hook.go hookSession
ORCH_SESSION internal/cli/cli_nightly.go nightlyLiveSessions
ORCH_SESSION internal/cli/cli_orch.go cmdSession
ORCH_SESSION internal/cli/cli_outside_seat.go noteOutsideSeat
ORCH_SESSION internal/cli/cli_session_hooks.go repairSessionHooks
ORCH_SESSION internal/config/resolve.go EnvConfigClash
ORCH_SESSION internal/config/resolve.go warnEnvConfigOutsideWorkshop
ORCH_SESSION internal/db/guard_events.go ResolveGuardSession
ORCH_SESSION internal/dispatch/dispatch.go denyOrOverride
ORCH_SESSION internal/dispatch/dispatch.go prepareSeat
ORCH_SESSION internal/dispatch/ensure_runtime.go defaultRuntimeMarkdown
ORCH_SESSION internal/dispatch/liveness.go InLiveSession
ORCH_SESSION internal/harness/destructive_audit.go AuditDestructive
ORCH_SESSION internal/harness/ide.go IDEHook
ORCH_SESSION internal/harness/ide.go chairActionNote
ORCH_SESSION internal/harness/ide.go chairSession
ORCH_SESSION internal/harness/ide.go recordCloneAdvisory
ORCH_SESSION internal/mcp/ask.go Server.callAsk
ORCH_SESSION internal/mcp/ask.go Server.callAskAnswer
ORCH_SESSION internal/mcp/reply.go Server.workerSeat
ORCH_SESSION internal/mcp/savings.go Server.recordSaving
ORCH_SESSION internal/mcp/server.go Server.inboxSession
ORCH_SESSION internal/mcp/server.go Server.recordToolCall
ORCH_SESSION internal/mcp/server.go Server.recordToolsOffered
ORCH_SESSION internal/mcp/tools_graph.go Server.caller
ORCH_SESSION internal/mcp/verify.go Server.callVerifyReport
ORCH_SESSION internal/mcp/verify.go Server.callVerifyStatus
ORCH_SESSION internal/notify/hook.go DrainForHook
ORCH_SESSION internal/notify/seat_orient.go recallSessionID
ORCH_SESSION_KEY internal/dispatch/liveness.go InLiveSession
ORCH_SESSION_KEY internal/dispatch/liveness.go sessionKeyProvesIdentity
ORCH_SESSION_NAME internal/dispatch/ensure_runtime.go defaultRuntimeMarkdown
ORCH_SETUP_YES internal/onboard/onboard.go AllowSkipSetup
ORCH_SKIP_GATEWAY_AUTOSTART internal/dispatch/dispatch.go agentEnv
ORCH_SKIP_GATEWAY_AUTOSTART internal/dispatch/ensure_gateway.go EnsureGatewayListening
ORCH_SKIP_GATEWAY_AUTOSTART internal/dispatch/ensure_gateway.go PreflightGatewayAuth alone" opt-out and turns this check off with it.
ORCH_SKIP_GATEWAY_AUTOSTART internal/dispatch/gateway_route.go GatewayRouteEnv
ORCH_SKIP_PI_ENSURE internal/config/pi.go skipPiEnsure
ORCH_STUB_SEAL internal/dispatch/seal_stub_470.go stubSealOn
ORCH_SUPERVISOR_BIN internal/dispatch/supervisor.go supervisorBin
ORCH_SUPERVISOR_DETACH internal/dispatch/supervisor.go WorkerRun
ORCH_SUPERVISOR_DETACH internal/dispatch/supervisor.go runQueued
ORCH_TASK internal/dispatch/ensure_runtime.go defaultRuntimeMarkdown
ORCH_TASK internal/mcp/verify.go Server.callVerifyReport
ORCH_TASK_TOKEN_BUDGET internal/circuit/breaker.go FromEnv
ORCH_TEST_REUSE internal/cli/cli_proofrun.go cmdTest
ORCH_TEST_REUSE internal/cli/cli_proofrun.go workerTestServe
ORCH_TEST_REUSE internal/dispatch/proofplan_audit.go AuditProofPlan
ORCH_TEST_REUSE internal/dispatch/sealreuse.go runSealPkgTestReusing
ORCH_VAR_PROJECT internal/cli/cli_orch.go ledgerCheckStarts
ORCH_WIRE internal/dispatch/ensure_runtime.go EnsureSeatDefaults A session-wired seat carries its guidance on its own argv (R24 1b).

agents.worker_cli candidates#

Source: config.WorkerCLICandidates(). orch init offers every row, in this order, whatever is on PATH; --yes takes the recommended one. Picking is not installing: an npm row installs when a seat first needs it, a you install it row never installs at all. Every capability carries [measured] (this repo / this machine) or [documented] (vendor or registry metadata) — see client/.workflow/WORKER-CLI-EVALUATION.md.

candidate how Orchemax obtains it speaks MCP follow-up turn pros cons recommended
pi Orchemax installs @earendil-works/pi-coding-agent (npm, official current release, when a seat needs it) no [measured] yes, via pi --mode rpc: dispatch feeds inbox rows as follow_up until SEAL. --print answers once and exits [measured] Orchemax already installs it: npm global install of the current release, lazy, opt-in (config.EnsurePi); MIT, no account login — the gateway key is enough no MCP: the seat reaches Orchemax by shelling out to the orch CLI; needs Node >= 22.19; installed tree 414 MiB (measured, du -sm) yes — the only candidate whose follow-up turn is measured here; the others have the flag documented, not proven against the bus
qwen Orchemax installs @qwen-code/[email protected] (npm, pinned, when a seat needs it) yes [documented] qwen --acp hosts its sessions in one process; not measured by us [documented] same npm install shape as pi, only package and version change; reads the three env vars the gateway already exports (measured: dispatch/gateway_route.go default branch); MCP per project in .qwen/settings.json (documented); Apache-2.0, no login follow-up turn not measured here — only the --acp flag is documented; needs Node >= 22.0; 118.9 MiB unpacked per registry metadata (documented, not a du) -
goose you install it: curl -fsSL https://github.com/block/goose/releases/download/stable/download_cli.sh | GOOSE_VERSION=1.52.0 bash yes [documented] goose acp over stdio, goose serve over HTTP; not measured by us [documented] no runtime prerequisite: Rust binary, release zip 76.9 MB in v1.52.0 (documented, release metadata); MCP can travel in the argv (--with-extension), so Orchemax touches no file of yours (documented); Apache-2.0, no login Orchemax cannot install it: GitHub release, not npm, and this repo has no release downloader; needs a gateway env case of its own (OPENAI_HOST + OPENAI_BASE_PATH, documented); follow-up turn not measured here -
opencode Orchemax installs [email protected] (npm, pinned, when a seat needs it) yes [measured] opencode acp is already in config.DefaultAgentACPCmds(); the turn itself not measured by us [documented] Orchemax already wires it: gateway worktree config and MCP injection exist and are dogfooded (measured); MIT; 344 MiB on this machine against pi's 414 MiB (measured, du -sm) the Chair-class CLI, so the lightweight seat means turning features off; follow-up turn from the bus not measured here -