Repository navigation
journeys: the action fuzzer (correctness and speed) as a mode of the smoke-gate driver - #29071
Conversation
…uzz.py, fuzz.py) Brings scripts/journeys (the journeys runner and the dogfood smoke gate, from cp/pa-d-dogfood-smoke-gate at 1222849) to feat-cmux-next, and adds the action fuzz on top of it (cmux-ad 2026-10-31, fuzz-catalog rows a and m): - ext_fuzz.py: step fuzz_run plays a seeded plan of user actions through debug.key, ext_window's drags and the driver's relaunch, at mixed timings, with a model of workspaces/tabs/terminals/panes. Oracles after each burst: create (or a visible refusal), R3a and R3b through ext_smoke's own smoke_r3 / column readings, focus, daemon == app topology, stall > 100 ms in cmux code, crash, leak after close-all. A failure is shrunk in the same app with ddmin. Speed marks per create: shown_ms, typeable_ms. - fuzz.py: rounds through run.py (exclusive, pool perf-lead, never cmux17), --base A/B on the same mini (ABBA), confirms each shrunk repro in a fresh lease and writes it as a regression journey; verdict CLEAN/RED/NOT JUDGED/DIAGNOSTIC, .clean file only for a judged clean run. - Sets: layout (row m: New Column, Cmd-D, Split Down, Ctrl-`, close pane, divider drag, window resize, relaunch) and full. - journeys/fuzz/: the fuzz journey and Lawrence's reported bugs as fixed sequences (lawrence-*.json). - test_fuzz.py (plan, ddmin, speed table, verdicts with a stand-in run.py) and test_fuzz_sim.py (the oracles against a simulated app with planted bugs): python only, no fleet. Tests: python3 scripts/journeys/test_fuzz.py (16 OK), test_fuzz_sim.py (8 OK), test_smoke_gate.py (OK), run.py --check (59 valid).
…ween Lawrence's reports)
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
Shipped in:
|
|
Found 1 test failure on Blacksmith runners: Failure
|
|
Review (independent review subagent, Claude): BLOCK at 0224106 Scope: BLOCK
Notes (not blocking)
|
- A round whose journey failed outside the fuzz verdict (smoke_ready, the final expect's other checks, a harness error) is RED, never skipped. An action whose input path fails is recorded and judged by the oracles (crash first) instead of ending the step. - predict: a workspace create resets the pane count (delta counts the shown workspace only). - paste: a comment line plus Return, so the next probe's line is clean. - desync, stall and focus are recorded findings (once per signature, with the seed and the actions before), not stops: the first trial on v2.2.11-opt and v2.2.10-opt stopped at the first Cmd-N on desync W1/W4/G1 and a 190 ms CefInitialize stall on both builds. A finding only on the build (not on the base) is RED; one on both is a base finding. - R3b read through settle_check; launch stalls after a relaunch skipped; shrink replays add no speed samples or findings. - Verdict: CLEAN needs --base, --minutes > 0, the full fuzz time and no replay; cmux20 (the quiet bench host) out of the default hosts. Tests: test_fuzz.py 19 OK, test_fuzz_sim.py 9 OK, 80 sim seeds clean.
… every run and shrink try - R3b: New Column (Ctrl-Cmd-D) keeps every old column's exact width; Cmd-D and Split Down split inside a column and no OTHER column changes width. Cmd-D is no longer a column action. New Column always starts its burst, so a red names the action that changed the column. - The layout set starts each run and each shrink try with every workspace closed and one fresh Ctrl-` workspace: the first fleet runs' shrink tries started in a workspace an earlier try had split, so ddmin could not shrink. - Corpus lawrence-column-widths: New Column twice, Cmd-D, Split Down, a New Column pair. - Sim: inside splits; planted 'a split resizes another column' is r3b, a split alone is not. Tests: test_fuzz.py 19 OK, test_fuzz_sim.py 12 OK.
Bugbot needs on-demand usage enabledBugbot uses usage-based billing for this team and requires on-demand usage to be enabled. A team admin can enable on-demand usage in the Cursor dashboard. |
|
Review (independent review subagent, Claude): BLOCK at 12857a6 Scope: The three earlier BLOCK items are fixed
The new verdict rules are correct. CLEAN needs BLOCK
Notes (not blocking)
|
…ures); the first red repro - signature() drops UUIDs, window ids and long hex: one focus or desync finding on the build and the base is one signature (no false RED). - paste only into a focused terminal (Return would submit a New Tab field). - The corpus round runs in the chosen set (the layout corpus gets the fresh start). - journeys/fuzz/found-r3b-new-column-narrows.json (P0, red on feat-tip-fixes-v2 f2f3083bac80ab71101d03ac): Cmd-N, Ctrl-`, New Column; the old column went 872 -> 291 pt. Owner a03ef38e4dc40283d. Tests: test_fuzz.py 20 OK, test_fuzz_sim.py 12 OK, run.py --check 60.
… Cmd-N, Ctrl-`, Cmd-D; fit_grid 110x40 vs grid 36x40)
Bugbot needs on-demand usage enabledBugbot uses usage-based billing for this team and requires on-demand usage to be enabled. A team admin can enable on-demand usage in the Cursor dashboard. |
|
Review (independent review subagent, Claude): SHIP at c70020e Scope: The BLOCK is fixed
Other checks
Notes (not blocking)
|
… per terminal, on in replays; Cmd-N first needs no Ctrl-` set-up
|
Review (independent review subagent, Claude): SHIP at 488ca50 Scope: the delta c70020e..488ca50 (scripts/journeys/ext_fuzz.py, scripts/journeys/fuzz.py). I did not build or test the app. Verdict checks (no blocker found):
Non-blocking findings (these affect traced replays only):
|
…ad 09:05Z) - run.py: SIGTERM raises Terminated, so run_lease's finally releases the lease; an acquire stopped by a signal is ended (capture-host unreserves). - run.py: the build comes from a per-mini cache outside the slot (~/.cache/cmux-journeys/builds/<job>/, newest 3), filled atomically by the first lease of that job; later rounds download nothing. - fuzz.py: ddmin runs outside the round, one short replay lease per try (--shrink-tries 10); the in-app shrink is off by default. fuzz.py passes its own SIGTERM to run.py as TERM (never KILL) and waits. - test_run_release.py: release after an error inside the round, after SIGTERM while driving, the acquire ended after SIGTERM while acquiring, and fuzz.py's SIGTERM reaching run.py as TERM. Tests: test_run_release.py 4 OK, test_fuzz.py 20 OK, test_fuzz_sim.py 12 OK, test_smoke_gate.py OK, run.py --check 61.
… default fuzz hosts
|
Review (independent review subagent, Claude): BLOCK at 22115f3 Delta reviewed: 488ca50..22115f3 (scripts/). Tests passed on a Blocker: a lease leak when fuzz.py is stopped with ^C (SIGINT to the process group)
Not blocking
|
… paths, unpinned on disk, cut tar, edit while packing (red) Review SHIP with should-fixes. Five new cases, red on 3592cf3 (python3 scripts/journeys/test_run_stale.py: 4 failures, 1 error): a used --out keeps the old <id>/ and run.json in place; a refused result's folder stays at <id>/ (clip and checks point at it); an unpinned round's result.json still says pass and fuzz.json stays; a cut-short result tar raises out of run_lease; an edit between the state read and the kit pack counts as pinned.
…, unpinned on disk, cut tar is not run, state read after packing - A used --out: the earlier results.jsonl, run.json and <id>/ folders are renamed with this run's id (finding 1). - A refused result.json: its <id>/ folder becomes <id>.foreign-<run id>, so no clip, check frame or reader takes it (finding 2). - Unpinned: result.json on disk gets the not-run status and reason too, and fuzz.json becomes fuzz.json.unpinned (finding 3). - A cut-short or bad result tar (tarfile.TarError, OSError) is "not run", not an exception out of run_lease (finding 4). - No start commit is unpinned, not a TypeError (finding 5); pinned: None on rows with no lease (finding 11). - The harness state is read before and after kit_tar; a change between them is unpinned (finding 6). - A journey start before the run start is logged, not refused: the random run id decides (finding 7). - Docs: what is packed at each lease, and whose id the .earlier name has (findings 9, 10). Green: python3 scripts/journeys/test_run_stale.py (13 tests).
|
Review (independent review subagent, Claude): SHIP at 72d5c43 Scope: delta 996108d..72d5c43 in scripts/journeys (commit 72d5c43: a Findings:
Observed / Not runObserved, in a |
…a pinned replay of the 3-action R3b repro on cmux20 shrank to New Column alone: shrinking a replay can be worth its leases) Test: the default replay uses one lease; --shrink-tries 4 shrinks it. test_fuzz.py 31 OK.
… aside with or without result.json; a failed folder rename is logged, not raised Re-review of 7115d71 (SHIP) nits 1 and 2. Nit 3 (a cut tar with a complete result.json) is left: dogfood-gate checks the frames itself. Green: test_run_stale.py (13), test_run_stale_result.py, test_smoke_gate.py (65).
|
Review (independent review subagent, Claude): SHIP at f487d34 Delta reviewed: Findings:
Non-blocking notes:
Observed: all from scripts/journeys of a |
…ction-fuzz' into cp/journeys-action-fuzz
|
Review (independent review subagent, Claude): BLOCK at 5be1587 Reviewed the merge result Blocking: a false RED from an unpinned round. Checked, OK:
Nit: |
…ogy; the app's desync monitor stays a recorded finding (it broke r11 round 2 on cmux20, seed 71008: a G1 desync counted twice made the round 'broken', a false RED) Test test_daemon_agrees_does_not_count_a_desync_finding_again: red on 5be1587, green here.
…O is dropped, and each .done names the GO it used (scheduler STATUS 1590: r11's shrink-001-02 on cmux20 at 12:54:53Z leased on the previous GO's copy) Test test_a_repeated_go_is_one_lease_and_done_names_its_go. test_fuzz.py 33 OK.
|
Review (independent review subagent, Claude): SHIP at 560419a Reviewed the delta The BLOCK is fixed. Pinned rounds still give RED (same simulation): smoke_ready failed, frame check failed, fuzz_run harness crash with no fuzz.json, and fuzz_daemon_agrees failed with a topology problem. A deadline round and a known-gap round ( (1) does not hide topology. Tests: test_fuzz.py:370 and test_fuzz_sim.py:511 fail on the 5be1587 fuzz.py/ext_fuzz.py and pass now. All suites pass: test_run_stale 13 (fresh worktree, now removed), test_run_stale_result 1, test_run_release 6, test_fuzz 32, test_fuzz_sim 25, test_smoke_gate 33, Nits (do not block):
|
Bugbot needs on-demand usage enabledBugbot uses usage-based billing for this team and requires on-demand usage to be enabled. A team admin can enable on-demand usage in the Cursor dashboard. |
|
Review (independent review subagent, Claude): SHIP at 45ddfc2 This receipt replaces my SHIP at 560419a (#29071 (comment)). All of that review still applies: the unpinned round gives NOT JUDGED, pinned smoke_ready, frame, fuzz_run crash and topology failures give RED, deadline and known-gap rounds count as not run, and ext_fuzz.py:1302 filters only Delta 560419a..45ddfc2 (one GO is one lease):
Runs at 45ddfc2 (git archive copy): test_run_stale 13 (fresh worktree, now removed), test_run_stale_result, test_run_release, test_fuzz, test_fuzz_sim, test_smoke_gate all OK. Nits (do not block): the |
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
Summary
The action fuzzer for cmux NEXT, built as a mode of the journeys / dogfood smoke-gate driver (cmux-ad 2026-10-31: "we need to fuzz greater for both correctness and speed"; fuzz-catalog rows a and m). One action layer and one set of oracles with the smoke gate.
scripts/journeys(the journeys runner and the dogfood smoke gate, fromcp/pa-d-dogfood-smoke-gateat1222849c09f, owner agent a7031071e77d3e582) to feat-cmux-next. Today it lives only on perf/chrome-parity and that branch.scripts/journeys/ext_fuzz.py: stepfuzz_run. It plays a seeded plan of user actions throughdebug.key(the key router's real path), ext_window's drags and the driver's relaunch, at mixed timings (now,pairwithin 60 ms,slow), with a model of workspaces, tabs, terminals and panes. Oracles after each burst:create(or a visible refusal),r3aandr3bthrough ext_smoke's owncond_smoke_r3,_widthsand_columns,focus,topology(daemon == app),stall(> 100 ms in cmux code),crash, andleakafter close-all. A failure is shrunk in the same app with ddmin. Speed marks per create:shown_msandtypeable_ms.scripts/journeys/fuzz.py: rounds throughrun.py(exclusive, pool perf-lead, never cmux17), a--baseA/B on the same mini (ABBA), confirmation of each shrunk repro in a fresh lease, written as a regression journey. Verdicts: CLEAN, RED, NOT JUDGED, DIAGNOSTIC. A.cleanfile is written only for a judged clean run.layout(row m: New Column, Cmd-D, Split Down, Ctrl-, close pane, divider drag, window resize, relaunch) andfull`.journeys/fuzz/: the fuzz journey, and Lawrence's reported bugs as fixed sequences (lawrence-*.json).This is not a CI job, step or gate (Lawrence 2026-10-23). It runs on the fleet, started by the lead, the tip watcher and the dogfood flow.
Testing
python3 scripts/journeys/test_fuzz.py: 16 OK (plan, bursts, ddmin, the speed table, and the verdicts with a stand-in run.py).python3 scripts/journeys/test_fuzz_sim.py: 8 OK. The oracles run against a simulated app. A correct app plays clean. Each planted bug fails with its own oracle (second split lost, column resize, grid mismatch, PTY mismatch, a stall in cmux code, a PTY leak), and ddmin shrinks it.python3 scripts/journeys/test_smoke_gate.py: OK.run.py --check: 59 valid.python3 scripts/cmux-next/prepush-gate.py: no new violations.Observed / Not run
journeys/fuzz/found-*.json. feat-tip-fixes-v1 cannot be driven: it is a plain Release build with no debug.* methods.Performance
No perf numbers: this changes only harness Python under
scripts/journeys(no app, daemon or web code). The fuzzer's own speed marks (shown_msandtypeable_msfor each create, an A/B against--base) are results it reports about the builds it tests. They are not a performance change of this PR.Changelog
none
Need help on this PR? Tag
@codesmith-botwith what you need.Summary by cubic
Adds a model-based action fuzzer for cmux NEXT as a mode of the journeys smoke-gate driver, bringing the journeys runner and smoke gate from
cp/pa-d-dogfood-smoke-gatewith the fuzzer built on top.The fuzzer (
ext_fuzz.py)debug.key, ext_window's drags and the driver's relaunch at mixed timings, with oracles for create, keys, R3a/R3b, focus, daemon-vs-app topology, stall, crash and leak.split_typeburst runs Cmd-D (or Split Down) with a line typed at once, then a second split 30 ms later with its own line; each must land in its own new pane or it is akeysred (TIP RED 1193).debug.creation.hold/release, the hold is proven by the release reply, so n(hold) = n(rounds); a split the app refused with a visible message is not judged.fuzz_crash_reportsstep classifies a mini's crash reports as product or harness.The orchestrator (
fuzz.py)run.pyon exclusive perf-lead leases (cmux19 only by default), with an optional--baseABBA; every lease waits on the mini scheduler's go hand-off, where one GO is one lease and a repeated GO is dropped.--replayis shrunk only when--shrink-triesis given.--base, positive--minutes, full fuzz time and no replay, and writes a.cleanfile.--whole-hostwith a key window; without one it reports "not run: known gap", never a product red.R3b: New Column keeps every old column's exact width; Cmd-D and Split Down split inside a column without changing others.
Includes
test_fuzz.py(33 tests),test_fuzz_sim.py(24 tests, 50 sim seeds clean),test_run_release.py(6 tests, including LateLease and DoubleStop),test_run_stale.py,test_run_stale_result.pyandtest_smoke_gate.py, all runnable without a fleet or app.Written for commit f9037b6. Summary will update on new commits.