0.9.13 — The baseline finds its home
Release 0.9.13 — The baseline finds its home
Released: 2026-08-08
🇩🇪 Deutsche Version
A big release. Baselines get a canonical home and a CI-safe switch, a
new corpus-proven rule catches a silent Delphi trap, the standalone EXE
catches up with the plugin on triage workflow — and its dark mode looks
like an editor, not a cave. Plus one revival story: two DFM rules that
had silently never fired in production do now.
Baselines: the .sca folder and --baseline-scan
The baseline JSON now has a standard location next to what you scan:
<dir>\.sca\<ProjectName>.baseline.json for a project or group (a
project falls back to its group's .sca one level up), or
<dir>\.sca\sca.baseline.json for a plain path scan.
Everything resolves it the same way — explicit --baseline wins, then
[Baseline] File= from analyser.ini, then the .sca default:
- CLI:
--baseline-scan yfilters against the resolved baseline and
fails hard (exit 99) when none exists, listing every probed path —
a typo in CI must not silently report "everything is new". A missing
explicit--baseline <file>is a hard error now too (previously a
silent no-op).--write-baseline autowrites to the.scadefault
and creates the folder. - Standalone EXE and IDE plugin: the Show only new findings
(baseline) toggle lives in both hamburger menus now and resolves the
.scalocation on its own — no hand-edited INI needed. Enabling it
with no baseline anywhere offers to write one on the spot; Write
baseline pre-fills the.scatarget. The plugin resolves via the
IDE's active project or group and its silent mode (the editor
markers while you type) honours the baseline too. - Opt-in
[Baseline] PathInFingerprint=1: fingerprints can include
the normalized relative path, so same-named files in different folders
stop sharing accepted findings. Off by default — it costs one baseline
rewrite and path stability; apathFingerprintmarker in the JSON
turns a mode mismatch into a warning instead of a silent non-match.
Baseline files remain interchangeable between CLI, EXE, plugin and HTML
report — a baseline written by the plugin filters a CLI scan.
New rule: SCA196 ManagedResultUninit
For managed return types (strings, dynamic arrays, Variant,
interfaces) Result is a hidden var parameter that aliases the caller's
target variable including its old content — and the compiler's
W1035 stays silent for exactly these types. A collector like
function Collect: TArray<string>;
begin
Result := Result + [x]; // appends to the CALLER's old array
end;works in the first call and duplicates data ever after. SCA196 reports
the first Result read before the first write. Three corpus measurement
rounds (2171 → 105 → 51 findings after two false-positive hunts), then
every one of the 49 unique sites verified by hand: 100 % precision,
real bugs in well-known projects among them. Ships at medium confidence
— visible in the default profile — with a localized before/after fix
hint (en/de/fr).
Two DFM rules were dead — now they live, hardened
A systematic always-zero audit found that SCA040 DfmCrossFormCoupling
and SCA042 DfmGodHandler ran before the event-binding repository
was populated: zero findings on every real scan since their
introduction. Both moved behind the binding build-up — and then got
hardened on the corpus: SCA040 no longer counts locals/parameters/
fields that shadow a form name (low confidence until the next precision
round); SCA042 stays silent when a handler's bindings all share one
component class and one event type — uniform parameterised bundling is
a pattern, not a god handler (−71 % on the corpus). In the same wave:
SCA032 no longer crashes on duplicate component names,
SCA034/SCA035 skip DataModule roots (false-positive swarm),
SCA091 and 15 further detectors blank string literals before
matching, SCA110–112 stop swallowing the statement after a
single-statement loop, and SCA101 finally sees the most common
if-formatting of all: the branch on the next line.
The standalone EXE catches up
Everything the plugin could do for triage, the EXE does now: keyboard
triage (Enter opens, Ctrl+Alt+S suppresses, Ctrl+Alt+F quick-fixes)
through a byte-faithful line editor that preserves encoding, line
endings and a missing trailing newline exactly — verified by a
round-trip probe that refuses to write rather than damage a file.
Stat tiles filter the grid. Column headers sort honestly. A right-click
menu mirrors the shortcuts. The window remembers size, position and
column widths. Findings can open in the editor of your choice
([Editor] in analyser.ini: VS Code, Notepad++, Sublime, …) or in
the Delphi IDE. Crash diagnostics report module-relative,
ASLR-surviving addresses. And a long tail of fixes — from the arrow key
that overwrote the clipboard thirty times a second to the sort arrow
that sat on the wrong column.
Dark mode: "SCA VSDark"
The EXE follows the Windows app theme (or a fixed choice under
Appearance). New in this release: the embedded dark style is SCA
VSDark — the VS Code Dark Modern palette (chrome #181818, content
#1F1F1F, inputs #313131, text #CCCCCC) instead of the stock
Windows10 Dark, which literally paints clBlack everywhere. The style
is generated reproducibly from the Redist original by
tools/make_scadark_style.py.
Full details in the CHANGELOG.