myxce/.kiro/specs/scheduler-sim-discrete-clock/tasks.md
2026-09-29 05:39:47 +00:00

12 KiB

Implementation Plan

Test-first throughout (red → green → refactor). Every sub-task leaves the build and the scheduler suite green. The simulator's speed field and its shadow copy stay in place, unused, until the last core task removes them together with every test that sets them (design.md, File Structure Plan: build-order constraint).

  • 1. Foundation: deprecation-warning helper and the new test binary

  • 1.1 Add the --sim-speed deprecation-warning helper and register the new discrete-clock test binary

    • Write the tests first, with a test-local stdout-capture helper and without initialising the logger (so warnings reach stdout): the values 0, abc, -1 and the empty string each produce exactly one line naming the value in quotes and containing --sim-speed, "deprecated", "no effect" and "will be removed"; no value produces no output.
    • Add the helper as its own small source (design.md, Components: CliCompat) and add it to the scheduler's source list only, not to the simulator-isolation library.
    • Register the new test binary in the scheduler suite with the same leak-detection setting as the other scheduler tests, a compile-time path to the built scheduler binary, and a build dependency on that binary. Its build sources are the new test file and the helper only, with the usual scheduler test dependencies; the white-box simulator #includes and the stand-in picker/allocator go into the test file itself in 2.1, as the other simulator tests do, not into the build file (listing the simulator sources there as well would define every symbol twice).
    • Done when the new test binary runs as part of the scheduler suite and its warning tests pass, and the scheduler binary still builds.
    • Requirements: 2.3, 2.4, 2.5
    • Boundary: CliCompat, scheduler test build
  • 2. Core: pin the simulator clock, remove the REPL speed parameter, retire the CLI option

  • 2.1 (P) Pin the simulation-mode clock so it moves only at recorded timestamps

    • Write the tests first in the new test binary, each passing a non-zero speed through the still-present simulator argument so they fail on the current code: after start the clock equals the chosen snapshot's timestamp and stays equal after a real sleep, with the core holding the frozen speed setting; with a stand-in allocator that sleeps and a recorded session start that is not a whole second, the session start seen inside the session equals the recorded one exactly, and simulation output has that session start, a zero session duration and every decision timestamp equal to it, with at least one decision per session; a session start earlier than the preceding event, and events earlier than the start snapshot, set the clock to exactly those values and the replay completes; a mid-replay snapshot followed by the end marker leaves the clock at the last event's timestamp after the run and after a sleep, with the start timestamp pinned so the real skip branch runs; the same recording replayed twice gives identical logical timestamps and decisions in both outputs, ignoring only the wall-clock header field (design.md, Testing Strategy: Unit (SimClock), Integration (replay loop)).
    • Make simulator startup always select the frozen clock setting and drop the speed parameter from the start-clock function. The start-clock function keeps writing the shadow copy, now always the frozen setting, because info config and the startup test still read it; the simulator's speed argument is no longer read. Both are removed in 3.1.
    • Update the speed-drift and never-runs-backwards comments in the simulator driver, replay loop and simulation-output sources; the simulator header's comments are left to 3.1 (design.md, Modified Files).
    • Done when the new clock tests pass, fail with the change reverted, and every existing simulator and REPL test still passes.
    • Requirements: 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 4.2
    • Boundary: SimClock
    • Depends: 1.1
  • 2.2 (P) Remove the REPL speed parameter

    • Write the tests first: set speed 7 and bare set speed print the removal message, return to the prompt and leave the clock and core speed setting unchanged; help and the set usage message do not mention speed; info config has no speed item and still shows output, verify, events processed, current timestamp and sessions; a scripted forked-child REPL run with set speed 7, info config and quit exits 0 and prints both the removal message and the config line; the other set parameters' existing tests still pass.
    • Handle set speed before the argument-count check, remove the speed setter, and drop speed from the usage, help and info config text (design.md, Components: ReplSet / ReplHelp / ReplInfo).
    • Replace the existing speed-setter test and update the help and info config tests, the comments about the set speed command in the REPL parameter, help and resource-formatting tests, and the REPL internal header's comments that mention set speed (comments about the simulator speed argument belong to 3.1).
    • Done when the REPL tests pass and no REPL output or help text offers a speed setting.
    • Requirements: 1.5, 3.1, 3.2, 3.3, 3.4, 3.5
    • Boundary: ReplSet, ReplHelp, ReplInfo
  • 2.3 Retire --sim-speed on the command line and prove the default command line end to end

    • Write the tests first in the new test binary, running the built scheduler binary as a child process on a fixture the test writes (session start not a whole second, a pending job before each session), draining its stdout before collecting the exit status: without the option it exits 0, its output has exact session starts, zero durations and decision timestamps equal to the session start, and its log has no warning; with each of 7, abc, -1 and an empty value (fresh output and log files per run) it exits 0, its output matches the default run except the wall-clock header field, and its log has exactly one warning naming the value; a repeated option logs one warning naming the last value; a trailing option with no value exits non-zero; an interactive run at end of input logs exactly one warning; --help describes the option as deprecated and mentions no real-time or as-fast-as-possible mode.
    • Stop defaulting, validating and passing a simulation speed; call the warning helper once right after the logger starts and, when the option was given, drain and restart the logger there while still single-threaded; update the option's help text and the comment that cites its numeric validation; the flag-meaning comments that describe the simulator speed argument are left to 3.1 (design.md, Modified Files: main.c; Error Handling).
    • Done when the end-to-end and help tests pass; the runs with abc, -1, an empty value and 7, the repeated-option run, the interactive run and the help test fail against the pre-change command-line handling, while the run without the option is a regression guard that 2.1 already makes pass.
    • Requirements: 1.4, 1.7, 1.8, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6
    • Boundary: main, CliCompat
    • Depends: 1.1, 2.1 (shares the new test file with 2.1, and its output assertions need the pinned clock)
  • 3. Integration: remove the simulator speed fields

  • 3.1 Remove the simulator speed argument and shadow copy, and update every test that set them

    • Remove the simulator's speed argument and its shadow copy, and in the same change update every test that assigns or asserts them: the 22 tests that only assign a speed, the startup test (keep its core frozen-setting assertions, drop the shadow-copy ones), the REPL parameter test's remaining assignments, and the non-zero speed assignments that 2.1 added to the new discrete-clock tests to prove RED (those tests keep asserting the pinned clock) (design.md, Modified Files and the build-order constraint).
    • Rename the three core clock tests that describe simulation speed modes as formula tests, including their test registrations and the file header; update the stale speed comments in the scheduler test build file, in the step-verbosity REPL test (which describe the removed speed argument), and in the command-line flag-meaning comments that describe the simulator speed argument, the simulator header's comments, and the core header's documentation of the speed setting (1/1 in normal mode, 0/1 in simulation mode).
    • Done when a search of the scheduler sources and tests finds no simulator speed argument or shadow copy, only the core speed setting, and the full scheduler suite passes.
    • Requirements: 1.5, 2.2, 4.1
    • Depends: 2.1, 2.2, 2.3
  • 4. Documentation and specification alignment

  • 4.1 (P) Update the operator documentation of simulation mode

    • Describe the simulator clock as moving only at recorded timestamps, describe --sim-speed as deprecated with no effect, remove it from the example command line, and remove the claim that REPL and batch runs differ in pacing.
    • Done when the simulation section of the deployment guide contains none of real-time, speed modes or pacing, and names --sim-speed only as deprecated.
    • Requirements: 5.1
    • Boundary: Docs (deployment guide)
  • 4.2 (P) Update the scheduler-core specification

    • Replace every speed-mode passage listed in requirements.md 5.2 in the scheduler-core requirements (flag table, AC 3, 12, 13, 14 including the monotonic-clock clause, AC 22 parameter table, pseudocode, rationale and out-of-scope note, data-structure summary) and design (traceability row, simulator fields, clock-test mode rows, fast-mode note).
    • Done when those passages state that no speed modes or wall-clock pacing exist, that --sim-speed is a deprecated no-op and that the REPL speed parameter was removed, and AC 14 permits the clock to move backwards to a recorded value.
    • Requirements: 5.2
    • Boundary: Docs (scheduler-core spec)
  • 5. Validation

  • 5.1 Full build and regression

    • Run the full ASAN build with the libxce, scheduler and controller suites, including the core-isolation test, and scan the test log for hidden Unity failures and sanitizer reports.
    • Confirm the replay schema and the normal-mode clock anchoring are unchanged by this feature's commits.
    • Done when every suite passes with no hidden failures, and the core clock source, the normal-mode wall-clock anchoring and the replay schema show no diff from this feature (the core header changes only in comments).
    • Requirements: 4.1, 4.2, 4.3
  • 5.2 HA soak with the existing --sim-speed caller

    • Run the HA soak skill, whose replay-verification step still passes --sim-speed=0, without modifying it.
    • Done when that step passes with zero mismatches and its log contains exactly one deprecation warning.
    • Requirements: 5.3

Implementation Notes

  • Build dir: bash src/tools/xce-build.sh scheduler asan xce.build.discrete builds into src/xce.build.discrete; iterate with meson test -C src/xce.build.discrete --suite scheduler and grep its testlog for :FAIL.
  • 2.1 added args->sim_speed = DISCRETE_CLOCK_RED_SPEED (and that define) to test_sim_discrete_clock.c to prove RED; 3.1 removes both. Its fixture writer leaves mkdtemp dirs under /tmp (as test_sim_record_output.c does).
  • test_clock.c (~40, ~435) quotes scheduler-core AC 12 "fast mode" wording in its session-timing tests; reword it together with 4.2.
  • 5.2: run-ha-soak.sh --sequential (5 rounds) with XCE_HA_BIN/XCE_HA_XT pointed at src/xce.build.dc-full: PASS, 18 jobs, zero loss; SIMVERIFY files=6 mismatches=0 errors=0; each simverify-N.log holds exactly one --sim-speed "0" deprecation warning. The soak finds xceadmin only in the shared default build dirs.