= core-tools == purpose Defines the contract for executable tools in Correx (their name, description, parameter schema, tier, and required capabilities), tracks the lifecycle of each tool invocation (requested → started → completed/failed/rejected) as event-sourced state, and provides a registry for resolving tools by name. == responsibilities * Defining the `Tool` interface that all tool implementations must satisfy * Tracking tool invocation records and their status transitions * Rebuilding tool invocation state from the event log * Providing a registry for resolving tools by name * Defining execution capabilities (file read, file write, network access, shell exec, process spawn) * Validating tool requests against a tool's declared schema == non-responsibilities * Does not execute tools — execution is delegated to infrastructure adapters via `ToolExecutor` * Does not manage approval — tools declare a tier; approval is handled by `:core:approvals` * Does not emit events — all events are consumed from the event store * Does not define tool implementations — only contracts and state tracking == key types === Tool * **kind**: interface * **purpose**: Contract for an executable tool. Declares name, description, JSON parameter schema, execution tier, and required capabilities. === FileAffectingTool * **kind**: interface (extends `Tool`) * **purpose**: A tool that modifies files on disk. Adds `affectedPaths(request)` to track which files are touched. === ToolExecutor * **kind**: interface * **purpose**: Executes a `ToolRequest` and returns a `ToolResult`. The actual execution is delegated to infrastructure adapters. === ToolResult * **kind**: sealed interface * **purpose**: Outcome of a tool execution. * **variants**: * `Success(invocationId, output, exitCode, metadata)` — completed successfully * `Failure(invocationId, reason, recoverable)` — failed; `recoverable` flag signals retryability === ToolCapability * **kind**: enum * **purpose**: Declares what a tool can do. * **variants**: `FILE_READ`, `FILE_WRITE`, `NETWORK_ACCESS`, `SHELL_EXEC`, `PROCESS_SPAWN` === ValidationResult * **kind**: sealed interface * **purpose**: Whether a `ToolRequest` is structurally valid against a tool's schema. * **variants**: `Valid`, `Invalid(reason)` === ToolRegistry * **kind**: interface * **purpose**: Resolves a tool by name and lists all registered tools. === ToolState * **kind**: data class * **purpose**: Event-sourced projection of all tool invocations for a session. * **fields**: `invocations` (list of `ToolInvocationRecord`) === ToolInvocationRecord * **kind**: data class * **purpose**: Immutable record of a single tool invocation, including request, status, and receipt. * **fields**: `invocationId`, `toolName`, `tier`, `request`, `status`, `receipt`, `requestedAt`, `completedAt` === ToolInvocationStatus * **kind**: enum * **purpose**: Lifecycle status of a tool invocation. * **variants**: `REQUESTED`, `STARTED`, `COMPLETED`, `FAILED`, `REJECTED` === ToolReducer / DefaultToolReducer * **kind**: interface / class * **purpose**: Transforms `ToolState` given a stored event. Handles `ToolInvocationRequestedEvent`, `ToolExecutionStartedEvent`, `ToolExecutionCompletedEvent`, `ToolExecutionFailedEvent`, `ToolExecutionRejectedEvent`. === ToolProjector * **kind**: class * **purpose**: Wraps `ToolReducer` as a `Projection`. === DefaultToolRepository * **kind**: class * **purpose**: Rebuilds `ToolState` for a session via `EventReplayer`. == event flow *inbound:* * `ToolInvocationRequestedEvent` → adds a new record with status `REQUESTED` * `ToolExecutionStartedEvent` → sets status to `STARTED` * `ToolExecutionCompletedEvent` → sets status to `COMPLETED`, attaches receipt * `ToolExecutionFailedEvent` → sets status to `FAILED` * `ToolExecutionRejectedEvent` → sets status to `REJECTED` *outbound:* * None. This module is purely a projection — events are emitted by the orchestrator. == integration points * `:core:events` — `StoredEvent`, `ToolRequest`, `ToolReceipt`, invocation lifecycle event types, `ToolInvocationId` * `:core:approvals` — `Tier` (tools declare their execution tier) * `:core:sessions` — `Projection`, `EventReplayer` == invariants * Status transitions are append-only: records are never removed from `ToolState` * A record transitions through statuses monotonically: `REQUESTED → STARTED → {COMPLETED, FAILED, REJECTED}` * `ToolInvocationRecord.completedAt` is always null until the invocation reaches a terminal status * Each `ToolInvocationId` must be unique across all sessions == PlantUML diagram [plantuml, core-tools, "png"] ---- include::../../diagrams/core-tools.puml[] ---- == known issues None. == open questions None.