# v0.6.0 Documentation Pass Implementation Plan

> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

**Goal:** Refresh all public-facing documentation for the v0.6.0 release — fix stale numbers, finalize the changelog, add a project hierarchy map to AGENTS.md, and write two missing feature pages (Composable Kernel, Eval) plus expand the reasoning guide with the Structured Plan Engine.

**Architecture:** Pure documentation work — Markdown and MDX edits only. No TypeScript changes. Docs site is Starlight (Astro) at `apps/docs/`. Run `cd apps/docs && npx astro build` to verify at the end.

**Tech Stack:** Markdown, MDX, Starlight/Astro, Bun (for test count verification)

---

## Task 1: Verify Real Test Count

Before touching numbers, get the real count from the test runner.

**Files:**
- Read: CLAUDE.md (current stated count: 173 files)

**Step 1: Run test suite and capture file count**

```bash
cd /home/tylerbuell/Documents/AIProjects/reactive-agents-ts
bun test 2>&1 | tail -5
```

Expected: summary line like `1340 tests (N files)` or similar. Note the exact numbers — **use these in all subsequent tasks.**

**Step 2: Note the numbers**

Record: `TOTAL_TESTS=<number>` and `TOTAL_FILES=<number>` for use in Tasks 2–4.

---

## Task 2: Fix README.md Accuracy

**Files:**
- Modify: `README.md:9` — package count
- Modify: `README.md:279–298` — packages table (add missing `@reactive-agents/testing`)
- Modify: `README.md` — update any stale test/file counts if present

**Step 1: Update the headline description on line 9**

Find:
```
Type-safe from prompt to production. 18 packages.
```

Replace with:
```
Type-safe from prompt to production. 19 packages.
```

**Step 2: Add `@reactive-agents/testing` to the packages table**

The table ends at line ~298 with the gateway row. Add a new row after gateway:

```markdown
| [`@reactive-agents/testing`](packages/testing)             | Mock LLM/tool services, assertion helpers, test fixtures           |
```

**Step 3: Update the "vs. Building From Scratch" comparison card reference**

In the README, find the line:
```
You get 19 production-ready packages with 1100+ tests
```
Replace with:
```
You get 19 production-ready packages with 1,340+ tests
```

**Step 4: Verify README renders correctly**

```bash
# Quick sanity check - count occurrences of "19 packages"
grep -c "19 packages" README.md
```

Expected: at least 1 match.

**Step 5: Commit**

```bash
git add README.md
git commit -m "docs: update README for v0.6.0 — 19 packages, 1340 tests, add testing package"
```

---

## Task 3: Fix CLAUDE.md Project Status

**Files:**
- Modify: `CLAUDE.md:1–10` — project status header
- Modify: `CLAUDE.md` — build command test count

**Step 1: Update the project status header**

Find (line ~3):
```
**v0.5.7 + Composable Kernel Architecture.** 19 packages + 2 apps built, 1340 tests across 173 files.
```

Replace with the actual file count from Task 1, and update to v0.6.0:
```
**v0.6.0 — Gateway + Composable Kernel Architecture.** 19 packages + 2 apps built, 1340 tests across <TOTAL_FILES> files.
```

**Step 2: Update the build command comment**

Find:
```bash
bun test                 # Run all tests (1340 tests, 173 files)
```

Replace `173` with the verified file count from Task 1.

**Step 3: Commit**

```bash
git add CLAUDE.md
git commit -m "docs: update CLAUDE.md to v0.6.0 with verified test counts"
```

---

## Task 4: Finalize CHANGELOG.md

**Files:**
- Modify: `CHANGELOG.md:9` — replace `[Unreleased]` heading with versioned release

**Step 1: Merge the two Unreleased sections into one [0.6.0] release**

The CHANGELOG currently has two separate `## [Unreleased]` sections (one for Composable Kernel Architecture, one for Structured Plan Engine). Merge them under a single versioned heading.

Find the first heading (line 9):
```markdown
## [Unreleased] — Composable Kernel Architecture
```

Replace with:
```markdown
## [0.6.0] - 2026-03-04
```

Find the second heading (line ~38):
```markdown
## [Unreleased] — Structured Plan Engine
```

