Skip to content

v2.0.0

Choose a tag to compare

@dannote dannote released this 05 May 13:17
· 152 commits to master since this release

Breaking changes

New canonical CLI — five dotted commands replace 15+ legacy tasks:

mix reach.map          # project overview (modules, hotspots, coupling, effects, depth, data)
mix reach.inspect TARGET  # function/module deep-dive (deps, impact, graph, candidates, --why)
mix reach.trace        # taint flow, variable tracing, backward/forward slicing
mix reach.check        # architecture policy, changed-risk, dead code, smells, candidates
mix reach.otp          # GenServer/gen_statem analysis, concurrency

Old task names raise with exact migration instructions.

What's new

  • .reach.exs architecture policy — layers, forbidden deps/calls, effect allowlists, public/internal boundaries, risk thresholds, test hints. Enforced via mix reach.check --arch.

  • Advisory refactoring candidatesbreak_cycle, isolate_effects, extract_pure_region, introduce_boundary with confidence scores and graph proof. Not auto-edits — evidence for humans/agents.

  • 30+ smell checks — pattern-based (ExAST ~p sigil) and IR-based:

    • Collection idioms, pipeline waste, loop O(n²) antipatterns
    • String building (iolists), config phase mistakes, dual key access
    • Fixed-shape map / behaviour extraction candidates
    • Clone-backed structural drift (return contract, side-effect order, validation)
    • Guard equality, Map.update-then-fetch, chained String.replace
  • Changed-risk reportsmix reach.check --changed --base main shows risk score, caller impact, clone siblings, and suggested tests.

  • --why relationship explanationsmix reach.inspect A --why B shows call paths, module dependency chains, or data flow connecting two targets.

  • Plugin-owned framework semantics — Phoenix, Ecto, Oban, Ash, Jido, OpenTelemetry, GenStage, QuickBEAM. Framework-specific trace patterns, behaviour labels, and graph edges live in plugins, not core.

  • Frontend registry — Elixir, Erlang, Gleam, JavaScript/TypeScript frontends behind Reach.Frontend dispatch.

Improved

  • Taint tracing ~40× faster on large codebases (Plausible: 130s → 3s)
  • All domain structs use @derive Jason.Encoder — clean JSON, no custom serialization
  • ProgramFacts oracle validation with metamorphic fuzzing and stress harness
  • 553 tests, 7 properties, full CI (format, credo strict, ExDNA, dialyzer, architecture policy)

Stats

Validated across 20 real codebases (Phoenix, Ecto, Ash, Elixir stdlib, Livebook, Oban, Absinthe, Nx, Broadway, Surface, and more): zero crashes, 2,232 smell findings.