# Migration Guide: 0.15 → 0.17

**Released in:** sprint-616 (Vague 1.B promotions)

---

## Summary of breaking changes

| Change | 0.15 | 0.17 |
|--------|------|------|
| `OODAAgentDeps.llm` | Not available | Optional (required in 1.0) |
| `createOODAAgent` `deps` param | Not available | Optional, strict validation |
| Messaging adapters | Internal to CC | Exported from SDK |
| `AgentRegistryPort` | Not available | Exported, 2 adapters |
| `HITLPort` state machine | Internal | Exported, 2 adapters |
| Tier templates | Forge-internal | `createSimpleAgent`, `createReasoningAgent`, `createComplexAgent` |
| `AgentFactory` | Forge-internal | `createAgentFromConfig` in SDK |
| `SkillRegistryBuilder` | Forge-internal | `buildSkills`, `buildSkillRegistry` in SDK |
| `EconomyRouter` | Sprint D | Fully exported |
| Event auth (ADR-ECO-017) | Separate | `signEvent`, `verifyEvent`, `InMemoryNonceStore` |

---

## 1. Inject `deps.llm` (strict mode — will throw in 1.0)

SDK 0.17 introduces `OODAAgentDeps` — the BYOM dependency injection contract for OODA agents. `deps` is optional in 0.17 but **required in 1.0**. Strict mode (default) already enforces `deps.llm` at boot.

```typescript
// Before (0.15 — no deps injection)
createOODAAgent({
  agentId: "my-agent",
  executionMode: "live",
  db,
  logger,
  phases: { ... },
});

// After (0.17 — inject deps)
import { LiteLLMAdapter } from "@vauban-org/agent-sdk";

createOODAAgent({
  agentId: "my-agent",
  executionMode: "live",
  db,
  logger,
  deps: {
    llm: new LiteLLMAdapter({ baseUrl: process.env["LITELLM_URL"]! }),
  },
  phases: { ... },
});
```

### `SDK_STRICT_DEPS` env control

| Value | Behavior |
|-------|----------|
| absent (default) | Strict — throws `MissingDependencyError` if `deps.llm` missing |
| `"true"` | Strict — same as absent |
| `"false"` | Legacy — logs `console.warn`, does NOT throw |

To temporarily suppress errors during migration (not recommended for production):

```bash
SDK_STRICT_DEPS=false node dist/my-agent.js
```

---

## 2. `ctx.deps` in phase functions

Phases now receive `ctx.deps` with all injected ports:

```typescript
{
  type: "decision",
  fn: async (input, ctx) => {
    // Direct LLM access from context — no hardcoded model
    const response = await ctx.deps.llm?.complete({
      messages: [{ role: "user", content: "Decide: ..." }],
    });
    return response?.content ?? "fallback";
  },
}
```

---

## 3. New: OODAAgentDeps interface

```typescript
import type {
  OODAAgentDeps,
  LLMProviderPort,
  EventBusPort,
  HITLPort,
  MessagingChannelPort,
  BrainPort,
  AgentRegistryPort,
} from "@vauban-org/agent-sdk";

// OODAAgentDeps (internal — used by createOODAAgent)
interface OODAAgentDeps {
  llm?: LLMProviderPort;
  eventBus?: EventBusPort;
  hitl?: HITLPort;
  messaging?: MessagingChannelPort;
  memory?: BrainPort;
  registry?: AgentRegistryPort;
}
```

---

## 4. New: Tier templates (Vague 1.B.7)

Replace manual `createOODAAgent` boilerplate with typed templates:

```typescript
// Before (0.15 — raw createOODAAgent)
import { createOODAAgent } from "@vauban-org/agent-sdk";
const agent = await createOODAAgent({ agentId, phases: { ... } });

// After (0.17 — tier template)
import { createSimpleAgent } from "@vauban-org/agent-sdk";
const agent = await createSimpleAgent(deps, {
  agentId: "kpi-monitor",
  intervalMs: 60_000,
  observe, orient, decide, act, feedback,
});
```

See [templates.md](../templates.md) for all three tiers.

---

## 5. New: AgentFactory (Vague 1.B.2)

Use `createAgentFromConfig` for full OODA wiring with auto-registration support:

```typescript
import { createAgentFromConfig } from "@vauban-org/agent-sdk";
```

---

## 6. New: SkillRegistryBuilder (Vague 1.B.3)

Replace ad-hoc `buildXxxSkills()` functions with the unified builder:

```typescript
// Before (0.15 — custom per-agent function)
function buildRevenueSkills(deps) { ... }

// After (0.17 — SDK builder)
import { buildSkills } from "@vauban-org/agent-sdk";

const { registry } = buildSkills({
  agentId: "forge-revenue",
  deps: { brain: deps.brain, logger: deps.logger },
  domain: "revenue",
  extras: [{ name: "http-fetch", skill: httpFetch }],
});
```

---

## 7. New messaging channel adapters

```typescript
import {
  ConsoleChannel,
  TelegramChannel, TelegramRateLimitError,
  SlackChannel,
  DiscordChannel,
  MCPChannel,
} from "@vauban-org/agent-sdk";
```

---

## 8. New: Event authentication (ADR-ECO-017)

```typescript
import {
  signEvent,
  verifyEvent,
  InMemoryNonceStore,
  canonicalEventString,
  InvalidSignatureError,
  ClockSkewError,
  ReplayDetectedError,
  UnknownSourceError,
} from "@vauban-org/agent-sdk";
```

---

## 9. New error classes

```typescript
import {
  MissingDependencyError,  // deps.llm absent in strict mode
  DepsValidationError,     // deps object structurally invalid
} from "@vauban-org/agent-sdk";
```

---

## Migration checklist

- [ ] Add `deps: { llm: new LiteLLMAdapter(...) }` to every `createOODAAgent()` call
- [ ] Update phases that hardcode model calls to use `ctx.deps.llm` instead
- [ ] Replace `buildXxxSkills()` functions with `buildSkills({ agentId, deps, domain, extras })`
- [ ] Replace raw `createOODAAgent` boilerplate with tier templates where applicable
- [ ] Remove `SDK_STRICT_DEPS=false` env overrides once migration is complete
- [ ] Run `pnpm build && pnpm test` — all boot-validation tests must pass
- [ ] Sign cross-product events with `signEvent()` from the SDK auth module

---

## Timeline

| Version | Status |
|---------|--------|
| 0.15 | Stable — no `deps` injection |
| 0.17 | Current — `deps` optional, strict mode enforced by default |
| 1.0 | Planned — `deps.llm` required, no `SDK_STRICT_DEPS=false` escape hatch |
