1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
(* 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 }
|