2 added, 2 removed. Audit A to A.
---
name: architecture-reference
description: Reactive Agents framework architecture — layer stack, dependency graph, build order, and package structure. Use when planning work, understanding package relationships, or determining build dependencies.
user-invocable: false
---
# Architecture Reference — Reactive Agents
- > For complete framework orientation, see `NAVIGATION.md` (repo structure + file mapping) and `QUICK_START.md` (5-minute quickstart).
+ > For complete framework orientation, see `AGENTS.md` (root, sole entry point) and `wiki/Development/Repo-Navigation.md` (repo structure map + file mapping).
>
> **For architectural questions, prefer `claude-obsidian:wiki-query "<topic>"`** over reading individual files. The wiki has MOCs, decisions, mechanism validations, and design specs that surface in semantic queries. See [[wiki/Development/Wiki-Workflow|Wiki-Workflow.md]] for the canonical pattern.
## Wiki Resources for Architecture Lookup
| Question | Where to look |
|----------|---------------|
- | "What's the kernel structure?" | `wiki/Architecture/Specs/05-DESIGN-NORTH-STAR.md` §Cognitive Architecture |
+ | "What's the kernel structure?" | `wiki/Architecture/Design-Specs/2026-07-11-harness-north-star-architecture.md` (ratified kernel architecture) |
| "Why was decision X made?" | `wiki/Decisions/Decision Index.md` |
| "What package contains Y?" | `wiki/Packages/00 Package Index.md` |
| "Has mechanism Z been validated?" | `wiki/Experiments/M*.md` (or `wiki/Experiments/by-verdict.base`) |
| "What failure modes apply here?" | `wiki/Failure-Modes/by-severity.base` |
| "Current empirical state?" | `wiki/Architecture/Specs/04-PROJECT-STATE.md` |
| "Roadmap for v1.0?" | `wiki/Architecture/Specs/07-ROADMAP-v1.0.md` |
## Package Dependency Graph
**Zero internal deps:**
- `@reactive-agents/core` — EventBus, types, Agent/Task services
- `@reactive-agents/runtime-shim` — unified Bun/Node.js primitives; consumed by memory, tools, health, judge-server
**Depends on core only:**
- `@reactive-agents/llm-provider` → `core`
- `@reactive-agents/observability` → `core`
- `@reactive-agents/identity` → `core`
- `@reactive-agents/a2a` → `core`
- `@reactive-agents/interaction` → `core`
- `@reactive-agents/observe` → `core` — OpenInference/OTel span exporter
**Depends on core + llm-provider:**
- `@reactive-agents/memory` → `core`, `llm-provider`
- `@reactive-agents/tools` → `core`, `llm-provider`
- `@reactive-agents/guardrails` → `core`, `llm-provider`
- `@reactive-agents/cost` → `core`, `llm-provider`
- `@reactive-agents/eval` → `core`, `llm-provider`
- `@reactive-agents/prompts` → `core`, `llm-provider`
**Higher layers:**
- `@reactive-agents/reasoning` → `core`, `llm-provider`, `memory`, `tools`
- `@reactive-agents/verification` → `core`, `llm-provider`, `memory`
- `@reactive-agents/gateway` → `core`, `llm-provider`, `tools`
- `@reactive-agents/reactive-intelligence` → `core`, `llm-provider`
- `@reactive-agents/replay` → `core`, `trace`, `runtime` — deterministic trace replay
- `@reactive-agents/compose` → `core`, `runtime` — harness composition + 6 killswitches
**Planned (branch `feat/channels-package`, not merged to `main`):**
- `@reactive-agents/channels` → `core`, `gateway` (external triggers, session bridge, webhook adapter); consumed by `@reactive-agents/runtime` via **`.withChannels()`** and optional dynamic import at `start()`. Gateway **`channels` → `accessControl`** rename separates sender policy from chat/task mode. See `wiki/Research/Debriefs/2026-05-03-channels-phase1-development-debrief.md`.
**Facade (depends on ALL):**
- `@reactive-agents/runtime` → all packages (composes layers via `createRuntime()`)
- `reactive-agents` → `runtime` (public API re-export)
**Private (never published):**
- `@reactive-agents/testing` → `core`, `llm-provider`
- `@reactive-agents/benchmarks` → `runtime`
- `@reactive-agents/health` → `core`
## Build Order
Build runs in dependency order. Lower layers must build before higher layers.
```
Phase 1: core → llm-provider
Phase 2: memory, tools, guardrails, cost, identity, observability, interaction, prompts, eval, a2a (parallel)
Phase 3: reasoning, verification, orchestration, gateway, reactive-intelligence (parallel)
Phase 4: runtime → reactive-agents (facade)
Phase 5: testing, benchmarks, health, cli, docs (parallel)
```
## ExecutionEngine 10-Phase Loop
```
Phase 1: BOOTSTRAP MemoryService.bootstrap(agentId)
Phase 2: GUARDRAIL GuardrailService.checkInput(input)
Phase 3: STRATEGY-SELECT AdaptiveStrategy or config.defaultStrategy
Phase 4: THINK ReasoningService.execute() → kernel loop
Phase 5: ACT (synthetic — extracted from reasoning steps)
Phase 6: OBSERVE (synthetic — extracted from reasoning steps)
Phase 7: MEMORY-FLUSH MemoryExtractor + MemoryService.snapshot()
Phase 8: VERIFY VerificationService.verify(result) [optional]
Phase 9: AUDIT AuditService.log() [optional]
Phase 10: COMPLETE EventBus.publish("AgentCompleted") + DebriefSynthesizer
```
## Kernel Architecture (Reasoning)
All 6 strategies delegate to `runKernel(reactKernel, input, options)` in `packages/reasoning/src/kernel/`.
### Composable Phase Pipeline
```
makeKernel({ phases?: Phase[] })
↓
kernel-runner.ts: runKernel() loop
↓ per turn:
1. context-builder.ts — buildSystemPrompt, toProviderMessage, buildConversationMessages, buildToolSchemas (pure data, no LLM)
2. think.ts — LLM stream, FC parsing, fast-path, loop detection, oracle hard gate
3. guard.ts — Guard[] pipeline, checkToolCall(guards), defaultGuards[]
4. act.ts — MetaToolHandler registry, final-answer gate, tool dispatch
```
### Key Files
```
packages/reasoning/src/kernel/
kernel-state.ts — KernelState, Phase type, KernelContext, ThoughtKernel
kernel-runner.ts — the loop: runKernel() — DO NOT add per-turn logic here directly
kernel-hooks.ts — KernelHooks lifecycle hooks
react-kernel.ts — makeKernel() factory + reactKernel + executeReActKernel
phases/
context-builder.ts — pure data: builds what the LLM sees this turn
think.ts — LLM decision: stream, FC parsing, loop detection
guard.ts — Guard[] pipeline: is this tool call allowed?
act.ts — MetaToolHandler registry: what happens when tools run?
utils/
ics-coordinator.ts, reactive-observer.ts, loop-detector.ts
tool-utils.ts, tool-execution.ts, termination-oracle.ts, strategy-evaluator.ts
stream-parser.ts, context-utils.ts, quality-utils.ts, service-utils.ts, step-utils.ts
```
### Two Independent State Records
```
state.messages[] ← What the LLM sees (multi-turn FC conversation thread)
state.steps[] ← What systems observe (entropy, metrics, debrief)
```
Do NOT conflate these. Debugging LLM behavior → inspect `messages[]`. Debugging metrics/entropy → inspect `steps[]`.
### Extending the Kernel
- **New phase**: create `phases/<name>.ts`, insert into `makeKernel({ phases: [...] })`
- **New guard**: add `Guard` fn to `guard.ts`, add to `defaultGuards[]`
- **New inline meta-tool**: add one entry to `metaToolRegistry` in `act.ts`
- **Custom kernel**: `makeKernel({ phases: [myThink, act] })`
See `.agents/skills/kernel-extension/SKILL.md` for full patterns.
### Context Assembly — Canonical Path
- `context-manager.ts` — `ContextManager.build(state, input)` returns `{ systemPrompt, messages }` (pure, deterministic)
- `context-builder.ts` — assembles raw conversation messages (`buildConversationMessages`), tool schemas, system prompt base
- `think.ts` — invokes `buildGuidanceSection(state.pendingGuidance)` and appends `Guidance:` block to system prompt
- `context-engine.ts` — retains only `buildStaticContext`, `buildEnvironmentContext`, `buildRules`; all dynamic/scoring code removed
## MCP Client Architecture
Location: `packages/tools/src/mcp/mcp-client.ts`
### Two Docker Patterns
| Pattern | Examples | Behavior |
|---------|---------|----------|
| stdio MCP | GitHub MCP, filesystem | Container reads JSON-RPC from stdin |
| HTTP-only | mcp/context7 | Container starts HTTP server, ignores stdin |
Both handled transparently via auto-detection.
### Critical Rules
- **`docker rm -f <containerName>` is the ONLY reliable container stop.** `subprocess.kill()` leaves the container alive in the Docker daemon.
- **Two-phase container naming**: `rax-probe-<name>-<pid>` (initial stdio probe) → `rax-mcp-<name>-<pid>` (port-mapped HTTP if HTTP detected)
- **PID in name** prevents conflicts between concurrent agents running the same MCP server
- **Transport auto-inferred**: `command` → `"stdio"`, endpoint `/mcp` → `"streamable-http"`, other endpoint → `"sse"`
- `transport` field is optional in `MCPServerConfig` — auto-inferred at runtime
See `.agents/skills/mcp-integration/SKILL.md` for full patterns.
## Technology Stack
| Decision | Choice |
|----------|--------|
| Language | TypeScript (strict mode) |
| Runtime | Bun >= 1.1 |
| FP framework | Effect-TS (^3.10) |
| Database | bun:sqlite (WAL mode), FTS5, sqlite-vec |
| LLM providers | Anthropic, OpenAI, Ollama, Gemini, LiteLLM (40+) |
| Module system | ESM ("type": "module") |
| Build | tsup (ESM + DTS) |
| Test | bun:test |
| Versioning | Changesets (fixed group) |
## Quick Navigation
| What you need | Where to look |
|--------------|---------------|
| Full file-level system map | `wiki/Architecture/Framework-Architecture-Index.md` |
| Coding standards | `CODING_STANDARDS.md` |
| Effect-TS patterns | `.agents/skills/effect-ts-patterns/SKILL.md` |
| LLM API signatures | `.agents/skills/llm-api-contract/SKILL.md` |
| Memory/SQLite patterns | `.agents/skills/memory-patterns/SKILL.md` |
| Spec documents | `spec/docs/` |
| Build commands | `AGENTS.md` (Build & Test Cycle) and `README.md` (quickstart/dev commands) |
| Extending the kernel | `.agents/skills/kernel-extension/SKILL.md` |
| Debugging agent behavior | `.agents/skills/kernel-debug/SKILL.md` |
| Provider streaming patterns | `.agents/skills/provider-streaming/SKILL.md` |
| MCP client patterns | `.agents/skills/mcp-integration/SKILL.md` |
| Full feature workflow | `.agents/skills/reactive-feature-dev/SKILL.md` |