Skip to content

fix(extract): retain provenance for legacy and data nodes - #3155

Open
GmailTedam wants to merge 1 commit into
Graphify-Labs:v8from
GmailTedam:codex/backfill-legacy-node-source-file
Open

fix(extract): retain provenance for legacy and data nodes#3155
GmailTedam wants to merge 1 commit into
Graphify-Labs:v8from
GmailTedam:codex/backfill-legacy-node-source-file

Conversation

@GmailTedam

Copy link
Copy Markdown
Contributor

Summary

  • retain one file-level graph node for deliberately unexpanded and oversized JSON artefacts
  • backfill legacy sourceless semantic nodes only from real incident-edge provenance
  • keep provenance selection deterministic and continue warning when no evidence exists

Evidence

  • 94 focused tests passed, 0 skipped
  • Ruff passed on all changed source and tests
  • BulletTrain regeneration: 88,458 nodes / 159,519 edges, 0 schema errors
  • all 3,442 JSON files in the manifest have graph source coverage
  • multigraph diagnostic: 0 missing endpoints, 0 dangling endpoints, 0 duplicate/collapsed edge groups

Copilot AI lite review requested due to automatic review settings August 28, 2026 05:05

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates JSON extraction and graph rebuild behavior to preserve file-level provenance for JSON artefacts that are intentionally not structurally expanded (oversized/data-shaped JSON) and to deterministically backfill missing source_file on legacy semantic nodes using incident-edge provenance.

Changes:

  • JSON extractor now always emits a single file-identity node for skipped/oversized/data JSON instead of emitting zero nodes.
  • Graph builder backfills source_file for legacy nodes that lack it, selecting deterministically from incident edges’ source_file.
  • Tests updated/added to lock in the new “retain file identity + deterministic provenance” behavior.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
tests/test_extract.py Updates expectations so skipped/data/oversized JSON still yields one file-identity node.
tests/test_build.py Adds coverage for deterministic source_file backfill from incident-edge evidence (and warning behavior when none exists).
graphify/extractors/json_config.py Emits a file-level node even when JSON is skipped or too large, preserving provenance visibility.
graphify/build.py Implements pre-validation provenance backfill for legacy nodes missing source_file.
Suppressed comments (1)

graphify/build.py:895

  • This loop skips nodes whenever the source_file key exists, even if it is empty/whitespace or non-string. Elsewhere in build_from_json (e.g., _fold_node_aliases) emptiness is treated as missing; keeping the current check can leave nodes effectively sourceless and prevent deterministic backfill.
        if not isinstance(node, dict) or "source_file" in node:
            continue

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread graphify/build.py
Comment on lines +887 to +892
for endpoint in (edge.get("source"), edge.get("target")):
try:
incident_sources.setdefault(endpoint, set()).add(source_file)
except TypeError:
# The validator reports malformed, non-hashable endpoints.
continue

@graphify-labs graphify-labs Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Graphify reviewed this change.

Worth a look — the grounded gate found no coupling regressions or blocking issues, but 2 advisory finding(s) below merit a look before merge.

Formal verification. No changes could be formally verified in this run.


Graphify review — findings

Makes extract_json always emit a file-identity node so data JSON (fixtures, datasets, oversized files, unparseable content, missing grammar) stays visible to freshness/affected checks, while still skipping per-key expansion for non-config JSON to avoid orphan key-node blowup. Backfills source_file on legacy semantic nodes during build_from_json by deriving it deterministically from the incident edge with the lowest case-folded path, and leaves the node flagged by the validator when no incident edge proves a path rather than inventing one.

Worth a look

  • incident_sources keyed by raw endpoint but node id may be coerced later, causing missed backfillgraphify/build.py:895 · Escalate · medium
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
  • Oversized JSON no longer reports an errorgraphify/extractors/json_config.py:88 · Escalate · medium
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification

Impact & health

Graphify review

Impact — 1566 functions depend on the 617 functions this change touches.

Health — this change adds coupling hotspots:

  • new: _rebuild_code() — 98 callers, 50 callees
  • new: build_from_json() — 192 callers, 18 callees
  • new: build_merge() — 53 callers, 13 callees
  • new: to_obsidian() — 36 callers, 13 callees
  • new: extract_files_direct() — 17 callers, 20 callees
  • new: to_wiki() — 41 callers, 7 callees
  • new: extract_corpus_parallel() — 26 callers, 11 callees
  • new: _call_claude_cli() — 31 callers, 9 callees
  • …and 40 more — each is listed as a finding

Verification — 1566 functions in the blast radius were not formally verified this run (proofs are advisory here).

Gate & verification

graphify gate

PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.

Advisory (not blocking):

  • verification_scope: 1179 function(s) in the blast radius were not formally verified this run

Formal verification

Could not verify: Could not verify build\_from\_json.

The verifier did not have enough to check build\_from\_json, so it is saying so rather than guessing. No false assurance is the whole point.

Guarantee: No guarantee either way, this is an honest abstention, not a pass.

Note: Reason: not verifiable: all 6 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous (mostly NameError — names the real obstacle, not a sampling gap)

Could not verify: Could not verify extract\_json.

The verifier did not have enough to check extract\_json, so it is saying so rather than guessing. No false assurance is the whole point.

Guarantee: No guarantee either way, this is an honest abstention, not a pass.

Note: Reason: parameter `path` is annotated `Path` — outside the synthesizable primitive/collection set

· 48 more finding(s) on lines outside this diff (see the check run).

safishamsi added a commit that referenced this pull request Aug 29, 2026
This reverts #3155 (b568488): the source_file backfill also fired on a shared external stub
(e.g. a cross-file `Path` reference with no source_file), giving the stub a file identity so
the orphan prune swept it when that one file was deleted even though another file still
referenced it — regressing test_prune_sweeps_orphans. The fix needs to distinguish a
legacy node that genuinely lost its provenance from an external stub that must stay
sourceless; sending #3155 back as needs-work.
safishamsi added a commit that referenced this pull request Aug 29, 2026
Ships three batches: php new Foo() calls (#3115), inherited-field receivers (#3151), objc
field-table remap (#3150), ts type-only-import cycles (#3123) and import-type args (#3185);
razor @Inject cross-file (partial #3187), MCP prs isError + get_node resolver parity,
project-scoped bare hook command (#3129); and T-SQL routine recovery (#3164), watch
markdown->semantic reconcile (#3190), --help completeness, and a deepseek pricing fix. The
#3155 provenance backfill was reverted (regressed the orphan prune).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants