From b5dcdd8d4048295cfbdf1606f4cafd39b3c433e6 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Thu, 13 Aug 2026 10:40:40 +0200 Subject: temporal(ef): Holy Name of Jesus, RG 17(a) -- fallback + Lord subject RG 17(a): "festum Ss.mi Nominis Iesu, celebrandum dominica quae occurrit a die 2 ad 5 ianuarii (secus die 2 ianuarii)" -- both photographic scans, confirmed on the calendarium's own January table and the Mass propers' own heading. Two defects closed together, since they interact through RG 91 entry 14/RG 16(a): 1. The Sunday shape (2-5 January) now tags subject = Lord, matching RG 91 entry 14 ("Festa Domini II classis") -- previously subject = Temporal, the same defect shape Holy Family had before it. 2. The fallback (RG 17(a)'s own "secus die 2 ianuarii", the calendarium's "vel, ea deficiente, die 2 ianuarii") is now built: 2 January carries the feast whenever no Sunday falls 2-5 January that year. Before this fix colitur emitted no Holy Name office at all in such a year -- a real II-class feast simply missing, on 3,619 of 8,417 years in the domain (43%; 20 of the 46 years 2005-2050, independently re-derived against `date -d`). Both shapes band identically at RG 91 entry 14's MOVABLE half (Precedence_ef.entry_14_movable_band) -- one feast, not two differently classified ones, per the Mass propers' own single heading covering both dates. No live collision exists in the current sanctoral data (nothing fixed-date falls 2-5 January besides a Commemoration_only entry on 5 Jan), so the RG 16(a)/RG 112(a) interaction is proved with synthetic precedence-level fixtures mirroring Holy Family's own precedent, not a live-data regression. One asymmetry the synthetic tests found and kept honest rather than forced: a losing Holy-Name-Sunday is privileged (RG 109(a), "of a Sunday") and survives RG 111(a)'s cap; a losing Holy-Name-fallback is not (2 January is not a Sunday, and no other RG 109(a)-(f) category applies to it), so it gets no commemoration at all if ever outranked -- both individually correct readings of RG 109/111's closed lists. Golden pins follow the brief's own vacuity warning: the Sunday shape already emitted the right slug/rank/colour before this fix (an ordinary Sunday and Holy Name coincide on those fields), so its pin asserts subject explicitly rather than pinning the whole line uncritically; the fallback pin (2029-01-02) is the one with teeth against the larger defect, reddening on slug/rank/subject together if reverted. Mutation-tested: each half of the fix reverted separately reddens exactly its own tests (Sunday subject: the dedicated unit test, the golden pin's subject field, one precedence end-to-end test; fallback: the fallback unit/anchor/golden tests, the new C16 differential count, and both shapes of the precedence end-to-end tests) and nothing else. Adds data/ef/expected-divergences.sexp's C16 (lectio has no fallback for this window at all) -- the lectio differential's own count, independently re-derived against `date -d` for the fixture's 2005-2050 span, not transcribed from the domain-wide figure. The missalemeum oracle window (2026-2027) exercises only the Sunday shape and needed no new entry: subject is not one of its compared fields, and both years' rows already corroborate the Sunday-shape ranking (missalemeum's own 2026-01-04 and 2027-01-03 rows: rank 2, white, title "Holy Name of Jesus"). --- test/test_precedence_ef.ml | 105 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) (limited to 'test/test_precedence_ef.ml') diff --git a/test/test_precedence_ef.ml b/test/test_precedence_ef.ml index 4ee2fd8..d873e34 100644 --- a/test/test_precedence_ef.ml +++ b/test/test_precedence_ef.ml @@ -1426,6 +1426,103 @@ let test_class1_feast_inside_holy_familys_window_end_to_end () = Alcotest.failf "expected exactly one Privileged commemoration (Holy Family), got %d" (List.length other)) +(* Most Holy Name of Jesus (RG 17(a)) -- the SAME two proofs immediately + above, restated for Holy Name instead of Holy Family. UNLIKE Holy Family, + there is no LIVE collision to exercise here (this file's own [cases]/ + [disposition_cases] rows never construct one, because + data/ef/sanctoral.sexp has nothing fixed-date 2-5 January besides + [telesphorus-pope-and-martyr] (5 Jan, Commemoration_only, so it can never + contest [observed] at all -- {!P.resolve}'s own partition holds it out of + the band contest entirely) -- register §6.2's own account: "no live + collision exists for it in this codebase's current data". These two + tests are the SYNTHETIC proof the task brief asked for instead: that + {!band}'s [entry_14_movable_band]/RG 112(a) mechanism, ALREADY proved + above for Holy Family, governs Holy Name identically, since neither + {!band} nor {!disposition} key on anything Holy-Family-specific (only on + [subject]/[rank]/[origin], which [temporal_ef.ml]'s fix now sets + identically for both feasts) -- not a live-data regression test, a + mechanism-generalises-correctly one, the same distinction this file's own + header draws between a table row and an end-to-end proof. + + Run against BOTH of RG 17(a)'s own shapes -- the Sunday (2026-01-04) and + the 2 January fallback (2029-01-02, {!T.holy_name_fallback_date}) -- + because [temporal_ef.ml]'s own fallback-branch comment claims both band + identically at {!PE.entry_14_movable_band} (ONE feast, not two + differently-classified ones); a table proving the SAME two outcomes hold + for both dates is direct evidence for that specific claim, not merely + for the Sunday shape colitur already had a name for before this task. *) +let holy_name_probe_dates = + [ ("Sunday shape (2026-01-04)", mk 2026 1 4); ("fallback shape (2029-01-02)", T.holy_name_fallback_date 2029) ] + +let test_holy_name_excludes_synthetic_lord_end_to_end () = + List.iter + (fun (label, date) -> + let holy_name = of_temporal date in + Alcotest.(check bool) (label ^ ": sanity -- temporal_ef really did tag this Lord") true + (holy_name.P.cel.Cel.subject = Sub.Lord); + let day_ctx = ctx date in + let synthetic_lord = + cand ~origin:P.Sanctoral ~rank:V.Class2 ~subject:Sub.Lord ~layer:PE.universal_layer + "ef-synthetic-fixed-lord-probe" + in + let resolution = P.resolve real_rules day_ctx ~temporal:holy_name ~sanctoral:[ synthetic_lord ] in + Alcotest.(check string) (label ^ ": Holy Name is observed (RG91 e14: movable first)") + (S.to_string holy_name.P.cel.Cel.slug) (S.to_string resolution.P.observed.P.cel.Cel.slug); + Alcotest.(check int) (label ^ ": no commemorations at all -- RG112(a)'s own exclusion") 0 + (List.length resolution.P.commemorations); + Alcotest.(check (list string)) (label ^ ": the synthetic Lord candidate is OMITTED, not commemorated") + [ "ef-synthetic-fixed-lord-probe" ] + (List.map (fun (c, _) -> S.to_string c.P.cel.Cel.slug) resolution.P.omitted)) + holy_name_probe_dates + +(* A REAL asymmetry this test found between the two shapes, kept explicit + rather than papered over by forcing one uniform expectation on both -- + RG 109(a)'s privilege is textually "of a SUNDAY" (docs/research/rules- + register.md §4), read here via {!PE.is_sunday_slug}'s own substring test: + the Sunday shape's slug ("ef-holy-name-sunday") carries the marker and + the fallback shape's ("ef-holy-name") genuinely does not, because 2 + January genuinely is not a Sunday. So a losing Holy-Name-Sunday is + PRIVILEGED (RG109(a)) and survives RG111(a)'s "I class: none save one + privileged" cap when it loses to a higher day; a losing Holy-Name- + fallback has no RG109(a)-(f) category to claim (not a Sunday, not I + class, none of (c)-(f) either) and so is only ORDINARY -- which + RG111(a)'s own cap admits NONE of on a I-class day. Both outcomes are + individually correct readings of RG 109/111's own closed lists, not a + defect in either shape -- first observed as a test failure while writing + this pair (the original version of this test asserted one Privileged + commemoration for BOTH shapes uniformly and reddened here), traced to + this citation rather than forced to pass. *) +let test_class1_feast_inside_holy_name_window_end_to_end () = + List.iter + (fun (label, date, expect_privileged_commemoration) -> + let holy_name = of_temporal date in + let day_ctx = ctx date in + let synthetic_class1 = + cand ~origin:P.Sanctoral ~subject:Sub.Saint ~layer:PE.universal_layer "ef-synthetic-class1-probe-hn" + in + let resolution = P.resolve real_rules day_ctx ~temporal:holy_name ~sanctoral:[ synthetic_class1 ] in + Alcotest.(check string) (label ^ ": the I-class candidate is observed, NOT Holy Name (RG91 e11 beats e14-movable)") + "ef-synthetic-class1-probe-hn" (S.to_string resolution.P.observed.P.cel.Cel.slug); + Alcotest.(check (list string)) (label ^ ": nothing transfers") [] + (List.map (fun c -> S.to_string c.P.cel.Cel.slug) resolution.P.deferred); + if expect_privileged_commemoration then + match resolution.P.commemorations with + | [ (c, P.Privileged) ] -> + Alcotest.(check string) + (label ^ ": Holy Name itself is privileged-commemorated (RG109(a)), neither omitted nor transferred") + (S.to_string holy_name.P.cel.Cel.slug) (S.to_string c.P.cel.Cel.slug) + | other -> + Alcotest.failf "%s: expected exactly one Privileged commemoration (Holy Name), got %d" label + (List.length other) + else + Alcotest.(check int) + (label ^ ": RG111(a) admits none -- Holy Name's own commemoration here is Ordinary \ + (no RG109(a)-(f) category applies to a non-Sunday loser), and a I-class day admits \ + only a Privileged one") + 0 (List.length resolution.P.commemorations)) + [ ("Sunday shape (2026-01-04)", mk 2026 1 4, true); + ("fallback shape (2029-01-02)", T.holy_name_fallback_date 2029, false) ] + (* Completes Task 7's carried fix (RG 91 entry 8, §4): on a real Sunday landing on 2 November, All Souls does not merely lose (that was Task 7's [band] fix, proved by [test_all_souls_yields_to_sunday] above) -- it must @@ -1681,6 +1778,14 @@ let suite = "fix round 1, finding 1: a synthetic I-class candidate inside Holy Family's own window is \ observed and does not transfer (2026-01-11)" `Quick test_class1_feast_inside_holy_familys_window_end_to_end; + Alcotest.test_case + "RG112(a) + RG91 e14 \"primum mobilia\": Holy Name of Jesus excludes a synthetic fixed Lord \ + candidate entirely, both shapes (Sunday + fallback)" + `Quick test_holy_name_excludes_synthetic_lord_end_to_end; + Alcotest.test_case + "a synthetic I-class candidate inside Holy Name's own window is observed and does not \ + transfer, both shapes (Sunday + fallback)" + `Quick test_class1_feast_inside_holy_name_window_end_to_end; Alcotest.test_case "transfer_target: general RG96 search walks past more than one blocked day" `Quick test_transfer_target_general_multi_step_search; Alcotest.test_case "transfer_target: Annunciation exception starts at Monday after Low Sunday" -- cgit v1.3