An analysis-only Mix.Task.Compiler: append it after the stock
compilers and it reads the .beam files they just produced, runs the
configured argus analyses incrementally, and reports findings as
compiler diagnostics with pentiment-rendered frames.
def project do
[compilers: Mix.compilers() ++ [:scry], ...]
endBecause scry runs last, its :error status can never block another
compiler — only the overall exit status. And because Mix halts the
compiler chain on :error, scry only ever sees the ebin of a
successful compile.
Cross-VM incrementality comes from Roux.Lang.Manifest: extraction
and solve memos persist per run, so a warm mix compile re-runs
nothing for unchanged beams, a comment-only edit re-extracts one
module and re-runs zero Souffle solves (the semantic-facts cutoff
seam), and prior findings re-emit from memo hits on every run —
including :noop runs, matching the Elixir compiler's
--all-warnings behavior.
Configuration lives under the scry: project key — see Scry.Config.
Status: findings are warnings by default and never fail the build;
fail_on: :warning promotes any finding to a build failure (CI), and
souffle: :require makes a missing solver an error instead of a
notice.