fix(scheduler): sim mode force-dispatched recorded decisions past live capacity (bug-1836, bug-1838)

User-reported: replaying a captured session dispatched 44 single-slot jobs
onto a 22-slot host. Root cause traced through two layers:

- bug-1836: sim_reconcile_unaccounted_jobs() (the "Recorded-Decision
  Reconciliation" backstop) force-applied any recorded DISPATCH decision
  it found, with zero live capacity check. Added
  sim_reconciled_alloc_fits_capacity(), reusing the same
  sched_check_host_satisfy()/sched_check_shared_satisfy() admission checks
  the live picker/allocator path already uses.

- bug-1838: even with that gate, reconciliation still preempted every
  freshly-PEND job before the live picker/allocator got a turn each round
  -- unnecessary now that scheduler-sim-live-allocation gave sim mode the
  same real, capacity-checked picker/allocator threads normal mode uses.
  Narrowed reconciliation's trigger back to JOB_IS_RUN-only (undoing a
  2026-09-11 widening whose own justification no longer holds), so a
  freshly-pushed job now always flows through the same live, verified
  decision path as normal mode. Reconciliation now only ever fires for a
  job already RUN from before the replay's own observation window --
  the one case structurally invisible to the live picker.

Also logged (bug-1837, not fixed here, needs its own design decision):
sim_reconcile_unaccounted_jobs() calls a picker's on_dispatch() hook from
the driver thread instead of the allocator thread plugin.h documents it
belonging to -- currently inert since the only real picker plugin happens
to lock internally, but not contract-safe for a future lock-free one.

Fixing bug-1838 required re-examining every test exercising the old
PEND-inclusive trigger; several needed their fixtures corrected to
register a real worker (harmless before any capacity check existed), and
others needed their actual intent re-derived and their assertions
inverted or restated now that a PEND job is never eligible for
reconciliation. Dated correction notes added in place to the
scheduler-sim-eager-reconciliation spec, matching its own existing
2026-09-11 correction-note precedent.

Verified: full scheduler suite 85/85, independently re-confirmed by
running the four most affected binaries directly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Rongsong Shen 2026-09-21 09:50:27 +00:00
parent cd9ecb4159
commit 94115b0024
No known key found for this signature in database
GPG key ID: 5BCDAAE0123E9FE2
44 changed files with 2769 additions and 333 deletions

View file

@ -5533,3 +5533,70 @@
| 20:38 | Edited src/include/typemap.h | 7→10 lines | ~151 |
| 20:39 | Edited src/controller/testsuite/test_e2e_capnp.c | modified test_ctrl_hello_request_key_round_trip() | ~1131 |
| 20:39 | Edited src/controller/testsuite/test_e2e_capnp.c | 2→3 lines | ~46 |
| 22:07 | Edited src/scheduler/include/core.h | 6→7 lines | ~39 |
| 22:08 | Edited src/scheduler/include/core.h | modified sched_account_jobs() | ~753 |
| 22:08 | Edited src/scheduler/include/scheduler.h | 13→14 lines | ~248 |
| 22:08 | Edited src/scheduler/src/scheduler.c | added 5 condition(s) | ~251 |
| 22:09 | Edited src/scheduler/src/sim_loop.c | 4→7 lines | ~83 |
| 22:10 | Edited src/scheduler/src/sim_loop.c | modified returns() | ~405 |
| 22:11 | Edited src/scheduler/src/sim_loop.c | modified for() | ~166 |
| 22:12 | Edited src/scheduler/src/sim_loop.c | added 1 condition(s) | ~659 |
| 22:12 | Edited src/scheduler/src/sim_loop.c | modified sched_account_jobs() | ~347 |
| 22:14 | Edited src/scheduler/src/sim_loop.c | added 16 condition(s) | ~1298 |
| 22:20 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | added 1 condition(s) | ~1328 |
| 22:32 | Edited src/scheduler/src/sim_loop.c | modified for() | ~90 |
| 22:33 | Edited src/scheduler/src/sim_loop.c | modified if() | ~293 |
| 22:33 | Edited src/scheduler/src/sim_loop.c | modified if() | ~114 |
| 22:43 | Edited src/scheduler/src/sim_loop.c | modified returns() | ~614 |
| 22:44 | Edited src/scheduler/src/sim_loop.c | sched_unaccount_jobs() → sim_reconcile_toggle_prior_charges() | ~331 |
| 22:45 | Edited src/scheduler/src/sim_loop.c | sched_unaccount_jobs() → sim_reconcile_toggle_prior_charges() | ~155 |
| 22:46 | Edited src/scheduler/src/sim_loop.c | added 4 condition(s) | ~526 |
| 22:47 | Edited src/scheduler/include/core.h | reduced (-15 lines) | ~119 |
| 22:48 | Edited src/scheduler/src/scheduler.c | removed 40 lines | ~13 |
| 23:13 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | modified test_reconcile_captures_non_run_state_job_when_dispatch_recorded() | ~283 |
| 23:13 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | modified test_reconcile_reconstructs_allocs_and_accounts_from_matching_dispatch() | ~168 |
| 23:13 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | modified test_reconcile_then_release_via_job_state_change_is_asan_clean() | ~149 |
| 23:14 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | 9→14 lines | ~117 |
| 23:14 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | 8→13 lines | ~127 |
| 23:14 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | expanded (+10 lines) | ~211 |
| 23:14 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | 9→14 lines | ~119 |
| 23:15 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | 9→14 lines | ~118 |
| 23:15 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | expanded (+10 lines) | ~207 |
| 23:19 | Edited src/scheduler/testsuite/test_sim_verify.c | modified add_bare_worker() | ~339 |
| 23:20 | Edited src/scheduler/testsuite/test_sim_verify.c | expanded (+7 lines) | ~129 |
| 23:28 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | 8→13 lines | ~224 |
| 00:49 | Edited src/scheduler/src/sim_loop.c | modified condition() | ~1331 |
| 00:50 | Edited src/scheduler/src/sim_loop.c | 4→9 lines | ~117 |
| 01:05 | Edited src/scheduler/testsuite/test_sim_live_allocation.c | added 1 condition(s) | ~961 |
| 01:07 | Edited src/scheduler/testsuite/test_sim_live_allocation.c | modified comment() | ~2255 |
| 01:08 | Edited src/scheduler/testsuite/test_sim_verify.c | modified INVERTED() | ~671 |
| 01:09 | Edited src/scheduler/testsuite/test_sim_verify.c | reduced (-7 lines) | ~573 |
| 01:10 | Edited src/scheduler/testsuite/test_sim_verify.c | 2→2 lines | ~24 |
| 01:16 | Edited src/scheduler/testsuite/test_sim_contention_parity.c | modified CORRECTED() | ~1686 |
| 01:17 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | modified test_reconcile_ignores_pend_state_job_even_when_dispatch_recorded() | ~1005 |
| 01:18 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | 2→2 lines | ~24 |
| 01:19 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | modified 12() | ~798 |
| 01:19 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | 3→3 lines | ~63 |
| 01:20 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | modified REVISED() | ~803 |
| 01:27 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | modified 15() | ~582 |
| 01:27 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | 3→3 lines | ~54 |
| 01:28 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | expanded (+9 lines) | ~530 |
| 01:33 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | modified test_reconcile_removes_reconciled_job_from_picker_candidates() | ~822 |
| 01:33 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | 11→12 lines | ~161 |
| 01:35 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | modified 13() | ~458 |
| 01:35 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | 6→7 lines | ~111 |
| 01:36 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | modified regression() | ~312 |
| 01:36 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | 2→2 lines | ~33 |
| 01:38 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | modified if() | ~291 |
| 01:39 | Edited src/scheduler/testsuite/test_sim_reconcile_unaccounted.c | 4→4 lines | ~35 |
| 01:41 | Edited .kiro/specs/scheduler-sim-eager-reconciliation/design.md | modified Correction() | ~1035 |
| 01:41 | Edited .kiro/specs/scheduler-sim-eager-reconciliation/requirements.md | modified Correction() | ~612 |
| 01:52 | Edited src/scheduler/testsuite/test_sim_live_allocation.c | 6→7 lines | ~42 |
| 01:52 | Edited src/scheduler/testsuite/test_sim_live_allocation.c | 36→38 lines | ~393 |
| 01:59 | Edited src/scheduler/testsuite/test_sim_live_allocation.c | 3→4 lines | ~43 |
| 02:13 | Edited src/scheduler/src/sim_verify.c | expanded (+12 lines) | ~220 |
| 02:20 | Edited src/scheduler/testsuite/test_sim_live_allocation.c | 2→2 lines | ~35 |
| 02:30 | Edited src/scheduler/testsuite/test_sim_live_allocation.c | 2→2 lines | ~35 |
| 02:31 | Edited src/scheduler/testsuite/test_sim_live_allocation.c | expanded (+22 lines) | ~556 |
| 02:31 | Edited src/scheduler/testsuite/test_sim_live_allocation.c | 4→3 lines | ~28 |
| 02:31 | Edited src/scheduler/src/sim_verify.c | removed 13 lines | ~17 |