# Mission: Adopt A2A as Internal Agent Communication Protocol

## Metadata
- **Created:** 2026-05-08
- **Status:** Proposed (not started)
- **Source:** Research from 4+ model consultations + codebase analysis + cross-repo pattern study
- **Plans:** `docs/plans/A2A_ADOPTION_PLAN.md`, `docs/plans/UNIFIED_DISPATCH_V2.md`, `docs/plans/dispatch-orchestration-architecture.md`

---

## Goal

Consolidate SF's 5 dispatch mechanisms + MessageBus into a unified dispatch architecture using A2A as the semantic communication layer, with MessageBus as the transport.

---

## Context

### Problem
SF has accumulated 5 dispatch mechanisms without a unifying abstraction:
1. **subagent tool** — inline delegation, 4 tools, no project DB
2. **parallel-orchestrator** — milestone-level parallelism, full tools, shared SQLite WAL
3. **slice-parallel-orchestrator** — same pattern at slice scope (~80% duplicate)
4. **UOK kernel** — autonomous loop controller
5. **MessageBus** — SQLite-backed durable messaging (well-implemented but not wired)
6. **Cmux** — surface integration (keep separate)

### Evidence
- `parallel-orchestrator.js` + `slice-parallel-orchestrator.js` share ~80% logic
- MessageBus has zero references in parallel-orchestrator (coordination via file-based IPC)
- `@a2a-js/sdk@0.3.11` already in node_modules (transitive dep of `@google/gemini-cli-core`)
- All 4 consulted models converged: merge the orchestrators first, wire MessageBus, keep subagent constraint

### Constraints
- Must preserve existing behavior throughout migration (feature-flagged rollout)
- `SF_A2A_ENABLED=0` must disable all new A2A behavior instantly
- subagent isolation (4 tools, no project DB writes) is NOT changed
- File-based IPC (`session-status-io.js`) stays as permanent crash-recovery fallback
- DB is authoritative; A2A messages are hints

---

## Mission Tasks

### Phase 1 — A2A Type Definitions (Week 1-2)
- [ ] Create `dispatch/a2a-types.ts` — A2A types + SF extensions (A2ATaskState, SFTaskExtension, MessagePriority, SFAgentCapabilities, SFAgentCard)
- [ ] Create `dispatch/a2a-task.ts` — Task creation + state mapping functions
- [ ] Create `dispatch/a2a-errors.ts` — DeliveryError + error codes
- [ ] Run: `npx tsc --noEmit` on new types
- [ ] Run: `npx vitest run dispatch/a2a-task.test.ts`

### Phase 2 — AgentRegistry (Week 2-3)
- [ ] Create `dispatch/capability-registry.ts` — AgentRegistry + SF_CAPABILITY_DEFINITIONS
- [ ] Create `dispatch/index.ts` — barrel exports
- [ ] Wire registry into `DispatchService` (opt-in via `SF_A2A_ENABLED=1`)
- [ ] Run: unit tests pass
- [ ] Run: existing tests pass with `SF_A2A_ENABLED=0`

### Phase 3 — MessageBus Wiring (Week 3-4)
- [ ] Create `dispatch/a2a-service.ts` — A2AMessageService wrapping MessageBus
- [ ] Create `dispatch/metrics.ts` — A2A Prometheus metrics
- [ ] Create `dispatch/logger.ts` — structured JSONL logging
- [ ] Create `dispatch/validation.ts` — message body validation
- [ ] Create `dispatch/auth.ts` — agent token generation + verification
- [ ] Replace file-based IPC with MessageBus.send() for pause/resume/stop
- [ ] Keep file-based IPC as crash-recovery fallback
- [ ] Run: integration tests with `SF_A2A_ENABLED=1`
- [ ] Run: existing tests pass with `SF_A2A_ENABLED=0`

### Phase 4 — Subagent A2A (Week 4-5)
- [ ] Refactor `subagent/index.ts` to use DispatchService
- [ ] Remove ~600 LOC spawn management (replaced by `dispatch.start()`)
- [ ] Verify all 4 subagent modes work identically
- [ ] Add optional MessageBus inbox for subagents (`useMessageBus: true`)
- [ ] Run: subagent tests with `SF_A2A_ENABLED=1`

### Phase 5 — UOK Kernel A2A (Week 5-6)
- [ ] Register coordinator AgentCard in `uok/kernel.ts`
- [ ] Replace `startParallel`/`startSliceParallel` calls with DispatchService
- [ ] Verify `sf headless autonomous` works identically
- [ ] Run: integration tests with `SF_A2A_ENABLED=1`

### Phase 6 — A2A Default On (Week 6-7)
- [ ] Set `SF_A2A_ENABLED=1` as default in preferences
- [ ] Monitor for 1 week
- [ ] Promote to stable

---

## Verification Criteria

1. `npx vitest run src/resources/extensions/sf/tests/uok-message-bus.test.mjs` passes throughout
2. `SF_A2A_ENABLED=0 npm run test:unit` passes throughout (legacy preserved)
3. Pause/resume works via MessageBus with `SF_A2A_ENABLED=1`
4. All 4 subagent modes work identically (parallel, debate, chain, single)
5. `sf headless autonomous` works with `SF_A2A_ENABLED=1`
6. Worker AgentCards visible in dashboard
7. Panic mode activates correctly (3 consecutive delivery failures → file-based fallback)
8. `sf uok messages compact` works
9. `sf dispatch agents list` shows registered agents with capabilities

---

## Key Files

| File | Role |
|---|---|
| `src/resources/extensions/sf/uok/message-bus.js` | Existing MessageBus (transport) |
| `src/resources/extensions/sf/dispatch/service.js` | DispatchService (A2A coordinator client) |
| `src/resources/extensions/sf/worktree-orchestrator.js` | Worker spawner (A2A agent) |
| `src/resources/extensions/sf/uok/kernel.js` | UOK kernel (A2A coordinator) |
| `src/resources/extensions/subagent/index.js` | Subagent tool (A2A constrained agent) |
| `docs/plans/A2A_ADOPTION_PLAN.md` | Full production-grade plan |

---

## Exit Criteria

Mission is complete when:
- All 6 phases are merged to main
- `SF_A2A_ENABLED=1` is the default
- `SF_A2A_ENABLED=0` still passes all tests (legacy preserved)
- 0 P0/P1 bugs in dispatch layer for 2 consecutive weeks
- A2A observability dashboard shows healthy metrics (delivery latency < 500ms p99)
