fix(detect): clear stale semantic_hash for dispatched-but-omitted files (#1948)#1956
Closed
alphanury wants to merge 1 commit into
Closed
fix(detect): clear stale semantic_hash for dispatched-but-omitted files (#1948)#1956alphanury wants to merge 1 commit into
alphanury wants to merge 1 commit into
Conversation
…es (Graphify-Labs#1948) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
safishamsi
added a commit
that referenced
this pull request
Jul 17, 2026
…is cleared) Follow-up to #1956: a doc stamped complete on a prior run that truncates (partial) this run must have its stale semantic_hash cleared so it is re-queued. Partial files are dropped by _stamped_manifest_files and therefore land in clear_semantic — pin that composed behavior. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Collaborator
|
Landed on v8 (ships in 0.9.18), cherry-picked to preserve your authorship. Thanks @alphanury — save_manifest no longer seeds a stale semantic_hash for a dispatched-but-omitted file, so the #1890 re-run actually fires. Rebased onto current v8 where it composes with #1950: a truncated (partial) file is also dropped from the stamped set and therefore cleared/re-queued. Added a regression test pinning that #1948 x #1950 interaction. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1948.
save_manifest's seed loop copied every on-disk manifest row verbatim for files still alive on disk, with no way to distinguish "never touched this run" from "dispatched this run but omitted from the result". So a doc whose chunk the LLM dropped on a--forcere-run kept its stalesemantic_hashfrom the earlier successful run,detect_incremental(kind="semantic")reported it unchanged, and the #1890 re-run promise silently never happened — exactly the failure this issue describes, and what the manual "blank the hash by hand" workaround was compensating for.Change
save_manifest()(graphify/detect.py) gains a keyword-onlyclear_semanticset: for any file in it, the seed loop forcessemantic_hashto""instead of inheriting the prior run's value. Defaults toNone(no-op) — every existing caller and the save_manifest drops untouched files on incremental runs, forcing full re-extraction #917/save_manifest retains scan-excluded files, causing permanent false deleted_files #1908 seed/prune behaviors are unchanged (guard tests pass unmodified).cli.pyderives the set assemantic_filesminus_stamped_manifest_files()'s result — i.e. dispatched this run but not stamped, regardless of why.semantic_filesis what was actually sent to the backend (narrowed by the incremental gate and--code-only, widened by deep mode), so untouched live files are never in the set and a partial incremental run cannot blank the rest of the corpus's stamps._save_manifestcall sites.Review note (why the derivation matters)
An earlier draft of this branch derived the set from
files_by_type(the full live corpus). Adversarial review before pushing caught that this wipessemantic_hashfor every unchanged file on any partial incremental run — forcing a full-corpus re-extraction on the next run, which would have been worse than the bug. The committed version derives from the dispatched subset and adds an end-to-end regression test for exactly that scenario.Tests
test_save_manifest_clear_semantic_erases_stale_hash_for_omitted_file(red before the detect.py change, green after), plus the seven pre-existing seed/prune guards, unmodified.test_incremental_partial_run_preserves_untouched_semantic_hash— full-scan run stamps two docs, a second incremental run dispatches only the changed one (asserted via the captured dispatch list), and the untouched doc'ssemantic_hashmust survive inmanifest.json. Red on thefiles_by_typederivation, green on the committed one.test_extract_cli.py+test_extract_code_only_cli.py+test_detect.py+test_build.py→ 226 passed. Full suite: 3269 passed; the 15 failures intest_ollama_retry_cap.py/test_skillgen.pyare pre-existing on a clean v8 checkout (verified byte-identical before/after).🤖 Generated with Claude Code