Skip to content

#2879 symptom returns in 0.9.64 via the #2543 heal: data JSON re-queued every run despite a populated ast_hash #3679

Description

@ExhibitJ

Summary

#2879 ("Deliberately-skipped data JSON (#1224) is classified as failed extraction, so it is re-queued on every incremental run") was fixed in v0.9.48 and closed. On v0.9.64 the same user-visible symptom is back, but through a different code path, so the original issue is still correctly closed — its fix is working.

The recurrence comes from the #2543 heal, _zero_node_stamped_code_sources in cli.py. The two mechanisms now hold contradictory beliefs about the same state:

Both ship in 0.9.64. The heal wins, and the file is re-extracted on every run, forever.

As with #2879, correctness is unaffected — the cost is unbounded repeated work plus a permanent, misleading "prior failed extraction" warning that never clears.

Evidence that this is not the #2879 path

#2879's signature was a blank ast_hash in the manifest. That is fixed: on 0.9.64 there are zero blank-ast_hash entries in the manifest, yet ten .json files are still re-queued on every run.

data JSONs with no nodes in graph.json: 10
  ast_hash=5d5902a3  .claude/settings.json
  ast_hash=0587f2cb  .claude/settings.local.json
  ast_hash=960a5833  .vite/vitest/results.json
  ast_hash=cd310488  evals/clustering.json
  ast_hash=7aa4a4ae  evals/metadata-tagging.json
  ast_hash=b4e67073  src/lib/citation-integrity-baseline.json
  ast_hash=9b7aa817  src/lib/entity-index-baseline.json
  ast_hash=110b35c9  src/lib/source-comment-citation-baseline.json
  ast_hash=16f676af  tsconfig.e2e.json
  ast_hash=a5e11940  tsconfig.json

total manifest entries with BLANK ast_hash: 0

Every one is data-shaped JSON — editor config, tsconfig, test-result output, and committed baseline fixtures. All are correctly stamped. All are re-queued anyway.

Mechanism

cli.py, _zero_node_stamped_code_sources:

"""Manifest-stamped code files with a registered extractor but ZERO nodes
in the existing graph.json (#2543 heal).
...
Bounded by the same no-wedge property: if it fails again this run it is now
left unstamped, and if it succeeds its nodes enter graph.json so the next
scan stops re-queuing it.
"""

The stated no-wedge property does not hold for a file whose extractor correctly produces nothing. Such a file can never "succeed" by the heal's definition, because success is defined as nodes entering graph.json. A data JSON has no symbols to contribute, so the exit condition is unreachable and the heal re-queues it on every run indefinitely.

The predicate is the same pair of conditions #2879 identified as indistinguishable — zero nodes and an extractor is registered — just evaluated against graph.json rather than against the extraction result.

Reproduction

Two consecutive identical runs on a repo containing data-shaped JSON. The second run should be a no-op; it is not, and the output is byte-identical to the first:

$ graphify extract . --code-only
[graphify extract] re-queuing 10 manifest-stamped code file(s) with no nodes in graph.json (prior failed extraction, #2543)
[graphify extract] 10 code, 0 docs, 0 papers, 0 images changed; 443 unchanged; 0 deleted
[graphify extract] wrote graphify-out/graph.json: 5005 nodes, 12371 edges, 214 communities
[graphify extract] incremental summary: 443 files cached/unchanged, 10 re-extracted, 0 deleted

$ graphify extract . --code-only
[graphify extract] re-queuing 10 manifest-stamped code file(s) with no nodes in graph.json (prior failed extraction, #2543)
[graphify extract] 10 code, 0 docs, 0 papers, 0 images changed; 443 unchanged; 0 deleted
[graphify extract] wrote graphify-out/graph.json: 5005 nodes, 12371 edges, 214 communities
[graphify extract] incremental summary: 443 files cached/unchanged, 10 re-extracted, 0 deleted

Identical node and edge counts confirm the re-extraction produces no change — it cannot, because these files have no symbols.

Suggested fix

The heal needs the same distinction #2879 introduced: declined is not failed. If the reason a file contributes no nodes is that its extractor deliberately declined it (the #1224 data-JSON path), exclude it from _zero_node_stamped_code_sources rather than treating it as a poisoned manifest entry. Reusing whatever marker the v0.9.48 fix already computes would keep the two mechanisms consistent.

Related

Environment

graphify 0.9.64 · macOS 22.6.0 · Python 3.12 · installed via uv tool install graphifyy

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions