Phase 1 of scheduler-hardening-plan.md: mechanically locks the bug-1521
contract that 91c3fb7f established but which lived only in code comments:
the allocator thread is the ONLY writer of a schedobj's reason fields;
the picker thread never touches reasons.
test_reason_ownership_audit.c (in the sched_unit_test aggregate) enforces
this in three layers:
- a whole-tree scan of every src/scheduler source (fixed 51-file list) for
schedobj-shaped reason ownership lines (obj->reason / schedobj->reason /
primary->reason / cobj->reason / compound->reason combined with
MOVE_PTR( / free_PendReason_ptr( / calloc( / a bare = store), checked
against an OWNERSHIP_SITES allowlist whose fragments must still exist in
their files (so the list cannot rot silently);
- a dedicated scan of sched_job_picker()'s brace-matched function body
rejecting ANY reason ownership inside the picker;
- detector self-tests proving it fires on the historical violation shapes
and stays quiet on sanctioned reads, ctx->reason (the sched_ctx_t local
shuttle), construction =NULL, and comment lines (skipped by the scans --
the contract's own documentation names the write shape in prose at
scheduler.c:496 / fcfs.c:243).
Red proof: a temporary MOVE_PTR(job->schedobj->reason, ...) injected into
the picker loop trips BOTH the file scan and the picker-body scan; the
injection is reverted and the suite is green.
.kiro/steering/scheduler-reason-ownership.md formalizes the discipline
(who allocates, who frees, which thread, MOVE_PTR semantics, the
ctx->reason exemption) for review use.
Full scheduler suite: 102/102 OK.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Phase 0 of the scheduler hardening plan is done:
- 0.1 (three-path skip symmetry): landed as test_res_account_symmetry.c
(b20caf8d), mutation-injection red-proven.
- 0.2 (rejoin trigger contract): audit found the contract fully covered
by test_scheduler_decision_publish_retry.c's five rejoin tests plus
test_scheduler_connect.c's no-io callback scan -- documented in the
plan instead of adding duplicate tests.
- 0.3 (two-round zero drift): folded into 0.1's
test_two_rounds_zero_drift_with_reconciling_worker, same shape.
Co-Authored-By: Claude Code <noreply@anthropic.com>