Architecture

July 26, 2026 · View on GitHub

Back to README

OpenCastle compiles one definition of your project's AI assistant setup — instructions, agents, skills, MCP servers — into the native format of every assistant your team uses, and reports when the generated files drift from source.

An experimental convoy engine builds on the same content to run long multi-step work in dependency order. The compiler does not depend on it.


System Overview

graph TB
    TL["🏰 Team Lead<br/><sub>Premium tier</sub><br/><sub>Analyze → Decompose → Delegate → Verify</sub>"]

    subgraph Premium["Premium"]
        ARCH[Architect]
        SEC[Security Expert]
    end

    subgraph Standard["Standard"]
        DEV[Developer]
        UI[UI/UX Expert]
        DATA[Data Engineer]
        CE[Content Engineer]
        TEST[Testing Expert]
        PERF[Performance Expert]
        OPS[DevOps &amp; Release]
        RES[Researcher]
    end

    subgraph Economy["Economy"]
        WRITE[Writer]
        REV[Reviewer]
    end

    TL --> Premium
    TL --> Standard
    TL --> Economy

    KB["📚 Instructions · Skills · Workflows · Prompts"]
    TL -.-> KB

Capability Tiers

Agents declare a tier rather than a model. Which model serves a tier is the assistant's decision — it knows which models the account can reach, what they cost today, and which have been retired.

TierFor
PremiumOrchestration, architecture, security review — the hardest reasoning
StandardFeature work, schemas, UI, tests — the bulk of the work
EconomyReview passes, docs, copy — high volume, low ambiguity

Defined once in src/cli/tiers.ts; agent frontmatter carries tier: and a test asserts no shipped file names a model.


Execution Modes

The Team Lead operates in two modes depending on task complexity:

ModeWhenMechanismParallelism
CompactScore ≤2, single subtaskInline runSubagent callsSequential
ConvoyScore 3+ or multi-task.convoy.yml spec → ConvoyEngineParallel (DAG-based)

Compact mode handles small, focused tasks synchronously within a single conversation. The Team Lead delegates to one specialist at a time, reviews the output, and moves on.

Convoy mode is the structured execution engine for complex, multi-step work. See Convoy Architecture below.


Agents

13 specialist agents, each with a defined scope, output contract, and file partition boundary.

AgentDomain
Team LeadOrchestration — never writes code
ArchitectStrategic architecture decisions, ADRs, system design
Security ExpertAuth, authorization, access policies, security headers, input validation
DeveloperPages, components, routing, API routes and their contracts, server logic
UI/UX ExpertAccessible, consistent UI components and design system
Data EngineerMigrations, access policies, query performance, ETL pipelines, imports
Content EngineerCMS schemas, content types, queries
Testing ExpertE2E tests, integration tests, browser validation
Performance ExpertFrontend, backend, and build performance
DevOps & ReleaseDeployments, CI/CD, cron jobs, pre-release verification, changelogs
ResearcherDeep codebase exploration, pattern discovery, git archaeology
WriterUI copy, error messages, docs, roadmaps, meta tags, structured data
ReviewerFast validation after every delegation

Knowledge System

src/orchestrator/
├── agents/          # Agent definitions (.agent.md)
├── skills/          # Reusable domain expertise
├── instructions/    # Cross-cutting guidelines
├── agent-workflows/ # Multi-step workflow templates
├── prompts/         # Prompt templates
├── plugins/         # IDE marketplace plugins
└── customizations/  # Project-specific overrides

Skills are on-demand knowledge modules loaded by agents when entering a specific domain. Examples: react-development, security-hardening, testing-workflow, observability-logging.


Adapters

OpenCastle generates agent definitions for multiple IDE formats via pluggable adapters:

AdapterIDE
vscodeGitHub Copilot (VS Code chat participants)
cursorCursor AI
claude-codeClaude Code
opencodeOpenCode
windsurfWindsurf
codexCodex CLI
antigravityAntigravity

Convoys can mix adapters in a single run — each task is assigned to an adapter independently.


Workflow Templates

TemplateFlow
feature-implementationDB → Query → UI → Tests
bug-fixTriage → RCA → Fix → Verify
data-pipelineScrape → Convert → Enrich → Import
security-auditScope → Automate → Review → Remediate
performance-optimizationMeasure → Analyze → Optimize → Verify
schema-changesCMS model modifications and queries
database-migrationMigrations, access policies, rollback
refactoringSafe refactoring with behavior preservation

Quality Gates

GateMethod
DeterministicLint, type-check, unit tests, build verification
Fast reviewMandatory single-reviewer sub-agent after every delegation, with automatic retry and escalation
Panel review3 isolated reviewer sub-agents, 2/3 majority wins (high-stakes or escalation)
Structured disputesFormal dispute records when automated resolution is exhausted — packages both perspectives for human decision
Browser testingChrome DevTools MCP at project-defined responsive breakpoints
Secret scanPost-execution scan for leaked credentials (API keys, tokens, passwords)
Blast radiusDetects risky file patterns (migrations, auth changes, RLS policies)
TDD gateNew source files must have corresponding test files

