Documents the target-only invariant that makes a single sweep pass sufficient,
and adds two tests: the sweep does not trip the #479 shrink guard (swept
source-less orphans count as explained loss), and a stub still referenced by a
surviving file is not swept. Also adds the CHANGELOG entry.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
An external-import stub (source_file: "") is only ever an edge target of the
file that imported the symbol. When prune_sources removes that file, the stub
is stranded at degree 0 but no stale-node path reaches it (they all key on
source_file), so it accumulates in the node count, GRAPH_REPORT and exports.
build_merge now sweeps source-less degree-0 nodes that the prune just orphaned,
guarded against nodes that were already isolated beforehand so real content is
never touched.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>