aboutsummaryrefslogtreecommitdiff
path: root/lib/rites/rite_ef
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rites/rite_ef')
-rw-r--r--lib/rites/rite_ef/rite_ef.ml3
-rw-r--r--lib/rites/rite_ef/rite_ef.mli4
-rw-r--r--lib/rites/rite_ef/rubrics_ef.ml496
-rw-r--r--lib/rites/rite_ef/rubrics_ef.mli35
4 files changed, 537 insertions, 1 deletions
diff --git a/lib/rites/rite_ef/rite_ef.ml b/lib/rites/rite_ef/rite_ef.ml
index d7b3d83..808e017 100644
--- a/lib/rites/rite_ef/rite_ef.ml
+++ b/lib/rites/rite_ef/rite_ef.ml
@@ -52,4 +52,5 @@ let context ~lectionary ~commons : (Vocab_ef.season, Vocab_ef.rank) Rite.t =
transfer_target = Precedence_ef.transfer_target;
readings = Lectionary_ef.readings ~lectionary ~commons;
creed = Rubrics_ef.creed;
- gloria = Rubrics_ef.gloria }
+ gloria = Rubrics_ef.gloria;
+ preface = Rubrics_ef.preface }
diff --git a/lib/rites/rite_ef/rite_ef.mli b/lib/rites/rite_ef/rite_ef.mli
index 7025143..2ed61de 100644
--- a/lib/rites/rite_ef/rite_ef.mli
+++ b/lib/rites/rite_ef/rite_ef.mli
@@ -39,6 +39,10 @@ module Rubrics_ef = Rubrics_ef
- [gloria]: {!Rubrics_ef.gloria}, RG 431-432 -- whether the Gloria in
excelsis is said. Reads {!Rubrics_ef.te_deum} (Breviary nn. 237-238)
for RG 431(a)/432(a)'s own deferral.
+ - [preface]: {!Rubrics_ef.preface}, RG 482-499 -- which preface is
+ said. Same seam as [creed]/[gloria]; [None] both for a day with no
+ Mass at all (Good Friday) and for a rite that has not implemented
+ the rule.
Deliberately carries no [sanctoral]/[lectionary] fields the way the
original design-doc sketch of [RITE] does: {!Colitur_kernel.Rite.t} (the
diff --git a/lib/rites/rite_ef/rubrics_ef.ml b/lib/rites/rite_ef/rubrics_ef.ml
index a497b57..eea92a9 100644
--- a/lib/rites/rite_ef/rubrics_ef.ml
+++ b/lib/rites/rite_ef/rubrics_ef.ml
@@ -697,3 +697,499 @@ let gloria ~(temporal : (Vocab_ef.season, Vocab_ef.rank) Temporal.t)
Gloria mirrors [te_deum] exactly for every Mass not already decided
above. This is the ONE call site [te_deum] exists to serve. *)
te_deum ~temporal ~observed ~date
+
+(* Missale Romanum, Rubricae Generales, Caput XVII, "H) De praefatione" (RG
+ 482-499; docs/research/LT.txt, grep "praefatione dicitur quae cuique"),
+ quoted here in full so every branch below can cite its own paragraph
+ without re-quoting the whole rubric:
+
+ "482. Praefatio dicitur quae cuique Missae propria est; qua deficiente,
+ dicitur praefatio de Tempore, secus communis.
+
+ 483. Nulla commemoratio, in Missa occurrens, praefationem propriam
+ inducit.
+
+ 484. Praefatio de Nativitate Domini dicitur:
+ a) tamquam propria in Missis de Nativitate Domini et de eiusdem
+ octava, necnon in festo Purificationis B. Mariae Virg.;
+ b) tamquam de Tempore, infra octavam Nativitatis Domini, etiam in
+ Missis quae secus praefationem propriam haberent, exceptis iis Missis
+ quae praefationem propriam de divinis mysteriis vel Personis habent; et
+ a die 2 ad 5 ianuarii.
+
+ 485. Praefatio de Epiphania Domini dicitur:
+ a) tamquam propria in Missis de festo Epiphaniae et de
+ Commemoratione Baptismatis D. N. Iesu Christi;
+ b) tamquam de Tempore diebus a 7 ad 13 ianuarii.
+
+ 486. Praefatio de Quadragesima dicitur:
+ a) tamquam propria in Missis de Tempore a feria IV cinerum usque ad
+ sabbatum ante dominicam I Passionis;
+ b) tamquam de Tempore in ceteris Missis quae celebrantur eodem
+ tempore, et praefatione propria carent.
+
+ 487. Praefatio de sancta Cruce dicitur:
+ a) tamquam propria in Missis de tempore a dominica I Passionis usque
+ ad feriam V in Cena Domini; in Missis tam festivis quam votivis de
+ sancta Cruce, de Passione Domini et instrumentis Passionis Domini, de
+ pretiosissimo Sanguine D. N. Iesu Christi, de Ss.mo Redemptore;
+ b) tamquam de Tempore in omnibus Missis a dominica I Passionis usque
+ ad feriam IV Hebdomadae sanctae, quae praefatione propria carent.
+
+ 488. Praefatio de Missa chrismatis dicitur feria V in Cena Domini, in
+ sua Missa.
+
+ 489. Praefatio paschalis dicitur:
+ a) tamquam propria in Missis de Tempore a Missa Vigiliae paschalis
+ usque ad vigiliam Ascensionis Domini;
+ b) tamquam de Tempore in ceteris Missis quae celebrantur eodem
+ tempore, et praefatione propria carent.
+
+ 490. Praefatio de Ascensione Domini dicitur:
+ a) tamquam propria in festo Ascensionis Domini;
+ b) tamquam de Tempore in omnibus Missis a feria VI post Ascensionem
+ usque ad feriam VI ante vigiliam Pentecostes, quae praefatione propria
+ carent.
+
+ 491. Praefatio de Ss.mo Corde Iesu dicitur in Missis festivis et
+ votivis de Ss.mo Corde Iesu.
+
+ 492. Praefatio de D. N. Iesu Christo Rege dicitur in Missis festivis
+ et votivis de D. N. Iesu Christo Rege.
+
+ 493. Praefatio de Spiritu Sancto dicitur:
+ a) tamquam propria in Missis de Tempore a vigilia Pentecostes usque
+ ad subsequens sabbatum; et in Missis festivis et votivis de Spiritu
+ Sancto;
+ b) tamquam de Tempore in ceteris Missis quae celebrantur eodem
+ tempore, et praefatione propria carent.
+
+ 494. Praefatio de Ss.ma Trinitate dicitur:
+ a) tamquam propria in Missis de festo et votivis Ss.mae Trinitatis;
+ b) tamquam de Tempore in dominicis Adventus, et in omnibus dominicis
+ II classis, extra tempus natalicium et paschale.
+
+ 495. Praefatio de beata Maria Virgine dicitur in Missis festivis et
+ votivis beatae Mariae Virginis, praeterquam in festo Purificationis B.
+ Mariae Virg.
+
+ 496. Praefatio de S. Ioseph dicitur in Missis festivis et votivis S.
+ Ioseph.
+
+ 497. Praefatio de Apostolis dicitur in Missis festivis et votivis
+ Apostolorum et Evangelistarum.
+
+ 498. Praefatio communis dicitur in Missis quae praefatione propria
+ carent, nec sumere debent praefationem de Tempore.
+
+ 499. Praefatio defunctorum dicitur in Missis defunctorum."
+
+ THE SHAPE OF THE RULE, once, rather than at every branch: RG 482's own
+ chain is "propria, else de Tempore, else communis". Read literally, 484-
+ 497 look like FOURTEEN SEPARATE RULES, but on inspection each numbered
+ rubric's own (a)/(b) pair (where it has both) produces the SAME preface
+ identity either way -- (a) is the propria reading ("this Mass's OWN
+ preface"), (b) is the de-Tempore reading ("this OTHER Mass, lacking one
+ of its own, borrows it") -- so for the single question this function
+ answers (WHICH preface, not WHETHER it counts as propria or de Tempore
+ for some other purpose) the two halves collapse into one PRIORITY-
+ ORDERED decision: a fixed list of "genuinely proper" triggers (title/
+ mystery feasts, independent of season), checked first in a citable
+ order, falling through to a fixed list of SEASONAL windows, falling
+ through to [Common]. RG 483 (a commemoration never induces a proper)
+ holds by construction, the same way [creed]'s own 476(e) does: every
+ branch below reads only [observed], never a day's admitted
+ commemorations.
+
+ THE PRIORITY ORDER ITSELF was cross-checked against 358 real,
+ individually classifiable entries in the FIUV Ordo's own [praef] column
+ (test/fixtures/fiuv-ordo-2025-2026.sexp, test_fiuv_ordo.ml) spanning the
+ WHOLE liturgical year -- not merely derived from the Latin text in
+ isolation. Two findings the plain text alone would not have settled,
+ both empirically confirmed rather than assumed:
+
+ - 484(b)'s own "exceptis iis Missis quae praefationem propriam de
+ divinis mysteriis vel Personis habent" is NARROWER than every other
+ window's implicit "unless it already has a genuine proper" -- St
+ John the Evangelist (27 December, on {!creed_apostle_slugs}, so his
+ OWN Apostles preface (497) would otherwise apply) is overridden to
+ [Nativity] inside the octave (confirmed: the Ordo's own 27 December
+ entry reads "de Nativ.", not "App."), while St Barnabas/Sts Philip &
+ James/the other Apostles OUTSIDE the octave keep their own Apostles
+ preface even inside another window (Sts Philip & James, 11 May,
+ inside the Easter window: confirmed "App." in the Ordo, not
+ "Pasch."). So [Apostles] is checked AFTER the Nativity window below,
+ but every OTHER title trigger (Holy Cross/Sacred Heart/Christ the
+ King/Trinity/St Joseph/BVM) is checked BEFORE it -- RG 484(b)'s own
+ narrower carve-out, read literally: unreachable on the shipped
+ calendar for the other five (no such feast falls 25 December-5
+ January), so this ordering is defensive for them, not observed live,
+ the same "checked, not merely assumed" discipline
+ {!Precedence_ef.marian_slugs}'s own citation follows elsewhere.
+ - RG 495's own "et votivis" half is live on this engine's data after
+ all, for the ONE office this project already models as a votive-
+ shaped Mass without a votive-Mass DIMENSION (RG 78/91 entry 27, the
+ Saturday Office of the BVM, {!Temporal_ef}'s own [subject = Bvm]
+ tag): confirmed directly (3 January and 10 January 2026, both the
+ Saturday Office, both read "BMV" in the Ordo) -- including on 3
+ January, itself inside the Nativity's own "2 ad 5 ianuarii" de-
+ Tempore window, where BVM still wins, corroborating the same
+ "genuine propria outranks every window" ordering the Apostles
+ finding above established from the opposite direction.
+
+ Good Friday's own printed [praef] text ("comm. Feria VI prima in
+ mense.") was NOT used to check this function's own [None] answer for
+ that day: {!test_fiuv_ordo.ml}'s own F1 (Gloria) already adjudicated
+ this exact date's raw text as unreliable (a copied, not a considered,
+ line -- see that allow-list entry's own citation for the full argument,
+ confirmed against the PDF's own page image, not merely the extracted
+ fixture) -- the same defect, read again, would apply equally to
+ whatever trails "praef." on the identical corrupted line, so this
+ function's [None] rests on RG 28's own "no Mass" structural argument
+ alone (the same argument [creed]/[gloria]/[te_deum] already give for
+ this date), not on any Ordo corroboration. *)
+
+(* RG 487(a): the two GENUINE fixed-date feast triggers in the shipped
+ universal calendar -- the Exaltation of the Holy Cross (14 September)
+ and the Most Precious Blood (1 July), both [subject = Lord]. RG 487(a)'s
+ own further-named categories ("de Passione Domini et instrumentis
+ Passionis Domini, de Ss.mo Redemptore") have NO corresponding entry
+ anywhere in data/ef/sanctoral.sexp (checked directly, grepping for
+ "instrument"/"redeem": zero hits) -- genuinely absent from the shipped
+ 1962 universal calendar, not merely unmatched by this list, so they are
+ N/A rather than silently unreachable. *)
+let preface_holy_cross_slugs =
+ [ "exaltation-of-the-holy-cross"; "precious-blood-of-our-lord-jesus-christ" ]
+
+(* RG 496: the two St Joseph feasts in the shipped calendar (19 March, 1
+ May) -- both [subject = Saint], so (unlike RG 495's own BVM feasts) no
+ [subject]-based fallback exists or is needed; this closed list is the
+ whole of what RG 496 can ever reach on shipped data. *)
+let preface_st_joseph_slugs = [ "joseph-spouse-of-the-bl-virgin-mary"; "joseph-the-workman" ]
+
+(* RG 497's own [Apostolorum et Evangelistarum] population is WIDER than
+ {!creed_apostle_slugs}: RG 475(e) is restricted to a NATALICIUM ("festis
+ NATALICIIS Apostolorum...", that module's own citation), but RG 497 has
+ no such restriction at all ("in Missis festivis et votivis Apostolorum
+ et Evangelistarum" -- ANY festive/votive Mass of an Apostle or
+ Evangelist). FOUND, not assumed: the FIUV Ordo's own 30 June entry
+ ("In Commemoratione S. Pauli Ap.", data/ef/adjustments.sexp's own RG
+ 110(c) [Add], {!Precedence_ef}'s own citation -- a genuine [Feast]-
+ status office of Paul the Apostle, but NOT his own dies natalis, so
+ {!creed_apostle_slugs} deliberately excludes it) reads "App. I", not
+ "comm." -- checked directly while building this comparison, not
+ guessed. [creed_apostle_slugs] itself is UNCHANGED (RG 475(e)'s own
+ narrower "natalicium" reading still holds for the Creed); this is a
+ SEPARATE, wider list for RG 497 alone.
+
+ "conversion-of-st-paul" (25 January, Class3, the SAME "not a
+ natalicium" shape {!creed_apostle_slugs}'s own citation excludes it
+ for) is a plausible SECOND candidate by the identical RG 497 reasoning
+ -- deliberately NOT added: it is UNWITNESSED (25 January falls on a
+ Sunday, hence impeded, in the one fixture year this engine's Ordo
+ evidence covers, {!test_fiuv_ordo.ml}'s own window), and "a wrong
+ citation is worse than a missing one" ({!Precedence_ef.marian_slugs}'s
+ own citation, the precedent this follows). Left for a future fixture
+ year to confirm or refute. *)
+let preface_apostle_slugs = "in-commemoratione-sancti-pauli-apostoli" :: creed_apostle_slugs
+
+(* RG 495's own [beatae Mariae Virginis] population is also WIDER than
+ {!Precedence_ef.marian_slugs}: that list was built for a DIFFERENT
+ rubric (RG 112(d), whether a commemoration invokes HER OWN
+ intercession specifically) with a correspondingly narrower, oration-
+ checked standard, and its own citation explicitly EXCLUDES "dedication-
+ of-the-basilica-of-st-mary-major" (5 August) for exactly that reason --
+ "whose own oration could not be found... to confirm it invokes her
+ intercession". RG 495 asks a different, WIDER question ("is this Mass
+ festive or votive OF the Blessed Virgin Mary at all"), which the
+ Dedication of St Mary Major answers on its own title alone, without
+ needing the oration-level standard RG 112(d) requires. FOUND, not
+ assumed: the FIUV Ordo's own 5 August entry reads "BMV Et te in
+ Festivitate.", not "comm." -- checked directly. *)
+let preface_bvm_slugs = "dedication-of-the-basilica-of-st-mary-major" :: Precedence_ef.marian_slugs
+
+let preface ~(temporal : (Vocab_ef.season, Vocab_ef.rank) Temporal.t)
+ ~(observed : Vocab_ef.rank Celebration.t) ~(date : Date.t) : Preface.t option =
+ let easter = Computus.gregorian_easter (Date.year date) in
+ let n = Date.to_rata date - Date.to_rata easter in
+ let m = Date.month date and dd = Date.day date in
+ let slug = Slug.to_string observed.Celebration.slug in
+ if
+ (* RG 28-34/RG 23(b), the same structural "no Mass at all" position
+ [creed]'s own vigil comment and [gloria]'s own 432(d) comment both
+ take for Good Friday specifically: the 1955-restored Holy Week has
+ no Mass whatsoever that day (only the afternoon liturgical action),
+ so there is no Mass to preface. Checked ahead of the
+ {!Colour.Black} Requiem proxy immediately below -- unlike All
+ Souls, Good Friday sharing that colour is coincidental, not
+ diagnostic (temporal_ef.ml's own RG 132 citation), and the two need
+ DIFFERENT answers here (unlike [creed]/[gloria]/[te_deum], where
+ both collapse to the same boolean) -- so this function cannot reuse
+ their shared single guard and must split Good Friday out first. *)
+ n = -2
+ then None
+ else if
+ (* RG 499: "in Missis defunctorum" -- the same {!Colour.Black} proxy
+ [creed]'s own 476(f), [te_deum]'s own 238(d) and [gloria]'s own
+ 432(d) already use (this file's own header has the full argument
+ and the two-member population this proxy rests on). With Good
+ Friday split out above, the one remaining member is All Souls. *)
+ observed.Celebration.colour = Colour.Black
+ then Some Preface.Requiem
+ else if
+ (* RG 487(a)'s own fixed-feast half -- checked first among the title
+ triggers per this file's own header (arbitrary among these six,
+ since none can ever co-occur with another on shipped data; Holy
+ Cross is placed first only because it is also the anchor for the
+ Passiontide WINDOW checked later below, keeping both citations
+ adjacent in this file). *)
+ List.mem slug preface_holy_cross_slugs
+ then Some Preface.Holy_cross
+ else if
+ (* RG 491: "in Missis festivis... de Ss.mo Corde Iesu" -- the Friday
+ after the Octave of Corpus Christi (Easter+68), {!Temporal_ef}'s own
+ named slug. Confirmed against the Ordo (12 June 2026: "de Ss.mi
+ Corde Iesu"). *)
+ slug = "ef-sacred-heart"
+ then Some Preface.Sacred_heart
+ else if
+ (* RG 492: "in Missis festivis... de D. N. Iesu Christo Rege" -- the
+ last Sunday of October, {!Temporal_ef.christ_the_king}'s own named
+ slug. Confirmed against the Ordo (25 October 2026: "de Domino
+ Nostro Jesu Rege"). *)
+ slug = "ef-christ-the-king"
+ then Some Preface.Christ_the_king
+ else if
+ (* RG 490(a): "in festo Ascensionis Domini" -- the feast itself
+ (Easter+39), checked here by slug rather than folded into the
+ Ascension WINDOW below (which starts the day AFTER, Easter+40):
+ Ascension Day itself needs no window at all, its own slug already
+ identifies it uniquely. Confirmed against the Ordo (14 May 2026:
+ "Ascensionis, Communic pr."). *)
+ slug = "ef-ascension"
+ then Some Preface.Ascension
+ else if
+ (* RG 494(a): "in Missis de festo... Ss.mae Trinitatis" -- Trinity
+ Sunday itself (Easter+56), {!Temporal_ef}'s own named slug. Checked
+ ahead of 494(b)'s own WIDER de-Tempore grant (checked last below,
+ after every other window) for the same "specific propria before any
+ season fallback" reason every other title trigger is. Confirmed
+ against the Ordo (31 May 2026: "Trinit. II"). *)
+ slug = "ef-trinity"
+ then Some Preface.Trinity
+ else if
+ (* RG 496: see {!preface_st_joseph_slugs}'s own citation. *)
+ List.mem slug preface_st_joseph_slugs
+ then Some Preface.St_joseph
+ else if
+ (* RG 495: "in Missis festivis et votivis beatae Mariae Virginis" --
+ {!preface_bvm_slugs} (its own citation has the full account of why
+ it is wider than {!Precedence_ef.marian_slugs}) covers every
+ genuine Marian FEAST; [subject = Bvm] covers the one VOTIVE-shaped
+ office this engine models without a votive-Mass dimension of its
+ own (RG 78/91 entry 27, the Saturday Office of the BVM -- this
+ file's own header has the empirical confirmation, 3/10 January
+ 2026). The Purification is deliberately ABSENT from both:
+ {!Precedence_ef.marian_slugs} already excludes it by name (its own
+ citation), and it never carries [subject = Bvm] (tagged [Lord]
+ instead, register ยง6.0) -- RG 495's own "praeterquam in festo
+ Purificationis" exclusion therefore holds by construction, not by
+ a guard written here.
+
+ [not (is_vigil slug)]: RG 495's own "festivis" reads "festum", not
+ "vigilia" -- the SAME RG 21/35 taxonomy distinction {!creed}'s own
+ RG 28-34 comment already makes ("a vigil is its OWN liturgical-day
+ category, distinct from 'festum'"), applied here for the first
+ time in THIS function because it is the first branch a vigil can
+ actually reach: {!Precedence_ef.marian_slugs} includes
+ "vigil-of-the-assumption" (that list's own citation), which without
+ this guard would wrongly claim [Bvm] for 14 August. FOUND, not
+ assumed: the FIUV Ordo's own 14 August entry reads "comm. I", not
+ "BMV" -- checked directly, the same as every other finding in this
+ branch's own history. Corroborates, from the opposite direction,
+ {!creed}'s own RG 28-34 comment: colitur's own Nativity WINDOW
+ below already excludes 24 December (the Nativity Vigil) by
+ construction (it starts at 25 December, never 24th), so this guard
+ makes the SAME "a vigil is not a festum" answer explicit here too,
+ rather than relying on a second, unrelated accident of a date
+ range to produce it. *)
+ (not (Precedence_ef.is_vigil slug))
+ && (List.mem slug preface_bvm_slugs || observed.Celebration.subject = Subject.Bvm)
+ then Some Preface.Bvm
+ else if
+ (* RG 484(a)'s own explicit Purification clause ("necnon in festo
+ Purificationis B. Mariae Virg.") -- 2 February, nowhere near the
+ Nativity's own Christmas-to-Epiphany calendar position, so this is
+ a standalone slug check, not part of the WINDOW test below (unlike
+ every other 484 trigger, which IS date-based). Checked here, after
+ the BVM check immediately above (which the Purification's own
+ [subject = Lord] tag never reaches) and before the Nativity window
+ (which its own actual date, 2 February, never reaches either) --
+ positioned with the rest of 484's own citations for readability,
+ not because anything below could otherwise pre-empt it. *)
+ slug = "purification-of-the-blessed-virgin-mary"
+ then Some Preface.Nativity
+ else if
+ (* RG 484(a)/(b) merged, per this file's own header: 25 December-1
+ January (the Nativity itself and its octave, propria) UNION 2-5
+ January (498(b)'s own explicit extra de-Tempore days) -- one
+ contiguous window, since both halves produce the identical
+ preface. Checked BEFORE Apostles (below) but AFTER every genuine
+ "divine mysteries/Persons" propria above, per this file's own
+ header (St John the Evangelist, 27 December, is the live witness:
+ Apostles would otherwise apply and does not). *)
+ (m = 12 && dd >= 25) || (m = 1 && dd <= 5)
+ then Some Preface.Nativity
+ else if
+ (* RG 497: "in Missis festivis et votivis Apostolorum et
+ Evangelistarum" -- {!preface_apostle_slugs} (its own citation has
+ the full account of why it is wider than {!creed_apostle_slugs}),
+ confirmed by this file's own header to produce the SAME preface
+ answer as the Ordo on every Apostle date outside the Nativity
+ octave: 11 June (Barnabas), 29-30 June (Peter & Paul, In
+ Commemoratione Pauli), 11 May (Philip & James, RG 484(b)'s own
+ witness against the Nativity window immediately above). Checked
+ AFTER the Nativity window specifically (RG 484(b)'s own narrower
+ carve-out), but before every OTHER season window below -- an
+ Apostle feast keeps his own preface inside Lent, Passiontide,
+ Paschaltide etc., where nothing narrows the exception the way
+ 484(b) does. No [is_vigil] guard is needed here the way RG 495's
+ own branch above needs one: checked directly, no entry on
+ {!preface_apostle_slugs} is ever a vigil slug (every Apostle vigil
+ in the shipped data -- "vigil-of-sts-peter-paul" -- carries its own
+ distinct slug, absent from this list). *)
+ List.mem slug preface_apostle_slugs
+ then Some Preface.Apostles
+ else if
+ (* RG 485(a): "in Missis de festo Epiphaniae et de Commemoratione
+ Baptismatis D. N. Iesu Christi" -- the feast itself and its own
+ named commemoration (13 January, {!Precedence_ef}'s own
+ "commemoration-of-the-baptism-of-the-lord" -- {!creed}'s own 475(c)
+ comment already documents this entry's [subject = Lord] tag), both
+ checked by slug so 485(b)'s own WIDER window below need not repeat
+ them. *)
+ slug = "ef-epiphany" || slug = "commemoration-of-the-baptism-of-the-lord"
+ then Some Preface.Epiphany
+ else if
+ (* RG 485(b): "diebus a 7 ad 13 ianuarii" -- every OTHER Mass in this
+ window (Holy Family Sunday, an ordinary Time-after-Epiphany feria
+ or Sunday, a saint's feast with no propria of its own), confirmed
+ against the Ordo's own 11 January 2026 entry (Holy Family Sunday:
+ "de Epiphania. II", not a Holy-Family-specific preface -- this
+ engine has none to offer it anyway). Colitur's own Christmastide
+ season already spans 25 December-13 January (RG 72-73,
+ {!Vocab_ef.season}'s own citation), so this window is exactly its
+ OWN post-Epiphany tail; written as an explicit date range rather
+ than a season test only because the Nativity window above already
+ claims the season's FIRST half by date, not by season either, for
+ symmetry. *)
+ m = 1 && dd >= 6 && dd <= 13
+ then Some Preface.Epiphany
+ else if
+ (* RG 486(a)/(b) merged: Ash Wednesday (Easter-46) through the
+ Saturday before Passion Sunday I (Easter-15) inclusive -- every
+ Lenten feria/Sunday's own Mass (a), and every OTHER Mass in the
+ same span lacking a proper of its own (b). Confirmed against the
+ Ordo throughout (e.g. 18 February/19-20 February 2026: "Quadr.").
+ {!creed}'s own RG 23 comment already explains why Ash Wednesday
+ (feria I classis) reaches this branch on [observed]'s own terms
+ regardless of rank -- this function reads no rank at all here,
+ only the date. *)
+ n >= -46 && n <= -15
+ then Some Preface.Lent
+ else if
+ (* RG 487(a)/(b) merged: Passion Sunday I (Easter-14) through Holy
+ Thursday (Easter-3) inclusive -- (a)'s own "de tempore"/festive-
+ votive half extends through Holy Thursday itself (the Mass of the
+ Lord's Supper), (b)'s own narrower saint-Mass half stops one day
+ earlier (Holy Wednesday) but reaches no LIVE day this check does
+ not already cover identically (Holy Thursday is a feria I classis,
+ RG 23(b), so no saint's feast can ever occupy it -- {!creed}'s own
+ RG 23 citation). Confirmed against the Ordo throughout (22 March
+ 2026, Passion Sunday: "de Sancta Cruce."; 2 April 2026, Holy
+ Thursday: "de Sancta Cruce, Communicantes..."). *)
+ n >= -14 && n <= -3
+ then Some Preface.Holy_cross
+ else if
+ (* RG 489(a)/(b) merged: the Easter Vigil Mass (Easter-1, on Holy
+ Saturday's own date) through the vigil of the Ascension (Easter+38)
+ inclusive. [n = -1] is this engine's own OVERLOADED representation
+ of "the Vigil Mass", not Holy Saturday's daytime (which has no Mass
+ of its own at all, unlike Good Friday's [n = -2] this function
+ excludes by name above) -- [gloria]'s own RG 431(c) comment already
+ establishes the same convention for the identical date, and RG
+ 489(a) resolves the question on its own terms regardless: the
+ Paschal preface's window STARTS at the Vigil Mass, so [n = -1] is
+ correctly [Easter]. Confirmed against the Ordo throughout (5 April
+ 2026, Easter Sunday: "Pasch."; 13 May 2026, the Ascension Vigil:
+ "Pasch. I"); the fixture prints nothing at all for Holy Saturday's
+ own daytime square (4 April 2026), corroborating rather than
+ contradicting this reading -- see test_fiuv_ordo.ml's own citation. *)
+ n >= -1 && n <= 38
+ then Some Preface.Easter
+ else if
+ (* RG 490(b): "a feria VI post Ascensionem usque ad feriam VI ante
+ vigiliam Pentecostes" -- the Friday after Ascension (Easter+40)
+ through the Friday before the Pentecost vigil (Easter+47)
+ inclusive; Ascension Day itself (Easter+39) is already handled by
+ its own slug check above, not repeated here. Confirmed against the
+ Ordo throughout (15-22 May 2026: "Ascensionis"). *)
+ n >= 40 && n <= 47
+ then Some Preface.Ascension
+ else if
+ (* RG 493(a)/(b) merged: the vigil of Pentecost (Easter+48) through
+ "subsequens sabbatum" (the FOLLOWING Saturday, i.e. the Ember
+ Saturday within the Octave of Pentecost, Easter+55) inclusive.
+ Confirmed against the Ordo throughout (23-24 May 2026, the vigil
+ and Pentecost itself: "de Spirito Sancto"; 30 May 2026, the Ember
+ Saturday: "de Spirito Sancto"). *)
+ n >= 48 && n <= 55
+ then Some Preface.Holy_spirit
+ else if
+ (* RG 494(b): "in dominicis Adventus, et in omnibus dominicis II
+ classis, extra tempus natalicium et paschale". Read off
+ [temporal]'s own season, NOT [observed]'s rank -- CORRECTED from an
+ earlier version of this branch that DID read [observed.rank] and
+ required it to equal [Class2], which is wrong for the identical RG
+ 16(a) reason {!Precedence.rules.admit}'s own [~temporal] parameter
+ exists and [creed]'s own 237(b)/475(a) comments already give: a
+ feast that has WON the day can carry a different rank than the
+ Sunday it stands on. FOUND, not assumed: All Saints' Day (1
+ November), Class1, observed outright over an ordinary
+ Time-after-Pentecost Sunday it commemorates
+ ([+ef-time-after-pentecost-sunday-23]), reads "Trinit." in the
+ Ordo -- [observed.rank] there is [Class1], so the OLD guard wrongly
+ answered [Common]; there is no dedicated preface for All Saints
+ among RG 484-497's own fourteen, so RG 482's chain correctly falls
+ through to the SUNDAY's own de-Tempore grant regardless of which
+ rank actually won the day.
+
+ {!Temporal_ef.temporal}'s own [match s with Advent | Lent -> Class1
+ | _ -> Class2] means EVERY Sunday's own TEMPORAL identity is
+ [Class2] except in Advent and Lent -- so "in omnibus dominicis II
+ classis" and "in dominicis Adventus" collapse into ONE test, "any
+ Sunday outside Christmastide and Paschaltide" (Lent's own Sundays
+ need no explicit exclusion here: {!creed}'s own RG 23/Lent-window
+ reasoning already means every one of them is claimed by the LENT
+ window earlier in this very priority chain, provably unreachable
+ here, the same "checked, not merely assumed" position the previous
+ version of this comment already took for Christmastide/Paschaltide
+ -- confirmed by the SAME domain sweep in test_rubrics_ef.ml, which
+ still finds zero Christmastide/Paschaltide/Lent days reaching this
+ branch after this change). Confirmed against the Ordo throughout
+ (e.g. every Advent/Time-after-Epiphany/Septuagesima/Time-after-
+ Pentecost Sunday not otherwise claimed: "Trinit."), now including
+ All Saints' Day itself. *)
+ temporal.Temporal.weekday = Date.Sun
+ && temporal.Temporal.season <> Vocab_ef.Christmastide
+ && temporal.Temporal.season <> Vocab_ef.Paschaltide
+ then Some Preface.Trinity
+ else
+ (* RG 498: "in Missis quae praefatione propria carent, nec sumere
+ debent praefationem de Tempore" -- everything else: an ordinary
+ weekday feria outside every window above, a plain sanctoral saint
+ with no title of his own, an ordinary (non-Sunday, non-Class2, or
+ Christmastide/Paschaltide) day. Confirmed against the Ordo
+ throughout (the single most common value in the fixture, 188 of
+ 360 comparable rows). *)
+ Some Preface.Common
diff --git a/lib/rites/rite_ef/rubrics_ef.mli b/lib/rites/rite_ef/rubrics_ef.mli
index 618af65..befbf72 100644
--- a/lib/rites/rite_ef/rubrics_ef.mli
+++ b/lib/rites/rite_ef/rubrics_ef.mli
@@ -68,3 +68,38 @@ val gloria :
observed:Vocab_ef.rank Celebration.t ->
date:Date.t ->
bool
+
+(** RG 487(a)'s own two fixed-feast triggers for the Holy Cross preference
+ (the Exaltation of the Holy Cross, the Most Precious Blood) -- see the
+ .ml's own citation for what RG 487(a)'s further-named categories (the
+ Passion/Instruments of the Passion, the Most Holy Redeemer) are absent
+ from the shipped calendar entirely, not merely from this list. *)
+val preface_holy_cross_slugs : string list
+
+(** RG 496's own two St Joseph feasts in the shipped calendar. *)
+val preface_st_joseph_slugs : string list
+
+(** RG 497's own [Apostolorum et Evangelistarum] population -- WIDER than
+ {!creed_apostle_slugs} (no natalicium restriction); see the .ml's own
+ citation for the FIUV Ordo evidence and what was deliberately left
+ off, unwitnessed. *)
+val preface_apostle_slugs : string list
+
+(** RG 495's own [beatae Mariae Virginis] population -- WIDER than
+ {!Precedence_ef.marian_slugs} (a different, looser standard than that
+ list's own RG 112(d) oration-level one); see the .ml's own citation
+ for the FIUV Ordo evidence. *)
+val preface_bvm_slugs : string list
+
+(** Which preface is said at this day's Mass (RG 482-499). [None] both when
+ this engine resolves a day with no Mass at all (Good Friday) and -- for
+ a rite that has not implemented this function at all -- as the type's
+ own neutral value; see the .ml's own header for the rubric quoted in
+ full, the priority order every branch follows and why, and the FIUV
+ Ordo evidence that order rests on. Same three parameters as {!creed}/
+ {!te_deum}/{!gloria}, for the same reasons. *)
+val preface :
+ temporal:(Vocab_ef.season, Vocab_ef.rank) Temporal.t ->
+ observed:Vocab_ef.rank Celebration.t ->
+ date:Date.t ->
+ Preface.t option