# Henchman v0.2.0 — Multi-Agent Dev Team Orchestration

## Vision

Transform Henchman from a single-agent CLI into a **multi-agent system that simulates a full software development team**. A Tech Lead orchestrator receives user input and delegates to specialist agents — Architect, Coder, Reviewer, Tester, DevOps, Researcher, and Technical Writer — each with scoped tool access, role-specific system prompts, and optionally distinct LLM providers/models.

Agents communicate through a **full event-driven pub/sub EventBus**, enabling both top-down delegation (Tech Lead → specialists) and peer-to-peer collaboration (Coder asks Researcher for docs mid-task). The team composition is **user-configurable** via `settings.yaml` with a battle-tested default preset shipped out of the box.

## Architecture Overview

```
User Input
    │
    ▼
┌──────────────────────────────────────────────────────┐
│  Repl (CLI layer)                                    │
│  - Renders events with agent source attribution      │
│  - /agent and /team commands                         │
│  - Direct agent targeting: /agent coder Fix the bug  │
└──────────────┬───────────────────────────────────────┘
               │
               ▼
┌──────────────────────────────────────────────────────┐
│  Orchestrator                                        │
│  - Owns AgentPool, EventBus, Tech Lead agent         │
│  - Routes user input to Tech Lead by default         │
│  - Intercepts delegate_task tool calls               │
│  - Runs sub-agents, returns results to delegator     │
│  - Supports recursive delegation (max depth 3)       │
│  - Direct targeting via run_direct()                 │
└──────────────┬───────────────────────────────────────┘
               │
    ┌──────────┼──────────┐
    ▼          ▼          ▼
┌────────┐ ┌────────┐ ┌────────┐
│Tech    │ │Coder   │ │Tester  │  ... (7 specialist agents)
│Lead    │ │        │ │        │
│        │ │scoped  │ │scoped  │
│all     │ │tools:  │ │tools:  │
│tools + │ │read,   │ │read,   │
│delegate│ │write,  │ │write,  │
│        │ │edit,   │ │shell,  │
│        │ │shell   │ │edit    │
└───┬────┘ └───┬────┘ └───┬────┘
    │          │          │
    └──────────┼──────────┘
               ▼
┌──────────────────────────────────────────────────────┐
│  EventBus (pub/sub)                                  │
│  - Typed subscriptions by EventType                  │
│  - Agents publish via SendMessageTool                │
│  - Queryable event history log                       │
│  - Thread-safe (anyio.Lock)                          │
└──────────────────────────────────────────────────────┘
```

### Key Design Decisions

| Decision | Choice | Rationale |
|----------|--------|-----------|
| **Agent interaction model** | Orchestrator + pub/sub hybrid | Tech Lead provides structured control; EventBus enables peer collaboration when needed |
| **Agent implementation** | Reuse existing `Agent` class | No subclassing — identity/role come from `AgentIdentity` + system prompt + scoped tools. Keeps the workhorse simple. |
| **Delegation mechanism** | `DelegateTaskTool` (stub) intercepted by Orchestrator | Keeps provider interface unchanged; LLM sees delegation as a normal tool call |
| **Agent instantiation** | Lazy (on first use) | Avoids startup cost when a task only needs 2-3 of 7 agents |
| **Tool scoping** | Copy-based scoped registries | Each agent gets its own `ToolRegistry` with only allowed tools; prevents mutation leaks |
| **Per-agent providers** | Configurable, defaults to shared | Enables cost optimization (cheap model for Researcher, powerful for Architect) |
| **Team configuration** | `settings.yaml` with default preset | Users can customize roles, add/remove agents, or override prompts |
| **Backwards compatibility** | Preserved | Empty `agents:` config falls back to current single-agent behavior |
| **User interaction** | Talk to Tech Lead by default; `/agent <name>` for direct | Low friction for new users; power users can target specific agents |

## Agent Team Roster

### Tech Lead (Orchestrator Agent)

**Role**: Receives all user input, analyzes requirements, creates execution plans, delegates to specialists, synthesizes results, and reports back to the user.