Replace with a level-3 heading to make it a subsection of 0.6.0:
```markdown
### Structured Plan Engine (`@reactive-agents/reasoning` + `@reactive-agents/memory`)
```

**Step 2: Add a summary line at the top of the 0.6.0 section**

Immediately after `## [0.6.0] - 2026-03-04`, insert:

```markdown

Gateway persistent agent harness, Composable Kernel Architecture (ThoughtKernel abstraction, KernelRunner, custom kernel registration), and Structured Plan Engine (type-safe JSON plans, 4-layer output pipeline, SQLite plan persistence). 19 packages, 1,340 tests.

```

**Step 3: Commit**

```bash
git add CHANGELOG.md
git commit -m "docs: finalize CHANGELOG for v0.6.0 release"
```

---

## Task 5: Update Landing Page Stats (`index.mdx`)

**Files:**
- Modify: `apps/docs/src/content/docs/index.mdx:29` — test count stat

**Step 1: Update the tests stat**

Find (line 29):
```mdx
    <span class="ra-stat-value">1000+</span>
    <span class="ra-stat-label">Tests</span>
```

Replace with:
```mdx
    <span class="ra-stat-value">1,340</span>
    <span class="ra-stat-label">Tests</span>
```

**Step 2: Update the "vs. Building From Scratch" card**

Find (line ~176):
```
You get 19 production-ready packages with 1100+ tests
```

Replace:
```
You get 19 production-ready packages with 1,340 tests
```

**Step 3: Add Composable Kernel as a feature card**

In the first `<CardGrid stagger>` block (after line 49), add a new card after the "5 Reasoning Strategies" card:

```mdx
  <Card title="Composable Kernel Architecture" icon="setting">
    Every reasoning strategy runs on a swappable ThoughtKernel abstraction.
    Register custom kernels via StrategyRegistry, or use the built-in ReAct
    kernel. KernelRunner handles the universal execution loop, tool call
    guards, and EventBus wiring — strategies stay focused on policy, not plumbing.
  </Card>
```

**Step 4: Commit**

```bash
git add apps/docs/src/content/docs/index.mdx
git commit -m "docs: update landing page stats and add Composable Kernel feature card"
```

---

## Task 6: Add Architecture Hierarchy Map to AGENTS.md

**Files:**
- Modify: `AGENTS.md` — insert new section after the opening title/intro

**Step 1: Insert the Architecture Quick Reference section**

After the first `---` separator (line 6 of AGENTS.md), insert the following new section before `## Golden Rules`:

```markdown
## Architecture Quick Reference

> Scan this before touching any package. Full dependency tree — read top to bottom for build order.

### Package Dependency Tree

```
Foundation (no reactive-agents deps)
├── @reactive-agents/core          — EventBus, AgentService, TaskService, all shared types
│
├── @reactive-agents/llm-provider  — LLMService, 6 provider adapters, streaming, tool calling
│
├── @reactive-agents/memory        — 4-layer memory (Working/Semantic/Episodic/Procedural), SQLite/FTS5/vec
│
├── @reactive-agents/reasoning     — 5 strategies + ThoughtKernel, KernelRunner, Structured Plan Engine
│   └── depends on: core, llm-provider, memory (PlanStoreService), tools (ToolService)
│
├── @reactive-agents/tools         — ToolService, ToolRegistry, 8 built-in tools, MCP client, sandbox
│   └── depends on: core, llm-provider
│
├── @reactive-agents/guardrails    — Injection/PII/toxicity detection, KillSwitch, BehavioralContracts
│   └── depends on: core, llm-provider
│
├── @reactive-agents/verification  — Semantic entropy, fact decomposition, NLI, hallucination detection
│   └── depends on: core, llm-provider
│
├── @reactive-agents/cost          — Complexity router, budget enforcer, semantic cache
│   └── depends on: core, llm-provider, memory
│
├── @reactive-agents/identity      — Ed25519 certs, RBAC, delegation, audit trail
│   └── depends on: core
│
├── @reactive-agents/observability — Distributed tracing, metrics, structured logging, MetricsCollector
│   └── depends on: core
│
├── @reactive-agents/interaction   — 5 autonomy modes, checkpoints, preference learning, approval gates
│   └── depends on: core
│
├── @reactive-agents/orchestration — Multi-agent workflows (sequential, parallel, pipeline, map-reduce)
│   └── depends on: core, llm-provider, tools
│
├── @reactive-agents/prompts       — Template engine, version control, tier-adaptive prompt variants
│   └── depends on: core, llm-provider
│
├── @reactive-agents/eval          — LLM-as-judge, EvalStore (SQLite), 5 scoring dimensions, regression checks
│   └── depends on: core, llm-provider
│
├── @reactive-agents/a2a           — Agent Cards, JSON-RPC 2.0, SSE streaming, A2A server/client
│   └── depends on: core
│
├── @reactive-agents/gateway       — Persistent harness: heartbeats, crons, webhooks, policy engine
│   └── depends on: core, llm-provider, tools
│
├── @reactive-agents/testing       — Mock LLMService, mock ToolService, mock EventBus, assertion helpers
│   └── depends on: core, llm-provider (dev only)
│
└── Facade & Runtime
    ├── @reactive-agents/runtime   — ExecutionEngine, ReactiveAgentBuilder, createRuntime()
    │   └── depends on: all packages above (optional via Effect Layers)
    └── reactive-agents            — Public API facade, re-exports builder + types
        └── depends on: runtime
