scheduler: FF link out of a start-of-day 0-day milestone anchors on the previous working day, absorbing lag
Summary
Found by the independent CPM oracle (#3987 (closed)): an FF link out of a 0-day milestone held at the start of a working day anchors on the end of the previous working day instead of the milestone's own instant, so a weekend absorbs a later lag on the link after it. Both the Python and Rust engines agree with each other and disagree with the reference.
Repro
Calendar: Mon–Fri, project start Mon 2026-01-05.
M0(0d, held at project start, Mon 01-05) -FF-> M1(0d) -FS+1d-> T(1d)Both engines put T on Mon 01-05. The reference — and the equivalent
M0 -FS-> M1, which both engines also agree on — puts T on Tue 01-06.
Why this is wrong
The FF link should anchor M1 on M0's own raw instant (the start of Monday),
the same point an FS link anchors on. Anchoring instead on the close of the
previous working day (Friday) moves M1 a working day earlier than its FS
equivalent, which then lets the weekend silently absorb the +1d lag on the
link after it.
Where it is tracked today
Excluded from oracle generation, unfixed, by _known_divergent() in
packages/scheduler/tests/test_cpm_oracle.py (~line 327):
(link.kind == "FF" and is_milestone[link.pred])Acceptance criteria
- Decide the correct behavior (reference's position, or amend the docs)
- Fix
packages/schedulerandpackages/wasm-schedulerin lockstep - Remove this case from
_known_divergent()and let the oracle generate it - Update
_known_divergent()'s docstring and theCONTRIBUTING.mdline - Once fixed,
finish_meeting()'s zero-lag branch inreference_cpm.pybecomes reachable from an FF-out-of-milestone case; drop the comment added in #3987 (closed) marking it unreachable until then