**System Prompt Focus**: Task decomposition, delegation strategy, quality gates, knowing when to involve which specialist. Never does implementation work directly — always delegates.

**Tool Access**: All built-in tools + `delegate_task` + `send_message`

**Can Delegate To**: All agents

---

### Architect

**Role**: Designs solutions, creates technical plans, reviews code for structural/design issues, evaluates trade-offs, and proposes system-level changes.

**System Prompt Focus**: Software architecture patterns, system design, API design, separation of concerns, scalability considerations. Produces design documents and architectural decision records.

**Tool Access**: `read_file`, `ls`, `glob`, `grep`, `web_fetch`, `rag_search`, `send_message`

**Can Delegate To**: Researcher

---

### Coder

**Role**: Implements code changes — new features, bug fixes, refactoring. The primary agent that writes and edits source files.

**System Prompt Focus**: Clean code, TDD practices, language idioms, minimal diffs, test-first mindset. Reads existing code thoroughly before making changes. Follows project conventions.

**Tool Access**: `read_file`, `write_file`, `edit_file`, `ls`, `glob`, `grep`, `shell`, `send_message`

**Can Delegate To**: Researcher

---

### Reviewer

**Role**: Reviews code for bugs, style issues, security vulnerabilities, performance problems, and adherence to project standards. Provides actionable feedback.

**System Prompt Focus**: Code review best practices, common bug patterns, security anti-patterns, performance analysis. Produces structured review comments with severity levels.

**Tool Access**: `read_file`, `ls`, `glob`, `grep`, `rag_search`, `send_message`

**Can Delegate To**: None (terminal agent — produces review output only)

---

### Tester

**Role**: Writes and runs tests, validates changes, ensures coverage requirements are met, and identifies edge cases.

**System Prompt Focus**: Test-driven development, pytest patterns, mocking strategies, edge case identification, coverage analysis. Writes tests before or alongside implementation.

**Tool Access**: `read_file`, `write_file`, `edit_file`, `shell`, `glob`, `grep`, `send_message`

**Can Delegate To**: None

---

### DevOps / CI

**Role**: Runs CI pipelines, checks build status, manages configuration, validates deployment readiness, and handles infrastructure-as-code tasks.

**System Prompt Focus**: CI/CD pipelines, build systems, container orchestration, environment configuration, infrastructure automation. Runs shell commands to check build/test status.

**Tool Access**: `shell`, `read_file`, `glob`, `grep`, `web_fetch`, `write_file`, `edit_file`, `send_message`

**Can Delegate To**: None

---

### Researcher

**Role**: Searches the web, reads documentation, gathers context from codebases, and synthesizes findings into actionable summaries.

**System Prompt Focus**: Information gathering, documentation reading, API exploration, summarization. Produces concise research briefs with sources cited.

**Tool Access**: `web_fetch`, `ddg_search`, `read_file`, `grep`, `rag_search`, `glob`, `send_message`

**Can Delegate To**: None

---

### Technical Writer

**Role**: Writes and updates documentation — READMEs, API docs, inline comments, changelogs, user guides, and architectural decision records.

**System Prompt Focus**: Technical writing clarity, audience awareness, documentation structure, Markdown formatting, docstring conventions, keeping docs in sync with code.

**Tool Access**: `read_file`, `write_file`, `edit_file`, `ls`, `glob`, `grep`, `send_message`

**Can Delegate To**: Researcher

---

## New Source Files

```
src/henchman/
├── agents/                          # NEW PACKAGE
│   ├── __init__.py                  # Exports: AgentIdentity, AgentConfig, AgentPool, Orchestrator
│   ├── config.py                    # AgentConfig Pydantic model
│   ├── identity.py                  # AgentIdentity dataclass
│   ├── pool.py                      # AgentPool — lifecycle, scoped registries, lazy init
│   ├── orchestrator.py              # Orchestrator — delegation engine, event routing
│   ├── presets.py                   # DEFAULT_TEAM preset with all 7 agents
│   └── prompts.py                   # Role-specific system prompt templates
├── core/
│   ├── eventbus.py                  # NEW — EventBus pub/sub system
│   ├── events.py                    # MODIFIED — new EventTypes, source_agent field
│   ├── agent.py                     # MODIFIED — optional AgentIdentity
│   └── session.py                   # MODIFIED — agent_id on SessionMessage
├── tools/
│   └── builtins/
│       ├── delegate.py              # NEW — DelegateTaskTool (stub)
│       └── send_message.py          # NEW — SendMessageTool
├── cli/
│   ├── app.py                       # MODIFIED — --agent flag
│   ├── repl.py                      # MODIFIED — Orchestrator replaces Agent
│   ├── prompts.py                   # MODIFIED — composable prompt parts
│   └── commands/
│       ├── agent.py                 # NEW — /agent command
│       └── team.py                  # NEW — /team command
└── config/
    └── schema.py                    # MODIFIED — agents config block
```

## Detailed Task List

### WP1: Core Infrastructure — Identity and Events

> Foundation types that everything else builds on. Must be done first.

- [x] **1.1** Create `src/henchman/agents/` package with `__init__.py`
- [x] **1.2** Create `src/henchman/agents/identity.py` — `AgentIdentity` dataclass
  - Fields: `id: str`, `name: str`, `role: str`, `description: str`
  - Immutable (frozen dataclass)
  - `__str__` returns `f"{name} ({role})"`
- [x] **1.3** Extend `AgentEvent` in `src/henchman/core/events.py`
  - Add `source_agent: str | None = None` field (backwards-compatible default)
- [x] **1.4** Add new `EventType` values to `src/henchman/core/events.py`
  - `AGENT_DELEGATED` — Tech Lead delegating a task to a specialist
  - `AGENT_STARTED` — Specialist agent beginning work
  - `AGENT_COMPLETED` — Specialist agent finished
  - `AGENT_MESSAGE` — Inter-agent message via EventBus
- [x] **1.5** Extend `Agent.__init__` in `src/henchman/core/agent.py`
  - Add optional `identity: AgentIdentity | None = None` parameter
  - When set, all yielded `AgentEvent`s get `source_agent = identity.id`
  - Existing behavior unchanged when `identity` is `None`
- [x] **1.6** Update `src/henchman/core/__init__.py` exports
- [x] **1.7** Write tests: `tests/agents/test_identity.py`, update `tests/core/test_events.py`
- [x] **1.8** Run `./scripts/ci.sh` — all checks pass

---

### WP2: EventBus — Pub/Sub System

> The nervous system for inter-agent communication.

- [x] **2.1** Create `src/henchman/core/eventbus.py` — `EventBus` class
  - `subscribe(event_type: EventType, handler: Callable) -> str` — returns subscription ID
  - `subscribe_all(handler: Callable) -> str` — subscribe to all events
  - `unsubscribe(subscription_id: str) -> None`
  - `publish(event: AgentEvent) -> None` — async dispatch to all matching handlers
  - `history(event_type: EventType | None, agent_id: str | None, limit: int) -> list[AgentEvent]`
  - `clear_history() -> None`
  - Thread-safe via `anyio.Lock`
  - Bounded history buffer (default 1000 events, configurable)
  - Error isolation — handler exceptions logged, don't break other handlers
- [x] **2.2** Create `src/henchman/tools/builtins/send_message.py` — `SendMessageTool`
  - Parameters: `to_agent: str`, `message: str`, `context: str | None`
  - `ToolKind.READ` (auto-approved)
  - `execute()` publishes `AGENT_MESSAGE` event to EventBus
  - Requires EventBus reference injected at construction
- [x] **2.3** Update `src/henchman/core/__init__.py` to export `EventBus`
- [x] **2.4** Write tests: `tests/core/test_eventbus.py`, `tests/tools/test_send_message.py`
- [x] **2.5** Run `./scripts/ci.sh` — all checks pass

---

### WP3: Agent Configuration and Prompts

> Define what agents look like in config and what they say.

- [x] **3.1** Create `src/henchman/agents/config.py` — `AgentConfig` Pydantic model
  - `name: str` — display name (e.g., "Architect")
  - `role: str` — role identifier (e.g., "architect")
  - `description: str` — one-line description
  - `system_prompt: str | None` — override prompt (None = use default for role)
  - `tools: list[str]` — allowlist of tool names this agent can use
  - `provider: str | None` — override provider (None = use default)
  - `model: str | None` — override model (None = use provider default)
  - `auto_approve: list[str]` — tools to auto-approve for this agent
  - `can_delegate_to: list[str]` — agent roles this one can delegate to
  - `enabled: bool = True` — toggle agents on/off without removing config
  - Validation: `tools` must be non-empty, `can_delegate_to` entries must be valid role names
- [x] **3.2** Refactor `src/henchman/cli/prompts.py` into composable parts
  - Extract `BASE_PROMPT` — tool documentation, constraints, coding standards
  - Extract `TECH_LEAD_PROMPT` — delegation instructions, team awareness
  - Keep `DEFAULT_SYSTEM_PROMPT` intact as `BASE_PROMPT + TECH_LEAD_PROMPT` for backwards compatibility
- [x] **3.3** Create `src/henchman/agents/prompts.py` — role-specific prompt templates
  - `get_agent_prompt(role: str, team_members: list[str], available_tools: list[str]) -> str`
  - Templates for all 7 roles, each composed as `BASE_PROMPT + role-specific instructions`
  - Role prompts define personality, expertise focus, communication style, and operational rules
  - Include delegation awareness: "You can ask {delegatable_agents} for help via send_message"
  - Include team awareness: "You are part of a team with: {team_members}"
- [x] **3.4** Create `src/henchman/agents/presets.py` — `DEFAULT_TEAM`
  - `get_default_team() -> dict[str, AgentConfig]` — returns all 7 agent configs
  - Each config specifies: tool allowlist, delegation targets, role description
  - Prompts use `None` (resolved from `prompts.py` at runtime)
- [x] **3.5** Extend `src/henchman/config/schema.py`
  - Add `AgentSettings` Pydantic model with `team_preset: str = "default"`, `agents: dict[str, AgentConfig] = {}`, `max_delegation_depth: int = 3`, `shared_context_max_tokens: int = 4000`
  - Add `agents: AgentSettings = AgentSettings()` to `Settings`
- [x] **3.6** Write tests: `tests/agents/test_config.py`, `tests/agents/test_prompts.py`, `tests/agents/test_presets.py`, update `tests/config/test_schema.py`
- [x] **3.7** Run `./scripts/ci.sh` — all checks pass

---

### WP4: AgentPool — Multi-Agent Lifecycle

> Factory and manager for all agent instances.

- [x] **4.1** Create `src/henchman/agents/pool.py` — `AgentPool` class
  - Constructor: `__init__(configs: dict[str, AgentConfig], default_provider: ModelProvider, provider_registry: ProviderRegistry, parent_tool_registry: ToolRegistry, event_bus: EventBus)`
  - `create_agent(role: str) -> Agent` — creates Agent with:
    - `AgentIdentity` from config
    - Scoped `ToolRegistry` (only allowed tools)
    - Role-specific system prompt from `prompts.py`
    - Provider from config override or default
    - EventBus subscription for incoming `AGENT_MESSAGE` events
  - `get_agent(role: str) -> Agent` — get or lazily create
  - `get_identity(role: str) -> AgentIdentity`
  - `list_agents() -> list[AgentIdentity]` — all configured (not just instantiated)
  - `list_active_agents() -> list[AgentIdentity]` — only instantiated agents
  - `reset_agent(role: str) -> None` — clear agent history, keep instance
  - `reset_all() -> None` — reset all agents
  - `shutdown() -> None` — cleanup all agents and subscriptions
- [x] **4.2** Implement `create_scoped_registry()` helper function
  - `create_scoped_registry(parent: ToolRegistry, allowed_tools: list[str], extra_tools: list[Tool] | None = None) -> ToolRegistry`
  - Copies only allowed tools from parent into new registry
  - Adds any extra tools (e.g., `SendMessageTool`, `DelegateTaskTool`)
  - Copies confirmation handler from parent
  - Applies auto-approve policies from `AgentConfig.auto_approve`
