Skip to content

fix #837: populate .graphify_detect.json in --update flow - #838

Closed
Adriftnote wants to merge 1 commit into
Graphify-Labs:v7from
Adriftnote:fix/update-populates-detect-json
Closed

Adriftnote wants to merge 1 commit into
Graphify-Labs:v7from
Adriftnote:fix/update-populates-detect-json

Conversation

@Adriftnote

Copy link
Copy Markdown

Fixes #837.

What changes

Adds one bash block to ## For --update (incremental re-extraction) in graphify/skill.md that derives .graphify_detect.json from .graphify_incremental.json right after detect_incremental runs.

Both keys carried:

  • files = new_files — drives the incremental path: Step 3A AST extracts only changed code, Step 3B0 cache check is bounded to the changed set, etc.
  • all_files = files (from detect()) — kept for any stage that wants the full corpus (Step 5 timing estimate header, future audits, etc.)

Why

In v7 / 0.7.14, every step from 3A onward reads .graphify_detect.json unconditionally:

detect = json.loads(Path('graphify-out/.graphify_detect.json').read_text(...))
for f in detect.get('files', {}).get('code', []):
    ...

The --update flow currently only writes .graphify_incremental.json, so those reads either fail (no prior full-rebuild) or operate on stale corpus data from a prior run.

The downstream merge block (save_manifest(incremental['files']) at line 839) already handles manifest persistence correctly, so this PR doesn't need to touch Step 9 or the manifest path.

Repro that prompted the issue

Mixed wiki+code+raw archive (~1028 files). After a clean full rebuild + a small --update, the next --update was reporting 1008 "new" files instead of 0. Tracing showed:

  1. .graphify_detect.json was either absent or stale, and the agent ended up populating it ad-hoc with {'files': new_files} to make Step 3A run.
  2. Then Step 9's save_manifest(detect['files']) shrunk the manifest to the changed subset — root cause of the false-positive cascade.

On v0.7.14 the new merge block sidesteps (2). This PR addresses (1) directly so the flow stops depending on ad-hoc rescue.

Verification

After this patch, on my corpus:

  • manifest.json retains all 1028 corpus entries across consecutive --update runs
  • detect_incremental reports new_total: 0 against an unchanged corpus (was reporting 1008 before)
  • A subsequent --update after touching ~20 wiki files extracts only those 20 (verified via cache-hit count)

Notes / alternatives

  • Considered moving the .graphify_detect.json synthesis into detect.py (e.g. an as_detect_dict() helper). Kept it in skill.md to match the existing per-stage scratchpad convention, but happy to refactor if you'd prefer.
  • Did not add a save_manifest defensive fallback at Step 9 — current --update flow never reaches Step 9 (Steps 4–8 only), and adding one would muddle the diff. Worth a follow-up if you want belt-and-suspenders for future flow changes.

🤖 Generated with Claude Code

The `## For --update` section writes only `.graphify_incremental.json`.
Subsequent stages (Step 3A AST extract, Step 3B0 cache check, Step 5
timing estimate, etc.) all read `.graphify_detect.json` and either
crash (FileNotFoundError) when no prior full-rebuild has populated it,
or silently operate on stale corpus data from a prior run.

This patch adds a small block right after `detect_incremental` writes
`.graphify_incremental.json` that derives `.graphify_detect.json` from
the same data:
- `files` = new/changed only — drives Step 3A AST + Step 3B0 cache check
- `all_files` = full corpus from detect_incremental — for any step that
  needs corpus-wide context

The new-merge block at line 839 already handles manifest persistence
correctly via `save_manifest(incremental['files'])`, so no Step 9 change
is required for --update mode. Full-rebuild path is unaffected (it never
writes `all_files`).

Verified locally: after applying this patch, `/graphify --update` on an
unchanged corpus produces zero re-extraction and the manifest round-trips
across runs.
@safishamsi

Copy link
Copy Markdown
Member

Hey @Adriftnote — thanks for the correct diagnosis and the fix! Your approach was right. We merged a slightly extended version of this directly in commit 822abd6:

  • Your populate step (writing both files and all_files to .graphify_detect.json after detect_incremental) — included as-is.
  • One additional line we added on top: Step 9's save_manifest(detect['files']) was changed to save_manifest(detect.get('all_files') or detect['files']) as a defense-in-depth guard, since LLM agents can sometimes run Step 9 during --update even though the spec says not to. Without this, an agent that does execute Step 9 would still overwrite the manifest with just the delta.

Your PR was the right call — we just bundled the extra line in directly rather than merging separately. Really appreciate the detailed root-cause write-up and the local verification. 🙏

@safishamsi safishamsi closed this May 13, 2026
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.

bug: --update shrinks manifest.json to changed-subset only, causing next --update to flag every unchanged file as new

2 participants