Skip to content

Design Decisions

Architectural Decision Records (ADRs) documenting the key design choices in Agent Flow.

ADR-001: Multi-Agent Architecture

Context

When building an AI-assisted development system, we need to decide between: 1. A single general-purpose agent handling all tasks 2. Multiple specialized agents with focused responsibilities

Decision

Use multiple specialized agents with distinct roles, tools, and behavioral guidelines.

Rationale

  1. Separation of Concerns: Each agent has a clear responsibility
  2. Exploration is separate from implementation
  3. Implementation is separate from verification
  4. This prevents shortcuts and ensures thoroughness

  5. Tool Restriction: Agents only have tools they need

  6. Explorers can't modify files (prevents accidental changes)
  7. Implementers can't skip verification (no temptation)
  8. Verifiers can't fix issues (forces handback)

  9. Model Optimization: Different tasks need different capabilities

  10. Strategic planning benefits from deeper reasoning (Opus)
  11. Execution benefits from speed (Sonnet)
  12. Cost is optimized by matching model to task

  13. Independent Verification: Self-verification is unreliable

  14. Agents reviewing their own work have inherent bias
  15. Separate verifiers provide objective assessment

Consequences

  • Positive: Clear responsibilities, better verification, cost optimization
  • Negative: More complexity, context passing overhead

Alternatives Considered

  1. Single Agent with Modes: One agent switching between modes
  2. Rejected: No clear boundaries, self-verification issues

  3. Parallel Agents with Consensus: Multiple agents vote on decisions

  4. Rejected: Overhead without clear benefit for development tasks

ADR-002: Verification-First Philosophy

Context

LLMs can generate confident claims about task completion without actual verification. We need to determine how to handle this.

Decision

Require evidence, not claims. Every significant assertion must be backed by actual command output.

Rationale

  1. LLMs Hallucinate Completion: Models report success based on patterns, not memories
  2. "Tests pass" is easy to generate without running tests
  3. Confidence doesn't correlate with accuracy

  4. Evidence is Verifiable: Command output can be checked

  5. Test results show actual pass/fail
  6. Type errors are explicit
  7. Build failures are undeniable

  8. Prevention Over Detection: Better to require evidence than detect lies

  9. Evidence requirements prevent false claims
  10. Detection is unreliable with capable models

Consequences

  • Positive: Reliable completion status, caught errors, user confidence
  • Negative: Slower workflows, more verbose output

Alternatives Considered

  1. Trust Agent Claims: Accept completion statements at face value
  2. Rejected: High false positive rate, bugs ship

  3. Sample Verification: Randomly verify some claims

  4. Rejected: Inconsistent quality, some bugs slip through

ADR-003: Model Tier Strategy

Context

Different AI models have different capabilities and costs. We need to decide how to allocate models to tasks.

Decision

Use two model tiers: - Opus for strategic/planning tasks (Riko, Senku) - Sonnet for execution/verification tasks (Loid, Lawliet, Alphonse)

Rationale

  1. Opus Strengths: Deep reasoning, complex analysis
  2. Valuable for unfamiliar codebase exploration
  3. Important for multi-step planning
  4. Worth the cost for strategic decisions

  5. Sonnet Strengths: Speed, clear task execution

  6. Sufficient for well-defined implementation
  7. Fast iterations for review cycles
  8. Cost-effective for command execution

  9. Cost Optimization: Not all tasks need maximum capability

  10. Running tests doesn't require deep reasoning
  11. Implementing a clear plan is straightforward
  12. Save expensive model for high-value decisions

Consequences

  • Positive: Cost efficiency, appropriate capability matching
  • Negative: Potential capability gaps, model switching overhead

Alternatives Considered

  1. All Opus: Use best model everywhere
  2. Rejected: Excessive cost for simple tasks

  3. All Sonnet: Use fast model everywhere

  4. Rejected: Insufficient for complex exploration/planning

  5. Dynamic Selection: Choose model per-task

  6. Rejected: Complexity without clear benefit over role-based

ADR-004: Hook-Based Lifecycle

Context

We need to inject behavior at specific points in the Claude Code lifecycle for validation and guidance.

Decision

Use hooks at lifecycle events: - UserPromptSubmit: Prompt refinement - PreToolUse: Operation validation - PostToolUse: Result verification - SessionStart: Context loading - Stop: Completion gates

Rationale

  1. Non-Invasive: Hooks augment without modifying core behavior
  2. Claude Code remains unchanged
  3. Plugin adds capabilities through hooks

  4. Targeted Intervention: Each hook has a specific purpose

  5. Validation happens before operations
  6. Verification happens after operations
  7. Gates happen before completion

  8. Extensible: New behaviors can be added via hooks

  9. No core changes needed
  10. Multiple hooks can run at same point

Consequences

  • Positive: Clean integration, extensible, targeted
  • Negative: Limited to supported hook points, execution overhead

Alternatives Considered

  1. Core Modification: Modify Claude Code directly
  2. Rejected: Not maintainable, version coupling

  3. Wrapper Approach: Intercept all operations

  4. Rejected: Too invasive, performance impact

ADR-005: State File Design

Context

Workflows span multiple agent interactions and need persistent state tracking.

Decision

Use YAML-frontmatter Markdown files in .claude/ directory: - Human readable - Machine parseable - Git-ignorable - Session-scoped

Rationale

  1. Dual-Purpose Format: YAML for structured data, Markdown for logs
  2. Frontmatter holds machine-parseable state
  3. Body holds human-readable history

  4. Local Storage: Files in .claude/ directory

  5. No external dependencies
  6. Easy to inspect and debug
  7. Can be safely deleted

  8. Session Scope: Files are ephemeral

  9. Not committed to git
  10. Fresh state each session
  11. No stale state issues

Consequences

  • Positive: Simple, debuggable, no dependencies
  • Negative: No persistence across sessions (by design), file I/O overhead

Alternatives Considered

  1. In-Memory State: Keep state in conversation context
  2. Rejected: Lost on context overflow, hard to debug

  3. Database Storage: Use SQLite or similar

  4. Rejected: Overkill for session-scoped state

ADR-006: Skill System Architecture

Context

Domain expertise needs to be encoded and shared across agents.

Decision

Create skill modules with: - Owner agent (maintains the skill) - Consumer agents (reference the skill) - Reference materials (detailed documentation) - Examples (worked scenarios)

Rationale

  1. Ownership Model: Clear responsibility for each skill
  2. One agent owns each skill
  3. Consumers reference but don't modify
  4. Prevents conflicting guidance

  5. Documentation as Code: Skills are markdown files

  6. Version controlled
  7. Easy to update
  8. Human readable

  9. Hierarchical Structure: SKILL.md + references + examples

  10. Quick reference in main file
  11. Deep dive in references
  12. Practical guidance in examples

Consequences

  • Positive: Clear ownership, extensible, documented
  • Negative: Potential inconsistency, maintenance burden

Alternatives Considered

  1. Inline Prompts: Embed all guidance in agent prompts
  2. Rejected: Duplication, hard to maintain

  3. Shared Knowledge Base: Single document for all agents

  4. Rejected: No ownership, conflicting guidance

ADR-007: Tool Access Control

Context

Agents need different capabilities for their roles. Unrestricted access enables shortcuts.

Decision

Restrict tools per agent role: - Only Loid can Write/Edit - Only Riko can WebSearch/WebFetch - Only Senku can TodoWrite

Rationale

  1. Prevents Shortcuts: Agents can't do others' jobs
  2. Explorer can't "just fix it" while exploring
  3. Verifier can't modify code to make tests pass
  4. Planner can't skip to implementation

  5. Clear Boundaries: Role is enforced by capability

  6. Not just guidance but actual restriction
  7. Agents don't need to resist temptation

  8. Audit Trail: Actions map to responsible agents

  9. File modifications came from Loid
  10. Web research came from Riko
  11. Plans came from Senku

Consequences

  • Positive: Clear boundaries, enforced specialization, accountability
  • Negative: Requires handoffs, potential delays

Alternatives Considered

  1. All Tools for All Agents: Trust agents to use appropriately
  2. Rejected: Temptation too strong, boundaries blur

  3. Request-Based Access: Agents request tools as needed

  4. Rejected: Overhead without clear benefit

ADR-008: Iteration and Failure Handling

Context

Verification may fail, requiring iteration. We need to handle this gracefully.

Decision

Implement iteration loops with maximum bounds: - Failed verification returns to implementation - Iteration counter tracks attempts - Maximum iterations prevent infinite loops - State tracks iteration history

Rationale

  1. Reality of Development: Not all implementations pass first try
  2. Tests may reveal bugs
  3. Review may find issues
  4. Iteration is normal

  5. Bounded Iteration: Maximum prevents runaway

  6. Default 10 iterations
  7. Configurable per task
  8. Fails cleanly at limit

  9. State Tracking: History enables debugging

  10. Each iteration logged
  11. Failure reasons recorded
  12. Pattern analysis possible

