Skip to content

Incremental build leaves stale cyclomatic complexity for unchanged functions in a changed file #1743

Description

@carlos-alm

Summary

codegraph build (default incremental mode) computes wrong cyclomatic complexity values for functions that were not edited, when they live in a file that was edited elsewhere. cognitive, Halstead volume/bugs, loc, and sloc are all correct — only cyclomatic (and the maintainabilityIndex derived from it) come out wrong. A full clean rebuild (rm .codegraph/graph.db && codegraph build, or codegraph build --no-incremental) recomputes the correct values.

Repro

  1. On a clean checkout, run a full build and record complexity for an untouched function, e.g.:
    codegraph build
    codegraph complexity --file src/extractors/javascript.ts --health -T --json -n 300 | jq '.functions[] | select(.name=="extractReturnTypeMapWalk")'
    # cyclomatic: 26, cognitive: 48, mi: 47.8
    
  2. Edit an unrelated function earlier in the same file (e.g. decompose a different function into helpers, adding/removing lines above extractReturnTypeMapWalk but not touching it at all).
  3. Rebuild incrementally (default mode, no --no-incremental):
    npm run build   # rebuild dist/ for the WASM path if relevant
    codegraph build
    codegraph complexity --file src/extractors/javascript.ts --health -T --json -n 300 | jq '.functions[] | select(.name=="extractReturnTypeMapWalk")'
    
    Observed: cyclomatic: 1 (!), cognitive: 48 (unchanged, correct), mi: 51.1 (wrong, since it's derived partly from cyclomatic).
  4. Delete .codegraph/graph.db and rebuild fully (or pass --no-incremental):
    rm .codegraph/graph.db
    codegraph build
    codegraph complexity --file src/extractors/javascript.ts --health -T --json -n 300 | jq '.functions[] | select(.name=="extractReturnTypeMapWalk")'
    
    Now cyclomatic: 26 again — correct, matching step 1.

Observed the same pattern for several other untouched functions in the same file during a real refactor (all had cognitive/volume/bugs/loc/sloc unchanged, but cyclomatic dropped to implausibly low values like 1, 12, 20 vs. correct 26, 23, 39):

function cyclomatic (clean rebuild) cyclomatic (incremental, same file changed elsewhere)
collectObjectRestParams 39 20
extractMemberExprCallInfo 35 21
collectParamBindings 23 12
extractReturnTypeMapWalk 26 1

Impact

This makes codegraph complexity and any check that reads cyclomatic/maintainabilityIndex (e.g. gauntlet/gate thresholds) unreliable after an incremental rebuild touches a file with multiple functions, unless a full rebuild is forced first. cognitive complexity appears unaffected and can be trusted; cyclomatic and MI cannot.

Environment

  • codegraph v3.15.0
  • Native engine (also reproduced after switching between --engine wasm and --engine native runs on the same graph.db, though a same-engine incremental rebuild also reproduces it)
  • Found while running a Titan-paradigm decomposition on src/extractors/javascript.ts; not related to the content of that specific change — purely a build/incremental-recompute issue in the complexity pipeline.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions