Skip to content

ADR-0009: Project import & auto-improvement

  • Status: Accepted
  • Date: 2026-06-05
  • Deciders: AOP core

Context

Phase 6 accepts an uploaded project (path / zip / git URL), analyzes it (static, AST, dependencies, data-leakage), runs an LLM review, produces a structured report, and applies approved improvements with a diff preview.

Decisions

1. Always operate on an isolated copy

Imports are copied/extracted/cloned into data/projects/<id>/project. All analysis and every apply touches only that copy — the user's original is never modified. apply is gated behind explicit approval and a unified-diff preview.

2. Real tools, no mocks

  • Static: ruff and mypy run as subprocesses with the target's own config ignored (ruff --isolated, lenient mypy --ignore-missing-imports) for a consistent baseline. Tools are located next to the active interpreter.
  • AST: cyclomatic complexity, function size/arity, parse errors, and project metrics from Python's ast.
  • Dependencies: parsed from pyproject.toml/requirements*.txt; unpinned specs flagged. (CVE scanning via pip-audit was deliberately deferred — no network dependency.)
  • Data leakage: high-precision AST heuristics (fit/fit_transform before train_test_split; split without random_state). Semantic leakage is left to the LLM review.

3. LLM review + LLM-generated diffs

The local LLM reviews the largest files for issues (severity-tagged) and, on demand, rewrites a file; the result becomes a unified diff (preview) + full revised content (applied on approval). Diff quality scales with the model; the mechanism is real and safe (copy-only, gated).

4. CLI + API first

aop project import|analyze|report|improve|apply and POST /projects/.... A dedicated frontend page was deferred; the structured ProjectReport (JSON) is the deliverable and is UI-ready.

Consequences

  • Positive: the full audit→review→improve→apply loop runs locally and safely; the platform can even analyze itself (verified in tests + demo).
  • Caveats:
  • ruff --isolated uses ruff's default line length (88), so a project configured for a different width shows E501s — expected baseline behavior.
  • LLM refactors from a tiny local model are best-effort; review before applying (the diff preview + approval gate exist precisely for this).
  • Python-focused static analysis; non-Python files get LLM review only.