Consequences

  • Positive: Handles reality, bounded, debuggable
  • Negative: May hit limit on complex tasks, overhead

Alternatives Considered

  1. No Iteration: Fail on first error
  2. Rejected: Too strict, wastes progress

  3. Unbounded Iteration: Keep trying until success

  4. Rejected: Potential infinite loops, cost concerns

ADR-009: Graphify Knowledge Graph Integration

Context

Agents exploring large codebases rely heavily on Grep and Read, which require knowing what to search for. Structural questions — "what imports this module?", "what is the blast radius of changing X?", "which community does this file belong to?" — are expensive to answer with text search alone.

Decision

Integrate graphify as a read-only MCP server with access granted to Riko, Senku, and Lawliet only. Expose 7 graph query tools via the mcp__plugin_agent-flow_graphify__* prefix. Auto-detect graphify-out/graph.json at orchestration init via detect-graph-context.sh and write a graph: block into the state file.

Rationale

  1. One-writer invariant: Loid (writes code) and Alphonse (runs tests) must not query the graph. Loid's writes make the graph stale; Alphonse's verification cannot rely on graph freshness. Scoping graph access to read-only exploration/planning/review agents enforces this cleanly.
  2. MCP provides a clean integration boundary: Tools appear natively in agent tool lists — no prompt engineering required, no bash scripts in tool chains.
  3. Graph queries complement grep, don't replace it: Structural traversal (callers, communities, paths) belongs to graph tools; literal content and freshly-edited files belong to Grep/Read. The graphify-usage skill defines this boundary explicitly.

Consequences

  • Positive: Structural queries (blast-radius, module clustering, dependency mapping) become cheap; agents orient faster in unfamiliar codebases
  • Negative: Graph can become stale after edits within a session; requires a build step (/graphify) before first use

Alternatives Considered

  1. Embedding graph data in prompts: Rejected — graph.json is thousands of nodes; token cost is prohibitive
  2. Giving all agents graph access: Rejected — violates one-writer invariant; Loid querying a stale graph during implementation would produce misleading structural information

ADR-010: Personal Knowledge Base Integration

Context

Each orchestration session starts without memory of prior sessions, projects, or decisions. Users accumulate patterns, anti-patterns, and preferences across projects that are not available in any single repository.

Decision

Integrate a second MCP server for the user's personal knowledge base graph, using the same 7-tool surface as graphify but pointed at $AGENT_FLOW_PERSONAL_KB_PATH/graphify-out/graph.json. Apply the same agent scoping as graphify: Riko, Senku, Lawliet have access; Loid and Alphonse do not.

Rationale

  1. Separate graph avoids mixing concerns: Project structure (current codebase) and personal notes (cross-project memory) are distinct knowledge domains. Keeping them in separate graphs allows independent refresh cycles and avoids contaminating structural queries with personal annotations.
  2. Same access pattern reduces cognitive load: Agents already know the 7-tool graph API from graphify-usage. personal-kb-usage reuses the same tool names via the mcp__personal-kb__* prefix — only the query intent differs.
  3. Env-var config preserves portability: The path to the personal KB is user-specific and outside the project. An env var (AGENT_FLOW_PERSONAL_KB_PATH) keeps the plugin project-agnostic.

Consequences

  • Positive: Cross-project recall (prior decisions, anti-patterns, style preferences) surfaces automatically during exploration and planning; pattern reuse across sessions
  • Negative: Personal KB may be stale if the user hasn't re-run graphify on their notes recently; requires env var configuration to activate

Alternatives Considered

  1. Inline notes in prompts: Rejected — personal knowledge bases can be large; pasting them into task prompts is token-expensive and brittle
  2. Shared project graph: Rejected — mixing project structure with personal annotations makes both harder to query accurately; separate graphs keep each domain clean

Summary

These decisions collectively create a system that:

  1. Specializes agents for clear responsibilities
  2. Requires evidence for reliable verification
  3. Optimizes costs with model tiers
  4. Integrates cleanly through hooks
  5. Tracks state with simple files
  6. Shares expertise through skills
  7. Enforces boundaries with tool restrictions
  8. Handles failure with bounded iteration
  9. Queries structure through read-only graph MCP integration
  10. Recalls cross-project knowledge through personal KB MCP integration

The overall philosophy: build in constraints that prevent problems rather than detecting them after the fact.