Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

extract(): `cache_root` without `root` re-anchors every AST node id, and the node-count shrink guard cannot notice

Aperta
#3,727 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@jnrod03-rgb ci sta già lavorando.

Dal 30/9/2026.

  • #3955 di @jnrod03-rgb — aperta

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
52/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
python

Direzione di ricerca

Start with the graphify.extract.extract() entry point and the skill's Step 3 Part A, reproducing calls A–C from the issue. Then inspect the post-build checks around graph.json and the health check. Done means the skill passes root separately, and rebuild validation reports identity changes and missing cached-edge endpoints rather than relying only on node counts.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

cache_root appears as a parameter of both the AST extract() and the semantic
cache helpers (check_semantic_cache, etc.). In the semantic path it says where
the cache lives. In extract(), when root is not passed, it also becomes the
base that source_file and node ids are computed from. The two meanings share one
name, and the skill's incremental-rebuild guidance (Step 3 Part A vs. Step B0/B3)
does not say so.

In one rebuild without an LLM (AST + semantic cache), the value documented for the
semantic cache — the folder that contains graphify-out — was passed to
extract() as well, by name. Nothing errored. The result:

  • source_file paths lost the sub-folder prefix, so all 1328 code node ids
    changed
    .
  • 313 cached edges linking document concepts to code were left pointing at ids
    that no longer existed.
  • Communities went from 262 to 433, and manual labels keyed by file stopped
    matching.

Reproduction (re-tested on 0.9.64)

One file, proj/pkg/mod.py, containing a single function. Same file list, three calls:

from graphify.extract import extract
f = [base/"proj"/"pkg"/"mod.py"]
extract(f, cache_root=base/"proj")                 # A
extract(f, cache_root=base)                        # B
extract(f, cache_root=base, root=base/"proj")      # C
call node ids source_file
A pkg_mod, pkg_mod_hello pkg/mod.py
B proj_pkg_mod, proj_pkg_mod_hello proj/pkg/mod.py
C pkg_mod, pkg_mod_hello pkg/mod.py

B is the trap: moving only the cache location renamed every node. C shows the fix is one keyword.

What 0.9.64 already does: the extract() docstring now states the fallback ("without it the anchor falls back to cache_root", #1941), and the CLI passes both ({"cache_root": out_root, "root": target}). What is still open: the skill's Step 3 Part A still calls extract(code_files, cache_root=Path('INPUT_PATH')) with no root, so anyone adapting that snippet to a cache that lives elsewhere (the documented --out case) gets B; and nothing between build and export checks node identity.

Why no existing guard caught it

  • The anti-shrink gate compares node counts. 1328 nodes disappeared and 1328
    appeared: the count did not move. A full replacement with the same cardinality
    passes any size guard.
  • The health check did report 412 dangling edges, but the corpus normally carries
    ~100 from third-party imports, so the figure read as "the usual, a bit higher".
    A count without a baseline next to it is easy to explain away.
  • The first hypothesis was a schema change in the new version, which the upgrade
    made plausible. What settled it was comparing node ids before and after by
    type
    : lost 1328, gained 1328, all code.

Suggested changes

  1. Skill, Step 3 Part A: pass root=INPUT_PATH explicitly next to
    cache_root, and say in one sentence that cache_root anchors ids when root
    is absent. The two call sites look alike and the parameter name invites copying
    the value across.
  2. After build, before export — an identity check, not a size check: against
    the previous graph.json, report how many code-node ids disappeared, how many
    appeared, and how many cached edges point at ids that do not exist. Stop (or at
    least warn loudly) when a large share of one node type is replaced. This is the
    check that would have caught it; the node-count gate cannot, by construction.
  3. Health check: print the dangling-edge count next to the previous run's, or
    split it into "endpoints that are third-party stubs" and "endpoints that look
    like project ids". The second number going from 0 to 300 is unmistakable; the
    sum going from 100 to 412 was not.
  4. Library (optional): the docstring now documents the fallback; a one-time
    warning when extract() receives cache_root without root and the scanned
    files do not sit directly under it would turn a silent rename into a visible one.

Workaround in use

Pass root and cache_root explicitly and separately, and gate the rebuild on two
assertions: no more than a small fraction of code-node ids may disappear between
consecutive builds, and no cached edge may point at a missing id. Both stop the
rebuild before anything is overwritten.

Environment: first hit on graphifyy 0.9.61; reproduction above re-run on 0.9.64. Windows 11, Python via uv tool. Corpus where it happened: ~2.9k nodes, mixed code and documents.

Lingua principale
Python
Stelle
124k
Fork
11.9k
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di Graphify-Labs/graphify

Tutte le issue di Graphify-Labs/graphify

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.