aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-08-27 00:37:45 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-08-27 00:37:45 +0200
commit6e62e499aed1c5a31a18bcf5e9eaa7f2b0c4ff2e (patch)
tree9650e9b60ed2c4b178f80ed10f4e7ba9a9bf572d
parentbf42e85ed622da5227a69c26ec801d32c767bb32 (diff)
downloadcolitur-6e62e499aed1c5a31a18bcf5e9eaa7f2b0c4ff2e.tar.gz
colitur-6e62e499aed1c5a31a18bcf5e9eaa7f2b0c4ff2e.zip
fix(of): break the movable-BVM-memorial tie per a CDWDS Notification
Mary, Mother of the Church (Easter+50) and the Immaculate Heart of Mary (Easter+69) are both movable obligatory memorials that can land on a FIXED obligatory memorial's own date -- e.g. 2011-06-13 and 2015-06-13, both against Anthony of Padua. Both candidates banded identically at Tabula III.10 (100, both universal Memoria_obligatoria), a tie band could not break, so Precedence.resolve's kernel-level alphabetical Slug.compare tie-break silently picked instead -- 892 days for Mater Ecclesiae and 1109 for the Immaculate Heart across 1583-9999, all one shape (measured against the pre-fix alphabetical order directly, zero unexplained). Searched the corpus rather than inventing a rule. colitur's two previously-checked primary sources really are silent: the 2018 decree (AAS 110, 437-438) never addresses universal-calendar coincidence, and Normae n. 14's third clause resolves only two AD-LIBITUM memorials colliding. A third source resolves it: the CDWDS's own "Notification on the Memorial of the Blessed Virgin Mary, Mother of the Church" (24 March 2018 -- same dicastery and signatories as the decree; published only on vatican.va, confirmed absent from the AAS 2018 combined index) states that when this memorial "coincides with another Memorial of a Saint or Blessed... the Memorial of the Blessed Virgin Mary is to prevail," and extends the identical reasoning to the Immaculate Heart of Mary by name. This is a rubric, not colitur's own reasoned choice. Implemented as a sub-rank of 95, strictly between Tabula entries 9 and 10 -- the same "fits between neighbours" technique this module already uses elsewhere -- scoped to the two named slugs rather than [subject = Bvm], since the Notification's own reasoning is specifically about a memorial's link to a movable solemnity of the Lord, not a blanket Marian precedence. Golden pin updated: test_rite_of.ml's 2011-06-13 tie now pins Mary, Mother of the Church as observed (was Anthony of Padua, labelled "known arbitrary"), with the header rewritten to state the outcome now rests on the Notification, not a coin-flip. The litcal oracle allow-list gains L10: litcal's own grade vocabulary has no representation for a 95 sub-rank (everything Memoria_obligatoria reads "Memorial"), a representational gap in litcal, not a computational disagreement -- the identity axis is untouched and needed no new entry.
-rw-r--r--data/of/expected-divergences-litcal.sexp31
-rw-r--r--lib/rites/rite_of/precedence_of.ml87
-rw-r--r--test/test_litcal_of.ml43
-rw-r--r--test/test_precedence_of.ml60
-rw-r--r--test/test_rite_of.ml65
5 files changed, 256 insertions, 30 deletions
diff --git a/data/of/expected-divergences-litcal.sexp b/data/of/expected-divergences-litcal.sexp
index e0b8b2a..633d2e0 100644
--- a/data/of/expected-divergences-litcal.sexp
+++ b/data/of/expected-divergences-litcal.sexp
@@ -178,3 +178,34 @@
(verdict colitur)
(note "2035-03-17 (StJoseph): the same known limitation L8 records for grade, IDENTITY axis.")
(expected_rows 1))
+
+; L10 -- W3 (of-known-wrongs, 2026-08-26). Precedence_of.band now gives the
+; two shipped movable BVM obligatory memorials (Mary, Mother of the Church;
+; the Immaculate Heart of Mary) a sub-rank of 95, strictly between Tabula
+; entries 9 and 10, rather than the ordinary 100 -- so a real collision with
+; a FIXED obligatory memorial (e.g. 2011-06-13, Mater Ecclesiae vs Anthony
+; of Padua) resolves in the Marian memorial's favour instead of falling to
+; Colitur_kernel.Precedence.resolve's own alphabetical tie-break. Cited
+; on a genuine primary source, not colitur's own invented rule: the CDWDS's
+; own "Notification on the Memorial of the Blessed Virgin Mary, Mother of
+; the Church" (24 March 2018 -- the same dicastery and signatories as the
+; 11 February 2018 decree itself; published only on vatican.va, confirmed
+; NOT in the AAS 2018 combined index) -- "In casu occurrentiae huius
+; memoriae cum alia memoria ... in casu occurrentiae cum alia memoria
+; alicuius Sancti vel Beati, ... memoria B.M.V. praevalere debet."
+;
+; litcal's own grade_lcl text is coarser than this: every
+; Memoria_obligatoria reads "Memorial" regardless of colitur's own finer
+; sub-rank, so the [100;110] bucket cannot represent 95 -- a genuine
+; representational gap in litcal's own vocabulary, not a computational
+; disagreement (the two engines still agree on WHICH day is observed; the
+; identity axis is untouched by this fix and needed no new entry). Fires on
+; every fixture row naming either entity where colitur's own band is
+; exactly 95, on ANY date that entity is observed, not only a live
+; collision date, because the sub-rank is unconditional. 15 rows over this
+; fixture's 12 years, measured directly, not guessed.
+((id L10)
+ (citation "CDWDS Notification on the Memorial of the BVM, Mother of the Church (24 March 2018); precedence_of.ml's movable_bvm_memorials")
+ (verdict colitur)
+ (note "MaryMotherChurch (11 years) and ImmaculateHeart (4 years): colitur bands both at 95 (between Tabula 9 and 10), which litcal's own coarse \"Memorial\" grade text cannot represent -- a cited design choice, not a defect.")
+ (expected_rows 15))
diff --git a/lib/rites/rite_of/precedence_of.ml b/lib/rites/rite_of/precedence_of.ml
index 5344374..0e2c246 100644
--- a/lib/rites/rite_of/precedence_of.ml
+++ b/lib/rites/rite_of/precedence_of.ml
@@ -124,6 +124,87 @@ let is_nativity_octave_day (ctx : Vocab_of.season Precedence.context) =
let is_lenten_feria (ctx : Vocab_of.season Precedence.context) =
ctx.season = Vocab_of.Lent
+(* W3 (of-known-wrongs, 2026-08-26). Both are shipped MOVABLE obligatory
+ memorials of the BVM (data/of/calendar-2002.sexp: [immaculate-heart-of-mary],
+ Easter_offset 69; data/of/amendments/006-mary-mother-of-the-church.sexp:
+ [mary-mother-of-the-church], Easter_offset 50), and both can land on a
+ FIXED obligatory memorial's own date in a real year -- confirmed, not
+ merely possible: e.g. 2011-06-13 (Mater Ecclesiae vs Anthony of Padua) and
+ 2015-06-13 (Immaculate Heart vs Anthony of Padua, three years apart via
+ the other offset). Both candidates then band identically at Tabula
+ III.10 (100, both universal Memoria_obligatoria) -- a tie {!band} could
+ not break on its own, so {!Colitur_kernel.Precedence.resolve}'s kernel
+ tie-break (Slug.compare, alphabetical) silently decided instead: 892 days
+ for Mater Ecclesiae and 1109 for the Immaculate Heart across 1583-9999
+ (measured with the fix applied and compared against the plain alphabetical
+ order every one of those days would otherwise have taken -- see this
+ task's own report for the full sweep).
+
+ NEITHER of colitur's two checked primary sources resolves this: the 2018
+ decree inscribing Mater Ecclesiae (AAS 110, 437-438) is silent on
+ universal-calendar coincidence (its own coincidence clause covers only a
+ PARTICULAR calendar keeping the celebration on a different day at a
+ higher grade); Normae n. 14's third clause ("Si eodem die plures
+ inscribuntur in calendario memoriae ad libitum, una tantum celebrari
+ potest, omissis ceteris.") resolves only memoriae AD LIBITUM colliding
+ with each other, and n. 14's second clause covers only the Lenten-feria
+ case. Two OBLIGATORY memorials colliding is genuinely unaddressed by
+ either.
+
+ RESOLVED on a THIRD, later primary source, found by searching the
+ corpus (docs/research/of/), not invented: the Congregation for Divine
+ Worship and the Discipline of the Sacraments' own "Notification on the
+ Memorial of the Blessed Virgin Mary, Mother of the Church" (24 March
+ 2018 -- the SAME dicastery, the SAME two signatories, Robertus Card.
+ Sarah [Praefectus] and Arturus Roche [Archiepiscopus a Secretis], as the
+ 11 February 2018 decree itself). Published only on the Dicastery's own
+ site (vatican.va/roman_curia/congregations/ccdds/documents/
+ rc_con_ccdds_doc_20180324_notificazione-mater-ecclesiae_{en,it,la,sp}.html);
+ confirmed NOT listed in the AAS 2018 combined index
+ (docs/research/of/aas-indices/aas-indice2018.pdf, checked directly via
+ pdftotext) alongside the decree it follows up, which IS indexed there
+ (p.437) -- so this is a genuine dicasterial clarification, not an AAS
+ promulgation, and is cited as such rather than papered over as "AAS n.".
+ Its own operative Latin: "In casu occurrentiae huius memoriae cum alia
+ memoria principia generalia normarum universalium de Anno liturgico et
+ de Calendario (cf. Tabula dierum liturgicorum, n. 60) sequenda sunt. Cum
+ autem memoria B.M.V. Ecclesiae Matris sit Pentecoste coniuncta, sicut
+ pariter memoria Immaculati Cordis B.M.V. celebrationi Sacratissimi
+ Cordis Iesu coniuncta est, in casu occurrentiae cum alia memoria
+ alicuius Sancti vel Beati, iuxta liturgicam traditionem praestantiae
+ inter personas, memoria B.M.V. praevalere debet." The Dicastery's own
+ official English: "In the case where this Memorial coincides with
+ another Memorial the principles of the Universal Norms... are to be
+ followed (cf. Table of Liturgical Days, n. 60). Given that the Memorial
+ of the Blessed Virgin Mary, Mother of the Church is linked to Pentecost,
+ as the Memorial of the Immaculate Heart of the Blessed Virgin Mary is
+ similarly linked to the celebration of the Most Sacred Heart of Jesus,
+ then, in the case where it coincides with another Memorial of a Saint or
+ Blessed, and following the liturgical tradition of pre-eminence amongst
+ persons, the Memorial of the Blessed Virgin Mary is to prevail." The
+ Notification itself names BOTH memorials by this same analogy -- Mater
+ Ecclesiae's own rule IS the Immaculate Heart's pre-existing one, restated
+ -- so both are listed here, not only the one this task's own defect
+ report was filed against.
+
+ THIS IS THEREFORE A RUBRIC, NOT COLITUR'S OWN REASONED CHOICE: a
+ primary, dicastery-issued clarification of universal application, not an
+ analogy imported from the EF's own RG 91 entry 14 (which was the
+ fallback this task's brief authorized if nothing resolving turned up).
+
+ Implemented as a sub-rank strictly BETWEEN Tabula entries 9 and 10 (95,
+ not 100/110) -- the same "fits between neighbours" technique this
+ module's own header comment documents for exactly this situation. Never
+ climbs above entries 1-9: neither memorial's own date range (Easter+50 =
+ 11 May-14 June; Easter+69 = 30 May-3 July) can ever reach a Tabula 1-9
+ day, so 95 is inert there. Deliberately NOT a [subject = Bvm] rule: the
+ Notification's own reasoning is specifically that EACH of these two
+ memorials is tied to a movable SOLEMNITY OF THE LORD (Pentecost, the
+ Sacred Heart) -- a FIXED BVM memorial (e.g. Our Lady of Guadalupe, 12
+ December) gets no such boost, because nothing in the Notification's own
+ text extends this to Marian memorials in general. *)
+let movable_bvm_memorials = [ "mary-mother-of-the-church"; "immaculate-heart-of-mary" ]
+
let band (ctx : Vocab_of.season Precedence.context)
(c : Vocab_of.rank Precedence.candidate) : int =
let temporal = c.Precedence.origin = Precedence.Temporal in
@@ -191,6 +272,12 @@ let band (ctx : Vocab_of.season Precedence.context)
temporal
&& (is_late_advent_feria ctx || is_nativity_octave_day ctx || is_lenten_feria ctx)
then 90 (* Tabula II.9 *)
+ else if
+ c.cel.rank = Vocab_of.Memoria_obligatoria && List.mem (slug_of c) movable_bvm_memorials
+ then
+ 95 (* Between Tabula 9 and 10 -- W3, see [movable_bvm_memorials]'s own
+ comment above for the Notification this cites and why it is
+ scoped to these two slugs rather than [subject = Bvm]. *)
else if c.cel.rank = Vocab_of.Memoria_obligatoria && not (is_proper layer) then
100 (* Tabula III.10 -- universal or proper; the [layer] test is what
separates entry 10 from entry 11. Unlike entries 3, 5 and 7, "or
diff --git a/test/test_litcal_of.ml b/test/test_litcal_of.ml
index 6a638a7..9dfc5ba 100644
--- a/test/test_litcal_of.ml
+++ b/test/test_litcal_of.ml
@@ -640,6 +640,44 @@ let is_l7_2033_tie_identity (l : litcal_row) =
exact date shape) -- NOT fixed here, per this task's own brief. *)
let is_l8_l9_joseph_2035 (l : litcal_row) = String.equal l.event_key "StJoseph" && String.equal l.date "2035-03-17"
+(* L10 -- W3 (of-known-wrongs, 2026-08-26). Precedence_of.band now gives the
+ two SHIPPED movable BVM obligatory memorials (Mary, Mother of the Church,
+ event_key "MaryMotherChurch"; the Immaculate Heart of Mary, event_key
+ "ImmaculateHeart") a sub-rank of 95 -- strictly between Tabula entries 9
+ and 10, never the ordinary 100 -- so a real collision with a FIXED
+ obligatory memorial (e.g. 2011-06-13, Mater Ecclesiae vs Anthony of
+ Padua) resolves in the Marian memorial's favour instead of falling to
+ Colitur_kernel.Precedence.resolve's own alphabetical tie-break. See
+ Rite_of.Precedence_of.movable_bvm_memorials's own comment for the primary
+ source (the CDWDS's own 24 March 2018 Notification) and the full
+ reasoning.
+
+ litcal's own [grade_lcl] text is coarser than this: EVERY
+ Memoria_obligatoria reads "Memorial", with no way to represent colitur's
+ own finer sub-rank -- so [expected_bands]'s [100;110] bucket cannot match
+ 95. This is a genuine, cited REPRESENTATIONAL gap in litcal's own
+ vocabulary, not a computational disagreement: the IDENTITY axis (which
+ day is actually observed) is untouched by this fix and stays unexplained
+ here on purpose -- [test_identity_matches_or_is_explained] needed no new
+ entry, confirmed by running it after this fix with no change.
+
+ Fires on every fixture row naming either event_key where colitur's own
+ band is exactly 95 -- ANY date that entity is observed, not only an
+ actual collision date, because the sub-rank is unconditional (see
+ [movable_bvm_memorials]'s own comment for why: neither entity's date
+ range can ever reach a Tabula 1-9 day, so 95 is always safe and never
+ needs a live-collision guard). 15 rows over this fixture's 12 years,
+ measured directly against a real `dune test` run, not guessed:
+ MaryMotherChurch in 11 of 12 years (2033's own occurrence is a DIFFERENT,
+ already-explained shape, band 30 not 95 -- not this entity's date at
+ all that year; see L6) and ImmaculateHeart in 4 (the other 8 years'
+ ImmaculateHeart-window rows are excluded upstream by litcal's own
+ "optional memorial" grade quirk, [expected_bands]'s [None] case above,
+ or by L6/L7's own 2033 tie). *)
+let is_l10_movable_bvm_subrank (l : litcal_row) band =
+ (String.equal l.event_key "MaryMotherChurch" || String.equal l.event_key "ImmaculateHeart")
+ && band = 95
+
let test_grade_matches_or_is_explained () =
let litcal = litcal_rows () in
let allow_list = load_allow_list () in
@@ -663,6 +701,7 @@ let test_grade_matches_or_is_explained () =
else if is_l5_mary_magdalene l then bump "L5"
else if is_l6_2033_tie_grade l then bump "L6"
else if is_l8_l9_joseph_2035 l then bump "L8"
+ else if is_l10_movable_bvm_subrank l band then bump "L10"
else
unexplained :=
Printf.sprintf "%s: colitur band=%d, litcal grade=%S (event_key=%S, expected one of [%s])" l.date band
@@ -679,7 +718,7 @@ let test_grade_matches_or_is_explained () =
match List.assoc_opt id by_id with
| None -> Alcotest.failf "allow-list entry %s is used by the comparator but not declared in %s" id allow_list_path
| Some e -> Alcotest.(check int) (Printf.sprintf "%s expected_rows (grade)" id) e.expected_rows actual)
- [ "L4"; "L5"; "L6"; "L8" ]
+ [ "L4"; "L5"; "L6"; "L8"; "L10" ]
(* The complement, mirroring [test_unwitnessed_ordinary_time_is_counted]:
every row [expected_bands] returns [None] for, classified by which of
@@ -796,7 +835,7 @@ let test_no_holy_family_2033_divergence () =
(* [is_holy_family_2033]'s own header. *)
(* ---------------------------------------------------------------------- *)
-let recognized_allow_ids = [ "L1"; "L4"; "L5"; "L6"; "L7"; "L8"; "L9" ]
+let recognized_allow_ids = [ "L1"; "L4"; "L5"; "L6"; "L7"; "L8"; "L9"; "L10" ]
let test_allow_list_has_no_orphan_entries () =
let allow_list = load_allow_list () in
diff --git a/test/test_precedence_of.ml b/test/test_precedence_of.ml
index 23c26c2..e2e8540 100644
--- a/test/test_precedence_of.ml
+++ b/test/test_precedence_of.ml
@@ -524,6 +524,60 @@ let test_all_souls_beats_an_ordinary_sunday () =
Alcotest.(check bool) "All Souls, not the Sunday, is observed" true
(resolution.Precedence.observed = all_souls_candidate)
+(* W3 (of-known-wrongs, 2026-08-26). Mary, Mother of the Church (Easter+50)
+ and a fixed obligatory memorial (e.g. Anthony of Padua, 13 June) both
+ used to band at Tabula III.10 (100) whenever they coincide -- a tie
+ {!Rite_of.Precedence_of.band} could not break, silently resolved instead
+ by {!Colitur_kernel.Precedence.resolve}'s own generic alphabetical
+ tie-break. See {!Rite_of.Precedence_of.movable_bvm_memorials}'s own
+ comment for the primary source (the CDWDS's own 24 March 2018
+ Notification) this fix cites: the Marian memorial now bands at 95 and
+ always prevails. This is the direct unit-level counterpart to
+ test_rite_of.ml's own end-to-end
+ [test_mater_ecclesiae_anthony_tie_2011_resolved] -- this one calls
+ {!Colitur_kernel.Precedence.resolve} directly, the same shape every
+ other test in this file uses, and checks BOTH real years the sweep in
+ this task's own report found (2011 for Mater Ecclesiae, 2015 for the
+ Immaculate Heart -- three years apart via the other offset, colliding
+ with the SAME rival, Anthony of Padua, both confirmed via
+ {!Colitur_kernel.Computus.gregorian_easter} rather than trusted). *)
+let test_movable_bvm_memorial_beats_a_fixed_one () =
+ let anthony =
+ mk ~slug:"anthony-of-padua-priest-and-doctor" ~rank:Vocab_of.Memoria_obligatoria
+ ~origin:Precedence.Sanctoral ()
+ in
+ List.iter
+ (fun (label, slug, easter_offset, year, expected_date) ->
+ let movable =
+ mk ~slug ~rank:Vocab_of.Memoria_obligatoria ~subject:Subject.Bvm
+ ~origin:Precedence.Sanctoral ()
+ in
+ Alcotest.(check bool)
+ (Printf.sprintf "%s: alphabetically \"anthony-of-padua...\" sorts BEFORE %S -- confirms this \
+ test exercises the tie-break the fix overrides, not a vacuous check"
+ label slug)
+ true (String.compare "anthony-of-padua-priest-and-doctor" slug < 0);
+ let easter = Computus.gregorian_easter year in
+ let d = Date.add_days easter easter_offset in
+ Alcotest.(check string)
+ (Printf.sprintf "%s: Easter+%d %d really is %s" label easter_offset year expected_date)
+ expected_date (Date.to_iso8601 d);
+ let temporal_c =
+ mk ~slug:"of-ordinary-time-feria" ~rank:Vocab_of.Feria ~origin:Precedence.Temporal ()
+ in
+ let ctx = { Precedence.date = d; season = Vocab_of.Ordinary_time; weekday = Date.weekday d } in
+ let resolution =
+ Precedence.resolve Rite_of.Precedence_of.rules ctx ~temporal:temporal_c
+ ~sanctoral:[ anthony; movable ]
+ in
+ Alcotest.(check bool)
+ (Printf.sprintf "%s prevails over Anthony of Padua, not the alphabetical order" label)
+ true (resolution.Precedence.observed = movable))
+ [ ("Mary, Mother of the Church vs Anthony of Padua", "mary-mother-of-the-church", 50, 2011,
+ "2011-06-13");
+ ("Immaculate Heart of Mary vs Anthony of Padua", "immaculate-heart-of-mary", 69, 2015,
+ "2015-06-13") ]
+
let suite =
( "precedence-of",
[ Alcotest.test_case "Tabula part I (entries 1-4)" `Quick test_part1;
@@ -549,5 +603,9 @@ let suite =
test_target_is_free_of_entries_1_to_8;
Alcotest.test_case
"fix round 2: shipped All Souls beats an ordinary per-annum Sunday (2025-11-02)" `Quick
- test_all_souls_beats_an_ordinary_sunday ]
+ test_all_souls_beats_an_ordinary_sunday;
+ Alcotest.test_case
+ "W3: a movable BVM obligatory memorial beats a fixed one, per the CDWDS's 24 March 2018 \
+ Notification" `Quick
+ test_movable_bvm_memorial_beats_a_fixed_one ]
@ List.map QCheck_alcotest.to_alcotest [ prop_band_total ] )
diff --git a/test/test_rite_of.ml b/test/test_rite_of.ml
index 42c9c98..1de3614 100644
--- a/test/test_rite_of.ml
+++ b/test/test_rite_of.ml
@@ -373,21 +373,32 @@ let test_holy_family_fallback_1583_now_correct () =
worked example that amendment header itself names (Easter 24 April 2011,
so Easter+50 = 13 June -- re-derived here, not trusted from the comment).
- KNOWN ARBITRARY, not KNOWN WRONG: unlike the two tests above, there is no
- rubric this contradicts. The 2018 decree (AAS 110, 437-438) is silent on
- a universal-calendar coincidence with an existing obligatory memorial, and
- Normae n. 14's own third clause resolves only the AD-LIBITUM/AD-LIBITUM
- case ("Si eodem die plures inscribuntur in calendario memoriae ad
- libitum") -- it does not reach two OBLIGATORY memorials. So colitur's
- Slug.compare tie-break ("anthony-of-padua-priest-and-doctor" sorts before
- "mary-mother-of-the-church") is not this project inventing a rule; it is
- the kernel's own generic, rite-agnostic fallback, applied here for lack of
- a rite-specific one. This test pins that CURRENT behaviour so a future
- Calendar/kernel change, a slug rename, or a future overlay cannot flip
- which of the two is observed with no test going red -- the same shape of
- invisible-drift risk the EF side's RG 113/[band] fidelity work (`ef-rg16a`,
- register ยง6.1) eliminated on that side. *)
-let test_mater_ecclesiae_anthony_tie_2011_known_arbitrary () =
+ RESOLVED (W3, of-known-wrongs, 2026-08-26) ON A RUBRIC, NOT COLITUR'S OWN
+ JUDGEMENT -- this test used to pin the OPPOSITE outcome ("KNOWN
+ ARBITRARY", the kernel's generic alphabetical Slug.compare tie-break,
+ for lack of anything rite-specific). That framing is now WRONG, not
+ merely superseded: colitur's own two previously-checked primary sources
+ really are silent (the 2018 decree, AAS 110, 437-438, on universal-
+ calendar coincidence; Normae n. 14's third clause, which resolves only
+ the AD-LIBITUM/AD-LIBITUM case, "Si eodem die plures inscribuntur in
+ calendario memoriae ad libitum") -- but a THIRD primary source, found by
+ searching the corpus rather than invented, does resolve it: the CDWDS's
+ own "Notification on the Memorial of the Blessed Virgin Mary, Mother of
+ the Church" (24 March 2018, same dicastery and signatories as the decree;
+ published only on vatican.va, confirmed absent from the AAS 2018
+ combined index) states plainly that when this memorial "coincides with
+ another Memorial of a Saint or Blessed... the Memorial of the Blessed
+ Virgin Mary is to prevail." See {!Rite_of.Precedence_of.movable_bvm_
+ memorials}'s own comment for the full Latin, the official English, and
+ why the same rule also covers the Immaculate Heart of Mary (the
+ Notification names both, by the identical link-to-a-Lord's-solemnity
+ argument). {!Rite_of.Precedence_of.band} now gives both a sub-rank of
+ 95, strictly between Tabula entries 9 and 10, so this is no longer a
+ coin-flip the kernel settles for lack of a rite rule -- it is the rite
+ rule, cited. This test still pins CURRENT behaviour, for the identical
+ invisible-drift reason the original comment gave; what changed is which
+ behaviour is correct to pin. *)
+let test_mater_ecclesiae_anthony_tie_2011_resolved () =
let easter_2011 = Computus.gregorian_easter 2011 in
Alcotest.(check string) "2011 Easter is really 24 April (the Easter+50 trigger)" "2011-04-24"
(Date.to_iso8601 easter_2011);
@@ -404,18 +415,18 @@ let test_mater_ecclesiae_anthony_tie_2011_known_arbitrary () =
let days = Cal.year real_of_rite real_of_layer 2010 in
let june13 = Array.to_list days |> List.find (fun d -> Date.compare d.LD.date tie_date = 0) in
Alcotest.(check string)
- "KNOWN ARBITRARY (no rubric decides this; see this test's own header): the kernel's generic \
- alphabetical tie-break observes Anthony of Padua, not Mary Mother of the Church"
- "anthony-of-padua-priest-and-doctor" (slug_of june13.LD.observed);
- let mater_ecclesiae_omitted =
- List.exists (fun (c, _) -> slug_of c = "mary-mother-of-the-church") june13.LD.omitted
+ "RESOLVED (W3): the CDWDS's own 24 March 2018 Notification (see this test's own header) makes \
+ Mary, Mother of the Church prevail, not Anthony of Padua"
+ "mary-mother-of-the-church" (slug_of june13.LD.observed);
+ let anthony_omitted =
+ List.exists (fun (c, _) -> slug_of c = "anthony-of-padua-priest-and-doctor") june13.LD.omitted
in
Alcotest.(check bool)
- "and Mary, Mother of the Church is recorded in `omitted`, not silently dropped -- {!Colitur_kernel \
+ "and Anthony of Padua is recorded in `omitted`, not silently dropped -- {!Colitur_kernel \
.Liturgical_day.t.omitted}'s own contract"
- true mater_ecclesiae_omitted;
- Alcotest.(check bool) "she carries no commemoration either (OF's own admit always returns [])" false
- (List.exists (fun (c, _) -> slug_of c = "mary-mother-of-the-church") june13.LD.commemorations)
+ true anthony_omitted;
+ Alcotest.(check bool) "he carries no commemoration either (OF's own admit always returns [])" false
+ (List.exists (fun (c, _) -> slug_of c = "anthony-of-padua-priest-and-doctor") june13.LD.commemorations)
let suite =
( "Rite_of (real data: assembled Rite.t end-to-end via Calendar/Validate)",
@@ -434,6 +445,6 @@ let suite =
Day is a Sunday (1583)" `Quick
test_holy_family_fallback_1583_now_correct;
Alcotest.test_case
- "KNOWN ARBITRARY pinned: Mary Mother of the Church vs Anthony of Padua tie, 2011-06-13 \
- (Easter+50)" `Quick
- test_mater_ecclesiae_anthony_tie_2011_known_arbitrary ] )
+ "RESOLVED (W3): Mary Mother of the Church beats Anthony of Padua's tie, 2011-06-13 \
+ (Easter+50), per the CDWDS's 24 March 2018 Notification" `Quick
+ test_mater_ecclesiae_anthony_tie_2011_resolved ] )