# Epic 8 — Tool System (core:tools)

## completed deliverables

### 1. shared vocabulary in core:events

introduced tool identity, request/receipt types, and a serialization bridge for dynamic parameters.

final structures:

* `ToolInvocationId` — typealias added to `IdentityTypes.kt`
* `ToolRequest` — captures invocation identity, session, stage, tool name, and arbitrary parameters
* `ToolReceipt` — captures exit code, output summary, structured output, affected entities, duration, tier, and timestamp
* `AnyMapSerializer` — `Map<String, Any>` ↔ JSON bridge via `JsonElement`; required because kotlinx.serialization cannot serialize `Any` directly

key properties:

* shared vocabulary lives in `core:events` to prevent circular dependencies
* `core:tools` depends on `core:events`, not the reverse
* parameters and structured output are fully round-trip serializable

---

### 2. tool lifecycle events in core:events

introduced five event classes covering the full execution lifecycle of a tool invocation.

final events:

* `ToolInvocationRequestedEvent` — invocation submitted with request and tier
* `ToolExecutionStartedEvent` — execution begun
* `ToolExecutionCompletedEvent` — execution succeeded; carries `ToolReceipt`
* `ToolExecutionFailedEvent` — execution failed; carries reason string
* `ToolExecutionRejectedEvent` — invocation rejected before execution; carries tier and reason

all five events:

* implement `EventPayload`
* registered in `Serialization.kt` polymorphic block
* validated via 8 round-trip serialization tests

---

### 3. tool contract interface (core:tools)

defined the `Tool` interface as the stable contract that all tool implementations must satisfy.

final structures:

* `Tool` — plain interface (not sealed; infrastructure implements it)
* `ToolCapability` — enum: `FILE_READ`, `FILE_WRITE`, `NETWORK_ACCESS`, `SHELL_EXEC`, `PROCESS_SPAWN`
* `ValidationResult` — sealed interface: `Valid` / `Invalid(reason)`

interface properties:

* `name: String`
* `tier: Tier`
* `requiredCapabilities: Set<ToolCapability>`
* `validateRequest(request: ToolRequest): ValidationResult`

`core:tools` declares the contract; it never executes tools. Infrastructure modules provide concrete implementations.

---

### 4. event-sourced state model

introduced the state layer that tracks all tool invocations for a session.

final structures:

* `ToolInvocationStatus` — enum: `REQUESTED`, `STARTED`, `COMPLETED`, `FAILED`, `REJECTED`
* `ToolInvocationRecord` — holds the full lifecycle of one invocation: id, name, tier, request, status, optional receipt, requested/completed timestamps
* `ToolState` — root state: `invocations: List<ToolInvocationRecord>`

properties:

* fully `@Serializable` throughout
* state is always rebuilt from events; never persisted independently
* `receipt` and `completedAt` are nullable; populated only on terminal events

---

### 5. reducer, projector, and repository

implemented the standard CORREX pattern for event-sourced state reconstruction.

final components:

```text
ToolReducer (interface)
    └── DefaultToolReducer (applies 5 lifecycle events to ToolState)

ToolProjector (implements Projection<ToolState>)
    └── bridges reducer to EventReplayer infrastructure

DefaultToolRepository
    └── thin wrapper over EventReplayer<ToolState>
        └── getToolState(sessionId): ToolState
```

reducer behavior:

* `ToolInvocationRequestedEvent` → appends new `REQUESTED` record
* `ToolExecutionStartedEvent` → transitions matching record to `STARTED`
* `ToolExecutionCompletedEvent` → transitions to `COMPLETED`, attaches receipt and completedAt
* `ToolExecutionFailedEvent` → transitions to `FAILED`, sets completedAt
* `ToolExecutionRejectedEvent` → transitions to `REJECTED`, sets completedAt
* unrelated events → pass through unchanged

wiring (`DefaultEventReplayer(store, ToolProjector(DefaultToolReducer()))`) is left to infrastructure modules.

---

### 6. mock tools in testing:fixtures

introduced three deterministic tool implementations for use across test suites.

final tools:

* `EchoTool` — tier T0, always returns `ValidationResult.Valid`
* `FailingTool` — tier T2, always returns `ValidationResult.Invalid("simulated validation failure")`
* `RejectedTool` — tier T4, always returns `ValidationResult.Valid`

`testing/fixtures/build.gradle` gains `:core:tools` dependency.

tier assignment mirrors the approval tier model: T0 (auto-approve), T2 (requires approval), T4 (always reject).

---

# final architecture after Epic 8

```text
Tool (interface — core:tools)
    ↓
ToolRequest / ToolReceipt (core:events — shared vocabulary)
    ↓
5 lifecycle EventPayload subclasses (core:events)
    ↓
DefaultToolReducer → ToolState (event-sourced projection)
    ↓
ToolProjector → EventReplayer → DefaultToolRepository
```

---

# major architectural outcomes

Epic 8 established:

* safe tool contract: execution is infrastructure's responsibility, not core's
* full lifecycle event coverage from request to terminal state
* deterministic, replay-safe tool invocation tracking
* tier-aware tool classification aligned with the approval system
* reusable mock tools for integration and deterministic test suites

---

# what Epic 8 intentionally does NOT include

not implemented:

* concrete tool implementations (file I/O, shell, network — infrastructure concern)
* approval gating logic (Epic 5)
* tool registry or discovery mechanism
* execution engine or sandbox enforcement
* kernel orchestration of tool invocations

those are explicitly deferred to infrastructure modules and later epics.

---

# final state

Correx now has:

> a complete tool abstraction layer: a stable contract interface, a full five-event lifecycle model, event-sourced invocation state with reducer/projector/repository, and deterministic mock tools for testing — with no coupling to execution infrastructure.
