Browse Source

Merge pull request #891 from mhenke/fix/888-content-md-sync

docs: sync CONTEXT.md with new backgroundJobs and council config options
Mike Henke 1 week ago
parent
commit
819e567ad2
2 changed files with 208 additions and 55 deletions
  1. 127 12
      CONTEXT.md
  2. 81 43
      docs/configuration.md

+ 127 - 12
CONTEXT.md

@@ -4,57 +4,155 @@ A glossary of the terms used in this project's domain. Definitions describe what
 
 ## Agents
 
+Core agent roles and classifications:
+
+The agent system defines the fundamental building blocks for AI-powered work delegation. Each agent type serves a specific purpose in the orchestration ecosystem. Agents are the unit of work — the orchestrator delegates bounded tasks to specialists rather than doing everything itself, which keeps prompts short and costs predictable.
+
+**When to use which agent:** Explorer for codebase search, Librarian for external docs, Oracle for architecture/review, Designer for UI/UX, Fixer for implementation, Observer for visual analysis.
+
+**Core agent types:**
+
 - **Agent** — A named LLM role with a defined lane (permissions, tools, prompt); the unit of work delegation in the system.
 - **Orchestrator** — The primary agent. Plans work, delegates to subagents, monitors them, and reconciles their results. One per session; cannot be disabled.
 - **Subagent** — A specialist agent the orchestrator delegates bounded work to.
+
+**Specialist subagents:**
+
 - **Explorer** — Subagent for fast codebase search and pattern matching.
 - **Librarian** — Subagent for external documentation and library research.
 - **Oracle** — Subagent for architecture, debugging strategy, and code review.
 - **Designer** — Subagent for UI/UX design and visual polish.
 - **Fixer** — Subagent for bounded implementation and execution.
-- **Observer** — Subagent for visual/media analysis (images, PDFs, diagrams). Disabled by default.
+- **Observer** — Subagent for visual/media analysis (images, PDFs, diagrams). Disabled by default because it requires a vision-capable model and adds cost; enable it with `"disabled_agents": []` when working with screenshots or diagrams.
+
+**Multi-LLM systems:**
+
 - **Council** — A multi-LLM agent that runs several councillors and synthesizes their views.
 - **Councillor** — A read-only LLM advisor dispatched as a subagent by the orchestrator. Each councillor is registered as `councillor-<name>` from the council preset. Not hidden; visible in the TUI as panes.
+
+**Agent classification and configuration:**
+
 - **Agent mode** — SDK classification of an agent: `primary` (orchestrator), `subagent` (specialist), or `all` (council, both user-facing and delegatable).
 - **Protected agent** — An agent that cannot be disabled (orchestrator).
 - **Custom agent** — A user-defined agent supplied via config, distinct from the built-ins.
-- **ACP agent** — An external agent defined via the Agent Communication Protocol, run through `acp_run`.
+
+**Naming and identification:**
+
 - **Display name** — A user-assignable name shown in @-mentions; may differ from the internal agent name.
 - **Agent alias** — A legacy or alternate name that maps to a built-in agent. Rejected synonyms: `explore` (use `explorer`), `frontend-ui-ux-engineer` (use `designer`).
+- **Agent permission** — A per-agent `permission` field that sets deterministic, tool-level rules (`ask` / `allow` / `deny`, with pattern support) enforced by the OpenCode SDK. Distinct from prompt instructions, which the model can ignore.
 
 ## Council
 
+Council-specific concepts:
+
+The council system enables multi-LLM consensus and collaborative decision-making. Use council when a single model's judgment is insufficient — architectural decisions, code review, or any question where multiple perspectives reduce risk. Each councillor runs as an independent subagent; the orchestrator synthesizes their responses into a consensus rating.
+
+**When to use:** High-stakes decisions, conflicting requirements, or when you need a second opinion on architecture/code. **When not to use:** Simple tasks that a single specialist can handle — council adds latency and cost.
+
 - **Consensus** — The synthesized conclusion of a council run, rated `unanimous`, `majority`, or `split`.
 - **Council preset** — A named lineup of councillor configurations used for a council run. Plugin config uses `preset` for the selected agent-override set; council config uses `default_preset` for the selected councillor lineup — the `default_` prefix disambiguates the active selection from the preset list within the council sub-object.
+- **Council timeouts / execution mode / retries** — No longer config keys. Per-councillor timeout, serial-vs-parallel execution, and empty-response retries are now handled by the orchestrator's council-mode prompt instructions (see `src/agents/council.ts`).
 
 ## Multiplexer & Sessions
 
