fix(cfg): surface skippedUnsoundFunctions in per-language stats (#2195 U2)

emitFileCdg computes skippedUnsoundFunctions (functions whose CDG is
withheld because EXIT isn't reverse-reachable from all blocks) but run.ts
dropped it on the floor — only cdgEdges/cdgDropped were aggregated. Add
the aggregation + a stats-line segment so CDG coverage gaps are an
explicit signal, not silent. Establishes the baseline skip count that
makes the U1 synthetic-escape pass's effect (the drop to genuine
anomalies only) measurable.

Additive; no emit-logic change. The emit-side field is covered by
cfg-emit.test.ts (asserts skippedUnsoundFunctions===1 + the warn on a
disconnected-block CFG); the run.ts aggregation is a thin pass-through.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Gergo Magyar 2026-06-14 15:41:34 +00:00
parent 417cc67a39
commit aa5edf12ab

View file

@ -778,6 +778,7 @@ export function runScopeResolution(
let rdTruncated = 0;
let cdgEdges = 0;
let cdgDropped = 0;
let cdgSkippedUnsound = 0;
// ── M3 taint setup (#2083 U4) ────────────────────────────────────────
// Explicit model-registration seam (idempotent, cheap) — the registry
// stays empty on non-pdg runs, preserving default-run parity. The
@ -899,6 +900,7 @@ export function runScopeResolution(
if (PROF) pdgMs += performance.now() - tCdg;
cdgEdges += cdg.edges;
cdgDropped += cdg.droppedEdges;
cdgSkippedUnsound += cdg.skippedUnsoundFunctions;
// M3 (#2083 U4): taint over the SAME validated CFGs, inside the SAME
// per-file try (a taint throw costs this file's taint layer only —
@ -975,6 +977,9 @@ export function runScopeResolution(
(rdTruncated > 0 ? `, ${rdTruncated} function(s) hit the fact limit` : '') +
`; ${cdgEdges} CDG edges` +
(cdgDropped > 0 ? `, ${cdgDropped} CDG edges dropped (per-function cap)` : '') +
(cdgSkippedUnsound > 0
? `, ${cdgSkippedUnsound} function(s) CDG-skipped (EXIT not reachable from all blocks)`
: '') +
// M3 volume telemetry — only for languages with a registered model.
(taintSpec !== undefined
? `; taint: ${taintTotals.findings} TAINTED, ${taintTotals.kills} SANITIZES ` +