(* OF (post-1970) temporal cycle vocabulary. Both types are closed variants private to this rite: EF code cannot name them, and this rite cannot name EF's. Every boundary and rank rule cites its Missale Romanum editio typica tertia (2002) "Normae universales de anno liturgico et de calendario" paragraph ("Normae n. N") or Institutio Generalis Missalis Romani paragraph ("IGMR n. N") -- the SAME PDF (docs/research/of/missale- romanum-2002.pdf) carries both documents, independently numbered from 1, so a bare "n. N" is ambiguous; every citation in this rite module names which document it is. *) (* Normae Titulus II ("De anni circulo"), sections II-VI, PRIMARY-SOURCE- VERIFIED against the 2002 typical edition (docs/research/of/ missale-romanum-2002.pdf, pdftotext -layout, around extracted line 3660 onward): the document's own six subsection headings under "De anni circulo" are "I. De Triduo paschali", "II. De tempore paschali", "III. De tempore Quadragesimae", "IV. De tempore Nativitatis", "V. De tempore Adventus", "VI. De tempore 'per annum'". FIVE of those six are literally called a "tempus" (season); the Triduum is deliberately NOT -- it is named only "Triduum paschale", never "tempus Tridui". That is a real textual signal, not an omission this module is working around: the Missal's own authors did not count the Triduum as one of the seasons a day's season vocabulary needs to name. Confirmed independently by the Missal's own Mass-propers structure (extracted lines ~7778, ~8480): "HEBDOMADA SANCTA" (the Lenten Holy Week propers) and "SACRUM TRIDUUM PASCHALE" are printed as two SEPARATE section headings, and neither is titled "tempus" either. This module therefore has FIVE seasons, matching the design's own prediction (2026-08-24-colitur-of-rite-module-design.md §4.2): [Advent], [Christmas], [Lent], [Easter], [Ordinary_time]. No [Septuagesima] (the 1969/2002 reform abolished the pre-Lent season the EF's Vocab_ef still carries -- Normae's own season list has no seventh "de tempore Septuagesimae" section at all, confirmed by its absence here) and no [Passiontide] (EF's separate season for the two weeks before Easter; the 2002 Normae's own n. 30 merges what used to be "Passion Sunday" and "Palm Sunday" into ONE day, "Dominica in palmis de Passione Domini", and folds it into Lent's own week numbering as week VI -- see [temporal_of.ml]'s own citation on this for the full argument). WHERE THE TRIDUUM'S OWN THREE DAYS LAND, given they get no season of their own: Normae n. 28, PRIMARY TEXT: "Tempus Quadragesimae decurrit a feria IV Cinerum ad Missam in Cena Domini EXCLUSIVE" -- Lent runs from Ash Wednesday up to (excluding) the evening Mass of the Lord's Supper. At colitur's own civil-day granularity (one season per [Date.t], never a sub-day boundary), that puts the WHOLE civil day of Holy Thursday inside Lent (the excluded boundary is the Mass itself, an event within that day, not the day's own start). Good Friday and Holy Saturday have no season of their own to fall back to either -- n. 22/23 fix Easter Time's own start at "dominica Resurrectionis" (Easter SUNDAY), not a day earlier -- so by the same "extend the last season through the Triduum's daytime, since the only actual Mass in that window (the Vigil) is textually already Easter" reasoning EF's own temporal_ef.ml already uses for its own Passiontide ("Holy Saturday stays in Passiontide: the Vigil is a night Mass"), Good Friday and Holy Saturday both stay [Lent] here too. Normae n. 30 gives this a SECOND, independent, and more direct textual anchor unavailable to EF's own analogous decision: "Dominicae huius temporis appellantur dominicae I, II, III, IV, V in Quadragesima. Dominica sexta, in qua initium sumit Hebdomada sancta, dicitur ... 'Dominica in palmis de Passione Domini'" -- the Sundays of THIS TIME [Lent] are called Sundays I-V in Lent; the SIXTH Sunday, ON WHICH HOLY WEEK BEGINS, is called [without dropping the 'Alleluia', a rubric not relevant here] "Palm Sunday of the Lord's Passion". Normae's OWN prose therefore states that Holy Week (Palm Sunday through the Vigil) IS Lent's own sixth week, not a thing outside Lent's own numbering -- confirmed against [temporal_of.ml]'s own [week] computation, which independently derives the identical result (Palm Sunday through Holy Saturday all fall in week 6 of Lent by the ordinary Sunday-aligned [floor_div] formula, with no special case needed for the Triduum days at all) -- see that file for the arithmetic. *) type season = Advent | Christmas | Lent | Easter | Ordinary_time [@@deriving sexp] (* Normae Titulus I ("De diebus liturgicis"), and the Tabula dierum liturgicorum's own 13-entry table (extracted lines ~3926-3980), name FOUR graded celebrations throughout: "Sollemnitas" (entries 1-4), "Festum" (entries 5-8), "Memoria obligatoria" (entries 10-11) and "Memoria ad libitum" (entry 12) -- confirmed against the Calendarium Romanum Generale's own printed month tables (e.g. "IN EPIPHANIA DOMINI Sollemnitas", "S. Raimundi de Penyafort, presbyteri" [no grade word: Memoria ad libitum by the table's own footnote, "Quando non indicatur gradus celebrationis, fit Memoria ad libitum"], "Ss. Stephani, protomartyris Festum"), which uses these four words as its own grade column, verbatim, for every entry. A FIFTH constructor, [Feria], is added beyond those four for an ordinary weekday -- not a fifth grade on the same Sollemnitas-Festum-Memoria scale, but a categorically different thing: Normae n. 16 (Titulus I.IV, "De feriis") calls these days "feriae" and never applies any of the four grade-words to one, yet {!Colitur_kernel.Celebration.t} requires SOME [rank] on every day (the same reason EF's own Vocab_ef.rank carries a catch-all [Class4] for its own plain ferias, RG 91 entry 28). The Tabula itself confirms ferias are graded for PRECEDENCE without ever being promoted to one of the four celebration-grades: entry 2 lists "Feriae Hebdomadae sanctae, a feria II ad feriam V inclusive" and "Feria IV Cinerum" [Ash Wednesday] at the SAME table position as Christmas, Epiphany, Ascension and Pentecost -- an extremely privileged PRECEDENCE, yet the table's own word for these days stays "feria", never "sollemnitas". Entry 9 similarly places "Feriae Adventus a die 17 ad 24 decembris inclusive" and "Feriae Quadragesimae" together with a THIRD kind of day (unnamed days within the Nativity octave), and entry 13 is the catch-all for every other feria. All THREE entries use the same word, "feria" -- what differs between them is precedence-table position, not grade. Phase 1 (this module, {!Temporal_of.temporal}) therefore assigns [Feria] uniformly to every day carrying no graded celebration; which Tabula entry a given [Feria] day occupies (Ash-Wednesday-tier vs. Advent-17-24/Lenten-tier vs. ordinary) is a {!Colitur_kernel.Precedence .rules.band} table lookup left to Phase 2, read off the day's own season/ date/weekday the same way EF's own [Precedence_ef.band] already distinguishes its RG 91 entry 2 Triduum ferias from its entry-28 ordinary ones without either of those two needing a DIFFERENT [Vocab_ef.rank] value -- see design 2026-08-24-colitur-of-rite-module-design.md §3, "No kernel change should be needed for the ranks themselves". *) type rank = Sollemnitas | Festum | Memoria_obligatoria | Memoria_ad_libitum | Feria [@@deriving sexp] let seasons = [ Advent; Christmas; Lent; Easter; Ordinary_time ] let ranks = [ Sollemnitas; Festum; Memoria_obligatoria; Memoria_ad_libitum; Feria ] let season_to_string = function | Advent -> "advent" | Christmas -> "christmas" | Lent -> "lent" | Easter -> "easter" | Ordinary_time -> "ordinary-time" let season_of_string = function | "advent" -> Some Advent | "christmas" -> Some Christmas | "lent" -> Some Lent | "easter" -> Some Easter | "ordinary-time" -> Some Ordinary_time | _ -> None (* No lectionary-legacy word to preserve (spec §4.4's reasoning for EF's own [Vocab_ef.season_slug_word] does not apply here -- OF has not been bootstrapped from any external lectionary key set yet), so this is simply [season_to_string] under a separate name, kept distinct only so a future real divergence does not force renaming every call site. *) let season_slug_word = season_to_string let rank_to_string = function | Sollemnitas -> "sollemnitas" | Festum -> "festum" | Memoria_obligatoria -> "memoria-obligatoria" | Memoria_ad_libitum -> "memoria-ad-libitum" | Feria -> "feria" let rank_of_string = function | "sollemnitas" -> Some Sollemnitas | "festum" -> Some Festum | "memoria-obligatoria" -> Some Memoria_obligatoria | "memoria-ad-libitum" -> Some Memoria_ad_libitum | "feria" -> Some Feria | _ -> None let vocab : (season, rank) Colitur_kernel.Vocab.t = { seasons; season_to_string; season_of_string; ranks; rank_to_string; rank_of_string }