Files
correx/docs/modules/infrastructure/infra-tools-filesystem.adoc
kami 9734eec63c docs: add module documentation in AsciiDoc with PlantUML diagrams
Generated by per-group subagents covering all 52 modules across:
core (18), infrastructure (10), apps (5), interfaces (3),
plugins (7), testing (9)

Documentation format:
- AsciiDoc (.adoc) files in docs/modules/<group>/
- PlantUML (.puml) files in docs/diagrams/
- .adoc files reference diagrams via include:: directives

Each doc covers: purpose, responsibilities, non-responsibilities,
key types, event flow, integration points, invariants, PlantUML
diagram, known issues, and open questions.
2026-05-26 16:59:21 +04:00

83 lines
3.8 KiB
Plaintext

= infra-tools-filesystem
== purpose
Provides three filesystem tool implementations for the Correx tool system: `FileReadTool` (read file content with optional line range), `FileWriteTool` (write or delete files with artifact capture via CAS), and `FileEditTool` (append, replace, or patch file content). All tools enforce path allowlisting and validate parameters before execution.
== responsibilities
* Read file contents with optional 1-indexed line range slicing
* Write content to files, optionally capturing artifacts to the CAS store
* Delete files on disk
* Edit files via three modes: append (add to end), replace (exact-target string replacement), patch (apply unified diff via external `patch` command)
* Validate paths against configured allowlists
* Report affected paths for sandbox backup/diff tracking
== non-responsibilities
* Do not implement sandboxed execution — that belongs to `infra:tools` (`SandboxedToolExecutor`)
* Do not define tool contracts — that belongs to `core:tools`
* Do not manage file permissions beyond optional POSIX mode setting
* Do not perform approval gating
== key types
=== FileReadTool
* **kind**: class
* **purpose**: Reads a file from disk within allowed paths, with optional start/end line range. Tier T1.
* **fields**: `allowedPaths` (set of permitted root directories)
=== FileWriteTool
* **kind**: class
* **purpose**: Writes content to a file or deletes a file, validates path against allowlist, optionally captures a `FileWrittenArtifact` to the CAS store. Tier T2.
* **fields**: `allowedPaths`, `artifactStore`, `materializingWriter`, `sandboxRoot`, `workingDir`
=== FileEditTool
* **kind**: class
* **purpose**: Edits a file via three operations: `append`, `replace` (exact single-occurrence string replacement), or `patch` (applies unified diff via external `patch` binary). Tier T3.
* **fields**: `allowedPaths`, `workingDir`
== event flow
*Inbound:* `ToolRequest` with parameters (`path`, `content`, `operation`, etc.)
*Outbound:* None directly. Event emission is handled by the wrapping `SandboxedToolExecutor`. The tools return `ToolResult.Success` or `ToolResult.Failure` synchronously.
== integration points
* `core:tools.contract` — `Tool`, `ToolExecutor`, `ToolResult`, `FileAffectingTool`, `ToolCapability`, `ValidationResult`
* `core:approvals` — `Tier`
* `core:artifactstore` — `ArtifactStore`
* `core:artifacts` — `MaterializingArtifactWriter`, `MaterializationResult`, `FileWrittenArtifact`, `FileWrittenPayload`
* `infra:artifacts-cas` — used by `FileWriteTool` for CAS artifact storage (via writer interface)
== invariants
* All tools validate path against allowed paths — if `allowedPaths` is empty, validation fails ("No paths are allowed")
* `FileWriteTool` prevents directory traversal via path normalization
* `FileEditTool.replace()` requires exactly one occurrence of the target string — zero or multiple occurrences produce a failure
* `FileEditTool.patch()` requires the external `patch` utility to be available
* All tools run on `Dispatchers.IO` for blocking filesystem operations
== PlantUML diagram
[plantuml, infra-tools-filesystem, "png"]
----
include::../../diagrams/infra-tools-filesystem.puml[]
----
== known issues
* `FileEditTool.patch()` shells out to the `patch` binary — not available on all platforms; no error if `patch` is missing beyond a failed `ProcessBuilder`
* `FileWriteTool.storeArtifact()` silently logs on materialization failure rather than failing the tool call
* `FileEditTool.replace()` reads the entire file into memory — unsuitable for very large files
* `FileWriteTool` and `FileEditTool` have duplicated path resolution logic
== open questions
* Should `FileEditTool` support a pure-Kotlin patching implementation to remove `patch` dependency?
* Should line-range edits (insert before/after line N) be added?