--- id: "bug-1803" status: "fixed" status_updated: "2026-09-24" status_note: "" component: "scheduler" severity: "unknown" timestamp: "2026-09-11T09:35:00Z" last_seen: "2026-09-19T09:00:00Z" occurrences: 1 files: ["src/scheduler/src/repl_break.c", "src/scheduler/src/repl_internal.h", "src/scheduler/src/sim.c", "src/scheduler/src/repl_info.c"] tags: ["scheduler", "repl", "sim", "replay", "break-ANY", "reverted", "info-summary", "next-non-dummy-session", "sim_prescan_next_nonempty_session", "cli-ux", "user-requested", "tdd", "design-mismatch"] related: ["bug-1802"] legacy: true gitea_issue: 272 gitea_synced_status: "fixed" --- # bug-1803: User feedback (live replay session, immediately after bug-1802's `break ANY` shipped): 'It seems… ## Description User feedback (live replay session, immediately after bug-1802's `break ANY` shipped): 'It seems that break any command will introduce too many break in single session' -- live transcript showed `break ANY` + repeated `step` firing 'hit breakpoint 1 @ event #N: any' on EVERY event (JOB_UPDATE, JOB_STATE_CHANGE, ...) inside an already-busy session (session 40), forcing many single-event `step`s just to get back OUT of that session -- the opposite of the intended 'skip past dummy sessions in one hop' workflow. User explicitly requested removing `break ANY` and instead having `info summary` display the next non-dummy session id so `step N` can jump there directly. ## Environment _Not recorded (migrated from buglog.json)._ ## Reproduction _Not recorded (migrated from buglog.json)._ ## Root cause Design mismatch, not a code defect: a breakpoint is inherently a persistent, repeatedly-firing mechanism (correct behavior for its stated purpose -- it fires on every matching event until deleted), but the user's actual need ('skip past a run of dummy sessions to the next one worth looking at') is a ONE-TIME navigation query, not a recurring pause condition. Modeling it as a breakpoint kind (bug-1802) meant it kept firing on every subsequent matching event for the rest of the session, well past the point it had already served its purpose, with no natural way to say 'just this once.' ## Fix REVERTED `break ANY` entirely (bug-1802's XCE_REPL_BP_ANY enum member, BP_KIND_TABLE entry, repl_breakpoint_matches_event() special case, and its 3 tests) back to the exact pre-bug-1802 code, confirmed via `grep -rn XCE_REPL_BP_ANY` returning nothing but the historical doc-comment note left in repl_internal.h. REPLACED with a one-time informational display: `info summary` now also prints 'next non-dummy session: N -- run `step M` to reach it' (or 'none remaining'), computed by a new sim_prescan_next_nonempty_session() (sim.c, exported via sim.h) that peeks ahead in sim->replay_file from the current read position (same ftell()/fseek()-around-a-shape-only-scan technique sim_prescan_session_count() already establishes for the startup session-count banner) for the next ReplaySession boundary preceded by at least one real event, then rewinds -- a pure read-only query, never a recurring pause. Returns a RELATIVE 'sessions ahead' count (not an absolute session number) specifically to avoid needing xce_sched_repl_state_t's full definition inside sim.c (an incomplete type there by the project's own Simulation Isolation boundary -- caught by a real compile error on the first attempt, `invalid use of incomplete typedef`, when the function tried to read sim->repl_state->session_count directly); repl_info.c (which has the full repl_internal.h definition) adds the relative count to rs->session_count for the absolute display number. TDD: added test_info_summary_reports_next_nondummy_session_when_present and test_info_summary_reports_none_remaining_when_all_dummy (test_repl_breakpoints_inspection.c). RED confirmed by temporarily hardcoding the summary's prescan result to a sentinel non-0/non-1 value and rebuilding: exactly these 2 new tests failed, 75 others green. GREEN confirmed after restoring: 77/77 Ok, zero regressions. The existing test_info_summary_reports_counts (a bare in-memory fixture with no `.replay` file, sim->replay_file==NULL) is correctly unaffected -- the new line is silently omitted whenever the prescan can't run, mirroring sched_sim_driver_start()'s own 'purely informational, silently skipped on failure' precedent for its sibling prescan function. ## Verification _Not recorded (migrated from buglog.json)._ ## References - Related: bug-1802 - Gitea: #272