Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
- 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)
2.5 KiB
2.5 KiB
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/pythonsource 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:
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:
relpathassumes 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/pythondirectory names. Brittle, violated zero-adapters constraint. Reverted tofeature/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.