You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 19aabad
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: docs/implementation/read-only-review.md
+7-1Lines changed: 7 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -21,10 +21,16 @@ Store schema v2 adds the review counter and per-item notes through a transaction
21
21
## Known limits and remaining gates
22
22
23
23
- No agent answers, test execution, AI findings ingestion, send-to-agent action, or merge control is included. These belong after the go/no-go gate. Four checks distinguish unavailable evidence from success.
24
-
- File cards show mode/path/object IDs; binary/image previews and byte-size retrieval are not implemented and explicitly say unavailable. The pure history API does not expose binary bytes.
24
+
- File cards show mode/path/object IDs and blob byte sizes. PNG/JPEG/GIF/WebP previews are bounded to 1 MiB each and 4 MiB across a history; unsupported/oversized images say unavailable. Gitlink byte sizes are not applicable. SVG/HTML is never embedded.
25
25
- The protocol at `docs/experiments/review-protocol.md` must be filled with the real pairs and committed before the first timed review. The manual assignment, real paired PRs, human timing, and final result are pending. Do not mark issue #3 closed or claim the gate passed.
26
26
- The planting helper is intentionally limited to disposable clones and supported regular top-level paths; it never publishes PRs.
27
27
28
28
## Validation
29
29
30
30
Baseline before this slice: 157 tests. Run `npm run typecheck`, `npm test`, and `npm run test:browser`. Browser tests use real Git and SQLite with Chromium and cover persistence, assignments, metadata, no-change approval, stale views, unsafe origins, keyboard/breakpoints, error display, and untrusted text. A browser regression exposed false stale reasons from JSON field order; structural comparison replaced that check. The plant test verifies source HEAD stays unchanged and both plants retain ledger ownership.
31
+
32
+
A large-change regression reproduced HTTP 413 when the browser sent the full content-based choice key for a 20 KB segment. Browser segment IDs are now bounded SHA-256 identifiers; the runner reconstructs the original identity/content/copy key before saving the choice. This retains choice expiry semantics without sending source content back in a review command.
33
+
34
+
## Review round 1
35
+
36
+
Reproduced and fixed no-change approval with item-owned ambiguous segments; the runner refuses it and the UI directs the user to resolve attribution first. Previously approved no-change items become stale if ambiguous work appears. Reproduced malformed non-ASCII credentials returning a generic conflict instead of unauthorized; credentials now require the expected ASCII hex shape before constant-time comparison. Reproduced stale item controls surviving a failed refresh; errors now discard the loaded view and require refresh. Added acceptance persistence and whole-plan empty-state browser coverage. No findings declined.
awaitpage.getByRole('button',{name:'Refresh',exact:true}).click();awaitexpect(page.getByText('Could not read this branch’s history.',{exact:false})).toBeVisible();awaitexpect(page.getByRole('button',{name:'Approve P1',exact:true})).not.toBeVisible();
47
47
});
48
+
test('can assign a large foreign change without sending its content back in the command',async({request})=>{
awaitpage.getByRole('button',{name:'Refresh',exact:true}).click();awaitexpect(page.getByText('Could not read this branch’s history.',{exact:false})).toBeVisible();awaitexpect(page.getByRole('button',{name:/P3ConfirmAPIcompatibility/})).toHaveCount(0);
64
+
});
65
+
test('accepts a foreign segment and keeps that choice across reload',async({page})=>{
66
+
awaitpage.goto(app.url);awaitpage.getByRole('button',{name:/Unplannedchanges/}).click();awaitpage.getByRole('button',{name:'Accept as is',exact:true}).first().click();awaitpage.getByRole('button',{name:/Accepted1/}).click();awaitexpect(page.getByRole('article').first()).toBeVisible();awaitpage.reload();awaitpage.getByRole('button',{name:/Accepted1/}).click();awaitexpect(page.getByRole('article').first()).toBeVisible();
67
+
});
68
+
test('shows the whole-plan empty state without claiming checks passed',async({page})=>{
0 commit comments