# Issue 21821 — read-only proof audit, pass 1

Issue: [#21821](https://git.cafe/pingdotgg/t3code/issues/21821). Branch `fix/issue-21821`; audited head [5117e44115](https://git.cafe/pingdotgg/t3code/commit/5117e44115aa5d87a51bd4e6cd14f3edf6d0df07), base [fef851bee0](https://git.cafe/pingdotgg/t3code/commit/fef851bee09102641061aeb78a3092c2ba2c72ab). Model: gpt-6.1-sol; harness: Codex.

## Scope and result

Read worktree AGENTS.md, the complete `git diff base...head`, shared loader/controller/command and history merge helpers, web and native mobile callers, desktop renderer entry, paging policy, issue description, and supplied seed scripts. No app/runtime modifications, captures, server starts, tests, pushes, comments, or PR operations performed. Only this requested artifact was written and uploaded. The lead's server on port 8102 was left untouched. All capture rows below are requirements, **not completed verification**.

Only `packages/client-runtime/src/state/threads.ts` and `threads-sync.test.ts` changed. There are **no component render changes**. Plain `loadEarlier()` now sequentially merges full history pages while no fetched item starts a user-message turn and both continuation indicators permit it. Loading remains true between pages. Cursor advances after each merged full page; cache remember runs per full page. Agent-authored MCP user messages count as starts; both steer intents do not; queued-turn messages do. Notifications do not satisfy this client's new stop predicate. `loadEarlier(throughEntryId)` deliberately retains one cursor, conversation preview then full activity (two phases), with no new page loop. The adjusted retry test now explicitly retains that target ID.

New source-level tests cover a three-page agent-start stop with older history remaining, and a second-page HTTP failure with retry at the failed cursor. Existing targeted-navigation tests cover preview, full activity, replacement snapshot, and retry. These tests were inspected, not executed in this audit. They are not substitutes for recordings of the user interaction.

## Evidence and seed conventions

- **W4** means fresh bounded app state at each of **1440 px/light, 1440 px/dark, 390 px/light, 390 px/dark** (suggest 900/844 px heights). Record each combination; do not reuse an expanded cached thread and call it a new starting state. Theme/viewport changes alone are insufficient to reset history.
- **W1** means one representative web recording at 1440 px/light. Branch-only changes use focused deterministic runtime tests rather than repeating every branch in four skins. W4 is covered by the primary interaction, not a Cartesian product of every branch.
- **N2** means real native mobile around 390 logical px, light and dark. Responsive web at 390 is not native mobile evidence. iOS and Android remain separately unverified unless actually exercised.
- Every interaction/time row requires a **recording**, including before/after transitions, loading, navigation, error/retry, and fold expansion. Stills can supplement a recording, never replace it. Pair base/head recordings for the primary repro with identical fixture and viewport/theme. Attach a redacted request/state trace where page counts or cursors matter; video alone cannot prove them.
- **S** = supplied `/tmp/issue-21821-retry/seed.py`: 11 completed runs, first 532 items (agent/MCP turn-start + 530 commands + final assistant), ten subsequent human runs of two items each. [Public seed](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/a4bf95d22b2650c9/seed.py). It mutates the first existing thread's projections, uses fixed IDs, and is not idempotent. It is a synthetic projection fixture, not an event replay or a copy of the reporter's actual history.
- **L** = supplied `literal.py`: clones S's first two runs into `literal-21821`. Already fully loads per lead; do not claim this as a failing baseline.
- **Safe real-app seeding for every row**: lead owns fixture preparation on a stopped, disposable isolated server/database; first migrate/copy real data read-only into that environment, then adapt S/L with unique IDs, valid thread/project linkage, ascending ordinals/times and completed run/message/turn-item projections. Verify API bounded snapshot/history responses and reopen through the actual app. Never run either script against the active 8102 database, live home, or an event-authoritative production database. Do not mutate the lead's runtime to manufacture a capture. If a row needs another fixture, request lead preparation in a separate stopped disposable environment. This audit did not seed anything.

## Fixture matrix

| ID / affected scope | Real app fixture / seeding delta from above | Minimum coverage and proof | Required observable result / assertion | Audit status |
|---|---|---|---|---|
| A — primary plain button; changed shared loop; web/desktop render path | S; fresh bounded open, long completed MCP run older than ten human turns; retain fold initially collapsed | **W4 paired base/head recordings** from pre-click through completion; redacted sequential history request trace | Base clicks can only grow hidden Worked activity/duration. Head one click continues across activity-only pages until agent opening `Agent opening: inspect the project` is loaded and reachable; show it, not only the duration. No repeated manual clicks needed; no lost newer messages | Required, uncaptured |
| B — fold interaction and scroll preservation; unchanged renderer receives more rows | Same S as A, no additional seed | Include in A W4 recording: expand Worked, inspect opening/commands, collapse, scroll back to newer turns | Newly loaded content exists; fold toggles work; no duplicate final assistant/opening, no unexpected jump to latest, button remains usable while more older history exists | Required, uncaptured |
| C — loading state, intermediate merges, repeated input/busy | S with lead-owned deterministic delayed history responses in disposable fixture environment | W1 recording + request sequence trace; can combine with A's 1440/light session | Loading label and disabled button persist across follow-up pages; rapid second activation cannot start another chain. Pages merge progressively; loading clears at stop | Required; new test does not hold intermediate page to prove this |
| D — start found before history exhaustion; changed positive stop | Prepend an older completed run before S so agent opening page still has a non-null cursor and more history | W1 recording + focused loader assertion | Stops at first fetched page containing agent/MCP turn-start; leaves older cursor/button; next click loads older turn. Does not needlessly drain entire thread | Source test covers stop metadata; app proof pending |
| E — human and queued start shapes; new predicate branches | Completed histories placing `createdBy=user,inputIntent=turn_start` and then `inputIntent=queued_turn` in boundary page; agent/MCP variant covered by A/D | Focused runtime cases for both shapes; W1 recording for normal human one-click control | Each opens a turn and terminates this invocation; authored source does not gate stop. Queued run must have started/completed so its message has a real turn item | Human/control capture pending; queued predicate assertion missing in added tests |
| F — steer exclusions; changed predicate negative branches | S variant with `steer` then `promoted_queued_to_steer` user-message items in intervening activity pages, older true start behind them; preserve valid run/message relationships | Focused runtime cases for both intents; W1 recording of combined fixture | Neither steer stops paging early; one click reaches true opener. Assistant/reasoning/command/file-change/dynamic-tool rows also do not count as starts | Added test covers command-only negative shape; steer cases unverified |
| G — notification and non-command history shapes; deliberate predicate scope | Completed notification-started run and mixed assistant/reasoning/file-change/dynamic-tool activity before older user-message start | Focused runtime fixture; if presenting UI evidence, W1 recording | Current code continues past notification until a user-message start or exhaustion; document that this is the implemented boundary, rather than claim all server-defined run starts stop it. No need for one provider fixture per activity kind | No new test for this shape; broader notification policy is outside this fix |
| H — exhaustion without a user-message start; changed continuation termination | Legacy/imported completed activity-only history spanning multiple fallback pages, no qualifying opener; final response false/null | W1 recording + focused runtime assertion | One click drains available history; loading clears; control disappears; no infinite loop. Seed must omit opener deliberately, not delete a live message | Not covered by new test |
| I — independent continuation flags and empty page shape | Real valid exhaustion covered by H; inconsistent hasMore=true/cursor=null or false/non-null and empty-but-advancing responses require controlled history service response fixtures, not corrupt DB edits | Focused runtime cases; no extra viewport matrix. Recording if any UI behavior is offered as proof | No follow-up when either continuation condition fails; empty advancing page continues. Repeated non-advancing cursor is a service-contract concern worth checking, not established by normal seed | Unverified protocol edges; proportionate test-only coverage |
| J — 1 MiB/large-row budget as well as 75-row paging | S variant with valid ~900 KB checkpoint-associated content matching actual stored history item shape (first inspect reporter-shaped projection/API; do not invent a new item type); retain ten human turns | W1 recording + encoded-response size/cursor trace | Same visible recovery under byte-driven boundaries; requests stay under existing server policy except its intentional single oversized-item allowance. No total-loop byte cap is added | Supplied seed has no checkpoint/large output: **not covered** |
| K — follow-up page failure and plain retry; changed moving request cursor | S; controlled one-shot 503 on second full-page request, then success; never stop active lead server to simulate this | W1 recording (prefer 390/dark if convenient) + request trace | Earlier successful page remains merged; loading clears, error visible; retry begins at failed cursor, clears error, reaches opener without duplicate rows | New source test covers cursor/retry; UI uncaptured |
| L — first-page failure/disconnected entry | S bounded history; controlled first response failure/disconnected prepared session | Focused runtime check; W1 recording only if reporting UI error behavior, may combine with K | No content/cursor advance on failed first page; recoverable error and retry. Existing disconnect guard unchanged, expanded request lifetime makes it relevant | Unverified here; no need four-theme failure matrix |
| M — replacement snapshot while a later page is pending; moving guard | S; gated follow-up response plus authoritative bounded replacement snapshot with different cursor, or thread deletion | Focused deterministic runtime cases, no sleeps; W1 recording only for a user-facing claim | Stale success/failure is a no-op and cannot merge or clear replacement state; deletion does not revive content. Test on a **follow-up** cursor, not only first request | Existing targeted two-phase replacement test does not prove new moving-cursor case |
| N — leave/remount/cancel and persistence; changed per-page remember/cursor | S; gate follow-up, navigate away, then reopen same thread; fresh bounded reopen separately | W1 recording + deterministic cancellation/cache assertions | Pending chain interrupted safely, loading resets for current cursor, no stuck spinner; remount can retry; cache behavior consistent with existing bounded-cache policy, no promise that all expanded history persists | Existing first-request unmount test is adjacent coverage, not new follow-up proof |
| O — targeted find navigation retained two phases; changed retry test | S, search a unique unloaded earlier assistant/opening text; target entry outside bounded window; add controlled delayed activity phase and one-shot activity error | W1 recording normal and retry (may combine); focused existing tests for preview/replacement/retry | Targeted invocation sends conversation then full activity at **same cursor**, passes throughEntryId both times; preview visible before activity; target/highlight stays positioned. No new plain loop on retry. UI may invoke again if target remains absent; do not describe whole search as globally limited to two network requests | Source tests support intent; app uncaptured |
| P — literal two-run non-regression control | L: completed 532-row agent run + one human run, as supplied; fresh open | W1 short recording of initial fully loaded history and any available history control; no staged failing baseline | Record already-loaded state honestly. If no button exists, do not manufacture one or claim this proves multi-page repair | Lead says fully loads; not independently verified |
| Q — actual desktop surface | Same S exposed to Electron renderer from disposable environment | One **real desktop** 1440 recording, light minimum; web W4 covers shared layout/themes. Show button, loading, opener and fold | Confirms actual Electron entry/scroll behavior; desktop wraps shared web, no new IPC path. 390 desktop is unnecessary; 390 web is separate responsive coverage | Desktop unverified until actual Electron recording; browser cannot certify it |
| R — actual native mobile surface | Same S reached through native client's environment/thread selection; no native DB seeding | **N2 recordings**, one tap through opener/fold behavior; test iOS/Android as available and name untested OS. Web 390 cannot substitute | `Load earlier activity` disables/shows loading through page chain, then clears; native list displays reachable opening/history and maintains usable scroll/folds | Separate RN renderer, **requires capture**; iOS and Android both unverified here |
| S — local versus remote/relay/tunnel | Same S served by isolated environment; connect actual client via existing authorized remote link; do not bake localhost origins | One representative remote W1 recording + request trace, can reuse A if A is remote; deterministic API coverage for remaining transport equivalence | Sequential fetches use existing prepared auth/environment routing, no new endpoint or contract. Report local-only if remote not exercised; no full W4 per transport | No transport verification in audit |
| T — assistant citation hook, dormant paging prop | No new seed required: current ChatView passes historyControls, **does not pass MessagesTimeline.loadEarlier**; that optional prop defaults null | Source trace only, no mandatory citation capture for this diff | Hook has an optional plain-page callback, but no production assignment found. Do not claim an active additional changed caller. If lead wires it later, use citation to older assistant in S and record paging/target reveal | Not an active entry point at audited head |

## Surface and scope decisions

Web paths are ChatView → MessagesTimeline history button (plain), and useThreadFindNavigation → historyControls (targeted). Mobile paths are ThreadRouteScreen → ThreadFeedLoadEarlierControl (plain). Both route via shared threadCommands → ThreadHistoryController → EnvironmentThreadState. Desktop loads the web application in DesktopWindow and inherits those web callers. No Settings, command palette, or independent keybinding caller to the history command was found; find's own invocation/navigation remains in its existing path. No provider adapter, server, wire schema, protected mutation, agent tool, scheduled task, or docs behavior changed; therefore no per-provider six-way capture matrix or MCP mutation proof is warranted. Agent/MCP **authorship** is a required data shape (A), not a requirement to launch live agents.

Minimum user-facing publication package: W4 paired primary repro recordings (include fold interactions), representative failure/retry and targeted-find recordings, real desktop smoke recording, real native mobile light/dark recordings where available, and a request trace plus focused tests for logical branches. Do not assert desktop/mobile/remote were verified from shared-code inspection. This is a proof plan and gap inventory, not a finding that all rows are release blockers or a claim of a code defect.

## FRICTION

| category | event | prevention |
|---|---|---|
| fixture fidelity | S exercises item count but omits reporter's ~900 KB checkpoint; L already fully loads | Separate byte-budget fixture and label literal case as a control; verify actual API boundary before recording |
| evidence validity | Growing Worked duration or still captures can look like success while opener is still absent | Record one click through loading, reveal opening/history, expand/collapse fold, attach cursor trace |
| runtime safety | Seed scripts directly mutate first thread, fixed IDs, and lead's active DB path | Lead-only preparation against stopped disposable copy with unique fixture IDs; never rerun on 8102 |
| surface coverage | Shared loader tempts counting responsive browser as desktop/native proof | Keep Electron and each native OS explicitly unverified until actual client recording |
| branch coverage | Existing replacement/unmount tests concern earlier request phases; loop now advances cursor | Add focused follow-up-cursor cancellation/replacement assertions instead of multiplying screenshots |
| caller scope | Optional citation paging callback resembles active caller but is not supplied by ChatView | Trace production prop assignments before expanding fixture matrix |

Audit author: gpt-6.1-sol via Codex. No subdelegation.
