Skip to content

Preserve inbox page states and integrate authenticated CR3 navigation - #362

Merged
BunsDev merged 10 commits into
cr3-inboxfrom
cr3-inbox-repair
Oct 21, 2026
Merged

BunsDev merged 10 commits into
cr3-inboxfrom
cr3-inbox-repair

Conversation

@BunsDev

@BunsDev BunsDev commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

CR3 inbox pagination could show stale group data as fresh, repeat a PR across page boundaries, and hide an earlier failed retry when a later page succeeded. This repair preserves per-page read evidence and Retry controls, deduplicates stable PR identities across all pages, and integrates the reviewed CR2 producer so navigation uses the real main-owned service.

Stacked on #346; includes producer #349 and repair #354. Land the producer before landing #346 to main. This PR does not close #322 or Code Review Gate A.

Validation

  • Three Electron regressions reproduced the pagination/status failures before their repairs.
  • Pre-integration renderer 65e86ddd: build/typecheck, 1,902 unit passes with 16 skips, full E2E 375 desktop passes with six opt-in skips and seven site passes.
  • Combined integration 080ea4da2d23e8853843ad896c5c8ca68d8259a0: build/typecheck and full unit suite passed (1,950 passes, 16 skips). Full combined E2E passed: 375 desktop passes with six opt-in skips and seven site passes.
  • Authenticated real-app probe passed inbox search, public PR resolution, Back/Forward, Changes/split controls, pin persistence after reload, missing-PR error and isolated signed-out behavior. No transport or IPC mocks, coding turns, or GitHub writes. See docs/reviews/2026-10-21-cr3-read-integration.md.
  • Independent review found no remaining material code blockers. Evidence wording corrections are included.

Original R1–R4 visual comparison and human keyboard/VoiceOver acceptance remain open. Account-switch races and stale/partial responses have fixture evidence; the live probe did not switch real accounts or interrupt the host network. Content panes, native AI review and GitHub writes remain separate follow-up issues.

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
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
@vercel

vercel Bot commented Oct 21, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
modex Ready Ready Preview Oct 21, 2026 1:02am UTC

Request Review

@github-code-quality

Copy link
Copy Markdown

Code coverage overview

Languages: TypeScript

TypeScript / code-coverage-agent

cr3-inbox 4e9d965 cr3-inbox-repair 080ea4d +/-
64% 65% +1%
View coverage of the 10 most impacted files.
File cr3-inbox 4e9d965 cr3-inbox-repair 080ea4d +/-
apps/desktop/sr...ckends/codex.ts 97% 97% 0%
apps/desktop/sr...task-context.ts 99% 99% 0%
apps/desktop/sr...TurnContent.tsx 48% 58% +10%
apps/desktop/sr...read-service.ts 0% 98% +98%
apps/desktop/sr...eview/github.ts 0% 99% +99%
apps/desktop/sr...de-review/gh.ts 0% 100% +100%
apps/desktop/sr...w/navigation.ts 0% 100% +100%
apps/desktop/sr...eview/reader.ts 0% 100% +100%
apps/desktop/sr...-review/pins.ts 0% 100% +100%
apps/desktop/sr...view/feature.ts 0% 100% +100%

ℹ️ Calculations represent line coverage. Results may change as calculations are updated.

@BunsDev
BunsDev merged commit ec498e7 into cr3-inbox Oct 21, 2026
6 checks passed
@BunsDev
BunsDev deleted the cr3-inbox-repair branch October 21, 2026 01:35

This branch was successfully deployed

1 active deployment
Preview — 080ea4da Deployed Oct 21, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant