Repository navigation
Description
Summary
WorldCore::check_schedule_replacing (pkgs/id/src/world/core.rs:600-627) trusts a caller-supplied replacing: bool to discount the pending-schedule count, instead of checking its own map:
let pending = self.schedules.len() - usize::from(replacing); // core.rs:612
ensure!(pending < crate::world_caps::MAX_PENDING_SCHEDULES, ...); // 64, world_caps.rs:95The flag is redundant — whether the id being set is actually pending is knowable from self.schedules — and a mismatched flag breaks the cap in both directions:
- Full map, absent id,
replacing=true: with 64 schedules pending,pendingcomputes as 63, the check passes, and the caller inserts a 65th pending schedule — one more thanMAX_PENDING_SCHEDULES(64). That state is one journal replay refuses: restore rejects a journal whose pendingScheduleSetentries reach the cap (world/core.rs:263-275,core.schedules.len() < MAX_PENDING_SCHEDULESper insert), so a journal ever written in that state would make the world unopenable. - Empty map,
replacing=true:0 - 1onusizepanics in debug builds (arithmetic overflow) and wraps tousize::MAXin release, making the check refuse a schedule that should be admitted.
Evidence (main b4136991, code-read verified this run)
pkgs/id/src/world/core.rs:612— the subtraction above; the duplicate check at :607-610 is keyed on the same flag (replacing || !contains_key), so the flag controls both guards while the map, which knows the truth, is consulted for neither.pkgs/id/src/world_caps.rs:95—MAX_PENDING_SCHEDULES: usize = 64.pkgs/id/src/world/core.rs:271-275— journal restore enforces the same cap perScheduleSet, i.e. the cap is a hard invariant of persisted state, not an advisory limit.- Sole production caller,
pkgs/id/src/world/actor.rs:1376-1383(WorldCommand::AdminScheduleAt), currently computes the flag correctly (let replacing = self.core.schedules.contains_key(&id);) — so today this is a latent trap, not a live breach: the invariant holds only by caller discipline, in exactly the function whose job is to enforce it. - Coverage gap:
pkgs/id/src/world/tests.rs:3405-3444(a_replacement_is_validated_as_a_replacement_not_as_an_addition) exercisesreplacing=trueonly with the id actually pending ("taken","s0"). No test passes a mismatched flag.
Verification note: verified by reading the code at the lines above and tracing the arithmetic for the boundary cases (64 pending + absent id + true; 0 pending + true). No compiled probe this run: the laptop SSH tunnel is down (see #2879), and the sandbox does not build. The boundary trace is deterministic from the quoted lines; triage can confirm with the two unit cases in the acceptance criteria in seconds.
Why it matters
The pending-schedule cap bounds journal size and wakeup work per world, and restore treats it as a hard invariant. An enforcement helper that can be talked out of the cap — or into a panic — by a redundant boolean is a footgun for the next caller (the manifest-apply path already grew one new caller in #807; SetSchedule frames and program schedule.at are adjacent surfaces). Deriving the discount from the map removes the whole class.
Acceptance criteria
-
check_schedule_replacingderives whether the id is being replaced fromself.schedulesitself (or otherwise cannot be desynchronised from the map); no caller-supplied flag can discount a schedule that is not pending. - Unit test: 64 schedules pending + set of a new id through the replacement path is refused with the "pending schedules" error.
- Unit test: replacement path on an empty map (and on a map not containing the id) neither panics nor wraps.
- Existing tests still pass, including
a_replacement_is_validated_as_a_replacement_not_as_an_addition(a true replacement at capacity still fits) and the id: F12.1 apply wiring — module install + schedules reconciliation #807 guarantee that a refused replacement leaves the existing schedule standing. - The duplicate guard and the capacity discount agree: both keyed on the same map lookup.
Activity
dezren39 commentedon Oct 31, 2026
🤖 Agent note · filed
replacingbool instead of its own map — full map + absent id + true admits a 65th schedule past the MAX_PENDING_SCHEDULES cap restore enforces (core.rs:271), and empty map + true underflows usize. Sole caller (actor.rs:1376) computes the flag correctly today, so this is a latent trap in the enforcing function. Verified by code-read + boundary trace on main b413699; no compiled probe (laptop SSH down, fleet: laptop SSH unreachable again 2026-10-30 — MaxStartups drops blocking conductor + lanes (recurrence of #1667) #2879).dezren39 commentedon Oct 31, 2026
Agent note (design-architect, 2026-10-30): this issue is Phase 3 of design #2898 ("reconstruction is admission", design doc
files/designs/code-id-reconstruction-validation.mdin the keep-the-four-repos-healthy goal workspace), together with #2876 and the closing reconstruction-seam audit.Recorded decisions for triage — do not re-file, re-scope, or split this issue; record the phase structure instead:
check_schedule_replacingloses its caller-suppliedreplacing: bool; whether the id replaces a pending schedule is derived from the core's ownschedulesmap inside the check, so live admission and restore enforce the identical cap from the identical ground truth. The crate-private wrapper and the actor call site stop supplying the fact (passing state the same function already computed from its own map is acceptable only if the check itself re-derives it).74 remaining items
dezren39 commentedon Nov 2, 2026
agent-note:v1 — holder: repo-worker-code (OpenChamber scheduled lane), at 2026-11-02T14:46:48Z. event: picked-up; task: 5457; queue: repo-health-code-pilot. Fresh metadata-only revalidation: issue #2882 OPEN, assigned dezren39; canonical PR #4261 OPEN, non-draft, authored and assigned to dezren39. Existing checkpoint identifies this as a Drew-owned hard stop. No checks, diff, reviews, branch, worktree, or source inspected or touched.
dezren39 commentedon Nov 2, 2026
agent-note:v1 — holder: repo-worker-code (OpenChamber scheduled lane), at 2026-11-02T14:47:21Z. event: parked; task: 5457; queue: repo-health-code-pilot. Parked 30 minutes for the explicit ownership release/PR disposition condition; preserve existing branch/worktree and checkpoint, do not inspect or touch the Drew-owned PR absent release.
dezren39 commentedon Nov 2, 2026
🤖 Agent note · done