Skip to content

feat(#2884): ToolCapabilityExtractor — static capability classification#121

Merged
Skobeltsyn merged 1 commit into
mainfrom
feat/2884-capability-extractor
Jun 1, 2026
Merged

feat(#2884): ToolCapabilityExtractor — static capability classification#121
Skobeltsyn merged 1 commit into
mainfrom
feat/2884-capability-extractor

Conversation

@Skobeltsyn
Copy link
Copy Markdown
Contributor

Slice 4 of epic #2882 — the last self-contained piece. New ToolCapabilityExtractor in agents-kt-detekt. TDD. (Reframed from KSP to detekt — KSP can't see lambda bodies.)

What

Statically classifies what a tool's executor body actually does — FS_READ / FS_WRITE / NETWORK / ENVIRONMENT / EXEC — by walking its call expressions and matching callee names (writeText/Files.write → write, readText/readAllBytes → read, URL/openConnection → network, getenv → env, ProcessBuilder/Runtime.exec → exec).

extract(scope: KtElement): Set<ToolCapability> is the reusable input the #2887 comparator will check against the declared ToolPolicy. Not wired into the project's own detekt — it's infrastructure for #2887, not a standalone codebase rule.

Honest limit: syntactic (callee-name match, no FQN resolution), intentionally conservative — over-classification only widens review for the comparator, never hides authority. Reflection / aliasing / transitive state are Pillar-3 residual (documented).

Tests (9, TDD RED→GREEN)

fs-write · fs-read · Files.write/readAllBytes by nio names · network · environment · exec (ProcessBuilder + Runtime.exec) · pure-compute = empty · bare File handle = empty · multi-capability body. Driven via detekt-test compileContentForTest.

Verified: full ./gradlew build green. With this, all four self-contained slices of epic #2882 are done; #2887 (comparator) + the #2883/#2889 ABI are the remaining architectural core.

🤖 Generated with Claude Code

Epic #2882 (Pillar 1, static layer), TDD. New ToolCapabilityExtractor in
agents-kt-detekt: classifies what a tool's executor body actually does
(FS_READ / FS_WRITE / NETWORK / ENVIRONMENT / EXEC) by walking call
expressions and matching callee names. The reusable input the #2887
comparator checks against the declared ToolPolicy.

- extract(scope: KtElement): Set<ToolCapability> — collects call expressions
  under a scope (the executor lambda) and classifies by callee name.
- Conservative + syntactic by design (no FQN resolution); reflection/aliasing/
  transitive state are Pillar-3 residual (documented). Over-classification only
  widens review for the comparator, never hides authority.
- Not wired into the project's own detekt — it's infrastructure for #2887,
  not a standalone codebase rule.

Tests (9, TDD RED->GREEN, via detekt-test compileContentForTest): fs-write,
fs-read, Files.write/readAllBytes by nio names, network, environment, exec
(ProcessBuilder + Runtime.exec), pure-compute = empty, bare File handle =
empty, multi-capability body. CHANGELOG. Full ./gradlew build green.
@Skobeltsyn Skobeltsyn merged commit b5300ab into main Jun 1, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant