# PR #22997 evidence: composer list-marker normalization (INCOMPLETE, budget exceeded)

**Environment:** Linux 6.1.102 (fs-09, load avg ≈20 during capture) · Chrome for Testing 148.0.7778.96 headless shell (Playwright 1.60.0) · DPR 1 · viewport 1440×900 · theme light (`colorScheme` emulation; app theme = system) · BEFORE `8d3b061121fe65669d5d43d011b48cd3027a4108` (`git rev-parse HEAD` in /tmp/ev-22997/before) · AFTER `9096191f300d60be9db7d547d9828604e706b256` (`git rev-parse HEAD` in ~/wt/pr-22997) · seed: one `vp run migrate-dev-db` snapshot of ~/.t3/userdata, copied byte-identically into both worktrees (sha256 a77f7619…b1be) · thread: seeded "New thread" (pingdotgg/t3code project), the default landing thread on both · rich text ON (default) · clock: `page.clock.install(2026-10-22T12:00:00Z)`, paused at +60 s for stills.

Driver: [drive-composer-list-markers.mjs](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/b65b6bbe47f35755/drive-composer-list-markers.mjs). Each video has a caption overlay naming the revision, row, and step; the times below are seconds into the mp4.

## Media (ghdrop -m output, verbatim)

[before-1440-light-g1.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/2b862ab2facc997e/before-1440-light-g1.mp4)
[after-1440-light-g1.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/79ef9a652988b059/after-1440-light-g1.mp4)
![before-1440-light-F1-end.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/1c4655a1901c4e59/before-1440-light-F1-end.png)
![after-1440-light-F1-end.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/d703f0679332309d/after-1440-light-F1-end.png)
![F1-1440-light-diff-x8.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/856cf31256205f08/F1-1440-light-diff-x8.png)
![F1-1440-light-diff-thr16.png](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/f3052998c52d6aac/F1-1440-light-diff-thr16.png)
[after-1440-light-g3.mp4](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/dfc865bec05e66af/after-1440-light-g3.mp4)

Step logs: BEFORE g1 [md](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/5b819fa2c8db415b/before-1440-light-g1.steps.md)/[json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/553b2255f5a4e596/before-1440-light-g1.steps.json) · AFTER g1 [md](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/20e5e247f5a7bbab/after-1440-light-g1.steps.md)/[json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/6184471a1055582a/after-1440-light-g1.steps.json) · AFTER g3 [md](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/38d0df9dd079c8fd/after-1440-light-g3.steps.md)/[json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/5bb959598afdc01c/after-1440-light-g3.steps.json)

## Rows (1440 light)

Video key: Bg1 = before-1440-light-g1.mp4, Ag1 = after-1440-light-g1.mp4, Ag3 = after-1440-light-g3.mp4.

