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-speeddeprecation-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,-1and 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
- Write the tests first, with a test-local stdout-capture helper and without initialising the logger (so warnings reach stdout): the values
-
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 configand 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 7and bareset speedprint the removal message, return to the prompt and leave the clock and core speed setting unchanged;helpand thesetusage message do not mention speed;info confighas no speed item and still shows output, verify, events processed, current timestamp and sessions; a scripted forked-child REPL run withset speed 7,info configandquitexits 0 and prints both the removal message and the config line; the othersetparameters' existing tests still pass. - Handle
set speedbefore the argument-count check, remove the speed setter, and drop speed from the usage, help andinfo configtext (design.md, Components: ReplSet / ReplHelp / ReplInfo). - Replace the existing speed-setter test and update the help and
info configtests, the comments about theset speedcommand in the REPL parameter, help and resource-formatting tests, and the REPL internal header's comments that mentionset 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
- Write the tests first:
-
2.3 Retire
--sim-speedon 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,-1and 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;--helpdescribes 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 and7, 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)
- 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
-
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-speedas 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-speedonly as deprecated. - Requirements: 5.1
- Boundary: Docs (deployment guide)
- Describe the simulator clock as moving only at recorded timestamps, describe
-
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-speedis 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-speedcaller- 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
- Run the HA soak skill, whose replay-verification step still passes
Implementation Notes
- Build dir:
bash src/tools/xce-build.sh scheduler asan xce.build.discretebuilds intosrc/xce.build.discrete; iterate withmeson test -C src/xce.build.discrete --suite schedulerand grep its testlog for:FAIL. - 2.1 added
args->sim_speed = DISCRETE_CLOCK_RED_SPEED(and that define) totest_sim_discrete_clock.cto prove RED; 3.1 removes both. Its fixture writer leaves mkdtemp dirs under/tmp(astest_sim_record_output.cdoes). 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) withXCE_HA_BIN/XCE_HA_XTpointed atsrc/xce.build.dc-full: PASS, 18 jobs, zero loss; SIMVERIFY files=6 mismatches=0 errors=0; eachsimverify-N.logholds exactly one--sim-speed "0"deprecation warning. The soak finds xceadmin only in the shared default build dirs.