Convoy Architecture

A convoy is the structured execution engine for multi-agent workflows. It provides deterministic, crash-recoverable orchestration with file isolation, DAG-based scheduling, and layered validation.

Lifecycle

graph LR
    S[".convoy.yml"] --> V["Validate & Build DAG"]
    V --> I["Initialize Engine"]
    I --> E["Execute Phases"]
    E --> G["Post-Convoy Gates"]
    G --> D["Deliver"]

    E -->|crash| R["Resume from checkpoint"]
    R --> E
  1. Spec — A .convoy.yml file defines tasks, agents, file partitions, dependencies, and orchestration rules
  2. DAG validation — Tasks form a directed acyclic graph; phase assignment is computed from dependencies
  3. Initialization — Engine creates convoy record in SQLite (.opencastle/convoy.db), starts health monitor, configures event emitter
  4. Execution — Tasks run phase-by-phase; within a phase, up to concurrency: N tasks run in parallel
  5. Completion — Post-convoy gates run, convoy guard validates logs, worktrees are cleaned up
  6. Recovery — On crash, resume(convoyId) replays from the last checkpoint using SQLite + NDJSON recovery

Per-Task Execution

Each task follows this flow:

Check dependencies → Resolve upstream outputs → Build isolation preamble
→ Assign to adapter → Execute with timeout → Run post-execution gates
→ Validate output contract → Run review → Update status → Emit events

Failure handling:

  • Max retries exceeded → Dead Letter Queue (DLQ)
  • Gate failure → gate-failed status, optional gate retry
  • Review block → review-blocked status, can escalate to dispute
  • Cascade → on_failure: stop skips all pending tasks; on_failure: continue skips only dependents

File Isolation

Each task operates in an isolated git worktree confined to its file partition:

  • Tasks declare files: [...] (directories or specific files)
  • Engine validates no two concurrent tasks have overlapping partitions
  • Post-execution scan detects partition violations
  • Isolation preamble warns the agent: "You may ONLY read and modify files within this partition"

This enables safe parallel execution and deterministic merging of results.

Effort Scaling

Task complexity (Fibonacci 1–13) maps to execution profiles:

ComplexityTierTimeoutMax RetriesReview Level
1–2Economy5–10m1Auto-pass
3Standard15m2Fast
5Standard20m2Fast
8Standard30m2Fast
13Premium45m3Panel

Agent Expertise & Circuit Breakers

The engine tracks agent performance over time:

  • Strong/weak areas recorded per agent based on task success rates
  • Circuit breaker opens after repeated failures (default: 3), preventing new task assignment
  • After cooldown, a probe task tests recovery; success closes the circuit
  • Optional fallback agent handles work while the primary is in cooldown
  • Weak-area avoidance skips agents for files they've historically struggled with

Event System

39 canonical event types provide full observability:

CategoryEvents
Convoy lifecycleconvoy_started, convoy_finished, convoy_failed, convoy_guard
Task lifecycletask_started, task_done, task_failed, task_skipped, task_retried
Review & disputesreview_verdict, dispute_opened, dlq_entry_created
Safetysecret_leak_prevented, drift_detected, merge_conflict_detected
Infrastructurecircuit_breaker_tripped, worker_killed

Events are dual-written to SQLite (queryable, durable) and NDJSON (append-only, crash-safe via fsyncSync). Secret scanning runs on every NDJSON write.

Contracts & Output Validation

Each agent type has a defined output contract with required fields:

  • developerfiles_changed[], tests_added[], summary
  • security-expertfindings[], severity, files_reviewed[], summary
  • After task completion, output is validated against the contract schema
  • Invalid output triggers a retry with a corrected prompt

Artifacts

Tasks can write artifacts to .opencastle/artifacts/{convoy-id}/{task-id}/:

  • Named files with metadata (type, summary, size)
  • Downstream tasks can read upstream artifacts via dependency resolution
  • Pruned by age as later convoys run

Observability

All execution is logged to .opencastle/logs/events.ndjson using the opencastle log CLI:

Record typeWho logsWhen
sessionEvery agentEvery session (hard gate)
delegationTeam LeadAfter each delegation
reviewTeam LeadAfter each fast review
panelPanel runnerAfter each panel vote
disputeTeam LeadAfter each dispute

The dashboard provides a web UI for exploring convoy runs, task timelines, agent performance, and event streams.


CLI

CommandPurpose
(none)Project status: targets, drift, and the next command to run
initSet up the project from detected stack and existing assistant config
syncRecompile every configured target from source
add <pack>Adopt an integration and recompile
doctorDiagnose configuration problems
removeRemove OpenCastle, keeping or deleting generated files
convoyExperimental: plan and run multi-step work

log and lesson also exist but are invoked by agents from generated instructions rather than by people, so they are not listed in help.