-- **Multiplexer** — A terminal backend (tmux, zellij, herdr, or kitty) that hosts child agent panes. Set via \`multiplexer.type\`, which also accepts \`auto\` (auto-detect) and \`none\` (disabled).
-- **Multiplexer type** — The selected backend: `auto`, `tmux`, `zellij`, `herdr`, `kitty`, or `none`.
+Terminal and session management:
+
+The multiplexer system manages terminal backends and agent session lifecycle. When enabled, each child agent gets its own terminal pane so you can see and interact with running work in real time. Disabled by default (`multiplexer.type: "none"`) — enable it when you want visibility into parallel work.
+
+**When to use:** Multi-agent work where you want to watch specialists run side-by-side. **When to leave off:** Single-threaded workflows or headless environments. See [Configuration Reference — Multiplexer](docs/configuration.md#multiplexer) for setup.
+
+- **Multiplexer** — A terminal backend (tmux, zellij, herdr, cmux, or kitty) that hosts child agent panes. Set via `multiplexer.type`, which also accepts `auto` (auto-detect) and `none` (disabled).
+- **Multiplexer type** — The selected backend: `auto`, `tmux`, `zellij`, `herdr`, `cmux`, `kitty`, or `none`.
 - **Pane** — A terminal region spawned by the multiplexer to run a child agent session.
 - **Child session** — A background agent session hosted in a multiplexer pane and tracked by the session manager.
 - **Session manager** — Tracks child sessions, spawns and closes multiplexer panes, and reacts to session lifecycle events. Note: `TmuxSessionManager` is a deprecated alias — use `MultiplexerSessionManager`.
-- **Close reason** — Why a pane is closed: `idle` or `deleted`.
+- **Close reason** — Why a pane is closed: `idle` or `deleted`. The cmux backend adds a third value: `cleanup`.
 
 ## Background Jobs
 
+Asynchronous job lifecycle management:
+
+The background job system tracks and manages delegated specialist tasks. Every subagent launch creates a job; the orchestrator references the job board when planning follow-up work. For full configuration options, see [Configuration Reference — Background Job Management](docs/configuration.md#background-job-management) and [Background Orchestration](docs/background-orchestration.md).
+
+**Why this exists:** Without the board, the orchestrator would lose track of parallel work and re-delegate already-running tasks. The board is the single source of truth for "what's running."
+
 - **Background job** — A delegated specialist task that runs asynchronously; tracked until its result is reconciled into the orchestrator's response.
 - **Background Job Board** — The store of background job state and metadata.
 - **Background Job Coordinator** — The layer that owns background-job lifecycle policy and deferred-close state, writing through the board.
+- **Background Job Store** — Interface (`src/utils/background-job-store.ts`) that both `BackgroundJobBoard` and `BackgroundJobCoordinator` implement.
 - **Job state** — A background job's status: `running`, `completed`, `error`, `cancelled`, or `reconciled`. `reconciled` is a distinct post-consumption phase marking that a terminal job's result has been folded into the orchestrator's response; it is not a terminal outcome itself.
 - **Job alias** — A short human-readable identifier for a background job (e.g., `fix-1`, `exp-2`).
 - **Terminal state** — A job state from which no further transition occurs (`completed`, `error`, `cancelled`).
+- **Board snapshot** — A formatted rendering of the Background Job Board injected into the orchestrator's prompt. Retention is bounded by `backgroundJobs.maxRetainedSnapshots` per checkpoint cache epoch.
+- **Checkpoint cache epoch** — A span of turns during which the same set of board snapshots is reused for prompt-cache hits. Adding a snapshot beyond the retention limit starts a new epoch with only the current snapshot, intentionally causing one cache miss.
+- **Board injection strategy** — How the board is written into the prompt: `latest` (strip-and-replace every turn) or `checkpoint-compatible` (append only when the formatted board changes, retaining snapshots per epoch to preserve cache hits).
+- **Incomplete-todo continuation nudge** — A beta opt-in (`backgroundJobs.continueOnIdle`) that lets idle orchestrator sessions with incomplete todos receive one automatic hidden continuation prompt. Off by default.
 
 ## Skills
 
-- **Skill** — A bundled, self-contained workflow or capability shipped with the plugin. Bundled skills: codemap, clonedeps, simplify, deepwork, reflect, worktrees, oh-my-opencode-slim. Note: `loop-engineering` exists on disk but is not registered as a bundled skill.
+Plugin capabilities and workflows:
+
+The skills system provides bundled, self-contained workflows and capabilities for the plugin. Skills are invoked by the orchestrator when it detects a matching task pattern — they encode best practices for specific work types so the model doesn't reinvent the approach each time.
+
+**When to use:** Invoke a skill when starting work that matches its pattern (e.g., `/codemap` for new repo exploration, `/verification-planning` before non-trivial implementation).
+
+- **Skill** — A bundled, self-contained workflow or capability shipped with the plugin. Bundled skills: codemap, clonedeps, simplify, deepwork, reflect, worktrees, oh-my-opencode-slim, verification-planning. Note: `loop-engineering` exists on disk but is not registered as a bundled skill.
+- **Verification-planning** — An orchestrator-only skill for designing project-specific evidence paths before non-trivial implementation.
 
 ## Hooks
 
+OpenCode lifecycle extension points:
+
+The hooks system provides extension points for OpenCode lifecycle events.
+
 - **Hook** — A plugin extension point that reacts to OpenCode lifecycle events (e.g., apply-patch, filter-available-skills, loop-command, session-lifecycle).
 
+## Companion
+
+Desktop visual companion:
+
+The companion provides a visual status overlay showing running and active agents.
+
+- **Companion** — A native desktop mascot that reflects agent activity; launched and tracked by the companion manager.
+
+## Cache Safety
+
+Prompt cache infrastructure and safety:
+
+The cache safety system ensures prompt cache hits and LLM cost optimization. Provider prompt caches are exact byte-prefix matches — any earlier change invalidates the entire suffix. Cache safety enforces stable byte prefixes so repeated orchestrator turns reuse the same cached prompt. See `AGENTS.md` "Prompt Cache Safety" for rules.
+
+**Why this matters:** Without cache hits, every orchestrator turn re-pays the full prefix cost. A 50K-token prefix at $3/M tokens, hit once per turn vs always full, saves ~$0.15/turn at scale.
+
+- **Cache safety** / **prompt cache safety** — Major concept with extensive infrastructure: `cache-safe-injection.ts` for deterministic content injection, `cache-monitor/` for runtime watchdog, `cache-safety.property.test.ts` for prefix-stability properties, `cache-payload.snapshot.test.ts` for golden snapshots, `cache-safety-tripwire.test.ts` for volatile-input pattern bans, and AGENTS.md "Prompt Cache Safety" section. Critical for provider prompt cache hits and LLM cost optimization.
+
+## ACP
+
+Agent Communication Protocol integration:
+
+The ACP system enables external Agent Client Protocol servers as optional OpenCode subagents. Each ACP agent is wrapped in a lightweight local subagent that calls `acp_run`; the external process runs the actual work. See [ACP Agents](docs/acp-agents.md) for setup.
+
+**When to use:** Connecting to external agent CLIs (Claude Code, Gemini, etc.) that speak ACP. **When not to use:** If the work can be done by a built-in specialist — ACP adds subprocess overhead.
+
+- **ACP agent** — An external agent defined via the Agent Communication Protocol, run through `acp_run`.
+- **ACP wrapper agent** — Lightweight local subagent that calls `acp_run` on behalf of the external ACP process. Distinct from the ACP agent itself — the wrapper handles protocol execution while the external agent provides the actual functionality.
+
+## Multiplexer
+
+Advanced multiplexer backend details:
+
+The cmux multiplexer provides advanced session handling with configurable timeouts and cleanup policies.
+
+- **cmux** — Multiplexer backend with idle-session lifecycle management, grace periods, and its own close-reason variant (`cleanup`). Supports advanced session handling with configurable timeouts and cleanup policies.
+
 ## Loop
 
+Auto-iterative execution and verification:
+
+The loop system enables auto-iterative work execution with verification. A loop runs an execute agent, verifies output against success criteria, and repeats until done or escalated. Use it for tasks that have a clear pass/fail check (tests, builds, lint).
+
+**When to use:** Well-defined tasks with objective success criteria (fix a failing test, implement a function with tests). **When not to use:** Open-ended work where "done" is subjective — loops will thrash without a clear signal.
+
 - **Loop** — An auto-iterative run that executes work with an agent, verifies it against success criteria, and repeats until done or escalated.
 - **Loop session** — The state of one loop run (goal, current phase, attempts, history).
 - **Loop phase** — A stage of a loop: `executing`, `verifying`, `done`, `escalated`, or `cancelled`.
@@ -64,26 +162,43 @@ A glossary of the terms used in this project's domain. Definitions describe what
 
 ## Interview
 
+Specification document generation:
+
+The interview system builds persistent specification documents from ideas through question/answer flows. The orchestrator asks structured questions, you answer, and the result is a persistent spec file. See [Interview](docs/interview.md) for the full workflow.
+
+**When to use:** Starting a new project, designing a feature, or capturing requirements before implementation. **When not to use:** Trivial changes or well-defined tasks that don't need upfront design.
+
 - **Interview** — A question/answer flow that builds a persistent specification document from an idea.
 - **Spec block** — A named section within a generated specification document.
 - **Interview dashboard** — The web UI for managing an interview and entering answers.
 
-## Companion
+## Config
 
-- **Companion** — A native desktop mascot that reflects agent activity; launched and tracked by the companion manager.
+Configuration concepts and terminology:
 
-## Config
+The configuration system provides user-facing configuration for the plugin. For the complete configuration reference with all options, defaults, and examples, see [Configuration Reference](docs/configuration.md). Most users only need `preset`, `presets.<name>.<agent>.model`, and maybe `disabled_agents` — the rest is for advanced tuning.
+
+**Layering order:** `~/.config/opencode/oh-my-opencode-slim.jsonc` is the user base; `.opencode/oh-my-opencode-slim.json` (project-local) overrides user config; CLI flags and runtime `/model` commands override config entirely. See [Project-local Customization](docs/project-local-customization.md) for precedence details.
 
 - **Plugin config** — The user-facing configuration loaded from `oh-my-opencode-slim.jsonc`.
 - **Preset** — A named set of per-agent overrides. The same word also names council councillor lineups (see Flagged).
 - **Model entry** — A normalized model reference with an optional variant, used in fallback chains.
-- **Variant** — An optional model qualifier (e.g., a preview build) used in fallback resolution.
+- **Variant** — An optional per-agent model qualifier that sets reasoning effort. Common values are `"low"`, `"medium"`, `"high"`, and `"max"` (provider-specific). Applied via `presets.<name>.<agent>.variant` or `council.presets.<name>.<councillor>.variant`. The string is unvalidated — any value is accepted, but the documented values are the expected ones.
 - **Fallback / failover** — The mechanism that switches models when a call is rate-limited or returns empty.
-- **Disabled agents** — Agents turned off via config; `observer` is disabled by default.
+- **Fallback max retries** — `fallback.maxRetries`: maximum failover attempts before giving up (default `3`).
+- **Runtime override** — `fallback.runtimeOverride`: deprecated, accepted for backward compatibility but no longer affects runtime behavior. Fallback is now always disabled when a user explicitly selects a model via `/model`.
+- **Strip orchestrator model** — `stripOrchestratorModel`: opt-in that preserves a runtime `/model` selection for the orchestrator after subagent dispatch by omitting its configured model from the SDK config. Exception: if the active preset defines `orchestrator.model`, stripping is skipped and the preset's model is used.
+- **Image routing** — `image_routing`: optional top-level setting (`"auto"` or `"direct"`). When omitted, images are intercepted only when Observer is enabled; `"auto"` requires Observer and saves attachments to disk before nudging delegation; `"direct"` always passes images to the orchestrator.
+- **Disabled agents** — Agents turned off globally via the `disabled_agents` config array; `observer` is disabled by default. This is global, not per-preset.
 
 ## Flagged
 
-Terms with genuine but non-blocking collisions or historical drift. Noted for awareness; no change required:
+Known terminology collisions and historical drift:
+
+These terms have genuine but non-blocking collisions or historical drift. Noted for awareness; no change required:
 
 - **"Presets" means two things** — A plugin *preset* is a set of agent overrides; a council *preset* is a lineup of councillor models. Same word, different JSON paths and types; no structural conflict, but easy to confuse.
 - **Config naming convention** — Config keys mix snake_case (`disabled_agents`, `main_pane_size`) with camelCase (`autoUpdate`, `backgroundJobs`) with no documented rule. Historical drift; `disabled_*` keys are uniformly snake_case while the rest is mixed even within sub-objects.
+- **`council.master*` fields removed** — Legacy `council.master*` keys were removed; a deprecation warning is logged this release only if a config contains the exact `council.master` key. Other `master_*` variants (e.g., `council.master_timeout`, `council.master_fallback`) are silently dropped without warning. Do not use them in new configs.
+- **Agent alias vs Display name** — Legacy agent aliases (`explore` → `explorer`, `frontend-ui-ux-engineer` → `designer`) provide backward compatibility at the code level, while `displayName` offers user-facing aliases (`advisor` → `oracle`). Both concepts coexist but serve different purposes.
+- **Closed vs close reason terminology** — Internal `CloseReason` enum uses `idle`/`deleted`/`cleanup` (cmux), while users see simplified "idle"/"deleted" in logs. The cmux-specific `cleanup` reason is invisible to end users.

+ 81 - 43
docs/configuration.md

@@ -114,7 +114,7 @@ Presets can also be switched at runtime without restarting using the `/preset` c
 |-----------|--------|---|-----------------------------|
 | `presets.<name>.<agent>.model` | string | - | Model ID in `provider/model` format |
 | `presets.<name>.<agent>.temperature` | number | - | Temperature (0–2) |
-| `presets.<name>.<agent>.variant` | string | - | Reasoning effort: `"low"`, `"medium"`, `"high"` |
+| `presets.<name>.<agent>.variant` | string | - | Reasoning effort: `"low"`, `"medium"`, `"high"`, or `"max"` (provider-specific) |
 | `presets.<name>.<agent>.displayName` | string | - | Custom user-facing alias for the agent (e.g. `"advisor"` for `oracle`) |
 | `presets.<name>.<agent>.skills` | string[] | - | Skills the agent can use (`"*"`, `"!item"`, explicit list) |
 | `presets.<name>.<agent>.mcps` | string[] | - | MCPs the agent can use (`"*"`, `"!item"`, explicit list) |
@@ -124,54 +124,54 @@ Presets can also be switched at runtime without restarting using the `/preset` c
 | `agents.<customAgent>.orchestratorPrompt` | string | - | Exact `@agent` block injected into the orchestrator prompt; must start with `@<agent-name>` |
 | `agents.<agent>.permission` | object \| string | - | Tool-level permission rules enforced by the SDK. See [Agent Permissions](#agent-permissions) |
 | `agents.<agent>.displayName` | string | - | Custom user-facing alias for the agent in the active config |
-| `acpAgents.<name>.command` | string | - | Command for an external ACP-compatible agent; creates a wrapper subagent named `<name>` |
-| `acpAgents.<name>.args` | string[] | `[]` | Arguments for the ACP agent command |
-| `acpAgents.<name>.env` | object | `{}` | Extra environment variables for the ACP subprocess |
-| `acpAgents.<name>.cwd` | string | session directory | Working directory override for this ACP subprocess; protocol paths should be absolute |
-| `acpAgents.<name>.description` | string | - | Description shown to OpenCode and injected into the orchestrator routing prompt |
-| `acpAgents.<name>.prompt` | string | generated wrapper prompt | Optional full prompt for the lightweight wrapper subagent |
-| `acpAgents.<name>.orchestratorPrompt` | string | generated routing block | Optional exact routing block injected into the orchestrator prompt |
-| `acpAgents.<name>.wrapperModel` | string | fixer default | Cheap OpenCode model used by the wrapper subagent that calls `acp_run` |
-| `acpAgents.<name>.permissionMode` | string | `ask` | How ACP permission requests are handled: `ask`, `allow`, or `reject` |
-| `acpAgents.<name>.timeoutMs` | integer | `0` | Timeout for a single ACP run in milliseconds. `0` disables the timeout so external agents can run indefinitely. Finite values can be up to `2147483647`ms (~24.8 days) |
-| `disabled_agents` | string[] | `["observer"]` | Agent names to disable globally. Set to `[]` to enable Observer; this is global, not per-preset |
+| `acpAgents.<name>.command` | string | - | Command for an external ACP-compatible agent; creates a wrapper subagent named `<name>` See [ACP-connected agents](#acp-connected-agents). |
+| `acpAgents.<name>.args` | string[] | `[]` | Arguments for the ACP agent command See [ACP-connected agents](#acp-connected-agents). |
+| `acpAgents.<name>.env` | object | `{}` | Extra environment variables for the ACP subprocess See [ACP-connected agents](#acp-connected-agents). |
+| `acpAgents.<name>.cwd` | string | session directory | Working directory override for this ACP subprocess; protocol paths should be absolute See [ACP-connected agents](#acp-connected-agents). |
+| `acpAgents.<name>.description` | string | - | Description shown to OpenCode and injected into the orchestrator routing prompt See [ACP-connected agents](#acp-connected-agents). |
+| `acpAgents.<name>.prompt` | string | generated wrapper prompt | Optional full prompt for the lightweight wrapper subagent See [ACP-connected agents](#acp-connected-agents). |
+| `acpAgents.<name>.orchestratorPrompt` | string | generated routing block | Optional exact routing block injected into the orchestrator prompt See [ACP-connected agents](#acp-connected-agents). |
+| `acpAgents.<name>.wrapperModel` | string | orchestrator default | Cheap OpenCode model used by the wrapper subagent that calls `acp_run` See [ACP-connected agents](#acp-connected-agents). |
+| `acpAgents.<name>.permissionMode` | string | `ask` | How ACP permission requests are handled: `ask`, `allow`, or `reject` See [ACP-connected agents](#acp-connected-agents). |
+| `acpAgents.<name>.timeoutMs` | integer | `0` | Timeout for a single ACP run in milliseconds. `0` disables the timeout so external agents can run indefinitely. Finite values can be up to `2147483647`ms (~24.8 days) See [ACP-connected agents](#acp-connected-agents). |
+| `disabled_agents` | string[] | `["observer"]` | Agent names to disable globally. Set to `[]` to enable Observer; this is global, not per-preset See [Custom Agents](#custom-agents). |
 | `image_routing` | `"auto"` \| `"direct"` | omitted (legacy conditional) | Optional. When omitted, images are intercepted only when Observer is enabled, preserving existing behavior. Explicit `"auto"` requires Observer enabled and saves image attachments to disk before nudging delegation to @observer. `"direct"`: always pass images to the orchestrator. |
 | `autoUpdate` | boolean | `true` | Automatically install plugin updates in the background; set to `false` for notification-only mode |
-| `multiplexer.type` | string | `"none"` | Multiplexer mode: `auto`, `tmux`, `zellij`, `herdr`, `cmux`, `kitty`, or `none` |
-| `multiplexer.layout` | string | `"main-vertical"` | Layout preset: `main-vertical`, `main-horizontal`, `tiled`, `even-horizontal`, `even-vertical`. Tmux applies full layouts; Zellij and Herdr map supported layouts to split directions; cmux maintains a right-hand agent column |
-| `multiplexer.main_pane_size` | number | `60` | Main pane size as percentage (20–80) for tmux main layouts; ignored by Zellij, Herdr, and cmux |
-| `multiplexer.zellij_pane_mode` | string | `"agent-tab"` | Zellij pane placement: `agent-tab` creates/reuses a dedicated `opencode-agents` tab; `current-tab` opens subagents as panes in the tab containing the parent OpenCode pane, falling back to the focused tab if the parent pane cannot be resolved |
-| `tmux.enabled` | boolean | `false` | Legacy alias for `multiplexer.type = "tmux"` |
-| `tmux.layout` | string | `"main-vertical"` | Legacy alias for `multiplexer.layout` |
-| `tmux.main_pane_size` | number | `60` | Legacy alias for `multiplexer.main_pane_size` |
-| `backgroundJobs.maxSessionsPerAgent` | integer | `2` | Maximum completed/reconciled reusable child sessions per specialist type in the current orchestrator session (1–10) |
-| `backgroundJobs.readContextMinLines` | integer | `10` | Minimum number of lines read from a file before it appears in reusable background-job context (0–1000) |
-| `backgroundJobs.readContextMaxFiles` | integer | `8` | Maximum number of recent read-context files shown per reusable child session (0–50) |
-| `backgroundJobs.maxRetainedSnapshots` | integer | `20` | Maximum board snapshots retained per checkpoint cache epoch (1–100). Adding a snapshot beyond the limit starts a new epoch with only the current snapshot, intentionally creating one cache miss |
-| `backgroundJobs.strategy` | `"latest"` \| `"checkpoint-compatible"` | `"latest"` | Board injection strategy. `latest` preserves the current strip-and-replace behavior; `checkpoint-compatible` appends only when the formatted board changes and uses `backgroundJobs.maxRetainedSnapshots` per cache epoch. Cache state resets on compaction/session boundaries and is lost on plugin restart |
-| `backgroundJobs.continueOnIdle` | boolean | `false` | **Beta opt-in.** Set `true` to let idle orchestrator sessions with incomplete todos receive one automatic hidden continuation prompt. When omitted or `false`, idle reconciliation and background-job orchestration remain active without automatic continuation prompts. See [Background Orchestration](background-orchestration.md#incomplete-todo-continuation-nudge) |
+| `multiplexer.type` | string | `"none"` | Multiplexer mode: `auto`, `tmux`, `zellij`, `herdr`, `cmux`, `kitty`, or `none` See [Multiplexer Integration](multiplexer-integration.md). |
+| `multiplexer.layout` | string | `"main-vertical"` | Layout preset: `main-vertical`, `main-horizontal`, `tiled`, `even-horizontal`, `even-vertical`. Tmux applies full layouts; Zellij and Herdr map supported layouts to split directions; cmux maintains a right-hand agent column See [Multiplexer Integration](multiplexer-integration.md). |
+| `multiplexer.main_pane_size` | number | `60` | Main pane size as percentage (20–80) for tmux main layouts; ignored by Zellij, Herdr, and cmux See [Multiplexer Integration](multiplexer-integration.md). |
+| `multiplexer.zellij_pane_mode` | string | `"agent-tab"` | Zellij pane placement: `agent-tab` creates/reuses a dedicated `opencode-agents` tab; `current-tab` opens subagents as panes in the tab containing the parent OpenCode pane, falling back to the focused tab if the parent pane cannot be resolved See [Multiplexer Integration](multiplexer-integration.md). |
+| `tmux.enabled` | boolean | `false` | Legacy alias for `multiplexer.type = "tmux"` See [Multiplexer Integration](multiplexer-integration.md). |
+| `tmux.layout` | string | `"main-vertical"` | Legacy alias for `multiplexer.layout` See [Multiplexer Integration](multiplexer-integration.md). |
+| `tmux.main_pane_size` | number | `60` | Legacy alias for `multiplexer.main_pane_size` See [Multiplexer Integration](multiplexer-integration.md). |
+| `backgroundJobs.maxSessionsPerAgent` | integer | `2` | Maximum completed/reconciled reusable child sessions per specialist type in the current orchestrator session (1–10) See [Background Job Management](#background-job-management). |
+| `backgroundJobs.readContextMinLines` | integer | `10` | Minimum number of lines read from a file before it appears in reusable background-job context (0–1000) See [Background Job Management](#background-job-management). |
+| `backgroundJobs.readContextMaxFiles` | integer | `8` | Maximum number of recent read-context files shown per reusable child session (0–50) See [Background Job Management](#background-job-management). |
+| `backgroundJobs.maxRetainedSnapshots` | integer | `20` | Maximum board snapshots retained per checkpoint cache epoch (1–100). Adding a snapshot beyond the limit starts a new epoch with only the current snapshot, intentionally creating one cache miss See [Background Job Management](#background-job-management). |
+| `backgroundJobs.strategy` | `"latest"` \| `"checkpoint-compatible"` | `"latest"` | Board injection strategy. `latest` preserves the current strip-and-replace behavior; `checkpoint-compatible` appends only when the formatted board changes and uses `backgroundJobs.maxRetainedSnapshots` per cache epoch. Cache state resets on compaction/session boundaries and is lost on plugin restart See [Background Job Management](#background-job-management). |
+| `backgroundJobs.continueOnIdle` | boolean | `false` | **Beta opt-in.** Set `true` to let idle orchestrator sessions with incomplete todos receive one automatic hidden continuation prompt. When omitted or `false`, idle reconciliation and background-job orchestration remain active without automatic continuation prompts. See [Background Orchestration](background-orchestration.md#incomplete-todo-continuation-nudge) See [Background Job Management](#background-job-management). |
 | `disabled_mcps` | string[] | `[]` | MCP server IDs to disable globally |
 | `fallback.enabled` | boolean | `true` | Enable model failover on timeout/error |
 | `fallback.timeoutMs` | number | `15000` | Time before aborting and trying next model |
 | `fallback.retryDelayMs` | number | `500` | Delay between retry attempts |
 | `fallback.maxRetries` | number | `3` | Maximum failover attempts before giving up |
-| `fallback.runtimeOverride` | boolean | `true` | Allow per-call model overrides to bypass the fallback chain |
+| `fallback.runtimeOverride` | boolean | `true` | **Deprecated.** No longer used. Fallback is always disabled when a user explicitly selects a model via `/model`. |
 | `fallback.retry_on_empty` | boolean | `true` | Treat silent empty provider responses (0 tokens) as failures and retry. Set `false` to accept empty responses |
-| `council.presets` | object | - | **Required if using council.** Named councillor presets |
-| `council.presets.<name>.<councillor>.model` | string | - | Councillor model |
-| `council.presets.<name>.<councillor>.variant` | string | - | Councillor variant |
-| `council.presets.<name>.<councillor>.prompt` | string | - | Optional role guidance for the councillor |
-| `council.default_preset` | string | `"default"` | Default preset when none is specified |
+| `council.presets` | object | - | **Required if using council.** Named councillor presets See [Council configuration note](#council-configuration-note). |
+| `council.presets.<name>.<councillor>.model` | string | - | Councillor model See [Council configuration note](#council-configuration-note). |
+| `council.presets.<name>.<councillor>.variant` | string | - | Councillor variant See [Council configuration note](#council-configuration-note). |
+| `council.presets.<name>.<councillor>.prompt` | string | - | Optional role guidance for the councillor See [Council configuration note](#council-configuration-note). |
+| `council.default_preset` | string | `"default"` | Default preset when none is specified See [Council configuration note](#council-configuration-note). |
 | — | — | — | *Timeouts, execution mode, and retries are now handled by the orchestrator's council-mode prompt instructions; see `src/agents/council.ts`.* |
-| `interview.maxQuestions` | integer | `2` | Max questions per interview round (1–10) |
-| `interview.outputFolder` | string | `"interview"` | Directory where interview markdown files are written (relative to project root) |
-| `interview.autoOpenBrowser` | boolean | `true` | Automatically open the interview UI in your default browser during interactive runs; suppressed in tests and CI |
-| `interview.port` | integer | `0` | Interview server port (0–65535). `0` = OS-assigned random port (per-session mode). Any value > 0 enables [dashboard mode](interview.md#dashboard-mode) |
-| `interview.dashboard` | boolean | `false` | Enable [dashboard mode](interview.md#dashboard-mode) on the default port (43211). Setting `port` > 0 also enables dashboard mode. If both are set, `port` takes precedence |
-| `companion.enabled` | boolean | `false` | Enable/disable the floating window Rust companion |
-| `companion.binaryPath` | string | - | Optional path to a custom companion binary to launch instead of the default install path |
-| `companion.position` | string | `"bottom-right"` | The initial corner position of the companion window: `bottom-right`, `bottom-left`, `top-right`, or `top-left` |
-| `companion.size` | string | `"medium"` | The default size preset of the companion window: `small` (80px), `medium` (120px), or `large` (160px) |
+| `interview.maxQuestions` | integer | `2` | Max questions per interview round (1–10) See [Interview configuration](interview.md). |
+| `interview.outputFolder` | string | `"interview"` | Directory where interview markdown files are written (relative to project root) See [Interview configuration](interview.md). |
+| `interview.autoOpenBrowser` | boolean | `true` | Automatically open the interview UI in your default browser during interactive runs; suppressed in tests and CI See [Interview configuration](interview.md). |
+| `interview.port` | integer | `0` | Interview server port (0–65535). `0` = OS-assigned random port (per-session mode). Any value > 0 enables [dashboard mode](interview.md#dashboard-mode) See [Interview configuration](interview.md). |
+| `interview.dashboard` | boolean | `false` | Enable [dashboard mode](interview.md#dashboard-mode) on the default port (43211). Setting `port` > 0 also enables dashboard mode. If both are set, `port` takes precedence See [Interview configuration](interview.md). |
+| `companion.enabled` | boolean | `false` | Enable/disable the floating window Rust companion See [Desktop Companion App](#desktop-companion-app). |
+| `companion.binaryPath` | string | - | Optional path to a custom companion binary to launch instead of the default install path See [Desktop Companion App](#desktop-companion-app). |
+| `companion.position` | string | `"bottom-right"` | The initial corner position of the companion window: `bottom-right`, `bottom-left`, `top-right`, or `top-left` See [Desktop Companion App](#desktop-companion-app). |
+| `companion.size` | string | `"medium"` | The default size preset of the companion window: `small` (80px), `medium` (120px), or `large` (160px) See [Desktop Companion App](#desktop-companion-app). |
 
 > **niri note:** `companion-v0.1.3` includes the fixed native companion release.
 > To make it open as a bottom-right overlay, add a niri rule matching its stable
@@ -218,6 +218,9 @@ and troubleshooting.
 }
 ```
 
