grammar-inference-engine/docs/adr/0010-universal-package-mapping-via-relpath.md
tobjend e23922a1b7
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
feat: adaptive multi-assignment clustering; add ADRs 1-10
- Multi-assignment clustering (no greedy 'used' set)
- Adaptive ngram fallback (shrink when (other) > 60%)
- Add docs/adr/ with 10 architecture decision records
- Fix ADR 1 (query modification description)
- Fix ADR 3 (multi-assignment + adaptive shrink)
- Fix ADR 5 (import sort order clarification)
- Fix ADR 6 (remove Kotlin call_suffix references)
- New ADR 9 (adaptive clustering rationale)
- New ADR 10 (universal package mapping via relpath)
2026-07-03 22:58:09 +02:00

56 lines
2.5 KiB
Markdown

# 10. Universal package mapping via project-relative path
**Date:** 2026-07-03
**Status:** Accepted
## Context
Each detected behavioral convention needs a "package" or "module" label so the LLM knows where to place generated code. Options:
- **No package info**: LLM guesses wrong directory, generates code at project root.
- **Per-language directory lookup**: Hardcode `kotlin`/`java`/`python` source root names. Breeds per-language branches — violates the zero-adapters constraint.
- **Full file path**: Too verbose, exposes absolute system paths (/home/user/project/...).
- **Project-relative path**: Pure path arithmetic, no language assumptions.
## Decision
Derive the package from the file's directory relative to the project root:
```python
def _file_to_package(fp, project_root):
rel = os.path.relpath(os.path.dirname(fp), project_root)
if rel == ".":
return "" # file at project root
return rel
```
No source root markers. No per-language directory names. Just `relpath` from the root the user passed to `analyze_directory`.
Examples:
```
/project/src/main/kotlin/org/app/User.kt → src/main/kotlin/org/app
/project/mypackage/module.py → mypackage
/project/lib/core/helper.rb → lib/core
/project/src/main.rs → src
/flat/project/file.py → flat
```
The project root is the directory passed to `analyze_directory(...)` and threaded down through `analyze_clusters``_top_packages`.
## Consequences
**Positive:**
- Zero per-language branches. Works identically for all 10 languages.
- No configuration or convention list to maintain.
- LLM sees the exact directory structure it should mirror in generated code.
**Negative:**
- `relpath` assumes the project root is the scan root. Scanning a subdirectory gives partial paths (still correct, but missing context).
- Files at the root of deeply nested projects get empty package strings. Mitigation: users should scan from the project root.
## Alternatives Considered
- **Per-language source root list (reverted)**: Hardcoded `kotlin`/`java`/`python` directory names. Brittle, violated zero-adapters constraint. Reverted to `feature/kotlin-specific-extras`.
- **Source root markers (`src`/`lib`/`pkg`/`app`)**: Broader than per-language but still assumes project layout conventions. Broke for flat repos, non-standard layouts.
- **No package mapping**: Simpler but useless — LLM can't locate generated code. The package label is essential for file placement.