Context
The "default agent" concept (default: true on AgentConfig, resolveDefaultAgentId()) silently routes messages to an arbitrary agent when routing fails. This hides configuration errors. See docs/scope/gut-default-agent.md for the full scope.
This is the foundational issue — all other gut-default-agent issues depend on this landing first.
What
- Remove
default?: boolean from AgentConfig type (src/config/types.agents.ts:10)
- Remove
default: z.boolean().optional() from zod schema (src/config/zod-schema.agent-runtime.ts:692)
- Add
resolveSoleAgentId(cfg): string | null — returns agent ID if exactly one agent, null otherwise
- Add
requireSoleAgentId(cfg): string — throws if zero or multiple agents
- Deprecate
resolveDefaultAgentId() as a shim delegating to the new function (temporary, removed once all callers migrate)
Acceptance Criteria
Files
src/config/types.agents.ts
src/config/zod-schema.agent-runtime.ts
src/agents/agent-scope.ts
src/agents/agent-scope.test.ts
src/config/sessions/main-session.ts — inline default-resolution at line 20: agents.find((agent) => agent?.default)?.id (bypasses resolveDefaultAgentId entirely)
src/config/legacy.shared.ts — resolveDefaultAgentIdFromRaw at line 94 reads entry.default === true
src/config/legacy.rules.ts — migration rule at line 112 referencing agents.list[].default
Migration Scope
resolveDefaultAgentId has ~50 production call sites across ~30 files (117 total references including imports, tests, and the definition itself). This issue creates the replacement functions (resolveSoleAgentId, requireSoleAgentId); dependent issues (#1576–#1581) migrate subsets of callers. Remaining callers (~20 files not covered by #1576–#1581) will need a follow-up issue.
Context
The "default agent" concept (
default: trueonAgentConfig,resolveDefaultAgentId()) silently routes messages to an arbitrary agent when routing fails. This hides configuration errors. Seedocs/scope/gut-default-agent.mdfor the full scope.This is the foundational issue — all other gut-default-agent issues depend on this landing first.
What
default?: booleanfromAgentConfigtype (src/config/types.agents.ts:10)default: z.boolean().optional()from zod schema (src/config/zod-schema.agent-runtime.ts:692)resolveSoleAgentId(cfg): string | null— returns agent ID if exactly one agent, null otherwiserequireSoleAgentId(cfg): string— throws if zero or multiple agentsresolveDefaultAgentId()as a shim delegating to the new function (temporary, removed once all callers migrate)Acceptance Criteria
AgentConfig.defaultfield removed from TypeScript type and zod schemaresolveSoleAgentId()returns agent ID for single-agent config (regardless of name)resolveSoleAgentId()returns null for zero or multiple agentsrequireSoleAgentId()throws descriptive error for zero or multiple agentsbuild,test,lint,docs)Files
src/config/types.agents.tssrc/config/zod-schema.agent-runtime.tssrc/agents/agent-scope.tssrc/agents/agent-scope.test.tssrc/config/sessions/main-session.ts— inline default-resolution at line 20:agents.find((agent) => agent?.default)?.id(bypassesresolveDefaultAgentIdentirely)src/config/legacy.shared.ts—resolveDefaultAgentIdFromRawat line 94 readsentry.default === truesrc/config/legacy.rules.ts— migration rule at line 112 referencingagents.list[].defaultMigration Scope
resolveDefaultAgentIdhas ~50 production call sites across ~30 files (117 total references including imports, tests, and the definition itself). This issue creates the replacement functions (resolveSoleAgentId,requireSoleAgentId); dependent issues (#1576–#1581) migrate subsets of callers. Remaining callers (~20 files not covered by #1576–#1581) will need a follow-up issue.