From 9ebb06983b7a26db5564302253f2551dfbcf834e Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Wed, 26 Aug 2026 23:45:16 +0200 Subject: fix(of): dispatch Holy Family's Normae n.35(a) fallback (W2) temporal_of.ml's temporal only ever reached holy_family's own correct 26-31 December / 30 December fallback logic through sunday_slug, which returns None immediately for a non-Sunday date. In a year 25 December is itself a Sunday (26-31 December then holding no Sunday of its own), the feast vanished entirely and fell through to an ordinary Christmas ferial slug -- confirmed on 2022, 2033, 2039, 2044, 2050 (and roughly 1583..9999 domain-wide, one year in seven). temporal's dispatch now consults holy_family directly, independent of weekday, between the sunday_slug and christmas_feria_slug branches, carrying the identical identity the Sunday case already builds (subject Lord, holy_family_names, rank Festum). holy_family and anchors were already correct and needed no change. Added a direct example-based test for the fallback across five affected years plus a control for the unaffected Sunday case, and a domain-wide property (Holy Family is observed in every liturgical year 1583-9999) folded into both the 200-sample QCheck run and the exhaustive sweep -- the property that would have caught this directly. Un-pinned the now-fixed behaviour everywhere it was recorded as known-wrong: test_rite_of.ml's own 1583 pin (rewritten to assert the fix), test_validate_of.ml's own independent exhaustive-sweep counter and landmark-year filter (found via make check, not the initial survey), and data/of/expected-divergences-litcal.sexp's L2/L3 allow-list entries against the litcal oracle (closed and removed, with a dedicated regression test replacing the allow-list's own silence). --- lib/rites/rite_of/temporal_of.ml | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'lib/rites/rite_of/temporal_of.ml') diff --git a/lib/rites/rite_of/temporal_of.ml b/lib/rites/rite_of/temporal_of.ml index 1da6cf9..4f3194b 100644 --- a/lib/rites/rite_of/temporal_of.ml +++ b/lib/rites/rite_of/temporal_of.ml @@ -470,7 +470,32 @@ let temporal d = (Subject.Temporal, Names.empty, rank) in build ~subject ~names ~season:s ~slug ~colour ~rank ~week:(week d) () - | None -> ( + | None -> + if same d (holy_family y) then + (* Normae n. 35(a) fallback: "vel, ea deficiente, die 30 + decembris" -- reached here only when {!holy_family}'s own + 26-31 December Sunday search found none that year (26-31 + December holds no Sunday exactly when 25 December, Christmas + Day, is itself a Sunday), so the office falls on 30 December + civilly, whatever weekday that is. {!sunday_slug} only ever + recognises this office on a Sunday (its Christmas-time branch + tests [same d (holy_family y)] but the surrounding function + returns [None] immediately for any non-Sunday [d]), so + without this branch the date fell through to + {!christmas_feria_slug} below and the feast vanished + entirely -- CLAUDE.md's own W2. Carries the IDENTICAL + identity the Sunday-dispatch branch above builds (subject + Lord, {!holy_family_names}, rank Festum): Normae n. 35(a)'s + "vel... die 30 decembris" is the same feast on a fallback + date, not a lesser one. Colour is the plain season default + (white, Christmas time) -- {!is_rose_sunday} never applies + here (Christmas is not Advent/Lent) and 30 December is never + itself a Sunday when this branch fires (a Sunday would have + already matched {!sunday_slug} above), so there is nothing + to override it with. *) + build ~subject:Subject.Lord ~names:holy_family_names ~season:s ~slug:"of-holy-family" + ~colour:(season_colour s) ~rank:Festum ~week:(week d) () + else ( match christmas_feria_slug d y with | Some slug -> build ~season:s ~slug ~colour:(season_colour s) ~rank:Feria ~week:(week d) () | None -> -- cgit v1.3