Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Incremental hook rebuild silently zeroes all nodes for 168 detected, unchanged, non-ignored files; shrink guard does not refuse

Abierto
#3,580 3 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
52/100
Tipo de issue
Error
Claridad
Bastante claro
Estado de actividad
Activo
Stack tecnológico
git, python
Área
devtools

Línea de trabajo

Start with _rebuild_code in watch.py, then trace _reconcile_existing_graph and _check_shrink at lines 1413 and 1662 using the reported incremental post-commit rebuild. Reproduce the 168-file zero-node case and compare the incremental result with a full rebuild. Done means unchanged detected files retain their nodes and the shrink guard refuses an unaccounted graph reduction.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Environment
  • graphifyy 0.9.42
  • Windows 11, Python 3.13, git 2.53.0.windows.1
  • Corpus: 4496 files, ~37.5k nodes, rebuilt by the installed post-commit hook (_rebuild_code(_root, changed_paths=changed))
Summary

A single incremental post-commit rebuild with 3 changed paths took the graph from 37482 to 36591 nodes. In that one run, 168 source files went from N nodes to exactly zero (1588 nodes), and nothing in the log mentioned any of them. Subsequent incremental rebuilds stayed pinned at 36591 forever; a full rebuild restored all 168 files and exactly 1588 nodes.

The affected set has a clean fingerprint: 165 of the 168 files live inside git submodules or at untracked paths in the parent repo (two submodules: 148 files; one untracked directory plus a handful of untracked root-level .md files: 18; tracked: 2). File types: 78 .md, 38 .tsx, 35 .ts, 6 .sql, 5 .sh, 3 .json, 3 js/mjs/cjs.

What was ruled out, by measurement
  • Not extraction. extract_markdown on one of the zeroed files returns 32 nodes right now.

  • Not detection. detect(Path(root)) returns all 4496 files, including all 169 of the affected paths that exist on disk (the other 5 "sources" in the diff are import stubs like react, node:fs).

  • Not corpus eviction. manifest.json still carries every one of them, with seen stamped at that rebuild and an unchanged ast_hash (byte-identical to the pre-loss manifest row apart from seen). So graphify saw them and considered them unchanged.

  • Not an ignore rule (#2495 / #1795). ignored_predicate(root, gitignore=False) and ignored_predicate(root, gitignore=True) both return False for all 169.

  • No warning was emitted. The rebuild log for that run contains no produced zero nodes line, no excluded but alive message, and no shrink warning. It reads as a clean success:

    [graphify hook] 3 file(s) changed - rebuilding graph...
    Graph has 36591 nodes (above 5000 limit). Building aggregated community view...
    [graphify watch] Rebuilt: 36591 nodes, 64913 edges, 2127 communities
    

    The immediately preceding run logged Rebuilt: 37482 nodes, 65657 edges.

  • Not recoverable incrementally. Two further hook rebuilds produced exactly 36591 again. Only _rebuild_code(root, changed_paths=None) healed it: 37950 nodes, and all 168 files back with exactly 1588 nodes restored.

Second bug in the same run: the shrink guard did not refuse

This run had changed_paths set, so rebuilt_sources was 3 files (watch.py:1413). 1588 lost nodes belonged to files that were not in that set, so _check_shrink at watch.py:1662 should have hit the _accounted check, failed it, and refused the write.

It did not. The only two ways past _check_shrink are:

if force or not existing_data:
    return True

force is False (the hook only sets it from GRAPHIFY_FORCE, which was unset), which leaves existing_data arriving empty or falsey from _reconcile_existing_graph. If reconcile can return {} on a path where the graph was in fact loaded and preserved from, then the guard is silently disarmed for that whole class of rebuild.

Why this is bad

Everything about the run looks healthy: the files are detected, manifest-stamped, unchanged by hash, not ignored, and extractable. Their nodes simply stop existing, incremental rebuilds can never bring them back because those files are never re-extracted again, and the guard that exists to catch exactly this said nothing. The only signal was a 2.4% drop in the node count printed in the log.

Happy to run any instrumented build against the same tree; the failure is reproducible in the sense that the graph re-entered the bad state twice and the full rebuild consistently fixes it.

Lenguaje dominante
Python
Estrellas
124k
Forks
11.9k
Métricas de merge de PR
Sin PR fusionados en 30 d

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de Graphify-Labs/graphify

Todos los issues de Graphify-Labs/graphify

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.