- [x] **4.3** Update `src/henchman/agents/__init__.py` exports
- [x] **4.4** Write tests: `tests/agents/test_pool.py` (lazy init, scoped registries, reset, provider overrides)
- [x] **4.5** Run `./scripts/ci.sh` — all checks pass

---

### WP5: Orchestrator — Delegation Engine

> The brain that routes work between agents and manages delegation flows.

- [x] **5.1** Create `src/henchman/tools/builtins/delegate.py` — `DelegateTaskTool`
  - Parameters: `agent: str` (target agent role), `task: str` (task description), `context: str | None` (relevant file contents, decisions, etc.)
  - `ToolKind.READ` (auto-approved — delegation is orchestration)
  - `execute()` returns `ToolResult(content="Delegation handled by orchestrator")` — **stub**
  - The tool exists to declare the JSON schema to the LLM; the Orchestrator intercepts the tool call before `execute()` is reached
- [x] **5.2** Create `src/henchman/agents/orchestrator.py` — `Orchestrator` class
  - Constructor: `__init__(default_provider: ModelProvider, provider_registry: ProviderRegistry | None, tool_registry: ToolRegistry, event_bus: EventBus | None, settings: Settings | None, system_prompt: str | None)`
    - Creates `EventBus` if not provided
    - Loads agent configs from settings (or default preset)
    - Creates `AgentPool`
    - Creates Tech Lead agent with all tools + `DelegateTaskTool`
  - `run(user_input: str) -> AsyncIterator[AgentEvent]` — main entry:
    1. Yields `AgentEvent(AGENT_STARTED, data={"agent": "tech_lead"})`
    2. Streams from `tech_lead.run(user_input)`
    3. For each event:
       - If `TOOL_CALL_REQUEST` with `name == "delegate_task"`:
         - Yields `AgentEvent(AGENT_DELEGATED, data={"from": "tech_lead", "to": target, "task": task})`
         - Calls `_run_delegation(target, task, context, depth=1)`
         - Submits delegation result to Tech Lead via `submit_tool_result()`
         - Continues with `tech_lead.continue_with_tool_results()`
       - Otherwise: yields event as-is (passthrough)
    4. Yields `AgentEvent(AGENT_COMPLETED, data={"agent": "tech_lead"})`
  - `run_direct(agent_role: str, user_input: str) -> AsyncIterator[AgentEvent]` — bypass Tech Lead:
    1. Gets/creates agent from pool
    2. Streams from `agent.run(user_input)`
    3. Handles nested delegation if agent has `can_delegate_to`
  - `_run_delegation(target_role, task, context, depth) -> str`:
    1. Checks `depth <= max_delegation_depth` (else return error)
    2. Gets/creates target agent from pool
    3. Injects shared context into task description
    4. Runs target agent, collects all content events
    5. If target agent delegates (recursive), handles sub-delegation
    6. Appends summary to `shared_context`
    7. Returns collected output as string
  - [x] **5.3** Handle inter-agent messaging:
  - When `SendMessageTool` fires, the Orchestrator's EventBus routes the message
  - Target agent receives the message as a user-injected prompt on its next turn
  - Orchestrator collects the response and routes it back
- [x] **5.4** Implement shared context management:
  - After each delegation completes, extract a brief summary
  - Maintain `shared_context` list with `{"agent": role, "summary": text, "timestamp": ...}`
  - Inject relevant shared context into sub-agent system prompts
  - Trim to `shared_context_max_tokens` from settings
- [x] **5.5** Update `src/henchman/agents/__init__.py` exports
- [x] **5.6** Write tests: `tests/agents/test_orchestrator.py`, `tests/tools/test_delegate.py`
  - Test: basic delegation flow (Tech Lead → Coder)
  - Test: recursive delegation (Tech Lead → Coder → Researcher)
  - Test: max depth exceeded → graceful error
  - Test: direct agent targeting
  - Test: inter-agent messaging
  - Test: shared context accumulation
  - Test: delegation with different providers per agent
  - Test: fallback to single-agent mode when no agents configured
- [x] **5.7** Run `./scripts/ci.sh` — all checks pass

---

### WP6: Session and History Enhancements

> Track which agent said what across sessions.

- [x] **6.1** Extend `SessionMessage` in `src/henchman/core/session.py`
  - Add `agent_id: str | None = None` — which agent produced this message
  - Add `agent_role: str | None = None` — human-readable role name
  - Backwards-compatible with existing saved sessions (new fields optional)
- [x] **6.2** Extend `Session` in `src/henchman/core/session.py`
  - Add `active_agents: list[str] = []` — agents that participated in this session
  - Add `delegation_log: list[dict] = []` — log of `{"from": ..., "to": ..., "task": ..., "timestamp": ...}`
- [x] **6.3** Update session recording in Repl to include agent attribution
  - When recording assistant messages, include `agent_id` and `agent_role` from event's `source_agent`
- [x] **6.4** Write tests: update `tests/core/test_session.py`
- [x] **6.5** Run `./scripts/ci.sh` — all checks pass

---

### WP7: REPL and CLI Integration

> Wire everything together in the user-facing layer.

- [x] **7.1** Modify `src/henchman/cli/repl.py` — Orchestrator integration
  - Add `self.orchestrator: Orchestrator` created in `__init__` alongside existing agent setup
  - `_run_agent()` calls `self.orchestrator.run(user_input)` instead of `self.agent.run()`
  - Keep `self.agent` as reference to `orchestrator.tech_lead` for backwards compat (session restore, etc.)
  - `_process_agent_stream()` handles new event types:
    - `AGENT_DELEGATED` → `renderer.info(f"[{from_agent}] Delegating to {to_agent}: {task}")`
    - `AGENT_STARTED` → update status spinner with agent name
    - `AGENT_COMPLETED` → `renderer.muted(f"[{agent}] Completed")`
    - `AGENT_MESSAGE` → `renderer.muted(f"[{from} → {to}] {message}")`
  - All existing event handling (`CONTENT`, `TOOL_CALL_REQUEST`, etc.) unchanged
- [x] **7.2** Create `src/henchman/cli/commands/agent.py` — `/agent` command
  - `/agent list` — table showing name, role, status (active/idle), tool count
  - `/agent <role> <message>` — direct message to specific agent via `orchestrator.run_direct()`
  - `/agent config [role]` — show configuration for agent(s)
- [x] **7.3** Create `src/henchman/cli/commands/team.py` — `/team` command
  - `/team` — show team overview: active members, last activity, message counts
  - `/team reset` — reset all agent histories
  - `/team status` — detailed status with delegation log
- [x] **7.4** Register new commands in `src/henchman/cli/commands/builtins.py`
  - Add `AgentCommand` and `TeamCommand` to `get_builtin_commands()`
- [x] **7.5** Update `src/henchman/cli/app.py`
  - Add `--agent` / `-a` CLI option: `mlg --agent coder --prompt "Fix the bug"`
  - Pass to `_run_headless()` and `_run_interactive()` for direct agent targeting
  - Add `--team` flag to show team info and exit
- [x] **7.6** Write tests: `tests/cli/test_agent_command.py`, `tests/cli/test_team_command.py`, update `tests/cli/test_repl.py`, update `tests/cli/test_app.py`
- [x] **7.7** Run `./scripts/ci.sh` — all checks pass

---

### WP8: Polish, Docs, and Release

> Version bump, documentation, and final verification.

- [x] **8.1** Version bump: `0.1.18` → `0.2.0`
  - Update `src/henchman/version.py`
  - Update `pyproject.toml`
- [x] **8.2** Update `CHANGELOG.md` with v0.2.0 release notes
- [x] **8.3** Create `docs/agents.md` — multi-agent system documentation
  - Architecture overview with diagram
  - Agent roster descriptions
  - Configuration reference with examples
  - Custom agent creation guide
  - Inter-agent communication explanation
- [x] **8.4** Update `docs/configuration.md` — add `agents:` config block reference
  - Example: customizing agent tools, prompts, providers
  - Example: disabling agents
  - Example: adding a custom agent
- [x] **8.5** Update `docs/getting-started.md` — team overview for new users
- [x] **8.6** Update `README.md` — v0.2.0 highlights, multi-agent feature summary
- [x] **8.7** Update `.github/copilot-instructions.md` — multi-agent architecture, new types, new patterns
- [x] **8.8** Final CI run: `./scripts/ci.sh` — 100% coverage, all checks green
- [x] **8.9** Manual smoke tests:
  - `mlg` → coding task → observe Tech Lead delegating → code written → review produced
  - `/agent coder Fix the bug in auth.py` → Coder handles directly
  - `/agent list` → shows all 7 agents with status
  - `/team` → shows active team overview
  - `mlg --agent researcher --prompt "How does X work?"` → headless with specific agent
  - Inter-agent: Coder asks Researcher for docs mid-task → response flows back
  - Scoped tools: Architect cannot call `write_file` → error/refusal
  - Custom config: modified `settings.yaml` with different agent setup loads correctly
  - Session resume: delegated session saves/loads with agent attribution

---

## Configuration Reference

### Default settings.yaml additions

```yaml
agents:
  # Which preset team to use (only "default" shipped for now)
  team_preset: "default"

  # Max recursive delegation depth (Tech Lead → Coder → Researcher = depth 2)
  max_delegation_depth: 3

  # Max tokens for shared context passed between agents
  shared_context_max_tokens: 4000

  # Agent overrides (merge with preset defaults)
  agents:
    # Example: give Architect a more powerful model
    architect:
      provider: "anthropic"
      model: "claude-sonnet-4-20250514"

    # Example: disable DevOps agent
    devops:
      enabled: false

    # Example: add extra tools to Coder
    coder:
      tools:
        - read_file
        - write_file
        - edit_file
        - ls
        - glob
        - grep
        - shell
        - web_fetch  # Added: let Coder search docs

    # Example: fully custom agent
    security_auditor:
      name: "Security Auditor"
      role: "security_auditor"
      description: "Audits code for security vulnerabilities"
      system_prompt: "You are a security expert. Analyze code for OWASP Top 10..."
      tools:
        - read_file
        - grep
        - glob
        - web_fetch
      can_delegate_to: []
```

### Environment Variables

| Variable | Purpose |
|----------|---------|
| `HENCHMAN_TEAM_PRESET` | Override team preset (default: "default") |
| `HENCHMAN_DISABLE_AGENTS` | Set to "1" to disable multi-agent, use single-agent mode |

---

## Implementation Order and Dependencies

```
WP1 (Identity + Events)
 │
 ├──► WP2 (EventBus)
 │     │
 │     └──► WP5 (Orchestrator) ──► WP7 (REPL/CLI Integration)
 │           │
 ├──► WP3 (Config + Prompts)──┘
 │     │
 │     └──► WP4 (AgentPool) ──┘
 │
 └──► WP6 (Session Enhancements) ──► WP7
                                       │
                                       └──► WP8 (Polish + Release)
```

**Critical path**: WP1 → WP3 → WP4 → WP5 → WP7 → WP8

**Can be parallelized**:
- WP2 (EventBus) can be built alongside WP3 (Config)
- WP6 (Session) can be built alongside WP4/WP5

---

## Risk Mitigation

| Risk | Mitigation |
|------|------------|
| **Token cost explosion** from multi-agent | Shared context is token-bounded; lazy agent init; configurable per-agent models |
| **Infinite delegation loops** | Max delegation depth (default 3); cycle detection in Orchestrator |
| **Slow startup with 7 agents** | Lazy instantiation — agents created only when first needed |
| **Backwards compatibility** | `HENCHMAN_DISABLE_AGENTS=1` env var; empty config = single-agent mode |
| **Test coverage regression** | Each WP ends with CI gate; no merging without 100% coverage |
| **Runaway agent behavior** | Turn limits already exist per-agent; Orchestrator enforces delegation depth |
| **Provider API differences** | Each agent reuses existing `Agent` class + provider; no new provider concerns |