fix(distill): only prune catalog entries whose origin project is visible here - #8
Open
JeePeeTee wants to merge 1 commit into
Open
fix(distill): only prune catalog entries whose origin project is visible here#8JeePeeTee wants to merge 1 commit into
JeePeeTee wants to merge 1 commit into
Conversation
…ble here Reconcile guards against pruning blind by checking that ProjectsDir exists, but ~/.claude/projects exists on every machine running Claude Code, so that check says nothing about any individual project. Each entry then falls through to os.ReadFile on <ProjectsDir>/<originProject>/memory/<originFile>; on a workstation that has never opened that project the path is legitimately absent, ErrNotExist is read as "the user deleted it", and the entry file is removed. Because the catalog lives inside the sync work-tree, the daemon's `git add -A` then propagates that deletion to every other machine -- so running `distill --prune` on a second workstation silently destroys entries distilled on the first. Skip entries whose origin project directory is not present, and count them. `claude-memsync distill` reports the count, so a conservative prune reads as a deliberate decision rather than as the command doing nothing. The cost is that an entry whose project directory the user really did delete now stays until removed by hand. That asymmetry is deliberate: a missed prune is an annoyance, a wrong prune is data loss across every machine. The existing TestReconcilePrunesStaleEntries still passes unchanged -- a source deleted under a project that *is* present is still pruned -- and a new test covers prune and skip happening in the same run, so the fix is selective rather than a blanket disable.
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.
Problem
Reconcileguards against pruning blind by checking thatProjectsDirexists — but~/.claude/projectsexists on every machine running Claude Code, so that check says nothing about any individual project.Each entry then falls through to
os.ReadFileon<ProjectsDir>/<originProject>/memory/<originFile>. On a workstation that has never opened that project the path is legitimately absent,ErrNotExistis read as "the user deleted it", and the entry file is removed.Because the catalog lives inside the sync work-tree, the daemon's
git add -Athen propagates that deletion everywhere. Runningclaude-memsync distill --pruneon a second workstation silently destroys entries distilled on the first.Solution
Skip entries whose origin project directory is not present, and count them.
claude-memsync distillreports the count, so a conservative prune reads as a deliberate decision rather than the command appearing to do nothing:The cost is that an entry whose project directory the user really did delete now stays until removed by hand. That asymmetry is deliberate, and noted in the code comment: a missed prune is an annoyance, a wrong prune is data loss across every machine.
Verification
go build ./... && go vet ./... && gofmt -l . && go test ./...all clean.The existing
TestReconcilePrunesStaleEntriespasses unchanged — a source deleted under a project that is present is still pruned, so this is selective rather than a blanket disable. A new test covers prune and skip happening in the same run; reverting the fix makes it fail withPruned = 2, want 1and the entry file gone.Docs updated to explain the scoping, including the troubleshooting entry that previously told you to run
--prunewithout saying it must be the machine owning the source project.