= 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<ToolState>`.

=== 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.
