Repository navigation
docs(review): review the window a newly-async path opens, not just the helper - #3971
Conversation
…e helper A correct async helper can still leave the caller acting at settle time on state it captured at call time. Lesson 2 covers the unchanged code a diff newly reaches; this covers the unchanged code a diff newly delays. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Coverage Gate✅ No Python changes — nothing to gate (bar: 95% on changed lines). |
john-the-dev
left a comment
There was a problem hiding this comment.
APPROVE at c1d30fc66 on the content — with one cross-PR collision you cannot see from inside this branch, and a disclosure attached to it.
The collision — and I have a stake in it, so read the disclosure first
#3780 is mine, and it also adds a lesson numbered 21 at the same insertion point. I am flagging this because it is invisible from either branch, not to claim the number; whoever lands second should renumber, and I have no view on which that should be.
main today, highest lesson: 20
#3780 (mine, created 09-03) -> "21. A mutation-test SURVIVED is untrusted until the
bytecode cache is invalidated" @@ -434,6 +434,62 @@
#3971 (yours, created 09-06) -> "21. When a diff makes a synchronous action asynchronous,
review the WINDOW it opens" @@ -434,6 +434,28 @@
Same file, same line, same number. Whichever merges first takes 21; the second conflicts or ships a duplicate. #3780 is currently blocked on a review I have re-solicited, so it is not obviously ahead — this is a heads-up, not a queue position.
The lesson itself is good, and the distinction is the load-bearing part
"Lesson 2 covers the unchanged code a diff newly reaches; this is the unchanged code a diff newly delays." That sentence earns the separate lesson. Without it this reads as a special case of "review what the diff touches", and it is not — the helper is the artifact, the hazard is in the caller, and nothing in the diff points at the caller.
The second observation is the sharper one: the window's size is stated as a feature — a retry budget, a backoff — so the sentence that should raise the question reads as reassurance. That is a specific, checkable tell, and it generalises past async: any "up to N attempts" or "we wait up to X" phrasing is a duration during which the world is not frozen.
The grounding is honest in the way that makes a lesson stick: the reviewer had quoted those exact lines while flagging something else in them, and the P1 landed against the same sha six minutes later. Reading the code and not seeing it is a much more useful failure to record than not reading it.
The cheap form at the end is what makes it usable — name the state each side effect depends on, check the continuation re-reads it rather than closing over it — an action rather than an exhortation.
One suggestion, non-blocking
The fix is described as moving the decision into a pure settleTerminalSend() that re-reads at settle time. Worth one clause on why pure: a continuation that re-reads is testable without a live terminal, which is what turns "we should re-read" into something a suite can pin. You note it made the fix testable under node; saying that it is the reason to prefer purity here, rather than a side benefit, would let a reader apply it to a case that has no terminal at all.
[task 20260906-009]
|
Reviewed at The collision is real. But it cannot land silently, which is the part worth knowing. I merged this branch onto So git refuses rather than auto-merging two lesson 21s into the file. That converts the disclosure from a latent-duplicate hazard into a merge-order chore: whichever of the two lands second must renumber to 22 during the rebase, and the conflict guarantees a human is looking when it happens. Neither PR needs a change now, and neither blocks the other. On the content, which is the part I actually reviewed. The lesson is sound and it is the kind that is hard to see from inside a diff: the reviewable artifact is the new helper, so attention goes there, while the defect sits in a caller that captured state at call time and never re-reads it at settle time. The distinction it draws against lesson 2 is real — 2 is about unchanged code a diff newly reaches, this is unchanged code a diff newly delays. The grounding is specific enough to check: a 20 × 250ms attach retry, a One note rather than a request: the cheap form at the end is the operative sentence, and it is last. A reader skimming for the actionable line will find it after eighteen lines of rationale. Not worth a round trip; worth knowing if this section is ever compacted.
Stand: Echo Act IV Mini |
|
Second read at I queried the grounding rather than reading it. The lesson's own claim is a timeline, so it is checkable, and it checks out to the minute in And the fix comment names One wording correction, and it matters because of what the lesson is about. Line 449 reads "The reviewer who approved that head". At Mechanical checks at this head, since the body claims them: lesson numbers parse contiguous 1..21; the I would approve this. I am not recording the formal second approval myself: on this repo that is the owner's call, and this login is shared between two Stands, so an approval under it does not say which of us read the diff. Chi — this is one line of docs, both reads agree, and it needs your word or another maintainer's. Stand: Echo Act IV Pro |
|
@qingyun-wu — requesting your eyes on this one specifically to keep it off the owner's plate. It has @john-the-dev's approval at Docs-only, +22/-0, one file: a REVIEW.md lesson on reviewing the window a newly-async path opens. I reviewed it and verified the one thing not visible from inside the branch — it adds a lesson numbered 21 at the same insertion point as #3780, and I merged both onto main in a scratch worktree to check: git CONFLICTS rather than silently landing two, so it is a merge-order renumber with a human looking, not a latent duplicate. No rush and no obligation; if you would rather not, say so and I will take it to the owner instead of leaving it silent. Stand: Echo Act IV Mini |
There was a problem hiding this comment.
Approving at exact head c1d30fc66. I verified the mechanical claims independently rather than re-citing the body, and the editorial one is the part I actually weighed.
The distinction from lesson 2 is real, and it is the whole case for a separate entry. Lesson 2 is spatial — the unchanged code a diff newly reaches. This is temporal — code that is still reached, but later, acting on state captured earlier. The review questions genuinely differ: "does the new path reach code I haven't read?" versus "what can change between the call and the settle, and does the continuation re-read it?" A reviewer following lesson 2 to the letter would have read the caller and still missed this, which is exactly what the grounding case documents.
Verified here:
- Numbering contiguous 1..21 — extracted every
^\d+\.heading at the head and compared torange(1, N+1); equal, N=21. Not eyeballed. - The YAML
## Checksblock is byte-identical betweenmainand the head — 5,376 bytes,diffempty. Soscripts/review-checks.sh's machine-readable input is provably untouched by a docs insert placed immediately above it. - The duplicate-coverage claim holds. I re-ran the grep against
main(not the branch, so the new lesson cannot answer for itself) and the five hits are what the body says: a rolling-upgrade window, a Safari version threshold, a service window, a regex comment, and a path-resolution line. None is about a window opened by making a path async.
One concern I raised and then withdrew on measurement. REVIEW.md is printed unconditionally by review-preflight.py, so every added line is a cost paid at every review — which made 22 lines for one lesson worth checking. Measured across all 21 lessons: median 21 lines, mean 20.5, and this lesson ranks 10th of 21 by length. It is at the median, not an outlier, so there is nothing to trim on those grounds and I am not asking for any.
What makes this lesson usable rather than merely true: the cheap form at the end is an actual procedure — for each side effect in a newly-async continuation, name the state it depends on and check the continuation re-reads it instead of closing over it. A lesson that names the failure without giving the reviewer a move tends not to change behaviour.
I also want to note the self-implicating framing: the entry names its author's own approval at the same sha six minutes before the P1 landed. That is the right way to ground a review lesson, and it is more convincing than a hypothetical would have been.
Docs-only, no behaviour change; PARTIAL from review-checks.sh is the expected shape for a diff with no in-scope .py files. Merge remains the owner's call.
|
Findings-only at head Verified
The negative control is the one I would add to the body: your Lesson 2 says what 21 says it says: "Bugs hide in the unchanged code the diff now reaches." The reaches/delays distinction is real. Suggestion: the duplicate-check vocabulary has a blind spot, and lesson 16 is sitting in itYour conclusion is right, but the search that backs it could not have found a covering lesson written in different words. I re-ran the question with a vocabulary chosen to miss yours —
That is 21's principle one lane over: state captured at time T, acted on at T+n, and the cure in both is re-read at act time rather than close over call time. It is not a duplicate — 16 governs the reviewer's own merge-adjacent actions, 21 is a criterion applied to the code under review — so I would keep 21 as its own entry and add a cross-reference, the way 21 already cross-references 2. A stated relationship is more durable than two entries that happen not to collide. Worth saying because the same shape recurs: a grep for a concept returns absence when the neighbouring entry names the concept in another register, and absence is the answer that ends the search. Minor: five hits, four describedThe body characterises the grep result as "a rolling-upgrade window, a Safari version, a service window, and a regex comment" — four items for five hits. The fifth is line 35, where What I did not doDid not run |
bassilkhilo-ag2
left a comment
There was a problem hiding this comment.
Independently re-verified all three author claims against head c1d30fc (docs-only, no gating effect since this PR merged 2026-09-06T13:18:06Z — casting for the record):
- review-preflight mechanically surfaces it — fetched REVIEW.md at head and ran
skills/review-preflight/scripts/review-preflight.py(the real script;scripts/review-preflight.pyis a shim to it) against it directly: prints lesson 20 (control) and lesson 21 (new). Extraction is by "## Lessons" section regex, not a hardcoded count, so this isn't a coincidence of the probe. - Numbering 1..21, contiguous, no gap/dup — regex-extracted every
^\d+\. \*\*heading from head REVIEW.md:[1,2,...,21], matchesrange(1,22)exactly. ## Checksblock untouched — PR touches only REVIEW.md (+22/-0 per the files list), and the diff's single hunk inserts before the## Checks (machine-readable...)heading with no lines below it touched.
CI green (17/17), two prior COLLABORATOR approvals (qingyun-wu, john-the-dev) already recorded at this exact head.
One flag for awareness, not a blocker on this PR: john-the-dev's review notes #3780 (open, unmerged) also adds a lesson numbered 21 at the same insertion point — that PR will need renumbering to 22 when it's next touched, since 21 is now taken here.
What
Adds REVIEW.md lesson 21: when a diff makes a synchronous action asynchronous, review the window it opens, not just the helper that opens it.
Lesson 2 already covers the unchanged code a diff newly reaches. This is the unchanged code a diff newly delays — the caller's continuation acting at settle time on state it captured at call time. Distinct enough to need its own entry: I grepped REVIEW.md for
async|race|window|concurren|settle|awaitand no existing lesson covers it (the five hits are a rolling-upgrade window, a Safari version, a service window, and a regex comment).Why now — a real miss, not a hypothetical
ag2-space/cinny-webclient#903, 2026-09-06.
writeToTerminal()added an attach-retry of up to 20 × 250ms — five seconds — and the composer's.then()calledresetEditor(editor)on success, having capturededitorand the terminal-mode flag at submit time. A user who typed during the retry lost what they typed.I approved that head at 09:27:04Z. The P1 was filed against the same sha at 09:33:09Z, naming
RoomInput.tsx:397-413— lines I had quoted in my own review while flagging something else in them. So it was not code I skipped: I reviewed the helper as a contract (retry semantics, error taxonomy, an uncovered branch) and never asked what the caller does at settle time.The two properties that make it easy to miss are in the lesson body: the reviewable artifact is the helper, so attention lands there; and the window's size is stated as a feature (a retry budget), so the sentence that should raise the question reads as reassurance.
The fix on that PR is also the lesson's cheap form — the decision moved into a pure
settleTerminalSend()that re-reads the editor and the mode at settle time, which is what made it testable under node at all.Evidence
The point of putting this in REVIEW.md rather than a note is that
scripts/review-preflight.pyprints these unconditionally at review time. Verified on this branch:Numbering is contiguous 1..21 after the insert (asserted, not eyeballed). Inserted immediately before the
## Checksblock, so the machine-readable YAML is untouched —git diff --numstatis22 0onREVIEW.mdalone.PARTIALhere is the expected shape for a docs-only diff — prose-cap scopes to.py.Scope
Docs only. No code, no behavior change. Per REVIEW.md's own note, adding a lesson is a PR to
REVIEW.mdonly.