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 885cf09
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: docs/implementation/read-only-review.md
+8Lines changed: 8 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -120,3 +120,11 @@ The browser owns unsent text, mode, navigation, and attachments; the refreshed r
120
120
The regression gate is `npm run test:browser -- --grep 'during refresh'`. It checks visible drafts and refreshed durable approval/snapshot/plan state, and confirms no draft was accidentally saved as a note. Issues #10 (review edge cases), #12 (polling efficiency), and #3 (human go/no-go experiment) remain separate work.
121
121
122
122
PR #14 review round 1 found that retained-draft rows omitted the regular rows' `aria-current` state. A browser assertion reproduced the missing attribute. Retained rows now expose their selected state; the regression checks selection, navigation away, and selection again. No findings were declined.
123
+
124
+
## Lightweight answer polling (#12)
125
+
126
+
The answer polling endpoint previously called `ReviewService.load()` every two seconds while a question was pending. A browser regression measured one full review load for a single poll before the fix. Polling now reads persisted question attempts directly from SQLite and adds only the in-memory active marker. The endpoint returns each question's ID, answer state, and active state; it does not rebuild Git history, linkage, previews, or the review token.
127
+
128
+
The displayed review remains the owner of note text, ordering, snapshot, plan revision, assignment, and reference-validity metadata. Poll responses update only `answer` and `answerActive` for IDs already displayed. The existing generation guard rejects responses started before an action or Refresh, and unknown note IDs are ignored. Explicit Refresh and mutating actions still call the full review service to validate current repository state.
129
+
130
+
The focused browser regression observes a completed answer and its durable SQLite state with zero review loads, verifies that the status payload omits note text, then proves explicit Refresh still performs a full load. Existing regressions continue to cover a poll returning after a newer submission and cancellation remaining active after a persisted attempt fails.
awaitpage.goto(app.url);awaitpage.getByLabel('Question about this item').fill('Why is this bounded?');awaitpage.getByRole('button',{name:'Ask agent',exact:true}).click();
try{constresponse=awaitapi("/api/questions");if(data&&generation===reviewGeneration){data.notes=response.notes.map(note=>note.answer?.status==="pending"&¬e.answer.expiresAt<=Date.now()&&!note.answerActive ? {...note,answer:{...note.answer,status:"failed",error:"Agent was interrupted or timed out. Retry the question."}} : note);renderNotes({follow: true});}}
619
+
try{constresponse=awaitapi("/api/questions");if(data&&generation===reviewGeneration){conststatuses=newMap(response.notes.map(note=>[note.id,note]));data.notes=data.notes.map(note=>{conststatus=statuses.get(note.id);if(!status)returnnote;constanswer=status.answer?.status==="pending"&&status.answer.expiresAt<=Date.now()&&!status.answerActive ? {...status.answer,status:"failed",error:"Agent was interrupted or timed out. Retry the question."} : status.answer;return{...note,answer,answerActive:status.answerActive};});renderNotes({follow: true});}}
620
620
catch{if(generation===reviewGeneration)$("saved").textContent="Could not refresh agent answers. Use Refresh to reconnect.";}
@@ -22,7 +25,7 @@ export async function startServer(config: ReviewConfig, port = 4318, questionAge
22
25
constsupplied=req.headers['x-codeboost-token'];
23
26
if(typeofsupplied!=='string'||!/^[a-f0-9]{64}$/.test(supplied)||!timingSafeEqual(Buffer.from(supplied),Buffer.from(token))){json(403,{error: 'Open the private local URL printed by the CLI.'});return;}
0 commit comments