Conversation
…199) A single-file review normalizes its root to the file's PARENT directory, and every identity hung off that directory: the store (<dir>/.prereview/), the "one server per store" pid lock inside it, and the CLI's --out resolution. Two reviews of DIFFERENT files that happened to share a directory were therefore one review — the second launch was refused, or with --replace it killed the first, and both fed off one comments.csv. It fires constantly on Claude Code plan files, which all live in ~/.claude/plans/. #171 had already noticed half of this and added a filter (session.json + inScope), but a filter cannot make two servers coexist: events.jsonl, session.json and llm-status.json are single-writer, and persist() rewrites the whole CSV from one server's in-memory buffer. - Namespace single-file stores as <root>/.prereview/files/<name>-<hash>/, keyed on the absolute target path (storeDirFor). Every store path already derives from filepath.Dir(csvPath), so relocating the directory relocates the whole store — including server.pid, which makes the lock per-target for free. Repo, plain-directory and --external reviews are unchanged. - Print the resolved store as a new STORE preamble line. REPO could not be repointed at it: REPO is also the base the agent resolves a comment's `file` column against, so pointing it at the store would leave the agent unable to find the document it is reviewing. - --out now accepts the STORE path, the reviewed file, or (as before) a directory. A directory anchor whose store holds only per-file stores errors and names them, instead of hanging a stale skill's `watch` on an event log nothing writes. - Carry a pre-#199 shared store's rows for the reviewed file into its own store on first launch, together with the id-keyed sidecars — processed.jsonl + reenqueued.jsonl (doneness is the count of one minus the other, so both are filtered by the same ids) and the thread-reply logs. Comments alone would re-queue work the agent had already finished. It COPIES: the shared store may still be a directory review's live store. - Scope QuizResults by inScope. It was the last annotation surface walking every file in the store, and the source of the cross-file quiz in the report. Tests: unit coverage for the slug, the three --out forms, the loud error and the carry-over (including its sidecars); a new chromedp e2e boots two single-file reviews in one directory and asserts through a real browser that the second launch needs no --replace, the first server keeps serving, and neither page shows the other's work. e2e_scope_test.go now seeds the legacy shared store, so it doubles as the upgrade test. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RwpqeDN9UwdseVzLC4K3GB
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 #199.
The bug
A single-file review normalizes its root to the file's parent directory, and every identity hung off that directory: the store (
<dir>/.prereview/), the "one server per store" pid lock inside it, and the CLI's--outresolution. So two reviews of different files that happened to share a directory were one review — the second launch was refused, or with--replaceit killed the first, and both fed off onecomments.csv. It fires constantly on Claude Code plan files, which all live in~/.claude/plans/.#171 had already noticed half of this and added a filter (
session.json+inScope). A filter cannot make two servers coexist:events.jsonl/session.json/llm-status.jsonare single-writer, andpersist()rewrites the whole CSV from one server's in-memory buffer.The fix
<root>/.prereview/files/<name>-<hash>/, hashed on the absolute target path (storeDirFor). Every store path already derives fromfilepath.Dir(csvPath), so relocating the directory relocates the whole store — includingserver.pid, which makes the lock per-target for free. Repo, plain-directory and--externalreviews are unchanged.STOREpreamble line;REPOuntouched.REPOcould not be repointed at the store: it is also the base the agent resolves a comment'sfilecolumn against, so pointing it at the store would leave the agent unable to find the document it is reviewing — exactly the plan-file case in the issue.REPO= where the files are,STORE= where the annotations are (--outfor every subcommand).--outtakes three forms — theSTOREpath, the reviewed file, or a directory. A directory anchor whose store holds only per-file stores now errors and names them, instead of hanging a stale skill'swatchon an event log nothing writes.processed.jsonl+reenqueued.jsonl(doneness is the count of one minus the other, so both are filtered by the same id set) and the thread-reply logs. Comments alone would re-queue work the agent had already finished. It copies: the shared store may still be a directory review's live store.QuizResultswas the last annotation surface walking every file in the store; now scoped byinScope.Behavior change worth knowing
A single-file review and a directory review of the same directory are now separate reviews and do not see each other's comments. Documented in
skill/reference.mdanddocs/cli.md.Tests
storeDirFor, the three--outforms, the loud error, and the carry-over (filtering, idempotence, sidecars).--replace, the first server keeps serving, and neither page shows the other's work.e2e/e2e_scope_test.gonow seeds the legacy shared store, so it doubles as the upgrade test.go test ./...✅ ·make tmpl-check✅ · full-tags browsersweep 145/145 ✅.🤖 Generated with Claude Code
https://claude.ai/code/session_01RwpqeDN9UwdseVzLC4K3GB