# core/toolintent — AGENTS.md ## Purpose Plane-2 tool-call intent validation: evaluates proposed tool calls against workspace policy rules before execution, records the assessment as an event, and provides `WorldProbe` for recording environment observations needed by rules. ## Ownership CORREX kernel team. This module enforces Hard Invariant #9 for the tool-call path. ## Local Contracts - `ToolCallAssessor` — evaluates a proposed tool call against all active `ToolCallRule`s; returns a `ToolCallAssessmentRecord`. - `ToolCallRule` — interface for a single validation rule. Built-in rules: - `PathContainmentRule` — tool must write within the workspace root. - `ReadBeforeWriteRule` — file must be read before being overwritten. - `StaleWriteRule` — detects write to a file that has changed on disk since last read. - `NetworkHostRule` — egress must be on the allowlist. - `ManifestContainmentRule` — write target must appear in the write manifest. - `WriteScopeRule` — enforces declared write scope. - `ReferenceExistsRule` — referenced entities must exist. - `ExecInterpreterRule` — interpreter must be in the allowed list. - `CycleExitRule` (in `core:validation`) — imported separately; not defined here. - `WorkspacePolicy` — aggregates rules and configuration for a workspace. - `WorldProbe` — performs environment checks (filesystem, network) and records the observations as events immediately (Hard Invariant #9). Never call `WorldProbe` during replay. - `EgressAllowlist` — current egress allowlist; rebuilt from `EgressAllowlistProjection` (in `core:events`). - `ParamValueExtractor` — extracts typed parameter values from tool call arguments. `candidatePathStrings` = every path-like argument (`ParamRole.PATH` + `ParamRole.SOURCE_PATH`), used by the containment/existence gates; `writeTargetPathStrings` = only the paths a call MUTATES (`ParamRole.PATH`), used by the write-target gates. A tool declaring none of those roles falls back to sniffing path-like strings, so `shell` is unaffected. - `RiskMapping` — maps rule violations to risk levels for `core:risk`. - `SessionContext` — session-scoped context passed to rules during evaluation. ## Work Guidance - Hard Invariant #9: all `WorldProbe` calls record observations as events. Replay reads those recorded events — it must not call `WorldProbe` again. - Hard Invariant #5: every tool call must be assessed before execution. Assessment result is recorded as `ToolCallAssessmentEvents` in `core:events`. - New rules implement `ToolCallRule` and are registered in `WorkspacePolicy`. Do not add rule logic directly to `ToolCallAssessor`. - Resolve every model-supplied path through `ToolPath.resolve` (`core:tools`) — the one canonical normalization rule, shared with the filesystem tools. A rule that resolves paths itself will judge a different path than the tool operates on (the `~` bug: `~/x` resolved to `/~/x`, so a real home-directory file was reported as a non-existent in-workspace file and the out-of-workspace prompt never fired). - `ReadBeforeWriteRule` exempts calls declaring `ToolCapability.CONTENT_FROM_SOURCE` — every byte written comes from an existing source object, so there is no model-authored content to clobber with, and requiring a read of a copied binary is unsatisfiable. The exemption keys on that declared PROVENANCE, never on the presence of a `SOURCE_PATH` parameter: a transform or import tool may name a source and still write model-controlled output, and must stay gated. It lives in `appliesTo`, so `ToolCallAssessor` skips the rule entirely. ## Verification ```bash ./gradlew :core:toolintent:test --rerun-tasks ``` ## Child DOX Index No child AGENTS.md (leaf module).