Chimera is composed from eight phases of agent infrastructure. Each phase is
a self-contained set of modules with a defined public surface, and each of
the seven coding-agent CLIs (mink, otter, ferret, weasel, shrew,
stoat, badger) is assembled by picking from those phase primitives.
Phases are independent enough to use on their own, but they were designed
so that the dependency edges flow in one direction: a higher phase may
reach into a lower one, never the reverse.
This page is the live phase-to-code map. If you are looking for the older "8-layer stack" view (CLI / Workflows / Synthesis / Evaluation / Agent / Provider / Infrastructure / Environment), the eight phases are an orthogonal slicing of the same codebase along the agent-loop axis rather than the synthesis-pipeline axis. The two views are complementary, not competing — see the old layer view at the bottom of this page.
The seven coding-agent CLIs share one library. Earlier versions of
Chimera tried to keep everything as horizontal "layers" — one giant
loop, one giant context manager, one giant permission system. That
worked while there was one CLI. Once mink and otter shipped side
by side, the seams started to show: features that needed to go into
the loop AND the session AND the permission system kept landing in
three different layers at once. The phases collect those features by
their cross-cutting concern (loop turns, sub-agent isolation,
persistence, gating, prompting, lifecycle hooks, command surface,
production wiring, snapshotting), so a feature lands in one place and
every CLI inherits it.
If you are reading this to figure out where to add code, the rule of thumb is: pick the phase whose contract your change touches, not the CLI it shows up in first.
The nine phases form a stack: phases 1 through 7 layer downward, each building on the one below; phases 8 and 9 cross-cut the stack rather than sitting inside it. The diagram below traces the load-bearing edges — read top-down, every arrow says "depends on the layer below me at runtime."
graph TD
P7["Phase 7 — Command + Skill surface<br/>slash commands, skills, flow workflows"]
P6["Phase 6 — Hook system<br/>Pre/PostToolUse, lifecycle, async registry"]
P5["Phase 5 — System prompt + context<br/>layered prompts, cache-safe, tool deferral"]
P4["Phase 4 — Permission system<br/>modes, rules, denial tracking, sandbox"]
P3["Phase 3 — State + persistence<br/>eventlog, snapshots, content replacement"]
P2["Phase 2 — Sub-agent architecture<br/>isolation tiers, spawner, task manager"]
P1["Phase 1 — Core loop<br/>AgentLoop, streaming executor, recovery"]
P8["Phase 8 — Production infrastructure<br/>auth, secrets, MCP/LSP/ACP, plugins"]
P9["Phase 9 — Snapshot / format / patch<br/>undo, auto-format, structured patching"]
P7 --> P6 --> P5 --> P4 --> P3 --> P2 --> P1
P8 -.threads through.-> P1
P8 -.threads through.-> P3
P8 -.threads through.-> P7
P9 -.plugs into.-> P1
P9 -.plugs into.-> P3
P9 -.plugs into.-> P4
classDef stack fill:#2563eb,stroke:#60a5fa,color:#fff
classDef cross fill:#d97706,stroke:#fbbf24,color:#000
class P1,P2,P3,P4,P5,P6,P7 stack
class P8,P9 cross
Caption. Solid edges = load-bearing call-graph dependencies. Dotted edges = cross-cutting attachment points (phases 8 and 9 don't sit in the stack — they thread through several layers at once).
The dependency edges are real. Phase 2 needs Phase 1's AbortSignal
to give sub-agents linked-but-cancellable children. Phase 4's permission
checks fire from inside Phase 1's tool-execution phase. Phase 5's
prompt builder feeds Phase 1's AgentLoop.run(). And so on. Phases 8
and 9 are cross-cutting: Phase 8 wires production concerns (auth,
analytics, MCP lifecycle) into every other phase, and Phase 9 plugs
snapshot/format/patch into the loop turn boundary, the persistence
layer, and the permission gate.
Purpose. Drive a tool-augmented LLM agent with streaming, concurrent tool execution, multi-stage error recovery, and cooperative cancellation. This is the engine every other phase plugs into.
Status. Shipped as the default loop in CodingAgent. The legacy
synchronous ReAct loop is preserved alongside for back-compat with
callers that still use Agent.run() directly.
Key modules.
chimera/core/agent_loop.py—AgentLoop, the async-generator core loopchimera/core/loop.py— legacy synchronousReActloop (back-compat)chimera/core/loop_events.py—LoopEvent,LoopEventType,LoopResultchimera/core/loop_state.py—LoopState,QuerySource,RETRY_POLICIESchimera/core/loop_deps.py—LoopDeps,production_deps()chimera/core/streaming_executor.py—StreamingToolExecutorwith concurrency flagschimera/core/recovery.py—ErrorRecovery,WithheldError, multi-stage recoverychimera/core/abort.py—AbortSignalwith linked childrenchimera/core/tool_executor.py— shared tool-execution path with permission/event/audit hookschimera/core/tool.py—BaseToolplus theis_concurrency_safe/is_read_only/is_destructiveflags
Public API.
from chimera.core.agent_loop import AgentLoop
from chimera.core.abort import AbortSignal
from chimera.core.loop_state import QuerySource
loop = AgentLoop()
async for event in loop.run(
messages=[...], tools=[...], provider=..., system_prompt=...,
abort_signal=AbortSignal(), query_source=QuerySource.FOREGROUND,
):
handle(event)Notes. Tools default to is_concurrency_safe = False (fail-closed).
Read-only tools (read, glob, grep, list_files) opt in. The recovery
ladder is context-collapse → reactive-compact → escalate-output → multi-turn.
Purpose. Spawn sub-agents with three-tier context isolation so a child agent cannot corrupt parent state, but infrastructure (background tasks, hooks) can still reach the root session. Every multi-agent workflow lives on top of this.
Status. Shipped. composition/ (Pipeline, Ensemble, Supervisor)
re-implements its primitives via AgentSpawner. Built-in agents
(general-purpose, explore, plan) are registered out of the box.
Key modules.
chimera/core/agent_context.py—AgentContext,IsolationLevelchimera/core/agent_spawner.py—AgentSpawner.spawn()chimera/core/agent_definition.py—AgentDefinitionand the on-disk loaderchimera/core/builtin_agents.py—BUILTIN_AGENTSchimera/core/task_manager.py—BackgroundTask,TaskManagerchimera/core/auto_background.py— auto-promote long-running foreground agentschimera/agents/—AgentConfig,AgentRegistry,AgentLoader, presetschimera/agents/dispatch/— request classifier, trigger router, force-routeschimera/composition/— Pipeline / Ensemble / Supervisor on top of the spawnerchimera/tools/agent_tool.py— the model-facingagenttoolchimera/tools/task_tools.py—TaskCreate,TaskGet,TaskList,TaskStop,TaskOutput
Public API.
from chimera.core.agent_context import AgentContext, IsolationLevel
from chimera.core.agent_spawner import AgentSpawner
spawner = AgentSpawner(...)
async for event in spawner.spawn(definition, prompt, parent_ctx,
isolation=IsolationLevel.FULL):
...Notes. Sub-agents get a per-agent denial counter (so "deny three
times → stop asking" works inside a sub-agent's own scope). The
set_app_state_for_tasks callback bypasses isolation so background bash
tasks can register with the root task manager.
Purpose. Long conversations don't blow up the context window, sessions resume losslessly, and prompt-cache hit rates stay high. Solved with the content-replacement state machine (large tool results spill to disk, model sees a preview), file-state caching for read deduplication, JSONL transcripts for sub-agent sidechains, and an event-sourced session store with snapshots.
Status. Shipped. The default EventSourcedSession backend has both a
JSONL-on-disk implementation and a side-car SQLite store with snapshot-driven
fast resume.
Key modules.
chimera/sessions/eventlog/— append-only event log with file locking, gap detection, crash recoverychimera/sessions/eventlog/session.py—EventSourcedSession, snapshot integration,with_sqlite()helperchimera/events/sourcing/sqlite_store.py—SqliteEventStore(SQLite + WAL + per-aggregate seq + snapshot table)chimera/events/sourcing/projector.py— projector registry and replaychimera/sessions/session.py—Session(chat / iter_chat / fork / save / resume / steer / queue / cancel)chimera/sessions/tree.py—SessionTreewith in-place branching viaparent_idchimera/sessions/storage/— Memory / File / SQLite backendschimera/core/content_replacement.py—ContentReplacementState, persisted-vs-inline decisionschimera/core/file_state_cache.py— file-state LRU for read deduplicationchimera/core/file_tracker.py—FileTrackeracross compaction boundarieschimera/core/tool_result_persister.py— disk persistence for oversized tool resultschimera/compaction/—SummaryCompaction, prune / counter / composite, threshold-based atomic compaction
Public API.
from chimera.sessions.eventlog.session import EventSourcedSession
session = EventSourcedSession.with_sqlite(
sqlite_path="~/.chimera/eventlog/run.sqlite",
snapshot_every_n_events=50,
)Notes. Once a tool_use_id is replaced (persisted-to-disk), the
decision is frozen — this is critical for prompt-cache stability across
turns. Snapshots let resume start from snapshot.seq + 1 instead of
seq=1; the side-car mode keeps the journal authoritative and the snapshot
purely for fast-forward.
Purpose. Gate tool execution with multi-source rules, five permission
modes, denial tracking with fallback-to-prompting, and a sandbox adapter
for shell execution. Bypass-immune safety checks make sure that even
bypass_permissions mode can't run truly destructive operations
unannounced.
Status. Shipped. All seven CLIs honor ~/.claude/settings.json rules;
ferret adds an OS-level sandbox layer on top via --sandbox × --approval
preset composition.
Key modules.
chimera/permissions/base.py—ApprovalPolicy,PermissionPolicychimera/permissions/modes.py—PermissionModeenum (default / plan / accept_edits / bypass / dont_ask / auto)chimera/permissions/rule.py,rules.py,patterns.py—PermissionRuleValue,ToolName(content)parsingchimera/permissions/checker.py— decision algorithmchimera/permissions/loader.py— multi-source rule loading with precedencechimera/permissions/denial_tracking.py— per-agent denial counterchimera/permissions/presets.py— read-only / auto / full (ferret-style)chimera/permissions/sandbox.py— sandbox adapterchimera/permissions/risk.py— risk classifier for bash patternschimera/permissions/audit.py—AuditEntry,AuditLogchimera/permissions/interactive.py+chimera/permissions/prompt_handler.py— interactive approval handlerschimera/cli/permission_prompt.py— REPL prompt UI
Public API.
from chimera.permissions import (
PermissionMode, PermissionRuleValue, AllowList, AlwaysDeny,
)
rule = PermissionRuleValue.from_string("bash(git *)")
policy = AllowList([rule])Notes. Settings discovery is project-root → user-global → built-in.
Ferret's two-flag composition is implemented as the cross product of
PermissionMode (policy gate) and a sandbox adapter (OS gate); a tool
call has to pass both.
Purpose. Layered prompt construction so the cache prefix stays stable across turns, agent-specific overrides for sub-agents, API-based token estimation with fallback, and tool deferral (lazy-load tools by name) to keep the initial prompt small even when the registry is large.
Status. Shipped. The Prompt template class is preserved for back-compat
callers; new code uses SystemPromptBuilder.
Key modules.
chimera/core/prompt.py—Promptclass with{{variable}}template substitution (legacy)chimera/core/system_prompt.py—PromptLayer,SystemPrompt,SystemPromptBuilder(cache-segmented layers)chimera/core/prompt_template.py— additional template helperschimera/core/context_assembler.py— assemble project-context layer (git status, project rules)chimera/core/cache_safe_params.py— frozen request params for forked agentschimera/core/tool_deferral.py—ToolSearchToollazy registrychimera/core/token_estimator.py— API-first, fallback-on-error token countingchimera/core/token_budget.py— budget enforcementchimera/core/context.py— conversation history managerchimera/core/memory.py—CLAUDE.md/AGENTS.mdingestion (per-CLI rules)
Public API.
from chimera.core.system_prompt import SystemPromptBuilder
prompt = (SystemPromptBuilder()
.add_layer("default", DEFAULT_SYSTEM, cacheable=True)
.add_layer("agent_override", AGENT_DESC, cacheable=True)
.add_layer("user_append", USER_RULES, cacheable=False)
.build())Notes. Each CLI ingests its own rule files (~/.claude/CLAUDE.md,
AGENTS.md, .codex/AGENTS.md, etc.) into the user-append layer; the
default and agent-override layers stay cacheable so the cache prefix
doesn't move when a user edits a project rule file mid-session.
Purpose. Event-driven lifecycle hooks — pre/post tool, permission events, session start/end, sub-agent start/stop, compaction boundaries, notifications — that can be implemented as shell commands, LLM prompts, or function callbacks. Hooks load from settings, plugins, and skill directories with priority ordering.
Status. Shipped with five built-in hooks plus a fully-async registry.
Key modules.
chimera/hooks/events.py—HookEventenum (27 lifecycle events)chimera/hooks/emitter.py— fire-and-collect hook event dispatcherchimera/hooks/executor.py— three executors (shell / prompt / function)chimera/hooks/async_registry.py— async hook registry with timeout / progresschimera/hooks/loader.py— multi-source hook loadingchimera/hooks/session_hooks.py— session-scoped hookschimera/hooks/hook_types.py— typed inputs and response schemaschimera/hooks/hooks.json— bundled defaultschimera/hooks/auto_test.py,auto_lint.py,validate_path.py,security_scan.py,verify_done.py,loop_detector.py,file_watcher.py— bundled hook scriptschimera/core/middleware.py—MiddlewareChain(before_model / after_model / after_agent) for in-process hooks
Public API.
from chimera.hooks.events import HookEvent
from chimera.hooks.async_registry import AsyncHookRegistry
reg = AsyncHookRegistry()
reg.register(HookEvent.POST_TOOL_USE, my_callback)Notes. Hooks support updatedInput mutation: a PreToolUse hook can
rewrite the tool input before execution. Audit-trail and cwd / env
inheritance landed in M2-B.
Purpose. Slash commands for the user (REPL palette), skills (markdown files with YAML frontmatter that the model can invoke), and a SkillTool bridge so the model can call commands directly. Skills support inline context (run in current loop) or forked context (spawn sub-agent).
Status. Shipped. The shared registry is in chimera/cli/slash_commands.py;
each CLI selects which subset to expose. Skills auto-discover from
<project>/skills/, ~/.chimera/skills/, and bundled defaults.
Key modules.
chimera/skills/discovery.py—discover_skills(), walks SKILL.md fileschimera/skills/loader.py—SkillLoaderchimera/skills/definition.py—SkillDefinitionchimera/skills/bundled.py— bundled built-inschimera/skills/flow.py,flow_parser.py,flow_executor.py— Mermaid flowchart workflowschimera/cli/slash_commands.py— shared REPL command registrychimera/commands/—CommandBase,PromptCommand,LocalCommand, registry, processorchimera/cli/code.py,chimera/mink/cli.py,chimera/otter/cli.py, etc. — per-CLI command surfaces
Public API.
from chimera.commands.registry import CommandRegistry
from chimera.skills.discovery import discover_skills
skills = discover_skills(["~/.chimera/skills/", "skills/"])Notes. Each CLI shows only its slash subset (mink: 19, otter: 26,
weasel: 7 on purpose, badger: shared + /parity + /rerun, stoat:
shared + /shell). Skills can register hooks at invocation time so a
skill becomes a small bundle of "command + hooks + system prompt
override" in one file.
Purpose. The cross-cutting plumbing that turns a prototype into a production tool: feature flags for build-time elimination, analytics with PII redaction, MCP / LSP / ACP server lifecycle, IDE bridge, auth (API key, OAuth device, OAuth browser, credential store with 0o600 perms), secret detection and redaction, streaming output, plugin system with marketplace, and coordinator mode for multi-agent orchestration.
Status. Shipped piece by piece. MCP, LSP, ACP, plugins, auth, and
secrets are all wired into the default CodingAgent build.
Key modules.
chimera/auth/—manager.py,api_key.py,oauth.py,oauth_device.py,store.py(file-based, 0o600)chimera/secrets/—registry.py(env-var loading),detector.py(10 built-in patterns),redactor.py(event bus middleware)chimera/security/—risk.py,analyzer.py(rule / LLM / composite),policy.py(ConfirmationPolicyvariants)chimera/streaming/—base.py,handlers.py,loop.py,protocol.pychimera/core/feature_flags.py—FeatureFlags.enabled(), env-var overrideschimera/analytics/— analytics with PII redactionchimera/mcp/— MCP client (stdio / HTTP / SSE / WS), OAuth, lifecyclechimera/lsp/— LSP client, diagnostics, completion, renamechimera/acp/— Agent Client Protocol (JSON-RPC 2.0 over stdio)chimera/bridge/— IDE bridge protocolchimera/plugins/—BasePlugin,PluginManager,PluginExtensionRegistry,DirectoryPluginLoader, marketplacechimera/coordinator/— multi-agent coordinator modechimera/server/— HTTP+SSE server (drivesotter serve --portandferret serve --http)chimera/wire/—WireMessage, request/response, approval requests, status updateschimera/rpc/— JSON-RPC server (stdin/stdout) and command/response/event typeschimera/providers/cost.py+cost_tracker.py— per-model pricing, granular token trackingchimera/learning/— observation store (SQLite + FTS5), confidence tracking, error feedback
Public API. This phase has no single entry point — it's the
collection of cross-cutting modules every other phase reaches into.
The clearest seam is chimera/assembly/coding_agent.CodingAgent,
which wires production infrastructure into a single buildable
agent: CodingAgent(model=..., preset='claude_code').
Notes. Feature flags read CHIMERA_FEATURE_<NAME>=1 from the
environment. Secrets pre-empt the event bus before logs / transcripts
are persisted. The plugin marketplace is a directory loader plus an
HTTP-fetched index.
Purpose. Three safety / quality features that span phases 1, 3, and 4:
turn-boundary file snapshots so users can undo agent edits to any prior
turn, auto-formatter integration that runs prettier / ruff / gofmt
after every file write, and a structured multi-file patch format with
fuzzy matching that handles multi-file edits in one tool call.
Status. Shipped. Snapshots integrate with the JSONL transcript so a
session can be reverted and resumed cleanly. Auto-format runs as a
PostToolUse hook on file-write tools. The structured patch parser
ships alongside the legacy edit formats (whole-file, search-replace,
diff, udiff) for callers that want the GPT-family-emitted format.
Key modules.
chimera/core/snapshot.py—SnapshotManager,Snapshot, shadow-git plumbing with file-copy fallbackchimera/checkpoints.py— high-levelCheckpointManager(create / restore_by_name / restore_by_id / undo / list)chimera/checkpoints_ghost.py— ghost-checkpoint helperschimera/core/auto_format.py—AutoFormatter, formatter detection (prettier,ruff,gofmt,rustfmt, …)chimera/core/patch_parser.py—PatchParser,FilePatch,PatchHunk, fuzzy-match passeschimera/core/proposed_edit.py—ProposedEditfor review-before-apply flowschimera/core/file_mutation_queue.py— serialize file-mutation toolschimera/tools/edit_formats.py— Aider-style edit formatschimera/transactions.py— file-transaction coordinator
Public API.
from chimera.core.snapshot import SnapshotManager
from chimera.checkpoints import CheckpointManager
snap = SnapshotManager(project_dir=Path.cwd())
await snap.take(turn=N, modified_files=[...])
await snap.revert(to_turn=N - 2)Notes. Snapshots use shadow git (a separate .git-style directory
outside the user's repo) when git is available, falling back to direct
file copies. Auto-format runs after the file write completes but before
the POST_TOOL_USE hook fires, so downstream hooks see the formatted
file.
Phase 8 wires chimera/providers/factory.create_provider() in front of
every loop. When the caller passes only a model id (no provider_type),
the factory infers the provider family from the model-name prefix and
local environment hints. The diagram below mirrors _infer_provider() in
chimera/providers/factory.py exactly — same precedence, same fallback
chain, same env-var override.
flowchart TD
Start(["model id<br/>(e.g. claude-sonnet-4, glm-5, gpt-4o)"])
Start --> Local{"prefix is<br/>vllm/* or sglang/*?"}
Local -- yes --> Compat["compatible provider<br/>(local OpenAI-compat server)"]
Local -- no --> EnvOverride{"ANTHROPIC_BASE_URL or<br/>ANTHROPIC_AUTH_TOKEN set?"}
EnvOverride -- yes --> NotAnth{"prefix in gpt / o1 / o3<br/>/ codex / gemini?"}
NotAnth -- no --> Anth["anthropic provider<br/>(routed via env URL)"]
NotAnth -- yes --> Prefix
EnvOverride -- no --> Prefix{"model prefix<br/>match?"}
Prefix -- "claude-*" --> Anth
Prefix -- "glm-*" --> Anth
Prefix -- "kimi-* / moonshot-*" --> Anth
Prefix -- "gpt-* / o1 / o3 / codex-*" --> OAI["openai provider"]
Prefix -- "gemini-*" --> Google["google provider"]
Prefix -- "grok-*" --> XAI["xai provider<br/>(OpenAI-compat to api.x.ai)"]
Prefix -- "llama* / mistral* / qwen* / phi*" --> Ollama["ollama provider"]
Prefix -- no match --> Catalog{"in default<br/>ProviderCatalog?"}
Catalog -- yes --> CatalogResult["catalog.provider_type"]
Catalog -- no --> OpenAIEnv{"OPENAI_API_KEY set?"}
OpenAIEnv -- yes --> OAI
OpenAIEnv -- no --> Err["ValueError:<br/>cannot infer provider"]
classDef terminal fill:#15803d,stroke:#86efac,color:#fff
classDef error fill:#b91c1c,stroke:#fecaca,color:#fff
classDef decision fill:#1e40af,stroke:#93c5fd,color:#fff
class Anth,OAI,Google,XAI,Ollama,Compat,CatalogResult terminal
class Err error
class Local,EnvOverride,NotAnth,Prefix,Catalog,OpenAIEnv decision
Caption. The first decision on vllm/ / sglang/ prefixes is
unconditional — those namespaces are reserved for local self-hosted
servers and short-circuit the rest of the chain. Env-var override wins
over prefix-match when both apply (so a user with an Anthropic-compat
endpoint in their environment can run glm-5, kimi-k2, and similar
through that one URL), but gpt-* / o1 / o3 / codex-* / gemini-*
prefixes are protected — they always go to their native provider
regardless of env vars, because the wire formats are incompatible.
Each CLI is a thin argparse + small per-CLI defaults file over the shared library. The CLI picks which phase primitives to enable by default, which to disable, and which to override.
chimera/<cli>/cli.py ← argparse + per-CLI defaults
↓
chimera/assembly/coding_agent.CodingAgent
↓
chimera/core/agent_loop.AgentLoop + chimera/core/tool_group.create_default_tools(...)
↓
chimera/providers/factory.create_provider(...)
↓
chimera/sessions/eventlog (file locking, gap detection, crash recovery)
↓
~/.chimera/eventlog/<cli>-<utc>-<uuid>/
| CLI | Phase 1 (loop) | Phase 2 (sub-agents) | Phase 3 (sessions) | Phase 4 (permissions) | Phase 5 (prompt rules) | Phase 6 (hooks) | Phase 7 (commands) | Phase 8 (production) | Phase 9 (snapshot) |
|---|---|---|---|---|---|---|---|---|---|
| mink | AgentLoop, max_steps=50 |
full (Task tool, agent-teams) | eventlog + sqlite | ~/.claude/settings.json rules |
~/.claude/CLAUDE.md ingest |
full hook registry | 19 slash commands | full | snapshot + auto-format |
| otter | AgentLoop, max_steps=50 |
full | eventlog + sqlite | ~/.claude/settings.json rules |
rules + share | full | 26 slash commands | + HTTP+SSE server, ACP serve | snapshot + auto-format |
| ferret | AgentLoop, max_steps=50 |
full | eventlog + sqlite | sandbox × approval presets | .codex/AGENTS.md ingest |
full + sandbox hooks | otter + /sandbox, /approval, /bridge |
+ sandbox adapter, cloud bridge | snapshot + auto-format |
| weasel | AgentLoop, max_steps=50 |
by design off | eventlog + sqlite | host-defined (no presets) | .weasel/extensions/ |
restricted | 7 slash commands (sparse) | + RPC mode, embedded SDK | snapshot + auto-format |
| shrew | AgentLoop, max_steps=30 |
inherited from weasel | eventlog + sqlite | weasel + restricted-tool default | chimera/shrew/skills/ + ~/.shrew/skills/ |
restricted | weasel parity | + bench harness | snapshot + auto-format |
| stoat | AgentLoop, max_steps=50 |
full | eventlog + sqlite | ~/.claude/settings.json |
rules + Kimi tuning | full | shared + /shell (mode toggle) |
+ Moonshot provider chain | snapshot + auto-format |
| badger | AgentLoop, max_steps=25 |
full | eventlog + sqlite | shared + harness-tight defaults | shared | full + parity hook | shared + /parity, /rerun |
+ parity-tracker subcommand | snapshot + auto-format |
The takeaway: every CLI inherits all nine phases. The differences are in defaults (step budget, tool restriction, model chain), which slash commands are exposed, and which Phase-8 transports the CLI fronts (HTTP+SSE for otter, ACP-default for ferret, RPC + SDK for weasel, shell-mode toggle for stoat, parity tracker for badger).
The composition graph below is the same idea as the table, but read as "which Phase-8 transport does each CLI add on top of the shared nine-phase core." All seven CLIs share phases 1, 3, 5, 6, 7, 9; phase 2 is on for six of seven (weasel disables sub-agents by design); phase 4 differs in preset (ferret adds OS sandbox); phase 8 is where each CLI plugs in its own transport surface.
graph LR
Core["Shared nine-phase core<br/>(phases 1, 3, 5, 6, 7, 9)"]
Mink["mink — TUI"]
Otter["otter — HTTP+SSE / ACP serve"]
Ferret["ferret — sandbox × approval"]
Weasel["weasel — RPC + embedded SDK"]
Shrew["shrew — small-model harness"]
Stoat["stoat — shell-mode toggle"]
Badger["badger — parity-tracker"]
Core --> Mink
Core --> Otter
Core --> Ferret
Core --> Weasel
Core --> Shrew
Core --> Stoat
Core --> Badger
P2off["Phase 2 disabled<br/>(no sub-agents)"]
P4sandbox["Phase 4: + sandbox adapter"]
P4tight["Phase 4: harness-tight defaults"]
P8http["Phase 8: HTTP+SSE server"]
P8sdk["Phase 8: RPC + embedded SDK"]
P8bench["Phase 8: bench harness"]
P8moon["Phase 8: Moonshot chain"]
P8parity["Phase 8: parity tracker"]
P8sandbox["Phase 8: cloud bridge"]
Otter --> P8http
Ferret --> P4sandbox
Ferret --> P8sandbox
Weasel --> P2off
Weasel --> P8sdk
Shrew --> P8bench
Stoat --> P8moon
Badger --> P4tight
Badger --> P8parity
classDef coreBox fill:#1e40af,stroke:#93c5fd,color:#fff
classDef cli fill:#7c3aed,stroke:#c4b5fd,color:#fff
classDef ext fill:#d97706,stroke:#fbbf24,color:#000
class Core coreBox
class Mink,Otter,Ferret,Weasel,Shrew,Stoat,Badger cli
class P2off,P4sandbox,P4tight,P8http,P8sdk,P8bench,P8moon,P8parity,P8sandbox ext
Caption. Solid edges from Core show every CLI inheriting the shared
core. Outgoing edges from each CLI box capture the per-CLI deltas: which
phases get new defaults (P4: sandbox, P4: harness-tight), which
phases are disabled (P2: off for weasel), and which Phase-8 transports
front the CLI (HTTP+SSE, RPC+SDK, bench harness, parity tracker, etc.).
For the per-CLI quickstart and parity row, see each CLI's docs:
- Mink quickstart — TUI-first
- Otter quickstart — server-first / multi-client
- Ferret quickstart — IDE-flagship sandbox-first
- Weasel quickstart — minimal harness, four modes
- Shrew quickstart — small-local-model
- Stoat quickstart — shell-mode toggle
- Badger quickstart — harness-rewrite discipline
For the side-by-side surface comparison and provider-chain matrix, see Coding Agents Overview.
For callers used to the older Chimera mental model — eight horizontal layers (CLI / Workflows / Synthesis / Evaluation / Agent / Provider / Infrastructure / Environment) — the relationship between the two views is:
- Layer 1 (Environment) maps roughly to Phase 8's environment
abstractions (
chimera/env/), but environments are referenced by every phase that touches files or shells. - Layer 2 (Infrastructure) is split across Phases 3, 4, 6, and 8 depending on which cross-cutting concern the module addresses.
- Layer 3 (Provider) is Phase 8 (production wiring), referenced by
Phase 1 (the loop calls
provider.stream()). - Layer 4 (Agent) is the union of Phases 1, 2, and 5.
- Layer 5 (Evaluation) is its own thing:
chimera/eval/,chimera/benchmarks/, used by training-side workflows. Sits next to the phase stack rather than inside it. - Layer 6 (Synthesis) is the training pipeline (
chimera/training/,chimera/synthesize.py). Also sits next to the phase stack. - Layer 7 (Workflows) uses the phase stack from outside —
CIFixWorkflow,ReviewOrchestrator,Researcher,MigrationPlanner,DocGenerator,TestGeneratorare all built on top of Phase 1'sAgentLoopplus their own domain-specific parsing. - Layer 8 (CLI) is the seven coding-agent CLIs above, plus the
top-level
chimera synthesize / eval / bench / code / review / ci-fix / research / docs / testgen / migrate / pluginssubcommands.
When in doubt, prefer the phase view for changes that touch the agent loop / tool-execution path, and prefer the layer view for changes that touch the synthesis or evaluation pipelines.
- Coding Agents Overview — comparative tour of the seven CLIs
- Build Your Own Agent — full developer library guide
- All Playbooks — 13 end-to-end recipes
- Benchmarks — transparency framework, raw data