```

### Per-Layer Quick Reference

| Package | First file to read | Key exports |
|---|---|---|
| `core` | `src/services/event-bus.ts` | `EventBus`, `AgentEvent`, `AgentId`, `TaskId` |
| `llm-provider` | `src/runtime.ts` | `LLMService`, `createLLMProviderLayer()` |
| `memory` | `src/runtime.ts` | `MemoryService`, `createMemoryLayer()` |
| `reasoning` | `src/strategy-registry.ts` | `ReasoningService`, `StrategyRegistry`, `ThoughtKernel` |
| `tools` | `src/services/tool-service.ts` | `ToolService`, `ToolDefinition`, `defineTool()` |
| `guardrails` | `src/services/guardrail-service.ts` | `GuardrailService`, `KillSwitchService` |
| `verification` | `src/services/verification-service.ts` | `VerificationService` |
| `cost` | `src/services/cost-service.ts` | `CostService` |
| `identity` | `src/services/identity-service.ts` | `IdentityService` |
| `observability` | `src/services/observability-service.ts` | `ObservabilityService`, `ThoughtTracer` |
| `gateway` | `src/services/gateway-service.ts` | `GatewayService`, `PolicyEngine`, `WebhookService` |
| `eval` | `src/services/eval-service.ts` | `EvalService`, `EvalStore`, `EvalSuite` |
| `runtime` | `src/builder.ts` | `ReactiveAgents`, `ReactiveAgentBuilder`, `createRuntime()` |

### Common Debugging Entry Points

| Symptom | Start reading |
|---|---|
| Agent not calling tools | `packages/reasoning/src/strategies/reactive.ts` → `packages/reasoning/src/kernel/kernel-runner.ts` |
| EventBus events not firing | `packages/core/src/services/event-bus.ts` → check `ManagedRuntime` is shared |
| LLM call fails silently | `packages/llm-provider/src/runtime.ts` → provider-specific file in `src/providers/` |
| Memory not persisting | `packages/memory/src/runtime.ts` → check `createMemoryLayer()` wiring |
| Plan-execute loops forever | `packages/reasoning/src/strategies/plan-execute.ts` → `isSatisfied()` + all-steps-completed guard |
| Gateway not starting | `packages/gateway/src/services/gateway-service.ts` → check `.withGateway()` in builder |
| Metrics dashboard missing | `packages/observability/src/services/observability-service.ts` → `MetricsCollectorLive` layer |
| Custom kernel not registering | `packages/reasoning/src/strategy-registry.ts` → `registerKernel()` call |

---
```

**Step 2: Commit**

```bash
git add AGENTS.md
git commit -m "docs: add Architecture Quick Reference hierarchy map to AGENTS.md"
```

---

## Task 7: New Page — Composable Kernel Architecture

**Files:**
- Create: `apps/docs/src/content/docs/concepts/composable-kernel.md`

**Step 1: Read existing kernel source files for accurate API details**

Before writing, read these files:
- `packages/reasoning/src/kernel/kernel-state.ts`
- `packages/reasoning/src/kernel/kernel-runner.ts`
- `packages/reasoning/src/strategy-registry.ts`

**Step 2: Create the page**

```markdown
---
title: Composable Kernel Architecture
description: ThoughtKernel abstraction, KernelRunner universal loop, and custom kernel registration via StrategyRegistry.
sidebar:
  order: 5
---

The Composable Kernel Architecture separates *how a reasoning step works* (the kernel) from *when and how many times it runs* (the strategy). This makes reasoning algorithms swappable, testable in isolation, and extensible without touching core framework code.

## The Three-Layer Model

```
Strategy (policy: when to run, how many times, what config)
    └── KernelRunner (universal loop: tool guard, EventBus wiring, state transitions)
            └── ThoughtKernel (algorithm: one step — thought → action → observation)
```

**Before this architecture:** Each strategy owned its own execution loop. `reactive.ts` was 905 lines. Tool call handling, EventBus wiring, and observation formatting were duplicated across 5 files.

**After:** `reactive.ts` is 128 lines. All strategies call `runKernel(reactKernel, ...)`. Tool handling lives once in `tool-execution.ts`.

## ThoughtKernel

A `ThoughtKernel` is the contract for a single reasoning step:

```typescript
import type { ThoughtKernel, KernelState } from "@reactive-agents/reasoning";

const myKernel: ThoughtKernel = {
  name: "my-kernel",

  step: (state: KernelState) =>
    Effect.gen(function* () {
      // Receive current state, return next state
      // state.context — full conversation context string
      // state.steps   — all prior steps (thought/action/observation)
      // state.status  — "thinking" | "acting" | "done" | "error"

      const thought = yield* thinkAbout(state.context);

      if (shouldActOn(thought)) {
        return { ...state, status: "acting", pendingAction: thought };
      }

      return { ...state, status: "done", finalAnswer: thought };
    }),
};
```

`KernelState` is **immutable** — each step returns a new state. This makes reasoning chains replayable and serializable for collective learning.

## KernelRunner

`runKernel()` is the universal execution loop. It handles:

- **Iteration limit** — stops at `maxIterations`
- **Tool call guard** — detects bare `tool_name({...})` in `FINAL ANSWER` text and executes the tool instead of returning raw output
- **KernelHooks** — wires `onThought`, `onAction`, `onObservation`, `onDone`, `onError` to EventBus automatically
- **State transitions** — drives the kernel's `step()` function until `status === "done"` or `status === "error"`

```typescript
import { runKernel, reactKernel } from "@reactive-agents/reasoning";

// All built-in strategies delegate here:
const result = yield* runKernel(reactKernel, {
  state: initialKernelState,
  tools,
  maxIterations: config.maxIterations ?? 10,
  hooks: buildKernelHooks(eventBus),
});
```

## KernelHooks

`KernelHooks` is the single source of truth for tool metrics. It wires EventBus events so the observability dashboard receives `ToolCallCompleted` exactly once per tool call:

```typescript
// Built automatically — you don't call this directly unless writing a custom runner
const hooks = buildKernelHooks(eventBus, { agentId, sessionId, taskId });
```

Events emitted: `ToolCallCompleted`, `ReasoningStepCompleted`.

## Registering a Custom Kernel

Use `StrategyRegistry` to register and use your own kernel:

```typescript
import { StrategyRegistry, type ThoughtKernel } from "@reactive-agents/reasoning";
import { Effect } from "effect";

// 1. Define your kernel
const chainOfThoughtKernel: ThoughtKernel = {
  name: "chain-of-thought",
  step: (state) =>
    Effect.gen(function* () {
      // Step-by-step reasoning without tool dispatch
      const steps = yield* generateChainOfThought(state.context);
      const finalStep = steps[steps.length - 1];
      return { ...state, status: "done", finalAnswer: finalStep };
    }),
};

// 2. Register it
StrategyRegistry.registerKernel("chain-of-thought", chainOfThoughtKernel);

// 3. Use it in a custom strategy
StrategyRegistry.register("cot", (input, services) =>
  Effect.gen(function* () {
    const kernel = StrategyRegistry.getKernel("chain-of-thought");
    return yield* runKernel(kernel, { state: initialState(input), ... });
  }),
);

// 4. Select it via the builder
const agent = await ReactiveAgents.create()
  .withProvider("anthropic")
  .withReasoning({ defaultStrategy: "cot" })
  .build();
```

**Available built-in kernels:**

| Kernel | Description |
|---|---|
| `reactKernel` | ReAct (Thought → Action → Observation loop). Default for all 5 strategies. |

List registered kernels at runtime: `StrategyRegistry.listKernels()`.

## Why This Matters

| Before | After |
|---|---|
| `reactive.ts` — 905 lines | `reactive.ts` — 128 lines |
| Tool execution duplicated ×5 | `tool-execution.ts` — shared once |
| EventBus wiring scattered | `kernel-hooks.ts` — single source |
| Double `ToolCallCompleted` metrics | Fixed — KernelHooks is the only publisher |
| Hard to add new strategy | Implement one `ThoughtKernel.step()` function |
```

**Step 3: Verify the file was created**

```bash
ls apps/docs/src/content/docs/concepts/
```

Expected: `composable-kernel.md` appears in the list.

**Step 4: Commit**

```bash
git add apps/docs/src/content/docs/concepts/composable-kernel.md
git commit -m "docs: add Composable Kernel Architecture page"
```

---

## Task 8: New Page — Eval Framework

**Files:**
- Create: `apps/docs/src/content/docs/features/eval.md`

**Step 1: Read the eval package index to confirm exports**

```bash
cat packages/eval/src/index.ts
```

**Step 2: Create the page**

```markdown
---
title: Evaluation Framework
description: LLM-as-judge scoring, EvalStore persistence, regression detection, and custom dimensions via @reactive-agents/eval.
sidebar:
  order: 10
---

The eval package provides a structured, LLM-as-judge evaluation framework for measuring agent quality across multiple dimensions. Run evaluations offline, store results in SQLite, and detect regressions before shipping changes.

## Quick Start

```typescript
import { EvalService, EvalStore } from "@reactive-agents/eval";
import { ReactiveAgents } from "reactive-agents";
import { Effect } from "effect";

// Define a test suite
const suite = {
  id: "research-agent-v1",
  name: "Research Agent Evaluation",
  description: "Tests research quality and factual accuracy",
  cases: [
    {
      id: "case-1",
      name: "Capital city lookup",
      input: "What is the capital of France?",
      expectedOutput: "Paris",
      expectedBehavior: { maxSteps: 3, maxCost: 0.01 },
      tags: ["factual", "geography"],
    },
    {
      id: "case-2",
      name: "Multi-step research",
      input: "Summarize the key differences between TCP and UDP",
      expectedBehavior: { maxSteps: 5 },
      tags: ["reasoning", "technical"],
    },
  ],
  dimensions: ["accuracy", "relevance", "completeness", "safety"],
};

// Run the suite against your agent
const program = Effect.gen(function* () {
  const evalService = yield* EvalService;

  const run = yield* evalService.runSuite(suite, "my-agent-v1");

  console.log(`Score: ${run.summary.overallScore.toFixed(2)}`);
  console.log(`Pass rate: ${run.summary.passRate * 100}%`);
  console.log(`Duration: ${run.summary.durationMs}ms`);
});
```

## Scoring Dimensions

Each case is scored across one or more dimensions using an LLM judge:

| Dimension | What It Measures | Scoring |
|---|---|---|
| `accuracy` | Factual correctness against `expectedOutput` | 0.0–1.0 |
| `relevance` | How well the response addresses the input | 0.0–1.0 |
| `completeness` | Whether all parts of the request were addressed | 0.0–1.0 |
| `safety` | Absence of harmful, biased, or inappropriate content | 0.0–1.0 |
| `cost-efficiency` | Token usage relative to task complexity | 0.0–1.0 |

A case **passes** when its overall score meets the configured threshold (default: `0.7`).

## EvalCase Schema

```typescript
type EvalCase = {
  id: string;
  name: string;
  input: string;
  expectedOutput?: string;          // Ground truth for accuracy scoring
  expectedBehavior?: {
    shouldUseTool?: string;         // Tool name that should be called
    shouldAskUser?: boolean;        // Whether agent should request clarification
    maxSteps?: number;              // Budget for reasoning steps
    maxCost?: number;               // Budget in USD
  };
  tags?: string[];                  // For filtering and grouping
};
```

## EvalStore — Persistent Results

Results are stored in SQLite via `EvalStore`. Access history and run comparisons:

```typescript
const program = Effect.gen(function* () {
  const evalService = yield* EvalService;

  // Compare two runs for regression detection
  const [runA, runB] = yield* Effect.all([
    evalService.getHistory("research-agent-v1", { limit: 1 }),
    evalService.runSuite(suite, "my-agent-v2"),
  ]);

  const regression = yield* evalService.checkRegression(runB, runA[0], 0.05);

  if (regression.hasRegression) {
    console.error("Regression detected:", regression.details);
    process.exit(1);
  }

  // See what improved vs regressed
  const comparison = yield* evalService.compare(runB, runA[0]);
  console.log("Improved:", comparison.improved);
  console.log("Regressed:", comparison.regressed);
});
```

## Configuration

```typescript
import { DEFAULT_EVAL_CONFIG } from "@reactive-agents/eval";

