Files
AirCoding/AirPlan/docs/implementation/IMPLEMENTATION-PLAN.md
AirCoding 071283df8f Add implementation plan & task breakdown for V1.0.0 Alpha
70+ granular tasks (T-001..T-809) across 9 phases, derived strictly from
frozen detailed design. Each task is self-contained for context-isolated
executor agents: file list, contract refs, applicable INV-1..5, dependencies,
DoD/verify. Includes invariant injection (§A1), import graph (§A2), reference
reuse map (§A3), validation gates (§A4), phase dependency summary (§A5).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 10:06:58 +08:00

771 lines
52 KiB
Markdown
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AirCoding V1.0.0 Alpha — Implementation Plan & Task Breakdown
Date: 2026-06-02
Status: **Implementation plan derived strictly from the FROZEN detailed design.** Architecture is frozen (DD §24). This plan adds **no** new contracts, events, DB columns, or runtime semantics.
Branch: `GLM5-Achieve`
Audience: **context-isolated executor agents (AirDo / cheap-model subagents).** Each task below is self-contained enough that an agent holding only that task's slice can implement it correctly.
---
## 0. How To Use This Plan (READ FIRST — every executor agent)
You are likely an **isolated subagent with partial context**. To avoid the most common slice-local mistakes:
1. **You MUST obey the 5 domain invariants** (DD §18.6), reproduced in §A1 below. Inject §A1 into your working context verbatim. INV-1 is the one partial context cannot otherwise detect.
2. **You MUST NOT introduce new public contracts, event types, DB columns, or runtime semantics.** Everything is frozen. If a task seems to need one, STOP and emit a blocker — do not improvise. (DD §0)
3. **Field naming**: exported contract fields are `snake_case`; class names `PascalCase`; private methods may be local `camelCase`. (DD §0)
4. **Import direction is one-way and enforced by lint** (DD §2, §A2). Never cross a forbidden edge.
5. **Authority precedence** when in doubt: `interface-contracts-v1.md` > `db-schema-v1.md` / `event-registry-v1.md` > `system-detailed-design.md` > this plan. This plan never overrides a frozen source; it routes you to the exact section.
6. **Definition of Done** for any code task: (a) implements the cited contract verbatim; (b) passes `bun run typecheck`; (c) has unit tests green via `bun test`; (d) respects INV-1..5; (e) crosses no forbidden import edge. Side-effect tasks additionally need evidence (test output) attached.
7. **Reference reuse**: if your task row in DD §23 names a reference project, consult it before re-deriving (renderer, diff engine, skill format, provider conversion). Reference checkouts are under `<repo-root>/reference/` (git-ignored). See §A3.
**Tech stack (frozen, ADR-0002):** TypeScript on **Bun**, Bun workspaces + **Turborepo**. Worker agents are independent Bun child processes (ADR-0005). IPC is NDJSON over stdio.
**Source-of-truth documents (all under `AirPlan/docs/architecture/`):**
`interface-contracts-v1.md`, `db-schema-v1.md`, `event-registry-v1.md`, `c4/code-view.md`, `c4/module.md`, `scheduler-state-machine-v1.md`, `main-agent-state-machine.md`, `runtime-semantics-v1.md`, `scope-escalation-v1.md`, `security-model-v1.md`, `error-taxonomy-v1.md`, `prompt-layering-v1.md`, `provider-capability-matrix-v1.md`, `capability-trust-v1.md`, `artifact-naming-v1.md`, `system-overview-design.md`, `system-detailed-design.md`.
---
## 1. Phase Map & Critical Serialization
Phases follow overview §16. **Phases must be serialized at the boundaries below; tasks *within* a phase (and across phases with no dependency) are parallelizable.**
| Phase | Scope | Gate to next phase |
|---|---|---|
| **P0** | Monorepo skeleton + `packages/contracts` (type-only) | contracts compile; barrel exports complete |
| **P1** | `.air` project/session storage, SQLite, migrations, EventStore/Bus/Ingestor, ArtifactStore/EvidenceStore | EventStore append+project+publish green; FK-off check green |
| **P2** | ToolRegistry, PermissionEngine, built-in tools, CapabilityRegistry | tool call → permission → event flow green |
| **P3** | Provider layer (`packages/llm`), ContextAssembler, prompt resources | provider stream normalized; context assembled Anthropic-canonical |
| **P4** | Worker IPC, WorkerManager, Scheduler subsystem | worker-fixture E2E green; scheduler run_until_idle green |
| **P5** | `packages/toolchain-cpp` complete C++ workflow | cpp detect→configure→build→parse→test→cppcheck green |
| **P6** | ProjectionStore, `packages/tui` TUI/HUD | tui-smoke green; projection renders |
| **P7** | MainAgent / ArchitectureDesigner / worker-role integration | direct-mode + architecture-gate E2E green |
| **P8** | Release gates, Doctor bundle, packaging | `bun run release:check` green |
**Hard serialization edges (overview §16):**
1. `contracts` before ALL implementation packages.
2. DB schema (migrations) before storage/EventStore tests.
3. ToolRegistry + PermissionEngine before any side-effect tool/worker.
4. Provider/context contracts before agent prompts.
5. IPC before real worker E2E.
6. Projection contracts before TUI implementation.
**Parallelization guidance for cheap-model fan-out:**
- Within P0: all 16 contract files are independent — fan out 16-wide.
- Within P1: repositories (16) are independent of each other once `DatabaseManager`+migrations land — fan out wide; EventStore projection depends on repositories.
- Within P2: each built-in tool is independent once ToolRegistry+PermissionEngine land.
- P5 (cpp) and P6 (projection/TUI scaffolding) can overlap P4 partially since they depend on contracts + tool layer, not on Scheduler internals.
---
## 2. Task ID Scheme
`T-<phase><nn>` e.g. `T-001` (P0), `T-1xx` (P1) … `T-8xx` (P8). Each task lists: **Files**, **Implements** (contract/DD ref), **INV** (applicable invariants), **Depends on**, **DoD/verify**.
---
## Phase 0 — Skeleton & Contracts (`packages/contracts`)
> Gate: `bun install && bun run typecheck` green at repo root; every contract symbol in `interface-contracts-v1.md` §2§21 is exported from the barrel. Contracts package is **type-only** (DD §3) — zero runtime deps.
### T-001 — Monorepo skeleton (root)
- **Files:** `package.json` (root, Bun workspaces), `turbo.json`, `tsconfig.base.json`, `tsconfig.json`, `bunfig.toml`, `.gitignore` (merge — keep existing `/reference/` rule), `packages/*/package.json` + `packages/*/tsconfig.json` for all 6 packages.
- **Implements:** ADR-0002 (Bun + workspaces + Turborepo); code-view §1 package list.
- **Depends on:** none.
- **DoD:** `bun install` resolves; `bun run typecheck` runs across the empty packages; package dependency graph in each `package.json` matches DD §2 allowed imports (contracts depends on nothing; runtime → contracts,llm; cli → runtime,tui,llm,cpp; tui → contracts; llm → contracts; cpp → contracts).
- **INV:** INV-4 (encode import direction in workspace deps).
### T-002 — `contracts/ids.ts` + `error.ts`
- **Files:** `packages/contracts/src/ids.ts`, `packages/contracts/src/error.ts`.
- **Implements:** contracts §2 (primitive ID aliases, `Clock`, `IdGenerator`), §3 (`ErrorKind`, `ErrorSeverity`, `Retryability`, `AirError`). DD §3, §18.1.
- **Depends on:** T-001.
- **DoD:** all aliases + `AirError` interface exported verbatim from contracts §2/§3. Optional pure type-guard `is_air_error` allowed only if dependency-free (DD §3 IMPL).
### T-003 — `contracts/event.ts`
- **Files:** `packages/contracts/src/event.ts`.
- **Implements:** contracts §5 (`EntityType`, `EntityRef`, `EventSource`, `RuntimeEvent`, `EventFilter`). Note `EventSource.kind` literal set `"main"|"architecture_designer"|"scheduler"|"agent"|"tool"|"system"` (DD §2, §22.1).
- **Depends on:** T-002.
- **DoD:** `RuntimeEvent<T>` shape matches DD §22.1 exactly; `agent_type?: AgentType` optional field present.
### T-004 — `contracts/runtime.ts`
- **Files:** `packages/contracts/src/runtime.ts`.
- **Implements:** contracts: `AgentType` (`executor|reviewer|debugger|compactor|experience_miner`), `AgentRuntimeContext`, `ContextPack`; co-locate PromptLayer types + `ContextAssembler`-facing context types per DD §3 mapping (context.ts symbols → runtime.ts).
- **Depends on:** T-002.
- **DoD:** `AgentType` union is exactly the 5 worker roles (DD §2). PromptLayer/PromptLayerLevel L0L9 union present (DD §10.2).
### T-005 — `contracts/ipc.ts`
- **Files:** `packages/contracts/src/ipc.ts`.
- **Implements:** contracts §10 IPC: `IpcDirection`, `IpcEnvelope`, `IpcKind`, `IpcMessage`, `ControlMessage`, payloads; plus `workers.ts` symbols (`WorkerRole`, `WorkerRuntime`, IPC payloads) merged here per DD §3.
- **Depends on:** T-003, T-004.
- **DoD:** direction typing present (parent→worker: `control`/`tool.result`/`tool.stream`; worker→parent: `event`/`log`/`tool.call`/`worker.result`/`worker.checkpoint`/`protocol.error`). DD §8.2.
### T-006 — `contracts/task.ts`
- **Files:** `packages/contracts/src/task.ts`.
- **Implements:** contracts §9: `TaskType`, `TaskScope`, `TaskDependencySpec`, `VerificationPolicy`, `TaskConstraints`, `TaskContextRefs`, `WorkerOutputContract`, `TaskSpec`, `TaskGraph` types, `Scheduler*` (`SchedulerWavePlan`, `SchedulerRunResult`), `TransactionManager`, `Repository<TRecord,TInsert,TUpdate>` (storage.ts symbols merged here per DD §3).
- **Depends on:** T-004.
- **DoD:** `TaskSpec` matches DD §22.1; `TaskType` includes `execute|review|debug|compact|mine_experience|docs` (DD §8.3).
### T-007 — `contracts/worker-result.ts`
- **Files:** `packages/contracts/src/worker-result.ts`.
- **Implements:** contracts §11: `WorkerStatus`, `WorkerResult`, `ExecutorResult`, `ReviewerResult`, `DebuggerResult`, `CompactorResult`, `ExperienceMinerResult`, `BlockerReport`, `Risk`, `FollowUpTask`.
- **Depends on:** T-006, T-002 (AirError), T-009 (Evidence/Artifact refs) — see note.
- **DoD:** `WorkerResult<T>` matches DD §22.1; `status ∈ {completed,failed,blocked,cancelled}`.
### T-008 — `contracts/tool.ts`
- **Files:** `packages/contracts/src/tool.ts`.
- **Implements:** contracts §12 + §21: `ToolCategory`, `ToolDefinition`, `ToolExecutor`, `StreamingToolExecutor`, `ToolExecutionContext`, `ToolResultEnvelope`, `ToolEvent`, `ToolRegistry`, plus `Diagnostic` + `semantic_signature` types (diagnostics.ts merged here, DD §3).
- **Depends on:** T-004, T-009 (ArtifactRef/EvidenceRef referenced by envelopes).
- **DoD:** `ToolDefinition<I,O>` matches DD §22.1; `Diagnostic` matches contracts §21.
### T-009 — `contracts/artifact.ts` + `evidence.ts`
- **Files:** `packages/contracts/src/artifact.ts`, `packages/contracts/src/evidence.ts`.
- **Implements:** contracts §14: `ArtifactRef`, `ArtifactCreateInput`, `ArtifactContext`, `ArtifactReadResult`, `ArtifactStore`, `EvidenceRef`, `EvidenceCreateInput`, `EvidenceStore`; plus `knowledge.ts` symbols (`DebugKnowledgeStore`, `LearnedMemoryStore`, `DebugRecord`, `LearnedMemory`) merged into `artifact.ts` per DD §3.
- **Depends on:** T-002.
- **DoD:** `EvidenceStore.list_for_entity(entity_type, entity_id)` present (NOT `list_for_task`). `ArtifactRef` matches DD §22.1.
### T-010 — `contracts/project.ts`
- **Files:** `packages/contracts/src/project.ts`.
- **Implements:** contracts §8: `ProjectContext`, `ProjectInitOptions`, `ProjectStore`, `SessionContext`, `OpenSessionOptions`, `SessionManager`.
- **Depends on:** T-002.
- **DoD:** matches contracts §8 verbatim.
### T-011 — `contracts/provider.ts`
- **Files:** `packages/contracts/src/provider.ts`.
- **Implements:** contracts §15: `ProviderCapabilityMatrix`, `ModelRequirement`, `ProviderCompletionInput`, `ProviderStreamEvent`, `ProviderAdapter`, `ProviderManager`, `ModelAssignment`.
- **Depends on:** T-004.
- **DoD:** matches contracts §15; `ProviderAdapter` matches DD §22.6.
### T-012 — `contracts/permission.ts`
- **Files:** `packages/contracts/src/permission.ts`.
- **Implements:** contracts §13: `PathPolicy`, `PermissionRequestContext`, `PermissionAction`, `PermissionGrantScope`, `PermissionDecision`, `PermissionRecordResult`, `PermissionEngine`.
- **Depends on:** T-009.
- **DoD:** `PermissionAction` covers `allow|announce_then_run|ask_user|deny|block|refuse` (DD §9.3). `PermissionDecision` matches DD §22.1.
### T-013 — `contracts/ui.ts`
- **Files:** `packages/contracts/src/ui.ts`.
- **Implements:** contracts §17: all `*Projection`, `ProjectionSnapshot`, `ProjectionStore`, `ProjectionClient`, `UiCommandChannel`; (projection.ts symbols merged here).
- **Depends on:** T-006, T-009.
- **DoD:** `CommandRunProjection.status` derivable values match DD §4.4 (`running|ok|error|cancelled|unknown`).
### T-014 — `contracts/capability.ts` + `platform.ts`
- **Files:** `packages/contracts/src/capability.ts`, `packages/contracts/src/platform.ts`.
- **Implements:** contracts §18 (`CapabilityManifestV1`, `ValidationResult`, `CapabilityRegistry`, trust levels), §19 (`DoctorService`, `DoctorRunInput`/`Output`, `DoctorIssue` — doctor.ts merged into platform.ts), cross-platform tier enums (from `cross-platform-matrix-v1.md`).
- **Depends on:** T-008 (ToolRegistry ref), T-002.
- **DoD:** trust levels `built_in|project_local|user_installed|verified_publisher|untrusted`; `CapabilityManifestV1.schema_version=1`.
### T-015 — `contracts/index.ts` barrel + boundary lint
- **Files:** `packages/contracts/src/index.ts`, root ESLint/import-boundary config (e.g. `eslint-plugin-import` or `dependency-cruiser`) enforcing DD §2 / code-view §12 forbidden edges.
- **Implements:** DD §3 rule 4 (barrel exports every contract file); DD §A2 forbidden edges.
- **Depends on:** T-002..T-014.
- **DoD:** barrel re-exports the full union; `bun run typecheck` green; lint fails on a deliberately-added forbidden import (test fixture), passes otherwise. **This is the P0 gate.**
---
## Phase 1 — Storage, Events, Artifacts (`packages/runtime`)
> Gate: migrations create all db-schema §2§18 tables; `EventStore.append` runs insert+project in one tx then publishes after commit; `SessionStore.referential_check()` green; ArtifactStore temp→rename→record green.
### T-101 — `DatabaseManager`
- **Files:** `packages/runtime/src/storage/DatabaseManager.ts`.
- **Implements:** `TransactionManager` (contracts §6) over Bun SQLite. DD §4.1.
- **INV:** enables INV-1/INV-2 infra (single-writer tx).
- **Depends on:** T-006, T-015.
- **DoD:** on `open` sets `journal_mode=WAL`, `synchronous=NORMAL`, `foreign_keys=OFF` (db-schema §1); `transaction` wraps BEGIN/COMMIT/ROLLBACK; nested calls reuse active handle.
### T-102 — `MigrationRunner` + full V1 schema
- **Files:** `packages/runtime/src/storage/MigrationRunner.ts`.
- **Implements:** DD §4.2; creates ALL tables/indexes from `db-schema-v1.md` §2§18; seeds `schema_meta` (`schema_version=1`).
- **Depends on:** T-101.
- **DoD:** idempotent create-on-empty; `currentVersion`/`targetVersion()=1`; updates `aircoding_version_last_opened` on open. Unit test: fresh DB → all 17 session tables present.
### T-103 — `assert_enum` helper + enum table
- **Files:** `packages/runtime/src/storage/assertEnum.ts`.
- **Implements:** DD §4.5; backs every closed-enum TEXT column (db-schema §21, 18 rows). Throws `AirError{kind:"system_error"}` on violation.
- **Depends on:** T-102, T-002.
- **DoD:** rejects an invalid enum value for each of the 18 columns (table-driven test).
### T-104..T-119 — Repositories (one task each, all parallel after T-103)
Each implements `Repository<...>` (contracts §6), thin persistence only (no policy). Records mirror db-schema columns `snake_case`. DD §4.3.
| Task | File | Table (db-schema §) | Extra methods (DD §4.3) |
|---|---|---|---|
| T-104 | `repositories/SessionRepository.ts` | sessions (§3) | `list_active()` |
| T-105 | `repositories/MessageRepository.ts` | messages (§4) | `list_by_session(session_id, since?)` |
| T-106 | `repositories/MessageDraftRepository.ts` | message_drafts (§5) | `upsert`, `delete_for_message` |
| T-107 | `repositories/EventRepository.ts` | events (§6) | `insert(rec,tx)`, `query(filter)` |
| T-108 | `repositories/TaskRepository.ts` | tasks (§7) | `list_by_status`, `list_runnable_candidates` |
| T-109 | `repositories/TaskDependencyRepository.ts` | task_dependencies (§8) | `list_for_task`, `list_dependents` |
| T-110 | `repositories/TaskAttemptRepository.ts` | task_attempts (§9) | `next_attempt_index`, `list_by_task` |
| T-111 | `repositories/AgentRepository.ts` | agents (§10) | `list_active`, `update_heartbeat` |
| T-112 | `repositories/ToolRunRepository.ts` | tool_runs (§11) | `list_by_task`, `list_by_origin_message` |
| T-113 | `repositories/CommandRunRepository.ts` | command_runs (§12) | `list_by_task` + `derive_command_status` (DD §4.4) |
| T-114 | `repositories/ArtifactRepository.ts` | artifacts (§13) | `list_by_entity`, `get_by_uri` |
| T-115 | `repositories/DiagnosticRepository.ts` | diagnostics (§14) | `list_by_signature`, `list_by_command_run` |
| T-116 | `repositories/EvidenceRepository.ts` | evidence_refs (§15) | `list_for_entity(type,id)` |
| T-117 | `repositories/WorkspaceRepository.ts` | workspaces (§16) | `list_by_status`, `list_gc_candidates` |
| T-118 | `repositories/SummaryRepository.ts` | summaries (§17) | `get`, `insert` |
| T-119 | `repositories/UiStateRepository.ts` | ui_state (§18) | `upsert(scope,key,value)`, `read(scope,key)` |
- **INV (all):** INV-1 — repositories are storage-only; they **do not** set status columns by policy. Status columns are written only via EventStore.project. **Exemptions:** T-111 `update_heartbeat` (agents.last_heartbeat_at) and T-119 ui_state are the explicit INV-1 exemptions (DD §18.6).
- **Depends on:** T-103.
- **DoD (each):** CRUD + listed methods; columns match db-schema exactly; unit test round-trips a row.
### T-120 — `SessionStore` aggregate + `referential_check()`
- **Files:** `packages/runtime/src/sessions/SessionStore.ts`.
- **Implements:** DD §4.3 aggregate; `referential_check(): OrphanReport` implementing the 8 FK-off invariants (DD §18.3).
- **Depends on:** T-104..T-119.
- **DoD:** exposes all 16 repositories; `referential_check` detects each of the 8 invariant violations (table-driven test).
### T-121 — `EventSchemaRegistry`
- **Files:** `packages/runtime/src/events/EventSchemaRegistry.ts`.
- **Implements:** contracts §7; DD §5.2. Seeded from `event-registry-v1.md` §3 (durable) + §4 (ephemeral).
- **Depends on:** T-003, T-015.
- **DoD:** `register/validate/list/get_schema`; unknown type+version fails → ingestion can reject with `system_error`; all 55 durable + 7 ephemeral types registered.
### T-122 — `EventStore` (append + projection map)
- **Files:** `packages/runtime/src/events/EventStore.ts`.
- **Implements:** contracts §7; DD §5.3 + **§5.4 projection map (Table A + Table B)**. `append` = tx{ validate → EventRepository.insert → project(event,tx) } then `EventBus.publish` AFTER commit.
- **INV:** **INV-1 (this is the ONLY place status columns are written)**, INV-2 (project never opens external DB/file), INV-5 (publish is post-commit transport).
- **Depends on:** T-120, T-121, T-123 (EventBus).
- **DoD:** every durable event in event-registry §3 has a projection case (Table A); Table B events (`memory.promoted`, `memory.archived`, `debug.record.created`) append event row only, no external write; project() throw → full rollback, no publish (DD §5.3 error handling). Unit test per projection case.
### T-123 — `EventBus`
- **Files:** `packages/runtime/src/events/EventBus.ts`.
- **Implements:** contracts §7; DD §5.5. Live transport only; handler throw is caught+logged, subscription survives; `drain()` flushes; ephemeral coalescing for the 7 ephemeral types.
- **INV:** INV-5.
- **Depends on:** T-003, T-015.
- **DoD:** publish/subscribe/match/drain; never a recovery source.
### T-124 — `EventIngestor`
- **Files:** `packages/runtime/src/events/EventIngestor.ts`.
- **Implements:** contracts §7; DD §5.1. `ingest` routes durable→EventStore.append, ephemeral→EventBus.publish by registry policy.
- **Depends on:** T-122, T-123.
- **DoD:** durable type → EventStore path; ephemeral type → bus path; never creates tasks/permissions/memory itself.
### T-125 — `ProjectStore` (+ `ProjectLocator`, `ProjectInitializer`)
- **Files:** `packages/runtime/src/project/ProjectStore.ts`, `ProjectLocator.ts`, `ProjectInitializer.ts`.
- **Implements:** contracts §8; DD §6.1. `.air/shared` + `.air/local` scaffolding (overview §8.1); stable `project_id` UUID in `.air/shared/project.json`.
- **Depends on:** T-010, T-015.
- **DoD:** `locate` walks up to `.air/shared/project.json`; `initialize` creates trees + project_id; `open` loads ProjectContext. No session DB created until session opens.
### T-126 — `SessionManager`
- **Files:** `packages/runtime/src/sessions/SessionManager.ts`.
- **Implements:** contracts §8; DD §6.2. `open_session` computes db_path, opens+migrates, ingests `session.created`; provider/model fixed at open (immutable, overview §14).
- **Depends on:** T-125, T-126-dep: T-124, T-102, T-120.
- **DoD:** open→migrate→ingest `session.created`→returns SessionContext; `close_session` flushes ui_state + releases handle.
### T-127 — `ArtifactStore`
- **Files:** `packages/runtime/src/artifacts/ArtifactStore.ts`.
- **Implements:** contracts §14; DD §11.1; naming from `artifact-naming-v1.md`.
- **INV:** INV-1 (artifact.created writes session row via projection — store calls EventIngestor, does not UPDATE).
- **Depends on:** T-124, T-009.
- **DoD:** `create` = write temp → sha256+size → atomic rename → ingest `artifact.created`; `artifact_id=art_<ulid>`; uri/filename per artifact-naming-v1; type from closed set. DB-insert-after-rename failure path documented for recovery (DD §16.3).
### T-128 — `EvidenceStore`
- **Files:** `packages/runtime/src/artifacts/EvidenceStore.ts`.
- **Implements:** contracts §14; DD §11.2.
- **INV:** INV-1.
- **Depends on:** T-124, T-009.
- **DoD:** `create` ingests `evidence.created`; `list_for_entity(entity_type,entity_id)`; `kind` from closed set.
### T-129 — Recovery: orphan-artifact + FK-off scan wiring
- **Files:** `packages/runtime/src/storage/Recovery.ts` (recovery helpers used by SessionManager/Scheduler startup).
- **Implements:** DD §16.3 steps 56 (orphan-artifact scan; FK-off orphan scan calls `SessionStore.referential_check`).
- **Depends on:** T-120, T-127.
- **DoD:** orphaned artifact file → registered or quarantined; dangling ref → logged + re-parented/archived. (Full recovery sequence completed in P4 T-4xx.)
---
## Phase 2 — Tools, Permission, Capability (`packages/runtime`)
> Gate: `ToolRegistry.call` runs lookup→validate→PermissionEngine.evaluate→branch→emit tool.started→execute→emit tool.completed/failed/cancelled. No side effect bypasses PermissionEngine (code-view §12).
### T-201 — `PathClassifier`
- **Files:** `packages/runtime/src/security/PathClassifier.ts`.
- **Implements:** DD §9.2; `security-model-v1.md`. 8 path categories; realpath normalization before prefix checks; `.git/` internals protected.
- **Depends on:** T-012.
- **DoD:** classifies the 8 categories; symlink escape not allowed by string-prefix (realpath test).
### T-202 — `CommandRiskAnalyzer`
- **Files:** `packages/runtime/src/security/CommandRiskAnalyzer.ts`.
- **Implements:** DD §9.2; security-model-v1. 10 command-risk categories; `sudo` risk by intent/target, not string alone (DD §18.5).
- **Depends on:** T-012.
- **DoD:** 10 categories covered; destructive command flagged; intent-based sudo test.
### T-203 — `SecretRedactor`
- **Files:** `packages/runtime/src/security/SecretRedactor.ts`.
- **Implements:** DD §9.2 / §16.2. Redacts secrets/auth refs/provider keys for logs/evidence.
- **Depends on:** T-001.
- **DoD:** redacts known secret patterns; shared by PermissionEngine + Logger.
### T-204 — `PermissionEngine`
- **Files:** `packages/runtime/src/security/PermissionEngine.ts`.
- **Implements:** contracts §13; DD §9.2. Layered order 16 (capability → profile → task scope → risk → credential override → user prompt). `record` writes `permission.decision.recorded`.
- **INV:** INV-3 (the mandatory gate for all side effects).
- **Depends on:** T-201, T-202, T-203, T-124.
- **DoD:** project-allow never overrides task scope; credential/system-sensitive overrides broad allow; realpath prefix; `record` returns `{ok:false,error}` on write failure.
### T-205 — `ToolRegistry`
- **Files:** `packages/runtime/src/tools/ToolRegistry.ts`.
- **Implements:** contracts §12; DD §9.1 + §9.3 branching table.
- **INV:** INV-3.
- **Depends on:** T-204, T-124, T-127 (backup/artifact).
- **DoD:** `call`/`call_streaming` per DD §9.1 algorithm; branches on all 6 `PermissionAction`s (DD §9.3); `call_streaming` ends with exactly one final `ToolResultEnvelope`.
### T-206..T-213 — Built-in tools (one task each, parallel after T-205)
Each: a `ToolDefinition` (declares `category`,`permissions`,`streaming`) + `ToolExecutor`, registered via `BuiltInToolRegistrar`. DD §9.1, code-view §4.
| Task | File group | Tools | Notes / DD |
|---|---|---|---|
| T-206 | `tools/fs/` | `fs.read`, `fs.edit`, `fs.patch`, `fs.write`, `fs.list` | **read-before-edit + exact-edit enforced at tool layer** (DD §9.4); successful edit/patch emits diff artifact. Reference: DD §23 (Claude Code behavioral, Codex pattern). |
| T-207 | `tools/shell/` | `shell.run` | emits `command.started`/`command.completed`; streaming stdout/stderr deltas (ephemeral). |
| T-208 | `tools/git/` | `git.*` (status/diff/commit/branch/merge as scoped) | `.git/` internals protected (DD §18.5). |
| T-209 | `tools/project/` | `project.*` (rules/context read) | read-only project metadata. |
| T-210 | `tools/artifact/` | `artifact.create/read` | wraps ArtifactStore. |
| T-211 | `tools/context/` | `context.*` (assemble/compact triggers) | wraps ContextAssembler (available P3). Stub acceptable in P2; finalize in P3. |
| T-212 | `tools/permission/` | `permission.*` (prompt resolve plumbing) | emits `permission.prompt.requested/resolved`. |
| T-213 | `tools/doctor/` | `doctor.*` | wraps DoctorService (P8). Stub acceptable in P2. |
| T-214 | `tools/BuiltInToolRegistrar.ts` | registrar | registers all of the above into a ToolRegistry. |
- **INV (all):** INV-3 (every tool goes through evaluate first — guaranteed by going through ToolRegistry.call, do NOT call side effects directly).
- **Depends on:** T-205.
- **DoD (each):** input schema validated; permission consulted; correct events emitted; unit test with a fake PermissionEngine returning each action.
### T-215 — `CapabilityManifestValidator`
- **Files:** `packages/runtime/src/capabilities/CapabilityManifestValidator.ts`.
- **Implements:** contracts §18; DD §9.5. Validates `schema_version=1`, tool schemas, permissions.
- **Depends on:** T-014.
- **DoD:** accepts a valid manifest, rejects bad schema_version/missing fields.
### T-216 — `CapabilityRegistry`
- **Files:** `packages/runtime/src/capabilities/CapabilityRegistry.ts`.
- **Implements:** contracts §18; DD §9.5. Lifecycle discovered→validated→doctor_checked→enabled→registered→active. Trust levels affect default posture, never bypass ToolRegistry/PermissionEngine.
- **INV:** INV-4 (dependency installs go only through Doctor).
- **Depends on:** T-215, T-205.
- **DoD:** `discover/validate/enable/disable/register_tools`; enabling registers tools into ToolRegistry; dependency install delegates to Doctor (no direct install).
---
## Phase 3 — Provider & Context (`packages/llm` + `packages/runtime/context`)
> Gate: provider stream normalized to `ProviderStreamEvent`; `ContextAssembler.assemble` returns Anthropic-canonical AssembledContext; prompt layers L0L9 ordered.
### T-301 — `ModelConfigLoader`
- **Files:** `packages/llm/src/ModelConfigLoader.ts`.
- **Implements:** DD §12.2. Loads global `~/.air/models.yaml` + project config.
- **Depends on:** T-011, T-001.
- **DoD:** loads model config; validates required fields.
### T-302 — `CapabilityMatrixRegistry`
- **Files:** `packages/llm/src/CapabilityMatrix.ts`.
- **Implements:** DD §12.2; holds `ProviderCapabilityMatrix` rows (`provider-capability-matrix-v1.md`).
- **Depends on:** T-011.
- **DoD:** lookup by provider/model; matches matrix doc.
### T-303 — `AnthropicCanonicalConverter` + `ToolUseConverter` + `StreamNormalizer`
- **Files:** `packages/llm/src/canonical/AnthropicCanonical.ts`, `ToolUseConverter.ts`, `StreamNormalizer.ts`.
- **Implements:** DD §12.2; Anthropic-canonical internal format (D-016 / DD §23 behavioral ref: Claude Code message model). **Must not silently drop semantic prompt/tool info** (contracts §23).
- **Reference:** DD §23 — `@opencode-ai/llm` (fork/adapt) for conversion structure; Claude Code message model (behavioral).
- **Depends on:** T-011.
- **DoD:** round-trips canonical↔provider for text/thinking/tool_use/tool_result blocks; conversion report flags any dropped field.
### T-304 — `AnthropicAdapter`
- **Files:** `packages/llm/src/adapters/AnthropicAdapter.ts`.
- **Implements:** `ProviderAdapter` (contracts §15); DD §12.2.
- **Depends on:** T-303.
- **DoD:** `list_models/validate_model/complete/count_tokens?`; streams normalized events.
### T-305 — `OpenAICompatibleAdapter`
- **Files:** `packages/llm/src/adapters/OpenAICompatibleAdapter.ts`.
- **Implements:** `ProviderAdapter`; uses `AnthropicCanonicalConverter`.
- **Depends on:** T-303.
- **DoD:** converts canonical↔OpenAI-compatible; streams normalized; no silent semantic loss.
### T-306 — `ProviderManager`
- **Files:** `packages/llm/src/ProviderManager.ts`, `packages/llm/src/index.ts` (facade export).
- **Implements:** contracts §15; DD §12.1. `load_config/select_model/complete`; `adapter_for`. No runtime model switching (immutable per session).
- **INV:** INV-4 (runtime calls llm only via this facade).
- **Depends on:** T-301, T-302, T-304, T-305.
- **DoD:** `select_model` matches ModelRequirement against matrix → ModelAssignment; `complete` routes to adapter; facade is the only export surface runtime imports.
### T-307 — `PromptLayerLoader`
- **Files:** `packages/runtime/src/context/PromptLayerLoader.ts`.
- **Implements:** contracts §16; DD §10.2. 4 methods: `load_runtime_invariant` (L0), `load_role` (L1, worker AgentType only), `load_project_rules` (L3), `load_task_context` (L5).
- **Depends on:** T-004, T-010.
- **DoD:** loads L0/L1/L3/L5; `load_role` accepts only worker AgentType (runtime roles load built-in directly).
### T-308 — Built-in prompt resources (L0/L1)
- **Files:** `packages/runtime/src/context/prompts/` (runtime_invariant.md, roles/{executor,reviewer,debugger,compactor,experience_miner}.md, main.md, architecture.md).
- **Implements:** prompt-layering-v1 L0/L1; DD §10.2. Inject §A1 (INV-1..5) into runtime_invariant L0.
- **Depends on:** T-307.
- **DoD:** L0 includes the 5 invariants; each worker role + main + architecture has a role prompt.
### T-309 — `CompactionPolicy`
- **Files:** `packages/runtime/src/context/CompactionPolicy.ts`.
- **Implements:** contracts §16; DD §10.3. `should_compact`, `compact` (compaction is executed by CompactorRole; policy decides + summarizes interface).
- **Depends on:** T-004.
- **DoD:** `should_compact` honors token budget; sequence ref documented (requested→started→summary.created→completed).
### T-310 — `ContextAssembler`
- **Files:** `packages/runtime/src/context/ContextAssembler.ts`.
- **Implements:** contracts §16; DD §10.1 + §10.2 layer-assembly table (L2/L4/L6/L7/L8/L9 internal).
- **INV:** reads EvidenceStore (L6) + SessionStore (L7/L8) — read-only.
- **Depends on:** T-307, T-309, T-120, T-128.
- **DoD:** `assemble` → Anthropic-canonical AssembledContext; fits token_budget, reports omissions; writes messages artifact + sets `messages_artifact_id` when too large; sets `compaction_requested=true` when required layers don't fit; L0/L1/L2 never dropped.
---
## Phase 4 — Worker IPC & Scheduler (`packages/runtime` + `packages/workers`)
> Gate: worker-fixture E2E green (spawn→handshake→tool.call round-trip→worker.result); `Scheduler.run_until_idle` drives §20.2 to a terminal state.
### T-401 — `WorkerProtocol`
- **Files:** `packages/runtime/src/workers/WorkerProtocol.ts`.
- **Implements:** contracts §10; DD §8.2. NDJSON encode/decode, direction validation, protocol-version check.
- **Depends on:** T-005.
- **DoD:** encode/decode NDJSON line; `validate_direction` rejects wrong-channel msg; version mismatch handling.
### T-402 — `WorkerProcess`
- **Files:** `packages/runtime/src/workers/WorkerProcess.ts`.
- **Implements:** DD §8.1. Owns NDJSON pipe; stdout=protocol, stderr=fatal/log; exit-code table 05.
- **Depends on:** T-401.
- **DoD:** send/on_message; exit-code semantics per DD §8.1 table.
### T-403 — `WorkerManager`
- **Files:** `packages/runtime/src/workers/WorkerManager.ts`.
- **Implements:** DD §8.1. `spawn` (Bun child process + handshake), `cancel`.
- **INV:** **INV-1 — WorkerManager never writes `agents.status` directly**; `worker.ready` handshake is a live signal, not a status write. `agent.started` projection sets status.
- **Depends on:** T-402, T-124.
- **DoD:** spawn→handshake (`agent.start``worker.ready`→validate protocol_version); cancel terminates worker; no direct agents.status UPDATE.
### T-404 — `WorkerRuntime` (in-worker side-effect surface)
- **Files:** `packages/workers/src/WorkerRuntime.ts`.
- **Implements:** contracts §10; DD §8.3. `emit`/`call_tool`/`checkpoint` — all via IPC to parent.
- **INV:** **INV-3 — workers reach fs/shell/network/SQLite ONLY through parent-mediated tool IPC.** Never open SQLite or touch fs directly.
- **Depends on:** T-401, T-005. (`packages/workers` imports only contracts + IPC surface — DD §2.)
- **DoD:** `call_tool` → IPC `tool.call` → awaits `tool.result`; `emit` → IPC `event`; `checkpoint` → IPC `worker.checkpoint`. No direct side effects.
### T-405..T-409 — Worker roles (one task each, parallel after T-404)
Each implements `WorkerRole<TResult>` (contracts §10/§11); DD §8.3/§8.4.
| Task | File | Role | Output | Write access |
|---|---|---|---|---|
| T-405 | `packages/workers/src/roles/ExecutorRole.ts` | Executor (also handles `docs`) | ExecutorResult | scoped project writes |
| T-406 | `packages/workers/src/roles/ReviewerRole.ts` | Reviewer | ReviewerResult | read-only |
| T-407 | `packages/workers/src/roles/DebuggerRole.ts` | Debugger | DebuggerResult | scoped writes when assigned |
| T-408 | `packages/workers/src/roles/CompactorRole.ts` | Compactor | CompactorResult | summaries/artifacts only |
| T-409 | `packages/workers/src/roles/ExperienceMinerRole.ts` | ExperienceMiner | ExperienceMinerResult | candidates/rules/skills when assigned |
- **INV (all):** INV-3 (all side effects via `WorkerRuntime.call_tool`). Executor/Debugger also enforce DD §8.4: read-before-edit, stay in write_area, run verification before `completed`, attach evidence.
- **Depends on:** T-404.
- **DoD (each):** `run` returns `WorkerResult<TResult>` with matching `agent_type`; code-changing result not `completed` unless verification passed or skipped-with-evidence; self-escalation returns `blocked` + BlockerReport.
### T-410 — worker entrypoint
- **Files:** `packages/workers/src/main.ts` (child-process entry; reads `agent.start`, dispatches to role, returns `worker.result`).
- **Depends on:** T-405..T-409.
- **DoD:** handshake replies `worker.ready{protocol_version,worker_version}`; routes TaskType→role (DD §8.3 mapping); exit codes per DD §8.1.
### T-411 — `TaskGraph`
- **Files:** `packages/runtime/src/scheduler/TaskGraph.ts`.
- **Implements:** DD §7.2. `get_runnable_tasks` (hard deps done, conflicts blocked), `mark_terminal`, `dependents_of`, `validate_refs`.
- **Depends on:** T-006, T-120.
- **DoD:** dependency semantics per scheduler-state-machine §4; FK-off `validate_refs`.
### T-412 — `WavePlanner`
- **Files:** `packages/runtime/src/scheduler/WavePlanner.ts`.
- **Implements:** DD §7.3. `plan`→SchedulerWavePlan; serialize write conflicts; `assign_workspace`; `assign_model`.
- **Depends on:** T-411, T-306.
- **DoD:** different write areas→concurrent; same uncertain area→serialize; reviewers concurrent except vs unstable outputs; resource cap; inferred conflict/serialization edges persisted via task_dependencies + events.
### T-413 — `RetryPlanner`
- **Files:** `packages/runtime/src/scheduler/RetryPlanner.ts`.
- **Implements:** DD §7.4. `decide`→RetryDecision (`retry|retry_serial|debug|skip|block|cancel`).
- **Depends on:** T-006, T-002.
- **DoD:** identical failure_signature escalates faster; env impossibility→block; arch/interface mismatch→route to ArchitectureDesigner; budget = retry_budget.
### T-414 — `WorkspaceManager`
- **Files:** `packages/runtime/src/scheduler/WorkspaceManager.ts`.
- **Implements:** DD §7.5. `create_workspace`/`merge_workspace`/`cleanup_workspace`. Strategies main/worktree/isolated_copy. **Mechanism owner only — never plans.**
- **INV:** INV-1 (workspaces.status only via workspace.* event projection).
- **Depends on:** T-124, T-117, T-208 (git).
- **DoD:** emits workspace.created/merge.started/merge.completed|conflicted/cleaned; GC retention (active→merged 7d→cleaned; abandoned 3d).
### T-415 — `AgentMonitor`
- **Files:** `packages/runtime/src/scheduler/AgentMonitor.ts`.
- **Implements:** DD §7.6. `record_heartbeat` (coalesced), `detect_lost_agents`, `enforce_timeouts`.
- **INV:** INV-1 exemption — heartbeat timestamps are the ONLY direct writes allowed (agents.last_heartbeat_at, tasks.heartbeat_at).
- **Depends on:** T-111, T-124.
- **DoD:** 5s coalescing; missing heartbeat→inspect→ping/soft-cancel or `agent.lost`; soft/hard timeout per scheduler-state-machine §MONITORING.
### T-416 — `Scheduler`
- **Files:** `packages/runtime/src/scheduler/Scheduler.ts`.
- **Implements:** contracts §9; DD §7.1 + state machine §20.2.
- **INV:** **INV-1 (status only via emitted events for projection), INV-5 (rebuild queues from SQLite, not EventBus replay).**
- **Depends on:** T-411, T-412, T-413, T-414, T-415, T-403, T-310.
- **DoD:** `create_tasks` ingests task.created; `run_until_idle` drives IDLE→LOADING_GRAPH→PLANNING_WAVE→DISPATCHING→MONITORING→COLLECTING_RESULTS→(MERGING|REVIEWING_WAVE|REPAIRING_OR_CONTINUING)→terminal; never prompts directly (via Main Agent/PermissionEngine).
### T-417 — Recovery completion (startup/resume)
- **Files:** extend `packages/runtime/src/storage/Recovery.ts`.
- **Implements:** DD §16.3 full 8-step sequence (load running/interrupted tasks, PID liveness, agent.lost, preserve workspaces, orphan scan, FK-off scan, workspace GC, rebuild queue).
- **INV:** INV-5 (rebuild from SQLite).
- **Depends on:** T-416, T-129.
- **DoD:** restart with in-flight tasks reconstructs scheduler queue; dead PID→agent.lost; workspaces preserved until decision.
### T-418 — worker-fixture E2E
- **Files:** `packages/runtime/test/e2e/worker-fixture.test.ts` + fixture worker.
- **Implements:** overview §17 `e2e worker-fixture`.
- **Depends on:** T-410, T-416.
- **DoD:** spawn→handshake→tool.call round-trip→worker.result→task.completed; **P4 gate**.
---
## Phase 5 — C++ Toolchain (`packages/toolchain-cpp`)
> Gate: detect→configure→build→parse diagnostics→test→cppcheck green on a fixture C++ project. Exposed via capability registration (code-view §2 rule 4), not direct runtime coupling.
### T-501 — `DiagnosticParser`
- **Files:** `packages/toolchain-cpp/src/analysis/DiagnosticParser.ts`.
- **Implements:** DD §15. `parse_compiler_output`→Diagnostic[] (contracts §21), `semantic_signature` (deterministic; NO LLM here).
- **Depends on:** T-008.
- **DoD:** parses gcc/clang output to Diagnostic; stable semantic_signature.
### T-502 — `CppProjectDetector`
- **Files:** `packages/toolchain-cpp/src/detect/CppProjectDetector.ts`.
- **Implements:** DD §15. `detect`→CppDetectOutput.
- **Depends on:** T-008.
- **DoD:** detects CMake/Make project, toolchain presence.
### T-503 — `CMakeConfigurator`
- **Files:** `packages/toolchain-cpp/src/build/CMakeConfigurator.ts`.
- **Implements:** DD §15. CMake+Ninja preferred, Make fallback; generates/locates `compile_commands.json`.
- **Depends on:** T-501.
- **DoD:** configure output + compile_commands.json path.
### T-504 — `CppBuilder`
- **Files:** `packages/toolchain-cpp/src/build/CppBuilder.ts`.
- **Implements:** DD §15. `build`→CppBuildOutput; diagnostics via DiagnosticParser.
- **Depends on:** T-501, T-503.
- **DoD:** build + parsed diagnostics.
### T-505 — `CppTestRunner`
- **Files:** `packages/toolchain-cpp/src/test/CppTestRunner.ts`.
- **Implements:** DD §15. `run_tests`→CppTestOutput.
- **Depends on:** T-501.
- **DoD:** runs ctest/test target; parses results.
### T-506 — `CppcheckRunner`
- **Files:** `packages/toolchain-cpp/src/analysis/CppcheckRunner.ts`.
- **Implements:** DD §15. `run`→CppcheckOutput; exhaustive branch checking.
- **Reference:** DD §23 (airsdb cppcheck pattern, asciinema/atuin PTY not needed here).
- **Depends on:** T-501.
- **DoD:** cppcheck invocation + parsed diagnostics.
### T-507 — `ClangdClient`
- **Files:** `packages/toolchain-cpp/src/analysis/ClangdClient.ts`.
- **Implements:** DD §15. `query`→ClangdQueryOutput (uses compile_commands.json).
- **Depends on:** T-501, T-503.
- **DoD:** clangd LSP query for symbol/diagnostic.
### T-508 — `CppToolRegistrar` + capability manifest
- **Files:** `packages/toolchain-cpp/src/CppToolRegistrar.ts`, `packages/toolchain-cpp/src/capability.ts`, `index.ts`.
- **Implements:** DD §15; registers `cpp.*` tools through CapabilityRegistry.
- **INV:** INV-4 (registered via capability boundary, not direct runtime import).
- **Depends on:** T-502..T-507, T-216.
- **DoD:** `cpp.*` tools registered through capability registration; **P5 gate** (cpp fixture E2E).
---
## Phase 6 — Projection & TUI (`packages/runtime/projection` + `packages/tui`)
> Gate: tui-smoke green; projections render from snapshot+events. TUI imports ONLY contracts + ProjectionClient (code-view §2 rule 3 / §7).
### T-601 — `ProjectionStore`
- **Files:** `packages/runtime/src/projection/ProjectionStore.ts`, `projections/*`.
- **Implements:** contracts §17; DD §13.1. `hydrate` (from repositories), `apply` (durable + key ephemeral), `snapshot`, `subscribe`. command_runs status via DD §4.4. Never a scheduling/recovery source.
- **Depends on:** T-013, T-120, T-123.
- **DoD:** hydrate rebuilds from DB; apply handles all durable + listed ephemeral; unknown events ignored.
### T-602 — `ProjectionClient` + `TuiApp` shell
- **Files:** `packages/tui/src/ProjectionClient.ts`, `packages/tui/src/TuiApp.tsx`, `index.ts`.
- **Implements:** contracts §17; DD §13.2. In-process ProjectionClient (direct ref, not IPC).
- **Reference:** DD §23 — **OpenTUI `@opentui/*` is `npm-dep`, do NOT build a renderer**; OpenCode TUI patterns (pattern, no SDK/session state).
- **INV:** INV-4 (tui imports only contracts).
- **Depends on:** T-601.
- **DoD:** TuiApp start/stop; consumes ProjectionClient; no runtime-private import, no SQLite, no EventBus subscribe.
### T-603..T-610 — TUI components (parallel after T-602)
| Task | File | Component | DD/notes |
|---|---|---|---|
| T-603 | `components/SessionView.tsx` | SessionView | render session projection |
| T-604 | `components/TaskListView.tsx` | TaskListView | render tasks |
| T-605 | `components/AgentStatusView.tsx` | AgentStatusView | render agents |
| T-606 | `components/ToolRunView.tsx` | ToolRunView | render tool/command runs |
| T-607 | `components/DiffView.tsx` + `EvidenceView.tsx` | Diff/Evidence | link back to artifact/evidence refs (code-view §7 rule 5) |
| T-608 | `components/PermissionPrompt.tsx` | PermissionPrompt | emits via UiCommandChannel only (never private services) |
| T-609 | `components/BlockerReport.tsx` | BlockerReport | render BlockerReport |
| T-610 | `components/HudView.tsx` + `theme/` + `keymap/` | HudView | HUD presets Full/Essential/Minimal; reference claude-hud/atuin/asciinema (pattern) |
- **INV (all):** components render projections only; never mutate domain tables; permission decisions only via UiCommandChannel.
- **Depends on:** T-602.
- **DoD (each):** renders from snapshot; no domain mutation. **P6 gate:** tui-smoke.
---
## Phase 7 — Agents Integration (`packages/runtime/agents`)
> Gate: direct-mode-fixture + architecture-review-gate E2E green.
### T-701 — `MainAgent`
- **Files:** `packages/runtime/src/agents/main/MainAgent.ts`.
- **Implements:** DD §14.1 + state machine §20.1 (main-agent-state-machine.md).
- **INV:** INV-1 (no direct status writes; works via Scheduler/events), INV-3.
- **Depends on:** T-416, T-310, T-306.
- **DoD:** `handle_user_message`→classify→ANSWERING|DELEGATING|DIRECT_MODE; full lifecycle to SUMMARIZING→IDLE; direct mode uses `main_direct` template; emits `requirement.changed`; confirmation gating per state machine.
### T-702 — `ArchitectureDesigner`
- **Files:** `packages/runtime/src/agents/architecture/ArchitectureDesigner.ts`.
- **Implements:** DD §14.2 + sequence §19.4. Review gate; result classes `silent_continue|requires_user_confirmation|requires_replan|reject_or_escalate` (scope-escalation §4).
- **INV:** INV-3 (doc writes via ToolRegistry+PermissionEngine; no direct fs/shell).
- **Depends on:** T-310, T-306, T-124.
- **DoD:** `assess_impact`→ArchitectureImpact; emits `architecture.impact.completed`; `update_architecture_docs` only if confirmed→`architecture.plan.updated`; never replaces Reviewer.
### T-703 — `DebugKnowledgeStore`
- **Files:** `packages/runtime/src/knowledge/DebugKnowledgeStore.ts`.
- **Implements:** contracts §20; DD §11.3. Project DB `debug-records.db`.
- **INV:** **INV-2 (single writer; outbox: external write first → then emit `debug.record.created`).**
- **Depends on:** T-009, T-124.
- **DoD:** insert/lookup_by_signature/lookup_by_task/update; outbox sequence per DD §18.4; never written by anyone else.
### T-704 — `LearnedMemoryStore`
- **Files:** `packages/runtime/src/knowledge/LearnedMemoryStore.ts`.
- **Implements:** contracts §20; DD §11.3. Project DB `learned-memory.db`.
- **INV:** **INV-2 (single writer; outbox: external write first → then emit `memory.promoted`).**
- **Reference:** DD §23 — Hermes Agent (pattern: Nudge/Curator); Anthropic Skills (pattern: SKILL.md format).
- **Depends on:** T-009, T-124.
- **DoD:** insert/lookup_by_type/update_status/scan_stale; `memory.promoted`/`memory.archived` outbox semantics (DD §18.4); never written by anyone else.
### T-705 — Role integration wiring + knowledge sequences
- **Files:** wiring in `Scheduler`/`agents` to route DebuggerRole↔DebugKnowledgeStore and ExperienceMinerRole↔LearnedMemoryStore per sequences §19.5.
- **Depends on:** T-703, T-704, T-407, T-409, T-416.
- **DoD:** debug-knowledge-capture (§19.5) green; experience-mining promotes via outbox.
### T-706 — agent E2E fixtures
- **Files:** `packages/runtime/test/e2e/{direct-mode-fixture,architecture-review-fixture}.test.ts`.
- **Implements:** overview §17 additional UX gates.
- **Depends on:** T-701, T-702.
- **DoD:** direct-mode + architecture-gate E2E green; **P7 gate**.
---
## Phase 8 — CLI, Doctor, Release (`packages/cli` + `packages/runtime/doctor`)
> Gate: `bun run release:check` green; full validation suite (overview §17).
### T-801 — `Logger` + `DeveloperLogEncryptor`
- **Files:** `packages/runtime/src/logging/Logger.ts`, `DeveloperLogEncryptor.ts`.
- **Implements:** DD §16.2. `air.log` (redacted user-facing) + `air.developer.log` (encrypted). Uses SecretRedactor.
- **Depends on:** T-203.
- **DoD:** redacts secrets in both logs; encrypts developer log chunks.
### T-802 — `DoctorService`
- **Files:** `packages/runtime/src/doctor/DoctorService.ts`, `checks/*`.
- **Implements:** contracts §19; DD §16.1. Self-bootstrap (Bun/SQLite/shell/.air writability) before capability checks; modes read_only/fix(under PermissionEngine)/bundle.
- **INV:** INV-4 (dependency installs originate here).
- **Depends on:** T-216, T-204, T-127.
- **DoD:** self_bootstrap blocks on failure; emits `doctor.*`; bundle = local artifact, no auto-upload (DD §18.5).
### T-803 — `RuntimeApp` + `ServiceRegistry` + `RuntimeFactory`
- **Files:** `packages/runtime/src/app/RuntimeApp.ts`, `ServiceRegistry.ts`, `packages/cli/src/bootstrap/createRuntime.ts`, `loadConfig.ts`.
- **Implements:** DD §22.2 (RuntimeApp/ServiceRegistry); wires all subsystems.
- **Depends on:** T-126, T-416, T-601, T-802, T-306.
- **DoD:** `start`/`shutdown` builds full service graph respecting dependency direction.
### T-804..T-808 — CLI commands (parallel after T-803)
Each routes side effects through RuntimeApp services; never bypasses ToolRegistry/PermissionEngine (DD §17).
| Task | File | Command class | Subcommands |
|---|---|---|---|
| T-804 | `commands/run.ts` | RunCommand | `run [project]` (+ spawns TUI) |
| T-805 | `commands/init.ts` | InitCommand | `init` (first-run wizard) |
| T-806 | `commands/doctor.ts` | DoctorCommand | `doctor [--fix\|--bundle]` |
| T-807 | `commands/provider.ts` | ProviderCommand | `provider list`, `provider current` (read-only, no switch) |
| T-808 | `commands/{e2e,release,resume,compact,history,session,restore}.ts` | E2E/Release/Resume/Compact/History/SessionList/Restore | per DD §17 table |
- **Depends on:** T-803.
- **DoD (each):** CliEntrypoint routes argv→command; matches DD §17 table; ProviderCommand read-only; RestoreCommand git-backed file/time/session granularity.
### T-809 — `CliEntrypoint` + release gate
- **Files:** `packages/cli/src/index.ts`, `release:check` script, CI-less local harness.
- **Implements:** overview §17 full validation list.
- **Depends on:** T-804..T-808.
- **DoD:** `bun run typecheck && bun test && bun run lint && bun run air -- doctor --read-only && ... && bun run release:check` all green. **P8 gate — release readiness.**
---
## Appendix
### A1 — The 5 Domain Invariants (DD §18.6) — INJECT INTO EVERY EXECUTOR CONTEXT
- **INV-1 — Session-DB state/lifecycle columns are written ONLY by `EventStore.project(event, tx)`.** No service issues a direct `UPDATE` to `*.status`/lifecycle columns. Authoritative table→event map in DD §18.6. **Exemptions (safe to write directly):** `agents.last_heartbeat_at`, `tasks.heartbeat_at` (AgentMonitor coalesce); `ui_state.*` (UiStateRepository). `command_runs` has NO status column — it's derived (DD §4.4).
- **INV-2 — Cross-DB/external writes use the outbox model with a single writer.** `debug-records.db`, `learned-memory.db`, `rules/`, `skills/`, artifact files go through the owning store (single writer), external write FIRST → then ingest ONE completion event. `EventStore.project()` never opens an external DB/file.
- **INV-3 — Side effects ONLY through `ToolRegistry.call``PermissionEngine.evaluate` first.** Workers reach fs/shell/network/SQLite only via parent-mediated tool IPC. LLM/provider output never performs a direct side effect.
- **INV-4 — Import/dependency direction is one-way** (see A2). Capabilities install dependencies only through Doctor.
- **INV-5 — EventBus is transport, never a source of truth.** Recovery/scheduling rebuild from SQLite, never from EventBus replay. Dropped/duplicated delivery must never change durable state.
### A2 — Allowed import graph (DD §2, frozen by c4/module.md + contracts §23)
```
contracts → (nothing)
llm → contracts
toolchain-cpp → contracts
tui → contracts
runtime → contracts, llm (facade only)
cli → contracts, runtime, tui, llm, toolchain-cpp
workers → contracts + WorkerRuntime IPC surface (NO direct runtime import)
```
Forbidden (enforced by lint, code-view §12): TUI direct DB access; worker direct SQLite writes; capability direct dependency install; provider adapter changing prompt semantics silently; tool execution without PermissionEngine; repositories containing scheduling policy.
### A3 — Reference reuse map (DD §23) — consult before re-deriving
Reference checkouts under `<repo-root>/reference/` (git-ignored). Verify present & non-empty first.
| Slice | Reference | Mode |
|---|---|---|
| TUI renderer | OpenTUI `@opentui/*` | **npm-dep (do NOT reimplement)** |
| TUI patterns | `reference/opencode-1.15.5/` | pattern (no SDK/session state) |
| Provider/converters | `@opencode-ai/llm` (`reference/opencode-1.15.5/`) | fork/adapt (output stays Anthropic-canonical) |
| Edit/patch discipline | `reference/claude-code-cli/` | behavioral (quality bar, no code) |
| fs.edit/patch + test loop | `reference/openai-codex/` | pattern |
| Knowledge/ExperienceMiner/Curator | `reference/hermes-agent-2026.5.16/` | pattern |
| Skills (SKILL.md) | `reference/anthropic-skills/` | pattern |
| Logging/HUD/PTY | `reference/asciinema-3.2.0/`, `reference/atuin-18.16.1/`, `reference/claude-hud-0.0.12/` | pattern |
| Message format | `reference/claude-code-cli/` | behavioral |
### A4 — Validation gates (overview §17)
```bash
bun install
bun run typecheck
bun test
bun run lint
bun run air -- doctor --read-only
bun run air -- e2e worker-fixture
bun run air -- fixture cpp-build-test
bun run air -- e2e cpp-fix-fixture
bun run air -- e2e cpp-debug-review-fixture
bun run air -- capability validate --all
bun run air -- e2e direct-mode-fixture
bun run air -- doctor --bundle
bun run air -- tui-smoke --project <fixture>
bun run release:check
```
### A5 — Dependency summary (phase gates)
```
P0(contracts) ─▶ P1(storage/events) ─▶ P2(tools/perm) ─▶ P3(provider/context) ─▶ P4(workers/scheduler) ─▶ P7(agents) ─▶ P8(cli/release)
│ │
└────────────▶ P5(cpp, after P2) └─▶ P6(projection/TUI, after P3 contracts)
```
P5 and P6 may overlap P4 once their dependencies (P2 tools / P3 provider+context contracts) are met.
---
End of Implementation Plan.