myxce/.kiro/specs/scheduler-sim-repl-verbosity/tasks.md
Rongsong Shen da6ba96eb4
feat(scheduler-sim-repl-verbosity): task 6.2 - implement dynamic REPL prompt
Adds repl_build_prompt(), building the readline() prompt fresh each
loop iteration: the plain "(sim) " before any session begins, else
"(sim session=<N> t=<ISO8601-ts>) " using the bare session count (not
+1, matching info session's convention) and the existing
repl_format_ts_human(). Both of task 6.1's tests pass.

repl.c grew 808->852 lines (6.5% over the 800-line cap). Review
empirically tried extracting repl_build_prompt() into a new
repl_prompt.c: it works, but requires updating 19 sibling white-box
test files' #include lists, and even then repl.c only drops to 814
lines - still over cap. Given the function is a small 15-line
formatter and the split doesn't even achieve compliance, accepted in
place rather than forcing disproportionate churn.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAWMhfRJFnmmnG8h97yUDd
2026-09-02 16:14:52 +00:00

14 KiB

Implementation Plan

  • 1. Foundation: job identifier range compression

  • 1.1 Write failing unit tests for compressing job-array identifier listings into index ranges

    • Cover a single contiguous range, non-contiguous indices within one array submission, multiple distinct array submissions in one listing, a mix of array and non-array identifiers, and an output buffer too small to hold the full listing
    • Observable: the new test cases execute and fail against the current codebase, which has no compression behavior yet
    • Requirements: 4.1, 4.2, 4.3, 4.4, 4.5
  • 1.2 Implement job identifier range compression so the new tests pass

    • Group identifiers by their shared array submission and render contiguous index runs as a single compressed range, comma-joining non-contiguous runs
    • Never drop or fabricate an identifier, and fail safely (without truncating or crashing) when the output buffer is too small
    • Observable: all tests from 1.1 pass; the helper is ready for the event-echo and round-summary work to adopt
    • Requirements: 4.1, 4.2, 4.3, 4.4, 4.5
  • 2. Core: per-round decision summary, repetitive-round collapsing, and the shared range-flush capability

  • 2.1 Write failing tests for round-level decision summaries, collapsing, and the shared flush capability

    • Cover: a round with at least one decision produces one summary line naming decision counts and affected job identifiers; a round with zero decisions produces no individual line; two or more consecutive idle rounds collapse into a single range notification; two or more consecutive rounds with an identical decision outcome collapse into a single range notification; a collapsed range notification states its round bounds, round count, and covered time span; a change in outcome ends an active collapsed range; a job's status change between rounds is reflected in the following round's summary even without a dedicated dispatch event to observe; the shared flush capability safely does nothing when no range is active and is safe to call more than once in a row; an active collapsed range open at replay completion is flushed and printed before xce_repl_on_replay_complete()'s existing completion banner
    • Observable: the new test cases fail against today's unconditional per-decision echo, which has no summarizing, collapsing, or flush behavior
    • Requirements: 2.1, 2.2, 2.4, 3.1, 3.2, 3.3, 3.4, 3.6
    • Boundary: Round Rollup
    • Depends: 1.2
  • 2.2 Implement the round-boundary decision summary, collapsing logic, and the shared range-flush capability

    • Add the state needed to track an active collapsed range across rounds
    • At each round boundary during continuous execution, determine the round's decision outcome directly from current job status (not solely from decision events) together with the existing per-round decision tally, then extend an active matching range or end it and begin reporting the new outcome
    • Expose the range-ending behavior so other parts of the REPL can trigger it safely, including when nothing is active; wire it into the existing replay-completion notification so a range open at end-of-replay is closed and reported before that notification prints
    • Observable: all tests from 2.1 pass; replaying the real 108-round capture that motivated this feature under continuous execution now produces the hand-validated collapsed shape (an idle range before the first job arrival, one line per job arrival, and one collapsed range per stable pending stretch, with any range still open at end-of-replay closed out before the completion notice) instead of thousands of repeated lines
    • Requirements: 2.1, 2.2, 2.4, 3.1, 3.2, 3.3, 3.4, 3.6
    • Boundary: Round Rollup
  • 3. (P) Core: mode-aware event echo, including ending an active collapsed range on structural events or breakpoint hits — Depends: 2.2

  • 3.1 (P) Write failing tests for suppressing routine event chatter and for ending an active collapsed range at the right moments

    • Cover: a routine per-tick event (a job status change, job progress update, job resource-usage update, queue update, or partial/delta resource-value update) produces no line under continuous execution; the same event still produces a line while single-stepping; a structural change (new jobs, workers, or resources arriving, a full resource-value snapshot arriving, or configuration pushed) still produces a line under continuous execution and ends any active collapsed range first; an event matching a breakpoint still interrupts continuous execution regardless of its classification, and ends any active collapsed range before the interruption is shown
    • Observable: the new test cases fail against today's unconditional per-event echo, which has no classification or range-ending behavior
    • Requirements: 1.1, 1.2, 1.3, 1.4, 3.5, 3.6
    • Boundary: Event Echo Gate
    • Depends: 1.2, 2.2
  • 3.2 (P) Implement the mode-aware event echo, range compression adoption, and range-ending wiring

    • Suppress routine per-event lines during continuous execution while preserving full detail while single-stepping; keep structural-change lines and breakpoint interruption behavior unaffected by the classification
    • Render job-arrival listings using the compressed range format
    • Before printing a structural-change line, and before a breakpoint interruption is shown, end any active collapsed range first so output never interleaves out of order
    • Observable: all tests from 3.1 pass; a continuous-execution run over a replay with only routine activity produces no per-event lines, a job arrival still prints one compressed line and correctly closes out any prior collapsed range, and a breakpoint hit shows the collapsed range's final state before the interactive prompt returns
    • Requirements: 1.1, 1.2, 1.3, 1.4, 3.5, 3.6, 4.5
    • Boundary: Event Echo Gate
  • 4. (P) Integration: retire the redundant per-decision echo during continuous execution — Depends: 2.2

  • 4.1 (P) Write failing tests confirming the old per-decision echo no longer duplicates the new round summary

    • Cover: during continuous execution, no bare per-decision line appears outside the round summary; while single-stepping, full per-decision detail still prints exactly as before; a non-interactive (headless) replay's decision output is unaffected
    • Observable: the new test cases fail while the old unconditional per-decision print path still runs alongside the new round summary
    • Requirements: 2.3, 5.1, 5.4
    • Boundary: sim_print_decision gate
    • Depends: 2.2
  • 4.2 (P) Suppress the old per-decision echo during continuous execution so the round summary is the sole source of decision output

    • Leave single-stepping and non-interactive output untouched
    • Observable: all tests from 4.1 pass; a full continuous-execution run over a replay shows only round-summary lines, with no duplicate bare decision lines
    • Requirements: 2.3, 5.1, 5.4
    • Boundary: sim_print_decision gate
  • 6. (P) REPL prompt shows current session and timestamp

  • 6.1 (P) Write failing tests for the dynamic REPL prompt

    • Cover: the prompt is the plain (sim) before any session has begun; once at least one session has run, the prompt includes the current session count and a human-readable timestamp; this holds in both step and continue modes; the prompt never alters any command's own output
    • Observable: the new test cases fail against today's static XCE_REPL_PROMPT macro, which never varies
    • Requirements: 5.5
    • Boundary: REPL Prompt Context
  • 6.2 (P) Implement the dynamic prompt

    • Build the prompt fresh on every repl_command_loop() iteration from the current session count and xce_core_now()/repl_format_ts_human(), falling back to the original plain prompt before any session begins
    • Observable: all tests from 6.1 pass; a live step/continue session shows the session/timestamp in the prompt starting from the first completed session, with no change to any command's own printed output
    • Requirements: 5.5
    • Boundary: REPL Prompt Context
  • 7. (P) Resource value classification, human-readable scaling, and the set units option

  • 7.1 (P) Write failing tests for byte/megabyte classification, adaptive scaling, and set units parsing

    • Cover: the bytes-valued classifier returns true only for mem/tmp/maxmem/maxtmp/maxswap and false for swp, unitless resources, and unknown names; the scaling helper adaptively renders across B/KB/MB/GB/TB, including exact unit-boundary values; swp's value is converted MB→bytes before scaling; set units raw/human/both each update the display-mode setting, defaulting to both; an unrecognized set units value is rejected the same way other unrecognized set parameters already are
    • Observable: the new test cases fail against the current codebase, which has neither the classifier/scaling helpers nor a units setting
    • Requirements: 6.1, 6.2, 6.3
    • Boundary: Resource Value Formatter
  • 7.2 (P) Implement the classification/scaling helpers, the units_mode setting, and set units parsing

    • Add the bytes-valued classifier and the adaptive human-scaling formatter as pure functions; add the units_mode field to the REPL session state, explicitly defaulted to both (not left to zero-initialization); wire set units raw|human|both into the existing set command dispatch alongside speed/output/verify
    • Observable: all tests from 7.1 pass; the helpers and the new setting are ready for the resource-listing rendering work to adopt
    • Requirements: 6.1, 6.2, 6.3
    • Boundary: Resource Value Formatter
  • 8. (P) info worker/info resource grouped table layout and units-mode-aware rendering — Depends: 1.2, 7.2

  • 8.1 (P) Write failing tests for the resource-listing table layout and units-mode rendering

    • Cover: info worker's and info resource's resource listings render as an aligned table grouped by category (consumable/capacity, load metrics, static hardware attributes, where applicable to that listing) instead of one flat list; a whole-number unitless value renders with no trailing .00, a fractional one keeps its decimals; each units_mode (raw/human/both) selects the corresponding rendering for a byte/megabyte-valued resource; the underlying stored/wire value and replay determinism are unaffected; info worker's assigned-job listing renders using the existing jobid-range-compression helper
    • Observable: the new test cases fail against today's unconditional flat per-resource fprintf loop and un-compressed assigned-job listing
    • Requirements: 6.4, 6.5, 6.6, 4.5
    • Boundary: Resource Value Formatter, Jobid Range Compressor
  • 8.2 (P) Implement the grouped table rendering for info worker and info resource

    • Replace the flat per-resource print loop with a shared, grouped, aligned-column table renderer reading rs->units_mode; adopt the jobid-range-compression helper for the assigned-job listing
    • Observable: all tests from 8.1 pass; a live info worker all against a real captured worker reproduces the hand-validated grouped-table shape instead of 20 unstructured lines
    • Requirements: 6.4, 6.5, 6.6, 4.5
    • Boundary: Resource Value Formatter, Jobid Range Compressor
  • 9. (P) Discoverable help listing and break event types — Depends: 7.2

  • 9.1 (P) Write failing tests for the reorganized help listing and break's event-type discoverability

    • Cover: help's output groups commands into the four labeled sections (execution control, breakpoints, state inspection, snapshot and parameters), uses one consistent column width throughout, lists info config alongside the other info subcommands, and lists set units alongside set speed/set output/set verify in the snapshot-and-parameters section; help's break line and break's unrecognized-event-type error both list the complete, current set of valid event types from the same source; no command's existence, argument parsing, or other output changes
    • Observable: the new test cases fail against today's unordered, hand-padded help listing (with info config disconnected from its siblings) and break's error message, which names no valid alternatives
    • Requirements: 7.1, 7.2, 7.3, 7.4, 7.5, 7.6
    • Boundary: Help & Breakpoint Discoverability
  • 9.2 (P) Implement the shared event-type accessor, the reorganized help, and break's enriched error message

    • Add one shared accessor rendering BP_KIND_TABLE's complete token set; rewrite repl_print_help() into the four labeled, consistently-aligned sections with info config moved next to its siblings, set units listed alongside set speed/set output/set verify, and the accessor's output appended to the break line; call the same accessor from repl_cmd_break()'s unrecognized-event-type error
    • Observable: all tests from 9.1 pass; help and break's error message can never disagree with each other or with BP_KIND_TABLE, since both read the same accessor
    • Requirements: 7.1, 7.2, 7.3, 7.4, 7.5, 7.6
    • Boundary: Help & Breakpoint Discoverability
  • 10. Validation: regression and real-data verification — Depends: 3.2, 4.2, 6.2, 8.2, 9.2

  • 10.1 Verify single-stepping and every other existing REPL command remain unchanged outside this feature's explicit exceptions

    • Confirm single-stepping's per-event/per-decision output, and the inspection/breakpoint/parameter/snapshot commands' behavior and output, match their pre-feature baseline exactly except for the prompt content (Requirement 5.5), info's job-identifier/resource-value listings (Requirements 4.5, 6), and help/break's discoverability changes (Requirement 7); confirm no new top-level command was introduced
    • Observable: the existing REPL test suite's pre-existing assertions all still pass unmodified, and a step-mode transcript comparison shows no textual difference from the pre-feature baseline outside the prompt line itself
    • Requirements: 5.1, 5.2, 5.3, 5.4
  • 10.2 Run the full scheduler test suite and re-verify against the real replay capture that originally motivated this feature

    • Observable: the full test suite passes with no regressions, and re-running the interactive REPL's continuous execution against the real capture reproduces the collapsed output shape validated during design, cutting a several-thousand-line transcript down to a handful of lines while preserving every state change; a step/info worker/help/break pass over the same capture shows the new prompt content, grouped resource table, reorganized help listing, and enriched break error, with no change to any scheduling decision
    • Requirements: 2.1, 2.2, 3.1, 3.2, 3.3, 3.4, 5.5, 6.6, 7.1, 7.2, 7.3, 7.4, 7.5