const config = {
  ...DEFAULT_EVAL_CONFIG,
  parallelism: 3,       // Run N cases in parallel (default: 1)
  timeoutMs: 30_000,    // Per-case timeout (default: 60s)
  retries: 2,           // Retry failed cases (default: 0)
  passThreshold: 0.8,   // Minimum score to pass (default: 0.7)
};

const run = yield* evalService.runSuite(suite, "my-agent", config);
```

## Integration with Builder

Enable eval in your agent's build pipeline:

```typescript
import { EvalServiceLive } from "@reactive-agents/eval";
import { Effect } from "effect";

// EvalService runs outside the agent — it evaluates the agent's outputs
// Typical pattern: run agent, capture output, score it

const agent = await ReactiveAgents.create()
  .withProvider("anthropic")
  .withReasoning()
  .withTools()
  .build();

// Run eval cases
for (const evalCase of suite.cases) {
  const agentResult = await agent.run(evalCase.input);

  await Effect.runPromise(
    Effect.gen(function* () {
      const evalService = yield* EvalService;
      yield* evalService.runCase(
        evalCase,
        "my-agent-v1",
        suite.dimensions,
        agentResult.output,
        {
          latencyMs: agentResult.metadata.duration,
          tokensUsed: agentResult.metadata.tokensUsed,
          stepsExecuted: agentResult.metadata.stepsCount,
        },
      );
    }).pipe(Effect.provide(EvalServiceLive)),
  );
}
```

## Running Evals in CI

A typical CI eval workflow:

```bash
# Run evaluation suite and fail if regression detected
bun run eval:run --suite research-agent --baseline latest
```

Or with the `rax` CLI:

```bash
rax eval --suite ./evals/research-suite.ts --provider anthropic
```
```

**Step 3: Commit**

```bash
git add apps/docs/src/content/docs/features/eval.md
git commit -m "docs: add Evaluation Framework feature page"
```

---

## Task 9: Expand Reasoning Guide — Structured Plan Engine

**Files:**
- Modify: `apps/docs/src/content/docs/guides/reasoning.md` — append new section at the end

**Step 1: Read the end of the current reasoning.md to find the right append point**

```bash
tail -30 apps/docs/src/content/docs/guides/reasoning.md
```

**Step 2: Append the Structured Plan Engine section**

At the end of `reasoning.md`, append:

````markdown

---

## Structured Plan Engine

The Plan-Execute strategy was rewritten in v0.6.0 with a **type-safe structured plan engine** that replaces fragile text-parsed numbered lists with JSON schemas, SQLite persistence, and a 4-layer output pipeline.

### How It Works

```
1. Plan Generation   — LLM generates a structured JSON plan (typed schema, not free text)
2. Structured Output — 4-layer pipeline: prompt → JSON repair → schema validation → retry
3. Step Execution    — Hybrid dispatch: tool_call (direct) or analysis (scoped ReAct kernel)
4. Cross-Step Data   — {{from_step:sN}} interpolation passes outputs between steps
5. Reflection        — Graduated retry → patch → replan on failure
6. Persistence       — Plans stored in SQLite via PlanStoreService
```

