# Proof audit pass 1 — mobile reasoning groups

Issue: [#25283](https://git.cafe/pingdotgg/t3code/issues/25283)
Branch: `fix/issue-25283`
Head: [261a20e499](https://git.cafe/pingdotgg/t3code/commit/261a20e499129bf6daecdaf2f3fe93a9e9f1e016)
Parent/base: [184d915d87](https://git.cafe/pingdotgg/t3code/commit/184d915d8774615a01ebae0350235a1039852e85)

Read-only source audit; no runtime, device, browser, or capture work performed. All rows below are planned proof, not observed passes. Checkout was clean and matched the supplied head; HEAD^ matched the supplied base. Scope derived from `git diff HEAD^ HEAD -- apps/mobile/src/features/threads/thread-work-log.tsx` and its feed/layout callers. No PR created.

## What changed and what constitutes proof

Only the expanded grouped-detail branch whose activities are ALL reasoning changes. It now uses WorkLogBlock and a new nested ScrollView wrapper with a bottom gradient. Existing ml-7, max-h-96, py-1 remain. WorkLogBlock contributes -mx-1/px-1 and mb-1 only when continuesWorkLog is false/undefined. True removes that trailing margin. Include the header and next feed row in framing: a crop of text alone cannot prove spacing.

The 12-unit bottom overlay has opacity clamp((contentHeight - viewportHeight - scrollOffset) / 12, 0, 1). Therefore short content must have no visible fade; overflow at top must show a bottom fade; the final 12 units must taper it to zero; at exact end it must vanish. There is NO top overlay in this reasoning branch. Verify top text is readable; do not require top-fade parity with the unchanged tool list. Overlay starts at left-7, extends right-0, and ignores pointer events. Fade must blend with the actual screen color in both themes.

## Fixture matrix

L/D means execute in both light and dark. Capture the same fixture, width, text scale, disclosure, scroll position, and theme on base and head. Still rows need matched before/after images; every interaction row explicitly needs a recording (endpoint stills may supplement it). Reuse recordings for several rows when the states are unambiguous; no Cartesian product of every dimension is necessary.

| ID | Real-app fixture / affected path | Theme | State or action | Required visible oracle | Evidence |
| --- | --- | --- | --- | --- | --- |
| S0 | Short, expanded all-reasoning, continues=false/default | L/D | Open at rest; content demonstrably fits | Full text visible; no bottom veil; normal indent; terminal gap to assistant reply comes from WorkLogBlock | Before/after still |
| S1 | Long, expanded all-reasoning, continues=false/default | L/D | Inner scroll at TOP (offset 0), overflowing | Bounded height; bottom fade over text, blended to screen; no top fade; header and next reply retain correct spacing | Before/after still |
| S2 | Same long terminal group | L/D | Scroll TOP → middle → final 12 units → exact END → TOP; gesture begins over bottom overlay too | Native inner scroll works without blocking parent navigation; bottom fade persists away from end, tapers then vanishes; last line readable; returns at top; no unexpected top overlay | RECORDING |
| C0 | Short, expanded all-reasoning followed immediately by another eligible work-log feed row; continues=true | L/D | At rest | No terminal mb-1 gap between adjoining work-log blocks; no fade on fitting text; compare same-width terminal S0 | Before/after still |
| C1 | Long equivalent of C0; continues=true | L/D | TOP → END | Continuation spacing remains compact; fade and last-line behavior match S1/S2 despite different outer spacing | RECORDING; include top/end frames |
| D0 | Existing long and short groups | L/D | Collapsed → expanded → inner scroll (long) → collapsed → reopened | Chevron/content agree; text and fade disappear on close; no orphan overlay, blank reserved block, or overlap with reply; reopening initializes a coherent fade for its actual position | RECORDING |
| R0 | Long expanded terminal group | L/D | Resize narrow ↔ wide while at TOP, then repeat from END | Text reflows; measured viewport/content update; fade matches actual remaining scroll; last text remains reachable; overlay follows new width and indent | RECORDING |
| R1 | Threshold-sized reasoning group, continues=true | L/D | Resize or text-scale change makes fitting ↔ overflowing, then reverse; include a resize from END | Fade turns on only with hidden content and off when all fits; no stale veil after shrink/clamped offset; continuation gap remains compact | RECORDING |
| T0 | Long expanded at TOP and END; short fitting | Light ↔ dark | Change appearance in place | Gradient immediately matches screen color; no contrasting stripe; visibility still follows overflow/end, not theme | RECORDING |
| G0 | Single reasoning item, expanded via its retained header | Light | One short and one overflowing item; disclose then scroll long to END | Same changed branch works for one item, not only seeded multi-item groups; no missing header/content | RECORDING |
| G1 | Mixed reasoning+tool grouped details, then tool-only group | Dark | Expand/collapse; scroll overflowing control | Uses existing ThreadWorkGroupList rather than new reasoning wrapper; existing row layout and top/bottom fades remain intact | RECORDING, focused regression control |

S0/S1 cover terminal spacing; C0/C1 cover continuation spacing independently of height. S2 covers continuous opacity rather than merely two endpoints. R1 covers layout/content event ordering at the fit boundary; an extremely long seed alone cannot show the transition. D0 collapsed is an unchanged entry path but a necessary reverse-state control. G0 is the same render branch with a distinct real feed/header construction; G1 guards the all-reasoning predicate boundary. Empty groups, proposed plans, subagents, and ungrouped rows bypass this change; no full visual matrix is warranted for them. Web/desktop, RPC contracts, provider adapters, and connection modes have no changed code here. Fixture data can originate from any provider that emits reasoning items; no provider-wide matrix is warranted for this presentation-only diff.

For practical coverage: run all rows on the primary-owned phone in its current session when the primary chooses to capture. An Android/iOS parity spot-check of S2, D0, R1 is useful later because native nested scrolling/layout differ, but this audit makes no claim that a second device is available or tested. Do not acquire or change any session for this audit.

## Real-app seed options and current coverage

1. Existing isolated backend: `/tmp/issue-25283-home`; existing script: `/tmp/issue-25283-seed.py`. Read-only SQL confirmed `thoughts-long` has 3 reasoning turn items plus 1 assistant_message, and `thoughts-short` has 2 reasoning items plus 1 assistant_message. These are actual V2 projection rows used by the app, not mocked JSX. Script also supplies project, completed run, user message, and assistant message projections. Long text is 3 × 7 paragraphs with repeated sentences; short text is 2 × 1 paragraph. Open `long thoughts` / `short thoughts` under `Visual fixtures` and expand the thoughts header when the primary runs proof. The dimensions must still be checked on screen: “short” is a seed label, not proof of fitting at every text scale/width.
2. Current seeds end reasoning with a final assistant reply. They supply terminal false/default fixtures, not proof of continues=true. To supply C0/C1, the primary can later add a distinct isolated fixture where the expanded all-reasoning activity-group is immediately followed by an eligible work-log feed row. Feed presentation sets continuesWorkLog from adjacent resulting rows; do not just place an ordinary tool in the same group, because that makes the group mixed and selects the unchanged tool-list branch. A trailing active-tail thinking row is a plausible real presentation route; validate the resulting feed adjacency and branch before capture. The completed-run script as written does not seed that state.
3. Additional isolated V2 fixtures can provide single-item groups, a near-fit threshold text, and mixed/tool-only controls. Clone fixture identities and adjust item ordinals/references coherently; derive from existing real projected data or seed through an isolated harness. Do not modify the current session's database while it is in use. Coordinate backend stop/reseed/restart with the primary; this audit does not execute the seed script (it opens SQLite read-write and commits).
4. Alternative real-app input: use an existing stopped thread containing actual all-reasoning groups, copied into isolated state through the project's migration workflow while the isolated server is stopped. Select groups with both terminal and continued adjacency and verify their resulting presentation. Live provider generation is less deterministic, can produce mixed groups, and is unnecessary for these static fixtures. Never point a test server at live `~/.t3/userdata`.

## FRICTION

- Coverage gap: existing long/short seed does not establish continues=true, single-item, threshold resize, or mixed/tool-only controls. These are fixture preparation tasks for the primary, not completed evidence.
- Native fit is unknown until capture: max-h-96 is a utility cap, while actual wrapping, font scale, and viewport determine overflow. Measure the displayed state rather than assuming seed names guarantee it.
- Resize needs an actual supported viewport/text-scale change. If the leased phone cannot resize, document that limitation; text-scale changes also remount ThreadWorkLog via its textSizeKey and do not alone prove an in-place width resize. No device action was attempted here.
- Scroll position persistence is not implemented by the new wrapper: it owns fresh shared values and receives no scrollPositions. D0 should judge coherent reopening, not demand restoration to the prior offset. Text-scale key changes may reset position; distinguish this from a stale fade.
- No runtime proof was requested or produced in this pass. The primary-owned pool session `issue-25283` was untouched. All capture rows remain pending.
- Requested ghdrop upload is the only authorized external write; no forge comments, issues, PRs, commits, pushes, merges, or watches were made. Artifact contains synthetic fixture descriptions and source references only.