+> **Tip:** Use ACP to connect local agent CLIs. For example, `ollama` or `llama.cpp`
+> can be exposed as ACP agents by wrapping them in a lightweight ACP adapter.
+
 After restart, the orchestrator can delegate to `@claude-research` or
 `@gemini-acp`. Use safe names matching `^[a-z][a-z0-9_-]*$`; names cannot
 conflict with built-in or custom agents. `permissionMode` controls ACP
@@ -230,8 +233,30 @@ subprocess.
   `presets.<name>.council.model`.
 - The **councillor models** are configured separately under
   `council.presets.<name>.<councillor>.model`.
-- `council.master*` fields have been removed. A deprecation warning is
-  logged this release if a config still contains them.
+- `council.master` (exact key) has been removed; a deprecation warning is
+  logged if a config still contains it. Other `council.master_*` variants
+  (e.g., `council.master_timeout`, `council.master_fallback`) are silently
+  dropped without warning — remove them manually.
+
+```jsonc
+{
+  "council": {
+    "default_preset": "balanced",
+    "presets": {
+      "balanced": {
+        "alpha": {
+          "model": "openai/gpt-5.6-sol",
+          "variant": "high"
+        },
+        "beta": {
+          "model": "anthropic/claude-sonnet-4-5",
+          "variant": "medium"
+        }
+      }
+    }
+  }
+}
+```
 
 ### Manual Update Mode
 
@@ -262,11 +287,17 @@ Background job management is enabled by default and does not need to be present
 in the starter config. Add `backgroundJobs` only if you want to tune how many
 completed/reconciled child-agent sessions are reusable, how much read context is
 shown, how board snapshots are injected, or to opt into beta automatic
-incomplete-todo continuation prompts on idle:
+incomplete-todo continuation prompts on idle. For glossary definitions of
+background-job terms (board snapshot, checkpoint cache epoch, injection
+strategy, etc.), see [CONTEXT.md — Background
+Jobs](../CONTEXT.md#background-jobs).
 
 ```jsonc
 {
   "backgroundJobs": {
+    "maxSessionsPerAgent": 3,
+    "strategy": "checkpoint-compatible",
+    "maxRetainedSnapshots": 10,
     "continueOnIdle": true
   }
 }
@@ -329,6 +360,9 @@ Notes:
 - Custom agents without a `model` are skipped with a warning
 - Disabled custom agents are not registered or injected into the orchestrator prompt
 
+> **Tip:** Keep `orchestratorPrompt` concise — the orchestrator reads it every turn.
+> Include: when to delegate, when NOT to delegate, and the agent's role in one paragraph.
+
 ### Agent Permissions
 
 The `permission` field provides deterministic, tool-level permission restrictions on custom agents, built-in agent overrides, and presets. Unlike prompt instructions ("do not edit files"), these rules are enforced by the OpenCode SDK at the tool-call level.
@@ -418,6 +452,10 @@ When a user supplies `permission` and also uses the `skills` or `mcps` arrays on
 
 Use the `skills`/`mcps` arrays for skill and MCP gating. Use `permission` for everything else (file access, bash, web, task delegation).
 
+### Multiplexer
+
+The multiplexer hosts child agent sessions in terminal panes. See [Multiplexer Integration](multiplexer-integration.md) for backend setup, layout configuration, and troubleshooting.
+
 ### Desktop Companion App
 
 The desktop companion app provides a visual status overlay showing running and active agents. For quick installation instructions, binary paths, config defaults, and release information, see the full **[Desktop Companion Guide](companion.md)**.