Repository navigation
Conversation
The design page's decision 4: one channel, CodeReviewRequest in and CodeReviewReply out. A cancel request answers null. No handler is registered yet; CR-2's read service adds it, and CR-3 binds to this line. Coven-Harness: Claude Code / claude-opus-5-5
The design page's decision 4: one channel, CodeReviewRequest in and CodeReviewReply out. A cancel request answers null. No handler is registered yet; CR-2's read service adds it, and CR-3 binds to this line. Coven-Harness: Claude Code / claude-opus-5-5
- PrSummary.stackHint is boolean | null. A search result names no base branch (checked live: no repository object either), so main knows the hint only for PRs it has read itself. - Unavailable gains head-changed: a files or checks read whose PR moved past the asked revision, with no earlier read kept to show as stale. - parseRevision is exported, so main checks GitHub's base ref and SHAs with the same rule the renderer's requests go through. Coven-Harness: Claude Code / claude-opus-5-5
- PrSummary.stackHint is boolean | null. A search result names no base branch (checked live: no repository object either), so main knows the hint only for PRs it has read itself. - Unavailable gains head-changed: a files or checks read whose PR moved past the asked revision, with no earlier read kept to show as stale. - parseRevision is exported, so main checks GitHub's base ref and SHAs with the same rule the renderer's requests go through. Coven-Harness: Claude Code / claude-opus-5-5
The renderer half of the read path and the workspace's rules, pure so they are tested without a window: - Reader: one read per slot. A newer read cancels the one it replaces; only the latest reply is applied, and only through acceptsReply with the scope it asked under. A rejected invoke is a failed read. - Navigation: history between PRs, each PR's tab arrangement (PR, Changes, or both side by side), the split folding to its focused pane when narrow, and saved pane widths fitted to the window. - Pins: a local list per account, validated on load, capped at 50. - The destination's switch: on in development, hidden in a built app unless set. - Layout keeps the split and file-tree widths with the other panes. Coven-Harness: Claude Code / claude-opus-5-5
A rail button opens the Code Review surface: the inbox beside a PR workspace whose PR and Changes tabs sit in the title bar, alone or side by side (R1, R4). Every read goes through main's code-review:read. - The inbox searches as you pause, opens a pasted or typed PR link, pages with Show more, and says when gh is missing or signed out, a read failed, or what it shows is stale. None of those look empty. - A PR opens with its header (state, repository and number, pin, copy link, Open in GitHub) over each pane. Review, instructions and merge are shown unavailable with their reason. - Back and forward move between PRs; each PR keeps its own tab arrangement and scroll positions. - The split and file-tree dividers resize by pointer and keyboard and persist with the layout, fitted to the window when restored. - Built apps hide the destination unless localStorage "modex.codeReview" is "on" (pending Val's decision). Overview content (#323) and the remote diff (#324) are not here; their panes say so. Coven-Harness: Claude Code / claude-opus-5-5
…(CR-3) The spec swaps main's code-review:read handler for one serving the synthetic fixtures, with requests it can hold and release: - Identical PR numbers in two repositories never show each other's answer, however late it arrives. - A slow search answer is cancelled and dropped when a newer query replaces it; typing reads only where it pauses. - Switching the gh account mid-read drops the answer and every PR of the old account. - Back and forward restore each PR's arrangement without reading it again; closing a tab moves focus to the tab or row it leaves. - No gh, signed out, offline, empty, denied and a failed page each say what happened. - Pin, copy and Open in GitHub use the canonical link; a pasted or typed link opens its PR; unavailable actions say why and do nothing; nothing reaches local Discard. - Keyboard alone at 1440x900 and 900x600, the split folding to one pane, resized panes persisting, and the inbox scrolling on its own. Fixes found on the way: a narrow "Review with Codex" kept no icon, and the signed-out message now says how to sign in. Coven-Harness: Claude Code / claude-opus-5-5
…(CR-3) A Workspace (CR-3) section at the end of docs/design/code-review.md: - The visibility switch. - How the PR and Changes tabs arrange the panes. - The built geometry against R1 and R4's measurements. - Pane minimums and folding. - Each #322 control with its test. - Deviations D6 to D10, and the open gates. Also drops a pane label that duplicated its tab's. Coven-Harness: Claude Code / claude-opus-5-5
The Store demo's handler map covers every bridge channel, so the new channel broke its build. The offline demo has no GitHub and answers it as unavailable, like its other account and system channels. Coven-Harness: Claude Code / claude-opus-5-5
The Store demo's handler map covers every bridge channel, so the new channel broke its build. The offline demo has no GitHub and answers it as unavailable, like its other account and system channels. Coven-Harness: Claude Code / claude-opus-5-5
code-review:read is registered localOnly. Every payload passes validateRequest before anything runs. Reads go through the person's own gh login: gh api <fixed path> --hostname github.com --method GET --include, with no shell, no new sign-in and no token in Modex. - gh.ts runs gh and reads its status line, headers and body. It refuses any path that is not user, the issue search or under repos/, and keeps nothing gh prints to stderr. - github.ts maps GitHub's REST answers to the contract, checking and bounding every field. - read-service.ts keys each read by the gh account (rechecked after 30 s, conditionally) and the repository's stable id. It learns names only from its own reads. An account switch aborts reads in flight and drops everything learned. A files page is bracketed by PR reads, so a moved head reads as stale head-changed, and checks for an old head are stale. It has conditional caching, bounded concurrency, rate-limit backoff, cancellation, and last-good answers kept as stale. It never polls. - Browser development answers the channel with a disabled service. Checked live on TypeSafeAI/modex with Val's authorization, and written into the design page: - Search results carry no repository object. - A cross-reference has no id of its own. - The timeline spells review states in lower case. - The raw media type answers a directory as JSON. Coven-Harness: Claude Code / claude-opus-5-5
The independent review of 197276e requested changes. - AC2 (blocker): a gh auth switch inside the 30 s identity window went unnoticed, so reads ran as the new account but were stamped as the old one. Main now fingerprints gh's hosts.yml, which switch, login and logout rewrite. It rechecks the account when that changes, and confirms the account after every read before replying. Where the file can't be read, it confirms with a conditional gh api user (a free 304). The read that notices a switch goes on under the new account, and a switch clears rate-limit state. - AC3: when the account can't be checked (offline, slow, limited), the last confirmed account still scopes kept answers, which come back stale. Repository lookups all settle before one failure is raised. A 2xx that gh exits non-zero after is failed, not a short file. A short files page is partial, and search pages after the first never claim complete. - AC4: checks are bracketed by PR reads, like files. - Nits: hasOwn enum lookups, strict ISO timestamps, a 429 without Retry-After waits 60 s, a recreated repository is re-resolved, duplicate request ids are rejected, a cancelled read never starts gh, and a forced identity check never joins an older one. - AC5: the smoke probe and its results are recorded in docs/reviews/2026-10-20-cr2-read-smoke.md. Coven-Harness: Claude Code / claude-opus-5-5
The re-review of f2c2de7 found two ways the after-read check still let another account's rows through: - A: a switch away and back within one read. gh answered the original account again, so the read was accepted. Each read now records the hosts.yml fingerprint it began under. If it moved during the read, the answer is refused and nothing is kept, even if the account matches now. - B: a confirming check that failed passed the read. It now fails it. Also: - An inbox's groups are kept only after the check. - A login seen to change stops the offline fallback to the last account's answers. - The fingerprint includes the file's change time. - The contract gains mergePages, which joins an inbox group's pages, deduplicated by key, and calls the list complete only when the distinct rows reach the provider's total. Coven-Harness: Claude Code / claude-opus-5-5
* Invalidate retained PR data after authoritative visibility loss * Invalidate shared read resources without losing partial inbox results
…#362) * Name the code-review:read bridge channel (CR-2) The design page's decision 4: one channel, CodeReviewRequest in and CodeReviewReply out. A cancel request answers null. No handler is registered yet; CR-2's read service adds it, and CR-3 binds to this line. Coven-Harness: Claude Code / claude-opus-5-5 * Extend the read contract for what GitHub's REST answers say (CR-2) - PrSummary.stackHint is boolean | null. A search result names no base branch (checked live: no repository object either), so main knows the hint only for PRs it has read itself. - Unavailable gains head-changed: a files or checks read whose PR moved past the asked revision, with no earlier read kept to show as stale. - parseRevision is exported, so main checks GitHub's base ref and SHAs with the same rule the renderer's requests go through. Coven-Harness: Claude Code / claude-opus-5-5 * Answer code-review:read in the Store demo (CR-2) The Store demo's handler map covers every bridge channel, so the new channel broke its build. The offline demo has no GitHub and answers it as unavailable, like its other account and system channels. Coven-Harness: Claude Code / claude-opus-5-5 * Add main's Code Review read service through gh (CR-2) code-review:read is registered localOnly. Every payload passes validateRequest before anything runs. Reads go through the person's own gh login: gh api <fixed path> --hostname github.com --method GET --include, with no shell, no new sign-in and no token in Modex. - gh.ts runs gh and reads its status line, headers and body. It refuses any path that is not user, the issue search or under repos/, and keeps nothing gh prints to stderr. - github.ts maps GitHub's REST answers to the contract, checking and bounding every field. - read-service.ts keys each read by the gh account (rechecked after 30 s, conditionally) and the repository's stable id. It learns names only from its own reads. An account switch aborts reads in flight and drops everything learned. A files page is bracketed by PR reads, so a moved head reads as stale head-changed, and checks for an old head are stale. It has conditional caching, bounded concurrency, rate-limit backoff, cancellation, and last-good answers kept as stale. It never polls. - Browser development answers the channel with a disabled service. Checked live on TypeSafeAI/modex with Val's authorization, and written into the design page: - Search results carry no repository object. - A cross-reference has no id of its own. - The timeline spells review states in lower case. - The raw media type answers a directory as JSON. Coven-Harness: Claude Code / claude-opus-5-5 * Fix the CR-2 review findings: account switches, stale fallback, coverage The independent review of 197276e requested changes. - AC2 (blocker): a gh auth switch inside the 30 s identity window went unnoticed, so reads ran as the new account but were stamped as the old one. Main now fingerprints gh's hosts.yml, which switch, login and logout rewrite. It rechecks the account when that changes, and confirms the account after every read before replying. Where the file can't be read, it confirms with a conditional gh api user (a free 304). The read that notices a switch goes on under the new account, and a switch clears rate-limit state. - AC3: when the account can't be checked (offline, slow, limited), the last confirmed account still scopes kept answers, which come back stale. Repository lookups all settle before one failure is raised. A 2xx that gh exits non-zero after is failed, not a short file. A short files page is partial, and search pages after the first never claim complete. - AC4: checks are bracketed by PR reads, like files. - Nits: hasOwn enum lookups, strict ISO timestamps, a 429 without Retry-After waits 60 s, a recreated repository is re-resolved, duplicate request ids are rejected, a cancelled read never starts gh, and a forced identity check never joins an older one. - AC5: the smoke probe and its results are recorded in docs/reviews/2026-10-20-cr2-read-smoke.md. Coven-Harness: Claude Code / claude-opus-5-5 * Refuse a read whose gh sign-in moved under it (CR-2 re-review) The re-review of f2c2de7 found two ways the after-read check still let another account's rows through: - A: a switch away and back within one read. gh answered the original account again, so the read was accepted. Each read now records the hosts.yml fingerprint it began under. If it moved during the read, the answer is refused and nothing is kept, even if the account matches now. - B: a confirming check that failed passed the read. It now fails it. Also: - An inbox's groups are kept only after the check. - A login seen to change stops the offline fallback to the last account's answers. - The fingerprint includes the file's change time. - The contract gains mergePages, which joins an inbox group's pages, deduplicated by key, and calls the list complete only when the distinct rows reach the provider's total. Coven-Harness: Claude Code / claude-opus-5-5 * Invalidate retained PR data after authoritative visibility loss * Invalidate shared read resources without losing partial inbox results * Preserve inbox page freshness and retry evidence while deduplicating rows
* Keep keyboard focus when an approval is answered, its turn folds, Stop ends it, or Jump to latest is used (CF-8) (#342) * Keep keyboard focus when an approval is answered and its turn folds The CF-8 keyboard walkthrough found that pressing Approve or Deny with the keyboard dropped focus onto the page body: the answer buttons unmount once pressed, and a finished turn then hides its folded work. A keyboard or VoiceOver user lost their place twice. Focus now moves to the card's answer line ("Sending decision…", then "Approved" or "Denied"). When the finished turn folds work that holds focus, it moves to the turn's "Worked for" toggle. Focus elsewhere, such as the composer, is left alone. Red first: both keyboard tests failed on main (answer line inactive). e2e/keyboard-answers.spec.ts passes 3/3; the full desktop e2e passes 366 with 6 opt-in skips. Part of #281 (CF-8), tracker #273. Coven-Harness: Claude Code / claude-opus-5-5 * Hand focus to the message box when a keyboard Stop ends the turn The second walkthrough probe found the same defect at Stop: the button goes away when the turn ends, and focus fell onto the page body. When Stop was pressed with focus on it, focus now moves to the message box, where the next message is typed. Red first: the new keyboard test failed on the previous commit (composer inactive); keyboard-answers.spec.ts passes 4/4 and the full desktop e2e passes 367 with 6 opt-in skips. Part of #281 (CF-8), tracker #273. Coven-Harness: Claude Code / claude-opus-5-5 * Hand focus to the message box after Jump to latest from the keyboard The third walkthrough probe found that Jump to latest, once activated, goes away at the bottom and left focus on the page body. When the button held focus, focus now moves to the message box there. Red first: the new test failed (message box inactive). The keyboard spec passes 5/5, app.spec with it 19/19, and conversation-continuity plus typed-turns, which also scroll, 8/8. Part of #281 (CF-8), tracker #273. Coven-Harness: Claude Code / claude-opus-5-5 * Restore main's status.md after the #339 merge, keeping only this PR's entry The merge kept both sides of a block #339 had moved, which duplicated the released entries. The page is now main's, plus this PR's one entry. Coven-Harness: Claude Code / claude-opus-5-5 * Show a Codex web search's query and the results Codex reported (CF-5) (#344) A live codex-cli 0.163.0 capture (test/fixtures/codex-websearch-0.163.0.json) shows the webSearch item starting with an empty query, no action and no results, and completing with the query, a search action and text_result entries (title, url, domain, snippet). Modex titled the row "search " from the empty start, read neither action nor results, and stored the JSON string "" as its output. codexWebSearch (shared/evidence.ts) keeps the query, the action and results with an http(s) link, each text bounded, and counts what it drops. The Codex backend titles the row "search the web" until the query arrives, then "search <query>", and carries the search on the tool item. Expanded, the results show as links with snippets, marked data-provenance="codex-search" and labelled as unchecked. The renderer checks each link again before showing it, and nothing is fetched until a link is clicked. Older searches no longer show "". Red first: the three evidence tests and the Codex backend test failed on a stub, and the e2e test failed ("done", not "2 results"). Now evidence, codex-backend and conversation-events pass 69/69, the conversation-evidence spec passes 7/7, and the desktop unit suite 1,709 passed with 16 skipped. Part of #278 (CF-5), tracker #273. Coven-Harness: Claude Code / claude-opus-5-5 * Land main through a merge queue (#345) main requires branches to be up to date, so every landing sent each open PR back through CI. On 2026-10-19 that cost #309 three extra macOS runs, and on 2026-10-20 #336, #340 and #343 one or more each. The ruleset file gains a merge_queue rule (squash, all-green groups, up to 3 groups building and 5 PRs per merge, a 90-minute check timeout, since the macOS job alone may take 45). It drops the up-to-date requirement, which the queue replaces: a queued PR is tested on top of main and the PRs ahead of it. CI runs on merge_group, so each queued group reports the required unit + e2e (macOS) check; without it the queue drops every PR. The iPhone job and the coverage upload skip queued groups: neither is required, the PR already ran them, and main's push run repeats them. README, AGENTS.md and status.md say PRs land through the queue. The live ruleset (23989202) takes this file once this lands, so the queue starts only after main can report checks for it. Coven-Harness: Claude Code / claude-opus-5-5 * Say the phone no longer shows a withdrawn approval as declined (#343) human-requests.md still said the iPhone shows a withdrawn approval as declined. Since #335, mobileItem (companion.ts) sends a withdrawn, sending or uncertain approval to the phone as a notice that says so. The companion fallback test now covers the withdrawn case, which had no test (CF-6 #279, finding 7). Coven-Harness: Claude Code / claude-opus-5-5 * Note that the merge queue needs auto-merge, and list the keyboard Jump to latest CI failure (steward cycle 17) (#347) The first PR queued after #345 failed to enqueue: "Auto merge is not allowed for this repository". gh pr merge adds a PR to a merge queue by enabling auto-merge, so the repository now allows it, as OpenCoven/coven does, and README says why. e2e/keyboard-answers.spec.ts:88 (#342) failed in three CI runs of #345 in a row and passed on #342, on main and 25/25 locally. It goes under Known rough edges with what the failure snapshot shows and a link to the analysis on #342. Coven-Harness: Claude Code / claude-opus-5-5 * Prove a queue-landed branch merged when its tip merges cleanly into the landed tree (#350) Since #345, main lands through a merge queue, which squashes each PR onto main as it stands at the PR's turn. A branch that merged main into itself, then landed behind another PR, had no proof that worktree.sh remove would accept: - the squash tree also holds the PRs ahead of it, so it is not the tip's tree; - the branch's merge commits rule out the binary-diff proof. cf6-docs-followup (#343) hit this on 2026-10-20 and had to be pointed at its squash commit by hand. The new merge-tree proof merges the exact PR tip onto the squash commit's parent with Git's own merge. It accepts only a clean merge (exit 0) whose tree is exactly the landed tree. A configured merge.<name>.driver turns the check off, because a driver can drop a side's changes and still report a clean merge. New tests: - a queued branch with merge commits is proven and removed, and its archive ref holds the tip; - a wrong head, a wrong base, a different tree, a conflicted merge (even when the squash holds exactly the conflicted tree) and a configured driver that keeps main's side each stay not-proven-merged. Checked against #343's real branch and PR record in a throwaway clone. The old proof returns null. The new proof returns merge-tree with tree 6fc493b, the tree of 0a67354. Coven-Harness: Claude Code / claude-opus-5-5 * Hold Jump to latest when the composer grows or a Page Up is still moving (#352) * Hold Jump to latest when the composer grows or a Page Up is still moving e2e/keyboard-answers.spec.ts:88 (#342) failed on slow CI runners: after Enter, Jump to latest stayed. A trace in the app found two causes. - A scroll event is delivered before the browser reports a resize. If the composer grew right after the jump (a follow-up chip), onScroll measured a shorter view and stopped following. It now keeps following while the view has not moved above where auto-scroll put it, as follow() already did. - A Page Up still animating keeps applying its remaining distance after the page sets a new position: plain assignment, scrollTo instant and an overflow toggle all lose to it. For a second after a jump, a scroll with no wheel, key, pointer or touch input since the jump is that leftover motion, and the view pins back to the bottom. The reader's own scroll still wins at once. Red first, each test alone on main's ThreadView: the composer-growth test failed (the button stayed), the Page Up test failed (the view went back up 138 px), and the scroll-up guard passed. With the fix, keyboard-answers passes 24/24 (8 tests x 3), and app, conversation- continuity, typed-turns, conversation-rendering and layout 43/43. Part of #281 (CF-8), tracker #273. Coven-Harness: Claude Code / claude-opus-5-5 * Move the Jump to latest rough edge to the resolved list, with its cause The entry #347 added leaves Known rough edges, as written, under #352, with the two causes the trace found. Coven-Harness: Claude Code / claude-opus-5-5 * Invalidate retained PR data after authoritative visibility loss * Say whether a check verified a turn's last change (CF-7 verification) (#351) * Say whether a check verified a turn's last change, in its task record (CF-7) verification() in shared/task-context.ts reads a turn's tools in transcript order: - A check is a known test, build, typecheck or lint command, read inside sh/bash/zsh -c with quotes respected. An exit-zero echo or the model saying "tests pass" is not one. - A check passes only as succeeded with exit code 0 or none reported. - A check goes stale when an edit that was not denied, or a command that might write, runs after it. - The turn reads verified, failed, unknown, stale or none. taskRecord carries it, and the note gets a Verification section that marks stale checks. Anything short of verified goes under Not settled; a failure a later fix superseded does not. Plan steps keep the CLI's statuses: neither CLI links a check to a step. Red first: five of six new tests failed on a stub, then edits and displayCommand on theirs. task-context passes 13/13; the desktop unit suite 1,723 passed, 16 skipped. Part of #280 (CF-7), tracker #273. Coven-Harness: Claude Code / claude-opus-5-5 * Show a turn's verification beside Save to Notes (CF-7) A finished turn's footer reads, for example, "Verified: pnpm test passed after the last change" or "Not verified: pnpm test ran before a later change". It also covers a check that failed, a check that did not say how it ended, and a turn whose changes no check followed. A check shows as the script its shell ran, with the exact command on hover. A turn that changed nothing and ran no check shows nothing. Red first: the new e2e test found no verification lines (expected 2, received 0). task-to-notes.spec.ts passes 3/3. docs/task-context.md gains a Verification section, and status.md an entry. Part of #280 (CF-7), tracker #273. Coven-Harness: Claude Code / claude-opus-5-5 * List #352's Jump to latest fix under On main, unreleased (steward cycle 19) (#353) #352 changed what readers see: after a jump, the transcript no longer stops short of the bottom when the message box grows or a Page Up is still scrolling. It moved the CI rough edge to the resolved list but added no unreleased entry, so the next release review would not have listed it. The entry sits beside CF-8's keyboard entry and links the resolved list's account of the causes. Coven-Harness: Claude Code / claude-opus-5-5 * Mark the CF-7 verification plan done in #351 (steward cycle 20) (#356) #351 landed every task in docs/superpowers/plans/2026-10-20-cf7-verification.md, but the plan still read as not started. The five boxes are ticked from #351's own evidence: - the red and green unit tests; - the footer e2e (3/3); - task-context.md and status.md updated; - pnpm build and typecheck passed locally; - the full e2e suite passed in CI, on the PR and in the merge queue (run 39508701952). The local run stopped when the disk filled. A dated status line says that linking a check to a plan step stays open on #280. Coven-Harness: Claude Code / claude-opus-5-5 * Invalidate shared read resources without losing partial inbox results
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Code coverage overviewLanguages: TypeScript TypeScript / code-coverage-agent
View coverage of the 10 most impacted files.
ℹ️ Calculations represent line coverage. Results may change as calculations are updated. Updated |
| if (state.account && req.key.account !== state.account.id) return { state: "unavailable", reason: "signed-out", fetchedAt: at }; | ||
| const known = state.overview[keyId(req.key)]; | ||
| if (known) return known; | ||
| const row = known().find((r) => r.key && keyId(r.key) === keyId(req.key!)); |
10 of 14 tasks
This was referenced Oct 22, 2026
This was referenced Oct 22, 2026
This branch was successfully deployed
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.
The Code Review destination opens a searchable PR inbox and workspace through the main-owned read service now landed in #366. PR history, split layout, account-scoped pins and safe retry preserve identity and distinguish stale, partial and unavailable pages. Development builds expose the destination; packaged builds retain the existing local feature flag.
Replaces #346 and preserves its #362 repair. The producer and Note-ownership fixes are integrated, including the reviewed full-log fixture synchronization repair from #363. The only reconciliation conflict was status text saying nothing was visible; it now accurately describes the flag-controlled inbox. The CR3 implementation and evidence are unchanged from the previously reviewed inbox head. Overview content (#323), remote diff content (#324), AI review and writes remain separate work.
Current head:
0866265396d2ac6090b926e96b5da0d5c38bbdf3.44518f2bb58f106531431ba6f97da41d5350d0edis clean.Current-head required CI and protected main-queue validation are still required. Earlier head54c46f1 passed required CI run39537593468; that is historical evidence, not validation of the new merge head.
Authenticated real-app observations are recorded separately in
docs/reviews/2026-10-21-cr3-read-integration.md: inbox search, PR resolution, history, split navigation, persisted pins, unavailable PR and isolated signed-out states. Those observations precede this reconciliation; current automated tests use fixtures. The producer’s production Electron IPC test uses a synthetic gh executable.Original R1–R4 comparison and human keyboard/VoiceOver acceptance remain open. Issue #322 and Gate A remain open.