### Plan Schema

Plans are fully typed. The LLM must produce valid JSON — the structured output pipeline repairs and validates before executing:

```typescript
type Plan = {
  goal: string;
  steps: PlanStep[];
};

type PlanStep = {
  id: string;           // Short deterministic ID: "s1", "s2", ...
  description: string;  // Human-readable step goal
  type: "tool_call" | "analysis" | "composite";
  toolName?: string;    // Required when type === "tool_call"
  toolArgs?: Record<string, unknown>;  // Supports {{from_step:sN}} references
  dependsOn?: string[]; // Step IDs that must complete first
};
```

### Cross-Step References

Steps can reference outputs from earlier steps using `{{from_step:sN}}` interpolation:

```typescript
// Example: write a summary based on a web search result
const plan = {
  goal: "Research and summarize AI news",
  steps: [
    {
      id: "s1",
      description: "Search for AI news this week",
      type: "tool_call",
      toolName: "web-search",
      toolArgs: { query: "AI news March 2026" },
    },
    {
      id: "s2",
      description: "Summarize the search results",
      type: "analysis",
      toolArgs: { context: "{{from_step:s1}}" },  // ← Interpolated at runtime
      dependsOn: ["s1"],
    },
  ],
};
```

Self-references are guarded at runtime — a step cannot reference its own output.

### The 4-Layer Output Pipeline

The structured output pipeline ensures reliable JSON even from models that don't support native JSON mode:

```
Layer 1 — High-signal prompting     Tier-adaptive prompt with schema example and rules
Layer 2 — JSON repair               extractJsonBlock() + repairJson() handles markdown
                                    fences, trailing commas, single quotes, truncated JSON
Layer 3 — Schema validation         Effect Schema.decode() validates against PlanSchema
Layer 4 — Retry with feedback       On failure, re-prompts with the validation error message
```

### Configuration

```typescript
const agent = await ReactiveAgents.create()
  .withProvider("anthropic")
  .withReasoning({
    defaultStrategy: "plan-execute",
    planExecuteConfig: {
      planMode: "linear",     // "linear" (default) or "dag" (parallel steps)
      stepRetries: 2,         // Retry failed steps before patching
      patchStrategy: "replan", // "patch" (fix step) or "replan" (regenerate plan)
    },
  })
  .withMemory("1")            // Enables PlanStoreService for plan persistence
  .build();
```

### Plan Persistence

When memory is enabled, plans are stored in SQLite:

```typescript
// Plans stored in: packages/memory/src/db/plans + plan_steps tables
// Accessible via PlanStoreService (internal to the memory layer)
// Useful for: resuming interrupted tasks, debugging, auditing plan quality
```

### Error Recovery

The plan engine uses graduated recovery:

| Situation | Recovery Strategy |
|---|---|
| Step fails, retries remain | Retry the same step |
| Step fails, no retries | Patch: ask LLM to fix just that step |
| Patch fails | Replan: regenerate entire plan with context of what failed |
| All steps completed | Treat as satisfied regardless of reflection text |

This prevents the false-negative refinement loops that caused duplicate message sends in earlier versions.
````

**Step 3: Commit**

```bash
git add apps/docs/src/content/docs/guides/reasoning.md
git commit -m "docs: add Structured Plan Engine section to reasoning guide"
```

---

## Task 10: Verify Docs Build

**Step 1: Build the docs site**

```bash
cd apps/docs && npx astro build
```

Expected: Build completes, outputs `dist/`, no errors. Page count should be ~34 (was 31, +3 new pages).

**Step 2: Check for broken links or missing references**

Scan build output for warnings. If any `.md` file in the sidebar generates a 404, fix the filename or frontmatter.

**Step 3: Final git status check**

```bash
cd /home/tylerbuell/Documents/AIProjects/reactive-agents-ts
git log --oneline -10
```

Expected: 9 new commits (Tasks 2–9 each have one commit).

**Step 4: Commit any remaining cleanup**

If anything was missed or the build revealed issues, fix and commit:

```bash
git add -p  # Review changes interactively
git commit -m "docs: fix build issues from v0.6.0 documentation pass"
```
