diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/cli.t | 13 | ||||
| -rw-r--r-- | test/test_precedence_ef.ml | 74 |
2 files changed, 72 insertions, 15 deletions
@@ -101,6 +101,19 @@ Sunday: 2 Nov 2026 is a Monday (1 Jan 2026 is a Thursday, same day-of-year (week 23: Pentecost 2026 is 24 May (colitur easter 2026); 24 May - 2 Nov is 162 days, floor_div(162, 7) = 23 -- same formula, same independent check.) +RG 96's Annunciation exception (25 March) is CONDITIONAL, not unconditional +-- fix round 1, coordinator review, register corrected 2026-08-12. In 2057, +25 March is Lent III Sunday (I class, impedes it); 26 March is an ordinary +Lent feria (III class, well before Easter, 22 April 2057), so the GENERAL +RG 96 target -- not the Monday after Low Sunday -- is what governs, since +the general walk never crosses Easter. Before this fix the unconditional +reading sent it to 30 April (Easter + 8) instead: + + $ colitur day 2057 | grep '^2057-03-26 ' + 2057-03-26 monday lent 3 annunciation-of-the-blessed-virgin-mary class-1 white +ef-lent-3-monday + $ colitur day 2057 | grep -c 'annunciation-of-the-blessed-virgin-mary' + 1 + A year outside the supported domain is rejected (exit 2): $ colitur day 1000 diff --git a/test/test_precedence_ef.ml b/test/test_precedence_ef.ml index 0973a93..aa98686 100644 --- a/test/test_precedence_ef.ml +++ b/test/test_precedence_ef.ml @@ -844,36 +844,76 @@ let test_transfer_target_general_multi_step_search () = Alcotest.(check string) "lands on the first day past the blocked run" "2026-01-13" (D.to_iso8601 target) -(* RG 96's Annunciation exception: starts the search at the Monday after Low - Sunday, NOT [origin + 1] -- occupant is unconditionally free, so a - general-path implementation would return [origin + 1] (26 March), a date - this test explicitly rules out as well as pinning the real expected one, - so the assertion genuinely discriminates the two starting points rather - than merely checking "some date after origin". *) +(* Coordinator review (fix round 1): RG 96 Attamen (a) (register-transcribed, + primary-source-verified) makes the Annunciation exception CONDITIONAL on + the general RG 96 walk carrying the feast past Easter Sunday -- NOT + unconditional as the first transcription had it. The occupant here blocks + every day from [origin + 1] through the day after Easter (26 March - 6 + April 2026 inclusive), so the GENERAL target itself would land at 7 + April -- after Easter (5 April) -- which is exactly the trigger + condition, not merely "the Annunciation is impeded at all". *) let test_transfer_target_annunciation_starts_at_monday_after_low_sunday () = let origin = mk 2026 3 25 in - let occupant = occupant_blocking_on [] in + let easter_2026 = Comp.gregorian_easter 2026 in + let blocked_through_day_after_easter = + let rec range a b = if D.compare a b > 0 then [] else a :: range (D.add_days a 1) b in + range (D.add_days origin 1) (D.add_days easter_2026 1) + in + let occupant = occupant_blocking_on blocked_through_day_after_easter in let c = cand ~origin:P.Sanctoral ~layer:PE.universal_layer PE.annunciation_slug in let target = PE.transfer_target c origin occupant in - let monday_after_low_sunday = D.add_days (Comp.gregorian_easter 2026) 8 in - Alcotest.(check string) "lands on the Monday after Low Sunday (Easter + 8)" + let monday_after_low_sunday = D.add_days easter_2026 8 in + Alcotest.(check string) "lands on the Monday after Low Sunday (Easter + 8), the general \ + walk having crossed Easter itself" (D.to_iso8601 monday_after_low_sunday) (D.to_iso8601 target); - Alcotest.(check bool) "NOT the general path's origin + 1 (discriminates the branch)" true - (D.compare target (D.add_days origin 1) <> 0) + Alcotest.(check bool) "NOT the general target (2 days after Easter, discriminates the branch)" + true + (D.compare target (D.add_days easter_2026 2) <> 0) (* RG 96's own qualifier on the exception -- "searching onward from there only if that day is itself blocked" (rite.mli) -- is [search_from]'s - ORDINARY behaviour, not a second mechanism: block the Monday after Low - Sunday itself and confirm the search continues exactly one more day. *) + ORDINARY behaviour, not a second mechanism: same blocked run as above + (forcing the general target past Easter, so the exception fires), PLUS + the Monday after Low Sunday itself blocked, confirming the search + continues exactly one more day from there. *) let test_transfer_target_annunciation_searches_onward_if_blocked () = let origin = mk 2026 3 25 in - let monday_after_low_sunday = D.add_days (Comp.gregorian_easter 2026) 8 in - let occupant = occupant_blocking_on [ monday_after_low_sunday ] in + let easter_2026 = Comp.gregorian_easter 2026 in + let monday_after_low_sunday = D.add_days easter_2026 8 in + let blocked = + let rec range a b = if D.compare a b > 0 then [] else a :: range (D.add_days a 1) b in + range (D.add_days origin 1) (D.add_days easter_2026 1) @ [ monday_after_low_sunday ] + in + let occupant = occupant_blocking_on blocked in let c = cand ~origin:P.Sanctoral ~layer:PE.universal_layer PE.annunciation_slug in let target = PE.transfer_target c origin occupant in Alcotest.(check string) "searches onward one more day when that Monday is itself blocked" (D.to_iso8601 (D.add_days monday_after_low_sunday 1)) (D.to_iso8601 target) +(* THE REGRESSION PIN (coordinator review): the bug an unconditional + exception produced. 25 March 2057 is Lent III Sunday (I class, RG 91 + entry 6), impeding the Annunciation; 26 March 2057 is an ordinary Lent + feria (III class, well before Easter, 22 April 2057) -- the general RG + 96 target. The general target does NOT fall after Easter, so the + exception must NOT fire: the Annunciation lands on 26 March, not 13 + April (Easter + 8), which is what the unconditional reading produced + (verified by reverting the fix and re-running this exact test -- see the + task report's mutation record). Uses the REAL [Temporal_ef.temporal] as + [occupant] (not a synthetic stand-in), the same coupling-safety + convention [of_temporal]'s callers use elsewhere in this file, so this + is also effectively an end-to-end check of the real 2057 calendar + shape, not just the search's own logic in isolation. *) +let test_transfer_target_annunciation_not_overridden_when_general_target_precedes_easter () = + let origin = mk 2057 3 25 in + Alcotest.(check string) "25 March 2057 is a Sunday (Lent III)" "sunday" + (D.weekday_to_string (D.weekday origin)); + let occupant d = (T.temporal d).Colitur_kernel.Temporal.office in + let c = cand ~origin:P.Sanctoral ~layer:PE.universal_layer PE.annunciation_slug in + let target = PE.transfer_target c origin occupant in + Alcotest.(check string) "lands on 26 March 2057 (the general RG96 target), NOT the \ + Annunciation exception's Monday after Low Sunday" + "2057-03-26" (D.to_iso8601 target) + (* rite.mli's own obligations on [transfer_target] (Task 11 brief): the call must TERMINATE and its result must be STRICTLY AFTER [origin], even for a rite/data shape this function cannot have anticipated -- an occupant that @@ -974,6 +1014,10 @@ let suite = Alcotest.test_case "transfer_target: Annunciation exception searches onward if that Monday is blocked" `Quick test_transfer_target_annunciation_searches_onward_if_blocked; + Alcotest.test_case + "transfer_target: Annunciation NOT overridden when the general target precedes Easter \ + (2057 regression)" + `Quick test_transfer_target_annunciation_not_overridden_when_general_target_precedes_easter; Alcotest.test_case "transfer_target: terminates and stays forward under a pathological occupant" `Quick test_transfer_target_terminates_under_pathological_occupant; Alcotest.test_case "transfer_target: does not raise probing past the domain ceiling" `Quick |
