diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-24 16:29:23 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-24 16:29:23 +0200 |
| commit | 8a5da8756cf6b57aa36c01b71ce893f7967d3a29 (patch) | |
| tree | 10873a692400fa25ce54c67ac9fc34d46af86272 /lib/kernel/rite.mli | |
| parent | 4f87cbde4ee79ac96aa7ebfed105b3a5ec02be43 (diff) | |
| parent | 73b15551804bb63ee0081005e2869d36afb54be2 (diff) | |
| download | colitur-8a5da8756cf6b57aa36c01b71ce893f7967d3a29.tar.gz colitur-8a5da8756cf6b57aa36c01b71ce893f7967d3a29.zip | |
merge: celebrant Mass rubrics, and four rubrical corrections
colitur now prints what a real ordo prints for the Mass: which formulary is
said and how it was reached, the Gloria, the Creed, the preface, and the
commemorations with their Low-Mass/sung distinction. colitur rubrics joins
day and readings.
Four defects were found and fixed on the way, each by an external witness
rather than by inspection: the Creed said at Requiem Masses (RG 476(f)),
the missing bissextile shift of St Matthias and St Gabriel (2 041 leap
years), Rogation Monday and Tuesday coloured violet in Paschaltide (RG
119(b)), and the ferias after the Ascension resuming the wrong Sunday's
Mass rather than the Ascension's.
Validation gained a sixth layer and then some: the preface is checked
against three independent publishers over seven witness-years (FIUV, three
LMS editions, three extraordinaryform.org editions), none of which shares
the Divinum Officium -> missalemeum -> lectio lineage the older layers all
descend from.
Diffstat (limited to 'lib/kernel/rite.mli')
| -rw-r--r-- | lib/kernel/rite.mli | 85 |
1 files changed, 81 insertions, 4 deletions
diff --git a/lib/kernel/rite.mli b/lib/kernel/rite.mli index 0324bf2..d53e4e6 100644 --- a/lib/kernel/rite.mli +++ b/lib/kernel/rite.mli @@ -17,6 +17,33 @@ type ('s, 'r) t = { into rite-agnostic code and be silently wrong for a Julian-reckoning rite. Read by {!Layer.index} to resolve {!Date_spec.Easter_offset}. *) + fixed_key : Date.t -> (int * int) option; + (** The (month, day) under which a FIXED sanctoral entry ({!Layer.on_date}) + is looked up for this civil date. [Some (month, day)] identity for + every rite with no reason to differ -- a Byzantine or other + non-Roman rite supplies nothing beyond that, and its output is + therefore byte-identical to a rite that predates this field + entirely. [None] means no fixed entry can ever be found for this + date, regardless of what {!Layer.index} holds. + + Exists for the Roman calendarium's own bissextile (leap-year) + footnote (February, docs/research/LT.txt:5011-5014): the + intercalary day is inserted by DOUBLING the sixth kalends of March + (civil 24 February in a common year), not by appending a 29th day + at the month's end, so every fixed feast dated at or after that + kalends position is kept one civil day later than usual, and 24 + February itself carries no fixed entry that year. This is a fact + about the ROMAN rite's own kalends reckoning, not a universal + computus rule -- a rite with no such convention (or none at all, + the default above) must not have it hardcoded into rite-agnostic + code, the same reason {!easter} above is rite-supplied rather than + chosen here. See rite_ef/temporal_ef.ml's [bissextile_fixed_key] + for the concrete Roman implementation and its full citation. + + Deliberately untouched: the MOVABLE half of {!Layer.on_date}'s + lookup ({!Date_spec.Easter_offset}, {!Date_spec.Nth_weekday}) -- + this field's contract is fixed-date reckoning only, and nothing in + the calendarium footnote concerns Easter-relative dates. *) rules : ('s, 'r) Precedence.rules; season_runs : 's list; (** the expected run-length-compressed season sequence over one liturgical @@ -71,13 +98,63 @@ type ('s, 'r) t = { temporal:('s, 'r) Temporal.t -> date:Date.t -> temporal_at:(Date.t -> ('s, 'r) Temporal.t) -> - Citation.t list; - (** The day's Epistle and Gospel citations, or []. Rite-supplied for the - same reason [transfer_target] is: what a day with no proper of its - own falls back to is a rubric of a particular rite, not a universal. + Mass_formulary.t option * Citation.t list; + (** The Mass actually said -- which formulary, and how that was decided + -- paired with its Epistle and Gospel citations. Rite-supplied for + the same reason [transfer_target] is: what a day with no proper of + its own falls back to is a rubric of a particular rite, not a + universal. + + The [Mass_formulary.t option] is [None] exactly when the rite's + lectionary is not built at all (the citation list is then also + []): a rite that HAS a lectionary is expected to resolve [Some] on + every day it covers, the same total-coverage discipline + {!Validate}'s own ["formulary"] check holds it to. [None] is never + a per-day "no Mass today" answer for a rite that otherwise + resolves readings -- that shape is coverage FAILURE, not a + legitimate outcome, which is exactly what makes the [Validate] + check meaningful. [temporal_at] is a callback so the rite can reach another date's temporal identity (the preceding Sunday's, for the ferial rule) without re-implementing the temporal cycle -- the same shape [transfer_target]'s own [occupant] callback established. *) + creed : temporal:('s, 'r) Temporal.t -> observed:'r Celebration.t -> date:Date.t -> bool; + (** Whether the Creed is said, post-Gospel/homily, at this day's Mass + (EF: RG 475-476). A [bool], not an [option]: this is a decision, + and a rite that has not implemented the rule returns [false] + explicitly rather than leaving the question unanswered. + + [temporal] and [observed] are supplied for the same reason + [readings] gets both: a rubric like this one can turn on either + the day's TEMPORAL-cycle identity (e.g. "is this a Sunday, even + one a feast has displaced") or on the celebration actually + observed, and only the rite knows which. [date] is supplied for + the same reason [readings] gets it too -- a rubric keyed to an + Easter-relative window (e.g. "within the octave of Easter") needs + the civil date and the rite's own Easter to test it, and neither + [temporal] nor [observed] alone carries that arithmetic. *) + gloria : temporal:('s, 'r) Temporal.t -> observed:'r Celebration.t -> date:Date.t -> bool; + (** Whether the Gloria in excelsis is said at this day's Mass (EF: RG + 431-432). Same seam as {!creed} in every respect: same three + parameters and the same reasons for each, a [bool] not an + [option], and [false] is the answer a rite that has not + implemented the rule returns explicitly. *) + preface : temporal:('s, 'r) Temporal.t -> observed:'r Celebration.t -> date:Date.t -> Preface.t option; + (** Which preface is said at this day's Mass (EF: RG 482-499). Same + seam and same three parameters as {!creed}/{!gloria}, for the + same reasons -- {!Preface}'s own citation has the rubric in full. + [Preface.t option], not a bare [Preface.t]: unlike [creed]/ + [gloria], where "not said" is itself a legitimate answer a + [bool] can carry, a preface is said only at a MASS, and this + engine constructs at least one day (Good Friday, the + 1955-restored Holy Week) that resolves an [observed] celebration + but has no Mass at all -- [None] is the honest answer there, not + a manufactured preface. [None] is also the value a rite that has + not implemented this rule returns, the same "the type's own + neutral value" contract {!creed}/{!gloria} give for [false] -- + the two meanings ("this rite does not model the question" and + "this specific day has no Mass to preface") collapse onto the + same representation deliberately: a caller with no rite-specific + context to distinguish them should not need one. *) } |
