Skip to content

Emit a bare file node for skipped data JSON (#2108) - #3626

Open
ayushcodes10 wants to merge 3 commits into
Graphify-Labs:v8from
ayushcodes10:fix-2108-data-json-file-node
Open

ayushcodes10 wants to merge 3 commits into
Graphify-Labs:v8from
ayushcodes10:fix-2108-data-json-file-node

Conversation

@ayushcodes10

Copy link
Copy Markdown
Contributor

Summary

Fixes #2108. Data-shaped .json (eval fixtures, parity corpora, i18n catalogues, GeoJSON) is deliberately skipped by extract_json's AST pass — the right call for structure, since walking it exploded into hundreds of orphan key-nodes (#1224). But the skip was total: the file contributed no node at all, so it was entirely absent from graph.json and unreachable from query/explain/affected, with no warning that anything was missing.

Root cause

extract_json already builds the file node (file_nid = _make_id(str(path)); add_node(file_nid, path.name, 1)) before deciding whether the document is a recognized config/manifest. Both skip branches then discarded it, returning a literal {"nodes": [], ...} instead of the nodes list — which at that point held exactly that one file node and nothing else.

Fix

Both skip paths (non-config object root, and non-object top-level root) now return the already-built nodes list instead of an empty one. Since nothing else has been added to it by that point, this yields exactly one bare file node — no per-key traversal, no children, no edges — keeping the file discoverable without reintroducing the node explosion #1224 fixed. Verified the size-limit and invalid-JSON early-return paths are unaffected (they return before the file node is ever built).

Test plan

  • Updated test_extract_json_data_file_skipped and test_extract_json_top_level_array_skipped in tests/test_extract.py, which previously pinned an empty node list, to assert the new single bare-file-node behavior.
  • Added test_extract_json_data_file_node_is_a_real_file_node (same id scheme, file_type: "code" matching .json's CODE_EXTENSIONS classification, no error key) and test_extract_json_many_data_files_still_one_node_each (a small corpus of data files stays AST pass explodes data .json into orphan key-nodes (CODE_EXTENSIONS includes .json) — 561 isolated nodes on a real repo #1224-safe: exactly one node per file, never per-key nodes).
  • Confirmed recognized config/manifest JSON (tsconfig.json, package.json-shaped fixtures) is unaffected — full structural extraction still runs.
  • Full suite: python3 -m pytest -q — 5623 passed, 68 skipped, no regressions.

🤖 Generated with Claude Code

ayushcodes10 and others added 3 commits September 17, 2026 15:24
extract_json already built the file node before checking whether the
document was a recognized config or manifest, but the skip branches
threw that node away and returned an empty node list, so a data
shaped JSON file such as an eval fixture or a parity corpus never
appeared anywhere in the graph at all, not even as a leaf.

Both skip paths now return the already built nodes list, which at
that point holds exactly the one bare file node and nothing else: no
per key traversal, no children, no edges. The file becomes
discoverable through query, explain, and affected without
reintroducing the orphan key node explosion the original skip was
added to prevent.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Updates the two existing tests that pinned an empty node list for
skipped data JSON to assert the new bare file node instead, and adds
two more: the node looks like a normal file node (same id scheme,
file_type code, no error key), and a small corpus of data files still
gets exactly one node per file, never per key nodes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

@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.

Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).

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


Graphify review — findings

Emits the bare file node for data-shaped .json files that fail the config/manifest check in extract_json, instead of returning an empty node list, so eval fixtures, datasets, and array/scalar-rooted JSON stay discoverable via query/explain/affected. The skip path still emits no per-key nodes and no edges, preserving the #1224 orphan-key-explosion fix — one file node per file regardless of corpus size. The file node carries the standard id scheme, file_type "code", and no error key, matching every other file node graphify emits.

No blocking issues surfaced.

Analysis details — impact, health, verification

Impact & health

Graphify review

Impact — 637 functions depend on the 637 functions this change touches.

Health — this change adds coupling hotspots:

  • new: extract_json() — 18 callers, 7 callees
  • new: walk_object() — 1 callers, 7 callees

Verification — 637 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: 637 function(s) in the blast radius were not formally verified this run

Test selection

Test selection

286 of 286 test file(s) selected (100%) via static blast radius.

Escalated to a full run for safety — the selection is not trustworthy on its own (see below). CI should run the whole suite.

  • tests/test_affected_cli.py — full-run-safety
  • tests/test_affected_member_seed.py — full-run-safety
  • tests/test_agents_platform.py — full-run-safety
  • tests/test_analyze.py — full-run-safety
  • tests/test_anthropic_custom_endpoint.py — full-run-safety
  • tests/test_antigravity_install.py — full-run-safety
  • tests/test_apm_fallback_version.py — full-run-safety
  • tests/test_architecture_doc.py — full-run-safety
  • tests/test_astro_extraction.py — full-run-safety
  • tests/test_astro_import_ids.py — full-run-safety
  • tests/test_atomic_canvas_export.py — full-run-safety
  • tests/test_atomic_version_stamp.py — full-run-safety
  • tests/test_atomic_writes.py — full-run-safety
  • tests/test_backend_env_isolation.py — full-run-safety
  • tests/test_backend_extras.py — full-run-safety
  • tests/test_benchmark.py — full-run-safety
  • tests/test_benchmark_raw_graph.py — full-run-safety
  • tests/test_build.py — full-run-safety
  • tests/test_build_merge_dedup_scope.py — full-run-safety
  • tests/test_build_merge_hyperedges_and_prune.py — full-run-safety
  • tests/test_build_merge_shrink_guard.py — full-run-safety
  • tests/test_builtin_global_type_refs.py — full-run-safety
  • tests/test_cache.py — full-run-safety
  • tests/test_callflow_html.py — full-run-safety
  • tests/test_cargo_introspect.py — full-run-safety
  • tests/test_carried_hyperedge_remap.py — full-run-safety
  • tests/test_case_sensitive_resolution.py — full-run-safety
  • tests/test_charmap_encoding.py — full-run-safety
  • tests/test_chunking.py — full-run-safety
  • tests/test_cjs_module_extension.py — full-run-safety
  • tests/test_claude_cli_backend.py — full-run-safety
  • tests/test_claude_md.py — full-run-safety
  • tests/test_cli_broken_pipe.py — full-run-safety
  • tests/test_cli_export.py — full-run-safety
  • tests/test_cli_help.py — full-run-safety
  • tests/test_cluster.py — full-run-safety
  • tests/test_codebuddy.py — full-run-safety
  • tests/test_community_hub_labels.py — full-run-safety
  • tests/test_community_labels_skill.py — full-run-safety
  • tests/test_confidence.py — full-run-safety
  • tests/test_corrupt_graph_json.py — full-run-safety
  • tests/test_cpp_nested_and_cli.py — full-run-safety
  • tests/test_cpp_objc_cross_file_calls.py — full-run-safety
  • tests/test_cpp_preprocess.py — full-run-safety
  • tests/test_cross_extension_reexport_self_cycle.py — full-run-safety
  • tests/test_cross_language_call_resolution.py — full-run-safety
  • tests/test_cross_repo_external_call_guards.py — full-run-safety
  • tests/test_cross_repo_member_calls.py — full-run-safety
  • tests/test_cross_repo_shared_types.py — full-run-safety
  • tests/test_csharp_call_site_generic_args.py — full-run-safety
  • … and 236 more

non-code file(s) changed (CHANGELOG.md) → running the full suite for safety (a code graph can't see config/fixture/data deps)

changed code file(s) with no mapped test (CHANGELOG.md) — a coverage gap or a missing link — running the full suite rather than only the selected tests

Selection is safe under the controlled-regression assumption; always-run tests + a periodic full run are the backstops. Advisory — it never changes the check verdict.

Formal verification

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: no capturable inputs from the test suite; property tier: parameter `path` is annotated `Path` — outside the synthesizable primitive/collection set

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

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.

Emit a bare file node for deliberately-skipped data .json so it stays discoverable (without reintroducing #1224)

1 participant