Skip to content

Make large dependency SCCs bounded and actionable #5197

Description

@Widthdom

Summary

Repository-scale deps --cycles analysis can collapse into one enormous file-level strongly connected component. The result is technically complete but not actionable, and --suppress-noise is ineffective for the C# edges that dominate it.

On this repository, a production-only query returns one SCC containing 928 files, 64,728 internal edges, and 319,356 references. Noise suppression removes zero edges.

Environment

  • origin/main: c642bc4c3dda4ef659df8e6b699e10f61da3c836
  • cdidx v1.44.3, locally built
  • fresh complete graph with no reference-extraction cap hits
  • full net8.0 and net9.0 suites pass

Reproduction

dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll deps \
  --db .cdidx/codeindex.db \
  --path 'src/**' --exclude-tests \
  --cycles --suppress-noise \
  --graph-budget 100000 --limit 5 --json

Observed first and only component:

node count: 928
internal_edge_count: 64728
reference_count: 319356
noise edges removed: 0

The full response materializes all 928 paths. --summary-only reports a cycle count but omits the most useful facts such as largest component size, internal edges, references, and suppression breakdown.

Problem

  • One giant SCC does not identify a reviewable cycle.
  • Node arrays dominate human and machine output.
  • Summary mode cannot guide narrowing.
  • --suppress-noise sounds general but cycle SQL currently suppresses only a Markdown-heading origin.
  • Partial types and fallback/name-level edges can connect many files without explaining which evidence classes caused the SCC.

Proposed behavior

Keep analysis deterministic and truthful while adding an actionable large-component contract:

  1. Expose largest/returned SCC size, internal-edge count, reference count, and sampled nodes in summaries.
  2. Bound node materialization with authoritative counts and recovery/expansion guidance.
  3. Report retained edge evidence by language, resolution state, reference kind, and suppression reason.
  4. Let --suppress-noise remove documented conservative C# non-authoritative/fallback edge classes.
  5. Consider an explicit authoritative partial-family grouping/collapse option with mapping back to files.
  6. Preserve an explicit complete raw expansion mode.

Root cause and evidence

  • src/CodeIndex/Cli/QueryCommandRunner.Dependencies.cs:1001-1120 builds SCCs directly over file paths; every retained file edge contributes equally.
  • BuildDependencyCyclesJson around lines 1140-1157 serializes the full node list.
  • src/CodeIndex/Database/DbReader.DependencyCyclePlan.cs:31-45 changes cycle suppression only by filtering markdown_heading_name_match.
  • Existing dependency noise profiles used by ranking paths do not make C# cycle suppression meaningful.

Focused PR scope

One PR should focus on large-SCC diagnostics and bounded presentation:

  1. add summary metrics and node sampling;
  2. add evidence/suppression breakdowns;
  3. extend suppression only for well-defined non-authoritative edges;
  4. optionally group current authoritative partial families;
  5. retain complete expansion behind an explicit bound/continuation path;
  6. preserve graph-budget and cursor semantics;
  7. add documentation and the bilingual changelog fragment.

Non-goals

  • Do not implement compiler-grade whole-program dependency analysis.
  • Do not silently drop confirmed edges to make SCCs smaller.
  • Do not conflate output sampling with incomplete graph analysis.
  • Do not apply C# partial-type assumptions to every language.

Implementation guidance and cautions

  • Keep graph analysis completeness, edge suppression/coarsening, and output sampling as separate states.
  • analysis_complete must describe graph work, not whether every node was printed.
  • Publish suppression counts/reasons so --suppress-noise remains auditable.
  • Partial-family collapse must require current authoritative family metadata and fail closed when stale.
  • Preserve deterministic ordering and cursor fingerprints.
  • Provide narrowing and component-expansion recovery commands.

Required tests

  • Small two-/three-node SCCs unchanged.
  • A large synthetic SCC with bounded node output and authoritative totals.
  • Summary includes largest-component metrics.
  • C# fallback/noise suppression retains confirmed resolved calls.
  • Partial-family metadata ready, stale, absent, and cross-file cases.
  • Graph budget truncation distinct from display sampling.
  • Cursor stability, CLI/MCP parity, and large-graph performance.

Acceptance criteria

  • The repository-scale result can be understood without materializing 928 paths.
  • Summary reports node, edge, and reference totals for the largest SCC.
  • Samples carry authoritative omitted counts and recovery guidance.
  • Suppression reports what was removed and why.
  • No confirmed edge is silently removed.
  • Analysis completeness, display truncation, and grouping remain distinguishable.

Related history

This issue preserves those correctness contracts while addressing remaining large-component actionability. No exact current issue was found.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions