Repository navigation
fix(dedupe): model returns bullets-to-remove, Python applies (no file regen) - #11
Merged
Merged
Conversation
… regen) Follow-up to #10. Validating semantic dedupe live surfaced that Sonnet at low effort keeps prepending a "No duplicates found" announcement and, worse, reads instruction-like text inside the memory (persona rules, security notes) and reacts to it — all of which #10's guard correctly rejected but which left the command erroring on every run, so the preview was never useful. Prompt wording alone can't stop this, and the claude_code backend only injects prefill as a soft system hint (not a real assistant-turn prefill), so that lever is out too. The durable fix is to change the contract: the model no longer regenerates the file. It returns only the verbatim text of the bullets to REMOVE (or NONE), and Python performs the removal. Stray chatter that matches no real bullet is ignored; the file's integrity no longer depends on model formatting. This supersedes #10's introduced-lines guard (the model can no longer introduce anything) with a sanity cap (never remove >half the bullets) and verbatim-match removal (a hallucinated/paraphrased line removes nothing). Also fixes a trailing-newline mismatch that produced a spurious 1-line diff on clean files, and a blank-line edge case ("" is spuriously `in` any string). Live-validated: `memsync dedup --semantic` on the real GLOBAL_MEMORY.md now returns "No semantic duplicates found." (exit 0), instead of erroring. Tests: mark-and-remove; NONE is byte-identical; non-matching commentary is a no-op; hallucinated removal is a no-op; bulk-removal cap; trailing-newline and blank-line spacing preserved. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
EdgeCaser
added a commit
that referenced
this pull request
Jul 27, 2026
…ening fix(dedupe): model returns bullets-to-remove, Python applies (no file regen)
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.
What & why
Follow-up to #10. When I validated
memsync dedup --semanticlive against the realGLOBAL_MEMORY.md, the model (Sonnet, low effort) kept prepending a "No duplicates found" announcement, and — because the memory file contains instruction-like text (persona rules, security notes) — it reacted to that text and injected a flag about it. #10's guard correctly rejected all of this, but that left the command erroring on every run, so the preview was never useful.Wording alone can't fix it, and the
claude_codebackend only injects prefill as a soft system hint (not a real assistant-turn prefill — see_call_claude_code), so that lever is out too.The fix: change the contract
The model no longer regenerates the file. It returns only the verbatim text of the bullets to remove (one per line), or
NONE. Python does the removal. Consequences:This supersedes #10's introduced-lines guard (the model can no longer introduce anything) with:
NONE(no spurious diff), preserving trailing newline on removal.Also fixes a subtle
""[:1] in "-*+"truthiness bug that would have treated blank lines as removable bullets.Validation
Live:
memsync dedup --semanticon the real file now prints "No semantic duplicates found." (exit 0) instead of erroring.Tests (7): mark-and-remove;
NONEbyte-identical; non-matching commentary is a no-op; hallucinated removal is a no-op; bulk-removal cap; trailing-newline preserved; blank-line spacing preserved with internal blanks in the response.Full suite: 460 passed, 1 skipped, coverage 82.60%.
ruff check memsync/clean.🤖 Generated with Claude Code