| ID | expected before → after | observed before | observed after | match? | recording (row start → observe times) | stills / diffs |
|---|---|---|---|---|---|---|
| F1 | Lit `- existing text` → bullet | p "- existing text", p "second line"; MD `- existing text\nsecond line` | ul li[marker=-] "existing text", p "second line"; same MD | ✅ | Bg1 0.0 → Space 10.5, observed 12.0, end 14.3 · Ag1 0.0 → Space ≈10.6, end 14.4 | before/after/diff-x8/diff-thr16 above (1843 px >16/255) |
| F2 | Lit → bullet `*`/`+`, ol `1)`; `1` alone Lit | p "* existing" / "+ existing" / "1 existing" / "1) existing" | ul[*], ul[+], p "1 existing", ol li[marker="1)"] | ✅ | Bg1/Ag1 ≈16 → 20.7 / 26.6 / 32.8 / 35.1 | none |
| F2-ctrl | list on both | ul[*], ul[+], ol[1.], ol[1)] | same | ✅ | Bg1/Ag1 ≈36 → 41.8 / 49.8 / 57.3 / 73.6 | none |
| F3 | Lit → ol start=3; `1.` → start=1 | p "3. existing", p "1. existing" | ol[start=3] li[3.], ol li[1.] | ✅ | Bg1/Ag1 ≈74 → 80.6 / 87.6 | none |
| F4 | Lit `* existing` → bullet | p "* existing" | ul[*] "existing" | ✅ | Bg1/Ag1 ≈88 → 95.0 | none |
| F5 | (a) Lit → task unchecked/checked; (b) Lit, then empty task on ArrowDown | (a) p "- [ ] existing", p "- [x] existing"; (b) p "- [ ]" before and after ArrowDown | (a) taskList checked=false / checked=true; (b) p "- [ ]" while the caret is on the line, then an empty taskList item on ArrowDown; MD `- [ ]\nother` | ✅ | Bg1/Ag1 ≈96 → 102.2 / 109.4 / (b) 189.9 & 192.1 (≈71 s stall at the Shift+Enter, 114→185) | none |
| F9 | (a) identical: empty item + paragraph; (b)/(c) Lit → bullet immediately; one undo | before not captured | (a) all 5 markers: empty list item of that type + p "existing text", one Ctrl+Z → p "existing text"; (b) bullet at once, undo → p "-existing", redo → bullet; (c) bullet, MD `-  existing` kept | AFTER ✅ (BEFORE missing) | Ag3 0 → 6.1, 15.0, 24.1, 109.2, 122.8; (b) 133.9/138.2/142.7; (c) 152.0/156.3/161.1 | none |
| F10 | identical, all Lit | not captured | (a) p "text - more", (b) p "a - b", (c) p "  - x"; (d) driver error (composer click timed out under load) | AFTER (a)–(c) ✅, (d) not run | Ag3 177.9 / 182.2 / 200.7; error 244.8 | none |
| F11 | Lit, same both | not captured | (a) p "- existing" (MD `**-** existing`); (b) p "`- `existing"; (c) driver error | AFTER (a)(b) ✅ | Ag3 359.7 / 367.6; error 400.0 | none |
| F12 | same both, untouched | not captured | (a) ul li "- outer" (MD `- - outer`); (b)–(d) driver error | AFTER (a) ✅ | Ag3 667.9; error 699.8 | none |
| F13 | — | not captured | driver error at reset | ✗ not run | Ag3 791.6 | none |

## What else changed (outside the composer)

- Git panel: BEFORE is a detached worktree, so it shows **"Select ref"** and Changes **+0 −0**. AFTER shows **fix/issue-22989** and the PR's diff stats. This is the worktree's git state, not the PR. It is visible in the F1 diff images.
- Sidebar relative time ("53m") comes from seeded thread timestamps. The frozen clock makes it the same on both sides.
- No toasts appeared in the observed steps (toast count 0 in the logs).

## Unverified / missing (with reasons)

- **F6, F7, F8, F8-E1 (g2), both revisions:** the app stuck on its splash screen for >240 s on initial load. The VM's load average was ≈20, and the server logged event-loop stalls of 2.6 s and a 33 s `/ws` upgrade.
- **F9–F13 BEFORE:** the BEFORE g3 run was still in progress when I stopped the servers at the time limit, and produced no output.
- **F10(d), F11(c), F12(b–d), F13 AFTER:** `locator.click` timed out after 30 s under load.
- **F14, F15, F16a, F16b (g4), both revisions:** not reached within the budget.
- **F15:** an AFTER smoke run (no video, not uploaded) showed the CDP events fire (`compositionstart`, `compositionupdate`×3, `compositionend`). After commit, `- 日本語` stayed a paragraph. **It also stayed a paragraph after End, and Ctrl+Z emptied the composer.** The matrix expects a bullet on End. End probably dispatches no transaction because the caret is already at the line end. This needs a re-run with a real non-composition edit.
- **F16c** (a pending question needs a live agent run; the seed drops pending work) and **F16d** (a disabled composer needs a disconnected or project-less state): not attempted.
- **Core F1/F6 at 1440 dark, 390 light, 390 dark; F14 stills; F1 stills at those variants:** not reached. The driver supports them (`--viewport 390 --theme dark --rows F1,F6,F14 --stills F1,F14`).
- **A Shift+Enter with the caret at line start stalled ≈71 s on both revisions** (F5b). Shift+Enter at line end was fast. This looks like a pre-existing or load-related issue, not caused by the PR, and was not investigated.
