grammar-inference-engine/docs/adr/0005-import-extraction-per-cluster.md
tobjend ca7ccb36ff
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
docs: add 8 architecture decision records
ADR 0001: nvim-treesitter highlights.scm as capture source
ADR 0002: language-agnostic method extraction via child_by_field_name
ADR 0003: method-level n-gram clustering before inference
ADR 0004: frequency filter with min_coverage threshold
ADR 0005: import extraction per cluster
ADR 0006: argument pattern extraction via AST node classification
ADR 0007: JSON output for LLM prompt injection
ADR 0008: BEX ensemble for grammar inference
2026-07-03 22:01:35 +02:00

45 lines
2.1 KiB
Markdown

# 5. Import extraction per cluster
**Date:** 2026-07-03
**Status:** Accepted
## Context
An LLM prompted with a behavioral convention like `every → assertEquals → verify` still needs to know *which imports to use*. Without imports, it will guess the wrong library — writing `from unittest.mock import patch` instead of `import io.mockk.every`, or importing from `jest` instead of `vitest`.
Imports are the bridge between abstract conventions and actionable code.
## Decision
For each cluster, scan the source files whose methods belong to that cluster and extract all unique import lines.
Language-agnostic approach: match lines against common import patterns:
- `import ...` (Java, Kotlin, Python, Go, JS/TS)
- `from ... import ...` (Python)
- `require ...` / `require_relative ...` (Ruby, JS)
- `#include ...` (C/C++)
- `use ...` (Rust)
- `include ...` (Ruby)
Scan the first 200 lines of each file (imports are always at the top), deduplicate across files, and sort the result.
File-to-cluster mapping is preserved by tracking `(file_path, sequence)` pairs through the pipeline. After `frequency_filter` (which preserves order and count), we use object identity to map each clustered sequence back to its source file.
## Consequences
**Positive:**
- Each cluster shows exact import lines used by its methods.
- An LLM can copy these directly — no guessing.
- Reveals *library choice conventions*: `kotlin.test.*` vs `org.junit.jupiter.api.*`, `io.mockk.coEvery` vs `io.mockk.every`.
**Negative:**
- Import scanning re-reads files (second pass). Negligible cost since files are small and OS-cached.
- 200-line scan limit might miss imports in files with very long license headers.
- Lines containing `import` in prose (comments, strings) may produce false positives — rare in practice.
## Alternatives Considered
- **Single global import list**: Simpler but useless — conflates imports from unrelated clusters.
- **No imports**: LLM must guess. Leads to wrong imports and broken code.
- **Per-file imports (not per-cluster)**: Too granular — mixes test imports with production imports in the same file.