Repository navigation
Conversation
…n linear time Saved decisions were keyed by a non-cryptographic fingerprint that a crafted file could collide with; they are now keyed by the SHA-256 of the file. The fallback current item no longer rescans the queue for every candidate, and judge badges are grouped once per render. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
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.
Closes #266
Summary
tools/reviewsaves a reviewer's decisions in localStorage so a reload resumes the review, and itsreviews.jsonlexport feeds the spot-check gate inscripts/freeze_documents_v1.py. Three fixes (findings 2, 5 and 3 of a security scan of 2074cc4):2, saved decisions were bound to a weak fingerprint. The storage key was two 32-bit FNV-style hashes plus the length. A file crafted to collide with one already reviewed would resume that review's decisions for every matching id, and Export would then report them for text that may have changed. The freeze gate checks ids and proposed labels, not document text, so it would not notice. The key is now the SHA-256 of the file's text (Web Crypto), under a new prefix,
kev-review:sha256:. Decisions resume only for a byte-identical file. Old entries are not migrated, because the only way to find them is the weak hash this replaces, and they are not deleted either; they stay in localStorage underkev-review:<old hash>.5, choosing the current item was quadratic. The fallback for
itemcalledstep(s.cur, 1), a full queue scan, once for every candidatequeue.findtried. When the filter has nothing left, which is the normal end of a review, every render cost n² checks. The fallback id is now computed once. With 5,000 items (about 20 options and 10 judges each), all decided, a render on the empty "undecided" filter took 318 and 301 ms on main and 109 ms here (production build, headless Chromium).3, every option scanned every judge. The judges of the current item are grouped by label once per render, instead of filtered again for each option. Same badges, same order.
Behavior relative to main
kev-review:+ FNV pair + lengthkev-review:sha256:+ SHA-256 of the filenpm run devon localhost is a secure contextRed / green
tools/reviewhas no test runner. A headless Chromium run of the production build covered the changed paths instead (below).Verification
npm ci && npm run build(tsc, then vite) intools/review: clean.vite previewof this branch: opened?file=sample.jsonl, accepted one item and reloaded; the review resumed at "1 / 24 reviewed" under the SHA-256 key. After deciding all 24, the empty "undecided" view renders.Merge Danger
npm run devURL is one.Checklist
npm run build(tsc + vite) passes intools/review.tools/review/README.mddescribes the new key.Generated with Devin