Resolved findings → pentiment frames → Mix.Task.Compiler.Diagnostic.
Driver-side presentation: nothing here is memoized, and the query
graph never renders. Each resolved finding (file + line + prose +
labelled related anchors, from Scry.Analysis.analysis_diagnostics)
becomes one pentiment report:
- the primary anchor is an inline label under the code of its line,
annotated with the finding's
at_label. BEAM anchors are line-granular, so the span is the line's code extent (first non-blank column to the end of the trimmed line), read from the source file; a line that cannot be read degrades to column 1; - same-file related anchors are secondary inline labels in the same
excerpt; cross-file related anchors carry
source:and render as├─[file:line:col]continuation frames against their own file; detailrenders as a note,helpentries as help trailers.
The Mix bridge follows the roux/haruspex pattern: the Diagnostic
carries a short message and an integer line position for editors,
and the full rendered frame rides in details — print/1 puts the
frame on stderr. Terminal output re-renders with colors: true
(pentiment itself degrades when stderr is not a TTY); details and
the persisted sidecar stay color-free.
File-level ignores apply here, at emission — an ignored file's facts still feed every cross-module analysis. Reports are suppressed, truth is not.
Summary
Types
A diagnostic paired with its ANSI rendering for terminal output.
Functions
Builds diagnostics from analysis_diagnostics values, most severe
first.
Builds an infrastructure diagnostic (no source frame): souffle missing, an analysis degraded, and similar conditions that are about the run rather than the code.
Prints rendered diagnostics to stderr, frames separated by blank lines.
Relativizes an absolute path against cwd, tolerating the macOS
/var ↔ /private/var symlink spelling difference.
The filtered, severity-overridden, sorted finding entries — the shared
substrate for both rendering (build/3) and machine formats
(Scry.Report.json/2).
Types
@type rendered() :: %{diagnostic: Mix.Task.Compiler.Diagnostic.t(), ansi: String.t()}
A diagnostic paired with its ANSI rendering for terminal output.
Functions
@spec build(%{optional(String.t()) => [map()]}, Scry.Config.t(), String.t()) :: [ rendered() ]
Builds diagnostics from analysis_diagnostics values, most severe
first.
Paths are relativized against cwd for display; the Diagnostic
keeps the absolute path.
Builds an infrastructure diagnostic (no source frame): souffle missing, an analysis degraded, and similar conditions that are about the run rather than the code.
@spec print([rendered()]) :: :ok
Prints rendered diagnostics to stderr, frames separated by blank lines.
Relativizes an absolute path against cwd, tolerating the macOS
/var ↔ /private/var symlink spelling difference.
@spec resolve(%{optional(String.t()) => [map()]}, Scry.Config.t(), String.t()) :: [ map() ]
The filtered, severity-overridden, sorted finding entries — the shared
substrate for both rendering (build/3) and machine formats
(Scry.Report.json/2).
findings_by_file merges every demanded analysis's resolved map.
File-level ignores drop entries here; severity overrides apply here.