From 3bfa0c459e3c0b5bfa962b7dbb0227db5a8ba09f Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Sat, 22 Aug 2026 12:58:15 +0200 Subject: test(ef): the LMS Ordo as a sixth validation layer An independent lineage -- neither Divinum Officium, missalemeum nor lectio -- covering the Mass formulary and the Creed. Characterised before use, per the discipline the extraordinaryform.org Ordo's blanket St Lawrence vigil gap taught this session: five opposite- prediction Creed probes (Sunday/feria, octave-override vs plain II-class, I-class) all confirmed against the raw extracted text before a single divergence was adjudicated, recorded in the fixture's own provenance header. tools/extract_lms_ordo.ml hand-parses pdftotext -layout output (no Str/regex, frozen deps) into test/fixtures/lms-ordo-2024-2025.sexp, 400 day-rows (2024-11-27..2025-12-31). Gl/Cr print per Mass-option, not per day; the extractor takes the first pair in reading order, which the source's own layout guarantees is the universal entry's, since a diocesan variant always follows it, never precedes it. The Ordo's I-V roman numeral ("Missae de sancta Maria in sabbato", RG 309(a)) is matched whole-line only, never by substring -- "V Mass of BVM" is a substring of "IV Mass of BVM". test/test_lms_ordo.ml compares two axes 1:1 by date: - the Creed (RG 475-476): 399 of 400 days comparable (Good Friday has no Mass at all, asserted as the only such day); one genuine divergence, adjudicated to the ORDO, not colitur -- All Souls' Day 2025-11-03 is a Requiem Mass, and colitur's own creed predicate has no notion of one, a pre-existing scope gap rubrics_ef.ml already documented in its own header before this task existed. - the BVM-Saturday seasonal Mass selection, the addendum's own "sharper check": all 14 Votive days in the window match their season's own numeral exactly, both directions, independently re-derived from RG 309(a) rather than calling colitur's private function. - the formulary override, for the three sources it can honestly discriminate (Proper 179, Preceding_sunday 66, Common 2, all clean); Own_slug (139) is excluded with evidence, not silently -- several ferial slugs carry citations byte-identical to their Sunday's own, so the Ordo's override line cannot distinguish the two representations. data/ef/expected-divergences-lms.sexp carries the one adjudicated entry (L1), cited to RG 476(f). Mutation-tested: inverting RG 475(a)'s Sunday clause reddens 10 existing Rubrics_ef unit tests AND this new layer's own comparator, independently, on a data source none of the other five layers touch. Reverted after confirming. No lib/ changes. day/readings/rubrics output re-confirmed byte- identical (1583, 2026, 2038, 9999) after this task; all three gates green (dune test, exhaustive sweep, make check). --- data/ef/expected-divergences-lms.sexp | 55 +++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 data/ef/expected-divergences-lms.sexp (limited to 'data/ef') diff --git a/data/ef/expected-divergences-lms.sexp b/data/ef/expected-divergences-lms.sexp new file mode 100644 index 0000000..96c9e50 --- /dev/null +++ b/data/ef/expected-divergences-lms.sexp @@ -0,0 +1,55 @@ +; data/ef/expected-divergences-lms.sexp -- Task 6 (2026-08-21-colitur- +; celebrant-rubrics-phase1)'s cited allow-list for the LMS Ordo comparison +; (test/test_lms_ordo.ml), fixture window 2024-11-27..2025-12-31. +; +; A SEPARATE file from data/ef/expected-divergences.sexp (the lectio +; allow-list) and data/ef/expected-divergences-missalemeum.sexp (the +; missalemeum/Divinum-Officium-lineage allow-list): this Ordo is a THIRD, +; independent lineage (a printed England & Wales diocesan book, ISBN +; 9781739209636, compiled directly from the 1962 Missal/1960 rubrics -- +; never passed through Divinum Officium, missalemeum or lectio), so its +; own divergences are kept apart rather than tangled into either existing +; file's own provenance. +; +; [verdict] names which side this task's own primary-source research +; backs, the SAME convention the missalemeum file's own header states: +; not always "colitur". +; +; L1 -- 2025-11-03 (All Souls' Day, transferred from 2 November, a Sunday +; that year, to the next available day -- RG's own transfer of a +; Commemoration when it falls on a Sunday). colitur (Rite_ef.Rubrics_ef. +; creed) says the Creed IS said (true): observed.rank = Class1, so RG +; 475(b)'s "in festis I classis" branch fires with nothing to stop it. +; The Ordo says it is NOT said (false): "Mon 3 ALL SOULS' DAY I Cl B / No +; Gl Sequence No Cr Pr of the Dead No Blessing" -- confirmed directly +; against the extracted pdftotext text, not merely the fixture row. +; +; The Ordo is right and colitur is not, on the rubric itself: RG 476(f), +; "Non dicitur symbolum ... f) in Missis defunctorum" -- the Creed is +; never said at a Requiem Mass, and All Souls' Day is definitionally one +; (colour black in colitur's own output on this very date). This is NOT a +; new defect this task found and is choosing to leave open -- it is +; rubrics_ef.ml's OWN documented scope limit, stated in that file's header +; comment before this task existed: "476(f) (Requiem Masses, also not +; modelled) ... genuinely inapplicable to this implementation -- a +; documented scope limit, not a defect." [creed] has no notion of "this +; Mass is a Requiem" anywhere in its own inputs (temporal/observed/date), +; so it cannot express 476(f) without a signature change this task's own +; constraints do not authorise (lib/ is read-only here except for this +; allow-list). Recorded here as the SPECIFIC real-world day the scope +; limit is finally witnessed on, rather than left as an abstract note in +; a doc comment nobody's data ever exercised. +; +; Domain-wide count: unmeasured (out of this task's scope -- would need a +; sweep of every I-class Requiem-shaped day 1583-9999, which does not +; exist as a distinct predicate in this codebase to sweep on). The two +; days this WOULD also apply to in principle -- 2 November itself in any +; year it does not fall on a Sunday, and the plain All Souls' Day office +; whenever it is not transferred -- are outside this fixture's own +; window's reach for a second occurrence, so only the one real day above +; is witnessed and adjudicated here. +((id L1) + (citation "RG 476(f): \"Non dicitur symbolum ... f) in Missis defunctorum\" -- the Creed is never said at a Mass of the dead; rubrics_ef.ml's own header already documents this Mass-type as unmodelled") + (verdict lms_ordo) + (note "colitur's [creed] has no notion of a Requiem Mass in its inputs (temporal/observed/date), so RG 475(b)'s I-class branch fires unopposed on All Souls' Day (Class1, black). A pre-existing, self-documented scope limit (rubrics_ef.ml's own header), witnessed here for the first time on a real date rather than left as an abstract note: 2025-11-03, All Souls' Day transferred from Sunday 2 November. The Ordo (\"No Gl Sequence No Cr Pr of the Dead\") is correct on the rubric.") + (expected_rows 1)) -- cgit v1.3 From 41263d60432fadd2aef3f04de66b60561f89cbec Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Sat, 22 Aug 2026 13:38:27 +0200 Subject: fix(ef): RG 476(f) -- the Creed is not said at a Requiem Mass colitur said the Creed IS said on All Souls' Day and every other Requiem-shaped day: RG 475(b)'s "in festis I classis" branch fired on rank alone, with nothing checking RG 476(f), "Non dicitur symbolum ... f) in Missis defunctorum". Allow-listed as L1 in expected-divergences-lms.sexp on the argument that [creed] has no notion of a Requiem Mass in its inputs and could not express the rule without a signature change. That argument does not hold. Colour.Black is used by exactly two celebrations in the whole engine, verified by grepping every occurrence in lib/ and data/: commemoration-of-all-souls (data/ef/sanctoral.sexp) and Good Friday (temporal_ef.ml, already false via the earlier RG 23(b) feria exclusion and has no Mass at all in the 1955-restored Holy Week). So on every day this engine can construct, colour = Black if and only if the Mass is a Requiem -- a citable implication (RG 117 assigns black to Masses of the dead) on this data, not a heuristic. Rite_ef.Rubrics_ef.creed now reads observed.colour as RG 476(f)'s own guard, positioned ahead of 475(b)'s rank branch. A new test, test_colour_black_population_is_exactly_two, sweeps both the shipped data and Temporal_ef's own code across a century and fails loudly the day a third Colour.Black celebration is ever introduced, so the proxy cannot silently rot. L1 is closed in expected-divergences-lms.sexp, citation preserved. Blast radius, measured (full 1583-9999 sweep, grouped by observed slug): 8 416 days change from true to false, every one commemoration-of-all-souls (missing from exactly 1 of the 8 417 domain years, a boundary-year transfer effect at 1583/9999). A further 8 416 Colour.Black days are Good Friday, unaffected (already false before this fix). colitur day/readings stay byte-identical to v0.10.1 (checked directly against a v0.10.1 worktree build, 9 domain-spanning years); colitur rubrics changes on exactly the 8 416 days above. colitur emit --format sexp's pretty-printed line count for 2027 moved 9010 -> 9011 as a side effect: Sexplib.Sexp.to_string_hum wraps by column width, and All Souls' Day 2027's record grew one wrapped line because "false" is one character longer than "true". Cosmetic only -- no field's data changed -- and pinned in test/cli.t with the measurement recorded. --- data/ef/expected-divergences-lms.sexp | 131 ++++++++++++++++++++++++---------- lib/rites/rite_ef/rubrics_ef.ml | 58 +++++++++++++-- lib/rites/rite_ef/rubrics_ef.mli | 5 +- test/cli.t | 14 +++- test/test_rubrics_ef.ml | 88 +++++++++++++++++++++++ 5 files changed, 249 insertions(+), 47 deletions(-) (limited to 'data/ef') diff --git a/data/ef/expected-divergences-lms.sexp b/data/ef/expected-divergences-lms.sexp index 96c9e50..e327419 100644 --- a/data/ef/expected-divergences-lms.sexp +++ b/data/ef/expected-divergences-lms.sexp @@ -15,41 +15,96 @@ ; backs, the SAME convention the missalemeum file's own header states: ; not always "colitur". ; -; L1 -- 2025-11-03 (All Souls' Day, transferred from 2 November, a Sunday -; that year, to the next available day -- RG's own transfer of a -; Commemoration when it falls on a Sunday). colitur (Rite_ef.Rubrics_ef. -; creed) says the Creed IS said (true): observed.rank = Class1, so RG -; 475(b)'s "in festis I classis" branch fires with nothing to stop it. -; The Ordo says it is NOT said (false): "Mon 3 ALL SOULS' DAY I Cl B / No -; Gl Sequence No Cr Pr of the Dead No Blessing" -- confirmed directly -; against the extracted pdftotext text, not merely the fixture row. -; -; The Ordo is right and colitur is not, on the rubric itself: RG 476(f), -; "Non dicitur symbolum ... f) in Missis defunctorum" -- the Creed is -; never said at a Requiem Mass, and All Souls' Day is definitionally one -; (colour black in colitur's own output on this very date). This is NOT a -; new defect this task found and is choosing to leave open -- it is -; rubrics_ef.ml's OWN documented scope limit, stated in that file's header -; comment before this task existed: "476(f) (Requiem Masses, also not -; modelled) ... genuinely inapplicable to this implementation -- a -; documented scope limit, not a defect." [creed] has no notion of "this -; Mass is a Requiem" anywhere in its own inputs (temporal/observed/date), -; so it cannot express 476(f) without a signature change this task's own -; constraints do not authorise (lib/ is read-only here except for this -; allow-list). Recorded here as the SPECIFIC real-world day the scope -; limit is finally witnessed on, rather than left as an abstract note in -; a doc comment nobody's data ever exercised. -; -; Domain-wide count: unmeasured (out of this task's scope -- would need a -; sweep of every I-class Requiem-shaped day 1583-9999, which does not -; exist as a distinct predicate in this codebase to sweep on). The two -; days this WOULD also apply to in principle -- 2 November itself in any -; year it does not fall on a Sunday, and the plain All Souls' Day office -; whenever it is not transferred -- are outside this fixture's own -; window's reach for a second occurrence, so only the one real day above -; is witnessed and adjudicated here. -((id L1) - (citation "RG 476(f): \"Non dicitur symbolum ... f) in Missis defunctorum\" -- the Creed is never said at a Mass of the dead; rubrics_ef.ml's own header already documents this Mass-type as unmodelled") - (verdict lms_ordo) - (note "colitur's [creed] has no notion of a Requiem Mass in its inputs (temporal/observed/date), so RG 475(b)'s I-class branch fires unopposed on All Souls' Day (Class1, black). A pre-existing, self-documented scope limit (rubrics_ef.ml's own header), witnessed here for the first time on a real date rather than left as an abstract note: 2025-11-03, All Souls' Day transferred from Sunday 2 November. The Ordo (\"No Gl Sequence No Cr Pr of the Dead\") is correct on the rubric.") - (expected_rows 1)) +; L1 -- CLOSED, FIXED (whole-branch review finding 1, 2026-08-22): was +; 2025-11-03 (All Souls' Day, transferred from 2 November, a Sunday that +; year). colitur used to say the Creed IS said (true) on rank alone +; (475(b), Class1) where the Ordo, correctly, says it is not: "Mon 3 ALL +; SOULS' DAY I Cl B / No Gl Sequence No Cr Pr of the Dead No Blessing". +; +; This entry's own PREVIOUS text argued the divergence could not be fixed +; without a signature change, because [creed]'s inputs (temporal/observed/ +; date) have no notion of "this Mass is a Requiem". That argument was +; wrong: {!Colour.Black} is used by exactly TWO celebrations in the whole +; engine (verified by grepping every [colour Black]/[Colour.Black] site in +; lib/ and data/) -- [commemoration-of-all-souls] (data/ef/sanctoral.sexp) +; and Good Friday (temporal_ef.ml, already [false] via the RG 23(b) feria +; exclusion regardless of colour, and has no Mass at all in the +; 1955-restored Holy Week) -- so on every day this engine can construct, +; [colour = Black] if and only if the Mass is a Requiem: a citable +; implication (RG 117 assigns black to Masses of the dead) on THIS DATA, +; not a heuristic guess. [Rite_ef.Rubrics_ef.creed] now reads +; [observed.colour] as RG 476(f)'s own guard, positioned ahead of 475(b)'s +; rank branch; see rubrics_ef.ml's own header and the guard's own comment +; for the full account, and test_rubrics_ef.ml's +; [test_colour_black_population_is_exactly_two] for the test that fails +; loudly the day a third [Colour.Black] celebration is ever added, so this +; proxy cannot silently rot. +; +; BLAST RADIUS, measured (full 1583-9999 sweep of {!Colitur_kernel. +; Calendar.year}, grouped by [observed]'s own slug): 8 416 days changed +; from [true] to [false], every one [commemoration-of-all-souls] (missing +; from exactly 1 of the 8 417 domain years -- a boundary-year transfer +; effect at 1583/9999, not a third population member: see the "know what +; each layer cannot see"-style caveats elsewhere in this project for other +; instances of the same edge). A further 8 416 [Colour.Black] days are +; Good Friday ([ef-passiontide-2-friday]), unchanged by this fix (already +; [false] before it, via the earlier feria exclusion) -- confirmed +; [creed_true_among_black = 0] after the fix, over the WHOLE domain, not +; merely the fixture's own 2024-2025 window. +; +; `colitur day`/`colitur readings` are unaffected (neither prints [creed]); +; `colitur rubrics` output changes on exactly the 8 416 days above. + +; L2 -- OPEN, colitur's own gap, found while building L1's fix (whole- +; branch review finding 2, 2026-08-22). NOT an active entry in this +; file's own machine-checked sense (no code loads or cross-checks an +; "L2" id anywhere -- this file's own [allow_entry] machinery is scoped +; to the CREED axis, {!test_lms_ordo.test_creed_matches_or_is_explained} +; alone; a second, unrelated axis reusing the same id-lookup mechanism +; would let one test's "declared but never fired" check spuriously trip +; on the other axis's own entry). Recorded here as prose only, the same +; discipline this file's own closed L1 note above and +; expected-divergences.sexp's own closed C-entries already use for a +; citation worth preserving without a live parser hook -- the REAL +; enforcement is test_lms_ordo.ml's own [test_formulary_override_matches], +; which asserts this population is exactly 3 days directly. +; +; Strengthening test_lms_ordo.ml's formulary-override check from PRESENCE +; to the actual STRING (this same finding 2) surfaced a real, separate +; defect in step 3 of the reading chain ({!Rite_ef.Lectionary_ef. +; readings}), independent of the Creed axis above. Three real days in the +; fixture window -- 2025-05-30 (Friday), 2025-06-02 (Monday), 2025-06-03 +; (Tuesday), all between Ascension Thursday and the following Sunday -- +; have no proper of their own and fall to {!Colitur_kernel. +; Mass_formulary.Preceding_sunday}. colitur resumes the nearest CALENDAR +; Sunday (the "5th"/"6th Sunday after Easter", Paschaltide's own week +; 6/7), but the Missal, and the Ordo, keep saying ASCENSION'S OWN Mass +; through this stretch instead: "Mass of the Ascension" on all three +; days, never a numbered-Sunday title. Step 3 has no notion of "inside +; Ascension's own after-feast period" -- it always resumes the nearest +; preceding Sunday, numbered or not. +; +; STRUCTURAL, not a fixture artefact: the Ascension is a fixed Easter+39 +; (a Thursday inside Paschaltide week 6), so every feria whose own +; Preceding_sunday fallback would otherwise resolve to week 6 or 7 falls +; in this same stretch, every year -- this is not a coincidence of +; 2024-2025 alone, though only this fixture's own window has been checked +; against a real Ordo. +; +; NOT FIXED in this task: fixing it means teaching step 3, or the +; lectionary data, about Ascension's own after-feast period -- the same +; shape as the Christmastide "infra octavam Nativitatis" entries +; data/ef/lectionary.sexp already carries directly rather than resolving +; through this fallback -- a lectionary-data change out of a fix round's +; own scope. test/test_lms_ordo.ml's own +; [expected_preceding_sunday_override] excludes exactly these two +; (season, week) pairs from its general mapping, and +; [test_formulary_override_matches] asserts the excluded population is +; exactly 3 real days, all showing "Mass of the Ascension", so a change +; to this population (a fourth day, a different Ordo string) would be +; caught rather than silently absorbed. +; +; Domain-wide count: unmeasured -- "which feria is inside Ascension's own +; after-feast period" is not a distinct predicate anywhere in this +; codebase to sweep on. Structurally recurs every year, so on the order +; of 3 days/year x domain years, not merely 3 total. diff --git a/lib/rites/rite_ef/rubrics_ef.ml b/lib/rites/rite_ef/rubrics_ef.ml index 6345399..ab9da32 100644 --- a/lib/rites/rite_ef/rubrics_ef.ml +++ b/lib/rites/rite_ef/rubrics_ef.ml @@ -26,12 +26,37 @@ engine resolves ONE observed office and ONE Mass per civil day (see Rite.t.readings' own doc comment) -- it has no separate "which votive Mass is said" dimension. So the "vel/et...votivis" halves of 475(a)/(b), - 476(c) entirely, 476(d)'s "et votivis" half, and 476(f) (Requiem Masses, - also not modelled) are genuinely inapplicable to this implementation -- - a documented scope limit, not a defect. 476(e) needs no branch at all: - [creed] below reads only [observed], never a day's admitted - commemorations, so a commemoration can never change its answer by - construction. *) + 476(c) entirely, and 476(d)'s "et votivis" half are genuinely + inapplicable to this implementation -- a documented scope limit, not a + defect. 476(e) needs no branch at all: [creed] below reads only + [observed], never a day's admitted commemorations, so a commemoration + can never change its answer by construction. + + 476(f) ("in Missis defunctorum") is DIFFERENT: this file used to carry + it in the same "not modelled" list above, on the reasoning that + [creed]'s inputs (temporal/observed/date) have no notion of "this Mass + is a Requiem". That reasoning was wrong, found by the LMS Ordo layer + (test_lms_ordo.ml, allow-list entry L1, now closed -- see + expected-divergences-lms.sexp) on 2025-11-03, All Souls' Day: colitur + said the Creed where the Ordo, correctly, does not. [observed] DOES + carry a usable signal -- RG 117 assigns black to Masses of the dead, + and {!Colour.Black} is used by exactly TWO celebrations in this whole + engine, verified by grepping every [colour Black]/[Colour.Black] site + in lib/ and data/: [commemoration-of-all-souls] in + data/ef/sanctoral.sexp, and Good Friday in temporal_ef.ml (which is a + Holy Week FERIA, RG 23(b), already excluded by the [n >= -6 && n <= + -1] branch below regardless of colour, and has no Mass at all in the + 1955-restored Holy Week). So on every day this engine can actually + construct, [colour = Black] if and only if the Mass is a Requiem -- + a citable implication ON THIS DATA, not a heuristic guess. [creed] + below uses it as 476(f)'s own guard. This is a PROXY, not a general + "is this a Requiem Mass" field, and it is only as good as that + two-member population: {!test_rubrics_ef}'s own + [test_colour_black_population_is_exactly_two] fails loudly the day a + third [Colour.Black] celebration is added anywhere, so the proxy + cannot silently rot into covering (or missing) a non-Requiem black + Mass. If that ever happens, this guard needs re-deriving, not merely + re-approving. *) open Colitur_kernel @@ -222,6 +247,27 @@ let creed ~(temporal : (Vocab_ef.season, Vocab_ef.rank) Temporal.t) {!Precedence_ef.marian_slugs} just below. *) Precedence_ef.is_vigil slug then false + else if + (* RG 476(f): "in Missis defunctorum" -- the Creed is never said at a + Requiem Mass, checked here, ahead of 475(b)'s rank branch, the same + "category excludes regardless of rank" position as the feria and + vigil checks immediately above (All Souls' Day is [Class1], so + without this guard 475(b) would grant it [true] unopposed, which is + exactly the defect this guard fixes -- see this file's own header + for the two-member [Colour.Black] population this proxy rests on, + and {!Colour.Black}'s own citation, RG 117, for why colour is the + Requiem signal. Placed before, not after, 475(b)/(c)/(e) so a black + Class1 or Class2 day can never reach them; nothing above this point + (the Nativity/Easter/Pentecost octave override, the Sunday rule, the + feria and vigil exclusions) is ever reachable by a Requiem Mass on + the shipped data either -- a Requiem is never kept on a Sunday or + inside a privileged octave -- so this guard's own position relative + to THOSE branches is moot on real data, checked, not merely assumed: + {!creed_apostle_slugs} and [marian_slugs] contain no Black-coloured + entry, and 2 November can never fall inside any of the three + octaves 475(d) names. *) + observed.Celebration.colour = Colour.Black + then false else if (* RG 475(b): "in festis I classis". Genuine feasts only, by construction of the two exclusions immediately above (feria I diff --git a/lib/rites/rite_ef/rubrics_ef.mli b/lib/rites/rite_ef/rubrics_ef.mli index 16e7491..7a1284b 100644 --- a/lib/rites/rite_ef/rubrics_ef.mli +++ b/lib/rites/rite_ef/rubrics_ef.mli @@ -29,7 +29,10 @@ val creed_apostle_slugs : string list {!Liturgical_day.t.commemorations}: RG 476(e), "ratione alicuius commemorationis in Missa occurrentis" [never say the Creed merely because of a commemoration], holds by construction rather than by a - checked branch. *) + checked branch. RG 476(f) ("in Missis defunctorum") reads + [observed]'s [colour]: see the .ml's own header for why [Colour.Black] + is a sound proxy for "this Mass is a Requiem" on the shipped data, and + what would have to be re-checked if that ever stops being true. *) val creed : temporal:(Vocab_ef.season, Vocab_ef.rank) Temporal.t -> observed:Vocab_ef.rank Celebration.t -> diff --git a/test/cli.t b/test/cli.t index ac1351b..e2d2eb5 100644 --- a/test/cli.t +++ b/test/cli.t @@ -534,10 +534,20 @@ CSV run rather than one per year: $ colitur emit --format csv --from 2027 --to 2028 | wc -l 732 -sexp and xml are also available: +sexp and xml are also available. This line count moved 9010 -> 9011 +(whole-branch review fix round, RG 476(f)): [emit --format sexp] pretty- +prints with [Sexplib.Sexp.to_string_hum], a column-width wrapping printer, +not a fixed-shape one -- 2027's All Souls' Day (2 November) record grew a +single wrapped line when its own [creed] field's value changed from +[true] to [false] (RG 476(f), the Creed is never said at a Requiem Mass; +see rubrics_ef.ml), because "false" is one character longer than "true" +and pushed that one line's rendered width over to_string_hum's own wrap +threshold. Purely cosmetic -- the record's DATA is unchanged in every +other field, and this is not a claim that [emit]'s FORMAT changed, only +that one record's pretty-printed SHAPE did: $ colitur emit --format sexp --from 2027 --to 2027 | wc -l - 9010 + 9011 $ colitur emit --format xml --from 2027 --to 2027 | head -2 diff --git a/test/test_rubrics_ef.ml b/test/test_rubrics_ef.ml index 5109c69..a778a5a 100644 --- a/test/test_rubrics_ef.ml +++ b/test/test_rubrics_ef.ml @@ -26,6 +26,7 @@ module Colour = Colitur_kernel.Colour module Subject = Colitur_kernel.Subject module Slug = Colitur_kernel.Slug module Temporal = Colitur_kernel.Temporal +module Computus = Colitur_kernel.Computus module V = Rite_ef.Vocab_ef module RE = Rite_ef.Rubrics_ef module TE = Rite_ef.Temporal_ef @@ -175,6 +176,87 @@ let test_holy_saturday_easter_vigil_no_creed () = by 476(a) ("in Missa Vigiliae paschalis"). *) check "RG 23(b)/476(a): Holy Saturday (the Easter Vigil Mass)" 2026 4 4 false +(* ---- RG 476(f): "in Missis defunctorum" -- the Creed is never said at a + Requiem Mass. Whole-branch review finding 1: colitur used to say [true] + here on rank alone (475(b), Class1) -- the LMS Ordo layer's own former + allow-list entry L1, now closed, was this exact day. See rubrics_ef.ml's + own header for why {!Colour.Black} is a sound RG 117 proxy for "this Mass + is a Requiem" on the shipped data. ---- *) + +let test_476f_all_souls_no_creed () = + (* 2025-11-03: All Souls' Day (2 November, a Sunday that year, transferred + to the next open day, RG's own Class1/black office unchanged by the + transfer) -- `colitur day 2025` confirms class-1/black/ + commemoration-of-all-souls on this date. Before this fix [creed] here + was [true] via 475(b); the Ordo's own text ("No Cr") says otherwise. *) + check "RG 476(f): All Souls' Day (transferred), a Requiem, says no Creed" 2025 11 3 false + +let test_476f_good_friday_no_creed () = + (* 2026-04-03: Good Friday, [colour = Black] (temporal_ef.ml's own + [days_between easter d = -2] branch) -- already [false] via the RG + 23(b) feria-I-classis exclusion checked earlier in [creed], so this is + a belt-and-braces witness that the 476(f) guard, were it ever reached + first, would agree rather than a case that depends on it: Good Friday + has no Mass in the 1955-restored Holy Week to begin with. *) + check "RG 476(f)/RG 23(b): Good Friday, black, says no Creed" 2026 4 3 false + +(* Whole-branch review finding 1's own instruction: a test that FAILS if a + third {!Colour.Black} celebration is ever introduced, so the RG 476(f) + guard's colour proxy cannot silently rot into covering the wrong + population. Two independent checks, matching the two places a black + celebration could be added: + + DATA: every entry the shipped sanctoral layer (sanctoral.sexp, with + adjustments.sexp merged on top -- the same [layer] every other test in + this file resolves against) carries directly, fixed AND movable alike + ({!Colitur_kernel.Layer.entries} holds the raw [Date_spec.t], not a + resolved index, so this needs no date walk at all to cover every civil + year). + + CODE: {!Rite_ef.Temporal_ef.temporal}'s own colour logic, which + sanctoral.sexp cannot see (Good Friday's black is computed, not data) -- + swept across a century the same span and for the same coverage reason + {!test_ferial_origin_never_carries_lord_bvm_or_apostle_slug} above + already uses, since a Colour.Black bug introduced into a rare branch + (an Ember day, Rogation Wednesday...) would not show up in one year. *) +let test_colour_black_population_is_exactly_two () = + let black_data_entries = + List.filter + (fun (e : V.rank Colitur_kernel.Layer.entry) -> e.Colitur_kernel.Layer.cel.Cel.colour = Colour.Black) + layer.Colitur_kernel.Layer.entries + in + Alcotest.(check int) "exactly one Colour.Black entry in the shipped data" 1 + (List.length black_data_entries); + (match black_data_entries with + | [ e ] -> + Alcotest.(check string) "the one Colour.Black data entry is All Souls" "commemoration-of-all-souls" + (Slug.to_string e.Colitur_kernel.Layer.cel.Cel.slug) + | _ -> ()); + let code_black = ref [] in + for y = 1583 to 1682 do + let dec31 = mk y 12 31 in + let d = ref (mk y 1 1) in + while Date.compare !d dec31 <= 0 do + let t = TE.temporal !d in + if t.Temporal.office.Cel.colour = Colour.Black then code_black := (y, !d, t) :: !code_black; + d := Date.add_days !d 1 + done + done; + Alcotest.(check bool) "the century sweep found at least 100 Colour.Black temporal days" true + (List.length !code_black >= 100); + List.iter + (fun (_, d, (t : (V.season, V.rank) Temporal.t)) -> + let easter = Computus.gregorian_easter (Date.year d) in + Alcotest.(check int) + (Printf.sprintf "%s: the only code-side Colour.Black day is Good Friday (Easter-2)" + (Date.to_iso8601 d)) + (-2) (Date.to_rata d - Date.to_rata easter); + Alcotest.(check string) + (Printf.sprintf "%s: Good Friday's own slug" (Date.to_iso8601 d)) + "ef-passiontide-2-friday" + (Slug.to_string t.Temporal.office.Cel.slug)) + !code_black + (* ---- RG 476(b) negative: a plain II-class saint, not Domini/BVM, not an Apostle/Evangelist ---- *) @@ -381,6 +463,12 @@ let suite = Alcotest.test_case "RG 23/476(a): Holy Thursday" `Quick test_holy_thursday_no_creed; Alcotest.test_case "RG 23/476(a): Holy Saturday / Easter Vigil" `Quick test_holy_saturday_easter_vigil_no_creed; + Alcotest.test_case "476(f): All Souls' Day (transferred), a Requiem, no Creed" `Quick + test_476f_all_souls_no_creed; + Alcotest.test_case "476(f)/RG 23(b): Good Friday, black, no Creed" `Quick + test_476f_good_friday_no_creed; + Alcotest.test_case "Colour.Black population is exactly two (data + code)" `Quick + test_colour_black_population_is_exactly_two; Alcotest.test_case "476(b): plain II-class saint (negative)" `Quick test_476b_plain_class2_saint; Alcotest.test_case "vigils excluded even when Class2 and Marian" `Quick -- cgit v1.3 From 72dd2426f020f83a392158ead7bd15b36088fd08 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Sat, 22 Aug 2026 14:51:07 +0200 Subject: test(lms-ordo): extend the LMS witness layer from one year to three Generalises tools/extract_lms_ordo.ml's start-of-body detection: the hardcoded "End of November 2024" sentinel assumed every edition opens with an "End of November" stub section. The 2023-2024 edition has none (Advent Sunday 2023 fell on 3 December, so the compiler folded the two tail days into the "December 2023" header directly) -- the generalised detector anchors on the body's own "ORDO" title line instead, verified unique in all three known editions and distinct from the Table of Contents' lowercase "Ordo" entries. Extracts test/fixtures/lms-ordo-2023-2024.sexp (397 rows) and lms-ordo-2025-2026.sexp (399 rows), each with a provenance header carrying its own SHA-256, source citation, and a per-edition characterisation record: five opposite-prediction Creed probes, independently re-verified against this run's own extracted rows (a failed probe is now a hard die, not a printed claim). The 2025-2026 edition needed a different sharp II-class pairing than 2024-2025's Joachim/Stephen one, because Joachim (16 August) is impeded by a Sunday that year -- recorded in the fixture header, not silently swapped. test/test_lms_ordo.ml is refactored into a parameterised make_suite, instantiated once per edition; every count Task 6 hardcoded against the single 2024-2025 window is now a per-edition parameter, several of which turned out to differ once measured (BVM-Saturday population 12/14/13, Ascension-week exclusion 1/3/2). Two mapping gaps surfaced only by the new windows and fixed here (test-side, not colitur): Low Sunday reached via Preceding_sunday for the first time (absent from 2024-2025's own window), and the Ascension-week exclusion was wrongly keyed off week number alone -- Rogation Monday also resumes week 6's Sunday but falls BEFORE Ascension, not after, and the Ordo prints the ordinary Sunday text there. Re-bounded by date, against Ascension and Pentecost. Two genuine divergences surfaced in the 2023-2024 window and are allow-listed (L3, L4) rather than fixed, per this task's no-lib-changes scope: - L3 (verdict ordo): colitur has no bissextile calendar rule. The 1962 Missal's own calendarium moves St Matthias from 24 to 25 February in leap years (docs/research/LT.txt:5011); colitur keeps him on the 24th every year. Domain-wide upper bound measured with a throwaway sweep: 1,650 of 2,041 leap years in 1583-9999 currently observe him there. - L4 (verdict open): Christmas Eve falling on the 4th Sunday of Advent (2023-12-24, roughly 1 year in 7). colitur says the Creed is said, reading RG 475(a)'s Sunday clause; the Ordo says it is not. RG 30(a)'s own "locum tenet ... nulla fit commemoratio" for this exact vigil reads like RG 16(a)'s Feast-of-the-Lord-on-Sunday shape, which colitur already treats as Creed-preserving -- but RG 475(a) names "festo" specifically, and a vigil is its own liturgical-day category (RG 35), so the counter-reading is real too. Left open rather than adjudicated. All 630 tests green (dune test), 631 with the exhaustive sweep. Claude-Session: https://claude.ai/code/session_017ZBxCCRM2ojnBupp3SBxV9 --- data/ef/expected-divergences-lms.sexp | 54 +- test/dune | 2 + test/fixtures/lms-ordo-2023-2024.sexp | 1507 ++++++++++++++++++++++++++++++++ test/fixtures/lms-ordo-2025-2026.sexp | 1511 +++++++++++++++++++++++++++++++++ test/test_colitur.ml | 4 +- test/test_lms_ordo.ml | 825 +++++++++--------- tools/extract_lms_ordo.ml | 251 ++++-- 7 files changed, 3672 insertions(+), 482 deletions(-) create mode 100644 test/fixtures/lms-ordo-2023-2024.sexp create mode 100644 test/fixtures/lms-ordo-2025-2026.sexp (limited to 'data/ef') diff --git a/data/ef/expected-divergences-lms.sexp b/data/ef/expected-divergences-lms.sexp index e327419..3850fd5 100644 --- a/data/ef/expected-divergences-lms.sexp +++ b/data/ef/expected-divergences-lms.sexp @@ -1,6 +1,11 @@ ; data/ef/expected-divergences-lms.sexp -- Task 6 (2026-08-21-colitur- ; celebrant-rubrics-phase1)'s cited allow-list for the LMS Ordo comparison -; (test/test_lms_ordo.ml), fixture window 2024-11-27..2025-12-31. +; (test/test_lms_ordo.ml). Extended by the Witnesses task (2026-08-22, +; same phase) from the single 2024-2025 window (2024-11-27..2025-12-31) +; to three: 2023-2024 (2023-12-01..2024-12-31) and 2025-2026 +; (2025-11-28..2026-12-31) joined it. L3/L4 below fired only in the +; 2023-2024 window -- neither recurs in the other two, a fact worth +; keeping visible rather than merging away (see [expected_rows] on each). ; ; A SEPARATE file from data/ef/expected-divergences.sexp (the lectio ; allow-list) and data/ef/expected-divergences-missalemeum.sexp (the @@ -96,15 +101,44 @@ ; shape as the Christmastide "infra octavam Nativitatis" entries ; data/ef/lectionary.sexp already carries directly rather than resolving ; through this fallback -- a lectionary-data change out of a fix round's -; own scope. test/test_lms_ordo.ml's own -; [expected_preceding_sunday_override] excludes exactly these two -; (season, week) pairs from its general mapping, and -; [test_formulary_override_matches] asserts the excluded population is -; exactly 3 real days, all showing "Mass of the Ascension", so a change -; to this population (a fourth day, a different Ordo string) would be -; caught rather than silently absorbed. +; own scope. test/test_lms_ordo.ml's own [is_after_ascension] excludes +; this population from the general mapping (bounded ABOVE by Pentecost, +; not merely "later than Ascension" -- see its own citation, corrected +; during the Witnesses task after a first version manufactured 8 false +; failures by matching any later date in the same civil year), and +; [test_formulary_override_matches] asserts its exact size per window. +; +; CORRECTED (Witnesses task, 2026-08-22): this note previously said "exactly +; 3 real days" as though that were a universal count. Extending the +; comparison to 2023-2024 and 2025-2026 showed it is not -- the population +; depends on which OTHER days that particular year's Ascension-adjacent +; week happen to have their own competing propers (a saint, a vigil), so +; it varies year to year: 3 in 2024-2025, 1 in 2023-2024 (only 30 May 2024 +; -- Rogation Monday, 6 May 2024, is BEFORE Ascension and correctly resumes +; the ordinary "5th Sunday after Easter" instead, once the exclusion's own +; date comparison was corrected to test "after Ascension AND before +; Pentecost" rather than "week 6 or 7"), 2 in 2025-2026. All three counts +; measured directly, all showing "Mass of the Ascension", none unexplained. ; ; Domain-wide count: unmeasured -- "which feria is inside Ascension's own ; after-feast period" is not a distinct predicate anywhere in this -; codebase to sweep on. Structurally recurs every year, so on the order -; of 3 days/year x domain years, not merely 3 total. +; codebase to sweep on. Structurally recurs every year, though the exact +; per-year count is now known to vary (1-3 in the three years measured), +; not a flat "3 days/year". + +; L3 -- OPEN, colitur's OWN genuine gap, found extending this suite to the +; 2023-2024 window (Witnesses task, 2026-08-22). Fired once: 2024-02-24. +((id L3) + (citation "The Missale Romanum's own CALENDARIUM table, February, footnote (docs/research/LT.txt:5011-5013, the Missal's printed calendar pages, not the numbered Rubricae Generales chapters): \"In anno bissextili mensis februarius est dierum 29, et festum S. Matthiae celebratur die 25 februarii, ac festum S. Gabrielis a Virgine perdolente 28 februarii, et bis dicitur sexto calendas, id est die 24 et die 25\" -- in a leap year February has 29 days, and the feast of St Matthias is kept on 25 February (not 24), with 24 and 25 February BOTH called \"the 6th kalends\"; St Gabriel of Our Lady of Sorrows (ordinarily 27 February) shifts to 28 February by the same rule. This bissextile shift is not RG-numbered (it is a calendarium footnote, not a Rubricae Generales paragraph) and is NOT scan-verified in this session -- only the LT.txt transcription was checked; scan1.txt/scan2.txt were searched for \"bissext\"/\"Matth\" and turned up only the unrelated Golden-Number/dominical-letter passage, not this specific calendarium footnote, so this citation rests on the transcription alone.") + (verdict ordo) + (note "colitur has NO bissextile-shift rule anywhere (grepped lib/rites/rite_ef/*.ml and data/ef/*.sexp for \"bissext\"/\"leap\": zero hits outside a code comment naming the saint, and the rules-register.md itself is silent on it too) -- St Matthias stays fixed at 24 February every year, leap or not. 2024 is a leap year: colitur's own [matthias] entry (Class2, an Apostle, RG91 entry 16 -- verified from the table itself to genuinely OUTRANK entry 18's privileged Ember-Saturday-of-Lent feria, so colitur's RANKING logic is not at fault here) WINS 24 February 2024 outright in colitur's output, correctly saying the Creed per RG475(e)'s Apostle clause. The Ordo shows no St Matthias anywhere near this date at all: 24 February 2024 is titled plainly \"EMBER SATURDAY of LENT\" (No Cr) and 25 February 2024 (a Sunday, 2nd Sunday in Lent, I class) is titled plainly \"2nd SUNDAY in LENT\" (Cr, but via RG475(a)'s own Sunday clause, not RG475(e)) -- consistent with Matthias having correctly MOVED to the 25th and then lost outright to the I-class Sunday there (RG91 entry 6 over entry 16), never even surviving as a commemoration (an I-class Sunday's own admission cap, RG111, is tight enough to exclude an ordinary II-class saint entirely -- the same shape already established for RG16(a)-adjacent cases elsewhere in this project). Both the 24th and 25th sides of the Ordo's silence are explained by ONE root cause (the missing shift), not two independent gaps -- a coherent, single-cause account, not a coincidence. BLAST RADIUS, roughly measured (a throwaway domain sweep, tools/probe_matthias.ml, run once for this task and not committed): of 2 041 leap years in 1583-9999, colitur observes [matthias] on 24 February in 1 650 of them -- an UPPER BOUND on how many years this gap could affect (some of those 1 650 years may see IDENTICAL final output either way, e.g. if Matthias would also win on the 25th against whatever competes there that year; a precise count needs the shift actually implemented, which is out of this task's own no-lib-changes scope). The Gabriel/27-28 February sibling shift is not witnessed by this fixture at all (no divergence on either date in this window) but is the same root cause and would need the same fix.") + (expected_rows 1)) + +; L4 -- OPEN, adjudicated FOR colitur (a defensible primary-source reading, +; not a fix confirmed against the Ordo -- the Ordo's own contrary reading is +; also textually arguable, see below). Fired once: 2023-12-24. +((id L4) + (citation "RG 30(a) (Caput V, De Vigiliis, docs/research/LT.txt:959-961): \"vigilia Nativitatis Domini quae, IN OCCURRENTIA, locum tenet dominicae IV Adventus, de qua, proinde, NULLA FIT COMMEMORATIO\" -- the Vigil of the Nativity, when it occurs [on a Sunday], TAKES THE PLACE of the 4th Sunday of Advent, of which, accordingly, no commemoration is made -- the identical \"locum tenet ... nulla fit commemoratio\" shape RG16(a) uses for a Feast of the Lord occurring on a II-class Sunday, which colitur already implements and which RG475(a) explicitly extends the Creed to (\"in qualibet dominica, etsi eius Officium alicui festo locum cedat\").") + (verdict open) + (note "2023-12-24 (the 4th Sunday of Advent AND Christmas Eve, a genuinely rare coincidence -- roughly 1 year in 7 -- absent from both the 2024-2025 and 2025-2026 windows, where Christmas Eve falls on a Tuesday and a Wednesday respectively). colitur says the Creed IS said (true), reading [temporal]'s own weekday (Sunday) per RG475(a)'s clause, positioned ahead of the vigil-exclusion check in {!Rite_ef.Rubrics_ef.creed} -- unconditionally, the same way it already does for RG16(a)'s Feast-of-the-Lord case. The Ordo says \"No Gl No Cr\" for this date. ADJUDICATED FOR COLITUR, not merely left open by default: RG30(a)'s own \"locum tenet ... nulla fit commemoratio\" language is textually closer to RG16(a) (which colitur already treats as Creed-preserving) than to an ordinary vigil superseding a Sunday -- the Vigil does not merely WIN THE DAY, it takes the SUNDAY'S OWN IDENTITY, the same shape RG475(a) was written to reach. The COUNTER-reading is real and not dismissed here: RG475(a)'s own text says \"locum cedat ... festo\" (gives way to a FEAST), and RG35 (Caput VI) classifies feria/vigilia/festum as three distinct liturgical-day categories -- a strict textual reading could confine 475(a)'s override to FEAST-displacement only, leaving a VIGIL-displaced Sunday to fall through to the general vigil exclusion (476, via RG33's own \"a vigil is a distinct category\" reasoning already coded elsewhere in {!Rite_ef.Rubrics_ef.creed}). Left OPEN rather than closed on this task's own authority: adjudicating scripture-grade primary-source questions is out of scope for a witness-wiring task, and the two readings are both defensible. Not fixable inside this task's own no-lib-changes constraint regardless of which reading eventually wins.") + (expected_rows 1)) diff --git a/test/dune b/test/dune index 44318a2..17865c4 100644 --- a/test/dune +++ b/test/dune @@ -17,7 +17,9 @@ fixtures/missalemeum-ef-2026-2027.txt fixtures/missalemeum-ef-2038.txt fixtures/missalemeum-ef-2035.txt + fixtures/lms-ordo-2023-2024.sexp fixtures/lms-ordo-2024-2025.sexp + fixtures/lms-ordo-2025-2026.sexp ../templates/ef/ordo.tex ../templates/ef/ordo.ms ../templates/ef/ordo.html diff --git a/test/fixtures/lms-ordo-2023-2024.sexp b/test/fixtures/lms-ordo-2023-2024.sexp new file mode 100644 index 0000000..9261ce7 --- /dev/null +++ b/test/fixtures/lms-ordo-2023-2024.sexp @@ -0,0 +1,1507 @@ +; test/fixtures/lms-ordo-2023-2024.sexp -- Witnesses task (2026-08-22-colitur-celebrant-rubrics-phase1), +; extending Task 6's single LMS fixture (2024-2025) to three editions of +; the Latin Mass Society's own printed Ordo for England & Wales -- a +; lineage independent of Divinum Officium/missalemeum/lectio (layers 3-4) +; and of the electronic LT.txt transcription (layers 1-2/5): a physically +; printed, professionally-compiled liturgical calendar with its own ISBN. +; +; Generator: tools/extract_lms_ordo.ml -- do not hand-edit; re-run against +; a fresh pdftotext dump and commit the diff instead. +; +; Source: "The Ordo 2023-2024", compiled by Peter Day-Milne, The Latin +; Mass Society, 9 Mallow Street, London EC1Y 8RQ (title page and +; colophon, verified directly against the PDF's own extracted text -- +; ISBN 978-1-7392096-2-9, Copyright (c) The Latin Mass Society, UK 2023). +; PDF metadata: Author "Peter Day-Milne", Producer "LibreOffice 6.4", CreationDate 2023-11-01, 140 pages. +; URL (identified 2026-08-22 via web search matching the PDF's own edition year to the publisher's own hosting path; NOT independently re-downloaded and byte-compared in this session -- recorded honestly rather than presented as verified): +; https://lms.org.uk/sites/default/files/u5374/ordo_2023-2024_2.2_final.pdf +; The local PDF (docs/research/ordo/lms-ordo-2023-2024.pdf) is gitignored +; (CLAUDE.md: "docs/ is gitignored"), so this header, not git, is this +; fixture's only record of where it came from. +; SHA-256 of docs/research/ordo/lms-ordo-2023-2024.pdf: 805a021bab246212c09a91706a04f4834fba052104de091b2fc5ed77c455bbba +; Extracted (UTC): 2026-08-22 +; Exact commands: +; pdftotext -layout docs/research/ordo/lms-ordo-2023-2024.pdf /tmp/lms.txt +; dune exec tools/extract_lms_ordo.exe -- /tmp/lms.txt \ +; docs/research/ordo/lms-ordo-2023-2024.pdf test/fixtures/lms-ordo-2023-2024.sexp +; +; COVERAGE: 397 day-rows, 2023-12-01 through 2024-12-31 (starting 1 December 2023 (this edition carries NO "End of November" stub section at all -- Advent Sunday 2023 fell on 3 December, so only 2 tail days of the prior liturgical year remained, and the compiler folded them directly into the "December 2023" header instead of giving them their own mini-section; see CHARACTERISATION below), +; through the day before a malformed trailing entry the extractor +; deliberately stops before -- see CHARACTERISATION below). +; +; CHARACTERISATION FINDINGS (Step 1, non-negotiable per the task brief -- +; the extraordinaryform.org Ordo silently omitted St Lawrence's vigil on +; EVERY date it covered, which nearly produced a false corroboration +; during the RG 33 work; every LMS edition, including this one, is probed +; with the same discipline before a single divergence is adjudicated): +; +; 1. Gl/Cr are printed PER MASS-OPTION, not per day (confirmed again for +; THIS edition: it carries many more Gl/Cr pairs than day-rows, because +; every diocesan variant repeats its own "Gl ... Cr ... Pr of ..." +; line). This extractor resolves the day's OWN office by taking the +; FIRST Gl/Cr pair in reading order, which the source's own layout +; guarantees is the universal entry's (diocesan variants are always +; introduced by a colon-terminated diocese-list line that comes AFTER +; the universal block, never before -- checked structurally, not +; assumed, in every sampled block during development, this edition +; included). +; +; 2. OPPOSITE-PREDICTION PROBES against Rite_ef.Rubrics_ef.creed (RG +; 475-476), RE-CHECKED BY THIS TOOL RUN (not merely copied from a prior +; edition's findings) before a single row of this fixture is trusted -- +; the technique CLAUDE.md records as the one that catches a source +; silently omitting the very thing it is meant to witness. This run's +; own extracted [rows] were checked against every one of the following +; before this header was even written; a failure here is a hard [die], +; not a printed claim: +; 2023-12-03 (Advent Sunday, RG 475(a)) -> TRUE +; 2023-12-04 (St Peter Chrysologus, III class, ordinary Advent day, RG 476(b)/(d)) -> FALSE +; 2023-12-26 (St Stephen, II class, inside the Nativity octave, RG 475(d)) -> TRUE +; 2024-08-15 (the Assumption, I class, RG 475(b)) -> TRUE +; 2024-08-16 (St Joachim, II class, no Lord/BVM/apostle clause applies, RG 476(b)) -> FALSE +; All 5 predictions confirmed, both directions (TRUE and FALSE each +; independently witnessed) -- this edition is discriminating, not a +; constant, on the Creed. +; +; 3. The BVM-Saturday roman numeral (I-V, "Missae de sancta Maria in +; sabbato", RG 309(a)) is anchored by WHOLE-LINE match against the five +; literal strings below, NEVER by substring search: "V Mass of BVM" is +; a substring of "IV Mass of BVM", so a naive `contains` check +; misreads every fourth-Mass day as the fifth (the coordinator's own +; misreading, recorded and retracted in commit 27b07b4 before Task 6 +; existed; the same anchoring logic runs unchanged for every edition). +; +; 4. SCOPE EXCLUDED, quantified, not silently dropped: +; - Diocesan variants: present on 159 of 397 days (40.1%) -- their own +; text is read only far enough to set [has_diocesan_variant], +; never compared, because colitur computes the UNIVERSAL General +; Roman Calendar only, with no diocesan overlay loaded. +; - The single malformed trailing entry ("...The OCTAVE DAY of the +; NATIVITY..." with a bare 4-digit token where a weekday+day-number +; pair belongs) is excluded outright: the extractor's own stop +; marker (a line whose first token is a bare 4-digit token) halts +; the scan before it. CONFIRMED IDENTICAL, word for word, across +; ALL FOUR known editions of this publisher's Ordo (2023-2024, +; 2024-2025, 2025-2026, and the 2024-2025 fixture's own prior +; header) -- always the literal stray year token "2025", regardless +; of which edition or which real trailing year it should read: a +; stale copy-paste leftover the compiler's own master document +; carries forward unedited release to release (even the 2024-2025 +; PDF's own tail page footer nearby still reads "Latin Mass Society +; Ordo 2021-2022"), not something specific to this edition. +; - Front matter, the Abbreviations/Rubrical-Primer/Breviary sections, +; and the "When may I say...?"/Appendix tail are never scanned at +; all (the extractor's own start/stop markers bound it to the Ordo +; proper). +(((date 2023-12-01) (weekday Fri) (title "FERIA IV Cl G \226\128\161 SH") + (formulary_override ("Mass of 24th & Last Sunday After Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2023-12-02) (weekday Sat) + (title "St BIBIANA V M III Cl R # IH JCHP") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2023-12-03) (weekday Sun) (title "ADVENT SUNDAY I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2023-12-04) (weekday Mon) + (title "St PETER CHRYSOLOGUS B C D III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2023-12-05) (weekday Tue) (title "FERIA III Cl V") + (formulary_override ("Mass of Advent Sunday")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant true)) + ((date 2023-12-06) (weekday Wed) (title "St NICOLAS B C III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2023-12-07) (weekday Thu) + (title "St AMBROSE B C D III Cl (Priv.) W JCHP*") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2023-12-08) (weekday Fri) + (title "The IMMACULATE CONCEPTION of the BVM I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2023-12-09) (weekday Sat) (title "FERIA III Cl V") + (formulary_override ("Mass of Advent Sunday")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant true)) + ((date 2023-12-10) (weekday Sun) (title "2nd SUNDAY of ADVENT I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2023-12-11) (weekday Mon) + (title "St DAMASUS I P C III Cl (Priv.) W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2023-12-12) (weekday Tue) (title "FERIA III Cl V") + (formulary_override ("Mass of 2nd Sunday of Advent")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant false)) + ((date 2023-12-13) (weekday Wed) (title "St LUCY V M III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2023-12-14) (weekday Thu) (title "FERIA III Cl V") + (formulary_override ("Mass of 2nd Sunday of Advent")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant false)) + ((date 2023-12-15) (weekday Fri) (title "FERIA III Cl V") + (formulary_override ("Mass of 2nd Sunday of Advent")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant false)) + ((date 2023-12-16) (weekday Sat) (title "St EUSEBIUS B M III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2023-12-17) (weekday Sun) + (title "3rd SUNDAY of ADVENT (GAUDETE SUNDAY) I Cl V/Rose") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2023-12-18) (weekday Mon) (title "FERIA II Cl V") + (formulary_override ("Mass of 3rd Sunday of Advent (Gaudete Sunday)")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2023-12-19) (weekday Tue) (title "FERIA II Cl V") + (formulary_override ("Mass of 3rd Sunday of Advent (Gaudete Sunday)")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2023-12-20) (weekday Wed) + (title "EMBER WEDNESDAY of ADVENT II Cl V") (formulary_override ()) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2023-12-21) (weekday Thu) (title "St THOMAS \194\167 Ap II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2023-12-22) (weekday Fri) (title "EMBER FRIDAY of ADVENT II Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2023-12-23) (weekday Sat) (title "EMBER SATURDAY of ADVENT II Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2023-12-24) (weekday Sun) + (title "VIGIL of The NATIVITY of OUR LORD I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2023-12-25) (weekday Mon) (title "The NATIVITY of OUR LORD I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2023-12-26) (weekday Tue) + (title "St STEPHEN \194\167 Protomartyr II Cl R") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2023-12-27) (weekday Wed) + (title "St JOHN \194\167 Ap Evangelist II Cl W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2023-12-28) (weekday Thu) (title "The HOLY INNOCENTS MM II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2023-12-29) (weekday Fri) + (title "5th DAY within the OCTAVE of the NATIVITY II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2023-12-30) (weekday Sat) + (title "6th DAY within the OCTAVE of the NATIVITY II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2023-12-31) (weekday Sun) + (title "SUNDAY within the OCTAVE of the NATIVITY II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-01-01) (weekday Mon) + (title "The OCTAVE DAY of the NATIVITY of the LORD I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-01-02) (weekday Tue) + (title "The MOST HOLY NAME of JESUS II Cl W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-01-03) (weekday Wed) (title "FERIA IV Cl W \226\128\160") + (formulary_override + ("Mass of the Octave Day of the Nativity of the Lord")) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-01-04) (weekday Thu) (title "FERIA IV Cl W \226\128\160 JCHP") + (formulary_override + ("Mass of the Octave Day of the Nativity of the Lord")) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-01-05) (weekday Fri) (title "FERIA IV Cl W \226\128\160 SH") + (formulary_override + ("Mass of the Octave Day of the Nativity of the Lord")) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-01-06) (weekday Sat) (title "The EPIPHANY I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-01-07) (weekday Sun) + (title "The HOLY FAMILY of JESUS, MARY AND JOSEPH II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-01-08) (weekday Mon) (title "FERIA IV Cl W \226\128\160") + (formulary_override ("Mass of 1st Sunday after the Epiphany")) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-01-09) (weekday Tue) (title "FERIA IV Cl W \226\128\160") + (formulary_override ("Mass of 1st Sunday after the Epiphany")) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-01-10) (weekday Wed) (title "FERIA IV Cl W \226\128\160") + (formulary_override ("Mass of 1st Sunday after the Epiphany")) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-01-11) (weekday Thu) (title "FERIA IV Cl W \226\128\160") + (formulary_override ("Mass of 1st Sunday after the Epiphany")) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-01-12) (weekday Fri) (title "FERIA IV Cl W \226\128\160") + (formulary_override ("Mass of 1st Sunday after the Epiphany")) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-01-13) (weekday Sat) (title "The BAPTISM of OUR LORD II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-01-14) (weekday Sun) + (title "2nd SUNDAY after the EPIPHANY II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-01-15) (weekday Mon) + (title "St PAUL the FIRST HERMIT C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-01-16) (weekday Tue) (title "St MARCELLUS I P M III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-01-17) (weekday Wed) (title "St ANTHONY Ab III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-01-18) (weekday Thu) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 2nd Sunday after the Epiphany")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-01-19) (weekday Fri) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 2nd Sunday after the Epiphany")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-01-20) (weekday Sat) + (title "SS FABIAN P & SEBASTIAN M III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-01-21) (weekday Sun) + (title "3rd SUNDAY after the EPIPHANY II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-01-22) (weekday Mon) + (title "SS VINCENT & ANASTASIUS MM III Cl R #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-01-23) (weekday Tue) + (title "St RAYMUND of PENAFORT C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-01-24) (weekday Wed) (title "St TIMOTHY B M III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-01-25) (weekday Thu) + (title "The CONVERSION of St PAUL \194\167 Ap III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-01-26) (weekday Fri) (title "St POLYCARP B M III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-01-27) (weekday Sat) + (title "St JOHN CHRYSOSTOM B C D III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-01-28) (weekday Sun) (title "SEPTUAGESIMA SUNDAY II Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-01-29) (weekday Mon) + (title "St FRANCIS de SALES B C D III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-01-30) (weekday Tue) (title "St MARTINA V M III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-01-31) (weekday Wed) (title "St JOHN BOSCO C III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-02-01) (weekday Thu) + (title "St IGNATIUS \194\167 B M III Cl (Priv.) R JCHP") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-02-02) (weekday Fri) + (title "The PURIFICATION of the BVM II Cl W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-02-03) (weekday Sat) + (title "CELEBRATION of the BVM IV Cl W \226\128\160 IH JCHP*") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-02-04) (weekday Sun) (title "SEXAGESIMA SUNDAY II Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-02-05) (weekday Mon) + (title "St AGATHA \194\167 V M III Cl (Priv.) R") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-02-06) (weekday Tue) (title "St TITUS B C III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-02-07) (weekday Wed) (title "St ROMUALD Ab III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-02-08) (weekday Thu) (title "St JOHN of MATHA C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-02-09) (weekday Fri) + (title "St CYRIL of ALEXANDRIA B C D III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-02-10) (weekday Sat) (title "St SCHOLASTICA V III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-02-11) (weekday Sun) (title "QUINQUAGESIMA SUNDAY II Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-02-12) (weekday Mon) + (title "The SEVEN HOLY FOUNDERS of the ORDER of the SERVANTS of the") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-02-13) (weekday Tue) (title "FERIA IV Cl V \226\128\161") + (formulary_override ("Mass of Quinquagesima Sunday")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant true)) + ((date 2024-02-14) (weekday Wed) (title "ASH WEDNESDAY I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-02-15) (weekday Thu) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-02-16) (weekday Fri) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-02-17) (weekday Sat) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-02-18) (weekday Sun) (title "1st SUNDAY in LENT I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-02-19) (weekday Mon) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-02-20) (weekday Tue) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-02-21) (weekday Wed) (title "EMBER WEDNESDAY of LENT II Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-02-22) (weekday Thu) + (title "The CHAIR of St PETER \194\167 Ap II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-02-23) (weekday Fri) (title "EMBER FRIDAY of LENT II Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-02-24) (weekday Sat) (title "EMBER SATURDAY of LENT II Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-02-25) (weekday Sun) (title "2nd SUNDAY in LENT I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-02-26) (weekday Mon) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-02-27) (weekday Tue) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-02-28) (weekday Wed) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-02-29) (weekday Thu) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-03-01) (weekday Fri) (title "FERIA III Cl V SH") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-03-02) (weekday Sat) (title "FERIA III Cl V IH JCHP") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-03-03) (weekday Sun) (title "3rd SUNDAY in LENT I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-03-04) (weekday Mon) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-03-05) (weekday Tue) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-03-06) (weekday Wed) + (title "SS PERPETUA \194\167 & FELICITY \194\167 MM III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-03-07) (weekday Thu) + (title "St THOMAS AQUINAS C D III Cl (Priv.) W JCHP") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-03-08) (weekday Fri) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-03-09) (weekday Sat) + (title "St FRANCES of ROME W III Cl (Priv.) W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-03-10) (weekday Sun) (title "4th SUNDAY in LENT I Cl V/Rose") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-03-11) (weekday Mon) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-03-12) (weekday Tue) + (title "St GREGORY I P C D III Cl (Priv.) W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-03-13) (weekday Wed) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-03-14) (weekday Thu) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-03-15) (weekday Fri) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-03-16) (weekday Sat) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-03-17) (weekday Sun) (title "PASSION SUNDAY I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-03-18) (weekday Mon) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-03-19) (weekday Tue) + (title "St JOSEPH \194\167 SPOUSE of the BVM C, PATRON of the UNIVERSAL") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-03-20) (weekday Wed) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-03-21) (weekday Thu) (title "St BENEDICT Ab III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-03-22) (weekday Fri) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-03-23) (weekday Sat) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-03-24) (weekday Sun) (title "PALM SUNDAY I Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-03-25) (weekday Mon) (title "MONDAY of HOLY WEEK I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-03-26) (weekday Tue) (title "TUESDAY of HOLY WEEK I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-03-27) (weekday Wed) (title "WEDNESDAY of HOLY WEEK I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-03-28) (weekday Thu) (title "MAUNDY THURSDAY I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-03-29) (weekday Fri) (title "GOOD FRIDAY I Cl B") + (formulary_override ()) (bvm_numeral ()) (gloria ()) (creed ()) + (has_diocesan_variant false)) + ((date 2024-03-30) (weekday Sat) (title "HOLY SATURDAY I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-03-31) (weekday Sun) (title "EASTER I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-04-01) (weekday Mon) (title "EASTER MONDAY I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-04-02) (weekday Tue) (title "EASTER TUESDAY I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-04-03) (weekday Wed) (title "EASTER WEDNESDAY I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-04-04) (weekday Thu) (title "EASTER THURSDAY I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-04-05) (weekday Fri) (title "EASTER FRIDAY I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-04-06) (weekday Sat) + (title "EASTER SATURDAY (SABBATO in ALBIS) I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-04-07) (weekday Sun) (title "LOW SUNDAY I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-04-08) (weekday Mon) + (title "The ANNUNCIATION of the BVM I Cl W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-04-09) (weekday Tue) (title "FERIA IV Cl W \226\128\161") + (formulary_override ("Mass of Low Sunday")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant true)) + ((date 2024-04-10) (weekday Wed) (title "FERIA IV Cl W \226\128\161") + (formulary_override ("Mass of Low Sunday")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant false)) + ((date 2024-04-11) (weekday Thu) (title "St LEO P C D III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-04-12) (weekday Fri) (title "FERIA IV Cl W \226\128\161") + (formulary_override ("Mass of Low Sunday")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant false)) + ((date 2024-04-13) (weekday Sat) (title "St HERMENEGILD M III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-04-14) (weekday Sun) (title "2nd SUNDAY after EASTER II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-04-15) (weekday Mon) (title "FERIA IV Cl W \226\128\161") + (formulary_override ("Mass of 2nd Sunday after Easter")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant false)) + ((date 2024-04-16) (weekday Tue) (title "FERIA IV Cl W \226\128\161") + (formulary_override ("Mass of 2nd Sunday after Easter")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant false)) + ((date 2024-04-17) (weekday Wed) (title "FERIA IV Cl W \226\128\161") + (formulary_override ("Mass of 2nd Sunday after Easter")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant true)) + ((date 2024-04-18) (weekday Thu) (title "FERIA IV Cl W \226\128\161") + (formulary_override ("Mass of 2nd Sunday after Easter")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant false)) + ((date 2024-04-19) (weekday Fri) (title "FERIA IV Cl W \226\128\161") + (formulary_override ("Mass of 2nd Sunday after Easter")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant true)) + ((date 2024-04-20) (weekday Sat) + (title "CELEBRATION of the BVM IV Cl W \226\128\160") + (formulary_override ("IV Mass of BVM")) (bvm_numeral (IV)) + (gloria (true)) (creed (false)) (has_diocesan_variant false)) + ((date 2024-04-21) (weekday Sun) (title "3rd SUNDAY after EASTER II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-04-22) (weekday Mon) + (title "SS SOTER & CAIUS PP MM III Cl R #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-04-23) (weekday Tue) (title "FERIA IV Cl W \226\128\161") + (formulary_override ("Mass of 3rd Sunday after Easter")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant true)) + ((date 2024-04-24) (weekday Wed) + (title "St FIDELIS of SIGMARINGEN M III Cl R #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-04-25) (weekday Thu) + (title "THE GREATER LITANIES. St MARK Evangelist II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-04-26) (weekday Fri) + (title "St CLETUS & MARCELLINUS PP MM III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-04-27) (weekday Sat) (title "St PETER CANISIUS C D III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-04-28) (weekday Sun) (title "4th SUNDAY after EASTER II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-04-29) (weekday Mon) (title "St PETER M III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-04-30) (weekday Tue) + (title "St CATHERINE of SIENNA V III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-05-01) (weekday Wed) + (title "St JOSEPH \194\167 the WORKER, SPOUSE of the BVM C I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-05-02) (weekday Thu) + (title "St ATHANASIUS B C D III Cl (Priv.) W JCHP") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-05-03) (weekday Fri) (title "FERIA IV Cl W \226\128\161 SH") + (formulary_override ("Mass of 4th Sunday after Easter")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant false)) + ((date 2024-05-04) (weekday Sat) + (title "St MONICA W III Cl (Priv.) W IH JCHP*") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-05-05) (weekday Sun) (title "5th SUNDAY after EASTER II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-05-06) (weekday Mon) (title "FERIA IV Cl W \226\128\161") + (formulary_override ("Mass of 5th Sunday after Easter")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant true)) + ((date 2024-05-07) (weekday Tue) (title "St STANISLAUS B M III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-05-08) (weekday Wed) (title "VIGIL of The ASCENSION II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-05-09) (weekday Thu) (title "The ASCENSION I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-05-10) (weekday Fri) (title "St ANTONINUS B C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-05-11) (weekday Sat) + (title "SS PHILIP \194\167 & JAMES \194\167 App II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-05-12) (weekday Sun) + (title "SUNDAY after the ASCENSION II Cl W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-05-13) (weekday Mon) + (title "St ROBERT BELLARMINE B C D III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-05-14) (weekday Tue) (title "FERIA IV Cl W \226\128\161") + (formulary_override ("Mass of the Ascension")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant true)) + ((date 2024-05-15) (weekday Wed) + (title "St JOHN BAPTIST de la SALLE C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-05-16) (weekday Thu) (title "St UBALDUS B C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-05-17) (weekday Fri) (title "St PASCHAL BAYLON C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-05-18) (weekday Sat) (title "VIGIL of PENTECOST I Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-05-19) (weekday Sun) (title "PENTECOST I Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-05-20) (weekday Mon) (title "WHIT MONDAY I Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-05-21) (weekday Tue) (title "WHIT TUESDAY I Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-05-22) (weekday Wed) + (title "WHIT WEDNESDAY (EMBER DAY) I Cl R") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-05-23) (weekday Thu) (title "WHIT THURSDAY I Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-05-24) (weekday Fri) (title "WHIT FRIDAY (EMBER DAY) I Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-05-25) (weekday Sat) (title "WHIT SATURDAY (EMBER DAY) I Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-05-26) (weekday Sun) (title "The MOST HOLY TRINITY I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-05-27) (weekday Mon) + (title "St BEDE the VENERABLE C D III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-05-28) (weekday Tue) (title "St AUGUSTINE B C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-05-29) (weekday Wed) + (title "St MARY MAGDALEN dei PAZZI V III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-05-30) (weekday Thu) (title "CORPUS CHRISTI I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-05-31) (weekday Fri) + (title "The BLESSED VIRGIN MARY, QUEEN II Cl W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-06-01) (weekday Sat) + (title "St ANGELA MERICI V III Cl W # IH JCHP") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-06-02) (weekday Sun) + (title "2nd SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-06-03) (weekday Mon) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 2nd Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-06-04) (weekday Tue) + (title "St FRANCIS CARACCIOLO C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-06-05) (weekday Wed) (title "St BONIFACE B M III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-06-06) (weekday Thu) (title "St NORBERT B C III Cl W # JCHP") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-06-07) (weekday Fri) (title "The SACRED HEART of JESUS I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-06-08) (weekday Sat) + (title "CELEBRATION of the BVM IV Cl W \226\128\160") + (formulary_override ("V Mass of BVM")) (bvm_numeral (V)) (gloria (true)) + (creed (false)) (has_diocesan_variant true)) + ((date 2024-06-09) (weekday Sun) + (title "3rd SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-06-10) (weekday Mon) (title "St MARGARET Q W III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-06-11) (weekday Tue) (title "St BARNABAS Ap III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-06-12) (weekday Wed) + (title "St JOHN of SAN FACONDO C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-06-13) (weekday Thu) + (title "St ANTHONY of PADUA C D III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-06-14) (weekday Fri) + (title "St BASIL the GREAT B C D III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-06-15) (weekday Sat) + (title "CELEBRATION of the BVM IV Cl W \226\128\160") + (formulary_override ("V Mass of BVM")) (bvm_numeral (V)) (gloria (true)) + (creed (false)) (has_diocesan_variant false)) + ((date 2024-06-16) (weekday Sun) + (title "4th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-06-17) (weekday Mon) + (title "St GREGORY BARBARIGO B C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-06-18) (weekday Tue) + (title "St EPHREM the SYRIAN Deacon C D III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-06-19) (weekday Wed) + (title "St JULIANA FALCONIERI V III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-06-20) (weekday Thu) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 4th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-06-21) (weekday Fri) + (title "St ALOYSIUS GONZAGA C III Cl (Priv.) W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-06-22) (weekday Sat) (title "St PAULINUS B C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-06-23) (weekday Sun) + (title "5th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-06-24) (weekday Mon) + (title "The NATIVITY of JOHN the BAPTIST \194\167 I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-06-25) (weekday Tue) (title "St WILLIAM Ab III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-06-26) (weekday Wed) + (title "SS JOHN & PAUL \194\167 MM III Cl R #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-06-27) (weekday Thu) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 5th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-06-28) (weekday Fri) + (title "VIGIL of SS PETER \194\167 & PAUL \194\167 App II Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-06-29) (weekday Sat) + (title "SS PETER \194\167 & PAUL \194\167 App I Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-06-30) (weekday Sun) + (title "6th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-07-01) (weekday Mon) + (title "The MOST PRECIOUS BLOOD of OUR LORD JESUS CHRIST I Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-07-02) (weekday Tue) + (title "The VISITATION of the BVM II Cl W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-07-03) (weekday Wed) (title "St IRENAEUS B M III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-07-04) (weekday Thu) (title "FERIA IV Cl G \226\128\161 JCHP") + (formulary_override ("Mass of 6th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-07-05) (weekday Fri) + (title "St ANTHONY MARY ZACCARIA C III Cl W # SH") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-07-06) (weekday Sat) + (title "CELEBRATION of the BVM IV Cl W \226\128\160 IH JCHP*") + (formulary_override ("V Mass of BVM")) (bvm_numeral (V)) (gloria (true)) + (creed (false)) (has_diocesan_variant false)) + ((date 2024-07-07) (weekday Sun) + (title "7th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-07-08) (weekday Mon) (title "St ELIZABETH Q W III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-07-09) (weekday Tue) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 7th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-07-10) (weekday Wed) + (title "The SEVEN HOLY BROTHERS MM & SS RUFINA & SECUNDA VV MM III") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-07-11) (weekday Thu) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 7th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-07-12) (weekday Fri) (title "St JOHN GUALBERTI Ab III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-07-13) (weekday Sat) + (title "CELEBRATION of the BVM IV Cl W \226\128\160") + (formulary_override ("V Mass of BVM")) (bvm_numeral (V)) (gloria (true)) + (creed (false)) (has_diocesan_variant false)) + ((date 2024-07-14) (weekday Sun) + (title "8th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-07-15) (weekday Mon) (title "St HENRY Emperor C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-07-16) (weekday Tue) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 8th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-07-17) (weekday Wed) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 8th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-07-18) (weekday Thu) + (title "St CAMILLUS de LELLIS C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-07-19) (weekday Fri) + (title "St VINCENT de PAUL C III Cl (Priv.) W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-07-20) (weekday Sat) (title "St JEROME EMILIANI C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-07-21) (weekday Sun) + (title "9th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-07-22) (weekday Mon) + (title "St MARY MAGDALEN Penitent III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-07-23) (weekday Tue) (title "St APOLLINARIS B M III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-07-24) (weekday Wed) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 9th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-07-25) (weekday Thu) (title "St JAMES \194\167 Ap II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-07-26) (weekday Fri) + (title "St ANNE MOTHER of the BVM II Cl W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-07-27) (weekday Sat) + (title "CELEBRATION of the BVM IV Cl W \226\128\160") + (formulary_override ("V Mass of BVM")) (bvm_numeral (V)) (gloria (true)) + (creed (false)) (has_diocesan_variant false)) + ((date 2024-07-28) (weekday Sun) + (title "10th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-07-29) (weekday Mon) (title "St MARTHA V III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-07-30) (weekday Tue) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 10th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-07-31) (weekday Wed) (title "St IGNATIUS C III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-08-01) (weekday Thu) (title "FERIA IV Cl G \226\128\161 JCHP") + (formulary_override ("Mass of 10th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-08-02) (weekday Fri) + (title "St ALPHONSUS MARIA LIGUORI B C D III Cl (Priv.) W SH") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-08-03) (weekday Sat) + (title "CELEBRATION of the BVM IV Cl W \226\128\160 IH JCHP*") + (formulary_override ("V Mass of BVM")) (bvm_numeral (V)) (gloria (true)) + (creed (false)) (has_diocesan_variant true)) + ((date 2024-08-04) (weekday Sun) + (title "11th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-08-05) (weekday Mon) + (title "The DEDICATION of St MARY of the SNOWS III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-08-06) (weekday Tue) + (title "The TRANSFIGURATION of OUR LORD JESUS CHRIST II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-08-07) (weekday Wed) (title "St CAJETAN C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-08-08) (weekday Thu) + (title "St JOHN MARY VIANNEY C III Cl (Priv.) W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-08-09) (weekday Fri) + (title "VIGIL of St LAURENCE \194\167 M III Cl V #") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-08-10) (weekday Sat) (title "St LAURENCE \194\167 M II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-08-11) (weekday Sun) + (title "12th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-08-12) (weekday Mon) (title "St CLARE V III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-08-13) (weekday Tue) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 12th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-08-14) (weekday Wed) + (title "VIGIL of The ASSUMPTION of the BVM II Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-08-15) (weekday Thu) (title "The ASSUMPTION of the BVM I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-08-16) (weekday Fri) + (title "St JOACHIM FATHER of the BVM C II Cl W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-08-17) (weekday Sat) (title "St HYACINTH C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-08-18) (weekday Sun) + (title "13th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-08-19) (weekday Mon) (title "St JOHN EUDES C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-08-20) (weekday Tue) (title "St BERNARD Ab D III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-08-21) (weekday Wed) + (title "St JANE FRANCES FREMIOT de CHANTAL W III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-08-22) (weekday Thu) + (title "The IMMACULATE HEART of the BVM II Cl W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-08-23) (weekday Fri) (title "St PHILIP BENIZI C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-08-24) (weekday Sat) + (title "St BARTHOLOMEW \194\167 Ap II Cl R") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-08-25) (weekday Sun) + (title "14th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-08-26) (weekday Mon) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 14th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-08-27) (weekday Tue) + (title "St JOSEPH CALASANCTIUS C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-08-28) (weekday Wed) + (title "St AUGUSTINE B C D III Cl (Priv.) W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-08-29) (weekday Thu) + (title "The BEHEADING of St JOHN the BAPTIST \194\167 III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-08-30) (weekday Fri) (title "St ROSE of LIMA V III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-08-31) (weekday Sat) (title "St RAYMUND NONNATUS C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-09-01) (weekday Sun) + (title "15th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-09-02) (weekday Mon) (title "St STEPHEN K C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-09-03) (weekday Tue) (title "St PIUS X P C III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-09-04) (weekday Wed) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 15th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-09-05) (weekday Thu) + (title "St LAURENCE JUSTINIAN B C III Cl W # JCHP") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-09-06) (weekday Fri) (title "FERIA IV Cl G \226\128\161 SH") + (formulary_override ("Mass of 15th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-09-07) (weekday Sat) + (title "CELEBRATION of the BVM IV Cl W \226\128\160 IH JCHP*") + (formulary_override ("V Mass of BVM")) (bvm_numeral (V)) (gloria (true)) + (creed (false)) (has_diocesan_variant false)) + ((date 2024-09-08) (weekday Sun) + (title "16th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-09-09) (weekday Mon) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 16th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-09-10) (weekday Tue) + (title "St NICOLAS of TOLENTINO C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-09-11) (weekday Wed) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 16th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-09-12) (weekday Thu) + (title "The MOST HOLY NAME of MARY III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-09-13) (weekday Fri) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 16th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-09-14) (weekday Sat) + (title "The EXALTATION of the HOLY CROSS II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-09-15) (weekday Sun) + (title "17th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-09-16) (weekday Mon) + (title + "SS CORNELIUS \194\167 P & CYPRIAN \194\167 B MM III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-09-17) (weekday Tue) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 17th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-09-18) (weekday Wed) + (title "EMBER WEDNESDAY of SEPTEMBER II Cl V") (formulary_override ()) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-09-19) (weekday Thu) + (title "St JANUARIUS B & COMPS MM III Cl R #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-09-20) (weekday Fri) + (title "EMBER FRIDAY of SEPTEMBER II Cl V") (formulary_override ()) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-09-21) (weekday Sat) + (title "St MATTHEW \194\167 Ap Evangelist II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-09-22) (weekday Sun) + (title "18th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-09-23) (weekday Mon) (title "St LINUS P M III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-09-24) (weekday Tue) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 18th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-09-25) (weekday Wed) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 18th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-09-26) (weekday Thu) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 18th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-09-27) (weekday Fri) + (title "SS COSMAS \194\167 & DAMIAN \194\167 MM III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-09-28) (weekday Sat) (title "St WENCESLAUS Duke M III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-09-29) (weekday Sun) + (title "The DEDICATION of St MICHAEL Archangel I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-09-30) (weekday Mon) + (title "St JEROME Priest C D III Cl (Priv.) W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-10-01) (weekday Tue) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 19th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-10-02) (weekday Wed) + (title "The HOLY GUARDIAN ANGELS III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-10-03) (weekday Thu) + (title "St TERESA of the CHILD JESUS V III Cl (Priv.) W JCHP") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-10-04) (weekday Fri) + (title "St FRANCIS of ASSISI C III Cl (Priv.) W SH") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-10-05) (weekday Sat) + (title "CELEBRATION of the BVM IV Cl W \226\128\160 IH JCHP*") + (formulary_override ("V Mass of BVM")) (bvm_numeral (V)) (gloria (true)) + (creed (false)) (has_diocesan_variant true)) + ((date 2024-10-06) (weekday Sun) + (title "20th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-10-07) (weekday Mon) (title "The BVM of the ROSARY II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-10-08) (weekday Tue) (title "St BRIDGET W III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-10-09) (weekday Wed) (title "St JOHN LEONARDI C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-10-10) (weekday Thu) (title "St FRANCIS BORGIA C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-10-11) (weekday Fri) + (title "The MOTHERHOOD of the BVM II Cl W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-10-12) (weekday Sat) + (title "CELEBRATION of the BVM IV Cl W \226\128\160") + (formulary_override ("V Mass of BVM")) (bvm_numeral (V)) (gloria (true)) + (creed (false)) (has_diocesan_variant true)) + ((date 2024-10-13) (weekday Sun) + (title "21st SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-10-14) (weekday Mon) + (title "St CALLISTUS I P M III Cl (Priv.) R") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-10-15) (weekday Tue) (title "St TERESA V III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-10-16) (weekday Wed) (title "St HEDWIG W III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-10-17) (weekday Thu) + (title "St MARGARET MARY ALACOQUE V III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-10-18) (weekday Fri) (title "St LUKE Evangelist II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-10-19) (weekday Sat) + (title "St PETER of ALCANTARA C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-10-20) (weekday Sun) + (title "22nd SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-10-21) (weekday Mon) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 22nd Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-10-22) (weekday Tue) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 22nd Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-10-23) (weekday Wed) + (title "St ANTHONY MARY CLARET B C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-10-24) (weekday Thu) (title "St RAPHAEL Archangel III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-10-25) (weekday Fri) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 22nd Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-10-26) (weekday Sat) + (title "CELEBRATION of the BVM IV Cl W \226\128\160") + (formulary_override ("V Mass of BVM")) (bvm_numeral (V)) (gloria (true)) + (creed (false)) (has_diocesan_variant true)) + ((date 2024-10-27) (weekday Sun) (title "CHRIST the KING I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-10-28) (weekday Mon) + (title "SS SIMON \194\167 & JUDE \194\167 Ap II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-10-29) (weekday Tue) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 23rd Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-10-30) (weekday Wed) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 23rd Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-10-31) (weekday Thu) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 23rd Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-11-01) (weekday Fri) (title "ALL SAINTS' DAY I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-11-02) (weekday Sat) (title "ALL SOULS' DAY I Cl B") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-11-03) (weekday Sun) + (title "4th SUNDAY remaining after the EPIPHANY II Cl G") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-11-04) (weekday Mon) (title "St CHARLES B C III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-11-05) (weekday Tue) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 4th Sunday remaining after the Epiphany")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-11-06) (weekday Wed) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 4th Sunday remaining after the Epiphany")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-11-07) (weekday Thu) (title "FERIA IV Cl G \226\128\161 JCHP") + (formulary_override ("Mass of 4th Sunday remaining after the Epiphany")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-11-08) (weekday Fri) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 4th Sunday remaining after the Epiphany")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-11-09) (weekday Sat) + (title "The DEDICATION of the ARCHBASILICA of OUR SAVIOUR II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-11-10) (weekday Sun) + (title "5th SUNDAY remaining after the EPIPHANY II Cl G") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-11-11) (weekday Mon) (title "St MARTIN B C III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-11-12) (weekday Tue) (title "St MARTIN I P M III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-11-13) (weekday Wed) (title "St DIDACUS C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-11-14) (weekday Thu) (title "St JOSAPHAT B M III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-11-15) (weekday Fri) + (title "St ALBERT the GREAT B C D III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-11-16) (weekday Sat) (title "St GERTRUDE V III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-11-17) (weekday Sun) + (title "6th SUNDAY remaining after the EPIPHANY II Cl G") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-11-18) (weekday Mon) + (title + "The DEDICATION of the BASILICAS of SS PETER & PAUL III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-11-19) (weekday Tue) (title "St ELIZABETH W III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-11-20) (weekday Wed) (title "St FELIX de VALOIS C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-11-21) (weekday Thu) + (title "The PRESENTATION of the BVM III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-11-22) (weekday Fri) + (title "St CECILIA \194\167 V M III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-11-23) (weekday Sat) + (title "St CLEMENT I \194\167 P M III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-11-24) (weekday Sun) + (title "24th & LAST SUNDAY After PENTECOST II Cl G") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-11-25) (weekday Mon) (title "St CATHERINE V M III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-11-26) (weekday Tue) (title "St SILVESTER Ab III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-11-27) (weekday Wed) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 24th & Last Sunday After Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-11-28) (weekday Thu) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 24th & Last Sunday After Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-11-29) (weekday Fri) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 24th & Last Sunday After Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-11-30) (weekday Sat) (title "St ANDREW \194\167 Ap II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-12-01) (weekday Sun) (title "ADVENT SUNDAY I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-12-02) (weekday Mon) (title "St BIBIANA V M III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-12-03) (weekday Tue) + (title "St FRANCIS XAVIER C III Cl (Priv.) W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-12-04) (weekday Wed) + (title "St PETER CHRYSOLOGUS B C D III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-12-05) (weekday Thu) (title "FERIA III Cl V JCHP") + (formulary_override ("Mass of Advent Sunday")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant true)) + ((date 2024-12-06) (weekday Fri) + (title "St NICOLAS B C III Cl (Priv.) W SH") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-12-07) (weekday Sat) + (title "St AMBROSE B C D III Cl (Priv.) W IH JCHP*") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-12-08) (weekday Sun) + (title "The IMMACULATE CONCEPTION of the BVM I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-12-09) (weekday Mon) (title "FERIA III Cl V") + (formulary_override ("Mass of 2nd Sunday of Advent")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant true)) + ((date 2024-12-10) (weekday Tue) (title "FERIA III Cl V") + (formulary_override ("Mass of 2nd Sunday of Advent")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant true)) + ((date 2024-12-11) (weekday Wed) + (title "St DAMASUS I P C III Cl (Priv.) W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2024-12-12) (weekday Thu) (title "FERIA III Cl V") + (formulary_override ("Mass of 2nd Sunday of Advent")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant false)) + ((date 2024-12-13) (weekday Fri) (title "St LUCY V M III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-12-14) (weekday Sat) (title "FERIA III Cl V") + (formulary_override ("Mass of 2nd Sunday of Advent")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant false)) + ((date 2024-12-15) (weekday Sun) + (title "3rd SUNDAY of ADVENT (GAUDETE SUNDAY) I Cl V/Rose") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-12-16) (weekday Mon) (title "St EUSEBIUS B M III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-12-17) (weekday Tue) (title "FERIA II Cl V") + (formulary_override ("Mass of 3rd Sunday of Advent (Gaudete Sunday)")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-12-18) (weekday Wed) + (title "EMBER WEDNESDAY of ADVENT II Cl V") (formulary_override ()) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-12-19) (weekday Thu) (title "FERIA II Cl V") + (formulary_override ("Mass of 3rd Sunday of Advent (Gaudete Sunday)")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-12-20) (weekday Fri) (title "EMBER FRIDAY of ADVENT II Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-12-21) (weekday Sat) (title "St THOMAS \194\167 Ap II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-12-22) (weekday Sun) (title "4th SUNDAY of ADVENT I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-12-23) (weekday Mon) (title "FERIA II Cl V") + (formulary_override ("Mass of 4th Sunday of Advent")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant false)) + ((date 2024-12-24) (weekday Tue) + (title "VIGIL of The NATIVITY of OUR LORD I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2024-12-25) (weekday Wed) (title "The NATIVITY of OUR LORD I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-12-26) (weekday Thu) + (title "St STEPHEN \194\167 Protomartyr II Cl R") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-12-27) (weekday Fri) + (title "St JOHN \194\167 Ap Evangelist II Cl W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-12-28) (weekday Sat) (title "The HOLY INNOCENTS MM II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-12-29) (weekday Sun) + (title "SUNDAY within the OCTAVE of the NATIVITY II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2024-12-30) (weekday Mon) + (title "6th DAY within the OCTAVE of the NATIVITY II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2024-12-31) (weekday Tue) + (title "7th DAY within the OCTAVE of the NATIVITY II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false))) diff --git a/test/fixtures/lms-ordo-2025-2026.sexp b/test/fixtures/lms-ordo-2025-2026.sexp new file mode 100644 index 0000000..7f8947e --- /dev/null +++ b/test/fixtures/lms-ordo-2025-2026.sexp @@ -0,0 +1,1511 @@ +; test/fixtures/lms-ordo-2025-2026.sexp -- Witnesses task (2026-08-22-colitur-celebrant-rubrics-phase1), +; extending Task 6's single LMS fixture (2024-2025) to three editions of +; the Latin Mass Society's own printed Ordo for England & Wales -- a +; lineage independent of Divinum Officium/missalemeum/lectio (layers 3-4) +; and of the electronic LT.txt transcription (layers 1-2/5): a physically +; printed, professionally-compiled liturgical calendar with its own ISBN. +; +; Generator: tools/extract_lms_ordo.ml -- do not hand-edit; re-run against +; a fresh pdftotext dump and commit the diff instead. +; +; Source: "The Ordo 2025-2026", compiled by Peter Day-Milne, The Latin +; Mass Society, 9 Mallow Street, London EC1Y 8RQ (title page and +; colophon, verified directly against the PDF's own extracted text -- +; ISBN 978-1-7392096-5-0, Copyright (c) The Latin Mass Society, UK 2025). +; PDF metadata: Author "Peter Day-Milne", Producer "LibreOffice 25.2.6.2 (X86_64) / LibreOffice Community", CreationDate 2025-10-23, 146 pages. +; URL (NOT found by URL-pattern web search this session (unlike the 2023-2024 and 2024-2025 editions, no exact download link matching this PDF's own filename/version turned up under lms.org.uk/sites/default/files/u5374/; several near-miss candidates were checked and rejected -- none matched this PDF's own metadata) -- left honestly blank rather than guessed; the file was supplied locally to this session, not fetched by this tool): +; (not found -- see the note on this line) +; The local PDF (docs/research/ordo/lms-ordo-2025-2026.pdf) is gitignored +; (CLAUDE.md: "docs/ is gitignored"), so this header, not git, is this +; fixture's only record of where it came from. +; SHA-256 of docs/research/ordo/lms-ordo-2025-2026.pdf: 3d71ad56af3fc8d9c1b37515bf9d946025961f8ef415c3b92520b9de7661f8a3 +; Extracted (UTC): 2026-08-22 +; Exact commands: +; pdftotext -layout docs/research/ordo/lms-ordo-2025-2026.pdf /tmp/lms.txt +; dune exec tools/extract_lms_ordo.exe -- /tmp/lms.txt \ +; docs/research/ordo/lms-ordo-2025-2026.pdf test/fixtures/lms-ordo-2025-2026.sexp +; +; COVERAGE: 399 day-rows, 2025-11-28 through 2026-12-31 (starting 28 November 2025 ("End of November 2025", the same shape as the 2024-2025 edition -- Advent Sunday 2025 fell on 30 November, so only 3 tail days remained; note this excludes 27 November 2025, which the PRECEDING edition's own window (2024-2025, through 2025-12-31) already covers -- a one-day-short overlap between consecutive editions' own windows, not a gap or a bug in either extraction, +; through the day before a malformed trailing entry the extractor +; deliberately stops before -- see CHARACTERISATION below). +; +; CHARACTERISATION FINDINGS (Step 1, non-negotiable per the task brief -- +; the extraordinaryform.org Ordo silently omitted St Lawrence's vigil on +; EVERY date it covered, which nearly produced a false corroboration +; during the RG 33 work; every LMS edition, including this one, is probed +; with the same discipline before a single divergence is adjudicated): +; +; 1. Gl/Cr are printed PER MASS-OPTION, not per day (confirmed again for +; THIS edition: it carries many more Gl/Cr pairs than day-rows, because +; every diocesan variant repeats its own "Gl ... Cr ... Pr of ..." +; line). This extractor resolves the day's OWN office by taking the +; FIRST Gl/Cr pair in reading order, which the source's own layout +; guarantees is the universal entry's (diocesan variants are always +; introduced by a colon-terminated diocese-list line that comes AFTER +; the universal block, never before -- checked structurally, not +; assumed, in every sampled block during development, this edition +; included). +; +; 2. OPPOSITE-PREDICTION PROBES against Rite_ef.Rubrics_ef.creed (RG +; 475-476), RE-CHECKED BY THIS TOOL RUN (not merely copied from a prior +; edition's findings) before a single row of this fixture is trusted -- +; the technique CLAUDE.md records as the one that catches a source +; silently omitting the very thing it is meant to witness. This run's +; own extracted [rows] were checked against every one of the following +; before this header was even written; a failure here is a hard [die], +; not a printed claim: +; 2025-11-30 (Advent Sunday, RG 475(a)) -> TRUE +; 2025-12-01 (ordinary Advent feria, RG 476(b)/(d)) -> FALSE +; 2025-12-26 (St Stephen, II class, inside the Nativity octave, RG 475(d)) -> TRUE +; 2026-08-10 (St Laurence, II class martyr, no Lord/BVM/apostle clause applies, RG 476(b) -- St Joachim (16 August) is IMPEDED by a Sunday in this edition's own calendar (12th Sunday after Pentecost), so this edition needed a DIFFERENT sharp non-octave II-class pairing than the 2023-2024/2024-2025 editions used; a real, edition-specific finding, not an extraction quirk) -> FALSE +; 2026-08-15 (the Assumption, I class, RG 475(b)) -> TRUE +; All 5 predictions confirmed, both directions (TRUE and FALSE each +; independently witnessed) -- this edition is discriminating, not a +; constant, on the Creed. +; +; 3. The BVM-Saturday roman numeral (I-V, "Missae de sancta Maria in +; sabbato", RG 309(a)) is anchored by WHOLE-LINE match against the five +; literal strings below, NEVER by substring search: "V Mass of BVM" is +; a substring of "IV Mass of BVM", so a naive `contains` check +; misreads every fourth-Mass day as the fifth (the coordinator's own +; misreading, recorded and retracted in commit 27b07b4 before Task 6 +; existed; the same anchoring logic runs unchanged for every edition). +; +; 4. SCOPE EXCLUDED, quantified, not silently dropped: +; - Diocesan variants: present on 163 of 399 days (40.9%) -- their own +; text is read only far enough to set [has_diocesan_variant], +; never compared, because colitur computes the UNIVERSAL General +; Roman Calendar only, with no diocesan overlay loaded. +; - The single malformed trailing entry ("...The OCTAVE DAY of the +; NATIVITY..." with a bare 4-digit token where a weekday+day-number +; pair belongs) is excluded outright: the extractor's own stop +; marker (a line whose first token is a bare 4-digit token) halts +; the scan before it. CONFIRMED IDENTICAL, word for word, across +; ALL FOUR known editions of this publisher's Ordo (2023-2024, +; 2024-2025, 2025-2026, and the 2024-2025 fixture's own prior +; header) -- always the literal stray year token "2025", regardless +; of which edition or which real trailing year it should read: a +; stale copy-paste leftover the compiler's own master document +; carries forward unedited release to release (even the 2024-2025 +; PDF's own tail page footer nearby still reads "Latin Mass Society +; Ordo 2021-2022"), not something specific to this edition. +; - Front matter, the Abbreviations/Rubrical-Primer/Breviary sections, +; and the "When may I say...?"/Appendix tail are never scanned at +; all (the extractor's own start/stop markers bound it to the Ordo +; proper). +(((date 2025-11-28) (weekday Fri) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 24th & Last Sunday After Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2025-11-29) (weekday Sat) + (title "OUR LADY on SATURDAY IV Cl W \226\128\160") + (formulary_override ("V Mass of BVM")) (bvm_numeral (V)) (gloria (true)) + (creed (false)) (has_diocesan_variant true)) + ((date 2025-11-30) (weekday Sun) (title "ADVENT SUNDAY I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2025-12-01) (weekday Mon) (title "FERIA III Cl V") + (formulary_override ("Mass of Advent Sunday")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant true)) + ((date 2025-12-02) (weekday Tue) (title "St BIBIANA V M III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2025-12-03) (weekday Wed) + (title "St FRANCIS XAVIER C III Cl (Priv.) W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2025-12-04) (weekday Thu) + (title "St PETER CHRYSOLOGUS B C D III Cl W # JCHP") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2025-12-05) (weekday Fri) (title "FERIA III Cl V SH") + (formulary_override ("Mass of Advent Sunday")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant true)) + ((date 2025-12-06) (weekday Sat) + (title "St NICOLAS B C III Cl (Priv.) W IH JCHP*") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2025-12-07) (weekday Sun) (title "2nd SUNDAY of ADVENT I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2025-12-08) (weekday Mon) + (title "The IMMACULATE CONCEPTION of the BVM I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2025-12-09) (weekday Tue) (title "FERIA III Cl V") + (formulary_override ("Mass of 2nd Sunday of Advent")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant true)) + ((date 2025-12-10) (weekday Wed) (title "FERIA III Cl V") + (formulary_override ("Mass of 2nd Sunday of Advent")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant true)) + ((date 2025-12-11) (weekday Thu) + (title "St DAMASUS I P C III Cl (Priv.) W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2025-12-12) (weekday Fri) (title "FERIA III Cl V") + (formulary_override ("Mass of 2nd Sunday of Advent")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant false)) + ((date 2025-12-13) (weekday Sat) (title "St LUCY V M III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2025-12-14) (weekday Sun) + (title "3rd SUNDAY of ADVENT (GAUDETE SUNDAY) I Cl V/Rose") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2025-12-15) (weekday Mon) (title "FERIA III Cl V") + (formulary_override ("Mass of 3rd Sunday of Advent (Gaudete Sunday)")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2025-12-16) (weekday Tue) (title "St EUSEBIUS B M III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2025-12-17) (weekday Wed) + (title "EMBER WEDNESDAY of ADVENT II Cl V") (formulary_override ()) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2025-12-18) (weekday Thu) (title "FERIA II Cl V") + (formulary_override ("Mass of 3rd Sunday of Advent (Gaudete Sunday)")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2025-12-19) (weekday Fri) (title "EMBER FRIDAY of ADVENT II Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2025-12-20) (weekday Sat) (title "EMBER SATURDAY of ADVENT II Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2025-12-21) (weekday Sun) (title "4th SUNDAY of ADVENT I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2025-12-22) (weekday Mon) (title "FERIA II Cl V") + (formulary_override ("Mass of 4th Sunday of Advent")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant false)) + ((date 2025-12-23) (weekday Tue) (title "FERIA II Cl V") + (formulary_override ("Mass of 4th Sunday of Advent")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant false)) + ((date 2025-12-24) (weekday Wed) + (title "VIGIL of The NATIVITY of OUR LORD I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2025-12-25) (weekday Thu) (title "The NATIVITY of OUR LORD I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2025-12-26) (weekday Fri) + (title "St STEPHEN \194\167 Protomartyr II Cl R") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2025-12-27) (weekday Sat) + (title "St JOHN \194\167 Ap Evangelist II Cl W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2025-12-28) (weekday Sun) + (title "SUNDAY within the OCTAVE of the NATIVITY II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2025-12-29) (weekday Mon) + (title "5th DAY within the OCTAVE of the NATIVITY II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2025-12-30) (weekday Tue) + (title "6th DAY within the OCTAVE of the NATIVITY II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2025-12-31) (weekday Wed) + (title "7th DAY within the OCTAVE of the NATIVITY II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-01-01) (weekday Thu) + (title "The OCTAVE DAY of the NATIVITY of the LORD I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-01-02) (weekday Fri) (title "FERIA IV Cl W \226\128\160 SH") + (formulary_override + ("Mass of the Octave Day of the Nativity of the Lord")) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-01-03) (weekday Sat) + (title "OUR LADY on SATURDAY IV Cl W \226\128\160 IH JCHP") + (formulary_override ("II Mass of BVM")) (bvm_numeral (II)) + (gloria (true)) (creed (false)) (has_diocesan_variant true)) + ((date 2026-01-04) (weekday Sun) + (title "The MOST HOLY NAME of JESUS II Cl W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-01-05) (weekday Mon) (title "FERIA IV Cl W \226\128\160") + (formulary_override + ("Mass of the Octave Day of the Nativity of the Lord")) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-01-06) (weekday Tue) (title "The EPIPHANY I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-01-07) (weekday Wed) (title "FERIA IV Cl W \226\128\160") + (formulary_override ("Mass of the Epiphany")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant false)) + ((date 2026-01-08) (weekday Thu) (title "FERIA IV Cl W \226\128\160") + (formulary_override ("Mass of the Epiphany")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant false)) + ((date 2026-01-09) (weekday Fri) (title "FERIA IV Cl W \226\128\160") + (formulary_override ("Mass of the Epiphany")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant false)) + ((date 2026-01-10) (weekday Sat) + (title "OUR LADY on SATURDAY IV Cl W \226\128\160") + (formulary_override ("II Mass of BVM")) (bvm_numeral (II)) + (gloria (true)) (creed (false)) (has_diocesan_variant false)) + ((date 2026-01-11) (weekday Sun) + (title "The HOLY FAMILY of JESUS, MARY AND JOSEPH II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-01-12) (weekday Mon) (title "FERIA IV Cl W \226\128\160") + (formulary_override ("Mass of 1st Sunday after the Epiphany")) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-01-13) (weekday Tue) (title "The BAPTISM of OUR LORD II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-01-14) (weekday Wed) (title "St HILARY B C D III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-01-15) (weekday Thu) + (title "St PAUL the FIRST HERMIT C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-01-16) (weekday Fri) (title "St MARCELLUS I P M III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-01-17) (weekday Sat) (title "St ANTHONY Ab III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-01-18) (weekday Sun) + (title "2nd SUNDAY after the EPIPHANY II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-01-19) (weekday Mon) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 2nd Sunday after the Epiphany")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-01-20) (weekday Tue) + (title "SS FABIAN P & SEBASTIAN M III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-01-21) (weekday Wed) + (title "St AGNES \194\167 V M III Cl (Priv.) R") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-01-22) (weekday Thu) + (title "SS VINCENT & ANASTASIUS MM III Cl R #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-01-23) (weekday Fri) + (title "St RAYMUND of PENAFORT C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-01-24) (weekday Sat) (title "St TIMOTHY B M III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-01-25) (weekday Sun) + (title "3rd SUNDAY after the EPIPHANY II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-01-26) (weekday Mon) (title "St POLYCARP B M III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-01-27) (weekday Tue) + (title "St JOHN CHRYSOSTOM B C D III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-01-28) (weekday Wed) (title "St PETER NOLASCO C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-01-29) (weekday Thu) + (title "St FRANCIS de SALES B C D III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-01-30) (weekday Fri) (title "St MARTINA V M III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-01-31) (weekday Sat) (title "St JOHN BOSCO C III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-02-01) (weekday Sun) (title "SEPTUAGESIMA SUNDAY II Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-02-02) (weekday Mon) + (title "The PURIFICATION of the BVM II Cl W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-02-03) (weekday Tue) + (title + "Today may be given the special blessing of candles; the special blessing of throats; and") + (formulary_override ("Mass of Septuagesima Sunday")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant true)) + ((date 2026-02-04) (weekday Wed) (title "St ANDREW CORSINI B C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-02-05) (weekday Thu) + (title "St AGATHA \194\167 V M III Cl (Priv.) R JCHP") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-02-06) (weekday Fri) (title "St TITUS B C III Cl (Priv.) W SH") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-02-07) (weekday Sat) + (title "St ROMUALD Ab III Cl W # IH JCHP*") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-02-08) (weekday Sun) (title "SEXAGESIMA SUNDAY II Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-02-09) (weekday Mon) + (title "St CYRIL of ALEXANDRIA B C D III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-02-10) (weekday Tue) (title "St SCHOLASTICA V III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-02-11) (weekday Wed) + (title "The APPARITION of the BVM IMMACULATE III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-02-12) (weekday Thu) + (title "The SEVEN HOLY FOUNDERS of the ORDER of the SERVANTS of the") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-02-13) (weekday Fri) (title "FERIA IV Cl V \226\128\161") + (formulary_override ("Mass of Sexagesima Sunday")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant true)) + ((date 2026-02-14) (weekday Sat) + (title "OUR LADY on SATURDAY IV Cl W \226\128\160") + (formulary_override ("III Mass of BVM")) (bvm_numeral (III)) + (gloria (true)) (creed (false)) (has_diocesan_variant false)) + ((date 2026-02-15) (weekday Sun) (title "QUINQUAGESIMA SUNDAY II Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-02-16) (weekday Mon) (title "FERIA IV Cl V \226\128\161") + (formulary_override ("Mass of Quinquagesima Sunday")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant true)) + ((date 2026-02-17) (weekday Tue) (title "FERIA IV Cl V \226\128\161") + (formulary_override ("Mass of Quinquagesima Sunday")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant true)) + ((date 2026-02-18) (weekday Wed) (title "ASH WEDNESDAY I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-02-19) (weekday Thu) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-02-20) (weekday Fri) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-02-21) (weekday Sat) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-02-22) (weekday Sun) (title "1st SUNDAY in LENT I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-02-23) (weekday Mon) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-02-24) (weekday Tue) (title "St MATTHIAS Ap II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-02-25) (weekday Wed) (title "EMBER WEDNESDAY of LENT II Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-02-26) (weekday Thu) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-02-27) (weekday Fri) (title "EMBER FRIDAY of LENT II Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-02-28) (weekday Sat) (title "EMBER SATURDAY of LENT II Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-03-01) (weekday Sun) (title "2nd SUNDAY in LENT I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant true)) + ((date 2026-03-02) (weekday Mon) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-03-03) (weekday Tue) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-03-04) (weekday Wed) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-03-05) (weekday Thu) (title "FERIA III Cl V JCHP") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-03-06) (weekday Fri) + (title "SS PERPETUA \194\167 & FELICITY \194\167 MM III Cl (Priv.) R SH") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-03-07) (weekday Sat) + (title "St THOMAS AQUINAS C D III Cl (Priv.) W IH JCHP*") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-03-08) (weekday Sun) (title "3rd SUNDAY in LENT I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-03-09) (weekday Mon) + (title "St FRANCES of ROME W III Cl (Priv.) W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-03-10) (weekday Tue) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-03-11) (weekday Wed) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-03-12) (weekday Thu) + (title "St GREGORY I P C D III Cl (Priv.) W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-03-13) (weekday Fri) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-03-14) (weekday Sat) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-03-15) (weekday Sun) (title "4th SUNDAY in LENT I Cl V/Rose") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-03-16) (weekday Mon) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-03-17) (weekday Tue) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-03-18) (weekday Wed) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-03-19) (weekday Thu) + (title "St JOSEPH \194\167 SPOUSE of the BVM C, PATRON of the UNIVERSAL") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-03-20) (weekday Fri) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-03-21) (weekday Sat) (title "St BENEDICT Ab III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-03-22) (weekday Sun) (title "PASSION SUNDAY I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-03-23) (weekday Mon) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-03-24) (weekday Tue) + (title "St GABRIEL Archangel III Cl (Priv.) W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-03-25) (weekday Wed) + (title "The ANNUNCIATION of the BVM I Cl W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-03-26) (weekday Thu) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-03-27) (weekday Fri) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-03-28) (weekday Sat) (title "FERIA III Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-03-29) (weekday Sun) (title "PALM SUNDAY I Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-03-30) (weekday Mon) (title "MONDAY of HOLY WEEK I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-03-31) (weekday Tue) (title "TUESDAY of HOLY WEEK I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-04-01) (weekday Wed) (title "WEDNESDAY of HOLY WEEK I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-04-02) (weekday Thu) (title "MAUNDY THURSDAY I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-04-03) (weekday Fri) (title "GOOD FRIDAY I Cl B") + (formulary_override ()) (bvm_numeral ()) (gloria ()) (creed ()) + (has_diocesan_variant false)) + ((date 2026-04-04) (weekday Sat) (title "HOLY SATURDAY I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-04-05) (weekday Sun) (title "EASTER I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-04-06) (weekday Mon) (title "EASTER MONDAY I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-04-07) (weekday Tue) (title "EASTER TUESDAY I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-04-08) (weekday Wed) (title "EASTER WEDNESDAY I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-04-09) (weekday Thu) (title "EASTER THURSDAY I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-04-10) (weekday Fri) (title "EASTER FRIDAY I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-04-11) (weekday Sat) + (title "EASTER SATURDAY (SABBATO in ALBIS) I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-04-12) (weekday Sun) (title "LOW SUNDAY I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-04-13) (weekday Mon) (title "St HERMENEGILD M III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-04-14) (weekday Tue) (title "St JUSTIN M III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-04-15) (weekday Wed) (title "FERIA IV Cl W \226\128\161") + (formulary_override ("Mass of Low Sunday")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant false)) + ((date 2026-04-16) (weekday Thu) (title "FERIA IV Cl W \226\128\161") + (formulary_override ("Mass of Low Sunday")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant false)) + ((date 2026-04-17) (weekday Fri) (title "FERIA IV Cl W \226\128\161") + (formulary_override ("Mass of Low Sunday")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant true)) + ((date 2026-04-18) (weekday Sat) + (title "OUR LADY on SATURDAY IV Cl W \226\128\160") + (formulary_override ("IV Mass of BVM")) (bvm_numeral (IV)) + (gloria (true)) (creed (false)) (has_diocesan_variant false)) + ((date 2026-04-19) (weekday Sun) (title "2nd SUNDAY after EASTER II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-04-20) (weekday Mon) (title "FERIA IV Cl W \226\128\161") + (formulary_override ("Mass of 2nd Sunday after Easter")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant false)) + ((date 2026-04-21) (weekday Tue) (title "St ANSELM B C D III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-04-22) (weekday Wed) + (title "SS SOTER & CAIUS PP MM III Cl R #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-04-23) (weekday Thu) (title "FERIA IV Cl W \226\128\161") + (formulary_override ("Mass of 2nd Sunday after Easter")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant true)) + ((date 2026-04-24) (weekday Fri) + (title "St FIDELIS of SIGMARINGEN M III Cl R #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-04-25) (weekday Sat) + (title "THE GREATER LITANIES. St MARK Evangelist II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2026-04-26) (weekday Sun) (title "3rd SUNDAY after EASTER II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-04-27) (weekday Mon) (title "St PETER CANISIUS C D III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-04-28) (weekday Tue) + (title "St PAUL of the CROSS C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-04-29) (weekday Wed) (title "St PETER M III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-04-30) (weekday Thu) + (title "St CATHERINE of SIENA V III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-05-01) (weekday Fri) + (title "St JOSEPH \194\167 the WORKER, SPOUSE of the BVM C I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-05-02) (weekday Sat) + (title "St ATHANASIUS B C D III Cl (Priv.) W IH JCHP") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-05-03) (weekday Sun) (title "4th SUNDAY after EASTER II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-05-04) (weekday Mon) (title "St MONICA W III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-05-05) (weekday Tue) (title "St PIUS V P C III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-05-06) (weekday Wed) (title "FERIA IV Cl W \226\128\161") + (formulary_override ("Mass of 4th Sunday after Easter")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant true)) + ((date 2026-05-07) (weekday Thu) + (title "St STANISLAUS B M III Cl R # JCHP*") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-05-08) (weekday Fri) (title "FERIA IV Cl W \226\128\161") + (formulary_override ("Mass of 4th Sunday after Easter")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant false)) + ((date 2026-05-09) (weekday Sat) + (title "St GREGORY NAZIANZEN B C D III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-05-10) (weekday Sun) (title "5th SUNDAY after EASTER II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-05-11) (weekday Mon) + (title "SS PHILIP \194\167 & JAMES \194\167 App II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2026-05-12) (weekday Tue) + (title "SS NEREUS, ACHILLEUS, DOMITILLA V, & PANCRAS MM III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-05-13) (weekday Wed) (title "VIGIL of The ASCENSION II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-05-14) (weekday Thu) (title "The ASCENSION I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-05-15) (weekday Fri) + (title "St JOHN BAPTIST de la SALLE C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-05-16) (weekday Sat) (title "St UBALDUS B C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-05-17) (weekday Sun) + (title "SUNDAY after the ASCENSION II Cl W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-05-18) (weekday Mon) (title "St VENANTIUS M III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-05-19) (weekday Tue) + (title "St PETER CELESTINE P C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-05-20) (weekday Wed) + (title "St BERNARDINE of SIENA C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-05-21) (weekday Thu) (title "FERIA IV Cl W \226\128\161") + (formulary_override ("Mass of the Ascension")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant true)) + ((date 2026-05-22) (weekday Fri) (title "FERIA IV Cl W \226\128\161") + (formulary_override ("Mass of the Ascension")) (bvm_numeral ()) + (gloria (true)) (creed (false)) (has_diocesan_variant false)) + ((date 2026-05-23) (weekday Sat) (title "VIGIL of PENTECOST I Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-05-24) (weekday Sun) (title "PENTECOST I Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-05-25) (weekday Mon) (title "WHIT MONDAY I Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-05-26) (weekday Tue) (title "WHIT TUESDAY I Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-05-27) (weekday Wed) + (title "WHIT WEDNESDAY (EMBER DAY) I Cl R") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-05-28) (weekday Thu) (title "WHIT THURSDAY I Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-05-29) (weekday Fri) (title "WHIT FRIDAY (EMBER DAY) I Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-05-30) (weekday Sat) (title "WHIT SATURDAY (EMBER DAY) I Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-05-31) (weekday Sun) (title "The MOST HOLY TRINITY I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2026-06-01) (weekday Mon) (title "St ANGELA MERICI V III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-06-02) (weekday Tue) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 1st Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-06-03) (weekday Wed) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 1st Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-06-04) (weekday Thu) (title "CORPUS CHRISTI I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2026-06-05) (weekday Fri) + (title "St BONIFACE B M III Cl (Priv.) R SH") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-06-06) (weekday Sat) + (title "St NORBERT B C III Cl W # IH JCHP") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-06-07) (weekday Sun) + (title "2nd SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2026-06-08) (weekday Mon) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 2nd Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-06-09) (weekday Tue) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 2nd Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-06-10) (weekday Wed) (title "St MARGARET Q W III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-06-11) (weekday Thu) (title "St BARNABAS Ap III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-06-12) (weekday Fri) (title "The SACRED HEART of JESUS I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-06-13) (weekday Sat) + (title "St ANTHONY of PADUA C D III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-06-14) (weekday Sun) + (title "3rd SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2026-06-15) (weekday Mon) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 3rd Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-06-16) (weekday Tue) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 3rd Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-06-17) (weekday Wed) + (title "St GREGORY BARBARIGO B C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-06-18) (weekday Thu) + (title "St EPHREM the SYRIAN Deacon C D III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-06-19) (weekday Fri) + (title "St JULIANA FALCONIERI V III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-06-20) (weekday Sat) + (title "OUR LADY on SATURDAY IV Cl W \226\128\160") + (formulary_override ("V Mass of BVM")) (bvm_numeral (V)) (gloria (true)) + (creed (false)) (has_diocesan_variant true)) + ((date 2026-06-21) (weekday Sun) + (title "4th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2026-06-22) (weekday Mon) (title "St PAULINUS B C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-06-23) (weekday Tue) + (title "VIGIL of The NATIVITY of JOHN the BAPTIST \194\167 II Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-06-24) (weekday Wed) + (title "The NATIVITY of JOHN the BAPTIST \194\167 I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-06-25) (weekday Thu) (title "St WILLIAM Ab III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-06-26) (weekday Fri) + (title "SS JOHN & PAUL \194\167 MM III Cl R #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-06-27) (weekday Sat) + (title "OUR LADY on SATURDAY IV Cl W \226\128\160") + (formulary_override ("V Mass of BVM")) (bvm_numeral (V)) (gloria (true)) + (creed (false)) (has_diocesan_variant true)) + ((date 2026-06-28) (weekday Sun) + (title "5th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2026-06-29) (weekday Mon) + (title "SS PETER \194\167 & PAUL \194\167 App I Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2026-06-30) (weekday Tue) + (title "The COMMEMORATION of St PAUL \194\167 Ap III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-07-01) (weekday Wed) + (title "The MOST PRECIOUS BLOOD of OUR LORD JESUS CHRIST I Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-07-02) (weekday Thu) + (title "The VISITATION of the BVM II Cl W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-07-03) (weekday Fri) (title "St IRENAEUS B M III Cl R # SH") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-07-04) (weekday Sat) + (title "OUR LADY on SATURDAY IV Cl W \226\128\160 IH JCHP") + (formulary_override ("V Mass of BVM")) (bvm_numeral (V)) (gloria (true)) + (creed (false)) (has_diocesan_variant true)) + ((date 2026-07-05) (weekday Sun) + (title "6th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-07-06) (weekday Mon) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 6th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-07-07) (weekday Tue) + (title "SS CYRIL & METHODIUS BB CC III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-07-08) (weekday Wed) (title "St ELIZABETH Q W III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-07-09) (weekday Thu) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 6th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-07-10) (weekday Fri) + (title "The SEVEN HOLY BROTHERS MM & SS RUFINA & SECUNDA VV MM") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-07-11) (weekday Sat) + (title "OUR LADY on SATURDAY IV Cl W \226\128\160") + (formulary_override ("V Mass of BVM")) (bvm_numeral (V)) (gloria (true)) + (creed (false)) (has_diocesan_variant true)) + ((date 2026-07-12) (weekday Sun) + (title "7th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-07-13) (weekday Mon) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 7th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-07-14) (weekday Tue) + (title "St BONAVENTURE B C D III Cl (Priv.) W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-07-15) (weekday Wed) (title "St HENRY Emperor C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-07-16) (weekday Thu) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 7th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-07-17) (weekday Fri) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 7th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-07-18) (weekday Sat) + (title "St CAMILLUS de LELLIS C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-07-19) (weekday Sun) + (title "8th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-07-20) (weekday Mon) (title "St JEROME EMILIANI C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-07-21) (weekday Tue) + (title "St LAURENCE of BRINDISI C D III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-07-22) (weekday Wed) + (title "St MARY MAGDALEN Penitent III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-07-23) (weekday Thu) (title "St APOLLINARIS B M III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-07-24) (weekday Fri) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 8th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-07-25) (weekday Sat) (title "St JAMES \194\167 Ap II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-07-26) (weekday Sun) + (title "9th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-07-27) (weekday Mon) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 9th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-07-28) (weekday Tue) + (title "SS NAZARIUS & CELSUS MM & VICTOR I P M & INNOCENT I P C III Cl") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-07-29) (weekday Wed) (title "St MARTHA V III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-07-30) (weekday Thu) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 9th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-07-31) (weekday Fri) (title "St IGNATIUS C III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-08-01) (weekday Sat) + (title "OUR LADY on SATURDAY IV Cl W \226\128\160 IH JCHP") + (formulary_override ("V Mass of BVM")) (bvm_numeral (V)) (gloria (true)) + (creed (false)) (has_diocesan_variant false)) + ((date 2026-08-02) (weekday Sun) + (title "10th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-08-03) (weekday Mon) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 10th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-08-04) (weekday Tue) (title "St DOMINIC C III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-08-05) (weekday Wed) + (title "The DEDICATION of St MARY of the SNOWS III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-08-06) (weekday Thu) + (title "The TRANSFIGURATION of OUR LORD JESUS CHRIST II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-08-07) (weekday Fri) (title "St CAJETAN C III Cl W # SH") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-08-08) (weekday Sat) + (title "St JOHN MARY VIANNEY C III Cl (Priv.) W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-08-09) (weekday Sun) + (title "11th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-08-10) (weekday Mon) (title "St LAURENCE \194\167 M II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-08-11) (weekday Tue) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 11th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-08-12) (weekday Wed) (title "St CLARE V III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-08-13) (weekday Thu) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 11th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-08-14) (weekday Fri) + (title "VIGIL of The ASSUMPTION of the BVM II Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-08-15) (weekday Sat) (title "The ASSUMPTION of the BVM I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-08-16) (weekday Sun) + (title "12th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2026-08-17) (weekday Mon) (title "St HYACINTH C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-08-18) (weekday Tue) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 12th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-08-19) (weekday Wed) (title "St JOHN EUDES C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-08-20) (weekday Thu) (title "St BERNARD Ab D III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-08-21) (weekday Fri) + (title "St JANE FRANCES FR\195\137MIOT de CHANTAL W III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-08-22) (weekday Sat) + (title "The IMMACULATE HEART of the BVM II Cl W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-08-23) (weekday Sun) + (title "13th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-08-24) (weekday Mon) + (title "St BARTHOLOMEW \194\167 Ap II Cl R") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-08-25) (weekday Tue) (title "St LOUIS K C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-08-26) (weekday Wed) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 13th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-08-27) (weekday Thu) + (title "St JOSEPH CALASANCTIUS C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-08-28) (weekday Fri) + (title "St AUGUSTINE B C D III Cl (Priv.) W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-08-29) (weekday Sat) + (title "The BEHEADING of St JOHN the BAPTIST \194\167 III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-08-30) (weekday Sun) + (title "14th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-08-31) (weekday Mon) (title "St RAYMUND NONNATUS C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-09-01) (weekday Tue) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 14th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-09-02) (weekday Wed) (title "St STEPHEN K C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-09-03) (weekday Thu) + (title "St PIUS X P C III Cl (Priv.) W JCHP") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-09-04) (weekday Fri) (title "FERIA IV Cl G \226\128\161 SH") + (formulary_override ("Mass of 14th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-09-05) (weekday Sat) + (title "St LAURENCE JUSTINIAN B C III Cl W # IH JCHP") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-09-06) (weekday Sun) + (title "15th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2026-09-07) (weekday Mon) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 15th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-09-08) (weekday Tue) (title "The NATIVITY of the BVM II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-09-09) (weekday Wed) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 15th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-09-10) (weekday Thu) + (title "St NICOLAS of TOLENTINO C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-09-11) (weekday Fri) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 15th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-09-12) (weekday Sat) + (title "The MOST HOLY NAME of MARY III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-09-13) (weekday Sun) + (title "16th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2026-09-14) (weekday Mon) + (title "The EXALTATION of the HOLY CROSS II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-09-15) (weekday Tue) + (title "The SEVEN SORROWS of the BVM II Cl W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-09-16) (weekday Wed) + (title + "SS CORNELIUS \194\167 P & CYPRIAN \194\167 B MM III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-09-17) (weekday Thu) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 16th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-09-18) (weekday Fri) + (title "St JOSEPH of CUPERTINO C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-09-19) (weekday Sat) + (title "St JANUARIUS B & COMPS MM III Cl R #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-09-20) (weekday Sun) + (title "17th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-09-21) (weekday Mon) + (title "St MATTHEW \194\167 Ap Evangelist II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2026-09-22) (weekday Tue) + (title "St THOMAS of VILLANOVA B C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-09-23) (weekday Wed) + (title "EMBER WEDNESDAY of SEPTEMBER II Cl V") (formulary_override ()) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-09-24) (weekday Thu) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 17th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-09-25) (weekday Fri) + (title "EMBER FRIDAY of SEPTEMBER II Cl V") (formulary_override ()) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-09-26) (weekday Sat) + (title "EMBER SATURDAY of SEPTEMBER II Cl V") (formulary_override ()) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-09-27) (weekday Sun) + (title "18th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-09-28) (weekday Mon) (title "St WENCESLAUS Duke M III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-09-29) (weekday Tue) + (title "The DEDICATION of St MICHAEL Archangel I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-09-30) (weekday Wed) + (title "St JEROME Priest C D III Cl (Priv.) W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-10-01) (weekday Thu) (title "FERIA IV Cl G \226\128\161 JCHP") + (formulary_override ("Mass of 18th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-10-02) (weekday Fri) + (title "The HOLY GUARDIAN ANGELS III Cl (Priv.) W SH") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-10-03) (weekday Sat) + (title "St TERESA of the CHILD JESUS V III Cl (Priv.) W IH JCHP*") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-10-04) (weekday Sun) + (title "19th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2026-10-05) (weekday Mon) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 19th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-10-06) (weekday Tue) (title "St BRUNO C III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-10-07) (weekday Wed) (title "OUR LADY of the ROSARY II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-10-08) (weekday Thu) (title "St BRIDGET W III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-10-09) (weekday Fri) (title "St JOHN LEONARDI C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-10-10) (weekday Sat) (title "St FRANCIS BORGIA C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-10-11) (weekday Sun) + (title "20th SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-10-12) (weekday Mon) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 20th Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-10-13) (weekday Tue) (title "St EDWARD K C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-10-14) (weekday Wed) + (title "St CALLISTUS I P M III Cl (Priv.) R") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-10-15) (weekday Thu) (title "St TERESA V III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-10-16) (weekday Fri) (title "St HEDWIG W III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-10-17) (weekday Sat) + (title "St MARGARET MARY ALACOQUE V III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-10-18) (weekday Sun) + (title "21st SUNDAY after PENTECOST II Cl G") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2026-10-19) (weekday Mon) + (title "St PETER of ALCANTARA C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-10-20) (weekday Tue) (title "St JOHN CANTIUS C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-10-21) (weekday Wed) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 21st Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-10-22) (weekday Thu) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 21st Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-10-23) (weekday Fri) + (title "St ANTHONY MARY CLARET B C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-10-24) (weekday Sat) (title "St RAPHAEL Archangel III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-10-25) (weekday Sun) (title "CHRIST the KING I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-10-26) (weekday Mon) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 22nd Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-10-27) (weekday Tue) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 22nd Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-10-28) (weekday Wed) + (title "SS SIMON \194\167 & JUDE \194\167 Ap II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-10-29) (weekday Thu) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 22nd Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-10-30) (weekday Fri) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 22nd Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-10-31) (weekday Sat) + (title "OUR LADY on SATURDAY IV Cl W \226\128\160") + (formulary_override ("V Mass of BVM")) (bvm_numeral (V)) (gloria (true)) + (creed (false)) (has_diocesan_variant false)) + ((date 2026-11-01) (weekday Sun) (title "ALL SAINTS' DAY I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-11-02) (weekday Mon) (title "ALL SOULS' DAY I Cl B") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-11-03) (weekday Tue) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 23rd Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-11-04) (weekday Wed) (title "St CHARLES B C III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-11-05) (weekday Thu) (title "FERIA IV Cl G \226\128\161 JCHP") + (formulary_override ("Mass of 23rd Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-11-06) (weekday Fri) (title "FERIA IV Cl G \226\128\161 SH") + (formulary_override ("Mass of 23rd Sunday after Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-11-07) (weekday Sat) + (title "OUR LADY on SATURDAY IV Cl W \226\128\160 IH JCHP*") + (formulary_override ("V Mass of BVM")) (bvm_numeral (V)) (gloria (true)) + (creed (false)) (has_diocesan_variant true)) + ((date 2026-11-08) (weekday Sun) + (title "5th SUNDAY remaining after the EPIPHANY II Cl G") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-11-09) (weekday Mon) + (title "The DEDICATION of the ARCHBASILICA of OUR SAVIOUR II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-11-10) (weekday Tue) (title "St ANDREW AVELLINO C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-11-11) (weekday Wed) (title "St MARTIN B C III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-11-12) (weekday Thu) (title "St MARTIN I P M III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-11-13) (weekday Fri) (title "St DIDACUS C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-11-14) (weekday Sat) (title "St JOSAPHAT B M III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-11-15) (weekday Sun) + (title "6th SUNDAY remaining after the EPIPHANY II Cl G") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2026-11-16) (weekday Mon) (title "St GERTRUDE V III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-11-17) (weekday Tue) + (title "St GREGORY THAUMATURGUS B C III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-11-18) (weekday Wed) + (title + "The DEDICATION of the BASILICAS of SS PETER & PAUL III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-11-19) (weekday Thu) (title "St ELIZABETH W III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-11-20) (weekday Fri) (title "St FELIX de VALOIS C III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-11-21) (weekday Sat) + (title "The PRESENTATION of the BVM III Cl W #") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-11-22) (weekday Sun) + (title "24th & LAST SUNDAY After PENTECOST II Cl G") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2026-11-23) (weekday Mon) + (title "St CLEMENT I \194\167 P M III Cl (Priv.) R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-11-24) (weekday Tue) + (title "St JOHN of the CROSS C D III Cl (Priv.) W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-11-25) (weekday Wed) (title "St CATHERINE V M III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-11-26) (weekday Thu) (title "St SILVESTER Ab III Cl W #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-11-27) (weekday Fri) (title "FERIA IV Cl G \226\128\161") + (formulary_override ("Mass of 24th & Last Sunday After Pentecost")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-11-28) (weekday Sat) + (title "OUR LADY on SATURDAY IV Cl W \226\128\160") + (formulary_override ("V Mass of BVM")) (bvm_numeral (V)) (gloria (true)) + (creed (false)) (has_diocesan_variant false)) + ((date 2026-11-29) (weekday Sun) (title "ADVENT SUNDAY I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-11-30) (weekday Mon) (title "St ANDREW \194\167 Ap II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-12-01) (weekday Tue) (title "FERIA III Cl V") + (formulary_override ("Mass of Advent Sunday")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant true)) + ((date 2026-12-02) (weekday Wed) (title "St BIBIANA V M III Cl R #") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-12-03) (weekday Thu) + (title "St FRANCIS XAVIER C III Cl (Priv.) W JCHP") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-12-04) (weekday Fri) + (title "St PETER CHRYSOLOGUS B C D III Cl W # SH") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-12-05) (weekday Sat) (title "FERIA III Cl V IH JCHP*") + (formulary_override ("Mass of Advent Sunday")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant true)) + ((date 2026-12-06) (weekday Sun) (title "2nd SUNDAY of ADVENT I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-12-07) (weekday Mon) + (title "St AMBROSE B C D III Cl (Priv.) W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-12-08) (weekday Tue) + (title "The IMMACULATE CONCEPTION of the BVM I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-12-09) (weekday Wed) (title "FERIA III Cl V") + (formulary_override ("Mass of 2nd Sunday of Advent")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant false)) + ((date 2026-12-10) (weekday Thu) (title "FERIA III Cl V") + (formulary_override ("Mass of 2nd Sunday of Advent")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant true)) + ((date 2026-12-11) (weekday Fri) + (title "St DAMASUS I P C III Cl (Priv.) W") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (false)) + (has_diocesan_variant true)) + ((date 2026-12-12) (weekday Sat) (title "FERIA III Cl V") + (formulary_override ("Mass of 2nd Sunday of Advent")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant false)) + ((date 2026-12-13) (weekday Sun) + (title "3rd SUNDAY of ADVENT (GAUDETE SUNDAY) I Cl V/Rose") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-12-14) (weekday Mon) (title "FERIA III Cl V") + (formulary_override ("Mass of 3rd Sunday of Advent (Gaudete Sunday)")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-12-15) (weekday Tue) (title "FERIA III Cl V") + (formulary_override ("Mass of 3rd Sunday of Advent (Gaudete Sunday)")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-12-16) (weekday Wed) + (title "EMBER WEDNESDAY of ADVENT II Cl V") (formulary_override ()) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-12-17) (weekday Thu) (title "FERIA II Cl V") + (formulary_override ("Mass of 3rd Sunday of Advent (Gaudete Sunday)")) + (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-12-18) (weekday Fri) (title "EMBER FRIDAY of ADVENT II Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-12-19) (weekday Sat) (title "EMBER SATURDAY of ADVENT II Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-12-20) (weekday Sun) (title "4th SUNDAY of ADVENT I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-12-21) (weekday Mon) (title "St THOMAS \194\167 Ap II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-12-22) (weekday Tue) (title "FERIA II Cl V") + (formulary_override ("Mass of 4th Sunday of Advent")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant false)) + ((date 2026-12-23) (weekday Wed) (title "FERIA II Cl V") + (formulary_override ("Mass of 4th Sunday of Advent")) (bvm_numeral ()) + (gloria (false)) (creed (false)) (has_diocesan_variant false)) + ((date 2026-12-24) (weekday Thu) + (title "VIGIL of The NATIVITY of OUR LORD I Cl V") + (formulary_override ()) (bvm_numeral ()) (gloria (false)) (creed (false)) + (has_diocesan_variant false)) + ((date 2026-12-25) (weekday Fri) (title "The NATIVITY of OUR LORD I Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-12-26) (weekday Sat) + (title "St STEPHEN \194\167 Protomartyr II Cl R") (formulary_override ()) + (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-12-27) (weekday Sun) + (title "SUNDAY within the OCTAVE of the NATIVITY II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-12-28) (weekday Mon) (title "The HOLY INNOCENTS MM II Cl R") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2026-12-29) (weekday Tue) + (title "5th DAY within the OCTAVE of the NATIVITY II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant true)) + ((date 2026-12-30) (weekday Wed) + (title "6th DAY within the OCTAVE of the NATIVITY II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false)) + ((date 2026-12-31) (weekday Thu) + (title "7th DAY within the OCTAVE of the NATIVITY II Cl W") + (formulary_override ()) (bvm_numeral ()) (gloria (true)) (creed (true)) + (has_diocesan_variant false))) diff --git a/test/test_colitur.ml b/test/test_colitur.ml index 8d05f75..6db744f 100644 --- a/test/test_colitur.ml +++ b/test/test_colitur.ml @@ -14,7 +14,9 @@ let () = Test_overlay.suite; Test_overlay_ini.suite; Test_temporal_ef.suite; Test_validate.suite; Test_precedence.suite; Test_calendar.suite; Test_precedence_ef.suite; Test_sanctoral_ef.suite; Test_rite_ef.suite; Test_rubrics_ef.suite; - Test_differential.suite; Test_oracle.suite; Test_oracle.suite_2038; Test_oracle.suite_2035; Test_lms_ordo.suite; + Test_differential.suite; Test_oracle.suite; Test_oracle.suite_2038; Test_oracle.suite_2035; + Test_lms_ordo.suite_2023_2024; Test_lms_ordo.suite_2024_2025; Test_lms_ordo.suite_2025_2026; + Test_lms_ordo.suite_allow_list; Test_golden.suite; ("lectionary", Test_lectionary.suite); ("lectionary-ef", Test_lectionary_ef.suite); diff --git a/test/test_lms_ordo.ml b/test/test_lms_ordo.ml index a728cbc..84c4776 100644 --- a/test/test_lms_ordo.ml +++ b/test/test_lms_ordo.ml @@ -1,112 +1,88 @@ -(* Task 6 (2026-08-21-colitur-celebrant-rubrics-phase1): validation layer 6 - -- the Latin Mass Society's own printed Ordo for England & Wales - (test/fixtures/lms-ordo-2024-2025.sexp; that file's own provenance - header carries the full source citation, SHA-256 and the - characterisation record demanded before trusting a single row of it). +(* Task 6 (2026-08-21-colitur-celebrant-rubrics-phase1) built this layer + against ONE LMS Ordo edition (2024-2025). The Witnesses task + (2026-08-22, same phase) extends it to THREE editions -- 2023-2024, + 2024-2025, 2025-2026 -- each compared in its OWN window, counted and + reported SEPARATELY, never merged: a divergence appearing in one year + and not another is informative on its own, and merging would hide it. + [make_suite] below is the shared machinery Task 6 built as a single + flat file; every per-year fact that Task 6 hardcoded (window dates, + fixture SHA-256, the "only Good Friday has no Creed marker" pin, the + formulary-bucket totals, the BVM-Saturday population) is now a + parameter or a value RE-DERIVED from the rubric independently per + window, not copied forward -- see each call site below for the + per-edition numbers, which do differ (397/399/400 rows; not every + edition even has the same II-class "sharp pairing" saint available, + see [fixture_probes] in tools/extract_lms_ordo.ml's own header for + 2025-2026's own Joachim-is-impeded finding). WHY THIS LAYER EXISTS, AND WHAT IT IS INDEPENDENT OF: layers 3-4 (test_differential.ml, test_oracle.ml) are ONE LINEAGE running Divinum Officium -> missalemeum -> lectio -> colitur (CLAUDE.md's "know what each layer cannot see" section); layer 5 (test_golden.ml) pins colitur's own output against itself. This Ordo is compiled independently by the - Latin Mass Society (a printed book, ISBN 9781739209636, England & Wales - diocesan propers) from the 1962 Missal/1960 rubrics directly -- it never - passed through Divinum Officium, missalemeum or lectio at any point, so - an error inherited by that whole lineage (colitur's own bootstrap - included) is visible here for the first time. + Latin Mass Society (a printed book, England & Wales diocesan propers) + from the 1962 Missal/1960 rubrics directly -- it never passed through + Divinum Officium, missalemeum or lectio at any point, so an error + inherited by that whole lineage (colitur's own bootstrap included) is + visible here for the first time. Three editions of the SAME publisher's + book are still only ONE compiler's judgement (see docs/research/ordo/ + PROVENANCE-ordo-corpus.md's own "what this corpus still cannot show" -- + genuine cross-compiler independence needs the FIUV layer, test_fiuv_ + ordo.ml, built separately in this same task). SCOPE, decided after running the comparison against real data (not - guessed in advance -- see the fixture's own CHARACTERISATION section - and task-6-report.md for the measurements this scoping rests on): + guessed in advance -- see each fixture's own CHARACTERISATION section): - The CREED (RG 475-476, {!Rite_ef.Rubrics_ef.creed}): compared on - every day, full 1:1. One genuine day is EXCLUDED, not silently - skipped: 2025-04-18 (Good Friday) has no Mass in the 1955-restored - Holy Week, so the Ordo prints no Gl/Cr line at all -- [test_ - creed_coverage] asserts this is the ONLY such day, so a future - parsing regression that swallowed a real row would fail loudly - here, not slip into "explained" silently. + every day, full 1:1, in every edition's own window. Exactly one day + per window is EXCLUDED, not silently skipped: that window's own + Good Friday (RE-DERIVED per window from {!Colitur_kernel.Computus. + gregorian_easter}, never hardcoded to a specific date) has no Mass + in the 1955-restored Holy Week, so the Ordo prints no Gl/Cr line at + all there -- [test_creed_coverage] asserts this is the ONLY such + day per window. - The BVM-SATURDAY SEASONAL SELECTION (RG 309(a), "iuxta temporum diversitatem", {!Rite_ef.Lectionary_ef.bvm_saturday_citations}): - the coordinator addendum's own "sharper check" -- the Ordo's own - roman numeral (I-V) names WHICH of the five seasonal "Missae de - sancta Maria in sabbato" is said, so it validates colitur's - SEASONAL SELECTION, not merely that some BVM Mass was chosen. - Built, because the extraction supports it (whole-line anchored - match against all five, see the fixture header on why substring - matching is wrong): every {!Colitur_kernel.Mass_formulary.Votive} - day inside the fixture's own 2024-11-27..2025-12-31 window is - checked against the numeral's implied season. + the Ordo's own roman numeral (I-V) names WHICH of the five seasonal + "Missae de sancta Maria in sabbato" is said, so it validates + colitur's SEASONAL SELECTION, not merely that some BVM Mass was + chosen. Checked against every {!Colitur_kernel.Mass_formulary. + Votive} day inside each edition's own window. - The FORMULARY OVERRIDE (does the day say its own Mass, or a borrowed one) -- compared for THREE of {!Colitur_kernel. - Mass_formulary.source}'s five constructors, each independently - 100% clean against the real fixture: - [Proper] (179 of 400 days): the Ordo shows NO "Mass of ..." line. - [Preceding_sunday] (66 of 400): the Ordo ALWAYS shows one. - [Common] (2 of 400): the Ordo shows NO "Mass of ..." line either - -- a Common-routed saint (ubaldus, didacus) still keeps his OWN - title in the Ordo, borrowing only the Common's PREFACE ("Common - Pr" on the title line itself), never a separate override line. - [Votive] is covered by the BVM check above instead (its own - override line IS the roman-numeral line). - [Own_slug] (139 of 400) is DELIBERATELY EXCLUDED from this axis, - not silently -- a real, evidenced data-representation fact, not a - guess: 11 of its 139 days DO show a "Mass of ..." override - ("2nd Sunday of Advent", "the Epiphany", "1st Sunday after - Pentecost"), because data/ef/lectionary.sexp carries some ferial - slugs (e.g. [ef-advent-2-monday]) as an EXPLICIT entry whose - citations are byte-identical to the following Sunday's own - ([ef-advent-sunday-2]: both "Rom 15:4-13" / "Matt 11:2-10" -- - checked directly against the shipped data), rather than resolving - through the {!Colitur_kernel.Mass_formulary.Preceding_sunday} - fallback path. Both representations name the SAME texts -- this is - a provenance-field ambiguity in colitur's own data, not a rubric - question the Ordo could adjudicate either way, so asserting on it - would manufacture exactly the kind of false divergence the - coordinator addendum's "collapsed to ~0 real ones" warning is - about. Recorded here rather than dropped silently, per the task - brief's own instruction for exactly this situation. - - GLORIA is extracted into the fixture (a genuine, independently useful + Mass_formulary.source}'s five constructors ([Proper]/ + [Preceding_sunday]/[Common]), on the same [Own_slug]-excluded, + [Votive]-covered-separately basis Task 6 established (see that + task's own report for the full reasoning: 11 of [Own_slug]'s + real days show an Ordo override anyway, a data-representation + ambiguity in colitur's own lectionary, not a rubric question the + Ordo could adjudicate). + + GLORIA is extracted into every fixture (a genuine, independently useful field for the still-unbuilt Phase 2 Gloria rule) but NOT compared here: - colitur has no {!Rite_ef.Rubrics_ef}-level Gloria predicate yet (the - design doc defers it explicitly), so there is nothing on colitur's own - side to compare it against. Comparing it would be comparing the Ordo - against nothing. + colitur has no {!Rite_ef.Rubrics_ef}-level Gloria predicate yet. DIOCESAN SCOPE: colitur computes the UNIVERSAL General Roman Calendar only (no diocesan overlay loaded by the differential/oracle harnesses - anywhere in this suite) -- the Ordo is an England & Wales diocesan - Ordo, and 156 of its 400 days (39%) carry at least one diocesan - variant. Every comparison in this file reads ONLY the fixture's own - universal-block fields ([formulary_override], [bvm_numeral], [gloria], - [creed] are all derived from the text BEFORE the first diocese-list - line -- see extract_lms_ordo.ml's own [scan_block]); the diocesan text - itself is never read at all, only its PRESENCE is recorded - ([has_diocesan_variant]), so no diocesan variant can leak into a - comparison here by construction, not merely by care. *) + anywhere in this suite) -- every LMS edition is an England & Wales + diocesan Ordo, and each fixture's own provenance header quantifies how + many of its days carry at least one diocesan variant. Every comparison + in this file reads ONLY each fixture's own universal-block fields. *) module Cal = Colitur_kernel.Calendar module Layer = Colitur_kernel.Layer module Overlay = Colitur_kernel.Overlay module LD = Colitur_kernel.Liturgical_day module Date = Colitur_kernel.Date +module Computus = Colitur_kernel.Computus module MF = Colitur_kernel.Mass_formulary module V = Rite_ef.Vocab_ef module TE = Rite_ef.Temporal_ef let sanctoral_path = "../data/ef/sanctoral.sexp" let adjustments_path = "../data/ef/adjustments.sexp" -let fixture_path = "fixtures/lms-ordo-2024-2025.sexp" -let allow_list_path = "../data/ef/expected-divergences-lms.sexp" - -(* Asserted, not merely documented -- test_oracle.ml's own [fixture_sha256] - comment explains why: a hand-edit or partial re-extraction would - otherwise silently turn the oracle into an unlabelled snapshot of - whatever someone last ran. Matches the fixture's own provenance header. *) -let fixture_sha256 = "da817b75c5bf40ed3be1d5f6890b199705e02ce4d42111253ab8547bccabc3f7" (* Duplicated, not shared, from test_oracle.ml/test_differential.ml's own identical function -- neither file exposes an .mli the other could @@ -176,23 +152,20 @@ type ordo_row = { } [@@deriving sexp] -let ordo_rows () = +let ordo_rows fixture_path = let sexp = try Sexplib.Sexp.load_sexp fixture_path with e -> Alcotest.failf "%s: failed to load: %s" fixture_path (Printexc.to_string e) in list_of_sexp ordo_row_of_sexp sexp -(* The fixture's own real window -- 2024-11-27 ("End of November 2024") - through 2025-12-31 (the day before the extractor's own stop marker). - 400 = 4 (27-30 Nov 2024) + 31 (Dec 2024) + 365 (2025, not a leap year). *) -let window_first = "2024-11-27" -let window_last = "2025-12-31" - (* ---------------------------------------------------------------------- *) -(* The colitur side, over the same window. Mirrors test_oracle.ml's own *) -(* [colitur_rows]: the resolution walk starts a year EARLY because a *) -(* liturgical year is Advent-anchored and straddles two civil years. *) +(* The colitur side, over the SAME window a given fixture covers. Mirrors *) +(* test_oracle.ml's own [colitur_rows]: the resolution walk starts a civil *) +(* year EARLY (and ends one late) because a liturgical year is *) +(* Advent-anchored and straddles two civil years -- generalised from Task *) +(* 6's single hardcoded [2023..2025] to a [~year_lo]/[~year_hi] parameter *) +(* per window, since the three editions' own civil-year spans differ. *) (* ---------------------------------------------------------------------- *) type colitur_row = { @@ -202,18 +175,20 @@ type colitur_row = { c_creed : bool; } -let colitur_rows () = +let colitur_rows ~year_lo ~year_hi ~window_first ~window_last = let layer = real_layer () in let rite = Rite_ef.context ~lectionary:(real_lectionary ()) ~commons:(real_commons ()) in let by_rata : (int, (V.season, V.rank) LD.t) Hashtbl.t = Hashtbl.create 800 in - for y = 2023 to 2025 do + for y = year_lo to year_hi do let days = Cal.year rite layer y in Array.iter (fun (d : (V.season, V.rank) LD.t) -> Hashtbl.replace by_rata (Date.to_rata d.LD.date) d) days done; - let mk y m d = match Date.make ~year:y ~month:m ~day:d with Ok t -> t | Error e -> failwith e in + let mk s = + match Date.of_iso8601 s with Ok d -> d | Error e -> Alcotest.failf "%s: not a valid ISO-8601 date: %s" s e + in let rows = ref [] in - let d = ref (mk 2024 11 27) in - let stop = mk 2025 12 31 in + let d = ref (mk window_first) in + let stop = mk window_last in while Date.compare !d stop <= 0 do (match Hashtbl.find_opt by_rata (Date.to_rata !d) with | Some day -> @@ -228,11 +203,7 @@ let colitur_rows () = (* ---------------------------------------------------------------------- *) (* RG 309(a), "iuxta temporum diversitatem" -- INDEPENDENTLY re-derived *) -(* from the rubric, not called from Lectionary_ef.bvm_saturday_citations *) -(* (private to that .ml, no .mli export, and re-deriving here is itself *) -(* the more useful check: importing colitur's own function would make *) -(* this axis tautological). Mirrors that function's own season match *) -(* exactly -- see its citation in lectionary_ef.ml for the scan lines. *) +(* from the rubric, not called from Lectionary_ef.bvm_saturday_citations. *) (* ---------------------------------------------------------------------- *) let expected_bvm_numeral season ~month ~day = @@ -246,13 +217,16 @@ let expected_bvm_numeral season ~month ~day = (* ---------------------------------------------------------------------- *) (* data/ef/expected-divergences-lms.sexp -- same shape as *) -(* test_oracle.ml's own [allow_entry]/[load_allow_list]. *) +(* test_oracle.ml's own [allow_entry]/[load_allow_list]. ONE allow-list *) +(* file for all three editions (they are one lineage, the same publisher *) +(* and compiler) -- an entry's own [note] names which edition(s) it fired *) +(* on when that matters. *) (* ---------------------------------------------------------------------- *) type allow_entry = { id : string; citation : string; verdict : string; note : string; expected_rows : int } [@@deriving sexp] -let load_allow_list () = +let load_allow_list allow_list_path = let sexps = try Sexplib.Sexp.load_sexps allow_list_path with e -> Alcotest.failf "%s: failed to load: %s" allow_list_path (Printexc.to_string e) @@ -260,213 +234,19 @@ let load_allow_list () = List.map allow_entry_of_sexp sexps (* ---------------------------------------------------------------------- *) -(* Tests *) -(* ---------------------------------------------------------------------- *) - -let test_fixture_checksum () = - Alcotest.(check string) "fixture SHA-256 matches its provenance note" fixture_sha256 - (sha256_of_file fixture_path) - -let test_dates_align () = - let ordo = ordo_rows () in - let colitur = colitur_rows () in - Alcotest.(check int) "the Ordo fixture has 400 rows (2024-11-27..2025-12-31)" 400 (List.length ordo); - Alcotest.(check int) "colitur resolved the same number of days" (List.length ordo) (List.length colitur); - (match ordo with o :: _ -> Alcotest.(check string) "first date" window_first o.date | [] -> Alcotest.fail "empty"); - (match List.rev ordo with - | o :: _ -> Alcotest.(check string) "last date" window_last o.date - | [] -> Alcotest.fail "empty"); - let mismatched = - List.filter_map - (fun (o, c) -> if String.equal o.date c.c_date then None else Some (o.date, c.c_date)) - (List.combine ordo colitur) - in - Alcotest.(check (list (pair string string))) "no misaligned dates" [] mismatched - -(* Good Friday (2025-04-18) has no Mass at all in the 1955-restored Holy - Week -- the Ordo prints no Gl/Cr line, confirmed directly against the - source (extract_lms_ordo's own row for that date, and the raw pdftotext - text: "The Solemn Liturgical Action is celebrated in the afternoon...", - no "Gl"/"Cr" token anywhere in the block). Asserted as the ONLY such - day, not merely observed once: a future parsing regression that - swallowed a real Gl/Cr line would otherwise silently join this - "not applicable" bucket instead of failing loudly as an unexplained - mismatch. *) -let test_creed_coverage () = - let ordo = ordo_rows () in - let no_creed = List.filter (fun o -> o.creed = None) ordo in - Alcotest.(check (list string)) "only Good Friday has no Ordo Creed marker" [ "2025-04-18" ] - (List.map (fun o -> o.date) no_creed) - -let describe_creed_mismatch (o : ordo_row) (c : colitur_row) = - Printf.sprintf "%s %S: colitur creed=%b, Ordo creed=%b (formulary=%s)" o.date o.title c.c_creed - (Option.get o.creed) - (match c.c_formulary with - | Some { MF.said = Some s; _ } -> Colitur_kernel.Slug.to_string s - | Some { MF.said = None; via = MF.Votive } -> "votive (said unnamed in the data)" - | Some { MF.said = None; _ } -> "NONE (said, unexpectedly outside Votive)" - | None -> "NONE") - -(* The core assertion: every Creed divergence, over all 400 days (Good - Friday excluded per [test_creed_coverage] above -- it is not a - divergence, it is a day with nothing on the Ordo's side to compare), - falls in a named, cited, adjudicated allow-list entry. Zero - unexplained. *) -let test_creed_matches_or_is_explained () = - let ordo = ordo_rows () in - let colitur = colitur_rows () in - let allow_list = load_allow_list () in - let by_id = List.map (fun e -> (e.id, e)) allow_list in - (* No known Creed divergence is adjudicated any more: L1 (RG 476(f), All - Souls' Day) was CLOSED by fixing {!Rite_ef.Rubrics_ef.creed} itself - (whole-branch review finding 1), not by re-adjudicating it -- see - expected-divergences-lms.sexp's own closure note for the citation and - the measured blast radius. [allow_list] is therefore expected to be - empty today; the [by_id]/[explained_counts] wiring below is kept - rather than deleted, because the "every declared entry must have - fired" check at the end is a real invariant worth keeping live even - while the list itself is empty -- exactly the shape a FUTURE entry of - this kind would need. *) - let unexplained = ref [] in - let explained_counts = Hashtbl.create 8 in - List.iter2 - (fun (o : ordo_row) (c : colitur_row) -> - if not (String.equal o.date c.c_date) then Alcotest.failf "misaligned: ordo %s vs colitur %s" o.date c.c_date; - match o.creed with - | None -> () (* Good Friday, see test_creed_coverage *) - | Some ocreed -> - if Bool.equal ocreed c.c_creed then () else unexplained := describe_creed_mismatch o c :: !unexplained) - ordo colitur; - Alcotest.(check (list string)) "every Creed mismatch is named in the allow-list -- none unexplained" [] - (List.rev !unexplained); - Hashtbl.iter - (fun id n -> - match List.assoc_opt id by_id with - | None -> Alcotest.failf "allow-list entry %s used by the comparator but not declared in %s" id allow_list_path - | Some e -> - Alcotest.(check int) (Printf.sprintf "%s: expected_rows matches the actual count" id) e.expected_rows n) - explained_counts; - (* every declared entry must actually have fired, so the allow-list - cannot silently accumulate a dead entry nothing triggers any more *) - List.iter - (fun e -> - if not (Hashtbl.mem explained_counts e.id) then - Alcotest.failf "allow-list entry %s is declared but never matched a real divergence" e.id) - allow_list - -(* ---------------------------------------------------------------------- *) -(* The BVM-Saturday seasonal selection -- the coordinator addendum's own *) -(* "sharper check". Restricted to colitur's [Votive] days, which is *) -(* exactly {!Rite_ef.Lectionary_ef.is_bvm_saturday_office}'s own domain. *) -(* ---------------------------------------------------------------------- *) - -let test_bvm_seasonal_selection () = - let ordo = ordo_rows () in - let colitur = colitur_rows () in - let votive_pairs = - List.filter_map - (fun (o, c) -> - match c.c_formulary with - | Some { MF.via = MF.Votive; _ } -> Some (o, c) - | _ -> None) - (List.combine ordo colitur) - in - Alcotest.(check int) "14 BVM-Saturday (Votive) days fall inside the fixture's own window" 14 - (List.length votive_pairs); - let mismatches = - List.filter_map - (fun (o, c) -> - let expected = expected_bvm_numeral c.c_season ~month:(int_of_string (String.sub c.c_date 5 2)) - ~day:(int_of_string (String.sub c.c_date 8 2)) in - match o.bvm_numeral with - | Some got when String.equal got expected -> None - | Some got -> Some (Printf.sprintf "%s: Ordo says %s, expected %s (season-derived)" o.date got expected) - | None -> Some (Printf.sprintf "%s: colitur says Votive but the Ordo shows no BVM numeral" o.date)) - votive_pairs - in - Alcotest.(check (list string)) "every BVM-Saturday numeral matches its season -- none unexplained" [] mismatches - -(* Reverse direction: every Ordo BVM-numeral day is a colitur Votive day - too (rules out the Ordo naming a Saturday BVM Mass colitur never - computed the office for at all). *) -let test_bvm_numeral_implies_votive () = - let ordo = ordo_rows () in - let colitur = colitur_rows () in - let mismatches = - List.filter_map - (fun (o, c) -> - match (o.bvm_numeral, c.c_formulary) with - | Some n, Some { MF.via = MF.Votive; _ } -> ignore n; None - | Some n, other -> - Some - (Printf.sprintf "%s: Ordo shows %S Mass of BVM but colitur's via is %s" o.date n - (match other with - | Some f -> MF.source_to_string f.MF.via - | None -> "NONE")) - | None, _ -> None) - (List.combine ordo colitur) - in - Alcotest.(check (list string)) "every Ordo BVM numeral day is a colitur Votive day" [] mismatches - -(* ---------------------------------------------------------------------- *) -(* Formulary override, restricted to Proper/Preceding_sunday/Common -- *) +(* Formulary override, restricted to Proper/Common/Preceding_sunday -- *) (* see this file's own header for why Own_slug is excluded, and Votive is *) -(* covered by the BVM checks above instead. *) -(* *) -(* Whole-branch review finding 2: the ORIGINAL version of this test only *) -(* checked WHETHER a Preceding_sunday day showed an override line, never *) -(* WHICH Sunday it named -- so colitur could resume the WRONG Sunday on *) -(* every one of the 66 such days and this layer would stay green (step 3 *) -(* of the reading chain, {!Rite_ef.Lectionary_ef.readings}, is exactly the *) -(* code this was supposed to be testing). Fixed by deriving the EXPECTED *) -(* prose from {!MF.t.said}'s own resolved SLUG -- not by calling colitur's *) -(* own [sunday_slug] a second time (which would make the check tautological, *) -(* the same reasoning this file's own header already gives for *) -(* re-deriving the BVM numeral rather than calling {!Rite_ef. *) -(* Lectionary_ef.bvm_saturday_citations}). The FIRST version of this fix *) -(* instead recomputed the preceding Sunday's DATE and re-derived (season, *) -(* week) via {!Rite_ef.Temporal_ef.temporal} independently -- and was WRONG, caught by its *) -(* own assertion on the very first run: {!Rite_ef.Temporal_ef.temporal}'s raw [week] field *) -(* and the SLUG's own embedded number genuinely diverge for the last *) -(* Sunday before Advent (always slug-numbered "24", whatever the raw week *) -(* count that year -- temporal_ef.ml's own [sunday_slug], the *) -(* [same d last_sunday] branch) and for the "surplus Sundays" that resume *) -(* Epiphany's own numbering when Septuagesima cut it short (same function, *) -(* the [n > 23] branch) -- exactly the two hard cases that function's own *) -(* comment names. Parsing the number back OUT of the already-resolved slug *) -(* sidesteps both: it is not tautological with the wrong-Sunday failure *) -(* mode this whole fix exists to catch (a wrong slug still parses to a *) -(* wrong number, which still fails to match the Ordo's real text), and it *) -(* is simpler and more robust than re-deriving the two special cases a *) -(* second time by hand. *) +(* covered by the BVM checks instead. Unchanged from Task 6 except for *) +(* being read per-window rather than off a single hardcoded fixture. *) (* ---------------------------------------------------------------------- *) -(* English ordinal suffix: 1st, 2nd, 3rd, 4th, 11th, 12th, 13th, 21st... -- - the "teens" exception applies to every multiple of 100 plus 11-13, not - just 11-13 themselves, but nothing in this fixture's own domain (weeks - 1-24) ever reaches three digits, so the simpler [n mod 100] test below - is exercised fully by 11-13 alone and is not a latent bug for values - this function is actually ever called with. *) let ordinal n = let suffix = if n mod 100 >= 11 && n mod 100 <= 13 then "th" - else - match n mod 10 with - | 1 -> "st" - | 2 -> "nd" - | 3 -> "rd" - | _ -> "th" + else match n mod 10 with 1 -> "st" | 2 -> "nd" | 3 -> "rd" | _ -> "th" in Printf.sprintf "%d%s" n suffix -(* [MF.t.said]'s own slug shape for every Preceding_sunday day observed in - the real fixture is [ef--sunday-] ({!Rite_ef.Temporal_ef.sunday_slug}'s - own generic branch -- the ONLY branch that ever reaches a weekday's - [Preceding_sunday] fallback; the specially-NAMED Sundays [ef-low-sunday], - [ef-palm-sunday] etc. are caught by {!Rite_ef.Temporal_ef.named} first and never fall - through to it). Manual parsing, not [Str]/regex (deps frozen): finds the - last "-sunday-" marker and splits on it, since a season word can itself - contain hyphens ("time-after-pentecost") but never contains "-sunday-". *) let parse_sunday_slug slug = let prefix = "ef-" in let plen = String.length prefix in @@ -485,14 +265,23 @@ let parse_sunday_slug slug = let num_str = String.sub body (i + mlen) (blen - i - mlen) in match int_of_string_opt num_str with Some n -> Some (word, n) | None -> None) -(* The Ordo's own prose, derived from [MF.t.said]'s own (season-word, - number) -- verified against every one of the 66 real Preceding_sunday - days in the fixture (test_formulary_override_matches below), not - invented from the naming convention alone. [None] means "this pair is - EXCLUDED from the mapping", handled explicitly by the caller, never - silently -- see [ascension_week_override] just below for the one real - population that lands there. *) -let expected_preceding_sunday_override (word : string) (n : int) = +(* [~season] disambiguates ONE genuinely ambiguous case, found extending + this suite to the 2023-2024 window (2024-11-05..08): colitur's own + "resumed-Sunday tail" (CLAUDE.md's own term) REUSES an Epiphany Sunday's + own slug ([ef-time-after-epiphany-sunday-4]) for a feria whose REAL + calendar date falls in November, inside Time after Pentecost -- Easter + was late enough in 2024 that not every Epiphany Sunday got "used" before + Septuagesima cut the season short, so the leftover ones resume near the + END of the year instead. The Ordo's own prose distinguishes the two + occurrences of the SAME slug by wording alone: "4th Sunday after the + Epiphany" in January, "4th Sunday REMAINING after the Epiphany" in + November (verified directly against the raw dump). [c_season] is the + feria's own actual calendar season -- [Time_after_epiphany] for the + January occurrence, [Time_after_pentecost] for the November one -- so + comparing it against the WORD parsed out of the resumed slug ("time- + after-epiphany" either way) is exactly the signal needed, with no new + colitur-side field required. *) +let expected_preceding_sunday_override ~(season : V.season) (word : string) (n : int) = match (word, n) with | "advent", 1 -> Some "Advent Sunday" | "advent", 2 -> Some "2nd Sunday of Advent" @@ -501,113 +290,118 @@ let expected_preceding_sunday_override (word : string) (n : int) = | "septuagesima", 1 -> Some "Septuagesima Sunday" | "septuagesima", 2 -> Some "Sexagesima Sunday" | "septuagesima", 3 -> Some "Quinquagesima Sunday" - | "time-after-epiphany", n -> Some (Printf.sprintf "%s Sunday after the Epiphany" (ordinal n)) + | "time-after-epiphany", n when season = V.Time_after_epiphany -> + Some (Printf.sprintf "%s Sunday after the Epiphany" (ordinal n)) + | "time-after-epiphany", n -> Some (Printf.sprintf "%s Sunday remaining after the Epiphany" (ordinal n)) | "time-after-pentecost", 24 -> Some "24th & Last Sunday After Pentecost" | "time-after-pentecost", n -> Some (Printf.sprintf "%s Sunday after Pentecost" (ordinal n)) - (* [ef-easter-sunday-]: Paschaltide's own numbering counts Easter - Sunday itself as 1 (Low Sunday, named separately via {!Rite_ef.Temporal_ef.named} and - so never reaching this generic branch at all, is 2), so the ordinal - PRINTED is [n - 1] -- confirmed against every one of n=3..5 in the - fixture ("2nd" through "4th" Sunday after Easter). n=6,7 are - deliberately NOT given here: see [ascension_week_override]. *) - | "easter", n when n >= 3 && n <= 5 -> Some (Printf.sprintf "%s Sunday after Easter" (ordinal (n - 1))) + (* [n >= 3], no upper bound: Task 6's original [n <= 5] excluded n=6/7 on + the (overfit, 2024-2025-window-only) assumption that EVERY such day is + Ascension-adjacent. Extending to 2023-2024/2025-2026 found a REAL + counter-example -- Rogation Monday (RG 87-89), which also resumes + week 6's own Sunday but falls BEFORE Ascension, not after, and the + Ordo prints the ordinary "5th Sunday after Easter" there, not "Mass + of the Ascension". The caller now decides Ascension-adjacency by the + day's own DATE against {!Computus.ascension}, not by [n] -- so this + mapping can be trusted for n=6/7 whenever the caller does not first + divert to [ascension_week_override]. *) + | "easter", n when n >= 3 -> Some (Printf.sprintf "%s Sunday after Easter" (ordinal (n - 1))) | _ -> None -(* One NAMED Sunday (not a generic "ef--sunday-" slug at all) - reaches [Preceding_sunday] in the real 66-day population: Christ the - King ({!Rite_ef.Temporal_ef.christ_the_king}, "the last Sunday of - October"), whose own ferias resume it the same way any other Sunday's - would. Unlike the Septuagesima trio's fixed proper names, its ORDINAL - position among the Sundays after Pentecost is not fixed -- it varies - year to year with Easter's own date -- so there is no string this - function could hard-code the way [expected_preceding_sunday_override] - does for the others. [word]/[n] cannot express it EITHER, because - {!Rite_ef.Temporal_ef.named} overrides the SLUG for that Sunday but, - confirmed directly in temporal_ef.ml ([build ~season ~slug ~colour - ~rank ~week:(week d) ()], called identically whether or not [named] - matched), never the raw [week] FIELD -- so re-deriving that one field - for this one named exception is not the same mistake the first version - of this fix made re-deriving [week] WHOLESALE (that failed on the - season's own two special-numbering cases, both of which this function - sidesteps by reading the slug directly); here there is no slug number - to read in the first place, so [week] is the only source of truth, - narrowly applied to the single slug that needs it. *) let expected_named_sunday_override slug ~year = if String.equal slug "ef-christ-the-king" then match TE.week (TE.christ_the_king year) with | Some n -> Some (Printf.sprintf "%s Sunday after Pentecost" (ordinal n)) | None -> None + (* [ef-low-sunday]: a SECOND named-Sunday population reaching + [Preceding_sunday], found the same way [ef-christ-the-king] was -- + absent from the 2024-2025 window Task 6 built this mapping against + (every Low-Sunday-week feria that year had its own proper), present + in both 2023-2024 (9-12 April 2024) and 2025-2026. The Ordo's own + text is the plain, unnumbered "Mass of Low Sunday". *) + else if String.equal slug "ef-low-sunday" then Some "Low Sunday" else None -(* [n] = 6 or 7 (Paschaltide's own numbering, see the comment above -- the - calendar Sundays traditionally called the 5th and 6th Sunday after - Easter) are STRUCTURALLY, not coincidentally, always Ascension-adjacent: - the Ascension is a fixed Easter+39 (a Thursday inside week 6), so EVERY - feria whose own [Preceding_sunday] fallback would otherwise resolve to - one of these two weeks falls between Ascension Thursday and the - following Saturday, every year, not merely in this fixture's own - 2024-2025 window. A REAL finding, not a fixture artefact: the Ordo - shows "Mass of the Ascension" on all three such days this window - contains (2025-05-30, 2025-06-02, 2025-06-03 -- Friday and the - following Monday/Tuesday, the days between Ascension and the Sunday - after it that have no proper of their own), never "5th"/"6th Sunday - after Easter" -- the Missal keeps saying ASCENSION's own Mass through - this stretch, not the last numbered Sunday's. colitur's step 3 has no - notion of "inside Ascension's own after-feast period" -- it always - resumes the nearest PRECEDING SUNDAY, numbered or not -- so on these - three real days {!MF.t.said} is a plain "ef-easter-sunday-6"/"-7" slug - the Missal would never actually print as such. A genuine content gap in - colitur's reading chain, found by this fix, NOT fixed here (fixing it - means teaching step 3 or the lectionary data about Ascension's own - after-feast period, a lectionary-data change out of this fix round's - own scope) -- recorded honestly, the same way L1 in - expected-divergences-lms.sexp already records the 476(f) gap this same - branch closed, and counted below so a change to this population would - be caught rather than silently absorbed. *) +(* See Task 6's own [ascension_week_override] citation (test_lms_ordo.ml + history, expected-divergences-lms.sexp L2): STRUCTURAL, not a fixture + artefact -- the Ascension is a fixed Easter+39, so every feria whose own + [Preceding_sunday] fallback would otherwise resolve to a week-6/7 Sunday + falls, in SOME years, between Ascension Thursday and the following + Sunday. Extending this suite past the single 2024-2025 window sharpened + the finding: it is specifically the days AFTER Ascension (not merely + "any week-6/7 Preceding_sunday day") that get this treatment -- see + [expected_preceding_sunday_override]'s own citation for the Rogation + Monday counter-example that exposed the difference. [is_ascension_week] + below is the corrected predicate: the day's own DATE compared against + {!Computus.ascension} for its own year, not [n]. *) let ascension_week_override = "Mass of the Ascension" -let test_formulary_override_matches () = - let ordo = ordo_rows () in - let colitur = colitur_rows () in +(* Bounded ABOVE by Pentecost, not merely "later than Ascension" -- a bare + lower bound is wrong for any date past Ascension in the SAME civil year + (every date from June to December satisfies "> Ascension", which a + first version of this predicate did and it manufactured 8 false + failures across the 2024-2025/2025-2026 windows, in July/November/ + December, caught immediately by re-running against those two + previously-clean windows). Task 6's own original population (Friday + after Ascension, then the following Monday/Tuesday) already showed the + window extends PAST the immediately-following Sunday, not merely up to + it, so Pentecost -- the next fixed liturgical anchor, Easter+49 -- is + the natural, provable upper bound: nothing in this stretch has its own + proper once Ascension's octave-like privilege takes over, and Pentecost + itself always does (RG 91 entry 3). *) +let is_after_ascension date = + let year = Date.year date in + Date.compare date (Computus.ascension year) > 0 && Date.compare date (Computus.pentecost year) < 0 + +type formulary_counts = { + fc_bad : string list; + fc_proper : int; + fc_common : int; + fc_preceding_sunday : int; + fc_ascension_week : int; +} + +let check_formulary_overrides ordo colitur = let pairs = List.combine ordo colitur in - let counts = Hashtbl.create 8 in - let bump k = Hashtbl.replace counts k (1 + try Hashtbl.find counts k with Not_found -> 0) in + let proper = ref 0 and common = ref 0 and preceding_sunday = ref 0 and ascension_week = ref 0 in let bad = ref [] in - let ascension_week_count = ref 0 in List.iter - (fun (o, c) -> + (fun ((o : ordo_row), (c : colitur_row)) -> match c.c_formulary with | Some { MF.via = MF.Proper; _ } -> - bump "proper"; + incr proper; if o.formulary_override <> None then bad := Printf.sprintf "%s: Proper day but Ordo shows override %s" o.date (Option.get o.formulary_override) :: !bad | Some { MF.via = MF.Common; _ } -> - bump "common"; + incr common; if o.formulary_override <> None then bad := Printf.sprintf "%s: Common day but Ordo shows override %s" o.date (Option.get o.formulary_override) :: !bad | Some { MF.via = MF.Preceding_sunday; said } -> ( - bump "preceding_sunday"; - (* [said] is [Some] for every constructor except [Votive] (see - {!Colitur_kernel.Mass_formulary.t}'s own citation) -- a bare - [Option.get] here would raise an unhelpful exception if that - ever stopped being true; [Alcotest.failf] names the day - instead. *) + incr preceding_sunday; let slug = match said with | Some s -> Colitur_kernel.Slug.to_string s | None -> Alcotest.failf "%s: Preceding_sunday day with said = None (should be impossible)" o.date in let ordo_says = Printf.sprintf "Mass of %s" in - (* Try the generic [ef--sunday-] shape first; fall back - to the one NAMED Sunday that also reaches this population - ([expected_named_sunday_override], see its own citation) when - the slug doesn't parse that way at all. *) let year = int_of_string (String.sub o.date 0 4) in + let date = match Date.of_iso8601 o.date with Ok d -> d | Error e -> Alcotest.failf "%s: %s" o.date e in + if is_after_ascension date then ( + match o.formulary_override with + | Some got when String.equal got ascension_week_override -> incr ascension_week + | Some got -> + bad := + Printf.sprintf "%s: colitur resumed %S (after Ascension), Ordo shows %S, not the adjudicated %S" + o.date slug got ascension_week_override + :: !bad + | None -> + bad := Printf.sprintf "%s: colitur resumed %S (after Ascension), Ordo shows no override" o.date slug :: !bad) + else let expected = match parse_sunday_slug slug with - | Some (word, n) -> expected_preceding_sunday_override word n + | Some (word, n) -> expected_preceding_sunday_override ~season:c.c_season word n | None -> expected_named_sunday_override slug ~year in match expected with @@ -618,13 +412,8 @@ let test_formulary_override_matches () = | Some got -> bad := Printf.sprintf "%s: colitur resumed %S, Ordo says %S" o.date expected_line got :: !bad | None -> bad := Printf.sprintf "%s: colitur resumed %S, Ordo shows no override" o.date expected_line :: !bad) | None -> ( - (* The Ascension-week exclusion above -- checked, not - assumed: fails loudly if the Ordo's own text ever stops - matching the one string this population is adjudicated to - carry, or if a slug outside every adjudicated case above - ever reaches here. *) match o.formulary_override with - | Some got when String.equal got ascension_week_override -> incr ascension_week_count + | Some got when String.equal got ascension_week_override -> incr ascension_week | Some got -> bad := Printf.sprintf "%s: unmapped (colitur resumed %S) and Ordo shows %S, not the adjudicated %S" o.date @@ -634,33 +423,214 @@ let test_formulary_override_matches () = bad := Printf.sprintf "%s: unmapped (colitur resumed %S) and Ordo shows no override" o.date slug :: !bad)) | Some { MF.via = MF.Votive; _ } | Some { MF.via = MF.Own_slug; _ } | None -> ()) pairs; - Alcotest.(check (list string)) "every formulary-override mismatch is explained -- none unexplained" [] (List.rev !bad); - Alcotest.(check int) "179 Proper days in the window" 179 (try Hashtbl.find counts "proper" with Not_found -> 0); - Alcotest.(check int) "2 Common days in the window" 2 (try Hashtbl.find counts "common" with Not_found -> 0); - Alcotest.(check int) "66 Preceding_sunday days in the window" 66 - (try Hashtbl.find counts "preceding_sunday" with Not_found -> 0); - Alcotest.(check int) "3 Preceding_sunday days fall in the Ascension-week exclusion, no more, no fewer" 3 - !ascension_week_count - -let test_via_distribution_totals_400 () = - let colitur = colitur_rows () in - let via_name c = - match c.c_formulary with - | None -> "none" - | Some f -> MF.source_to_string f.MF.via - in - let counts = Hashtbl.create 8 in - List.iter - (fun c -> Hashtbl.replace counts (via_name c) (1 + try Hashtbl.find counts (via_name c) with Not_found -> 0)) - colitur; - let total = Hashtbl.fold (fun _ n acc -> acc + n) counts 0 in - Alcotest.(check int) "every via bucket sums to the full 400-day window" 400 total + { fc_bad = List.rev !bad; fc_proper = !proper; fc_common = !common; fc_preceding_sunday = !preceding_sunday; + fc_ascension_week = !ascension_week } -let suite = - ( "lms-ordo", +(* ---------------------------------------------------------------------- *) +(* [make_suite]: one edition's worth of tests, parameterised. Every count *) +(* below is a genuine per-edition PIN (measured once against real data, *) +(* not guessed), the same discipline every other golden/oracle fixture in *) +(* this suite already uses -- a change to any of them is a real finding, *) +(* not noise to silence. *) +(* ---------------------------------------------------------------------- *) + +let make_suite ~label ~fixture_path ~fixture_sha256 ~window_first ~window_last ~year_lo ~year_hi ~allow_list_path + ~expected_rows ~expected_bvm_votive ~expected_proper ~expected_common ~expected_preceding_sunday + ~expected_ascension_week = + let test_fixture_checksum () = + Alcotest.(check string) "fixture SHA-256 matches its provenance note" fixture_sha256 + (sha256_of_file fixture_path) + in + let test_dates_align () = + let ordo = ordo_rows fixture_path in + let colitur = colitur_rows ~year_lo ~year_hi ~window_first ~window_last in + Alcotest.(check int) (Printf.sprintf "the Ordo fixture has %d rows (%s..%s)" expected_rows window_first window_last) + expected_rows (List.length ordo); + Alcotest.(check int) "colitur resolved the same number of days" (List.length ordo) (List.length colitur); + (match ordo with o :: _ -> Alcotest.(check string) "first date" window_first o.date | [] -> Alcotest.fail "empty"); + (match List.rev ordo with + | o :: _ -> Alcotest.(check string) "last date" window_last o.date + | [] -> Alcotest.fail "empty"); + let mismatched = + List.filter_map + (fun (o, c) -> if String.equal o.date c.c_date then None else Some (o.date, c.c_date)) + (List.combine ordo colitur) + in + Alcotest.(check (list (pair string string))) "no misaligned dates" [] mismatched + in + (* This window's own Good Friday(s) (Easter-2, RE-DERIVED here from + {!Computus.gregorian_easter} for every civil year the window touches, + never hardcoded) is the only day expected to carry no Ordo Creed + marker at all -- Good Friday has no Mass in the 1955-restored Holy + Week. Exactly one such date falls inside any one edition's ~13-month + window (its OTHER Easter, a year apart, falls outside it), but this + is computed, not assumed: a window that unexpectedly contained zero or + two would be a real finding this test would catch. *) + let window_good_fridays () = + let first_year = int_of_string (String.sub window_first 0 4) in + let last_year = int_of_string (String.sub window_last 0 4) in + let candidates = + List.concat_map + (fun y -> + let gf = Date.add_days (Computus.gregorian_easter y) (-2) in + [ Date.to_iso8601 gf ]) + (List.init (last_year - first_year + 1) (fun i -> first_year + i)) + in + List.filter (fun d -> String.compare d window_first >= 0 && String.compare d window_last <= 0) candidates + in + let test_creed_coverage () = + let ordo = ordo_rows fixture_path in + let no_creed = List.filter (fun o -> o.creed = None) ordo in + let expected = window_good_fridays () in + Alcotest.(check (list string)) "only this window's own Good Friday has no Ordo Creed marker" expected + (List.map (fun o -> o.date) no_creed) + in + let describe_creed_mismatch (o : ordo_row) (c : colitur_row) = + Printf.sprintf "%s %S: colitur creed=%b, Ordo creed=%b (formulary=%s)" o.date o.title c.c_creed + (Option.get o.creed) + (match c.c_formulary with + | Some { MF.said = Some s; _ } -> Colitur_kernel.Slug.to_string s + | Some { MF.said = None; via = MF.Votive } -> "votive (said unnamed in the data)" + | Some { MF.said = None; _ } -> "NONE (said, unexpectedly outside Votive)" + | None -> "NONE") + in + (* Which allow-list id, if any, explains a Creed mismatch on this date. + Date-keyed (not merely "any mismatch is fine") deliberately: an id + that stops firing, or fires on a NEW date it was never adjudicated + for, must be visible as a real change, not silently absorbed by a + loose "some entry explains something" check. Task 6's own version of + this function declared [by_id]/[explained_counts] but never actually + populated the latter (the mechanism this comment sits in) -- L1 was + already CLOSED by the time that task shipped, so it had nothing real + to explain and the gap went unexercised. L3/L4 (Witnesses task, + 2026-08-22, both 2023-2024-only) are the first live tests of it. *) + let allow_list_id_for_date d = + if String.equal d "2024-02-24" then Some "L3" + else if String.equal d "2023-12-24" then Some "L4" + else None + in + let test_creed_matches_or_is_explained () = + let ordo = ordo_rows fixture_path in + let colitur = colitur_rows ~year_lo ~year_hi ~window_first ~window_last in + let allow_list = load_allow_list allow_list_path in + let by_id = List.map (fun e -> (e.id, e)) allow_list in + let unexplained = ref [] in + let explained_counts = Hashtbl.create 8 in + List.iter2 + (fun (o : ordo_row) (c : colitur_row) -> + if not (String.equal o.date c.c_date) then Alcotest.failf "misaligned: ordo %s vs colitur %s" o.date c.c_date; + match o.creed with + | None -> () + | Some ocreed -> + if Bool.equal ocreed c.c_creed then () + else ( + match allow_list_id_for_date o.date with + | Some id -> Hashtbl.replace explained_counts id (1 + try Hashtbl.find explained_counts id with Not_found -> 0) + | None -> unexplained := describe_creed_mismatch o c :: !unexplained)) + ordo colitur; + Alcotest.(check (list string)) (Printf.sprintf "[%s] every Creed mismatch is named in the allow-list -- none unexplained" label) + [] (List.rev !unexplained); + Hashtbl.iter + (fun id n -> + match List.assoc_opt id by_id with + | None -> Alcotest.failf "allow-list entry %s used by the comparator but not declared in %s" id allow_list_path + | Some e -> + Alcotest.(check int) (Printf.sprintf "%s: expected_rows matches the actual count" id) e.expected_rows n) + explained_counts + in + let test_bvm_seasonal_selection () = + let ordo = ordo_rows fixture_path in + let colitur = colitur_rows ~year_lo ~year_hi ~window_first ~window_last in + let votive_pairs = + List.filter_map + (fun (o, c) -> match c.c_formulary with Some { MF.via = MF.Votive; _ } -> Some (o, c) | _ -> None) + (List.combine ordo colitur) + in + Alcotest.(check int) (Printf.sprintf "%d BVM-Saturday (Votive) days fall inside this window" expected_bvm_votive) + expected_bvm_votive (List.length votive_pairs); + let mismatches = + List.filter_map + (fun (o, c) -> + let expected = expected_bvm_numeral c.c_season ~month:(int_of_string (String.sub c.c_date 5 2)) + ~day:(int_of_string (String.sub c.c_date 8 2)) in + match o.bvm_numeral with + | Some got when String.equal got expected -> None + | Some got -> Some (Printf.sprintf "%s: Ordo says %s, expected %s (season-derived)" o.date got expected) + | None -> + (* One SOURCE-TEXT anomaly, found extending this suite to + 2023-2024: 2024-02-03 is the ONLY BVM-Saturday day in the + 2023-2024 fixture (of 12) whose Ordo entry carries no + roman-numeral " Mass of BVM" line at all. Verified + directly against the raw pdftotext dump (not inferred): + every OTHER BVM-Saturday day in this edition prints "Sat + CELEBRATION of the BVM IV Cl W" immediately followed + by its own " Mass of BVM" line; this one date's block + goes straight from the title line to "(Blessing of + throats in honour of St Blaise may be given on this + day)" -- the numeral line the Ordo's own layout convention + would otherwise print is simply MISSING from the printed + text, a publisher-side omission this session cannot + correct, not a colitur defect (colitur's own side is + independently right here: St Blaise is scan-verified + "Com." -- a bare commemoration, not a feast -- in the + calendarium itself, docs/research/LT.txt:4978, so RG 91's + table has no row for him and the BVM-Saturday office + correctly wins the day outright, exactly as colitur + computes). Excluded by name, not silently: a future + change to this population (a different date, or a SECOND + gap) would still be caught below. *) + if String.equal fixture_path "fixtures/lms-ordo-2023-2024.sexp" && String.equal o.date "2024-02-03" then + None + else Some (Printf.sprintf "%s: colitur says Votive but the Ordo shows no BVM numeral" o.date)) + votive_pairs + in + Alcotest.(check (list string)) "every BVM-Saturday numeral matches its season -- none unexplained" [] mismatches + in + let test_bvm_numeral_implies_votive () = + let ordo = ordo_rows fixture_path in + let colitur = colitur_rows ~year_lo ~year_hi ~window_first ~window_last in + let mismatches = + List.filter_map + (fun (o, c) -> + match (o.bvm_numeral, c.c_formulary) with + | Some n, Some { MF.via = MF.Votive; _ } -> ignore n; None + | Some n, other -> + Some + (Printf.sprintf "%s: Ordo shows %S Mass of BVM but colitur's via is %s" o.date n + (match other with Some f -> MF.source_to_string f.MF.via | None -> "NONE")) + | None, _ -> None) + (List.combine ordo colitur) + in + Alcotest.(check (list string)) "every Ordo BVM numeral day is a colitur Votive day" [] mismatches + in + let test_formulary_override_matches () = + let ordo = ordo_rows fixture_path in + let colitur = colitur_rows ~year_lo ~year_hi ~window_first ~window_last in + let r = check_formulary_overrides ordo colitur in + Alcotest.(check (list string)) "every formulary-override mismatch is explained -- none unexplained" [] r.fc_bad; + Alcotest.(check int) (Printf.sprintf "%d Proper days in the window" expected_proper) expected_proper r.fc_proper; + Alcotest.(check int) (Printf.sprintf "%d Common days in the window" expected_common) expected_common r.fc_common; + Alcotest.(check int) (Printf.sprintf "%d Preceding_sunday days in the window" expected_preceding_sunday) + expected_preceding_sunday r.fc_preceding_sunday; + Alcotest.(check int) + (Printf.sprintf "%d Preceding_sunday days fall in the Ascension-week exclusion, no more, no fewer" + expected_ascension_week) + expected_ascension_week r.fc_ascension_week + in + let test_via_distribution_totals () = + let colitur = colitur_rows ~year_lo ~year_hi ~window_first ~window_last in + let via_name c = match c.c_formulary with None -> "none" | Some f -> MF.source_to_string f.MF.via in + let counts = Hashtbl.create 8 in + List.iter + (fun c -> Hashtbl.replace counts (via_name c) (1 + try Hashtbl.find counts (via_name c) with Not_found -> 0)) + colitur; + let total = Hashtbl.fold (fun _ n acc -> acc + n) counts 0 in + Alcotest.(check int) "every via bucket sums to the full window" expected_rows total + in + ( label, [ Alcotest.test_case "fixture SHA-256 matches its provenance note" `Quick test_fixture_checksum; - Alcotest.test_case "streams are 400 rows each, dates aligned 1:1" `Quick test_dates_align; - Alcotest.test_case "only Good Friday has no Ordo Creed marker" `Quick test_creed_coverage; + Alcotest.test_case "streams are N rows each, dates aligned 1:1" `Quick test_dates_align; + Alcotest.test_case "only this window's own Good Friday has no Ordo Creed marker" `Quick test_creed_coverage; Alcotest.test_case "every Creed difference is named in the cited allow-list -- none unexplained" `Quick test_creed_matches_or_is_explained; Alcotest.test_case "every BVM-Saturday numeral matches its season" `Quick test_bvm_seasonal_selection; @@ -668,5 +638,42 @@ let suite = test_bvm_numeral_implies_votive; Alcotest.test_case "formulary override STRING matches on Proper/Common/Preceding_sunday days" `Quick test_formulary_override_matches; - Alcotest.test_case "the via distribution sums to the full window" `Quick test_via_distribution_totals_400 + Alcotest.test_case "the via distribution sums to the full window" `Quick test_via_distribution_totals ] ) + +let allow_list_path = "../data/ef/expected-divergences-lms.sexp" + +(* Guards against a stale allow-list entry (declared in the sexp file, but + the OCaml-side [allow_list_id_for_date] predicate above no longer maps + any date to it, or never did) -- the per-window suites above only prove + an id that DOES fire has the right count; nothing in them can notice an + id that never fires in ANY of the three windows, since each suite only + ever looks at its own explained_counts. Fixed to the two ids this task + added (L3, L4) -- L1 is CLOSED/removed and L2 is deliberately prose-only + (see the sexp file's own header on why), so neither is expected here. *) +let test_allow_list_ids_are_exactly_l3_l4 () = + let ids = List.sort String.compare (List.map (fun e -> e.id) (load_allow_list allow_list_path)) in + Alcotest.(check (list string)) "the LMS allow-list declares exactly L3 and L4" [ "L3"; "L4" ] ids + +let suite_allow_list = ("lms-ordo-allow-list", [ Alcotest.test_case "declares exactly L3 and L4" `Quick test_allow_list_ids_are_exactly_l3_l4 ]) + +let suite_2023_2024 = + make_suite ~label:"lms-ordo-2023-2024" ~fixture_path:"fixtures/lms-ordo-2023-2024.sexp" + ~fixture_sha256:"c8d9d4b790f6b4438e932f70dad8ebe9a0316662f1eb02c26248e04c7be1a62b" ~window_first:"2023-12-01" + ~window_last:"2024-12-31" ~year_lo:2022 ~year_hi:2025 ~allow_list_path ~expected_rows:397 + ~expected_bvm_votive:12 ~expected_proper:182 ~expected_common:2 ~expected_preceding_sunday:61 + ~expected_ascension_week:1 + +let suite_2024_2025 = + make_suite ~label:"lms-ordo-2024-2025" ~fixture_path:"fixtures/lms-ordo-2024-2025.sexp" + ~fixture_sha256:"da817b75c5bf40ed3be1d5f6890b199705e02ce4d42111253ab8547bccabc3f7" ~window_first:"2024-11-27" + ~window_last:"2025-12-31" ~year_lo:2023 ~year_hi:2026 ~allow_list_path ~expected_rows:400 + ~expected_bvm_votive:14 ~expected_proper:179 ~expected_common:2 ~expected_preceding_sunday:66 + ~expected_ascension_week:3 + +let suite_2025_2026 = + make_suite ~label:"lms-ordo-2025-2026" ~fixture_path:"fixtures/lms-ordo-2025-2026.sexp" + ~fixture_sha256:"8839a61e0c7d1e6c8326114f4f45a5c183551287a88f4ed01127154add6ae5a5" ~window_first:"2025-11-28" + ~window_last:"2026-12-31" ~year_lo:2024 ~year_hi:2027 ~allow_list_path ~expected_rows:399 + ~expected_bvm_votive:13 ~expected_proper:174 ~expected_common:2 ~expected_preceding_sunday:68 + ~expected_ascension_week:2 diff --git a/tools/extract_lms_ordo.ml b/tools/extract_lms_ordo.ml index b7c97fd..8680a91 100644 --- a/tools/extract_lms_ordo.ml +++ b/tools/extract_lms_ordo.ml @@ -167,7 +167,36 @@ let scan_block lines = type block = { b_weekday : string; b_day : int; b_month : int; b_year : int; b_title : string; b_lines : string list } -let start_sentinel = [ "End"; "of"; "November"; "2024" ] +(* Generalised (Witnesses task, 2026-08-22) from a single hardcoded + sentinel ["End";"of";"November";"2024"], which assumed every edition + opens its Ordo body with an "End of November " stub section. That + assumption FAILED characterisation against the two newly-acquired + editions: the 2023-2024 PDF has NO such stub -- Advent Sunday 2023 fell + on 3 December, so only 2 tail days of the old liturgical year remained + (1-2 December), and the compiler folded them directly into the + "December 2023" header rather than giving them their own mini-section. + So a start marker anchored to "End of November" cannot generalise. + + What DOES generalise, checked directly against all three editions' + pdftotext -layout dumps: exactly one line in the whole document begins + with the bare, all-uppercase token "ORDO" -- either alone ("ORDO", + 2024-2025/2025-2026, introducing an "End of " stub next) + or fused with the edition's own year range ("ORDO 2023-2024", + introducing the first REAL month header directly, no stub). This is + NEVER the Table of Contents' own entry, which prints title-case "Ordo + 20XX-20XX" followed by dot leaders and a page number -- a different + string ("Ordo", not "ORDO"), confirmed by grepping all three raw dumps + for both patterns before relying on either. *) +let is_ordo_marker tokens = match tokens with "ORDO" :: _ -> true | _ -> false + +(* The "End of " stub heading, when an edition has one -- + parsed directly (never hardcoded to November/a specific year) so the + edition's own initial (month, year) state comes from the text itself, + not an assumption baked into the tool. *) +let parse_end_of_month tokens = + match tokens with + | [ "End"; "of"; m; y ] when is_all_digits y -> ( match month_index m with Some mi -> Some (mi, int_of_string y) | None -> None) + | _ -> None let is_stop_tail_line tokens = match tokens with tok :: _ -> String.length tok = 4 && is_all_digits tok | [] -> false @@ -194,21 +223,52 @@ let () = let arr = Array.of_list all_lines in let n = Array.length arr in let trimmed i = String.trim arr.(i) in - let start_idx = - let rec go i = if i >= n then die "start sentinel %S not found" (String.concat " " start_sentinel) - else if split_ws (trimmed i) = start_sentinel then i else go (i + 1) + let ordo_marker_idx = + let rec go i = if i >= n then die "no line begins with the bare \"ORDO\" body marker (see the tool's own comment on [is_ordo_marker] -- this edition's format may have drifted)" + else if is_ordo_marker (split_ws (trimmed i)) then i else go (i + 1) in go 0 in + (* The first non-blank line after the marker is either an "End of + " stub (consumed here as a pure sentinel, exactly as the old + hardcoded design did -- [start_idx] becomes ITS OWN index so the main + loop below begins right after it) or a real " " header + with an explicit year token (an edition with no stub, e.g. 2023-2024 -- + [start_idx] becomes the ORDO marker's own index instead, so the main + loop re-encounters this header line on its very first iteration and + [is_month_header]'s own existing per-line handling sets [cur_month]/ + [cur_year] from it normally). Either way [init_month]/[init_year] come + directly from parsed text, never a hardcoded constant -- a missing + explicit year on this FIRST header is a genuine format break, so it + dies loudly rather than silently seeding a wrong year. *) + let rec first_nonblank i = + if i >= n then die "no content found after the ORDO marker at line %d" ordo_marker_idx + else if trimmed i = "" then first_nonblank (i + 1) + else i + in + let content_idx = first_nonblank (ordo_marker_idx + 1) in + let content_toks = split_ws (trimmed content_idx) in + let start_idx, init_month, init_year = + match parse_end_of_month content_toks with + | Some (mi, y) -> (content_idx, mi, y) + | None -> ( + match content_toks with + | m :: (y :: _ as rest) when month_index m <> None && List.for_all is_all_digits rest -> + (ordo_marker_idx, (match month_index m with Some x -> x | None -> assert false), int_of_string y) + | _ -> + die "first content after the ORDO marker (%S) is neither an \"End of \" stub nor a \" \" header carrying an explicit year" + (String.concat " " content_toks)) + in let stop_idx = let rec go i = if i >= n then n else if is_stop_tail_line (split_ws (trimmed i)) then i else go (i + 1) in go (start_idx + 1) in - Printf.printf "extract_lms_ordo: Ordo body lines %d..%d (of %d total)\n" start_idx stop_idx n; + Printf.printf "extract_lms_ordo: Ordo body lines %d..%d (of %d total), initial month/year %d/%d\n" start_idx stop_idx n + init_month init_year; (* --- the scan: month/year tracker + block accumulator ------------------ *) - let cur_month = ref 11 and cur_year = ref 2024 in + let cur_month = ref init_month and cur_year = ref init_year in let blocks = ref [] in let cur = ref None in let flush () = match !cur with Some b -> blocks := b :: !blocks; cur := None | None -> () in @@ -306,11 +366,81 @@ let () = Printf.sprintf "%04d-%02d-%02d" (tm.Unix.tm_year + 1900) (tm.Unix.tm_mon + 1) tm.Unix.tm_mday in let pdf_sha = sha256_of_file pdf_path in + (* --- per-edition provenance + characterisation, Witnesses task --------- + Generalised 2026-08-22 from Task 6's single hand-written header (which + named "lms-ordo-2024-2025.sexp" literally throughout). Facts 1/3/4 + below are STRUCTURAL -- true of the publisher's whole known corpus, + re-checked directly against the two new editions' own pdftotext dumps + before being asserted here again, not merely copied forward. Fact 2 + (the Creed opposite-prediction probes) is inherently edition-specific + (the actual calendar dates differ year to year, and one edition's own + calendar even breaks the standard pairing -- see the 2025-2026 note + below), so it is looked up per [dest] and, critically, RE-VERIFIED + against this run's own [rows] before being printed: a probe that + fails is a [die], not a silently-wrong "confirmed" claim in a fixture + header nobody will re-check by eye. *) + let base = Filename.basename dest in + let pdf_base = Filename.basename pdf_path in + let edition_label, isbn, copyright_year, pdf_meta, url, url_note, window_open_desc = + match base with + | "lms-ordo-2023-2024.sexp" -> + ( "2023-2024", + "978-1-7392096-2-9", + "2023", + {|Author "Peter Day-Milne", Producer "LibreOffice 6.4", CreationDate 2023-11-01, 140 pages|}, + "https://lms.org.uk/sites/default/files/u5374/ordo_2023-2024_2.2_final.pdf", + "identified 2026-08-22 via web search matching the PDF's own edition year to the publisher's own hosting path; NOT independently re-downloaded and byte-compared in this session -- recorded honestly rather than presented as verified", + {|1 December 2023 (this edition carries NO "End of November" stub section at all -- Advent Sunday 2023 fell on 3 December, so only 2 tail days of the prior liturgical year remained, and the compiler folded them directly into the "December 2023" header instead of giving them their own mini-section; see CHARACTERISATION below)|} + ) + | "lms-ordo-2025-2026.sexp" -> + ( "2025-2026", + "978-1-7392096-5-0", + "2025", + {|Author "Peter Day-Milne", Producer "LibreOffice 25.2.6.2 (X86_64) / LibreOffice Community", CreationDate 2025-10-23, 146 pages|}, + "(not found -- see the note on this line)", + "NOT found by URL-pattern web search this session (unlike the 2023-2024 and 2024-2025 editions, no exact download link matching this PDF's own filename/version turned up under lms.org.uk/sites/default/files/u5374/; several near-miss candidates were checked and rejected -- none matched this PDF's own metadata) -- left honestly blank rather than guessed; the file was supplied locally to this session, not fetched by this tool", + {|28 November 2025 ("End of November 2025", the same shape as the 2024-2025 edition -- Advent Sunday 2025 fell on 30 November, so only 3 tail days remained; note this excludes 27 November 2025, which the PRECEDING edition's own window (2024-2025, through 2025-12-31) already covers -- a one-day-short overlap between consecutive editions' own windows, not a gap or a bug in either extraction|} + ) + | _ -> die "no provenance/characterisation entry for %s -- add one to extract_lms_ordo.ml's own per-edition table before generating this fixture (the tool refuses to emit an under-characterised header)" base + in + let creed_of_date rows d = List.find_map (fun r -> if String.equal r.date d then r.creed else None) rows in + let probes = + match base with + | "lms-ordo-2023-2024.sexp" -> + [ ("2023-12-03", true, "Advent Sunday, RG 475(a)"); + ("2023-12-04", false, "St Peter Chrysologus, III class, ordinary Advent day, RG 476(b)/(d)"); + ("2023-12-26", true, "St Stephen, II class, inside the Nativity octave, RG 475(d)"); + ("2024-08-15", true, "the Assumption, I class, RG 475(b)"); + ("2024-08-16", false, "St Joachim, II class, no Lord/BVM/apostle clause applies, RG 476(b)") ] + | "lms-ordo-2025-2026.sexp" -> + [ ("2025-11-30", true, "Advent Sunday, RG 475(a)"); + ("2025-12-01", false, "ordinary Advent feria, RG 476(b)/(d)"); + ("2025-12-26", true, "St Stephen, II class, inside the Nativity octave, RG 475(d)"); + ( "2026-08-10", false, + "St Laurence, II class martyr, no Lord/BVM/apostle clause applies, RG 476(b) -- St Joachim (16 August) is IMPEDED by a Sunday in this edition's own calendar (12th Sunday after Pentecost), so this edition needed a DIFFERENT sharp non-octave II-class pairing than the 2023-2024/2024-2025 editions used; a real, edition-specific finding, not an extraction quirk" + ); + ("2026-08-15", true, "the Assumption, I class, RG 475(b)") ] + | _ -> die "no probe list for %s" base + in + List.iter + (fun (d, expected, desc) -> + match creed_of_date rows d with + | Some got when Bool.equal got expected -> () + | Some got -> die "characterisation probe FAILED: %s (%s) -- expected creed=%b, extracted creed=%b" d desc expected got + | None -> die "characterisation probe FAILED: %s (%s) -- no row extracted for this date at all" d desc) + probes; + Printf.printf "extract_lms_ordo: all %d characterisation probes confirmed for %s\n" (List.length probes) edition_label; + let probe_lines = + String.concat "\n" + (List.map + (fun (d, expected, desc) -> Printf.sprintf "; %s (%s) -> %s" d desc (if expected then "TRUE" else "FALSE")) + probes) + in let header = Printf.sprintf - {|; test/fixtures/lms-ordo-2024-2025.sexp -- Task 6 (2026-08-21-colitur- -; celebrant-rubrics-phase1)'s sixth validation layer: the Latin Mass -; Society's own printed Ordo, an England & Wales diocesan Ordo -- a + {|; %s -- Witnesses task (2026-08-22-colitur-celebrant-rubrics-phase1), +; extending Task 6's single LMS fixture (2024-2025) to three editions of +; the Latin Mass Society's own printed Ordo for England & Wales -- a ; lineage independent of Divinum Officium/missalemeum/lectio (layers 3-4) ; and of the electronic LT.txt transcription (layers 1-2/5): a physically ; printed, professionally-compiled liturgical calendar with its own ISBN. @@ -318,97 +448,94 @@ let () = ; Generator: tools/extract_lms_ordo.ml -- do not hand-edit; re-run against ; a fresh pdftotext dump and commit the diff instead. ; -; Source: "The Ordo 2024-2025", compiled by Peter Day-Milne, The Latin +; Source: "The Ordo %s", compiled by Peter Day-Milne, The Latin ; Mass Society, 9 Mallow Street, London EC1Y 8RQ (title page and ; colophon, verified directly against the PDF's own extracted text -- -; ISBN 9781739209636, Copyright (c) The Latin Mass Society, UK 2024). -; PDF metadata: Author "Peter Day-Milne", Producer "LibreOffice 7.4", -; CreationDate 2024-11-06, 140 pages. -; URL (identified 2026-08-22 via web search matching the PDF's own -; version number and filename to the publisher's own hosting path; -; NOT independently re-downloaded and byte-compared in this session -- -; recorded honestly rather than presented as verified): -; https://lms.org.uk/sites/default/files/u5374/ordo_2.21_2024-2025.pdf -; (product page: https://lms.org.uk/product/latin-mass-society-ordo-2024-25) -; The local PDF (docs/research/ordo/lms-ordo-2024-2025.pdf) is gitignored +; ISBN %s, Copyright (c) The Latin Mass Society, UK %s). +; PDF metadata: %s. +; URL (%s): +; %s +; The local PDF (docs/research/ordo/%s) is gitignored ; (CLAUDE.md: "docs/ is gitignored"), so this header, not git, is this ; fixture's only record of where it came from. -; SHA-256 of docs/research/ordo/lms-ordo-2024-2025.pdf: %s +; SHA-256 of docs/research/ordo/%s: %s ; Extracted (UTC): %s ; Exact commands: -; pdftotext -layout docs/research/ordo/lms-ordo-2024-2025.pdf /tmp/lms.txt +; pdftotext -layout docs/research/ordo/%s /tmp/lms.txt ; dune exec tools/extract_lms_ordo.exe -- /tmp/lms.txt \ -; docs/research/ordo/lms-ordo-2024-2025.pdf test/fixtures/lms-ordo-2024-2025.sexp +; docs/research/ordo/%s %s ; -; COVERAGE: %d day-rows, %s through %s (2024-11-27, "End of November 2024", +; COVERAGE: %d day-rows, %s through %s (starting %s, ; through the day before a malformed trailing entry the extractor ; deliberately stops before -- see CHARACTERISATION below). ; ; CHARACTERISATION FINDINGS (Step 1, non-negotiable per the task brief -- ; the extraordinaryform.org Ordo silently omitted St Lawrence's vigil on ; EVERY date it covered, which nearly produced a false corroboration -; during the RG 33 work; this Ordo was probed with the same discipline -; before a single divergence was adjudicated): +; during the RG 33 work; every LMS edition, including this one, is probed +; with the same discipline before a single divergence is adjudicated): ; -; 1. Gl/Cr are printed PER MASS-OPTION, not per day (confirmed: this PDF -; alone -- not the multi-year corpus the task brief's own grep count -; was measured against -- carries many more Gl/Cr pairs than day-rows, -; because every diocesan variant repeats its own "Gl ... Cr ... Pr of -; ..." line). This extractor resolves the day's OWN office by taking -; the FIRST Gl/Cr pair in reading order, which the source's own layout +; 1. Gl/Cr are printed PER MASS-OPTION, not per day (confirmed again for +; THIS edition: it carries many more Gl/Cr pairs than day-rows, because +; every diocesan variant repeats its own "Gl ... Cr ... Pr of ..." +; line). This extractor resolves the day's OWN office by taking the +; FIRST Gl/Cr pair in reading order, which the source's own layout ; guarantees is the universal entry's (diocesan variants are always ; introduced by a colon-terminated diocese-list line that comes AFTER ; the universal block, never before -- checked structurally, not -; assumed, in every sampled block during development). +; assumed, in every sampled block during development, this edition +; included). ; ; 2. OPPOSITE-PREDICTION PROBES against Rite_ef.Rubrics_ef.creed (RG -; 475-476), checked BEFORE trusting a single row of this fixture -- +; 475-476), RE-CHECKED BY THIS TOOL RUN (not merely copied from a prior +; edition's findings) before a single row of this fixture is trusted -- ; the technique CLAUDE.md records as the one that catches a source -; silently omitting the very thing it is meant to witness: -; 2024-12-01 (Advent Sunday, RG 475(a)) -- Ordo "No Gl Cr" -> TRUE -; 2024-12-02 (ordinary Advent feria) -- Ordo "Gl No Cr" -> FALSE -; 2024-12-26 (St Stephen, II class, but inside the Nativity octave, -; RG 475(d)) -- Ordo "Gl Cr" -> TRUE -; 2025-08-15 (the Assumption, I class, RG 475(b)) -; -- Ordo "Gl Cr" -> TRUE -; 2025-08-16 (St Joachim, II class, no Lord/BVM/apostle clause -; applies, RG 476(b)) -- Ordo "Gl No Cr" -> FALSE -; All five predictions confirmed, both directions (TRUE and FALSE each -; independently witnessed, including the Stephen/Joachim pair, which -; are BOTH II-class non-Sunday saints and differ ONLY on the octave -; question) -- this source is discriminating, not a constant, on the -; Creed. See task-6-report.md for the full record. +; silently omitting the very thing it is meant to witness. This run's +; own extracted [rows] were checked against every one of the following +; before this header was even written; a failure here is a hard [die], +; not a printed claim: +%s +; All %d predictions confirmed, both directions (TRUE and FALSE each +; independently witnessed) -- this edition is discriminating, not a +; constant, on the Creed. ; ; 3. The BVM-Saturday roman numeral (I-V, "Missae de sancta Maria in ; sabbato", RG 309(a)) is anchored by WHOLE-LINE match against the five ; literal strings below, NEVER by substring search: "V Mass of BVM" is ; a substring of "IV Mass of BVM", so a naive `contains` check ; misreads every fourth-Mass day as the fifth (the coordinator's own -; misreading, recorded and retracted in commit 27b07b4 before this -; task existed). +; misreading, recorded and retracted in commit 27b07b4 before Task 6 +; existed; the same anchoring logic runs unchanged for every edition). ; ; 4. SCOPE EXCLUDED, quantified, not silently dropped: ; - Diocesan variants: present on %d of %d days (%s%%) -- their own ; text is read only far enough to set [has_diocesan_variant], ; never compared, because colitur computes the UNIVERSAL General ; Roman Calendar only, with no diocesan overlay loaded. -; - The single malformed trailing entry ("2025 1 The OCTAVE DAY of -; the NATIVITY..." printed with "Thu" wrapped onto the following -; line and the year token "2025" where "2026" belongs -- a literal -; duplicate, word for word, of the fixture's own already-extracted -; 2025-01-01 row) is excluded outright: the extractor's own stop -; marker (a line whose first token is a bare 4-digit year) halts -; the scan before it, so this fixture's last row is 2025-12-31. +; - The single malformed trailing entry ("...The OCTAVE DAY of the +; NATIVITY..." with a bare 4-digit token where a weekday+day-number +; pair belongs) is excluded outright: the extractor's own stop +; marker (a line whose first token is a bare 4-digit token) halts +; the scan before it. CONFIRMED IDENTICAL, word for word, across +; ALL FOUR known editions of this publisher's Ordo (2023-2024, +; 2024-2025, 2025-2026, and the 2024-2025 fixture's own prior +; header) -- always the literal stray year token "2025", regardless +; of which edition or which real trailing year it should read: a +; stale copy-paste leftover the compiler's own master document +; carries forward unedited release to release (even the 2024-2025 +; PDF's own tail page footer nearby still reads "Latin Mass Society +; Ordo 2021-2022"), not something specific to this edition. ; - Front matter, the Abbreviations/Rubrical-Primer/Breviary sections, ; and the "When may I say...?"/Appendix tail are never scanned at -; all (the extractor's own start/stop sentinels bound it to the -; Ordo proper, "End of November 2024" through the stop marker -; above). +; all (the extractor's own start/stop markers bound it to the Ordo +; proper). |} - pdf_sha (today ()) (List.length rows) + dest edition_label isbn copyright_year pdf_meta url_note url pdf_base pdf_base pdf_sha (today ()) pdf_base + pdf_base dest + (List.length rows) (match rows with r :: _ -> r.date | [] -> "?") (match List.rev rows with r :: _ -> r.date | [] -> "?") - with_variant (List.length rows) + window_open_desc probe_lines (List.length probes) with_variant (List.length rows) (Printf.sprintf "%.1f" (100.0 *. float_of_int with_variant /. float_of_int (List.length rows))) in let body = Sexplib.Sexp.to_string_hum ~indent:2 (sexp_of_list sexp_of_row rows) in -- cgit v1.3 From 96aed1b6f04ef89e8f3d18af8b13e6fd30dbd4d2 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Sat, 22 Aug 2026 15:11:43 +0200 Subject: test(fiuv-ordo): add the FIUV universal Ordo as a second, independent witness MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wires in the FIUV (Foederatio Internationalis Una Voce) Ordo for 2025-2026 as validation layer seven -- the first UNIVERSAL (not diocesan) source in this project, and the first compiled by someone other than the LMS editions' own Peter Day-Milne (Joseph Shaw, FIUV President). tools/extract_fiuv_ordo.ml hand-parses pdftotext's -layout dump of the Latin-language ordo (no Str/regex, frozen deps). Three real parsing traps were found and fixed by tracing actual false results against the raw source, not assumed in advance: - "Gloria" is also the first word of "Gloria Patri" (the psalm doxology), which can appear INSIDE the very Mass clause being scanned (Good Friday: "...omittuntur ps. Iudica me et Gloria Patri), Gloria, sine Credo..."). Guarded by rejecting any "Gloria" hit whose next token is "Patri". - Christmas Day's own rubric uses the PLURAL "Missae"/"Missae" ("tres Missae celebrantur..."), never the singular "Missa" every other real day anchors on -- silently produced gloria=None/credo=None on the one most doctrinally unambiguous day in the calendar until traced and fixed, guarded in turn against "Missae defunctorum" (an unrelated Requiem-prohibition notice appearing at the end of many day-blocks). - The Vespers boundary (bounding the primary Mass option before a second "Vel Missa" alternative or before Vespers information) missed the ligature spelling "VESPERÆ", the dominant form in this source, letting a whole day's trailing prose leak into the captured [praef] field on the task brief's own worked example day (19 September). A distinct second stop-marker bug: the malformed trailing entry this source shares structurally with the LMS PDFs (a stray, mislabelled duplicate of 1 January) was initially over-matched by a generic "first token is 4 digits" heuristic, which false-positived on an indulgence-decree date citation wrapped mid-sentence in October ("...20 augusti / 1885, 26 augusti 1886..."), truncating the extraction to 308 of 400 real days. Fixed by anchoring on the tail entry's own distinctive "1st Jan" opening instead. Five opposite-prediction Creed probes are re-verified by the tool itself against its own extracted rows (a failed probe is a hard exit, not a printed claim) before the fixture is written. test/test_fiuv_ordo.ml compares the Creed against colitur across all 399 comparable days (Holy Saturday excluded, no Mass that day) -- CLEAN, zero unexplained divergences, a genuine second confirmation of {!Rite_ef.Rubrics_ef.creed} independent of the LMS lineage. [praef], [te_deum] and [class_] (including the FIUV ordo's own "III cl." vs "III cl. (Priv.)" Cum Sanctissima convention, stated on its title page) are captured into the fixture but deliberately not compared -- colitur has no Gloria/preface predicate yet, and its default configuration models no Cum Sanctissima overlay to compare the class convention against. All 634 tests green (dune test), 635 with the exhaustive sweep and make check. No lib/ file touched. Claude-Session: https://claude.ai/code/session_017ZBxCCRM2ojnBupp3SBxV9 --- data/ef/expected-divergences-fiuv.sexp | 26 + test/dune | 2 + test/fixtures/fiuv-ordo-2025-2026.sexp | 1558 ++++++++++++++++++++++++++++++++ test/test_colitur.ml | 2 +- test/test_fiuv_ordo.ml | 268 ++++++ tools/dune | 14 + tools/extract_fiuv_ordo.ml | 637 +++++++++++++ 7 files changed, 2506 insertions(+), 1 deletion(-) create mode 100644 data/ef/expected-divergences-fiuv.sexp create mode 100644 test/fixtures/fiuv-ordo-2025-2026.sexp create mode 100644 test/test_fiuv_ordo.ml create mode 100644 tools/extract_fiuv_ordo.ml (limited to 'data/ef') diff --git a/data/ef/expected-divergences-fiuv.sexp b/data/ef/expected-divergences-fiuv.sexp new file mode 100644 index 0000000..5506e46 --- /dev/null +++ b/data/ef/expected-divergences-fiuv.sexp @@ -0,0 +1,26 @@ +; data/ef/expected-divergences-fiuv.sexp -- Witnesses task +; (2026-08-22-colitur-celebrant-rubrics-phase1)'s cited allow-list for the +; FIUV Ordo comparison (test/test_fiuv_ordo.ml), fixture window +; 2025-11-27..2026-12-31. +; +; A SEPARATE file from data/ef/expected-divergences-lms.sexp (the LMS +; allow-list, also third-party but England & Wales diocesan and single- +; compiler across its three editions), data/ef/expected-divergences.sexp +; (the lectio allow-list) and data/ef/expected-divergences-missalemeum.sexp +; (the missalemeum/Divinum-Officium-lineage allow-list): the FIUV Ordo is +; a FOURTH, independent lineage -- universal, not diocesan, compiled by a +; different person (Joseph Shaw) than the LMS editions (Peter Day-Milne). +; +; [verdict] names which side this task's own primary-source research +; backs, the SAME convention every other allow-list file in this project +; uses: not always "colitur". +; +; Empty as of this task: the Creed comparison found no unexplained +; divergence anywhere in the 400-day window (399 comparable days, Holy +; Saturday excluded per test_creed_coverage -- see that test's own +; citation). Kept as a file, not deleted, on the same footing as +; expected-divergences-lms.sexp's own empty-but-live state after L1's +; closure: the machinery that would explain a FUTURE divergence needs +; somewhere to live, and an empty allow-list with a live "every entry +; must be used" check is a real invariant worth keeping, not a +; formality. diff --git a/test/dune b/test/dune index 17865c4..374fa8f 100644 --- a/test/dune +++ b/test/dune @@ -10,6 +10,7 @@ ../data/ef/expected-divergences.sexp ../data/ef/expected-divergences-missalemeum.sexp ../data/ef/expected-divergences-lms.sexp + ../data/ef/expected-divergences-fiuv.sexp ../data/ef/lectionary.sexp ../data/ef/commons.sexp ../data/ef/examples/diocesan-example.sexp @@ -20,6 +21,7 @@ fixtures/lms-ordo-2023-2024.sexp fixtures/lms-ordo-2024-2025.sexp fixtures/lms-ordo-2025-2026.sexp + fixtures/fiuv-ordo-2025-2026.sexp ../templates/ef/ordo.tex ../templates/ef/ordo.ms ../templates/ef/ordo.html diff --git a/test/fixtures/fiuv-ordo-2025-2026.sexp b/test/fixtures/fiuv-ordo-2025-2026.sexp new file mode 100644 index 0000000..7b72ca3 --- /dev/null +++ b/test/fixtures/fiuv-ordo-2025-2026.sexp @@ -0,0 +1,1558 @@ +; test/fixtures/fiuv-ordo-2025-2026.sexp -- Witnesses task (2026-08-22-colitur- +; celebrant-rubrics-phase1)'s SEVENTH validation layer, and the first +; UNIVERSAL (non-diocesan), SECOND-COMPILER witness: the FIUV (Foederatio +; Internationalis Una Voce) Ordo, compiled independently of the Latin Mass +; Society's own three editions (test/test_lms_ordo.ml) -- see +; docs/research/ordo/PROVENANCE-ordo-corpus.md for the full four-reasons +; account of why this source is the more valuable of the two newly- +; acquired ones. +; +; Generator: tools/extract_fiuv_ordo.ml -- do not hand-edit; re-run +; against a fresh pdftotext dump and commit the diff instead. +; +; Source: "Ordo Divini Officii recitandi sacrique peragendi secundum +; antiquam Ritus Romani formam pro anno Domini 2026", Foederatio +; Internationalis Una Voce, compiled by Joseph Shaw (Praefatio signed +; "Joseph Shaw, President", Feast of the Nativity of Our Lady [8 Sept] +; 2025) -- title page and Praefatio, verified directly against the PDF's +; own extracted text. 2025 is stated as the Federation's own 60th +; anniversary year. +; PDF metadata: Creator "TeX", Producer "pdfTeX-1.40.22", CreationDate +; 2025-11-08, 128 pages. +; URL: identified via web search as +; https://lms.org.uk/sites/default/files/u5374/fiuv_ordo_2025-2026_1.1_a5_format.pdf +; (hosted by the Latin Mass Society's own site alongside its own three +; editions -- Joseph Shaw is both FIUV President and LMS Chairman, which +; plausibly also explains why this PDF's own trailing malformed entry +; (see COVERAGE below) is structurally identical to the LMS PDFs' own, +; despite the two being compiled by different people); NOT independently +; re-downloaded and byte-compared in this session -- recorded honestly +; rather than presented as verified, the same discipline the LMS +; fixtures' own headers use. +; The local PDF (docs/research/ordo/fiuv-ordo-2025-2026.pdf) is gitignored (CLAUDE.md: "docs/ +; is gitignored"), so this header, not git, is this fixture's only record +; of where it came from. +; SHA-256 of docs/research/ordo/fiuv-ordo-2025-2026.pdf: 4335cc112b5fb6ec4d9511465ccc9381bed9b6056a56bc82dbaa5b2d85d0d855 +; Extracted (UTC): 2026-08-22 +; Exact commands: +; pdftotext -layout docs/research/ordo/fiuv-ordo-2025-2026.pdf /tmp/fiuv.txt +; dune exec tools/extract_fiuv_ordo.exe -- /tmp/fiuv.txt \ +; docs/research/ordo/fiuv-ordo-2025-2026.pdf test/fixtures/fiuv-ordo-2025-2026.sexp +; +; COVERAGE: 400 day-rows, 2025-11-27 through 2026-12-31. Starts at the book's own first +; real content line ("November MMXXV", the FIRST month header found with +; a parseable Roman-numeral year -- used as this parser's sole date +; anchor, see the tool's own header on why no LATER header's year is ever +; read, the second one being a publisher typo, "December MMXV" for 2025). +; Stops before a malformed trailing entry, structurally the SAME artefact +; found in all three LMS editions (a stray, mislabelled duplicate of the +; fixture's own already-extracted 1 January row, headed "1st Jan / 2025." +; -- see extract_lms_ordo.ml's own COVERAGE section for the fuller +; account of this shared publisher-side quirk). +; +; CHARACTERISATION FINDINGS (non-negotiable per the task brief -- the +; extraordinaryform.org Ordo silently omitted St Lawrence's vigil on +; EVERY date it covered, which nearly produced a false corroboration +; during the RG 33 work; this Ordo was probed with the same discipline +; before a single divergence was adjudicated): +; +; 1. UNIVERSAL, not diocesan: unlike the three LMS editions (which had to +; exclude diocesan variants from every comparison, quantified in each +; of their own fixture headers), this Ordo carries ONE block per day, +; always. There is no [has_diocesan_variant] field in this fixture's +; own [row] at all -- there is nothing to exclude. +; +; 2. OPPOSITE-PREDICTION PROBES against Rite_ef.Rubrics_ef.creed (RG +; 475-476), RE-CHECKED BY THIS TOOL RUN against its own extracted +; [rows] before this header was even written -- a failed probe is a +; hard [die], never a printed claim: +; 2025-11-30 (Advent Sunday, I class, RG 475(a)) -> TRUE +; 2025-12-01 (ordinary Advent feria, III class, RG 476(b)/(d)) -> FALSE +; 2025-12-26 (St Stephen, II class, inside the Nativity octave, RG 475(d)) -> TRUE +; 2026-08-10 (St Laurence, II class martyr, no Lord/BVM/apostle clause applies, RG 476(b)) -> FALSE +; 2026-08-15 (the Assumption, I class, RG 475(b)) -> TRUE +; All 5 predictions confirmed, both directions -- this source is +; discriminating, not a constant, on the Creed. +; +; 3. THE SUBSTRING TRAP this parser defends against, found live in this +; corpus: "Gloria" is also the first word of "Gloria Patri" (the psalm +; doxology), which can appear INSIDE the very Mass clause being +; scanned (Good Friday, 3 April 2026: "Missa pr., (omittuntur ps. +; Iudica me et Gloria Patri), Gloria, sine Credo, praef. comm." -- the +; real, standalone Gloria mention follows immediately after). See +; [find_word]'s own citation. +; +; 4. RAW SUBSTRING COUNTS measured against this session's own pdftotext +; dump, for comparison against the task brief's own figures (328 +; Gloria / 132 sine Gloria / 119 Credo / 260 sine Credo, 262 Te Deum): +; "sine Gloria" 132 (EXACT match), "sine Credo" 260 (EXACT match), raw +; "Te Deum" substring 262 (EXACT match, includes negated occurrences +; as substring hits -- 42 of them are "non dicitur Te Deum"). Raw +; "Gloria"/"Credo" substring totals (494/411) do NOT match the brief's +; implied positive totals (328/119) even after subtracting the 25 +; "Gloria Patri" occurrences (469, still 9 over) -- not chased further +; here; this extractor's own token-scoped, Missa-clause-bounded counts +; below are what this fixture actually asserts, not a forced match to +; the brief's approximate figures. +; +; MEASURED DISTRIBUTION (this extraction, not the brief's figures): Gloria +; true=269 false=130 unresolved=1; Credo true=116 false=283 unresolved=1; +; Te Deum true=231 false=42 unresolved=127. +(((date 2025-11-27) (class_ ("IV cl.")) + (title "Vir Feria V post Dom. XXIV & Ultima post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2025-11-28) (class_ ("IV cl.")) + (title "Vir Feria VI post Dom. XXIV & Ultima post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2025-11-29) (class_ ("IV cl.")) + (title "Alb Sabb. S. Maria in Sabbato,") (te_deum (true)) (gloria (true)) + (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147"))) + ((date 2025-11-30) (class_ ("I cl.")) + (title "Viol DOM. I ADVENTUS, De ea,") (te_deum (true)) (gloria (false)) + (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2025-12-01) (class_ ("III cl.")) + (title "Viol Feria II post Dom. I Adventus, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2025-12-02) (class_ ("III cl.")) + (title "Rub Feria III. S Bibianae Virg. et Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. AD"))) + ((date 2025-12-03) (class_ ("III cl. (Priv.)")) + (title "Alb Feria IV. S Francisci Xavierii Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. AD"))) + ((date 2025-12-04) (class_ ("III cl.")) + (title "Alb Feria V. S Petri Chrysologi Ep., Conf. et Eccl. Doct.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef + ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa S Barbarae Virg. et Mart. (rub.) Loquebar de testimoniis tuis, Gloria, comm. 1\194\170 Feriae, comm. 2\194\170 S Petri Chrysologi Ep., Conf. et Eccl. Doct., praef. comm. vel de Martyribus. AD"))) + ((date 2025-12-05) (class_ ("III cl.")) + (title "Viol Feria VI post Dom. I Adventus, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) + (praef ("comm. Feria VI prima in mense."))) + ((date 2025-12-06) (class_ ("III cl. (Priv.)")) + (title "Alb Sabb. S Nicolai Ep. et Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef ("comm. Sabbatum primum in mense. I"))) + ((date 2025-12-07) (class_ ("I cl.")) + (title "Viol DOM. II ADVENTUS, De ea,") (te_deum (true)) (gloria (false)) + (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2025-12-08) (class_ ("I cl.")) + (title "Alb Feria II. IN CONCEPTIONE IMMACULATA B. MARIAE VIRGINIS,") + (te_deum ()) (gloria (true)) (credo (true)) + (praef ("BMV Et te in Conceptione Immaculata. AD"))) + ((date 2025-12-09) (class_ ("III cl.")) + (title "Viol Feria III post Dom. II Adventus, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2025-12-10) (class_ ("III cl.")) + (title "Viol Feria IV post Dom. II Adventus, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2025-12-11) (class_ ("III cl. (Priv.)")) + (title "Alb Feria V. S Damasi I Papae et Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. AD"))) + ((date 2025-12-12) (class_ ("III cl.")) + (title "Viol Feria VI post Dom. II Adventus, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2025-12-13) (class_ ("III cl. (Priv.)")) + (title "Rub Sabb. S Luciae Virg. et Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. I"))) + ((date 2025-12-14) (class_ ("I cl.")) + (title "Viol/ DOM. III ADVENTUS (GAUDETE), De ea,") (te_deum (true)) + (gloria (false)) (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2025-12-15) (class_ ("III cl.")) + (title "Viol Feria II post Dom. III Adventus (Gaudete), De ea,") + (te_deum ()) (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2025-12-16) (class_ ("III cl.")) + (title "Alb Feria III. S Eusebii Ep. et Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. AD"))) + ((date 2025-12-17) (class_ ("II cl.")) + (title "Viol FERIA IV QUATTUOR TEMP., De ea,") (te_deum ()) + (gloria (false)) (credo (false)) + (praef ("comm.\226\128\147 Quoad Flectamus genua vide RM 440."))) + ((date 2025-12-18) (class_ ("II cl.")) + (title "Viol FERIA V POST DOM. III ADVENTUS (GAUDETE), De ea,") + (te_deum ()) (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2025-12-19) (class_ ("II cl.")) + (title "Viol FERIA VI QUATTUOR TEMP., De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2025-12-20) (class_ ("II cl.")) + (title "Viol SABB. QUATTUOR TEMP., De eo,") (te_deum ()) (gloria (false)) + (credo (false)) + (praef + ("comm. \226\128\147 Quoad Flectamus genua vide RM 440. Quoad lectiones vide RM 468. I"))) + ((date 2025-12-21) (class_ ("I cl.")) + (title "Viol DOM. IV ADVENTUS, De ea,") (te_deum (true)) (gloria (false)) + (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2025-12-22) (class_ ("II cl.")) + (title "Viol FERIA II POST DOM. IV ADVENTUS, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2025-12-23) (class_ ("II cl.")) + (title "Viol FERIA III POST DOM. IV ADVENTUS, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2025-12-24) (class_ ("I cl.")) + (title "Viol Feria IV. VIGILIA NATIVITATIS DOMINI,") (te_deum (true)) + (gloria (false)) (credo (false)) (praef ("comm. I"))) + ((date 2025-12-25) (class_ ("I cl.")) + (title "Alb Feria V. IN NATIVITATE DOMINI,") (te_deum ()) (gloria (true)) + (credo (true)) + (praef + ("et Communic. pr. per totam oct. \226\128\147 In Communicantes: in 1\194\170 Missa dicitur Noctem sacratissimam celebrantes, qua, in 2\194\170 et 3\194\170 Missa et per octavam Diem sacratissimum celebrantes, quo. \226\128\147 In 2\194\170 Missa (etiam in cantu) fit comm. S. Anastasi\195\166 * M. \226\128\147 In Missis in cantu, ad verba symboli Et incarnatus est\226\128\166 et homo factus est, omnes genuflectunt versus altare, non tantum cum a celebrante recitantur, sed etiam cum a choro canuntur (RM 518 b). II"))) + ((date 2025-12-26) (class_ ("II cl.")) + (title "Rub Feria VI. S STEPHANI * PROTOMARTYRIS,") (te_deum ()) + (gloria (true)) (credo (true)) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. AD"))) + ((date 2025-12-27) (class_ ("II cl.")) + (title "Alb Sabb. S IOANNIS * AP. ET EV.,") (te_deum ()) (gloria (true)) + (credo (true)) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. AD"))) + ((date 2025-12-28) (class_ ("II cl.")) + (title "Alb DOM. INFRA OCTAVAM NATIVITATIS, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. Ad II"))) + ((date 2025-12-29) (class_ ("II cl.")) + (title "Alb FERIA II DOM. INFRA OCTAVAM NATIVITATIS, De ea,") + (te_deum ()) (gloria (true)) (credo (true)) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum."))) + ((date 2025-12-30) (class_ ("II cl.")) + (title "Alb FERIA III DOM. INFRA OCTAVAM NATIVITATIS, De ea,") + (te_deum ()) (gloria (true)) (credo (true)) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum."))) + ((date 2025-12-31) (class_ ()) + (title + "Alb FERIA IV DOM. INFRA OCTAVAM NATIVITATIS, De ea. \226\128\147 Off. semifestivum. \226\128\147 Ad MAT. invit., hymnus, 9 antt. et 9 pss. cum ultimo V de festo Nativ., Ll. de Scr. occ. cum suis RR (ad 2um additur Gloria Patri)\226\128\147 Ad Laudes antt. de Nativ., pss. de dom., comm. S Silvestri I Papae et Conf. \226\128\147 Ad HORAS ant. et pss. de feria curr., rel ut in festo Nativ. \226\128\147 Ad Primam in R Br. V Qui natus es de Maria Virgine. Missa Puer natus de diebus infra octavam, Gloria, Credo, comm. S Silvestri I Papae et Conf., praef. de Nativ., Communic. de Nativ. diem sacratissimum. I VESPER\195\134 de seq. \226\128\147 Compl. de dom. Hodie ad solemnem recitationem hymni Te Deum, indulgentia plenaria lucrari potest. 16") + (te_deum ()) (gloria (true)) (credo (true)) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. I"))) + ((date 2026-01-01) (class_ ("I cl.")) + (title "Al Feria V. OCTAVA NATIVITATIS,") (te_deum ()) (gloria (true)) + (credo (true)) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. II"))) + ((date 2026-01-02) (class_ ("IV cl.")) + (title "Alb Feria VI post Octavam Nativitatis, De ea,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef ("de Nativ., sine Communic. pr. Feria VI prima in mense."))) + ((date 2026-01-03) (class_ ("IV cl.")) + (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) + (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147"))) + ((date 2026-01-04) (class_ ("II cl.")) + (title "Alb Dom. SS.MI NOMINIS IESU,") (te_deum ()) (gloria (true)) + (credo (true)) (praef ("de Nativ., sine Communic. pr. II"))) + ((date 2026-01-05) (class_ ("IV cl.")) + (title "Alb Feria II post Octavam Nativitatis, De ea,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef ("de Nativ., sine Communic. pr. \226\128\147"))) + ((date 2026-01-06) (class_ ("I cl.")) + (title "Alb Feria III. IN EPIPHANIA DOMINI,") (te_deum ()) + (gloria (true)) (credo (true)) (praef ("et Communic pr. II"))) + ((date 2026-01-07) (class_ ("IV cl.")) + (title "Alb Feria IV post Epiphaniam, De ea,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("de Epiphania."))) + ((date 2026-01-08) (class_ ("IV cl.")) + (title "Alb Feria V post Epiphaniam, De ea,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("de Epiphania."))) + ((date 2026-01-09) (class_ ("IV cl.")) + (title "Alb Feria VI post Epiphaniam, De ea,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("de Epiphania."))) + ((date 2026-01-10) (class_ ("IV cl.")) + (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) + (credo (false)) (praef ("BMV Et te in Veneratione. I"))) + ((date 2026-01-11) (class_ ("II cl.")) + (title + "Alb Dom. I post Epiphaniam. SANCT\195\134 FAMILI\195\134 IESU, MARI\195\134, IOSEPH *,") + (te_deum ()) (gloria (true)) (credo (true)) (praef ("de Epiphania. II"))) + ((date 2026-01-12) (class_ ("IV cl.")) + (title "Alb Feria II post Dom. I post Epiphaniam, De ea,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef ("de Epiphania."))) + ((date 2026-01-13) (class_ ("II cl.")) + (title "Alb Feria III. IN COMMEMORATIONE BAPTISMATIS D.N.I.C.,") + (te_deum ()) (gloria (true)) (credo (true)) (praef ("de Epiphania. Ad"))) + ((date 2026-01-14) (class_ ("III cl.")) + (title "Alb Feria IV. S Hilarii Ep., Conf. et Eccl. Doct.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef + ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa S Felicis Presbyt. et Mart. (rub.) L\195\166tabitur iustus, Gloria, ors. pr., comm. S Hilarii Ep., Conf. et Eccl. Doct., praef. comm. vel de Martyribus. Ad"))) + ((date 2026-01-15) (class_ ("III cl.")) + (title "Alb Feria V. S Pauli Primi Eremitae Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef + ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa S Mauri Abbatis. (alb.) Os iusti de Comm. Abb., Gloria, comm. S Pauli Primi Eremitae Conf., praef. comm."))) + ((date 2026-01-16) (class_ ("III cl.")) + (title "Rub Feria VI. S Marcelli I Papae et Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus."))) + ((date 2026-01-17) (class_ ("III cl. (Priv.)")) + (title "Alb Sabb. S Antonii Abb.,") (te_deum (true)) (gloria (true)) + (credo (false)) (praef ("comm. I"))) + ((date 2026-01-18) (class_ ("II cl.")) + (title "Vir DOM. II POST EPIPHANIAM, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-01-19) (class_ ("IV cl.")) + (title "Vir Feria II post Dom. II post Epiphaniam, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-01-20) (class_ ("III cl. (Priv.)")) + (title "Rub Feria III. SS Fabiani Papae et Sebastiani Mm.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef ("comm. vel de Martyribus."))) + ((date 2026-01-21) (class_ ("III cl. (Priv.)")) + (title "Rub Feria IV. S Agnetis * Virg. et Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. Ad"))) + ((date 2026-01-22) (class_ ("III cl.")) + (title "Rub Feria V. SS Vincentii et Anastasii Mm.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus."))) + ((date 2026-01-23) (class_ ("III cl.")) + (title "Alb Feria VI. S Raymundi de Pe\195\177afort Conf.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef + ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa S Emerentianae Virg. et Mart. (rub.) Me exspectaverunt, Gloria, comm. S Raymundi de Pe\195\177afort Conf., praef. comm. vel de Martyribus. \226\128\147"))) + ((date 2026-01-24) (class_ ("III cl. (Priv.)")) + (title "Rub Sabb. S Timothei Ep. et Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. I"))) + ((date 2026-01-25) (class_ ("II cl.")) + (title "Vir DOM. III POST EPIPHANIAM, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-01-26) (class_ ("III cl. (Priv.)")) + (title "Rub Feria II. S Polycarpi Ep. et Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus."))) + ((date 2026-01-27) (class_ ("III cl. (Priv.)")) + (title "Alb Feria III. S Ioannis Chrysostomi Ep., Conf. et Eccl. Doct.,") + (te_deum (true)) (gloria (true)) (credo (false)) (praef ("comm. Ad"))) + ((date 2026-01-28) (class_ ("III cl.")) + (title "Alb Feria IV. S Petri Nolasci Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef + ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa pr. S Agnetis * Virg. et Mart. secundo. (rub.), Gloria, comm. S Petri Nolasci Conf., praef. comm. vel de Martyribus."))) + ((date 2026-01-29) (class_ ("III cl. (Priv.)")) + (title "Alb Feria V. S Francisci Salesii Ep., Conf. et Eccl. Doct.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-01-30) (class_ ("III cl.")) + (title "Rub Feria VI. S Martinae Virg. et Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus."))) + ((date 2026-01-31) (class_ ("III cl. (Priv.)")) + (title "Alb Sabb. S Ioannis Bosco Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. I"))) + ((date 2026-02-01) (class_ ("II cl.")) + (title "Viol DOM. SEPTUAGESIMAE, De ea,") (te_deum (true)) + (gloria (false)) (credo (true)) (praef ("Trinit. II"))) + ((date 2026-02-02) (class_ ("II cl.")) + (title "Alb Feria II. IN PURIFICATIONE B. MARIAE VIRG.,") (te_deum ()) + (gloria (true)) (credo (true)) + (praef ("de Nativ. Ad benedictionem candelarum: ut in Missali. Ad"))) + ((date 2026-02-03) (class_ ("IV cl.")) + (title "Viol Feria III Dom. Septuagesimae, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef ("comm. \226\128\147"))) + ((date 2026-02-04) (class_ ("III cl.")) + (title "Alb Feria IV. S Andreae Corsini Ep. et Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef (comm.))) + ((date 2026-02-05) (class_ ("III cl. (Priv.)")) + (title "Rub Feria V. S Agathae * Virg. et Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. Ad"))) + ((date 2026-02-06) (class_ ("III cl. (Priv.)")) + (title "Alb Feria VI. S Titi Ep. et Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef ("comm. Feria VI prima in mense."))) + ((date 2026-02-07) (class_ ("III cl.")) + (title "Alb Sabb. S Romualdi Abb.,") (te_deum (true)) (gloria (true)) + (credo (false)) (praef ("comm. Sabbatum primum in mense. I"))) + ((date 2026-02-08) (class_ ("II cl.")) + (title "Viol DOM. SEXAGESIMAE, De ea,") (te_deum (true)) (gloria (false)) + (credo (true)) (praef ("Trinit. II"))) + ((date 2026-02-09) (class_ ("III cl.")) + (title "Alb Feria II. S Cyrilli Ep. Alexandrini, Conf. et Eccl. Doct.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef + ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa S Apolloniae Virg. et Mart. (rub.) Loquebar de testimoniis tuis, Gloria, comm. S Cyrilli Ep. Alexandrini, Conf. et Eccl. Doct., tractus, praef. comm. vel de Martyribus. Ad"))) + ((date 2026-02-10) (class_ ("III cl.")) + (title "Alb Feria III. S Scholasticae Virg.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef (comm.))) + ((date 2026-02-11) (class_ ("III cl.")) + (title "Alb Feria IV. In Apparitione B. Mariae Virg. Immaculatae,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef ("BMV Et te in Conceptione Immaculata."))) + ((date 2026-02-12) (class_ ("III cl.")) + (title + "Alb Feria V. SS Septem Fundatorum Ordinis Servorum B. Mariae Virg., Cc.,") + (te_deum (true)) (gloria (true)) (credo (false)) (praef ("comm. Ad"))) + ((date 2026-02-13) (class_ ("IV cl.")) + (title "Viol Feria VI Dom. Sexagesimae, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2026-02-14) (class_ ("IV cl.")) + (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) + (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147"))) + ((date 2026-02-15) (class_ ("II cl.")) + (title "Viol DOM. QUINQUAGESIMAE, De ea,") (te_deum (true)) + (gloria (false)) (credo (true)) (praef ("Trinit. II"))) + ((date 2026-02-16) (class_ ("IV cl.")) + (title "Viol Feria II Dom. Quinquagesimae, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2026-02-17) (class_ ("IV cl.")) + (title "Viol Feria III Dom. Quinquagesimae, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2026-02-18) (class_ ("I cl.")) + (title "Viol FERIA IV CINERUM, De ea,") (te_deum ()) (gloria (false)) + (credo (false)) + (praef + ("Quadr., or. super populum. In Missa qu\195\166 dicitur post benedictionem et impositionem cinerum omittuntur omnes preces ad gradus altaris dicend\195\166, necnon ors. Aufer a nobis et Oramus te, Domine, non autem osculum altaris (RM, 424 a)."))) + ((date 2026-02-19) (class_ ("III cl.")) + (title "Viol Feria V Dom. Quinquagesimae, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + ((date 2026-02-20) (class_ ("III cl.")) + (title "Viol Feria VI Dom. Quinquagesimae, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + ((date 2026-02-21) (class_ ("III cl.")) + (title "Viol Sabb. Dom. Quinquagesimae, De eo,") (te_deum ()) + (gloria (false)) (credo (false)) + (praef ("Quadr., or. super populum. I"))) + ((date 2026-02-22) (class_ ("I cl.")) + (title "Viol DOM. I QUADRAGESIMAE, De ea,") (te_deum (true)) + (gloria (false)) (credo (true)) (praef ("Quadr. II"))) + ((date 2026-02-23) (class_ ("III cl.")) + (title "Viol Feria II post Dom. I Quadragesimae, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + ((date 2026-02-24) (class_ ("II cl.")) + (title "Rub Feria III. S MATTHIAE AP.,") (te_deum ()) (gloria (true)) + (credo (true)) (praef ("App. Ad"))) + ((date 2026-02-25) (class_ ("II cl.")) + (title "Viol FERIA IV QUATTUOR TEMP., De ea,") (te_deum ()) + (gloria (false)) (credo (false)) + (praef + ("Quadr., or. super populum. \226\128\147 Quoad Flectamus genua vide RM 440."))) + ((date 2026-02-26) (class_ ("III cl.")) + (title "Viol Feria V post Dom. I Quadragesimae, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + ((date 2026-02-27) (class_ ("II cl.")) + (title "Viol FERIA VI QUATTUOR TEMP., De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + ((date 2026-02-28) (class_ ("II cl.")) + (title "Viol SABB. QUATTUOR TEMP., De eo,") (te_deum ()) (gloria (false)) + (credo (false)) + (praef + ("Quadr., or. super populum. \226\128\147 Quoad Flectamus genua vide RM 440. Quoad lectiones vide RM 468. I"))) + ((date 2026-03-01) (class_ ("I cl.")) + (title "Viol DOM. II QUADRAGESIMAE, De ea,") (te_deum (true)) + (gloria (false)) (credo (true)) (praef ("Quadr. II"))) + ((date 2026-03-02) (class_ ("III cl.")) + (title "Viol Feria II post Dom. II Quadragesimae, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + ((date 2026-03-03) (class_ ("III cl.")) + (title "Viol Feria III post Dom. II Quadragesimae, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + ((date 2026-03-04) (class_ ("III cl.")) + (title "Viol Feria IV post Dom. II Quadragesimae, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + ((date 2026-03-05) (class_ ("III cl.")) + (title "Viol Feria V post Dom. II Quadragesimae, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + ((date 2026-03-06) (class_ ("III cl.")) + (title "Viol Feria VI post Dom. II Quadragesimae, De ea,") + (te_deum (true)) (gloria (false)) (credo (false)) + (praef ("Quadr., or. super populum. Feria VI prima in mense."))) + ((date 2026-03-07) (class_ ("III cl.")) + (title "Viol Sabb. post Dom. II Quadragesimae, De eo,") (te_deum (true)) + (gloria (false)) (credo (false)) + (praef ("Quadr., or. super populum. Sabbatum primum in mense. I"))) + ((date 2026-03-08) (class_ ("I cl.")) + (title "Viol DOM. III QUADRAGESIMAE, De ea,") (te_deum (true)) + (gloria (false)) (credo (true)) (praef ("Quadr. II"))) + ((date 2026-03-09) (class_ ("III cl.")) + (title "Viol Feria II post Dom. III Quadragesimae, De ea,") + (te_deum (true)) (gloria (false)) (credo (false)) + (praef ("Quadr., or. super populum."))) + ((date 2026-03-10) (class_ ("III cl.")) + (title "Viol Feria III post Dom. III Quadragesimae, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + ((date 2026-03-11) (class_ ("III cl.")) + (title "Viol Feria IV post Dom. III Quadragesimae, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + ((date 2026-03-12) (class_ ("III cl.")) + (title "Viol Feria V post Dom. III Quadragesimae, De ea,") + (te_deum (true)) (gloria (false)) (credo (false)) + (praef ("Quadr., or. super populum."))) + ((date 2026-03-13) (class_ ("III cl.")) + (title "Viol Feria VI post Dom. III Quadragesimae, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + ((date 2026-03-14) (class_ ("III cl.")) + (title "Viol Sabb. post Dom. III Quadragesimae, De eo,") (te_deum ()) + (gloria (false)) (credo (false)) + (praef ("Quadr., or. super populum. I"))) + ((date 2026-03-15) (class_ ("I cl.")) + (title "Viol/ DOM. IV QUADRAGESIMAE (LAETARE), De ea,") (te_deum (true)) + (gloria (false)) (credo (true)) (praef ("Quadr. II"))) + ((date 2026-03-16) (class_ ("III cl.")) + (title "Viol Feria II post Dom. IV Quadragesimae (Laetare), De ea,") + (te_deum ()) (gloria (false)) (credo (false)) + (praef ("Quadr., or. super populum."))) + ((date 2026-03-17) (class_ ("III cl.")) + (title "Viol Feria III post Dom. IV Quadragesimae (Laetare), De ea,") + (te_deum ()) (gloria (false)) (credo (false)) + (praef ("Quadr., or. super populum."))) + ((date 2026-03-18) (class_ ("III cl.")) + (title "Viol Feria IV post Dom. IV Quadragesimae (Laetare), De ea,") + (te_deum ()) (gloria (false)) (credo (false)) + (praef ("Quadr., or. super populum. I"))) + ((date 2026-03-19) (class_ ("I cl.")) + (title + "Alb Feria V. S IOSEPH * SPONSI B. MARIAE VIRG., CONF. ET ECCLESIAE UNIVERSAE PATRONI,") + (te_deum ()) (gloria (true)) (credo (true)) + (praef ("de S Iosepho Et te in festivitate. II"))) + ((date 2026-03-20) (class_ ("III cl.")) + (title "Viol Feria VI post Dom. IV Quadragesimae (Laetare), De ea,") + (te_deum ()) (gloria (false)) (credo (false)) + (praef ("Quadr., or. super populum."))) + ((date 2026-03-21) (class_ ("III cl.")) + (title "Viol Sabb. post Dom. IV Quadragesimae (Laetare), De eo,") + (te_deum (true)) (gloria (false)) (credo (false)) + (praef ("Quadr., or. super populum. I"))) + ((date 2026-03-22) (class_ ("I cl.")) + (title "Viol DOM. I PASSIONIS, De ea,") (te_deum (true)) (gloria (false)) + (credo (true)) (praef ("de Sancta Cruce. II"))) + ((date 2026-03-23) (class_ ("III cl.")) + (title "Viol Feria II post Dom. I Passionis, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) + (praef ("de Sancta Cruce or. super populum."))) + ((date 2026-03-24) (class_ ("III cl.")) + (title "Viol Feria III post Dom. I Passionis, De ea,") (te_deum (true)) + (gloria (false)) (credo (false)) + (praef ("de Sancta Cruce or. super populum. I"))) + ((date 2026-03-25) (class_ ("I cl.")) + (title "Alb Feria IV. IN ANNUNTIATIONE B. MARIAE VIRG.,") (te_deum ()) + (gloria (true)) (credo (true)) + (praef + ("BMV Et te in Annuntiatione \226\128\147 In Missis in cantu, ad verba symboli Et incarnatus est\226\128\166 et homo factus est, omnes genuflectunt versus altare, non tantum cum a celebrante recitantur, sed etiam cum a choro canuntur (RM 518 b). II"))) + ((date 2026-03-26) (class_ ("III cl.")) + (title "Viol Feria V post Dom. I Passionis, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) + (praef ("de Sancta Cruce or. super populum."))) + ((date 2026-03-27) (class_ ("III cl.")) + (title "Viol Feria VI post Dom. I Passionis, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) + (praef ("de Sancta Cruce or. super populum."))) + ((date 2026-03-28) (class_ ("III cl.")) + (title "Viol Sabb. post Dom. I Passionis, De eo,") (te_deum ()) + (gloria (false)) (credo (false)) + (praef ("de Sancta Cruce or. super populum. I"))) + ((date 2026-03-29) (class_ ("I cl.")) + (title + "Rub in Officio, Rub. ad Bened. ramorum et in Processione, Viol. in Missa. DOM. IN PALMIS, De ea,") + (te_deum (true)) (gloria (false)) (credo (true)) + (praef + ("de Sancta Cruce. \194\171Asperges\194\187 omittitur. \226\128\147 Benedictio palmorum et processio ante missam principalem celebrandae sunt. \226\128\147 Orationes praeparatoriae omittuntur. \226\128\147 Evangelium de passione secundum S Matthiam 26, 36-75; 27,1-60 legitur. Munda cor dicitur, celebrans autem (vel diaconus chronista) signum crucis nec super libro nec super se facit, necque librum osculatur, necque Laus tibi Domine dicit. \226\128\147 Evangelium finale omittitur. \226\128\147 In Missis sine processione, legitur in fine Evangelium Cum appropinquasset de benedictione ramorum. Sacerdotibus plures quam unam missam dicentibus licet Evangelium S Matthi\195\166 27, 45-52 legere potius quam Evangelium Passionis. II"))) + ((date 2026-03-30) (class_ ("I cl.")) + (title "Viol FERIA II HEBDOMADAE SANCTAE, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) + (praef ("de Sancta Cruce or. super populum."))) + ((date 2026-03-31) (class_ ("I cl.")) + (title "Viol FERIA II HEBDOMADAE SANCTAE, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) + (praef + ("de Sancta Cruce or. super populum. Passio secundum S Marcum 14, 32-72; 15,1-46. Munda cor dicitur, celebrans autem (vel diaconus chronista) signum crucis nec super libro nec super se facit, necque librum osculatur, necque Laus tibi Domine dicit."))) + ((date 2026-04-01) (class_ ("I cl.")) + (title "Viol FERIA IV HEBDOMADAE SANCTA, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) + (praef + ("de Sancta Cruce or. super populum. Passio secundum S Lucam 22, 39-71; 23, 1-53. Munda cor dicitur, celebrans autem (vel diaconus chronista) signum crucis nec super libro nec super se facit, necque librum osculatur, necque Laus tibi Domine dicit."))) + ((date 2026-04-02) (class_ ("I cl.")) + (title "Viol. in Off., Alb. in Missa. FERIA V IN CENA DOMINI, De ea,") + (te_deum ()) (gloria (true)) (credo (false)) + (praef + ("de Sancta Cruce, Communicantes, Hanc igitur et Qui pridie pr., ad triplex Agnus Dei ter respondetur miserere nobis. Osculum pacis non datur, et omittitur or. Domine Iesu Christe, qui dixisti."))) + ((date 2026-04-03) (class_ ("I cl.")) + (title + "Nig in Actione liturgica usque ad 4am partem, Viol. in S. Communione. FERIA VI IN PASSIONE ET MORTE DOMINI, De ea,") + (te_deum ()) (gloria (true)) (credo (false)) + (praef ("comm. Feria VI prima in mense."))) + ((date 2026-04-04) (class_ ("I cl.")) + (title "Viol in Vig. pasch., Alb. in Missa. SABBATUM SANCTUM, De eo,") + (te_deum ()) (gloria ()) (credo ()) (praef ())) + ((date 2026-04-05) (class_ ("I cl.")) + (title "Alb DOM. RESURRECTIONIS, De ea,") (te_deum ()) (gloria (true)) + (credo (true)) + (praef + ("Pasch. (in hac potissimum die), Communic. et Hanc igitur pr., ad Ite, missa est additur duplex Alleluia. Hodie prohibentur omnes Missae defunctorum, etiam exsequialis."))) + ((date 2026-04-06) (class_ ("I cl.")) + (title "Alb FERIA II INFRA OCTAVAM PASCHATIS, De ea,") (te_deum ()) + (gloria (true)) (credo (true)) + (praef ("etc. ut in festo., ad Ite, missa est additur duplex Alleluia."))) + ((date 2026-04-07) (class_ ("I cl.")) + (title "Alb FERIA III INFRA OCTAVAM PASCHATIS, De ea,") (te_deum ()) + (gloria (true)) (credo (true)) + (praef ("etc. ut in festo., ad Ite, missa est additur duplex Alleluia."))) + ((date 2026-04-08) (class_ ("I cl.")) + (title "Alb FERIA IV INFRA OCTAVAM PASCHATIS, De ea,") (te_deum ()) + (gloria (true)) (credo (true)) + (praef ("etc. ut in festo., ad Ite, missa est additur duplex Alleluia."))) + ((date 2026-04-09) (class_ ("I cl.")) + (title "Alb FERIA V INFRA OCTAVAM PASCHATIS, De ea,") (te_deum ()) + (gloria (true)) (credo (true)) + (praef ("etc. ut in festo., ad Ite, missa est additur duplex Alleluia."))) + ((date 2026-04-10) (class_ ("I cl.")) + (title "Alb FERIA VI INFRA OCTAVAM PASCHATIS, De ea,") (te_deum ()) + (gloria (true)) (credo (true)) + (praef ("etc. ut in festo., ad Ite, missa est additur duplex Alleluia."))) + ((date 2026-04-11) (class_ ("I cl.")) + (title "Alb SABBATUM IN ALBIS, De eo,") (te_deum ()) (gloria (true)) + (credo (true)) + (praef + ("etc. ut in festo., ad Ite, missa est additur duplex Alleluia. I"))) + ((date 2026-04-12) (class_ ("I cl.")) (title "Alb DOM. IN ALBIS,") + (te_deum (true)) (gloria (true)) (credo (true)) + (praef ("Pasch. \226\128\147 Ite Missa est sine Alleluia. II"))) + ((date 2026-04-13) (class_ ("III cl.")) + (title "Rub Feria II. S Hermenegildi Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("Pasch. vel de Martyribus. Ad"))) + ((date 2026-04-14) (class_ ("III cl. (Priv.)")) + (title "Rub Feria III. S Iustini Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("Pasch. vel de Martyribus."))) + ((date 2026-04-15) (class_ ("IV cl.")) + (title "Alb Feria IV Dom. in Albis, De ea,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef (Pasch.))) + ((date 2026-04-16) (class_ ("IV cl.")) + (title "Alb Feria V Dom. in Albis, De ea,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("Pasch. \226\128\147"))) + ((date 2026-04-17) (class_ ("IV cl.")) + (title "Alb Feria VI Dom. in Albis, De ea,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("Pasch. \226\128\147"))) + ((date 2026-04-18) (class_ ("IV cl.")) + (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) + (credo (false)) (praef ("BMV Et te in Veneratione. I"))) + ((date 2026-04-19) (class_ ("II cl.")) + (title "Alb DOM. III PASCHATIS, De ea,") (te_deum (true)) (gloria (true)) + (credo (true)) (praef ("Pasch. II"))) + ((date 2026-04-20) (class_ ("IV cl.")) + (title "Alb Feria II post Dom. III Paschatis, De ea,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef (Pasch.))) + ((date 2026-04-21) (class_ ("III cl.")) + (title "Alb Feria III. S Anselmi Ep., Conf. et Eccl. Doct.,") + (te_deum (true)) (gloria (true)) (credo (false)) (praef ("Pasch. Ad"))) + ((date 2026-04-22) (class_ ("III cl.")) + (title "Rub Feria IV. SS Soteris et Caii Pp. et Mm.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("Pasch. vel de Martyribus."))) + ((date 2026-04-23) (class_ ("IV cl.")) + (title "Alb Feria V post Dom. III Paschatis, De ea,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("Pasch. \226\128\147"))) + ((date 2026-04-24) (class_ ("III cl.")) + (title "Rub Feria VI. S Fidelis de Sigmaringa Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("Pasch. vel de Martyribus."))) + ((date 2026-04-25) (class_ ("II cl.")) + (title "Rub Sabb. LITANIA MAIOR. S MARCI EVANGELISTAE,") (te_deum ()) + (gloria (true)) (credo (true)) (praef ("App. Ad"))) + ((date 2026-04-26) (class_ ("II cl.")) + (title "Alb DOM. IV PASCHATIS, De ea,") (te_deum (true)) (gloria (true)) + (credo (true)) (praef ("Pasch. II"))) + ((date 2026-04-27) (class_ ("III cl.")) + (title "Alb Feria II. S Petri Canisii Conf. et Eccl. Doct.,") + (te_deum (true)) (gloria (true)) (credo (false)) (praef ("Pasch. Ad"))) + ((date 2026-04-28) (class_ ("III cl.")) + (title "Alb Feria III. S Pauli a Cruce Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("Pasch. \226\128\147"))) + ((date 2026-04-29) (class_ ("III cl.")) + (title "Rub Feria IV. S Petri Mart.,") (te_deum (true)) (gloria (true)) + (credo (false)) (praef ("Pasch. vel de Martyribus \226\128\147"))) + ((date 2026-04-30) (class_ ("III cl. (Priv.)")) + (title "Alb Feria V. S Catharinae Senensis Virg.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("Pasch. I"))) + ((date 2026-05-01) (class_ ("I cl.")) + (title + "Alb Feria VI. S IOSEPH * OPIFICIS SPONSI B. MARIAE VIRG., CONF.,") + (te_deum ()) (gloria (true)) (credo (true)) + (praef + ("de S Iosepho Et te in solemnitate \226\128\147 Etiam dici potest Missa Adiutor (cfr. in Missis votivis), cum Alleluia pasch., praef. S Ioseph Et et in solemnitate. Feria VI prima in mense. II"))) + ((date 2026-05-02) (class_ ("III cl. (Priv.)")) + (title "Alb Sabb. S Athanasii Ep., Conf. et Eccl. Doct.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef ("Pasch. Sabbatum primum in mense. I"))) + ((date 2026-05-03) (class_ ("II cl.")) + (title "Alb DOM. V PASCHATIS, De ea,") (te_deum (true)) (gloria (true)) + (credo (true)) (praef ("Pasch. II"))) + ((date 2026-05-04) (class_ ("III cl. (Priv.)")) + (title "Alb Feria II. S Monicae Vid.,") (te_deum (true)) (gloria (true)) + (credo (false)) (praef (Pasch.))) + ((date 2026-05-05) (class_ ("III cl. (Priv.)")) + (title "Alb Feria III. S Pii V Papae et Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("Pasch. Ad"))) + ((date 2026-05-06) (class_ ("IV cl.")) + (title "Alb Feria IV post Dom. V Paschatis, De ea,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("Pasch. \226\128\147"))) + ((date 2026-05-07) (class_ ("III cl.")) + (title "Rub Feria V. S Stanislai Ep. et Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("Pasch. vel de Martyribus."))) + ((date 2026-05-08) (class_ ("IV cl.")) + (title "Alb Feria VI post Dom. V Paschatis, De ea,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("Pasch. \226\128\147"))) + ((date 2026-05-09) (class_ ("III cl. (Priv.)")) + (title "Alb Sabb. S Gregorii Nazianzeni Ep., Conf. et Eccl. Doct.,") + (te_deum (true)) (gloria (true)) (credo (false)) (praef ("Pasch. I"))) + ((date 2026-05-10) (class_ ("II cl.")) + (title "Alb DOM. VI PASCHATIS, De ea,") (te_deum (true)) (gloria (true)) + (credo (true)) (praef ("Pasch. II"))) + ((date 2026-05-11) (class_ ("II cl.")) + (title "Rub Feria II. SS PHILIPPI * & IACOBI * APP,") (te_deum ()) + (gloria (true)) (credo (true)) (praef ("App. Ad"))) + ((date 2026-05-12) (class_ ("III cl.")) + (title + "Rub Feria III. SS Nerei, Achillei, Domitillae Virg., & Pancratii Mm.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef ("Pasch. vel de Martyribus."))) + ((date 2026-05-13) (class_ ("II cl.")) + (title "Alb Feria IV. VIGILIA ASCENSIONIS,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("Pasch. I"))) + ((date 2026-05-14) (class_ ("I cl.")) + (title "Alb Feria V. IN ASCENSIONE DOMINI NOSTRI IESU CHRISTI,") + (te_deum ()) (gloria (true)) (credo (true)) + (praef + ("Ascensionis, Communic pr. In Missa principali post Evangelium exstinguitur cereus paschalis. II"))) + ((date 2026-05-15) (class_ ("III cl.")) + (title "Alb Feria VI. S Ioannis Baptistae de la Salle Conf.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef ("Ascensionis \226\128\147"))) + ((date 2026-05-16) (class_ ("III cl.")) + (title "Alb Sabb. S Ubaldi Ep. et Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("Ascensionis \226\128\147"))) + ((date 2026-05-17) (class_ ("II cl.")) + (title "Alb DOM. POST ASCENSIONEM, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) + (praef + ("Ascensionis. Hodie prohibentur omnes Missae defunctorum, excepta exsequiali."))) + ((date 2026-05-18) (class_ ("III cl.")) + (title "Rub Feria II. S Venantii Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef ("Ascensionis vel de Martyribus."))) + ((date 2026-05-19) (class_ ("III cl.")) + (title "Alb Feria III. S Petri Caelestini Papae et Conf.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef + ("Ascensionis \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa S Pudentianae Virg. (alb.) Dilexisti iustitiam, Gloria, comm. S Petri Caelestini Papae et Conf., praef. Ascensionis. Ad"))) + ((date 2026-05-20) (class_ ("III cl.")) + (title "Alb Feria IV. S Bernardini Senensis Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef (Ascensionis.))) + ((date 2026-05-21) (class_ ("IV cl.")) + (title "Alb Feria V Dom. post Ascensionem, De ea,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef (Ascensionis.))) + ((date 2026-05-22) (class_ ("IV cl.")) + (title "Alb Feria VI Dom. post Ascensionem, De ea,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("Ascensionis \226\128\147"))) + ((date 2026-05-23) (class_ ("I cl.")) + (title "Rub Sabb. VIGILIA PENTECOSTES,") (te_deum (true)) (gloria (true)) + (credo (false)) + (praef + ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. I"))) + ((date 2026-05-24) (class_ ("I cl.")) (title "Rub Dom. PENTECOSTES,") + (te_deum ()) (gloria (true)) (credo (true)) + (praef + ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. \226\128\147 Genu flectendum est cum Veni Sancte Spiritus in versu Alleluia dicitur. II"))) + ((date 2026-05-25) (class_ ("I cl.")) + (title "Rub FERIA II INFRA OCTAVAM PENTECOSTES, De ea,") (te_deum ()) + (gloria (true)) (credo (true)) + (praef + ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. \226\128\147 Genu flectendum est cum Veni Sancte Spiritus in versu Alleluia dicitur."))) + ((date 2026-05-26) (class_ ("I cl.")) + (title "Rub FERIA III INFRA OCTAVAM PENTECOSTES, De ea,") (te_deum ()) + (gloria (true)) (credo (true)) + (praef + ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. \226\128\147 Genu flectendum est cum Veni Sancte Spiritus in versu Alleluia dicitur."))) + ((date 2026-05-27) (class_ ("I cl.")) + (title + "Rub FERIA IV QUATTUOR TEMPORUM INFRA OCTAVAM PENTECOSTES, De ea,") + (te_deum ()) (gloria (true)) (credo (true)) + (praef + ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. \226\128\147 Genu flectendum est cum Veni Sancte Spiritus in versu Alleluia dicitur."))) + ((date 2026-05-28) (class_ ("I cl.")) + (title "Rub FERIA V INFRA OCTAVAM PENTECOSTES, De ea,") (te_deum ()) + (gloria (true)) (credo (true)) + (praef + ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. \226\128\147 Genu flectendum est cum Veni Sancte Spiritus in versu Alleluia dicitur."))) + ((date 2026-05-29) (class_ ("I cl.")) + (title + "Rub FERIA VI QUATTUOR TEMPORUM INFRA OCTAVAM PENTECOSTES, De ea,") + (te_deum ()) (gloria (true)) (credo (true)) + (praef + ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. \226\128\147 Genu flectendum est cum Veni Sancte Spiritus in versu Alleluia dicitur."))) + ((date 2026-05-30) (class_ ("I cl.")) + (title + "Rub SABBATUM QUATTUOR TEMPORUM II INFRA OCTAVAM PENTECOSTES, De eo,") + (te_deum ()) (gloria (true)) (credo (true)) + (praef + ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. \226\128\147 Genu flectendum est cum Veni Sancte Spiritus in versu Alleluia dicitur (quae in forma Miss\195\166 longiori post sixtam lectionem dicitur). Post Nonam exspirat tempus paschale. Compl de dom., cum antiphona finali de B. V. M. Salve Regina, quae dicitur ad Feriam VI ante Dom. I Adventus inclusive. Hodie prohibentur omnes Missae defunctorum, excepta exsequiali."))) + ((date 2026-05-31) (class_ ("I cl.")) + (title "Alb Dom. I post Pentecosten. IN FESTO SANCTISSIMAE TRINITATIS,") + (te_deum ()) (gloria (true)) (credo (true)) (praef ("Trinit. II"))) + ((date 2026-06-01) (class_ ("III cl.")) + (title "Alb Feria II. S Angelae Mericiae Virg.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef (comm.))) + ((date 2026-06-02) (class_ ("IV cl.")) + (title "Vir Feria III post Dom. I post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-06-03) (class_ ("IV cl.")) + (title "Vir Feria IV post Dom. I post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) (praef ("comm. I"))) + ((date 2026-06-04) (class_ ("I cl.")) + (title "Alb Feria V. CORPORIS CHRISTI,") (te_deum ()) (gloria (true)) + (credo (true)) + (praef + ("comm. vel de Cor Sacratissimo. \226\128\147 Si processio cum benedicto sacramento post missam principalem fit, in Missa Benedicamus Domino dicitur, sed benedictio et evangelium finale omittuntur. II"))) + ((date 2026-06-05) (class_ ("III cl. (Priv.)")) + (title "Rub Feria VI. S Bonifatii Ep. et Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef ("comm. vel de Martyribus. Feria VI prima in mense."))) + ((date 2026-06-06) (class_ ("III cl.")) + (title "Alb Sabb. S Norberti Ep. et Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef ("comm. Sabbatum primum in mense. I"))) + ((date 2026-06-07) (class_ ("II cl.")) + (title "Vir DOM. II POST PENTECOSTEN, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-06-08) (class_ ("IV cl.")) + (title "Vir Feria II post Dom. II post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2026-06-09) (class_ ("IV cl.")) + (title "Vir Feria III post Dom. II post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-06-10) (class_ ("III cl.")) + (title "Alb Feria IV. S Margaritae Reginae, Vid.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef (comm.))) + ((date 2026-06-11) (class_ ("III cl. (Priv.)")) + (title "Rub Feria V. S Barnabae Apostoli,") (te_deum (true)) + (gloria (true)) (credo (true)) (praef ("App. I"))) + ((date 2026-06-12) (class_ ("I cl.")) + (title "Alb Feria VI. SACRATISSIMI CORDIS IESU,") (te_deum ()) + (gloria (true)) (credo (true)) + (praef + ("de Ss.mi Corde Iesu. Hodie, in qualibet ecclesia, coram Ss. Sacramento exposito, legatur formula reparationis et cantentur vel recitentur Litani\195\166 Sacratissimi Cordis Iesu (cfr. Enchiridion Indulgentiarum. Preces et pia opera, 1952, n.256, p.163). II"))) + ((date 2026-06-13) (class_ ("III cl. (Priv.)")) + (title "Alb Sabb. S Antonii de Padua Conf. et Eccl. Doct.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-06-14) (class_ ("II cl.")) + (title "Vir DOM. III POST PENTECOSTEN, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-06-15) (class_ ("IV cl.")) + (title "Vir Feria II post Dom. III post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-06-16) (class_ ("IV cl.")) + (title "Vir Feria III post Dom. III post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-06-17) (class_ ("III cl.")) + (title "Alb Feria IV. S Gregorii Barbadici Ep. et Conf.,") + (te_deum (true)) (gloria (true)) (credo (false)) (praef (comm.))) + ((date 2026-06-18) (class_ ("III cl.")) + (title "Alb Feria V. S Ephraem Syri Diaconi, Conf. et Eccl. Doct.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef + ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa pr. SS Marci et Marcelliani Mm. (rub.), Gloria, comm. S Ephraem Syri Diaconi, Conf. et Eccl. Doct., praef. comm. vel de Martyribus. Ad"))) + ((date 2026-06-19) (class_ ("III cl.")) + (title "Alb Feria VI. S Iulianae De Falconeriis Virg.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef + ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa pr. SS Gervasii et Protasii Mm. (rub.), Gloria, comm. S Iulianae De Falconeriis Virg., praef. comm. vel de Martyribus."))) + ((date 2026-06-20) (class_ ("IV cl.")) + (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) + (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147"))) + ((date 2026-06-21) (class_ ("II cl.")) + (title "Vir DOM. IV POST PENTECOSTEN, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-06-22) (class_ ("III cl.")) + (title "Alb Feria II. S Paulini Ep. et Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef (comm.))) + ((date 2026-06-23) (class_ ("II cl.")) + (title "Viol Feria III. VIGILIA NATIVITATIS S IOANNIS * BAPTISTAE,") + (te_deum (true)) (gloria (false)) (credo (false)) (praef ("comm. I"))) + ((date 2026-06-24) (class_ ("I cl.")) + (title "Alb Feria IV. IN NATIVITATE S IOANNIS * BAPTISTAE,") (te_deum ()) + (gloria (true)) (credo (true)) + (praef ("comm. vel de S Ioanni Baptista. II"))) + ((date 2026-06-25) (class_ ("III cl.")) + (title "Alb Feria V. S Gulielmi Abb.,") (te_deum (true)) (gloria (true)) + (credo (false)) (praef (comm.))) + ((date 2026-06-26) (class_ ("III cl.")) + (title "Rub Feria VI. SS Ioannis * et Pauli * Mm.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus."))) + ((date 2026-06-27) (class_ ("IV cl.")) + (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) + (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147"))) + ((date 2026-06-28) (class_ ("II cl.")) + (title "Vir DOM. V POST PENTECOSTEN, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) (praef ("Trinit. I"))) + ((date 2026-06-29) (class_ ("I cl.")) + (title "Rub Feria II. SS PETRI * ET PAULI * APP.,") (te_deum ()) + (gloria (true)) (credo (true)) (praef ("App. II"))) + ((date 2026-06-30) (class_ ("III cl. (Priv.)")) + (title "Rub Feria III. In Commemoratione S Pauli * Ap.,") + (te_deum (true)) (gloria (true)) (credo (false)) (praef ("App. I"))) + ((date 2026-07-01) (class_ ("I cl.")) + (title "Rub Feria IV. PRETIOSISSIMI SANGUINIS D. N. I. C.,") (te_deum ()) + (gloria (true)) (credo (true)) (praef ("de Sancta Cruce. II"))) + ((date 2026-07-02) (class_ ("II cl.")) + (title "Alb Feria V. IN VISITATIONE B. MARIAE VIRG.,") (te_deum ()) + (gloria (true)) (credo (true)) (praef ("BMV Et te in Visitatione. Ad"))) + ((date 2026-07-03) (class_ ("III cl.")) + (title "Rub Feria VI. S Iren\195\166i Ep. et Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef ("comm. vel de Martyribus. Feria VI prima in mense."))) + ((date 2026-07-04) (class_ ("IV cl.")) + (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) + (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147"))) + ((date 2026-07-05) (class_ ("II cl.")) + (title "Vir DOM. VI POST PENTECOSTEN, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-07-06) (class_ ("IV cl.")) + (title "Vir Feria II post Dom. VI post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-07-07) (class_ ("III cl. (Priv.)")) + (title "Alb Feria III. SS Cyrilli et Methodii Epp. et Cc.,") + (te_deum (true)) (gloria (true)) (credo (false)) (praef ("comm. Ad"))) + ((date 2026-07-08) (class_ ("III cl.")) + (title "Alb Feria IV. S Elisabeth Reginae, Vid.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. Ad"))) + ((date 2026-07-09) (class_ ("IV cl.")) + (title "Vir Feria V post Dom. VI post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-07-10) (class_ ("III cl.")) + (title + "Rub Feria VI. SS Septem Fratrum Mm., Ac SS Rufinae et Secundae Vv. et Mm.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef ("comm. vel de Martyribus."))) + ((date 2026-07-11) (class_ ("IV cl.")) + (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) + (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147"))) + ((date 2026-07-12) (class_ ("II cl.")) + (title "Vir DOM. VII POST PENTECOSTEN, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-07-13) (class_ ("IV cl.")) + (title "Vir Feria II post Dom. VII post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2026-07-14) (class_ ("III cl. (Priv.)")) + (title "Alb Feria III. S Bonaventurae Ep., Conf. et Eccl. Doct.,") + (te_deum (true)) (gloria (true)) (credo (false)) (praef ("comm. Ad"))) + ((date 2026-07-15) (class_ ("III cl.")) + (title "Alb Feria IV. S Henrici Imperatoris Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef (comm.))) + ((date 2026-07-16) (class_ ("IV cl.")) + (title "Vir Feria V post Dom. VII post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-07-17) (class_ ("IV cl.")) + (title "Vir Feria VI post Dom. VII post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-07-18) (class_ ("III cl.")) + (title "Alb Sabb. S Camilli de Lellis Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef + ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa SS Symphorosae et septem filiorum eius Mm. (rub.) Clamaverunt (ut in festo Ss. duodecim Fratrum Mm., die 1 sept.), Gloria, ors. pr., comm. S Camilli de Lellis Conf., praef. comm. vel de Martyribus. I"))) + ((date 2026-07-19) (class_ ("II cl.")) + (title "Vir DOM. VIII POST PENTECOSTEN, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-07-20) (class_ ("III cl.")) + (title "Alb Feria II. S Hieronymi \211\148miliani Conf.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef + ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa S Margaritae Virg. et Mart. (rub.) Me exspectaverunt, Gloria, comm. S Hieronymi \211\148miliani Conf., praef. comm. vel de Martyribus."))) + ((date 2026-07-21) (class_ ("III cl.")) + (title "Alb Feria III. S Laurentii de Brundusio Conf. et Eccl. Doct.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef + ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa pr. S Praexedis Virg. (alb.), Gloria, comm. S Laurentii de Brundusio Conf. et Eccl. Doct., praef. comm. \226\128\147"))) + ((date 2026-07-22) (class_ ("III cl. (Priv.)")) + (title "Alb Feria IV. S Mariae Magdalenae P\197\147nitentis,") + (te_deum (true)) (gloria (true)) (credo (false)) (praef ("comm. Ad"))) + ((date 2026-07-23) (class_ ("III cl.")) + (title "Rub Feria V. S Apollinaris Ep. et Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef + ("comm. vel de Martyribus \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa S Liborii Ep. et Conf. (alb.) Statuit de Comm. Confessoris Pontificis, Gloria, comm. S Apollinaris Ep. et Mart., praef. comm."))) + ((date 2026-07-24) (class_ ("IV cl.")) + (title "Vir Feria VI post Dom. VIII post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-07-25) (class_ ("II cl.")) + (title "Rub Sabb. S IACOBI * APOSTOLI,") (te_deum ()) (gloria (true)) + (credo (true)) (praef ("App. Ad"))) + ((date 2026-07-26) (class_ ("II cl.")) + (title "Vir DOM. IX POST PENTECOSTEN, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-07-27) (class_ ("IV cl.")) + (title "Vir Feria II post Dom. IX post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-07-28) (class_ ("III cl.")) + (title + "Rub Feria III. SS Nazarii et Celsi, Mm., Victoris I Papae et Mart. ac Inocentii I Papae et Conf.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef ("comm. vel de Martyribus."))) + ((date 2026-07-29) (class_ ("III cl. (Priv.)")) + (title "Alb Feria IV. S Marthae Virg.,") (te_deum (true)) (gloria (true)) + (credo (false)) (praef (comm.))) + ((date 2026-07-30) (class_ ("IV cl.")) + (title "Vir Feria V post Dom. IX post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-07-31) (class_ ("III cl. (Priv.)")) + (title "Alb Feria VI. S Ignatii Conf.,") (te_deum (true)) (gloria (true)) + (credo (false)) (praef (comm.))) + ((date 2026-08-01) (class_ ("IV cl.")) + (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) + (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147"))) + ((date 2026-08-02) (class_ ("II cl.")) + (title "Vir DOM. X POST PENTECOSTEN, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-08-03) (class_ ("IV cl.")) + (title "Vir Feria II post Dom. X post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-08-04) (class_ ("III cl. (Priv.)")) + (title "Alb Feria III. S Dominici Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef (comm.))) + ((date 2026-08-05) (class_ ("III cl. (Priv.)")) + (title "Alb Feria IV. In Dedicatione S Mariae ad Nives,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef ("BMV Et te in Festivitate."))) + ((date 2026-08-06) (class_ ("II cl.")) + (title "Alb Feria V. IN TRANSFIGURATIONE D. N. I. C.,") (te_deum ()) + (gloria (true)) (credo (true)) (praef ("comm. II"))) + ((date 2026-08-07) (class_ ("III cl.")) + (title "Alb Feria VI. S Caietani Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef + ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa pr. S Donati, Ep. et Mart. (rub.), Gloria, comm. S Caietani Conf., praef. comm. vel de Martyribus. Feria VI prima in mense."))) + ((date 2026-08-08) (class_ ("III cl. (Priv.)")) + (title "Alb Sabb. S Ioannis Mariae Vianney Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. \226\128\147"))) + ((date 2026-08-09) (class_ ("II cl.")) + (title "Vir DOM. XI POST PENTECOSTEN, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-08-10) (class_ ("II cl.")) + (title "Rub Feria II. S LAURENTII * MART.,") (te_deum ()) (gloria (true)) + (credo (false)) (praef ("comm. vel de Martyribus. II"))) + ((date 2026-08-11) (class_ ("IV cl.")) + (title "Vir Feria III post Dom. XI post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-08-12) (class_ ("III cl. (Priv.)")) + (title "Alb Feria IV. S Clarae Virg.,") (te_deum (true)) (gloria (true)) + (credo (false)) (praef (comm.))) + ((date 2026-08-13) (class_ ("IV cl.")) + (title "Vir Feria V post Dom. XI post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-08-14) (class_ ("II cl.")) + (title "Viol Feria VI. VIGILIA ASSUMPTIONIS B. MARIAE VIRG.,") + (te_deum (true)) (gloria (false)) (credo (false)) (praef ("comm. I"))) + ((date 2026-08-15) (class_ ("I cl.")) + (title "Alb Sabb. IN ASSUMPTIONE B. MARIAE VIRG.,") (te_deum ()) + (gloria (true)) (credo (true)) (praef ("BMV Et te in Assumptione. Ad"))) + ((date 2026-08-16) (class_ ("II cl.")) + (title "Vir DOM. XII POST PENTECOSTEN, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-08-17) (class_ ("III cl.")) + (title "Alb Feria II. S Hyacinthi Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef (comm.))) + ((date 2026-08-18) (class_ ("IV cl.")) + (title "Vir Feria III post Dom. XII post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-08-19) (class_ ("III cl.")) + (title "Alb Feria IV. S Ioannis Eudes Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef (comm.))) + ((date 2026-08-20) (class_ ("III cl. (Priv.)")) + (title "Alb Feria V. S Bernardi Abb. et Eccl. Doct.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. \226\128\147"))) + ((date 2026-08-21) (class_ ("III cl.")) + (title + "Alb Feria VI. S Ioannae Franciscae Fr\195\169miot de Chantal Vid.,") + (te_deum (true)) (gloria (true)) (credo (false)) (praef (comm.))) + ((date 2026-08-22) (class_ ("II cl.")) + (title "Alb Sabb. IMMACULATI CORDIS B. MARIAE VIRG.,") (te_deum ()) + (gloria (true)) (credo (true)) (praef ("BMV Et te in Festivitate. Ad"))) + ((date 2026-08-23) (class_ ("II cl.")) + (title "Vir DOM. XIII POST PENTECOSTEN, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-08-24) (class_ ("II cl.")) + (title "Rub Feria II. S BARTHOLOMAEI * AP.,") (te_deum ()) + (gloria (true)) (credo (true)) (praef (App.))) + ((date 2026-08-25) (class_ ("III cl.")) + (title "Alb Feria III. S Ludovici Regis Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef (comm.))) + ((date 2026-08-26) (class_ ("IV cl.")) + (title "Vir Feria IV post Dom. XIII post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-08-27) (class_ ("III cl.")) + (title "Alb Feria V. S Iosephi Calasanctii Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef (comm.))) + ((date 2026-08-28) (class_ ("III cl. (Priv.)")) + (title "Alb Feria VI. S Augustini Ep., Conf. et Eccl. Doct.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-08-29) (class_ ("III cl. (Priv.)")) + (title "Rub Sabb. In Decollatione S Ioannis * Baptistae,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef ("comm. vel de S Ioanni Baptista \226\128\147"))) + ((date 2026-08-30) (class_ ("II cl.")) + (title "Vir DOM. XIV POST PENTECOSTEN, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-08-31) (class_ ("III cl.")) + (title "Alb Feria II. S Raymundi Nonnati Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef (comm.))) + ((date 2026-09-01) (class_ ("IV cl.")) + (title "Vir Feria III post Dom. XIV post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-09-02) (class_ ("III cl.")) + (title "Alb Feria IV. S Stephani Regis Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef (comm.))) + ((date 2026-09-03) (class_ ("III cl. (Priv.)")) + (title "Alb Feria V. S Pii X Papae et Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. Ad"))) + ((date 2026-09-04) (class_ ("IV cl.")) + (title "Vir Feria VI post Dom. XIV post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-09-05) (class_ ("III cl.")) + (title "Alb Sabb. S Laurentii Iustiniani Ep. et Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef ("comm. Sabbatum primum in mense. I"))) + ((date 2026-09-06) (class_ ("II cl.")) + (title "Vir DOM. XV POST PENTECOSTEN, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-09-07) (class_ ("IV cl.")) + (title "Vir Feria II post Dom. XV post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2026-09-08) (class_ ("II cl.")) + (title "Alb Feria III. IN NATIVITATE B. MARIAE VIRG.,") (te_deum ()) + (gloria (true)) (credo (true)) (praef ("BMV Et te in Nativitate. Ad"))) + ((date 2026-09-09) (class_ ("IV cl.")) + (title "Vir Feria IV post Dom. XV post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-09-10) (class_ ("III cl.")) + (title "Alb Feria V. S Nicolai de Tolentino Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef (comm.))) + ((date 2026-09-11) (class_ ("IV cl.")) + (title "Vir Feria VI post Dom. XV post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-09-12) (class_ ("III cl. (Priv.)")) + (title "Alb Sabb. Sanctissimi Nominis Mariae,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("BMV Et te in Festivitate. I"))) + ((date 2026-09-13) (class_ ("II cl.")) + (title "Vir DOM. XVI POST PENTECOSTEN, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-09-14) (class_ ("II cl.")) + (title "Rub Feria II. IN EXALTATIONE S CRUCIS,") (te_deum ()) + (gloria (true)) (credo (true)) + (praef + ("de Sancta Cruce. In Epistola ad verba Ut in nomine Iesu usque ad infernorum inclusive genuflectitur, item in Choro ab omnibus in Missa in cantu. II"))) + ((date 2026-09-15) (class_ ("II cl.")) + (title "Alb Feria III. SEPTEM DOLORUM B. MARIAE VIRGINIS,") (te_deum ()) + (gloria (true)) (credo (true)) (praef ("BMV Et te in Transfixione. Ad"))) + ((date 2026-09-16) (class_ ("III cl. (Priv.)")) + (title "Rub Feria IV. SS Cornelis * Papae et Cypriani * Ep., Mm.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef ("comm. vel de Martyribus."))) + ((date 2026-09-17) (class_ ("IV cl.")) + (title "Vir Feria V post Dom. XVI post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-09-18) (class_ ("III cl.")) + (title "Alb Feria VI. S Iosephi de Cupertino Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef (comm.))) + ((date 2026-09-19) (class_ ("III cl.")) + (title "Rub Sabb. SS Ianuarii Ep. et Sociorum Mm.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. I"))) + ((date 2026-09-20) (class_ ("II cl.")) + (title "Vir DOM. XVII POST PENTECOSTEN, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-09-21) (class_ ("II cl.")) + (title "Rub Feria II. S MATTHAEI * AP. ET EV.,") (te_deum ()) + (gloria (true)) (credo (true)) (praef (App.))) + ((date 2026-09-22) (class_ ("III cl.")) + (title "Alb Feria III. S Thomae de Villanova Ep. et Conf.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef + ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa SS Mauritii et Sociorum Mm. (rub.) Intret in conspectu tuo, Gloria, ors. et Evangelium pr., comm. S Thomae de Villanova Ep. et Conf., praef. comm. vel de Martyribus."))) + ((date 2026-09-23) (class_ ("II cl.")) + (title "Viol FERIA IV QUATTUOR TEMP., De ea,") (te_deum (true)) + (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147 Quoad Flectamus genua vide RM 440."))) + ((date 2026-09-24) (class_ ("IV cl.")) + (title "Vir Feria V post Dom. XVII post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-09-25) (class_ ("II cl.")) + (title "Viol FERIA VI QUATTUOR TEMP., De ea,") (te_deum (true)) + (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2026-09-26) (class_ ("II cl.")) + (title "Viol SABB. QUATTUOR TEMP., De eo,") (te_deum (true)) + (gloria (false)) (credo (false)) + (praef + ("comm. \226\128\147 Quoad Flectamus genua vide RM 440. Quoad lectiones vide RM 468. I"))) + ((date 2026-09-27) (class_ ("II cl.")) + (title "Vir DOM. XVIII POST PENTECOSTEN, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-09-28) (class_ ("III cl.")) + (title "Rub Feria II. S Wenceslai Ducis Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. I"))) + ((date 2026-09-29) (class_ ("I cl.")) + (title "Alb Feria III. IN DEDICATIONE S MICHA\195\139LIS ARCHANGELI,") + (te_deum ()) (gloria (true)) (credo (true)) + (praef ("comm. vel de Angelis. II"))) + ((date 2026-09-30) (class_ ("III cl. (Priv.)")) + (title "Alb Feria IV. S Hieronymi Presbyteri, Conf. et Eccl. Doct.,") + (te_deum (true)) (gloria (true)) (credo (false)) (praef ("comm. Ad"))) + ((date 2026-10-01) (class_ ("IV cl.")) + (title "Vir Feria V post Dom. XVIII post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-10-02) (class_ ("III cl. (Priv.)")) + (title "Alb Feria VI. SS Angelorum Custodum,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef + ("comm. vel de Angelis. Feria VI prima in mense. Vesper\195\166 pr."))) + ((date 2026-10-03) (class_ ("III cl. (Priv.)")) + (title "Alb Sabb. S Teresiae a Iesu Infante Virg.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef + ("comm. Sabbatum primum in mense. I Vesper\195\166 de seq. dom., ut in Psalt. de sabb, ad Magn. ant. Adaperiat (dom. I octobris), or. pr., sine comm. \226\128\147 Compl. de sabb."))) + ((date 2026-10-04) (class_ ("II cl.")) + (title "Vir DOM. XIX POST PENTECOSTEN, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-10-05) (class_ ("IV cl.")) + (title "Vir Feria II post Dom. XIX post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-10-06) (class_ ("III cl. (Priv.)")) + (title "Alb Feria III. S Brunonis Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef ("comm. Vesper\195\166 de festo. 100"))) + ((date 2026-10-07) (class_ ("II cl.")) + (title "Alb Feria IV. B. MARIAE VIRG. A ROSARIO,") (te_deum ()) + (gloria (true)) (credo (true)) (praef ("BMV Et te in Festivitate. Ad"))) + ((date 2026-10-08) (class_ ("III cl.")) + (title "Alb Feria V. S Birgittae Vid.,") (te_deum (true)) (gloria (true)) + (credo (false)) + (praef + ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa SS Sergii, Bacchi, Marcelli et Apuleii Mm. (rub.) Sapientiam Sanctorum, Gloria, ors. pr., comm. S Birgittae Vid., praef. comm. vel de Martyribus. Vesper\195\166 de festo, sine comm."))) + ((date 2026-10-09) (class_ ("III cl.")) + (title "Alb Feria VI. S Ioannis Leonardi Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef + ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa pr. SS Dionysii Ep., Rustici et Eleutherii Mm. (rub.), Gloria, comm. S Ioannis Leonardi Conf., praef. comm. vel de Martyribus. Vesper\195\166 de festo, sine comm."))) + ((date 2026-10-10) (class_ ("III cl.")) + (title "Alb Sabb. S Francisci Borgiae Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef + ("comm. I Vesper\195\166 de seq. dom., ut in Psalt. de sabb, ad Magn. ant. Refulsit sol (dom. II octobris), or. pr., sine comm. \226\128\147 Compl. de sabb."))) + ((date 2026-10-11) (class_ ("II cl.")) + (title "Vir DOM. XX POST PENTECOSTEN, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-10-12) (class_ ("IV cl.")) + (title "Vir Feria II post Dom. XX post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. Vesper\195\166 de feria or. dom. pr\195\166c."))) + ((date 2026-10-13) (class_ ("III cl.")) + (title "Alb Feria III. S Eduardis Regis Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef ("comm. Vesper\195\166 de festo."))) + ((date 2026-10-14) (class_ ("III cl. (Priv.)")) + (title "Rub Feria IV. S Callisti I Papae et Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef ("comm. vel de Martyribus. Vesper\195\166 de festo."))) + ((date 2026-10-15) (class_ ("III cl. (Priv.)")) + (title "Alb Feria V. S Teresiae Virg.,") (te_deum (true)) (gloria (true)) + (credo (false)) (praef ("comm. \226\128\147"))) + ((date 2026-10-16) (class_ ("III cl.")) + (title "Alb Feria VI. S Hedwigis Vid.,") (te_deum (true)) (gloria (true)) + (credo (false)) (praef ("comm. Vesper\195\166 de festo."))) + ((date 2026-10-17) (class_ ("III cl.")) + (title "Alb Sabb. S Margaritae Mariae Alacoque Virg.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef + ("comm. I Vesper\195\166 de seq. dom., ut in Psalt. de sabb, ad Magn. ant. Exaudiat Dominus (dom. IV octobris), or. pr., sine comm. \226\128\147 Compl. de sabb."))) + ((date 2026-10-18) (class_ ("II cl.")) + (title "Vir DOM. XXI POST PENTECOSTEN, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-10-19) (class_ ("III cl.")) + (title "Alb Feria II. S Petri de Alcantara Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef ("comm. Vesper\195\166 de festo."))) + ((date 2026-10-20) (class_ ("III cl.")) + (title "Alb Feria III. S Ioannis Cantii Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef ("comm. Vesper\195\166 de festo."))) + ((date 2026-10-21) (class_ ("IV cl.")) + (title "Vir Feria IV post Dom. XXI post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-10-22) (class_ ("IV cl.")) + (title "Vir Feria V post Dom. XXI post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. Vesper\195\166 de feria or. dom. pr\195\166c."))) + ((date 2026-10-23) (class_ ("III cl.")) + (title "Alb Feria VI. S Antonii Mariae Claret Ep. et Conf.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-10-24) (class_ ("III cl.")) + (title "Alb Sabb. S Rapha\195\171lis Archangeli,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef + ("comm. vel de Angelis. I Vesper\195\166 de seq., sine comm. \226\128\147 Compl. de dom. 104"))) + ((date 2026-10-25) (class_ ("I cl.")) + (title "Alb Dom. DOMINI NOSTRI JESU CHRISTI REGIS,") (te_deum ()) + (gloria (true)) (credo (true)) + (praef + ("de Domino Nostro Jesu Rege. Hodie, in omnibus ecclesiis, coram Ss.mo Sacramento exposito, recitetur formula consecrationis generis humani Christo Regi, cum Litaniis de eodem Sacro Corde. II Vesper\195\166 pr. Hodie prohibentur omnes Missae defunctorum, etiam exsequialis."))) + ((date 2026-10-26) (class_ ("IV cl.")) + (title "Vir Feria II post Dom. XXII post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-10-27) (class_ ("IV cl.")) + (title "Vir Feria III post Dom. XXII post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. Vesper\195\166 de feria, or. dom. XXII post Pent."))) + ((date 2026-10-28) (class_ ("II cl.")) + (title "Rub Feria IV. SS SIMONIS * ET IUD\195\134 * APP.,") (te_deum ()) + (gloria (true)) (credo (true)) + (praef + ("App. In Canone Miss\195\166, nomen S. Apostoli Iud\195\166 inscribitur cum nomine Thadd\195\166i: ergo inclinatur caput quando dicitur Thadd\195\166i. Vesper\195\166 de Comm. \226\128\147 Compl. de dom. Hodie permittuntur tantum Missae votivae et defunctorum I et II classis."))) + ((date 2026-10-29) (class_ ("IV cl.")) + (title "Vir Feria V post Dom. XXII post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. Vesper\195\166 de feria or. dom. XXII post Pent."))) + ((date 2026-10-30) (class_ ("IV cl.")) + (title "Vir Feria VI post Dom. XXII post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. Vesper\195\166 de feria or. dom. XXII post Pent."))) + ((date 2026-10-31) (class_ ("IV cl.")) + (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) + (credo (false)) + (praef + ("BMV Et te in Veneratione. I Vesper\195\166 de seq. \226\128\147 Compl. de dom. 106"))) + ((date 2026-11-01) (class_ ("I cl.")) (title "Alb Dom. OMNIUM SANCTORUM,") + (te_deum ()) (gloria (true)) (credo (true)) + (praef ("Trinit. vel de Omnibus Sanctis et Patronis. II"))) + ((date 2026-11-02) (class_ ("I cl.")) + (title "Nig Feria II. IN COMMEMORATIONE OMNIUM FIDELIUM DEFUNCTORUM,") + (te_deum ()) (gloria (false)) (credo (false)) + (praef + ("defunctorum, unica or. \226\128\147 Benedictio non dicitur. \226\128\147 Si tres Miss\195\166 celebrantur sine intermissione, sequentia dici debet tantum in Missa principali; si minus, dici debet in Missa prima. In aliis Missis, nisi sint in cantu, sequentia omitti potest."))) + ((date 2026-11-03) (class_ ("IV cl.")) + (title "Vir Feria III post Dom. XXIII post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2026-11-04) (class_ ("III cl. (Priv.)")) + (title "Alb Feria IV. S Caroli Ep. et Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. \226\128\147"))) + ((date 2026-11-05) (class_ ("IV cl.")) + (title "Vir Feria V post Dom. XXIII post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-11-06) (class_ ("IV cl.")) + (title "Vir Feria VI post Dom. XXIII post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. Feria VI prima in mense."))) + ((date 2026-11-07) (class_ ("IV cl.")) + (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) + (credo (false)) + (praef ("BMV Et te in Veneratione. Sabbatum primum in mense. I"))) + ((date 2026-11-08) (class_ ("II cl.")) + (title "Vir DOM. V QUI SUPERFUIT POST EPIPHANIAM, De ea,") + (te_deum (true)) (gloria (true)) (credo (true)) + (praef + ("Trinit. Dicitur Missa qu\195\166 inscribitur \194\171Dominica. V qui superfuit post Epiphaniam\194\187. Antiphonae ad Introitum, ad Offertorium et ad Communionem, necnon graduale et Alleluia cum suo versu, sumuntur e Dom. XXIII post Pent.; orationes, Epistola et Evangelium, e Dom. V qui superfuit post Epiphaniam. Ad II"))) + ((date 2026-11-09) (class_ ("II cl.")) + (title + "Alb Feria II. IN DEDICATIONE ARCHIBASILICAE SANCTISSIMI SALVATORIS,") + (te_deum ()) (gloria (true)) (credo (true)) + (praef ("comm. vel de Dedicatione ecclesi\195\166."))) + ((date 2026-11-10) (class_ ("III cl.")) + (title "Alb Feria III. S Andreae Avellini Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef + ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa pr. SS Tryphonis, Respicii et Nymphae Virg., Mm. (rub.), Gloria, comm. S Andreae Avellini Conf., praef. comm. vel de Martyribus."))) + ((date 2026-11-11) (class_ ("III cl. (Priv.)")) + (title "Alb Feria IV. S Martini Ep. et Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef (comm.))) + ((date 2026-11-12) (class_ ("III cl.")) + (title "Rub Feria V. S Martini I Papae et Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus."))) + ((date 2026-11-13) (class_ ("III cl.")) + (title "Alb Feria VI. S Didaci Conf.,") (te_deum (true)) (gloria (true)) + (credo (false)) (praef ("comm. \226\128\147"))) + ((date 2026-11-14) (class_ ("III cl. (Priv.)")) + (title "Rub Sabb. S Iosaphat Ep. et Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef ("comm. vel de Martyribus \226\128\147"))) + ((date 2026-11-15) (class_ ("II cl.")) + (title "Vir DOM. VI QUI SUPERFUIT POST EPIPHANIAM, De ea,") + (te_deum (true)) (gloria (true)) (credo (true)) + (praef + ("Trinit. Dicitur Missa qu\195\166 inscribitur \194\171Dominica. VI qui superfuit post Epiphaniam\194\187. Antiphonae ad Introitum, ad Offertorium et ad Communionem, necnon graduale et Alleluia cum suo versu, sumuntur e Dom. XXIII post Pent.; orationes, Epistola et Evangelium, e Dom. VI qui superfuit post Epiphaniam. Ad II"))) + ((date 2026-11-16) (class_ ("III cl.")) + (title "Alb Feria II. S Gertrudis Virg.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef (comm.))) + ((date 2026-11-17) (class_ ("III cl.")) + (title "Alb Feria III. S Gregorii Thaumaturgi Ep. et Conf.,") + (te_deum (true)) (gloria (true)) (credo (false)) (praef (comm.))) + ((date 2026-11-18) (class_ ("III cl. (Priv.)")) + (title + "Alb Feria IV. In Dedicatione Basilicarum SS Petri et Pauli App.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef ("comm. vel de Dedicatione ecclesi\195\166."))) + ((date 2026-11-19) (class_ ("III cl.")) + (title "Alb Feria V. S Elisabeth Vid.,") (te_deum (true)) (gloria (true)) + (credo (false)) + (praef + ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa S Pontiani Papae et Mart. (rub.) Si diligis, Gloria, comm. S Elisabeth Vid., praef. comm. vel de Martyribus."))) + ((date 2026-11-20) (class_ ("III cl.")) + (title "Alb Feria VI. S Felicis de Valois Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef (comm.))) + ((date 2026-11-21) (class_ ("III cl.")) + (title "Alb Sabb. In Praesentatione B. Mariae Virg.,") (te_deum (true)) + (gloria (true)) (credo (false)) + (praef ("BMV Et te in Pr\195\166sentatione. I"))) + ((date 2026-11-22) (class_ ("II cl.")) + (title "Vir DOM. XXIV & ULTIMA POST PENTECOSTEN, De ea,") + (te_deum (true)) (gloria (true)) (credo (true)) + (praef ("Trinit. Ad II"))) + ((date 2026-11-23) (class_ ("III cl. (Priv.)")) + (title "Rub Feria II. S Clementis I * Papae et Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. Ad"))) + ((date 2026-11-24) (class_ ("III cl. (Priv.)")) + (title "Alb Feria III. S Ioannis a Cruce Conf. et Eccl. Doct.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-11-25) (class_ ("III cl.")) + (title "Rub Feria IV. S Catharinae Virg. et Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus."))) + ((date 2026-11-26) (class_ ("III cl.")) + (title "Alb Feria V. S Silvestri Abb.,") (te_deum (true)) (gloria (true)) + (credo (false)) + (praef + ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa S Petri Alexandrini Ep. et Mart. (rub.) Statuit ei, Gloria, comm. S Silvestri Abb., praef. comm. vel de Martyribus. \226\128\147"))) + ((date 2026-11-27) (class_ ("IV cl.")) + (title "Vir Feria VI post Dom. XXIV & Ultima post Pentecosten, De ea,") + (te_deum (false)) (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-11-28) (class_ ("IV cl.")) + (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) + (credo (false)) (praef ("BMV Et te in Veneratione. I"))) + ((date 2026-11-29) (class_ ("I cl.")) + (title "Viol DOM. I ADVENTUS, De ea,") (te_deum (true)) (gloria (false)) + (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-11-30) (class_ ("II cl.")) + (title "Rub Feria II. S ANDREAE * APOSTOLI,") (te_deum ()) + (gloria (true)) (credo (true)) (praef ("App. Ad"))) + ((date 2026-12-01) (class_ ("III cl.")) + (title "Viol Feria III post Dom. I Adventus, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2026-12-02) (class_ ("III cl.")) + (title "Rub Feria IV. S Bibianae Virg. et Mart.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. Ad"))) + ((date 2026-12-03) (class_ ("III cl. (Priv.)")) + (title "Alb Feria V. S Francisci Xavierii Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. Ad"))) + ((date 2026-12-04) (class_ ("III cl.")) + (title "Alb Feria VI. S Petri Chrysologi Ep., Conf. et Eccl. Doct.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef + ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa S Barbarae Virg. et Mart. (rub.) Loquebar de testimoniis tuis, Gloria, comm. 1\194\170 Feriae, comm. 2\194\170 S Petri Chrysologi Ep., Conf. et Eccl. Doct., praef. comm. vel de Martyribus. Feria VI prima in mense. Ad"))) + ((date 2026-12-05) (class_ ("III cl.")) + (title "Viol Sabb. post Dom. I Adventus, De eo,") (te_deum ()) + (gloria (false)) (credo (false)) + (praef ("comm. Sabbatum primum in mense. I"))) + ((date 2026-12-06) (class_ ("I cl.")) + (title "Viol DOM. II ADVENTUS, De ea,") (te_deum (true)) (gloria (false)) + (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-12-07) (class_ ("III cl. (Priv.)")) + (title "Alb Feria II. S Ambrosii Ep., Conf. et Eccl. Doct.,") + (te_deum (true)) (gloria (true)) (credo (false)) + (praef ("comm. \226\128\147"))) + ((date 2026-12-08) (class_ ("I cl.")) + (title "Alb Feria III. IN CONCEPTIONE IMMACULATA B. MARIAE VIRGINIS,") + (te_deum ()) (gloria (true)) (credo (true)) + (praef ("BMV Et te in Conceptione Immaculata. Ad"))) + ((date 2026-12-09) (class_ ("III cl.")) + (title "Viol Feria IV post Dom. II Adventus, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2026-12-10) (class_ ("III cl.")) + (title "Viol Feria V post Dom. II Adventus, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2026-12-11) (class_ ("III cl. (Priv.)")) + (title "Alb Feria VI. S Damasi I Papae et Conf.,") (te_deum (true)) + (gloria (true)) (credo (false)) (praef ("comm. Ad"))) + ((date 2026-12-12) (class_ ("III cl.")) + (title "Viol Sabb. post Dom. II Adventus, De eo,") (te_deum ()) + (gloria (false)) (credo (false)) (praef ("comm. I"))) + ((date 2026-12-13) (class_ ("I cl.")) + (title "DOM. III ADVENTUS (GAUDETE), De ea,") (te_deum (true)) + (gloria (false)) (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-12-14) (class_ ("III cl.")) + (title "Viol Feria II post Dom. III Adventus (Gaudete), De ea,") + (te_deum ()) (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2026-12-15) (class_ ("III cl.")) + (title "Viol Feria III post Dom. III Adventus (Gaudete), De ea,") + (te_deum ()) (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2026-12-16) (class_ ("II cl.")) + (title "Viol FERIA IV QUATTUOR TEMP., De ea,") (te_deum ()) + (gloria (false)) (credo (false)) + (praef ("comm. \226\128\147 Quoad Flectamus genua vide RM 440."))) + ((date 2026-12-17) (class_ ("II cl.")) + (title "Viol FERIA V POST DOM. III ADVENTUS (GAUDETE), De ea,") + (te_deum ()) (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2026-12-18) (class_ ("II cl.")) + (title "Viol FERIA VI QUATTUOR TEMP., De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2026-12-19) (class_ ("II cl.")) + (title "Viol SABB. QUATTUOR TEMP., De eo,") (te_deum ()) (gloria (false)) + (credo (false)) + (praef + ("comm. \226\128\147 Quoad Flectamus genua vide RM 440. Quoad lectiones vide RM 468. I"))) + ((date 2026-12-20) (class_ ("I cl.")) + (title "Viol DOM. IV ADVENTUS, De ea,") (te_deum (true)) (gloria (false)) + (credo (true)) (praef ("Trinit. Ad II"))) + ((date 2026-12-21) (class_ ("II cl.")) + (title "Rub Feria II. S THOM\195\134 * APOSTOLI,") (te_deum ()) + (gloria (true)) (credo (true)) (praef ("App. Ad"))) + ((date 2026-12-22) (class_ ("II cl.")) + (title "Viol FERIA III POST DOM. IV ADVENTUS, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2026-12-23) (class_ ("II cl.")) + (title "Viol FERIA IV POST DOM. IV ADVENTUS, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef (comm.))) + ((date 2026-12-24) (class_ ("I cl.")) + (title "Viol Feria V. VIGILIA NATIVITATIS DOMINI,") (te_deum (true)) + (gloria (false)) (credo (false)) (praef ("comm. I"))) + ((date 2026-12-25) (class_ ("I cl.")) + (title "Alb Feria VI. IN NATIVITATE DOMINI,") (te_deum ()) + (gloria (true)) (credo (true)) + (praef + ("et Communic. pr. per totam oct. \226\128\147 In Communicantes: in 1\194\170 Missa dicitur Noctem sacratissimam celebrantes, qua, in 2\194\170 et 3\194\170 Missa et per octavam Diem sacratissimum celebrantes, quo. \226\128\147 In 2\194\170 Missa (etiam in cantu) fit comm. S. Anastasi\195\166 * M. \226\128\147 In Missis in cantu, ad verba symboli Et incarnatus est\226\128\166 et homo factus est, omnes genuflectunt versus altare, non tantum cum a celebrante recitantur, sed etiam cum a choro canuntur (RM 518 b). II"))) + ((date 2026-12-26) (class_ ("II cl.")) + (title "Rub Sabb. S STEPHANI * PROTOMARTYRIS,") (te_deum ()) + (gloria (true)) (credo (true)) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. Ad"))) + ((date 2026-12-27) (class_ ("II cl.")) + (title "Alb DOM. INFRA OCTAVAM NATIVITATIS, De ea,") (te_deum (true)) + (gloria (true)) (credo (true)) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. Ad II"))) + ((date 2026-12-28) (class_ ("II cl.")) + (title "Rub Feria II. SS INNOCENTIUM MM.,") (te_deum ()) (gloria (true)) + (credo (true)) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. Ad"))) + ((date 2026-12-29) (class_ ("II cl.")) + (title "Alb FERIA III DOM. INFRA OCTAVAM NATIVITATIS, De ea,") + (te_deum ()) (gloria (true)) (credo (true)) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum."))) + ((date 2026-12-30) (class_ ("II cl.")) + (title "Alb FERIA IV DOM. INFRA OCTAVAM NATIVITATIS, De ea,") + (te_deum ()) (gloria (true)) (credo (true)) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum."))) + ((date 2026-12-31) (class_ ()) + (title + "Alb FERIA V DOM. INFRA OCTAVAM NATIVITATIS, De ea. \226\128\147 Off. semifestivum. \226\128\147 Ad MAT. invit., hymnus, 9 antt. et 9 pss. cum ultimo V de festo Nativ., Ll. de Scr. occ. cum suis RR (ad 2um additur Gloria Patri)\226\128\147 Ad Laudes antt. de Nativ., pss. de dom., comm. S Silvestri I Papae et Conf. \226\128\147 Ad HORAS ant. et pss. de feria curr., rel ut in festo Nativ. \226\128\147 Ad Primam in R Br. V Qui natus es de Maria Virgine. Missa Puer natus de diebus infra octavam, Gloria, Credo, comm. S Silvestri I Papae et Conf., praef. de Nativ., Communic. de Nativ. diem sacratissimum. I VESPER\195\134 de seq. \226\128\147 Compl. de dom. Hodie ad solemnem recitationem hymni Te Deum, indulgentia plenaria lucrari potest. 126") + (te_deum ()) (gloria (true)) (credo (true)) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. I")))) diff --git a/test/test_colitur.ml b/test/test_colitur.ml index 6db744f..7708fef 100644 --- a/test/test_colitur.ml +++ b/test/test_colitur.ml @@ -16,7 +16,7 @@ let () = Test_rubrics_ef.suite; Test_differential.suite; Test_oracle.suite; Test_oracle.suite_2038; Test_oracle.suite_2035; Test_lms_ordo.suite_2023_2024; Test_lms_ordo.suite_2024_2025; Test_lms_ordo.suite_2025_2026; - Test_lms_ordo.suite_allow_list; + Test_lms_ordo.suite_allow_list; Test_fiuv_ordo.suite; Test_golden.suite; ("lectionary", Test_lectionary.suite); ("lectionary-ef", Test_lectionary_ef.suite); diff --git a/test/test_fiuv_ordo.ml b/test/test_fiuv_ordo.ml new file mode 100644 index 0000000..8b3e942 --- /dev/null +++ b/test/test_fiuv_ordo.ml @@ -0,0 +1,268 @@ +(* Witnesses task (2026-08-22-colitur-celebrant-rubrics-phase1): the + SEVENTH validation layer, and the first UNIVERSAL, SECOND-COMPILER + witness -- the FIUV (Foederatio Internationalis Una Voce) Ordo for + 2025-2026, compiled by Joseph Shaw, independent of the Latin Mass + Society's own three editions (test_lms_ordo.ml) except for sharing a + publisher/host (see test/fixtures/fiuv-ordo-2025-2026.sexp's own + provenance header, and docs/research/ordo/PROVENANCE-ordo-corpus.md, + for the full account of what independence this source does and does + not buy). + + WHY THIS LAYER IS MORE VALUABLE THAN THE LMS ONE, per the task brief's + own four reasons: (1) UNIVERSAL -- no diocesan variants to exclude at + all, so this fixture's own [row] carries no [has_diocesan_variant] + field, unlike the LMS one; (2) IN LATIN, the rubrics' own vocabulary; + (3) BOTH DIRECTIONS EXPLICIT ("Gloria"/"sine Gloria", "Credo"/"sine + Credo") -- used here exactly as with the LMS source; (4) RECORDS THE + TE DEUM, the hinge of RG 431(a)'s own Mass-Gloria rule (deferred to + Phase 2, Breviary nn. 237-238) -- captured into the fixture, NOT + compared here (no colitur-side Te Deum predicate exists yet). + + SCOPE: the CREED (RG 475-476, {!Rite_ef.Rubrics_ef.creed}) is the ONE + axis compared against colitur, per the task brief. [praef] and + [te_deum] are captured into the fixture (a genuinely useful data set + for Phase 2/3's still-unbuilt Gloria and preface rules) but + deliberately NOT validated here -- there is nothing on colitur's own + side yet to compare either against. [class_] (raw, including the FIUV + ordo's own explicit "III cl." vs "III cl. (Priv.)" Cum Sanctissima + convention, stated on its own title page) is likewise captured but not + compared: colitur's core is strictly the 1962 Missal with Cum + Sanctissima/Quo Magis modelled only as an OVERLAY, never core + (CLAUDE.md's own binding decision #2), so colitur's UNOVERLAID output + has no Cum-Sanctissima-aware notion of "III cl." vs "(Priv.)" to + compare this field against in the first place -- comparing it would be + comparing the Ordo against a question colitur's default configuration + was never asked. *) + +module Cal = Colitur_kernel.Calendar +module Layer = Colitur_kernel.Layer +module Overlay = Colitur_kernel.Overlay +module LD = Colitur_kernel.Liturgical_day +module Date = Colitur_kernel.Date +module V = Rite_ef.Vocab_ef + +let sanctoral_path = "../data/ef/sanctoral.sexp" +let adjustments_path = "../data/ef/adjustments.sexp" +let fixture_path = "fixtures/fiuv-ordo-2025-2026.sexp" +let allow_list_path = "../data/ef/expected-divergences-fiuv.sexp" + +(* Duplicated, not shared -- test_lms_ordo.ml's own identical function + carries the same "no shared .mli" reasoning. *) +let sha256_of_file path = + let tmp = Filename.temp_file "colitur_fiuv_ordo_sha256" ".txt" in + Fun.protect + ~finally:(fun () -> try Sys.remove tmp with Sys_error _ -> ()) + (fun () -> + let cmd = Printf.sprintf "sha256sum %s > %s" (Filename.quote path) (Filename.quote tmp) in + let rc = Sys.command cmd in + if rc <> 0 then Alcotest.failf "sha256sum exited %d for %s (is it on PATH?)" rc path; + let ic = open_in tmp in + let line = + try input_line ic + with End_of_file -> + close_in ic; + Alcotest.failf "sha256sum produced no output for %s" path + in + close_in ic; + match String.index_opt line ' ' with + | Some i -> String.sub line 0 i + | None -> Alcotest.failf "unexpected sha256sum output for %s: %S" path line) + +let fixture_sha256 = "becadaad43b3a42c4eb820cb4e93d68f9b1c07a2c8e5273167cd599758af5c67" + +let real_layer () = + let layer = + match Layer.load V.rank_of_sexp sanctoral_path with + | Ok l -> l + | Error e -> Alcotest.failf "%s: failed to load: %s" sanctoral_path e + in + let overlay = + match Overlay.load V.rank_of_sexp adjustments_path with + | Ok o -> o + | Error e -> Alcotest.failf "%s: failed to load: %s" adjustments_path e + in + let layer, diagnostics = Overlay.apply layer overlay in + Alcotest.(check (list string)) "the committed overlay applies cleanly, no diagnostics" [] + (List.map Overlay.diagnostic_to_string diagnostics); + layer + +let real_lectionary () = + match Colitur_kernel.Lectionary.load "../data/ef/lectionary.sexp" with + | Ok l -> l + | Error e -> Alcotest.failf "../data/ef/lectionary.sexp: failed to load: %s" e + +let real_commons () = + match Rite_ef.Lectionary_ef.Commons.load "../data/ef/commons.sexp" with + | Ok c -> c + | Error e -> Alcotest.failf "../data/ef/commons.sexp: failed to load: %s" e + +(* ---------------------------------------------------------------------- *) +(* The Ordo side: the sexp row, mirrored from tools/extract_fiuv_ordo.ml's *) +(* own [row] -- see this file's own header on why there is no *) +(* [has_diocesan_variant] field here, unlike the LMS mirror. *) +(* ---------------------------------------------------------------------- *) + +open Sexplib0.Sexp_conv + +type ordo_row = { + date : string; + class_ : string option; + title : string; + te_deum : bool option; + gloria : bool option; + credo : bool option; + praef : string option; +} +[@@deriving sexp] + +let ordo_rows () = + let sexp = + try Sexplib.Sexp.load_sexp fixture_path + with e -> Alcotest.failf "%s: failed to load: %s" fixture_path (Printexc.to_string e) + in + list_of_sexp ordo_row_of_sexp sexp + +let window_first = "2025-11-27" +let window_last = "2026-12-31" + +(* ---------------------------------------------------------------------- *) +(* The colitur side, over the same window -- mirrors test_lms_ordo.ml's *) +(* own [colitur_rows] exactly (a liturgical year straddles two civil *) +(* years, so the resolution walk starts a civil year early and ends one *) +(* late). *) +(* ---------------------------------------------------------------------- *) + +type colitur_row = { c_date : string; c_creed : bool } + +let colitur_rows () = + let layer = real_layer () in + let rite = Rite_ef.context ~lectionary:(real_lectionary ()) ~commons:(real_commons ()) in + let by_rata : (int, (V.season, V.rank) LD.t) Hashtbl.t = Hashtbl.create 800 in + for y = 2024 to 2027 do + let days = Cal.year rite layer y in + Array.iter (fun (d : (V.season, V.rank) LD.t) -> Hashtbl.replace by_rata (Date.to_rata d.LD.date) d) days + done; + let mk s = match Date.of_iso8601 s with Ok d -> d | Error e -> Alcotest.failf "%s: %s" s e in + let rows = ref [] in + let d = ref (mk window_first) in + let stop = mk window_last in + while Date.compare !d stop <= 0 do + (match Hashtbl.find_opt by_rata (Date.to_rata !d) with + | Some day -> rows := { c_date = Date.to_iso8601 day.LD.date; c_creed = day.LD.creed } :: !rows + | None -> Alcotest.failf "no colitur day resolved for %s" (Date.to_iso8601 !d)); + d := Date.add_days !d 1 + done; + List.rev !rows + +(* ---------------------------------------------------------------------- *) +(* data/ef/expected-divergences-fiuv.sexp -- same shape as the LMS/ *) +(* missalemeum allow-lists' own [allow_entry]. A SEPARATE file: this Ordo *) +(* is a fourth, independent lineage from all three others already in this *) +(* project. *) +(* ---------------------------------------------------------------------- *) + +type allow_entry = { id : string; citation : string; verdict : string; note : string; expected_rows : int } +[@@deriving sexp] + +let load_allow_list () = + let sexps = + try Sexplib.Sexp.load_sexps allow_list_path + with e -> Alcotest.failf "%s: failed to load: %s" allow_list_path (Printexc.to_string e) + in + List.map allow_entry_of_sexp sexps + +(* ---------------------------------------------------------------------- *) +(* Tests *) +(* ---------------------------------------------------------------------- *) + +let test_fixture_checksum () = + Alcotest.(check string) "fixture SHA-256 matches its provenance note" fixture_sha256 (sha256_of_file fixture_path) + +let test_dates_align () = + let ordo = ordo_rows () in + let colitur = colitur_rows () in + Alcotest.(check int) "the Ordo fixture has 400 rows (2025-11-27..2026-12-31)" 400 (List.length ordo); + Alcotest.(check int) "colitur resolved the same number of days" (List.length ordo) (List.length colitur); + (match ordo with o :: _ -> Alcotest.(check string) "first date" window_first o.date | [] -> Alcotest.fail "empty"); + (match List.rev ordo with + | o :: _ -> Alcotest.(check string) "last date" window_last o.date + | [] -> Alcotest.fail "empty"); + let mismatched = + List.filter_map + (fun (o, c) -> if String.equal o.date c.c_date then None else Some (o.date, c.c_date)) + (List.combine ordo colitur) + in + Alcotest.(check (list (pair string string))) "no misaligned dates" [] mismatched + +(* Holy Saturday (2026-04-04) is the ONLY day this fixture shows no Credo + marker for -- confirmed directly against the raw source: unlike the + LMS Ordo (whose "no Mass" day is Good Friday, the 1955-restored Holy + Week having no Mass that day at all), THIS Ordo's Good Friday DOES + carry a Mass rubric ("Missa pr., ... Gloria, sine Credo, praef. + comm."), leaving Holy Saturday as the sole day with no Mass mentioned + at all (its own Vigil Mass is conventionally counted under Easter + Sunday's own date in this source, matching a real, if narrower, + instance of the same "a vigil Mass is dated to the day it anticipates" + convention the LMS characterisation already established). Asserted as + the ONLY such day, not merely observed once: a parsing regression that + swallowed a real row would otherwise silently join this bucket instead + of failing loudly as an unexplained mismatch. *) +let test_creed_coverage () = + let ordo = ordo_rows () in + let no_creed = List.filter (fun o -> o.credo = None) ordo in + Alcotest.(check (list string)) "only Holy Saturday has no Ordo Creed marker" [ "2026-04-04" ] + (List.map (fun o -> o.date) no_creed) + +let describe_creed_mismatch (o : ordo_row) (c : colitur_row) = + Printf.sprintf "%s %S: colitur creed=%b, Ordo creed=%b" o.date o.title c.c_creed (Option.get o.credo) + +(* Which allow-list id, if any, explains a Creed mismatch on this date -- + date-keyed, not "any declared entry excuses any mismatch", the same + discipline test_lms_ordo.ml's own [allow_list_id_for_date] uses and + for the identical reason: an entry that starts firing on an + UNEXPECTED new date must be visible as a real change, not silently + absorbed. Empty until characterisation found a real divergence to + name. *) +let fiuv_allow_list_id_for_date = ([] : (string * string) list) + +let test_creed_matches_or_is_explained () = + let ordo = ordo_rows () in + let colitur = colitur_rows () in + let allow_list = load_allow_list () in + let by_id = List.map (fun e -> (e.id, e)) allow_list in + let unexplained = ref [] in + let explained_counts = Hashtbl.create 8 in + List.iter2 + (fun (o : ordo_row) (c : colitur_row) -> + if not (String.equal o.date c.c_date) then Alcotest.failf "misaligned: ordo %s vs colitur %s" o.date c.c_date; + match o.credo with + | None -> () + | Some ocreed -> + if Bool.equal ocreed c.c_creed then () + else + match List.assoc_opt o.date fiuv_allow_list_id_for_date with + | Some id -> Hashtbl.replace explained_counts id (1 + try Hashtbl.find explained_counts id with Not_found -> 0) + | None -> unexplained := describe_creed_mismatch o c :: !unexplained) + ordo colitur; + Alcotest.(check (list string)) "every Creed mismatch is named in the allow-list -- none unexplained" [] + (List.rev !unexplained); + Hashtbl.iter + (fun id n -> + match List.assoc_opt id by_id with + | None -> Alcotest.failf "allow-list entry %s used by the comparator but not declared in %s" id allow_list_path + | Some e -> Alcotest.(check int) (Printf.sprintf "%s: expected_rows matches the actual count" id) e.expected_rows n) + explained_counts; + List.iter + (fun e -> + if not (Hashtbl.mem explained_counts e.id) then + Alcotest.failf "allow-list entry %s is declared but never matched a real divergence" e.id) + allow_list + +let suite = + ( "fiuv-ordo", + [ Alcotest.test_case "fixture SHA-256 matches its provenance note" `Quick test_fixture_checksum; + Alcotest.test_case "streams are 400 rows each, dates aligned 1:1" `Quick test_dates_align; + Alcotest.test_case "only Holy Saturday has no Ordo Creed marker" `Quick test_creed_coverage; + Alcotest.test_case "every Creed difference is named in the cited allow-list -- none unexplained" `Quick + test_creed_matches_or_is_explained + ] ) diff --git a/tools/dune b/tools/dune index 487751e..9a4dea5 100644 --- a/tools/dune +++ b/tools/dune @@ -32,6 +32,7 @@ ; reads no EF-specific vocabulary. (executable (name extract_lms_ordo) + (modules extract_lms_ordo) (libraries colitur_kernel unix sexplib) (preprocess (pps ppx_sexp_conv))) @@ -54,3 +55,16 @@ (deps check_citations.py test_check_citations.py) (action (run python3 test_check_citations.py))) + +; Witnesses task (2026-08-22-colitur-celebrant-rubrics-phase1): turns +; pdftotext's -layout dump of the FIUV universal Ordo into +; test/fixtures/fiuv-ordo-2025-2026.sexp. Run via `dune exec +; tools/extract_fiuv_ordo.exe -- +; `. Same `unix`-for-`sha256sum` usage as extract_lms_ordo.ml; +; `colitur_kernel` only, no `rite_ef` -- same reasoning, dates only. +(executable + (name extract_fiuv_ordo) + (modules extract_fiuv_ordo) + (libraries colitur_kernel unix sexplib) + (preprocess + (pps ppx_sexp_conv))) diff --git a/tools/extract_fiuv_ordo.ml b/tools/extract_fiuv_ordo.ml new file mode 100644 index 0000000..42d3b96 --- /dev/null +++ b/tools/extract_fiuv_ordo.ml @@ -0,0 +1,637 @@ +(* Witnesses task (2026-08-22-colitur-celebrant-rubrics-phase1): turns + pdftotext's -layout dump of the FIUV (Foederatio Internationalis Una + Voce) universal Ordo into test/fixtures/fiuv-ordo-2025-2026.sexp, one + row per day, 2025-11-27..2026-12-31. + + A DIFFERENT format from tools/extract_lms_ordo.ml's own LMS PDFs in + every way that matters (see docs/research/ordo/PROVENANCE-ordo-corpus.md): + UNIVERSAL (no diocesan variants to exclude at all -- one block per day, + not "the first of several"), IN LATIN, using the rubrics' own + vocabulary ("Missa pr., Gloria, sine Credo, praef. comm."), and BOTH + directions of Gloria/Credo are stated explicitly in the source's own + words ("Gloria"/"sine Gloria", "Credo"/"sine Credo") rather than by a + printed flag letter. Hand-rolled, no Str/regex (frozen deps) -- the + same String.sub/index/split_on_char discipline extract_lms_ordo.ml + already uses for a different publisher's layout. + + THE KEY STRUCTURAL FACTS this parser leans on, established during + characterisation (see the fixture's own provenance header for the + full record): + + 1. A day-start line's own FIRST token is always "<1-2 digit day>." + (e.g. "27.", "3."), immediately followed by a colour code (not + anchored on below -- colour is captured as raw prose, never parsed + into a closed set, because a few real days use a COMPOUND colour + ("Viol. in Off., Alb. in Missa." on Holy Thursday) or drop the + token to a blank cell entirely (13 December 2026, a rendering + quirk) -- neither is needed for anything this task compares). + + 2. Month headers/running-footers name a month EITHER in English with a + trailing ROMAN-NUMERAL year ("November MMXXV", the book's own first + two months only) OR bare in Latin with no year at all + ("Januarius", "Februarius", ... every month after). The English + Nov/Dec spellings happen to be IDENTICAL to their Latin + equivalents, so one 12-entry table covers both vocabularies. + CHARACTERISATION FINDING: the SECOND header ("December MMXV") is a + publisher-side TYPO -- MMXV is 2015, ten years off, contradicted by + every neighbouring date and by month-order inference alone. This + parser therefore reads a Roman-numeral year ONLY off the very + FIRST header encountered (the anchor) and tracks every subsequent + month purely by wraparound inference (increment the year exactly + once, at the Dec->Jan transition) -- the typo is never read at all, + not merely tolerated. + + 3. Every real Mass rubric line starts with the literal token "Missa" + (401 of ~400 real day-blocks, confirmed structurally). A SECOND, + alternate Mass option, when the day offers one, is introduced by + the CAPITALISED two-token sequence "Vel Missa" -- never bare lower- + case "vel" alone, which is the ordinary Latin conjunction "or" and + appears constantly inside ordinary prose (e.g. "praef. comm. vel de + Martyribus", part of ONE preface's own text, not a second Mass + option) -- so only "Vel Missa", both tokens, anchors a real + alternate-option boundary. This parser reads Gloria/Credo/praef. + from the FIRST Mass option only, bounded above by whichever comes + first: "Vel Missa" or "VESPERAE"/"VESPERA" -- the identical + "day's own PRIMARY office, not a menu entry" discipline + extract_lms_ordo.ml already uses for the LMS diocesan-variant + colon boundary. + + 4. SUBSTRING TRAP, found and defended against: "Gloria" is also the + first word of "Gloria Patri" (the psalm doxology, "Glory be to the + Father"), a DIFFERENT liturgical unit that has nothing to do with + whether the Mass's own Gloria in excelsis is said -- and it can + appear INSIDE the very Mass clause being scanned (Good Friday: + "Missa pr., (omittuntur ps. Iudica me et Gloria Patri), Gloria, + sine Credo, praef. comm." -- the real, standalone "Gloria," follows + immediately after). [find_word] below rejects any "Gloria" hit + whose very next token is "Patri", the same whole-token discipline + extract_lms_ordo.ml's own header describes for "V Mass of BVM" + being a substring of "IV Mass of BVM". + + Usage: + pdftotext -layout docs/research/ordo/fiuv-ordo-2025-2026.pdf /tmp/fiuv.txt + dune exec tools/extract_fiuv_ordo.exe -- /tmp/fiuv.txt \ + docs/research/ordo/fiuv-ordo-2025-2026.pdf \ + test/fixtures/fiuv-ordo-2025-2026.sexp *) + +open Sexplib0.Sexp_conv +module Date = Colitur_kernel.Date + +let die fmt = Printf.ksprintf (fun s -> prerr_endline ("extract_fiuv_ordo: " ^ s); exit 1) fmt + +(* Mirrored, not shared, by test/test_fiuv_ordo.ml -- tools/ and test/ + have no common .mli either could hang a shared type from, the same + reasoning extract_lms_ordo.ml's own header already gives. *) +type row = { + date : string; (** ISO-8601 *) + class_ : string option; (** raw, e.g. "III cl.", "III cl. (Priv.)", "I cl." -- [None] only if genuinely unparseable *) + title : string; (** the day-start line's own text before the class marker *) + te_deum : bool option; (** [None] only if neither "Te Deum" nor "non dicitur Te Deum" is found *) + gloria : bool option; + credo : bool option; + praef : string option; (** raw trailing text after "praef." within the primary Mass clause -- CAPTURED, NOT VALIDATED *) +} +[@@deriving sexp] + +(* --- tiny hand-rolled helpers, no Str/regex ------------------------------ *) + +let split_ws s = + String.split_on_char ' ' (String.map (fun c -> if c = '\t' then ' ' else c) s) + |> List.filter (fun t -> t <> "") + +let is_all_digits s = s <> "" && String.for_all (fun c -> c >= '0' && c <= '9') s + +let has_prefix ~prefix s = + String.length s >= String.length prefix && String.sub s 0 (String.length prefix) = prefix + +(* Strips ASCII trailing punctuation only (.,();) -- tokens in this source + never carry other trailing marks that matter to comparisons below. *) +let rec strip_trailing_punct s = + let n = String.length s in + if n = 0 then s + else + match s.[n - 1] with + | '.' | ',' | ')' | ';' | ':' -> strip_trailing_punct (String.sub s 0 (n - 1)) + | _ -> s + +let contains s ~sub = + let ls = String.length s and lu = String.length sub in + if lu = 0 then true + else + let rec go i = if i + lu > ls then false else if String.sub s i lu = sub then true else go (i + 1) in + go 0 + +let index_of s ~sub = + let ls = String.length s and lu = String.length sub in + if lu = 0 then Some 0 + else + let rec go i = if i + lu > ls then None else if String.sub s i lu = sub then Some i else go (i + 1) in + go 0 + +let months = + [| "Januarius"; "Februarius"; "Martius"; "Aprilis"; "Maius"; "Junius"; "Julius"; "Augustus"; "September"; + "October"; "November"; "December" |] + +let month_index name = + let rec go i = if i >= Array.length months then None else if months.(i) = name then Some (i + 1) else go (i + 1) in + go 0 + +(* Roman numerals, subtractive form -- only ever called once, on the + FIRST month header's own year token (the anchor); see the module + header on why every LATER header's own year, when present at all, is + deliberately never read. *) +let roman_value = function + | 'I' -> Some 1 | 'V' -> Some 5 | 'X' -> Some 10 | 'L' -> Some 50 | 'C' -> Some 100 | 'D' -> Some 500 + | 'M' -> Some 1000 | _ -> None + +let parse_roman s = + let n = String.length s in + let rec go i acc = + if i >= n then Some acc + else + match roman_value s.[i] with + | None -> None + | Some v -> ( + let next = if i + 1 < n then roman_value s.[i + 1] else None in + match next with + | Some nv when nv > v -> go (i + 2) (acc + nv - v) + | _ -> go (i + 1) (acc + v)) + in + if n = 0 then None else go 0 0 + +(* --- day-block scanning --------------------------------------------------- *) + +type block = { b_day : int; b_month : int; b_year : int; b_lines : string list } + +let is_day_start_line toks = + match toks with + | t :: _ :: _ when String.length t >= 2 && t.[String.length t - 1] = '.' -> + let core = String.sub t 0 (String.length t - 1) in + if is_all_digits core then + let d = int_of_string core in + if d >= 1 && d <= 31 then Some d else None + else None + | _ -> None + +(* A month running-header/footer line: first token is a recognised month + name (English Nov/Dec spelled identically to Latin), optionally + followed by a Roman-numeral year and/or a page number -- ALWAYS pure + noise for the day-block scanner (never a continuation line's own + content), but the FIRST time a given month index is seen it also + drives the [cur_month]/[cur_year] state transition. *) +let is_month_marker_line toks = match toks with m :: _ -> month_index m <> None | [] -> false + +(* Left-margin indulgence-notation codes ("Ind." = an indulgence is + available, "Plen." = a plenary one, "DFP" unexplained but structurally + identical -- all three print in the SAME left-margin column pdftotext + -layout preserves, glued onto the following content line as literal + leading tokens, the identical trap extract_lms_ordo.ml's own + [strip_left_column] already documents for the LMS PDFs' "Pl"/"Ind" + column. Found by tracing a real parse failure (8 December 2025's own + class marker split across two physical lines by "DFP" sitting between + "I" and "cl."), not assumed in advance: catalogued via a frequency + scan of every short capitalised token opening a continuation line, and + deliberately does NOT include "RM" (11 occurrences, ALSO short and + capitalised) -- checked directly, "RM" is a real citation abbreviation + ("Rubricae Missalis", e.g. "vide RM 440"), not a margin code, so + stripping it would corrupt real text for no parsing benefit. *) +let strip_left_column tokens = + let is_marker t = t = "Ind." || t = "Plen." || t = "DFP" in + let rec go = function t :: rest when is_marker t -> go rest | ts -> ts in + go tokens + +(* The malformed trailing entry's own distinctive two-token prefix, + "1st Jan" -- NOT a generic "first token is a bare 4-digit number" + check (extract_lms_ordo.ml's own approach): that generic shape false- + positived here, on real body content deep in October ("...20 augusti + / 1885, 26 augusti 1886..." -- an indulgence-decree date citation + whose line-wrap happens to put a 4-digit year token first on its own + physical line). This source's OWN tail artefact is reliably + distinguished only by its literal, unique "1st Jan" opening -- found + by tracing the false stop, not assumed in advance. *) +let is_stop_tail_line toks = match toks with "1st" :: "Jan" :: _ -> true | _ -> false + +let read_lines path = + let ic = open_in path in + let rec loop acc = match input_line ic with l -> loop (l :: acc) | exception End_of_file -> List.rev acc in + let ls = loop [] in + close_in ic; + ls + +(* --- per-block field extraction ------------------------------------------- *) + +(* First WHOLE-TOKEN hit of [word] in [tokens] starting at-or-after + [from], REJECTING a hit whose immediately-following token (stripped) + is [reject_next] -- the "Gloria Patri" trap, see the module header. + Returns the hit's own index and whether the token immediately BEFORE + it (stripped) is "sine" (a negation). *) +let find_word tokens ~from ~word ~reject_next = + let n = Array.length tokens in + let rec go i = + if i >= n then None + else if strip_trailing_punct tokens.(i) = word then + let next_is_rejected = i + 1 < n && strip_trailing_punct tokens.(i + 1) = reject_next in + if next_is_rejected then go (i + 1) + else + let negated = i > 0 && strip_trailing_punct tokens.(i - 1) = "sine" in + Some (i, negated) + else go (i + 1) + in + go from + +(* [class_]: the roman-numeral token immediately followed by a token + starting "cl" (covers "cl.", "cl.,"), whole-token matched -- never a + substring search (the same discipline the LMS extractor's own BVM + numeral anchor uses, for the identical reason: "I" is a substring of + "II"/"III"/"IV"). Also detects the trailing "(Priv.)" two tokens later. *) +let extract_class tokens = + let n = Array.length tokens in + let is_class_numeral t = t = "I" || t = "II" || t = "III" || t = "IV" in + let rec go i = + if i + 1 >= n then None + else if is_class_numeral tokens.(i) && has_prefix ~prefix:"cl" tokens.(i + 1) then + let base = tokens.(i) ^ " cl." in + if i + 2 < n && strip_trailing_punct tokens.(i + 2) = "(Priv" then Some (base ^ " (Priv.)") else Some base + else go (i + 1) + in + go 0 + +let extract_title tokens = + let n = Array.length tokens in + let is_class_numeral t = t = "I" || t = "II" || t = "III" || t = "IV" in + let rec find i = if i + 1 >= n then n else if is_class_numeral tokens.(i) && has_prefix ~prefix:"cl" tokens.(i + 1) then i else find (i + 1) in + let stop = find 0 in + String.concat " " (Array.to_list (Array.sub tokens 0 stop)) + +(* Te Deum: bounded to the "Ad Mat." .. "Ad Laudes" span specifically + (both casings occur: "Ad MAT."/"Ad Mat."/"ad Mat.", "Ad LAUDES"/ + "Ad Laudes") -- NOT the whole block, because a day can separately + mention "Te Deum" in an unrelated INDULGENCE note (31 December: "Hodie + ad solemnem recitationem hymni Te Deum, indulgentia plenaria lucrari + potest" -- about gaining an indulgence for the New Year's Eve Te Deum + of thanksgiving, not about whether it is sung at that day's own + Matins) that a whole-block search would wrongly read as a positive hit. *) +let extract_te_deum full_text = + let find_ci needles start = + List.fold_left + (fun acc needle -> + match acc with + | Some _ -> acc + | None -> ( + match index_of (String.sub full_text start (String.length full_text - start)) ~sub:needle with + | Some i -> Some (start + i) + | None -> None)) + None needles + in + match find_ci [ "Ad Mat."; "Ad MAT."; "ad Mat." ] 0 with + | None -> None + | Some mat_start -> ( + let laudes_start = + match find_ci [ "Ad Laudes"; "Ad LAUDES"; "ad Laudes" ] mat_start with + | Some i -> i + | None -> String.length full_text + in + let span = String.sub full_text mat_start (laudes_start - mat_start) in + if contains span ~sub:"non dicitur Te Deum" then Some false + else if contains span ~sub:"Te Deum" then Some true + else None) + +(* Gloria/Credo/praef.: bounded to the FIRST Mass option only -- from the + token "Missa" to whichever comes first: "Vel" immediately followed by + "Missa" (a real second option), or a token starting "VESPER" (Vespers + info -- a PREFIX match, not one or two hardcoded exact spellings, + found necessary by tracing a real over-capture: this source uses at + least four surface forms depending on grammatical case and whether + pdftotext renders the Æ ligature as one glyph or splits it -- + "VESPERÆ", "VESPERAS", "VESPERA" (Ad VESPERA, rare) and "VESPERÆ" + with the ligature reproduced as a single non-ASCII codepoint an exact- + string match against the two ASCII spellings alone could never catch, + which let a whole day's own trailing Vespers/Compline prose leak into + [praef] uncaught until checked against the task brief's own worked + example day, 19 September), or the end of the block. *) +let extract_missa_fields tokens = + let n = Array.length tokens in + (* [Missa] (singular, 549 of the corpus's own occurrences of any "Miss-" + word) anchors 398 of the 400 real days; the two genuine exceptions + are Good Friday and Holy Saturday, which have no Mass at all in the + 1955-restored Holy Week (matching extract_lms_ordo.ml's own + identically-shaped finding for the LMS corpus). CHRISTMAS DAY is a + THIRD, found by tracing a real false-None result: its own rubric + reads "Hodie celebrantur tres Missae pr., Gloria, Credo..." ("today + three Masses are celebrated..."), using the PLURAL "Missae"/"Missæ" + (both spellings occur across the fixture's two Christmas Days) -- + [tokens.(i) = "Missa"] alone never matches it, silently returning + [None] for Gloria/Credo/praef on the single most doctrinally + unambiguous day in the whole calendar. Widened to accept "Missae"/ + "Missæ" too, guarded against the ONE real collision risk: "Hodie + prohibentur omnes Missae defunctorum..." (a Requiem-Mass-prohibition + notice, common at the end of many day-blocks, unrelated to the + day's own Mass) also contains "Missae" -- rejected here by checking + the immediately FOLLOWING token is not "defunctorum". *) + let missa_idx = + let rec go i = + if i >= n then None + else if (tokens.(i) = "Missa" || tokens.(i) = "Missae" || tokens.(i) = "Missæ") + && not (i + 1 < n && strip_trailing_punct tokens.(i + 1) = "defunctorum") + then Some i + else go (i + 1) + in + go 0 + in + match missa_idx with + | None -> (None, None, None) + | Some m -> + let end_idx = + let rec go i = + if i >= n then n + else if tokens.(i) = "Vel" && i + 1 < n && tokens.(i + 1) = "Missa" then i + else if has_prefix ~prefix:"VESPER" tokens.(i) then i + else go (i + 1) + in + go (m + 1) + in + let span = Array.sub tokens m (end_idx - m) in + let gloria = + match find_word span ~from:0 ~word:"Gloria" ~reject_next:"Patri" with + | Some (_, negated) -> Some (not negated) + | None -> None + in + let credo = + match find_word span ~from:0 ~word:"Credo" ~reject_next:"__never__" with + | Some (_, negated) -> Some (not negated) + | None -> None + in + let praef = + let sn = Array.length span in + let rec go i = if i >= sn then None else if strip_trailing_punct span.(i) = "praef" then Some i else go (i + 1) in + match go 0 with + | None -> None + | Some i -> + let rest = Array.to_list (Array.sub span (i + 1) (sn - i - 1)) in + if rest = [] then None else Some (String.concat " " rest) + in + (gloria, credo, praef) + +(* --- top level -------------------------------------------------------------- *) + +let () = + if Array.length Sys.argv <> 4 then + die "usage: extract_fiuv_ordo "; + let txt_path = Sys.argv.(1) in + let pdf_path = Sys.argv.(2) in + let dest = Sys.argv.(3) in + let all_lines = read_lines txt_path in + let arr = Array.of_list all_lines in + let n = Array.length arr in + let trimmed i = String.trim arr.(i) in + (* Anchor: the FIRST month-marker line carrying a parseable Roman year + -- established during characterisation to be line 47, "November + MMXXV". Search generically rather than hardcoding the line number, + so a re-extraction against a re-flowed pdftotext dump still finds it. *) + let anchor_idx, anchor_month, anchor_year = + let rec go i = + if i >= n then die "no month header with a parseable Roman-numeral year found (expected the book's own first header, e.g. \"November MMXXV\")" + else + let toks = split_ws (trimmed i) in + match toks with + | m :: y :: _ -> ( + match (month_index m, parse_roman y) with + | Some mi, Some yr when yr > 1000 -> (i, mi, yr) + | _ -> go (i + 1)) + | _ -> go (i + 1) + in + go 0 + in + let stop_idx = + let rec go i = if i >= n then n else if is_stop_tail_line (split_ws (trimmed i)) then i else go (i + 1) in + go (anchor_idx + 1) + in + Printf.printf "extract_fiuv_ordo: Ordo body lines %d..%d (of %d total), anchor %d/%d\n" anchor_idx stop_idx n + anchor_month anchor_year; + let cur_month = ref anchor_month and cur_year = ref anchor_year in + let blocks = ref [] in + let cur = ref None in + let flush () = match !cur with Some b -> blocks := b :: !blocks; cur := None | None -> () in + for i = anchor_idx + 1 to stop_idx - 1 do + let raw = trimmed i in + if raw = "" then () + else + let toks = split_ws raw in + if is_month_marker_line toks then ( + match toks with + | m :: _ -> ( + match month_index m with + | Some mi -> + if mi <> !cur_month then begin + if mi < !cur_month then incr cur_year; + cur_month := mi + end + | None -> ()) + | [] -> ()) + else + match is_day_start_line toks with + | Some day -> + flush (); + cur := Some { b_day = day; b_month = !cur_month; b_year = !cur_year; b_lines = toks } + | None -> ( + match !cur with + | None -> () + | Some b -> cur := Some { b with b_lines = b.b_lines @ strip_left_column toks }) + done; + flush (); + let blocks = List.rev !blocks in + Printf.printf "extract_fiuv_ordo: %d day-blocks parsed\n" (List.length blocks); + let rows = + List.map + (fun b -> + let date = + match Date.make ~year:b.b_year ~month:b.b_month ~day:b.b_day with + | Ok d -> d + | Error e -> die "%d/%d/%d: %s" b.b_year b.b_month b.b_day e + in + let tokens = Array.of_list b.b_lines in + (* [b_lines] tokens 0 is the day's own leading "." marker -- + dropped before field extraction, kept for nothing (the day + number is already known from [b_day]). *) + let content = if Array.length tokens > 0 then Array.sub tokens 1 (Array.length tokens - 1) else tokens in + let class_ = extract_class content in + let title = extract_title content in + let full_text = String.concat " " (Array.to_list content) in + let te_deum = extract_te_deum full_text in + let gloria, credo, praef = extract_missa_fields content in + { date = Date.to_iso8601 date; class_; title; te_deum; gloria; credo; praef }) + blocks + in + let missing_class = List.filter (fun r -> r.class_ = None) rows in + let missing_gloria = List.filter (fun r -> r.gloria = None) rows in + let missing_credo = List.filter (fun r -> r.credo = None) rows in + let missing_te_deum = List.filter (fun r -> r.te_deum = None) rows in + if missing_class <> [] then + Printf.printf "extract_fiuv_ordo: WARNING %d rows with no class found: %s\n" (List.length missing_class) + (String.concat ", " (List.map (fun r -> r.date) missing_class)); + Printf.printf + "extract_fiuv_ordo: %d rows; %d with no Gloria found; %d with no Credo found; %d with no Te Deum found\n" + (List.length rows) (List.length missing_gloria) (List.length missing_credo) (List.length missing_te_deum); + (* CHARACTERISATION, Step C of the task brief, non-negotiable: probed + BEFORE trusting a single row of this fixture, and RE-VERIFIED here + against this run's own [rows] -- a failed probe is a hard [die], the + same self-verifying discipline extract_lms_ordo.ml already uses, + never a printed claim resting on a one-off manual check that could + silently rot on a re-extraction. Every date/expectation pair below + was confirmed directly against the raw pdftotext dump before being + encoded here. *) + let creed_of_date d = List.find_map (fun r -> if String.equal r.date d then r.credo else None) rows in + let probes = + [ ("2025-11-30", true, "Advent Sunday, I class, RG 475(a)"); + ("2025-12-01", false, "ordinary Advent feria, III class, RG 476(b)/(d)"); + ("2025-12-26", true, "St Stephen, II class, inside the Nativity octave, RG 475(d)"); + ("2026-08-10", false, "St Laurence, II class martyr, no Lord/BVM/apostle clause applies, RG 476(b)"); + ("2026-08-15", true, "the Assumption, I class, RG 475(b)") ] + in + List.iter + (fun (d, expected, desc) -> + match creed_of_date d with + | Some got when Bool.equal got expected -> () + | Some got -> die "characterisation probe FAILED: %s (%s) -- expected creed=%b, extracted creed=%b" d desc expected got + | None -> die "characterisation probe FAILED: %s (%s) -- no row extracted for this date at all" d desc) + probes; + Printf.printf "extract_fiuv_ordo: all %d characterisation probes confirmed\n" (List.length probes); + let probe_lines = + String.concat "\n" + (List.map + (fun (d, expected, desc) -> Printf.sprintf "; %s (%s) -> %s" d desc (if expected then "TRUE" else "FALSE")) + probes) + in + let sha256_of_file path = + let cmd = Printf.sprintf "sha256sum %s" (Filename.quote path) in + let ic = Unix.open_process_in cmd in + let line = try input_line ic with End_of_file -> die "sha256sum produced no output for %s" path in + (match Unix.close_process_in ic with Unix.WEXITED 0 -> () | _ -> die "sha256sum failed for %s" path); + match String.index_opt line ' ' with Some i -> String.sub line 0 i | None -> die "unexpected sha256sum output: %S" line + in + let today () = + let tm = Unix.gmtime (Unix.time ()) in + Printf.sprintf "%04d-%02d-%02d" (tm.Unix.tm_year + 1900) (tm.Unix.tm_mon + 1) tm.Unix.tm_mday + in + let pdf_sha = sha256_of_file pdf_path in + let pdf_base = Filename.basename pdf_path in + let gloria_true = List.length (List.filter (fun r -> r.gloria = Some true) rows) in + let gloria_false = List.length (List.filter (fun r -> r.gloria = Some false) rows) in + let credo_true = List.length (List.filter (fun r -> r.credo = Some true) rows) in + let credo_false = List.length (List.filter (fun r -> r.credo = Some false) rows) in + let te_deum_true = List.length (List.filter (fun r -> r.te_deum = Some true) rows) in + let te_deum_false = List.length (List.filter (fun r -> r.te_deum = Some false) rows) in + let header = + Printf.sprintf + {|; %s -- Witnesses task (2026-08-22-colitur- +; celebrant-rubrics-phase1)'s SEVENTH validation layer, and the first +; UNIVERSAL (non-diocesan), SECOND-COMPILER witness: the FIUV (Foederatio +; Internationalis Una Voce) Ordo, compiled independently of the Latin Mass +; Society's own three editions (test/test_lms_ordo.ml) -- see +; docs/research/ordo/PROVENANCE-ordo-corpus.md for the full four-reasons +; account of why this source is the more valuable of the two newly- +; acquired ones. +; +; Generator: tools/extract_fiuv_ordo.ml -- do not hand-edit; re-run +; against a fresh pdftotext dump and commit the diff instead. +; +; Source: "Ordo Divini Officii recitandi sacrique peragendi secundum +; antiquam Ritus Romani formam pro anno Domini 2026", Foederatio +; Internationalis Una Voce, compiled by Joseph Shaw (Praefatio signed +; "Joseph Shaw, President", Feast of the Nativity of Our Lady [8 Sept] +; 2025) -- title page and Praefatio, verified directly against the PDF's +; own extracted text. 2025 is stated as the Federation's own 60th +; anniversary year. +; PDF metadata: Creator "TeX", Producer "pdfTeX-1.40.22", CreationDate +; 2025-11-08, 128 pages. +; URL: identified via web search as +; https://lms.org.uk/sites/default/files/u5374/fiuv_ordo_2025-2026_1.1_a5_format.pdf +; (hosted by the Latin Mass Society's own site alongside its own three +; editions -- Joseph Shaw is both FIUV President and LMS Chairman, which +; plausibly also explains why this PDF's own trailing malformed entry +; (see COVERAGE below) is structurally identical to the LMS PDFs' own, +; despite the two being compiled by different people); NOT independently +; re-downloaded and byte-compared in this session -- recorded honestly +; rather than presented as verified, the same discipline the LMS +; fixtures' own headers use. +; The local PDF (docs/research/ordo/%s) is gitignored (CLAUDE.md: "docs/ +; is gitignored"), so this header, not git, is this fixture's only record +; of where it came from. +; SHA-256 of docs/research/ordo/%s: %s +; Extracted (UTC): %s +; Exact commands: +; pdftotext -layout docs/research/ordo/%s /tmp/fiuv.txt +; dune exec tools/extract_fiuv_ordo.exe -- /tmp/fiuv.txt \ +; docs/research/ordo/%s %s +; +; COVERAGE: %d day-rows, %s through %s. Starts at the book's own first +; real content line ("November MMXXV", the FIRST month header found with +; a parseable Roman-numeral year -- used as this parser's sole date +; anchor, see the tool's own header on why no LATER header's year is ever +; read, the second one being a publisher typo, "December MMXV" for 2025). +; Stops before a malformed trailing entry, structurally the SAME artefact +; found in all three LMS editions (a stray, mislabelled duplicate of the +; fixture's own already-extracted 1 January row, headed "1st Jan / 2025." +; -- see extract_lms_ordo.ml's own COVERAGE section for the fuller +; account of this shared publisher-side quirk). +; +; CHARACTERISATION FINDINGS (non-negotiable per the task brief -- the +; extraordinaryform.org Ordo silently omitted St Lawrence's vigil on +; EVERY date it covered, which nearly produced a false corroboration +; during the RG 33 work; this Ordo was probed with the same discipline +; before a single divergence was adjudicated): +; +; 1. UNIVERSAL, not diocesan: unlike the three LMS editions (which had to +; exclude diocesan variants from every comparison, quantified in each +; of their own fixture headers), this Ordo carries ONE block per day, +; always. There is no [has_diocesan_variant] field in this fixture's +; own [row] at all -- there is nothing to exclude. +; +; 2. OPPOSITE-PREDICTION PROBES against Rite_ef.Rubrics_ef.creed (RG +; 475-476), RE-CHECKED BY THIS TOOL RUN against its own extracted +; [rows] before this header was even written -- a failed probe is a +; hard [die], never a printed claim: +%s +; All %d predictions confirmed, both directions -- this source is +; discriminating, not a constant, on the Creed. +; +; 3. THE SUBSTRING TRAP this parser defends against, found live in this +; corpus: "Gloria" is also the first word of "Gloria Patri" (the psalm +; doxology), which can appear INSIDE the very Mass clause being +; scanned (Good Friday, 3 April 2026: "Missa pr., (omittuntur ps. +; Iudica me et Gloria Patri), Gloria, sine Credo, praef. comm." -- the +; real, standalone Gloria mention follows immediately after). See +; [find_word]'s own citation. +; +; 4. RAW SUBSTRING COUNTS measured against this session's own pdftotext +; dump, for comparison against the task brief's own figures (328 +; Gloria / 132 sine Gloria / 119 Credo / 260 sine Credo, 262 Te Deum): +; "sine Gloria" 132 (EXACT match), "sine Credo" 260 (EXACT match), raw +; "Te Deum" substring 262 (EXACT match, includes negated occurrences +; as substring hits -- 42 of them are "non dicitur Te Deum"). Raw +; "Gloria"/"Credo" substring totals (494/411) do NOT match the brief's +; implied positive totals (328/119) even after subtracting the 25 +; "Gloria Patri" occurrences (469, still 9 over) -- not chased further +; here; this extractor's own token-scoped, Missa-clause-bounded counts +; below are what this fixture actually asserts, not a forced match to +; the brief's approximate figures. +; +; MEASURED DISTRIBUTION (this extraction, not the brief's figures): Gloria +; true=%d false=%d unresolved=%d; Credo true=%d false=%d unresolved=%d; +; Te Deum true=%d false=%d unresolved=%d. +|} + dest pdf_base pdf_base pdf_sha (today ()) pdf_base pdf_base dest (List.length rows) + (match rows with r :: _ -> r.date | [] -> "?") + (match List.rev rows with r :: _ -> r.date | [] -> "?") + probe_lines (List.length probes) gloria_true gloria_false (List.length missing_gloria) credo_true credo_false + (List.length missing_credo) te_deum_true te_deum_false (List.length missing_te_deum) + in + let body = Sexplib.Sexp.to_string_hum ~indent:2 (sexp_of_list sexp_of_row rows) in + let oc = open_out dest in + Fun.protect + ~finally:(fun () -> close_out_noerr oc) + (fun () -> + output_string oc header; + output_string oc body; + output_string oc "\n"); + Printf.printf "extract_fiuv_ordo: wrote %d rows to %s\n" (List.length rows) dest -- cgit v1.3 From 219c0ca6884a634e83293c62b27cca990fa25854 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Sat, 22 Aug 2026 15:19:25 +0200 Subject: docs(L3): the bissextile rubric is scan-verified after all L3 recorded that the leap-year shift rested on the LT.txt transcription alone, the scans having been searched without result. It is in scan2.txt at 3050-3058, OCR-damaged but unmistakable. The earlier search missed it for a findable reason, now written into the entry: the OCR mangles the saint and the keyword alike -- "Matthue", "Cabrielis", "bi&sextili" -- so neither "Matth" nor "bissext" matches. It turns up on the undamaged phrase "februarius est dierum". Transcription and scan now agree, which makes this two witnesses of one document rather than one. Still one document; the citation continues to say calendarium rather than RG, because a calendarium footnote is what it is. --- data/ef/expected-divergences-lms.sexp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'data/ef') diff --git a/data/ef/expected-divergences-lms.sexp b/data/ef/expected-divergences-lms.sexp index 3850fd5..d67e291 100644 --- a/data/ef/expected-divergences-lms.sexp +++ b/data/ef/expected-divergences-lms.sexp @@ -129,7 +129,7 @@ ; L3 -- OPEN, colitur's OWN genuine gap, found extending this suite to the ; 2023-2024 window (Witnesses task, 2026-08-22). Fired once: 2024-02-24. ((id L3) - (citation "The Missale Romanum's own CALENDARIUM table, February, footnote (docs/research/LT.txt:5011-5013, the Missal's printed calendar pages, not the numbered Rubricae Generales chapters): \"In anno bissextili mensis februarius est dierum 29, et festum S. Matthiae celebratur die 25 februarii, ac festum S. Gabrielis a Virgine perdolente 28 februarii, et bis dicitur sexto calendas, id est die 24 et die 25\" -- in a leap year February has 29 days, and the feast of St Matthias is kept on 25 February (not 24), with 24 and 25 February BOTH called \"the 6th kalends\"; St Gabriel of Our Lady of Sorrows (ordinarily 27 February) shifts to 28 February by the same rule. This bissextile shift is not RG-numbered (it is a calendarium footnote, not a Rubricae Generales paragraph) and is NOT scan-verified in this session -- only the LT.txt transcription was checked; scan1.txt/scan2.txt were searched for \"bissext\"/\"Matth\" and turned up only the unrelated Golden-Number/dominical-letter passage, not this specific calendarium footnote, so this citation rests on the transcription alone.") + (citation "The Missale Romanum's own CALENDARIUM table, February, footnote (docs/research/LT.txt:5011-5013, the Missal's printed calendar pages, not the numbered Rubricae Generales chapters): \"In anno bissextili mensis februarius est dierum 29, et festum S. Matthiae celebratur die 25 februarii, ac festum S. Gabrielis a Virgine perdolente 28 februarii, et bis dicitur sexto calendas, id est die 24 et die 25\" -- in a leap year February has 29 days, and the feast of St Matthias is kept on 25 February (not 24), with 24 and 25 February BOTH called \"the 6th kalends\"; St Gabriel of Our Lady of Sorrows (ordinarily 27 February) shifts to 28 February by the same rule. This bissextile shift is not RG-numbered -- it is a calendarium footnote, not a Rubricae Generales paragraph. SCAN-VERIFIED 2026-08-22 (coordinator), upgrading this entry's own earlier caveat that it rested on the transcription alone: the footnote IS present in the photographic scan at docs/research/scan2.txt:3050-3058, OCR-damaged but unmistakable -- \"In anno bi&sextili mensis februarius est dierum 29^ et festum S. Matthue celebra-tur die 2S februarii, ac festum S. Cabrielis a Virgine Perdolente die 28 februarii, et bis dicitur Sexto Kalen-\". The earlier search missed it because the OCR mangles both the saint (\"Matthue\", \"Cabrielis\") and the keyword (\"bi&sextili\"), so neither \"Matth\" nor \"bissext\" matches; it was found by searching for the undamaged phrase \"februarius est dierum\" instead. Transcription and scan agree, so the rule now rests on two witnesses of the SAME document rather than one -- still one document, which is why the citation says calendarium and not RG.") (verdict ordo) (note "colitur has NO bissextile-shift rule anywhere (grepped lib/rites/rite_ef/*.ml and data/ef/*.sexp for \"bissext\"/\"leap\": zero hits outside a code comment naming the saint, and the rules-register.md itself is silent on it too) -- St Matthias stays fixed at 24 February every year, leap or not. 2024 is a leap year: colitur's own [matthias] entry (Class2, an Apostle, RG91 entry 16 -- verified from the table itself to genuinely OUTRANK entry 18's privileged Ember-Saturday-of-Lent feria, so colitur's RANKING logic is not at fault here) WINS 24 February 2024 outright in colitur's output, correctly saying the Creed per RG475(e)'s Apostle clause. The Ordo shows no St Matthias anywhere near this date at all: 24 February 2024 is titled plainly \"EMBER SATURDAY of LENT\" (No Cr) and 25 February 2024 (a Sunday, 2nd Sunday in Lent, I class) is titled plainly \"2nd SUNDAY in LENT\" (Cr, but via RG475(a)'s own Sunday clause, not RG475(e)) -- consistent with Matthias having correctly MOVED to the 25th and then lost outright to the I-class Sunday there (RG91 entry 6 over entry 16), never even surviving as a commemoration (an I-class Sunday's own admission cap, RG111, is tight enough to exclude an ordinary II-class saint entirely -- the same shape already established for RG16(a)-adjacent cases elsewhere in this project). Both the 24th and 25th sides of the Ordo's silence are explained by ONE root cause (the missing shift), not two independent gaps -- a coherent, single-cause account, not a coincidence. BLAST RADIUS, roughly measured (a throwaway domain sweep, tools/probe_matthias.ml, run once for this task and not committed): of 2 041 leap years in 1583-9999, colitur observes [matthias] on 24 February in 1 650 of them -- an UPPER BOUND on how many years this gap could affect (some of those 1 650 years may see IDENTICAL final output either way, e.g. if Matthias would also win on the 25th against whatever competes there that year; a precise count needs the shift actually implemented, which is out of this task's own no-lib-changes scope). The Gabriel/27-28 February sibling shift is not witnessed by this fixture at all (no divergence on either date in this window) but is the same root cause and would need the same fix.") (expected_rows 1)) -- cgit v1.3 From 60e87914718dd2c8e69bb89d8cc48d6bef9bfc74 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Sat, 22 Aug 2026 16:40:07 +0200 Subject: feat(ef): implement the calendarium's bissextile February shift The Missale Romanum's calendarium footnote for February (LT.txt:5011-5014, scan-corroborated scan2.txt:3050-3058): in a leap year the sixth kalends of March (24 February) is doubled rather than a 29th day appended, so St Matthias moves 24->25 February and St Gabriel of Our Lady of Sorrows 27->28, with 24 February itself carrying no fixed office that year. data/ef/expected-divergences-lms.sexp entry L3 tracked this as an open gap. Implemented as the rubric's own general mechanism (every fixed entry from 24 through 28 February shifts one civil day later in a leap year), not as "move these two named saints": the two readings are indistinguishable on shipped data (nothing else is fixed in that window) and diverge only for a future --overlay entry in the same range, which the mechanism reading covers correctly and a two-saints special case would not. This project has already been bitten once (RG 16(a)) by a rule implemented against shipped data's coincidental shape rather than the rubric itself. Kernel stays rite-agnostic: Rite.t gains a fixed_key field (Date.t -> (int * int) option), the same seam easter already establishes, read only by Layer.on_date's FIXED half -- the movable half (Easter_offset/Nth_weekday) is untouched. Default is the identity mapping, an optional argument on on_date, so every existing caller and every rite that supplies nothing is byte-identical to before this field existed. Date.is_leap is exposed in date.mli (already existed in date.ml) so the rite reads the kernel's own single-sourced leap-year definition. The EF implementation lives in Rite_ef.Temporal_ef.bissextile_fixed_key, fully cited, wired into Rite_ef.context. Blast radius, measured over the full 1583-9999 domain (Calendar.year run twice per civil year, real fixed_key vs identity, every day diffed): all 2,041 leap years in the domain show a visible change for each saint; 6,983 individual liturgical days change total, zero unclassified, across four shapes (Matthias vacates 24 Feb in 1,803 years / occupies 25 Feb in 1,811; Gabriel vacates 27 Feb in 1,699 / occupies 28 Feb in 1,670). L3's own prior estimate (1,650 years, observed-outright only) is confirmed close on the same definition (1,677 measured); the broader observed-or- commemorated count is higher, not lower, showing the narrow estimate undercounted visible impact rather than overcounting it. The lectio differential (2005-2050 fixture) gains a new cited entry, C40 in data/ef/expected-divergences.sexp: lectio implements no such shift, so every leap year in its window now diverges on the two shifted days (21 rows, not the naive 44 -- the comparator never compares commemorations, so a side where the shifted saint has zero comparator-visible footprint on both engines produces no row). The LMS Ordo's 2023-2024 fixture -- the window L3 was originally found in -- now matches on the Creed comparison; its formulary-override bucket count is corrected 182->181 (24 February leaves the counted Proper population, becoming Own_slug-sourced). The missalemeum oracle fixtures (2026-2027, 2038, 2035) cover no leap year and are unaffected. L3 is closed: converted from an active allow-list record to a prose closure paragraph (L1's own precedent), citation preserved verbatim, fix and measured blast radius recorded. The id-list assertion narrows to [L4] alone, and the now-dead "2024-02-24" -> "L3" date mapping is removed. Six golden values pinned across four new test cases: Matthias in a leap year (both the vacated and occupied sides) and a common-year control; Gabriel likewise, deliberately choosing a leap year where he is admitted only as an ordinary commemoration rather than winning outright, a different shape from Matthias's. Mutation-tested: forcing fixed_key back to identity reddens exactly five test cases -- the differential's Layer C count-pin (C40 drops to 0 actual vs 21 expected), the LMS Ordo's Creed and formulary-bucket checks, and both new golden pins -- confirming the tests actually exercise the fix. Reverted; dune test, the exhaustive sweep, and make check are all green. --- data/ef/expected-divergences-lms.sexp | 100 +++++++++++++++++++++++++++++++--- data/ef/expected-divergences.sexp | 15 +++++ lib/kernel/calendar.ml | 7 ++- lib/kernel/date.mli | 7 +++ lib/kernel/layer.ml | 8 ++- lib/kernel/layer.mli | 13 ++++- lib/kernel/rite.ml | 1 + lib/kernel/rite.mli | 27 +++++++++ lib/kernel/validate.ml | 2 +- lib/rites/rite_ef/rite_ef.ml | 4 ++ lib/rites/rite_ef/temporal_ef.ml | 62 +++++++++++++++++++++ lib/rites/rite_ef/temporal_ef.mli | 11 ++++ test/test_calendar.ml | 3 + test/test_differential.ml | 32 +++++++++++ test/test_golden.ml | 71 +++++++++++++++++++++++- test/test_lms_ordo.ml | 36 ++++++++---- test/test_validate.ml | 3 + 17 files changed, 375 insertions(+), 27 deletions(-) (limited to 'data/ef') diff --git a/data/ef/expected-divergences-lms.sexp b/data/ef/expected-divergences-lms.sexp index d67e291..4cb5d2a 100644 --- a/data/ef/expected-divergences-lms.sexp +++ b/data/ef/expected-divergences-lms.sexp @@ -126,13 +126,99 @@ ; per-year count is now known to vary (1-3 in the three years measured), ; not a flat "3 days/year". -; L3 -- OPEN, colitur's OWN genuine gap, found extending this suite to the -; 2023-2024 window (Witnesses task, 2026-08-22). Fired once: 2024-02-24. -((id L3) - (citation "The Missale Romanum's own CALENDARIUM table, February, footnote (docs/research/LT.txt:5011-5013, the Missal's printed calendar pages, not the numbered Rubricae Generales chapters): \"In anno bissextili mensis februarius est dierum 29, et festum S. Matthiae celebratur die 25 februarii, ac festum S. Gabrielis a Virgine perdolente 28 februarii, et bis dicitur sexto calendas, id est die 24 et die 25\" -- in a leap year February has 29 days, and the feast of St Matthias is kept on 25 February (not 24), with 24 and 25 February BOTH called \"the 6th kalends\"; St Gabriel of Our Lady of Sorrows (ordinarily 27 February) shifts to 28 February by the same rule. This bissextile shift is not RG-numbered -- it is a calendarium footnote, not a Rubricae Generales paragraph. SCAN-VERIFIED 2026-08-22 (coordinator), upgrading this entry's own earlier caveat that it rested on the transcription alone: the footnote IS present in the photographic scan at docs/research/scan2.txt:3050-3058, OCR-damaged but unmistakable -- \"In anno bi&sextili mensis februarius est dierum 29^ et festum S. Matthue celebra-tur die 2S februarii, ac festum S. Cabrielis a Virgine Perdolente die 28 februarii, et bis dicitur Sexto Kalen-\". The earlier search missed it because the OCR mangles both the saint (\"Matthue\", \"Cabrielis\") and the keyword (\"bi&sextili\"), so neither \"Matth\" nor \"bissext\" matches; it was found by searching for the undamaged phrase \"februarius est dierum\" instead. Transcription and scan agree, so the rule now rests on two witnesses of the SAME document rather than one -- still one document, which is why the citation says calendarium and not RG.") - (verdict ordo) - (note "colitur has NO bissextile-shift rule anywhere (grepped lib/rites/rite_ef/*.ml and data/ef/*.sexp for \"bissext\"/\"leap\": zero hits outside a code comment naming the saint, and the rules-register.md itself is silent on it too) -- St Matthias stays fixed at 24 February every year, leap or not. 2024 is a leap year: colitur's own [matthias] entry (Class2, an Apostle, RG91 entry 16 -- verified from the table itself to genuinely OUTRANK entry 18's privileged Ember-Saturday-of-Lent feria, so colitur's RANKING logic is not at fault here) WINS 24 February 2024 outright in colitur's output, correctly saying the Creed per RG475(e)'s Apostle clause. The Ordo shows no St Matthias anywhere near this date at all: 24 February 2024 is titled plainly \"EMBER SATURDAY of LENT\" (No Cr) and 25 February 2024 (a Sunday, 2nd Sunday in Lent, I class) is titled plainly \"2nd SUNDAY in LENT\" (Cr, but via RG475(a)'s own Sunday clause, not RG475(e)) -- consistent with Matthias having correctly MOVED to the 25th and then lost outright to the I-class Sunday there (RG91 entry 6 over entry 16), never even surviving as a commemoration (an I-class Sunday's own admission cap, RG111, is tight enough to exclude an ordinary II-class saint entirely -- the same shape already established for RG16(a)-adjacent cases elsewhere in this project). Both the 24th and 25th sides of the Ordo's silence are explained by ONE root cause (the missing shift), not two independent gaps -- a coherent, single-cause account, not a coincidence. BLAST RADIUS, roughly measured (a throwaway domain sweep, tools/probe_matthias.ml, run once for this task and not committed): of 2 041 leap years in 1583-9999, colitur observes [matthias] on 24 February in 1 650 of them -- an UPPER BOUND on how many years this gap could affect (some of those 1 650 years may see IDENTICAL final output either way, e.g. if Matthias would also win on the 25th against whatever competes there that year; a precise count needs the shift actually implemented, which is out of this task's own no-lib-changes scope). The Gabriel/27-28 February sibling shift is not witnessed by this fixture at all (no divergence on either date in this window) but is the same root cause and would need the same fix.") - (expected_rows 1)) +; L3 -- CLOSED, FIXED (bissextile-shift task, 2026-08-22; NOT an active +; sexp record any more, same convention L1 above established -- removed +; from [test_allow_list_ids_are_exactly_l3_l4]'s own expected set, which +; now names L4 alone). Was OPEN, colitur's OWN genuine gap, found +; extending this suite to the 2023-2024 window (Witnesses task, +; 2026-08-22), firing once: 2024-02-24. +; +; Citation, preserved verbatim: the Missale Romanum's own CALENDARIUM +; table, February, footnote (docs/research/LT.txt:5011-5013, scan- +; corroborated docs/research/scan2.txt:3050-3058, OCR-damaged to +; "bi&sextili"/"Matthue"/"Cabrielis" but unmistakable against the +; undamaged transcription): "In anno bissextili mensis februarius est +; dierum 29, et festum S. Matthiae celebratur die 25 februarii, ac festum +; S. Gabrielis a Virgine perdolente 28 februarii, et bis dicitur sexto +; calendas, id est die 24 et die 25" -- in a leap year February has 29 +; days, St Matthias is kept on 25 February (not 24), St Gabriel of Our +; Lady of Sorrows on 28 February (not 27), and the sixth kalends of March +; is said twice. Not RG-numbered -- a calendarium footnote, not a +; Rubricae Generales paragraph. +; +; FIXED: {!Rite_ef.Temporal_ef.bissextile_fixed_key}, threaded through +; {!Colitur_kernel.Rite.t}'s new [fixed_key] field (read only by +; {!Colitur_kernel.Layer.on_date}'s FIXED half, so the kernel stays +; rite-agnostic -- a rite that supplies nothing behaves exactly as +; before). Implemented as the rubric's own MECHANISM (every fixed entry +; from 24 through 28 February shifts one civil day later in a leap year, +; 24 February itself carrying no fixed entry that year), not as "move +; these two named saints": the two are indistinguishable on shipped data +; (nothing else is fixed in that window) and diverge only for a future +; [--overlay] entry in the same range, which the mechanism reading covers +; and a two-saints special case would not. +; +; 2024-02-24/25 now MATCH the Ordo: colitur's Creed follows the same +; Matthias-vacates-24/loses-outright-on-the-Sunday-25th path the note +; below already inferred from the Ordo's own titles, and the LMS +; 2023-2024 suite's Creed and formulary-override checks are both green +; (the formulary bucket's own [expected_proper] constant dropped 182->181 +; for this window: 24 February is now the Ember Saturday's own Own_slug- +; sourced proper, not Matthias's Proper-sourced one, leaving the counted +; population rather than changing which slug's proper it is). +; +; BLAST RADIUS, MEASURED (full 1583-9999 sweep, {!Colitur_kernel.Calendar. +; year} run twice per civil year -- once with the real [fixed_key], once +; with it forced to the identity default -- every changed liturgical day +; diffed on observed slug/rank/colour/subject/commemorations; throwaway +; probe, tools/probe_bissextile.ml, run for this task and not committed, +; same precedent as tools/probe_matthias.ml above): +; +; - ALL 2 041 leap years in the domain show at least one visible +; Matthias-related change, and separately all 2 041 show at least one +; Gabriel-related change -- every leap year in 1583-9999 is touched. +; - 6 983 individual liturgical days change domain-wide, ZERO +; unclassified: exactly four shapes, all the same mechanism -- +; Matthias vacates 24 February (1 803 years) and newly appears on 25 +; February (1 811 years); Gabriel vacates 27 February (1 699 years) +; and newly appears on 28 February (1 670 years). "Vacates"/"appears" +; covers BOTH observed-outright and commemorated-only presence, not +; observed alone -- RG 111's admission cap can relegate the shifted +; saint to a bare commemoration rather than the day's own office, and +; a classifier that only watched [observed] undercounted by roughly a +; tenth on a first pass (found and corrected before this note was +; written: the OBSERVED-outright figures alone, tracked separately +; for direct comparison against this entry's own prior estimate +; below, are 1 677 for Matthias and 571 for Gabriel). +; - THIS ENTRY'S OWN PRIOR ESTIMATE, checked: "of 2 041 leap years, +; colitur observes matthias on 24 February in 1 650 of them" is +; confirmed close but not exact against the real, precisely-measured +; figure on the SAME (observed-outright-only) definition -- 1 677, a +; 2% difference consistent with the prior probe's own "roughly +; measured" caveat, not a sign either probe was wrong in kind. The +; prior estimate's own further caveat -- "some of those years may see +; identical final output either way" -- is also confirmed real but +; small: 1 677 (narrow, observed-only) vs 1 803 (broad, observed-or- +; commemorated) for the SAME 24-February-vacated population shows the +; narrow definition undercounts genuine visible impact rather than +; overcounting it, because a saint who only lost outright pre-fix +; (never observed, never commemorated, invisible either way) is +; absent from BOTH counts and was never the source of the gap between +; them. +; - Gabriel's own sibling shift, unwitnessed by this fixture's own +; 2023-2024 window (no divergence fired on either 27 or 28 February +; 2024 -- 2024's own competing office there does not expose it), is +; the identical mechanism and closes with the same fix; its own +; measured figures are recorded above for the first time, this entry +; having previously had no estimate for it at all. +; +; The differential (lectio, layer 3) gained a new cited entry for its own +; 2005-2050 window, data/ef/expected-divergences.sexp's C40 -- lectio +; implements no such shift either (confirmed directly against the +; fixture: Matthias/Gabriel sit at their PRE-shift dates in every one of +; the 11 leap years that window covers), so every leap year in it now +; diverges on the two shifted days, 21 rows total. See C40's own note for +; the row-by-row account. ; L4 -- OPEN, adjudicated FOR colitur (a defensible primary-source reading, ; not a fix confirmed against the Ordo -- the Ordo's own contrary reading is diff --git a/data/ef/expected-divergences.sexp b/data/ef/expected-divergences.sexp index 19ff2ef..632854c 100644 --- a/data/ef/expected-divergences.sexp +++ b/data/ef/expected-divergences.sexp @@ -116,6 +116,21 @@ WHAT THIS ENTRY ALSO RESTS ON. Two things, neither of them a day-level witness. Gated on lectio's own slug being one of the three vigils this clause can reach and colitur's not being a vigil -- identity on both sides, not a diff-set shape. The Assumption's and the Ascension's vigils are absent from that list because their I-class feasts always keep their own day: 0 occurrences across the whole domain, measured rather than assumed.") (expected_rows 10)) + ((id C40) + (citation "The Missale Romanum's own CALENDARIUM table, February, footnote (docs/research/LT.txt:5011-5014, scan-corroborated docs/research/scan2.txt:3050-3058): \"In anno bissextili mensis februarius est dierum 29, et festum S. Matthiae celebratur die 25 februarii, ac festum S. Gabrielis a Virgine perdolente 28 februarii, et bis dicitur sexto calendas, id est die 24 et die 25\" -- in a leap year February has 29 days, St Matthias is kept on 25 February (not 24), St Gabriel of Our Lady of Sorrows on 28 February (not 27), and the sixth kalends of March is said twice. Implemented in Rite_ef.Temporal_ef.bissextile_fixed_key, threaded through Colitur_kernel.Rite.t's new [fixed_key] field (bissextile-shift task, 2026-08-22). Not RG-numbered -- a calendarium footnote, not a Rubricae Generales paragraph.") + (verdict colitur) + (note "lectio builds no such shift at all: checked directly against the fixture, Matthias sits at 24 February and Gabriel of Our Lady of Sorrows at 27 February in EVERY ONE of the 11 leap years the 2005-2050 window covers (2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036, 2040, 2044, 2048), never moved. colitur now moves both, per the calendarium's own footnote, so every leap year in this window diverges on the two shifted civil days: colitur vacates 24/27 February (the saint moves away) and occupies 25/28 February instead (the saint newly appears there), while lectio keeps the pre-shift assignment throughout. + +19 Matthias rows + 2 Gabriel rows = 21, not the naive 11-years x 2-sides x 2-feasts = 44 ceiling: this comparator, BY DESIGN (see this file's own header), never compares commemorations -- only observed slug/rank/colour/citations -- so a side where the shifted saint has ZERO comparator-visible footprint, on both engines, whether pre- or post-shift, produces no row even though a real change happened underneath (the full-domain probe below, which DOES track commemorations, still counts it). + +MATTHIAS fires on both sides (24 vacated AND 25 occupied) in 8 of the 11 years; in the remaining 3 (2008, 2024, 2036) exactly one side is missing, and in every one of the three the missing side is a SUNDAY -- 2008-02-24 and 2036-02-24 (Matthias already loses outright to that Sunday whichever engine or shift-state is asked, so the vacated side shows no change); 2024-02-25 (the occupied side: colitur's post-shift Matthias loses outright to the 2nd Sunday of Lent, I class, with no commemoration surviving RG111's own tight cap -- Matthias's footprint there is genuinely zero, not merely uncompared). A Sunday's own observed slug is unaffected by this shift either way, so whichever side coincides with one contributes nothing comparator-visible; only the other, non-Sunday side shows the real new divergence. 2024-02-24 is L3's own original date (data/ef/expected-divergences-lms.sexp), now confirmed independently by a second, larger fixture. + +GABRIEL (Class3, weaker than Matthias's Class2/Apostle rank) fires in only 2 of the 11 years (2028 occupied, 2044 vacated) because in the other 9 his position is already dominated by a Class3-or-stronger competing office both before and after the shift, so his own presence is commemoration-only throughout -- invisible to this comparator on either side. He surfaces only where the position happens to be a plain, unprivileged Class4 feria weak enough for his own Class3 to win outright: 2028-02-28 (colitur: gabriel-of-our-lady-of-sorrows, Class3, White, beating ef-septuagesima-3-monday, Class4) and 2044-02-27 (lectio still shows gabriel there unmoved, Class3, White; colitur's post-shift 27th falls to RG78's own votive BVM-Saturday office instead, also White, hence the colour match but slug/rank/citation mismatch in that row). Every one of the 21 rows was read directly off the comparator's own failure output, not apportioned by hand. + +Diff shapes: most rows carry [Slug_f; Rank; Colour_f; First_f; Gospel_f] (the temporal office on one side and the saint's own Class2/3 proper on the other differ in rank too); a handful carry only [Slug_f; Colour_f; First_f; Gospel_f] where the competing temporal office happens to share Matthias's own Class2 (the privileged Lenten Ember Friday/Saturday, 2024 and 2040) or Gabriel's own White (a BVM Saturday, 2044-02-27's own vacated row). Season never differs on any of the 21 -- both sides stay in whichever season that Sunday-relative week already put them in, regardless of which fixed entry, if any, sits on the day. + +BLAST RADIUS, MEASURED, full 1583-9999 domain (not merely this fixture's 2005-2050 window): 6 983 liturgical days change, zero unclassified, across all 2 041 leap years in the domain -- see data/ef/expected-divergences-lms.sexp's own now-closed L3 entry for the full figures (this entry's own 21-row 2005-2050 population is the expected subset of that domain-wide count landing inside the fixture's own window: 11 leap years x up to 2 new rows each, minus the three already-explained overlaps above).") + (expected_rows 21)) ; C8 -- CLOSED, REMOVED (2026-08-18): 0 of 16801 rows, was 26. lectio builds ; Rogation Monday and Tuesday now (RG 87, Easter+36/+37, violet under ; RG 128(d)). The Wednesday is NOT built there and deliberately so: Easter+38 diff --git a/lib/kernel/calendar.ml b/lib/kernel/calendar.ml index d55e38d..db6c58e 100644 --- a/lib/kernel/calendar.ml +++ b/lib/kernel/calendar.ml @@ -79,7 +79,7 @@ let resolve_with_injected ?(suppressed = no_suppression) (rite : ('s, 'r) Rite.t { Precedence.cel = temporal.Temporal.office; origin = Precedence.Temporal } in let natural = - Layer.on_date idx date + Layer.on_date ~fixed_key:rite.Rite.fixed_key idx date |> List.map (fun (e : 'r Layer.entry) -> { Precedence.cel = e.Layer.cel; origin = Precedence.Sanctoral }) in @@ -339,7 +339,7 @@ let rg33_suppressed (rite : ('s, 'r) Rite.t) (idx : 'r Layer.index) Array.iter (fun date -> let candidates = - Layer.on_date idx date + Layer.on_date ~fixed_key:rite.Rite.fixed_key idx date |> List.map (fun (e : 'r Layer.entry) -> { Precedence.cel = e.Layer.cel; origin = Precedence.Sanctoral }) in @@ -529,7 +529,8 @@ let build_day (rite : ('s, 'r) Rite.t) (idx : 'r Layer.index) | None -> [] | Some slugs -> let on_date = - Layer.on_date idx date |> List.map (fun (e : 'r Layer.entry) -> e.Layer.cel) + Layer.on_date ~fixed_key:rite.Rite.fixed_key idx date + |> List.map (fun (e : 'r Layer.entry) -> e.Layer.cel) in let temporal_office = temporal.Temporal.office in (temporal_office :: (on_date @ List.map (fun c -> c.Precedence.cel) arrived)) diff --git a/lib/kernel/date.mli b/lib/kernel/date.mli index 2f632c8..0e86d54 100644 --- a/lib/kernel/date.mli +++ b/lib/kernel/date.mli @@ -14,6 +14,13 @@ val month : t -> int val day : t -> int val weekday : t -> weekday +(** Proleptic Gregorian leap-year test: divisible by 4, except a century year + not divisible by 400. The same rule {!make}/{!days_in_month} already use + internally to admit 29 February -- exposed so a rite can key its own + calendar-reckoning rules (e.g. a kalends-doubling convention) off the + identical, single-sourced definition rather than re-deriving it. *) +val is_leap : int -> bool + (** [to_rata]/[of_rata] expose the underlying day-count (days since 1970-01-01); [of_rata] and [add_days] are unbounded total arithmetic (they may denote a year outside 1583..9999 — only [make] enforces the domain). *) diff --git a/lib/kernel/layer.ml b/lib/kernel/layer.ml index f069546..2a072f0 100644 --- a/lib/kernel/layer.ml +++ b/lib/kernel/layer.ml @@ -73,8 +73,12 @@ let index t ~easter ~years = Hashtbl.iter (fun k v -> Hashtbl.replace movable k (canonical v)) movable; { fixed; movable } -let on_date idx date = - let f = try Hashtbl.find idx.fixed (Date.month date, Date.day date) with Not_found -> [] in +let on_date ?(fixed_key = fun d -> Some (Date.month d, Date.day d)) idx date = + let f = + match fixed_key date with + | None -> [] + | Some k -> ( try Hashtbl.find idx.fixed k with Not_found -> []) + in let m = try Hashtbl.find idx.movable (Date.to_rata date) with Not_found -> [] in match m with [] -> f | _ -> canonical (f @ m) diff --git a/lib/kernel/layer.mli b/lib/kernel/layer.mli index ab6e56b..a71e113 100644 --- a/lib/kernel/layer.mli +++ b/lib/kernel/layer.mli @@ -36,8 +36,17 @@ type 'r index val index : 'r t -> easter:(int -> Date.t) -> years:int list -> 'r index (** Entries falling on [date], fixed and movable together, in the layer's - canonical slug order. *) -val on_date : 'r index -> Date.t -> 'r entry list + canonical slug order. + + [fixed_key] answers "which (month, day) does the FIXED half look up for + this civil date", defaulting to the identity [Some (Date.month date, + Date.day date)] -- exactly today's behaviour, for a caller that supplies + nothing. A rite's own kalends-reckoning convention (see {!Rite.t}'s + [fixed_key] field) is threaded through here rather than applied to + [date] itself, so it touches ONLY the fixed table: the MOVABLE half + (keyed by rata die, via {!Date_spec.Easter_offset}/{!Date_spec. + Nth_weekday}) always uses [date] unchanged. *) +val on_date : ?fixed_key:(Date.t -> (int * int) option) -> 'r index -> Date.t -> 'r entry list (** Loads a layer from a sexp file. Parse and validation failures come back as [Error], never as an exception. *) diff --git a/lib/kernel/rite.ml b/lib/kernel/rite.ml index 4999fc2..738785a 100644 --- a/lib/kernel/rite.ml +++ b/lib/kernel/rite.ml @@ -8,6 +8,7 @@ type ('s, 'r) t = { temporal : Date.t -> ('s, 'r) Temporal.t; anchors : int -> (string * Date.t) list; easter : int -> Date.t; + fixed_key : Date.t -> (int * int) option; rules : ('s, 'r) Precedence.rules; season_runs : 's list; transfer_target : diff --git a/lib/kernel/rite.mli b/lib/kernel/rite.mli index 39538d0..0dcf17e 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 diff --git a/lib/kernel/validate.ml b/lib/kernel/validate.ml index ce48615..f523b39 100644 --- a/lib/kernel/validate.ml +++ b/lib/kernel/validate.ml @@ -239,7 +239,7 @@ let run (rite : ('s, 'r) Rite.t) (layer : 'r Layer.t) ~year = let expected : (string, int) Hashtbl.t = Hashtbl.create 64 in List.iter (fun date -> - Layer.on_date idx date + Layer.on_date ~fixed_key:rite.Rite.fixed_key idx date |> List.iter (fun (e : 'r Layer.entry) -> bump expected (Slug.to_string e.Layer.cel.Celebration.slug))) days; diff --git a/lib/rites/rite_ef/rite_ef.ml b/lib/rites/rite_ef/rite_ef.ml index e48ff33..ba1274b 100644 --- a/lib/rites/rite_ef/rite_ef.ml +++ b/lib/rites/rite_ef/rite_ef.ml @@ -39,6 +39,10 @@ let context ~lectionary ~commons : (Vocab_ef.season, Vocab_ef.rank) Rite.t = Julian-reckoning rite can supply {!Computus.julian_easter} instead. Read by [Layer.index] for [Date_spec.Easter_offset]. *) easter = Colitur_kernel.Computus.gregorian_easter; + (* The calendarium's own bissextile footnote (February, LT.txt:5011-5014): + see {!Temporal_ef.bissextile_fixed_key} for the full citation and + mechanism. Read by [Layer.on_date]'s fixed half only. *) + fixed_key = Temporal_ef.bissextile_fixed_key; rules = { Precedence.band = Precedence_ef.band; disposition = Precedence_ef.disposition; diff --git a/lib/rites/rite_ef/temporal_ef.ml b/lib/rites/rite_ef/temporal_ef.ml index c16732b..1c916f4 100644 --- a/lib/rites/rite_ef/temporal_ef.ml +++ b/lib/rites/rite_ef/temporal_ef.ml @@ -1158,6 +1158,68 @@ let anchors y = | Some d -> [ ("ef-holy-name-sunday", d) ] | None -> [ ("ef-holy-name", holy_name_fallback_date y) ]) +(* The Missale Romanum's own CALENDARIUM table, February, footnote + (docs/research/LT.txt:5011-5014, scan-corroborated at + docs/research/scan2.txt:3050-3058, where OCR mangles it to + "bi&sextili"/"Matthue"/"Cabrielis" -- transcription and scan agree, so + this rests on two witnesses of the same document): + + "In anno bissextili mensis februarius est dierum 29, et festum S. + Matthiae celebratur die 25 februarii, ac festum S. Gabrielis a + Virgine perdolente 28 februarii, et bis dicitur sexto calendas, id + est die 24 et die 25; et littera dominicalis, quae assumpta fuit in + mense ianuario, mutetur in praecedentem..." + + In a leap year February has 29 days, St Matthias is kept on 25 February + (not 24), St Gabriel of Our Lady of Sorrows on 28 February (not 27), and + the sixth kalends of March is said TWICE -- "bis dicitur sexto + calendas... die 24 et die 25". That last clause names the MECHANISM, not + two independent exceptions: the Roman calendar's intercalary day is + inserted by DOUBLING the sixth kalends (civil 24 February in a common + year), not by appending a 29th day at the month's end. Reckoned by + kalends position: 24 Feb = VI Kal. Mart., 25 Feb = V Kal., 26 Feb = IV + Kal., 27 Feb = III Kal., 28 Feb = pridie Kal. In a leap year VI Kal. + itself falls on TWO consecutive civil days (24th and 25th, "bis"), and + every kalends position after it is pushed one civil day later as a + result: V Kal. from 25th to 26th, IV Kal. from 26th to 27th, III Kal. + (Gabriel) from 27th to 28th, pridie Kal. from 28th to 29th. A feast fixed + at VI Kal. itself (Matthias) is kept on the SECOND occurrence, not the + first -- 25 February carries it, 24 February carries no fixed office at + all that year (confirmed against the LMS Ordo witness, + data/ef/expected-divergences-lms.sexp entry L3: 24 February 2024 is + titled plainly "EMBER SATURDAY of LENT", no Matthias anywhere near it). + + IMPLEMENTED AS THE GENERAL MECHANISM, not as "shift these two named + feasts": only three sanctoral entries exist in 23-29 February on shipped + data (peter-damien the 23rd, before the doubled kalends and therefore + unaffected; matthias the 24th; gabriel-of-our-lady-of-sorrows the 27th), + so "shift the two named feasts" and "shift every fixed entry from 24 + February" are indistinguishable on universal data -- they produce + identical output. They differ only for a locally-supplied entry, e.g. an + [--overlay] patronal feast fixed at 26 February: under the mechanism + reading it shifts to 27 February in a leap year (IV Kal. -> the civil day + IV Kal. falls on that year), exactly as a diocesan calendar compiled + against the same kalends convention would expect. The rubric's own text + states a MECHANISM ("bis dicitur sexto calendas"), not a closed list of + two saints, and this project has already been bitten once by a rule + implemented against the shipped data's coincidental shape rather than the + rubric itself (RG 16(a), CLAUDE.md's own carried lesson) -- so the general + reading is the one implemented here. + + Threaded through {!Rite.t}'s [fixed_key] field, read only by + {!Colitur_kernel.Layer.on_date}'s FIXED half: the kernel stays + rite-agnostic (a Byzantine or other non-Roman rite supplies nothing and + is unaffected), and the MOVABLE half ({!Date_spec.Easter_offset}, + {!Date_spec.Nth_weekday}) is untouched -- nothing in the footnote + concerns Easter-relative dates. *) +let bissextile_fixed_key (d : Date.t) : (int * int) option = + let m = Date.month d and day = Date.day d in + if m = 2 && Date.is_leap (Date.year d) then + if day = 24 then None (* the FIRST VI Kal.: no fixed entry lands here in a leap year *) + else if day >= 25 && day <= 29 then Some (2, day - 1) (* the SECOND VI Kal. onward, one day later *) + else Some (m, day) + else Some (m, day) + (* Compile-time check that this module satisfies the kernel's rite contract. *) module _ : Colitur_kernel.Temporal.RITE = struct let id = id diff --git a/lib/rites/rite_ef/temporal_ef.mli b/lib/rites/rite_ef/temporal_ef.mli index 5e85111..2bed5b6 100644 --- a/lib/rites/rite_ef/temporal_ef.mli +++ b/lib/rites/rite_ef/temporal_ef.mli @@ -51,6 +51,17 @@ val week : Date.t -> int option (** The lectionary key for a Sunday, or [None] if [d] is not a Sunday. *) val sunday_slug : Date.t -> string option +(** The calendarium's own bissextile (leap-year) footnote, February + (docs/research/LT.txt:5011-5014): in a leap year the sixth kalends of + March (24 February) is doubled rather than a 29th day appended, so every + fixed entry from 24 through 28 February is kept one civil day later than + usual (Matthias 24->25, Gabriel of Our Lady of Sorrows 27->28), and 24 + February itself carries no fixed office that year. Supplied as {!Rite.t}'s + [fixed_key] field -- see that field's own doc comment and this function's + definition for the full citation and the general-mechanism-vs-two-named- + feasts reasoning. *) +val bissextile_fixed_key : Date.t -> (int * int) option + val id : string (** Total over 1583..9999: every date yields exactly one temporal identity. *) diff --git a/test/test_calendar.ml b/test/test_calendar.ml index 74fe26a..0d402e6 100644 --- a/test/test_calendar.ml +++ b/test/test_calendar.ml @@ -116,6 +116,9 @@ module Fixture = struct any for a fixture; nothing here is Easter-relative, so the value is never actually read. *) easter = Colitur_kernel.Computus.gregorian_easter; + (* Not a Roman rite either, so no bissextile-doubling convention: + identity, {!Rite.t.fixed_key}'s own documented default. *) + fixed_key = (fun d -> Some (D.month d, D.day d)); rules; season_runs = [ A; B ]; transfer_target; readings; creed } let entry ~month ~day ~slug ~rank = diff --git a/test/test_differential.ml b/test/test_differential.ml index 8c1dd8d..2f63df6 100644 --- a/test/test_differential.ml +++ b/test/test_differential.ml @@ -1096,6 +1096,36 @@ let rg33_vigil_slugs = [ "vigil-of-st-lawrence"; "vigil-of-the-nativity-of-st-john-the-baptist"; "vigil-of-sts-peter-paul" ] +(* C40 -- the calendarium's own bissextile (leap-year) footnote (February, + docs/research/LT.txt:5011-5014; see rite_ef/temporal_ef.ml's + [bissextile_fixed_key] for the full citation and mechanism), implemented + 2026-08-22. lectio builds no such shift at all (confirmed directly + against the fixture: Matthias sits at 24 February and Gabriel of Our Lady + of Sorrows at 27 February in EVERY leap year the 2005-2050 fixture + covers, 11 of them), so every leap year now diverges on the two shifted + civil days: colitur vacates 24/27 February (Matthias/Gabriel move away) + and occupies 25/28 February instead, while lectio keeps the pre-shift + assignment on both. + + Four shapes, one mechanism -- OLD position vacated (colitur no longer + matches lectio's still-there Matthias/Gabriel) and NEW position occupied + (colitur now shows a saint lectio's own unmoved date does not) -- each + checked by NAME on both sides, the same identity discipline C39 and + C6/C14 already apply, not merely a diff-set shape: a coincidental + same-shape diff on an unrelated 24/25/27/28 February slug would not match + any of the four literal-slug conjuncts below. *) +let is_bissextile_shift_row (l : row) (c : row) ~month ~day = + month = 2 + && Date.is_leap (year_of_date c.date) + && ((day = 24 && String.equal l.slug "matthias" && not (String.equal c.slug "matthias")) + || (day = 25 && String.equal c.slug "matthias" && not (String.equal l.slug "matthias")) + || (day = 27 + && String.equal l.slug "gabriel-of-our-lady-of-sorrows" + && not (String.equal c.slug "gabriel-of-our-lady-of-sorrows")) + || (day = 28 + && String.equal c.slug "gabriel-of-our-lady-of-sorrows" + && not (String.equal l.slug "gabriel-of-our-lady-of-sorrows"))) + let layer_c_reason (l : row) (c : row) diffs = let m = month_of_date l.date and d = day_of_date l.date in if diffs = [] then None @@ -1158,6 +1188,8 @@ let layer_c_reason (l : row) (c : row) diffs = && (not (List.mem c.slug rg33_vigil_slugs)) && subset diffs [ Slug_f; Rank; Colour_f; First_f; Gospel_f ] then Some "C39" + else if is_bissextile_shift_row l c ~month:m ~day:d && subset diffs [ Slug_f; Rank; Colour_f; First_f; Gospel_f ] + then Some "C40" (* C25 -- CLOSED, BVM Saturday Mass (2026-08-17), predicate removed: 0 rows. Its days are unoccupied IV-class Saturdays, so they carry RG 78's office and now RG 309(a)'s Mass for it, which answers before step 3's walkback diff --git a/test/test_golden.ml b/test/test_golden.ml index ba25d8a..d680720 100644 --- a/test/test_golden.ml +++ b/test/test_golden.ml @@ -1315,6 +1315,67 @@ let test_rogation_wednesday_yields_to_a_feast_2026 () = "2026-05-13 wednesday season=paschaltide week=6 slug=ef-ascension-vigil rank=class-2 colour=white \ subject=temporal name_la=- comms=[robert-bellarmine:ordinary] in=- out=[]" +(* ---- The bissextile (leap-year) calendarium footnote, bissextile-shift + task, 2026-08-22 ---- + + The Missale Romanum's own CALENDARIUM table, February, footnote + (docs/research/LT.txt:5011-5014, scan-corroborated docs/research/ + scan2.txt:3050-3058): "In anno bissextili mensis februarius est dierum + 29, et festum S. Matthiae celebratur die 25 februarii, ac festum S. + Gabrielis a Virgine perdolente 28 februarii, et bis dicitur sexto + calendas, id est die 24 et die 25" -- in a leap year the sixth kalends + of March (24 February) is doubled rather than a 29th day appended, so + St Matthias (ordinarily 24 February) is kept on 25 February and St + Gabriel of Our Lady of Sorrows (ordinarily 27 February) on 28 February; + 24 February itself carries no fixed office that year. + {!Rite_ef.Temporal_ef.bissextile_fixed_key} implements this as the + rubric's own general MECHANISM, so a leap year moves the VACATED date's + slug/rank/colour away and the OCCUPIED date's toward it -- both sides + pinned for each saint, plus one common-year control apiece proving the + identity default is unchanged where the footnote does not apply. *) + +(* Matthias, 2044 (leap): 24 February carries no fixed office at all + (Class4 temporal only, zero commemorations); Matthias (Class2, an + Apostle) wins 25 February outright against that day's own Class4 + feria. *) +let test_bissextile_matthias_leap_2044 () = + check ~msg:"leap year: 24 February carries no fixed office, Matthias has moved away" 2044 2 24 + "2044-02-24 wednesday season=septuagesima week=2 slug=ef-septuagesima-2-wednesday rank=class-4 colour=violet \ + subject=temporal name_la=- comms=[] in=- out=[]"; + check ~msg:"leap year: Matthias observed outright on 25 February, not 24" 2044 2 25 + "2044-02-25 thursday season=septuagesima week=2 slug=matthias rank=class-2 colour=red subject=saint name_la=- \ + comms=[] in=- out=[]" + +(* Matthias, 2025 (common): unaffected control -- the identity default + applies, Matthias stays at his ordinary 24 February. *) +let test_bissextile_matthias_common_2025 () = + check ~msg:"common year: Matthias unaffected, still 24 February" 2025 2 24 + "2025-02-24 monday season=septuagesima week=2 slug=matthias rank=class-2 colour=red subject=saint name_la=- \ + comms=[] in=- out=[]" + +(* Gabriel of Our Lady of Sorrows, 2008 (leap): 27 February carries no + trace of him at all (not even a commemoration -- fixed_key removes him + from the candidate set entirely, RG 111's admission machinery never + sees him); on 28 February he is admitted as an ORDINARY commemoration + (Class3 ties the day's own privileged Lenten feria, which keeps + observed). A different shape from Matthias's outright win above, + deliberately pinned: the mechanism moves WHERE the saint is tried, not + whether he wins once he gets there. *) +let test_bissextile_gabriel_leap_2008 () = + check ~msg:"leap year: 27 February carries no trace of Gabriel, he has moved away" 2008 2 27 + "2008-02-27 wednesday season=lent week=3 slug=ef-lent-3-wednesday rank=class-3 colour=violet subject=temporal \ + name_la=- comms=[] in=- out=[]"; + check ~msg:"leap year: Gabriel admitted as an ordinary commemoration on 28 February, not 27" 2008 2 28 + "2008-02-28 thursday season=lent week=3 slug=ef-lent-3-thursday rank=class-3 colour=violet subject=temporal \ + name_la=- comms=[gabriel-of-our-lady-of-sorrows:ordinary] in=- out=[]" + +(* Gabriel of Our Lady of Sorrows, 2025 (common): unaffected control -- + observed outright at his ordinary 27 February. *) +let test_bissextile_gabriel_common_2025 () = + check ~msg:"common year: Gabriel unaffected, still observed on 27 February" 2025 2 27 + "2025-02-27 thursday season=septuagesima week=2 slug=gabriel-of-our-lady-of-sorrows rank=class-3 colour=white \ + subject=saint name_la=- comms=[] in=- out=[]" + (* RG 128, transcribed in docs/research/rules-register.md §3b: violet is used for "II/III-class vigils outside Paschaltide". Two of colitur's five vigils disagreed with that rule until the ef-oconnell-rubrics branch -- the @@ -1510,5 +1571,13 @@ let suite = Alcotest.test_case "RG87: Rogation Wednesday admitted (2024)" `Quick test_rogation_wednesday_admitted_2024; Alcotest.test_case "RG87/113: Rogation Wednesday yields to an impeded feast (2026)" `Quick - test_rogation_wednesday_yields_to_a_feast_2026 + test_rogation_wednesday_yields_to_a_feast_2026; + Alcotest.test_case "bissextile footnote: Matthias moves 24->25 February (leap, 2044)" `Quick + test_bissextile_matthias_leap_2044; + Alcotest.test_case "bissextile footnote: Matthias unaffected (common, 2025)" `Quick + test_bissextile_matthias_common_2025; + Alcotest.test_case "bissextile footnote: Gabriel of Our Lady of Sorrows moves 27->28 February (leap, 2008)" + `Quick test_bissextile_gabriel_leap_2008; + Alcotest.test_case "bissextile footnote: Gabriel of Our Lady of Sorrows unaffected (common, 2025)" `Quick + test_bissextile_gabriel_common_2025 ] ) diff --git a/test/test_lms_ordo.ml b/test/test_lms_ordo.ml index 84c4776..219e51f 100644 --- a/test/test_lms_ordo.ml +++ b/test/test_lms_ordo.ml @@ -502,13 +502,15 @@ let make_suite ~label ~fixture_path ~fixture_sha256 ~window_first ~window_last ~ this function declared [by_id]/[explained_counts] but never actually populated the latter (the mechanism this comment sits in) -- L1 was already CLOSED by the time that task shipped, so it had nothing real - to explain and the gap went unexercised. L3/L4 (Witnesses task, - 2026-08-22, both 2023-2024-only) are the first live tests of it. *) - let allow_list_id_for_date d = - if String.equal d "2024-02-24" then Some "L3" - else if String.equal d "2023-12-24" then Some "L4" - else None - in + to explain and the gap went unexercised. L4 (Witnesses task, + 2026-08-22, 2023-2024-only) is the first live test of it. L3's own + "2024-02-24" branch (bissextile-shift task, 2026-08-22) is REMOVED, + not left dead: the fix makes that date's Creed match outright, so the + branch would never fire again, and a stale date->id mapping for a + now-closed entry is exactly the kind of thing this file's own + "must be visible as a real change" discipline (this comment's own + opening sentence) argues against leaving in place. *) + let allow_list_id_for_date d = if String.equal d "2023-12-24" then Some "L4" else None in let test_creed_matches_or_is_explained () = let ordo = ordo_rows fixture_path in let colitur = colitur_rows ~year_lo ~year_hi ~window_first ~window_last in @@ -651,17 +653,29 @@ let allow_list_path = "../data/ef/expected-divergences-lms.sexp" ever looks at its own explained_counts. Fixed to the two ids this task added (L3, L4) -- L1 is CLOSED/removed and L2 is deliberately prose-only (see the sexp file's own header on why), so neither is expected here. *) -let test_allow_list_ids_are_exactly_l3_l4 () = +(* L3 CLOSED (bissextile-shift task, 2026-08-22): removed from the active + sexp record set -- see its own now-prose closure note in + data/ef/expected-divergences-lms.sexp for the fix and the measured + blast radius. Only L4 remains active. *) +let test_allow_list_ids_are_exactly_l4 () = let ids = List.sort String.compare (List.map (fun e -> e.id) (load_allow_list allow_list_path)) in - Alcotest.(check (list string)) "the LMS allow-list declares exactly L3 and L4" [ "L3"; "L4" ] ids + Alcotest.(check (list string)) "the LMS allow-list declares exactly L4" [ "L4" ] ids -let suite_allow_list = ("lms-ordo-allow-list", [ Alcotest.test_case "declares exactly L3 and L4" `Quick test_allow_list_ids_are_exactly_l3_l4 ]) +let suite_allow_list = ("lms-ordo-allow-list", [ Alcotest.test_case "declares exactly L4" `Quick test_allow_list_ids_are_exactly_l4 ]) let suite_2023_2024 = make_suite ~label:"lms-ordo-2023-2024" ~fixture_path:"fixtures/lms-ordo-2023-2024.sexp" ~fixture_sha256:"c8d9d4b790f6b4438e932f70dad8ebe9a0316662f1eb02c26248e04c7be1a62b" ~window_first:"2023-12-01" ~window_last:"2024-12-31" ~year_lo:2022 ~year_hi:2025 ~allow_list_path ~expected_rows:397 - ~expected_bvm_votive:12 ~expected_proper:182 ~expected_common:2 ~expected_preceding_sunday:61 + (* expected_proper 182 -> 181 (bissextile-shift task, 2026-08-22): 24 + February 2024, previously Matthias's own Proper Mass, is now the + Ember Saturday of Lent's own temporal proper -- Own_slug-sourced, not + Proper, so it leaves this bucket's population rather than merely + changing which slug's proper it is (see this file's own header on why + Own_slug is excluded). Matthias himself moves to 25 February, an + I-class Sunday that admits him not even as a commemoration (RG16(a)), + so his own Mass is not said anywhere in this window any more. *) + ~expected_bvm_votive:12 ~expected_proper:181 ~expected_common:2 ~expected_preceding_sunday:61 ~expected_ascension_week:1 let suite_2024_2025 = diff --git a/test/test_validate.ml b/test/test_validate.ml index 1ceaca2..671c706 100644 --- a/test/test_validate.ml +++ b/test/test_validate.ml @@ -339,6 +339,9 @@ module Synthetic = struct any for a fixture; nothing here is Easter-relative, so the value is never actually read. *) easter = Colitur_kernel.Computus.gregorian_easter; + (* Not a Roman rite either, so no bissextile-doubling convention: + identity, {!Rite.t.fixed_key}'s own documented default. *) + fixed_key = (fun d -> Some (D.month d, D.day d)); transfer_target; readings; creed } (* Empty by default: every check built before Task 12 exercises the -- cgit v1.3 From f4cc032d7e812d716ff6b5df8192f79a2560e8f0 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Sat, 22 Aug 2026 17:56:42 +0200 Subject: feat(ef): the Gloria in excelsis, RG 431-432, deferring to Breviary 237-238 Phase 2 of celebrant-rubrics-phase1: colitur rubrics gains a fifth column, whether the Gloria is said. Follows the Creed's own seam exactly -- Rite.t.gloria, Liturgical_day.t.gloria, wired through calendar.ml the same way. RG 431(a)/432(a) defer the Gloria to the Breviary's own Te Deum rule (nn. 237-238), so te_deum is implemented as its own named predicate, cited clause by clause, not collapsed into a colour heuristic. 431(c) (Holy Thursday, the Easter Vigil Mass) and 432(b)/(d) (violet; a Requiem) are independent overrides checked ahead of the Te Deum-derived answer. Every clause this engine has no dimension to model (votive Mass classes, the wider n.302 "Missa festiva" categories) is stated as N/A with its own reasoning, not silently dropped. Validated against the FIUV universal Ordo (Gloria and Te Deum) and all three LMS editions (Gloria). A first pass over-trusted a clean-looking 15-for-15 FIUV contradiction of 237(b)'s own Septuagesima exception and replaced it with a blanket "every Sunday" rule; the evidence was itself corrupted -- the FIUV extractor recognised only one of the source's two Te Deum negations ("non dicitur", not "sine"), so every "sine Te Deum" Sunday read wrongly true. Fixed in tools/extract_fiuv_ordo.ml, fixture re-extracted, and the literal 237(b) reading restored once the corrected data confirmed it. A second bug surfaced alongside it (Palm/ Passion Sunday wrongly reading true via Temporal_ef.named's own table membership, then Christ the King wrongly reading false from an over-broad fix) is closed with an explicit two-slug exclusion. Domain-wide 1583-9999: every violet or Rose day is gloria=false except the Easter Vigil (RG 431(c) lex specialis), every Requiem is gloria=false, both measured exhaustively, zero exceptions. Mutation- proved: disabling 431(c) reddens 8 tests including all four oracle comparisons; disabling 238(c)'s feria-I-classis exclusion reddens exactly the dedicated Ash Wednesday unit test, a genuine blind spot in both oracle layers, reported rather than hidden. Two open, cited findings, neither fixed here (out of this task's "follow creed's exact seam" scope): a privileged Lenten/Passiontide feria carrying one commemoration reads Gloria=true in the LMS Ordo but Te-Deum=true/Gloria=false in FIUV -- the two oracles disagree with each other, not merely with colitur (data/ef/expected-divergences-lms.sexp L5, expected-divergences-fiuv.sexp F3); and a pre-existing, uncited Colour.Violet bug on Rogation Monday/Tuesday in Temporal_ef.temporal, surfaced by this comparison but root-caused as a separate defect (L6). day/readings verified byte-identical against a build from the branch tip before this task (v0.10.1's own tag predates an already-landed bissextile fix that legitimately changed both, so it is not the right baseline). 671 tests green (dune test); 678 with the exhaustive sweep (COLITUR_EXHAUSTIVE_SWEEP=1 dune test --force, ~104s). --- bin/main.ml | 26 ++- data/ef/expected-divergences-fiuv.sexp | 108 +++++++++- data/ef/expected-divergences-lms.sexp | 112 ++++++++++ lib/kernel/calendar.ml | 4 + lib/kernel/liturgical_day.ml | 1 + lib/kernel/liturgical_day.mli | 4 + lib/kernel/rite.ml | 1 + lib/kernel/rite.mli | 6 + lib/rites/rite_ef/rite_ef.ml | 3 +- lib/rites/rite_ef/rite_ef.mli | 3 + lib/rites/rite_ef/rubrics_ef.ml | 378 +++++++++++++++++++++++++++++++++ lib/rites/rite_ef/rubrics_ef.mli | 30 +++ man/colitur.1 | 24 ++- test/cli.t | 40 ++-- test/fixtures/fiuv-ordo-2025-2026.sexp | 79 ++++--- test/test_calendar.ml | 9 +- test/test_fiuv_ordo.ml | 169 ++++++++++++++- test/test_lms_ordo.ml | 112 +++++++++- test/test_rubrics_ef.ml | 324 +++++++++++++++++++++++++++- test/test_validate.ml | 16 +- tools/extract_fiuv_ordo.ml | 21 ++ 21 files changed, 1378 insertions(+), 92 deletions(-) (limited to 'data/ef') diff --git a/bin/main.ml b/bin/main.ml index 01410f2..cf8cae2 100644 --- a/bin/main.ml +++ b/bin/main.ml @@ -408,7 +408,12 @@ let readings_line ~lang ~sigla (d : (Rite_ef.Vocab_ef.season, Rite_ef.Vocab_ef.r for a [Votive] day before [said] became honest, and it is a value this function already has in scope regardless of [via]. So this is not "print a placeholder for the missing case", it is "the value was - already available from a different field, and still is". *) + already available from a different field, and still is". + + Task (celebrant-rubrics-phase1, Phase 2): a FIFTH column, whether the + Gloria in excelsis is said (EF: RG 431-432, {!Rite_ef.Rubrics_ef.gloria}) + -- same [string_of_bool] convention as [creed], same plain [bool] with + no [option] to guard, same reasoning throughout. *) let rubrics_line (d : (Rite_ef.Vocab_ef.season, Rite_ef.Vocab_ef.rank) Colitur_kernel.Liturgical_day.t) = let said, via = @@ -421,8 +426,9 @@ let rubrics_line (d : (Rite_ef.Vocab_ef.season, Rite_ef.Vocab_ef.rank) Colitur_k Colitur_kernel.Mass_formulary.source_to_string f.Colitur_kernel.Mass_formulary.via ) | None -> ("-", "-") in - Printf.printf "%s\t%s\t%s\t%s\n" (D.to_iso8601 d.Colitur_kernel.Liturgical_day.date) said via + Printf.printf "%s\t%s\t%s\t%s\t%s\n" (D.to_iso8601 d.Colitur_kernel.Liturgical_day.date) said via (string_of_bool d.Colitur_kernel.Liturgical_day.creed) + (string_of_bool d.Colitur_kernel.Liturgical_day.gloria) (* One civil year, Jan 1 - Dec 31, matching [temporal_report]'s own scan -- NOT one liturgical year: [Colitur_kernel.Calendar.year] resolves a single @@ -1281,8 +1287,8 @@ output formats: 2026-04-05 sunday paschaltide 1 ef-easter-sunday class-1 white readings date slug | Epistle | Gospel [| name] 2026-12-25 ef-nativity | Heb 1:1-12 | John 1:1-14 - rubrics date, formulary slug, source, creed -- TAB-separated - 2026-01-01[TAB]ef-circumcision[TAB]own[TAB]true + rubrics date, formulary slug, source, creed, gloria -- TAB-separated + 2026-01-01[TAB]ef-circumcision[TAB]own[TAB]true[TAB]true A citation contains spaces, so readings uses " | " between its fields while day stays space-separated; that is why they are separate commands rather @@ -1299,14 +1305,16 @@ output formats: (source: proper/own/preceding-sunday/common/votive) -- not always the day's own: a weekday with no proper resumes the preceding Sunday's, a saint with no proper says his assigned Common -- followed by whether the - Creed is said (RG 475-476: "true"/"false", OCaml's own literal, not - "yes"/"no" or "1"/"0"). TAB-separated rather than space or " | ": a + Creed is said (RG 475-476) and whether the Gloria in excelsis is said + (RG 431-432, deferring to the Breviary's own Te Deum rule, nn. 237-238, + for RG 431(a)) -- both "true"/"false", OCaml's own literal, not + "yes"/"no" or "1"/"0". TAB-separated rather than space or " | ": a resolved formulary NAME is a column a later version may add, and it can carry both spaces and punctuation a citation never does, which rules out either alternative already in use above. --overlay is accepted (the - observed celebration it changes decides the formulary and the Creed); - --lang/--raw/--sigla-* are refused -- this row resolves no display name - and no citation for any of them to affect. + observed celebration it changes decides the formulary, the Creed and the + Gloria); --lang/--raw/--sigla-* are refused -- this row resolves no + display name and no citation for any of them to affect. emit one schema (season, week, slug, rank, colour, subject, names, citations, commemorations), rendered five ways: csv (RFC 4180, diff --git a/data/ef/expected-divergences-fiuv.sexp b/data/ef/expected-divergences-fiuv.sexp index 5506e46..6ed9a04 100644 --- a/data/ef/expected-divergences-fiuv.sexp +++ b/data/ef/expected-divergences-fiuv.sexp @@ -15,12 +15,106 @@ ; backs, the SAME convention every other allow-list file in this project ; uses: not always "colitur". ; -; Empty as of this task: the Creed comparison found no unexplained +; The Creed comparison (Task 6/Witnesses task) found no unexplained ; divergence anywhere in the 400-day window (399 comparable days, Holy ; Saturday excluded per test_creed_coverage -- see that test's own -; citation). Kept as a file, not deleted, on the same footing as -; expected-divergences-lms.sexp's own empty-but-live state after L1's -; closure: the machinery that would explain a FUTURE divergence needs -; somewhere to live, and an empty allow-list with a live "every entry -; must be used" check is a real invariant worth keeping, not a -; formality. +; citation) and still does not. Phase 2 (celebrant-rubrics-phase1, +; 2026-08-22) extended this file to two more axes, Gloria and Te Deum -- +; F1 below (Gloria) and F3 (Te Deum). Both prose-only, the same L2/L5/L6 +; convention data/ef/expected-divergences-lms.sexp's own header explains: +; the real enforcement is test_fiuv_ordo.ml's own predicates and count +; assertions, not a machine-loaded [id] record. +; +; F2 and F4 (Te Deum: every vigil; the three September Ember days) were +; found, then CLOSED within the same task: tools/extract_fiuv_ordo.ml's +; own Te Deum parser recognised only ONE of the source's two negative +; phrasings ("non dicitur Te Deum"), so "sine Te Deum" -- how the source +; actually negates a Sunday's/vigil's/Ember-day's own Te Deum -- fell +; through to a bare "Te Deum" substring match and was wrongly read +; [true]. Fixed in the extractor (its own citation has the full account); +; the fixture was re-extracted from the SAME pdftotext dump; 24 of 400 +; rows flipped true->false, and colitur's own answer already matched the +; corrected value on every one of them -- no code change needed for F2/ +; F4 specifically. See test/fixtures/fiuv-ordo-2025-2026.sexp's own +; "RE-EXTRACTED" note and lib/rites/rite_ef/rubrics_ef.ml's own [te_deum] +; header (237(a)'s comment) for the fuller account, including a real, +; separate regression this same fix round found and reverted (a first +; attempt at "every Sunday says Te Deum" wrongly excluded Christ the +; King, caught by the LMS Ordo's own Gloria axis, 2024-10-27). + +; F1 -- OPEN, adjudicated FOR colitur. Fired once: 2026-04-03, Good +; Friday. +; +; The raw source (docs/research/ordo/fiuv-ordo-2025-2026.pdf, page 46, +; verified directly against the PDF, not merely the extracted fixture): +; "3. Nig in Actione liturgica usque ad 4am partem, Viol. in S. +; Communione. FERIA VI IN PASSIONE ET MORTE DOMINI, De ea, I cl. ... +; Missa pr., (omittuntur ps. Iudica me et Gloria Patri), Gloria, sine +; Credo, praef. comm." -- read LITERALLY, this states the Gloria IS said +; on Good Friday. colitur says [false] (RG 432(d)'s own {!Colour.Black} +; proxy this Mass shares with the Requiem population, {!Rite_ef.Rubrics_ +; ef.gloria}'s own header). +; +; ADJUDICATED FOR COLITUR: Good Friday's own liturgical action has no +; Mass at all in the 1955-restored Holy Week (RG 28's own "non sit dies +; liturgicus" framing for the Paschal Vigil is the closest parallel this +; project already cites, {!Rite_ef.Rubrics_ef.creed}'s own RG 28-34 +; comment) -- no Consecration, no Communion under both species by the +; celebrant, only Communion from the reserved Sacrament. That the Gloria +; is NOT said on Good Friday is among the most widely and consistently +; attested facts in the whole of 1962-rite literature (O'Connell, +; Fortescue, every published Ordo this project has touched, and this +; author's own independent knowledge of the rite) -- essentially +; undisputed. The printed "Missa pr., ..., Gloria, ..." block, structured +; identically to a REAL Mass's own rubric line elsewhere in this same +; Ordo (compare Easter Day's "Missa pr., Gloria, sequentia, Credo, praef. +; Pasch."), most plausibly describes the liturgical action's own +; STRUCTURE using the book's standard notation for bookkeeping +; consistency, or is a genuine single-word compiler error -- neither +; resolvable without contacting the compiler, out of this task's own +; scope. NOT the same failure mode as the Te Deum extractor bug above +; (F2/F4): this is the RAW pdftotext TEXT itself making the claim, not a +; downstream parsing artefact of test_fiuv_ordo.ml's own extraction -- +; re-run directly against a fresh -layout dump for this task, not merely +; trusted from the fixture. The PDF's own page IMAGE was not separately +; inspected (out of this task's own tool access), so a pdftotext-layer +; misread (a stray line from an adjacent block folded into this one) is +; not fully ruled out either -- named as a real possibility, not +; silently excluded. + +; F3 -- OPEN, single-witnessed, colitur's own possible gap (Te Deum +; axis). Fires 6 times, every one of the six dates +; data/ef/expected-divergences-lms.sexp's own L5 already found for +; Gloria: 2026-03-06/07/09/12/21/24, a privileged Lenten or Passiontide +; feria (Class3, RG25) whose own office is impeded and carries exactly +; one commemoration of a Class3 saint. colitur's [te_deum] reads [false] +; (a plain ferial office by every branch {!Rite_ef.Rubrics_ef.te_deum} +; checks); FIUV reads [true] in all six -- confirmed directly against +; the raw pdftotext dump, not merely the fixture: e.g. 12 March, "Ll. 1a +; et 2a (= 2a+3a) de Scr. occ., 3a de festo, Te Deum." -- a genuine, +; unnegated "Te Deum" (neither of the two negative phrasings the +; extractor now checks for), so this is NOT the same failure mode F2/F4 +; were. +; +; CITATION: the same n.302(b)/RG431(b) text L5 already cites (LT.txt -- +; a MISSAL rubric, not a Breviary one, so its literal text governs the +; MASS's own Gloria, not Matins' Te Deum) does not directly license this +; finding at all -- 237/238 (the BREVIARY rubric {!Rite_ef.Rubrics_ef. +; te_deum} actually implements) has no clause naming a commemoration as +; grounds for Te Deum. What this finding suggests, not yet established: +; the DIVINE OFFICE may treat a commemorated day more generously than the +; MASS does for exactly this shape (a commemorated saint's own lessons +; are read at Matins even on an impeded day, which could plausibly extend +; to Te Deum by an unwritten or unlocated convention) -- genuinely +; speculative, offered as a research lead for a follow-on task, not a +; citation this entry treats as settled. +; +; WHY NOT FIXED HERE: SINGLE-WITNESSED (the LMS fixtures never captured +; Te Deum at all, so there is no second Ordo to corroborate this shape +; the way the Sacred-Triduum/BVM-Saturday/vigil findings elsewhere in +; this task were cross-checked). Fixing it would need the SAME kernel +; signature widening L5 already declines for the identical reason +; (`~commemorations` on {!Colitur_kernel.Rite.t.gloria}, and by extension +; a parallel widening of [te_deum] if the two were ever to diverge in +; their own inputs) -- out of a task briefed to follow creed's existing +; seam exactly. Left OPEN for the same follow-on task L5 recommends. diff --git a/data/ef/expected-divergences-lms.sexp b/data/ef/expected-divergences-lms.sexp index 4cb5d2a..df813f9 100644 --- a/data/ef/expected-divergences-lms.sexp +++ b/data/ef/expected-divergences-lms.sexp @@ -6,6 +6,10 @@ ; (2025-11-28..2026-12-31) joined it. L3/L4 below fired only in the ; 2023-2024 window -- neither recurs in the other two, a fact worth ; keeping visible rather than merging away (see [expected_rows] on each). +; L5/L6 (Phase 2, 2026-08-22) extended the comparison to a second axis, +; Gloria (RG431-432) -- both fire in more than one window, at DIFFERENT +; counts per window, so both are prose-only (L2's own precedent), not +; machine-checked [id] records; see each for the real enforcement site. ; ; A SEPARATE file from data/ef/expected-divergences.sexp (the lectio ; allow-list) and data/ef/expected-divergences-missalemeum.sexp (the @@ -228,3 +232,111 @@ (verdict open) (note "2023-12-24 (the 4th Sunday of Advent AND Christmas Eve, a genuinely rare coincidence -- roughly 1 year in 7 -- absent from both the 2024-2025 and 2025-2026 windows, where Christmas Eve falls on a Tuesday and a Wednesday respectively). colitur says the Creed IS said (true), reading [temporal]'s own weekday (Sunday) per RG475(a)'s clause, positioned ahead of the vigil-exclusion check in {!Rite_ef.Rubrics_ef.creed} -- unconditionally, the same way it already does for RG16(a)'s Feast-of-the-Lord case. The Ordo says \"No Gl No Cr\" for this date. ADJUDICATED FOR COLITUR, not merely left open by default: RG30(a)'s own \"locum tenet ... nulla fit commemoratio\" language is textually closer to RG16(a) (which colitur already treats as Creed-preserving) than to an ordinary vigil superseding a Sunday -- the Vigil does not merely WIN THE DAY, it takes the SUNDAY'S OWN IDENTITY, the same shape RG475(a) was written to reach. The COUNTER-reading is real and not dismissed here: RG475(a)'s own text says \"locum cedat ... festo\" (gives way to a FEAST), and RG35 (Caput VI) classifies feria/vigilia/festum as three distinct liturgical-day categories -- a strict textual reading could confine 475(a)'s override to FEAST-displacement only, leaving a VIGIL-displaced Sunday to fall through to the general vigil exclusion (476, via RG33's own \"a vigil is a distinct category\" reasoning already coded elsewhere in {!Rite_ef.Rubrics_ef.creed}). Left OPEN rather than closed on this task's own authority: adjudicating scripture-grade primary-source questions is out of scope for a witness-wiring task, and the two readings are both defensible. Not fixable inside this task's own no-lib-changes constraint regardless of which reading eventually wins.") (expected_rows 1)) + +; L5 -- OPEN, colitur's own gap, found extending this suite to the Gloria +; axis (celebrant-rubrics-phase1 Phase 2, 2026-08-22). NOT an active +; machine-checked [id] entry -- same reasoning L2 above gives: the count +; varies window to window (5 in 2023-2024, 5 in 2024-2025, 6 in +; 2025-2026), so a single static [expected_rows] cannot check it. The REAL +; enforcement is test_lms_ordo.ml's own [is_l5_lenten_commemoration] +; predicate plus [make_suite]'s own ~expected_gloria_l5 parameter, +; asserted per window directly. +; +; SHAPE, identical in all 16 instances found (5+5+6, zero exceptions): +; a privileged Lenten or Passiontide feria (Class3, violet -- RG25, +; {!Rite_ef.Temporal_ef.ferial_rank}) whose own office is impeded and +; carries EXACTLY ONE commemoration, of a Class3 saint colitur's own +; precedence engine (independently validated, layers 3-5) correctly +; reduces to a mere commemoration. colitur's [gloria] reads [false] (the +; day is a plain ferial office by every test [Rite_ef.Rubrics_ef.te_deum] +; runs -- no Sunday, no vigil, no octave, [named] = [None], [subject] = +; [Temporal]); the Ordo reads [true] in every one of the 16 instances. +; +; CITATION (docs/research/LT.txt:2359-2361, "V - De Missis festivis", +; quoted in rubrics_ef.ml's own [gloria] header in full): "302. Sensu +; autem latiore, dicuntur quoque Missae de festo: ... b) Missa de +; commemoratione in Officio diei occurrente" -- in the WIDER sense, a Mass +; "of a commemoration occurring in the day's own Office" is ALSO called a +; "Missa festiva" -- and RG431(b): "Hymnus Gloria in excelsis dicitur ... +; in Missis festivis de quibus n. 302" -- such a Mass says the Gloria. +; Textually, this appears to be EXACTLY the shape found: the day's own +; ferial Office, carrying a commemoration, is elevated to "festive" status +; for the Gloria specifically. +; +; WHY NOT FIXED HERE: n.303(b), the very next paragraph (LT.txt:2359-2367, +; same quote in rubrics_ef.ml), qualifies n.302(b)'s own Masses: "dici +; potest tantum si occurrit dies liturgicus IV classis" -- CAN ONLY BE +; SAID if the liturgical day occurring is IV class. Every instance found +; here is a Class3 PRIVILEGED FERIA (RG25), not IV class, which reads as a +; textual CONTRADICTION of the empirical finding rather than a +; confirmation of it -- unresolved without n.304 onward (not in this +; project's sources), which may clarify that 301-303 govern which Mass a +; priest may freely CHOOSE among several options in one church on one day +; (a dimension colitur does not model -- see [gloria]'s own SCOPE NOTE), +; a different question from \"does THE Mass actually said, once +; determined, say the Gloria\" (431(b)'s own question). Implementing this +; also has a real architectural cost this task's own instructions +; explicitly avoided: [Rite_ef.Rubrics_ef.gloria] would need a FOURTH +; parameter, the day's own {!Colitur_kernel.Liturgical_day.t.commemorations} +; -- a kernel [Rite.t.gloria] signature change, the same shape RG16(a)'s +; own [admit] fix needed a [~temporal] parameter for, and squarely out of +; a task briefed to \"follow exactly how creed was wired -- same seam\". +; Left OPEN, not guessed into a possibly-wrong rule. Recommended for a +; follow-on task, ideally alongside Phase 3's Preface work (RG483 governs +; a DIFFERENT, but textually adjacent, commemoration-vs-Mass-part +; question, so the two may share the same kernel signature widening). +; +; UPDATE (same task, after wiring the FIUV Ordo's own Gloria and Te Deum +; axes, test_fiuv_ordo.ml): this paragraph previously said FIUV's own +; [gloria] axis was not compared at all. It now is, and the result +; WEAKENS this entry's own case rather than strengthening it: FIUV's own +; [gloria] is [false] on all six of these exact dates in its window -- +; AGREEING WITH COLITUR, DIRECTLY CONTRADICTING the LMS Ordo's [true] +; above. So this is not \"colitur has a corroborated gap\", it is \"two +; independent Ordos disagree with EACH OTHER on Gloria for this shape, +; and colitur happens to agree with the universal one, not the diocesan +; one\". What FIUV's OWN Te Deum axis DOES show for the identical six +; dates: [true] -- Te Deum, unlike Gloria, genuinely IS said at Matins on +; these days (data/ef/expected-divergences-fiuv.sexp's own F3), a real, +; single-witness finding that this entry's own n.302(b)/431(b) citation +; may in fact belong to the DIVINE OFFICE, not the MASS -- which would +; mean L5 itself is answering the wrong question, not merely open. +; Genuinely uncertain which of the two Mass-Gloria witnesses (LMS or +; FIUV) is right for this shape; left OPEN, not adjudicated either way, +; for a follow-on task with more primary-source access than this one +; had. + +; L6 -- OPEN, root-caused to a DIFFERENT, PRE-EXISTING bug this Gloria +; comparison merely surfaced, not a Gloria defect itself. Fired once, +; 2023-2024 only (2024-05-06, Rogation Monday) -- absent from the other +; two windows because Rogation Monday/Tuesday is impeded by a real +; sanctoral feast in both of them, so the office's own colour never +; reaches [observed] there. Same non-machine-checked-count reasoning as L5 +; above (count 1/0/0); enforced by test_lms_ordo.ml's own +; [is_l6_rogation_colour] predicate and [make_suite]'s own +; ~expected_gloria_l6 parameter. +; +; {!Rite_ef.Temporal_ef.temporal}'s own Rogation Monday/Tuesday branch +; hardcodes [~colour:Colour.Violet] with NO RG citation at all (verified +; by reading the branch directly, temporal_ef.ml, the Rogation comment +; block). The Ordo shows 2024-05-06 as \"FERIA IV Cl W †\" (white), +; borrowing \"Mass of 5th Sunday after Easter\" (matching colitur's own +; [Mass_formulary.Preceding_sunday] resolution for the identical date) -- +; consistent with RG88 (Caput X, \"De Litaniis maioribus et minoribus\"): +; \"De Litaniis minoribus nihil fit in Officio, sed tantum in Missa\" -- +; nothing changes in the OFFICE for the Minor Litanies, only the Mass +; TEXT is proper, which reads as the Office's own colour (Paschaltide, +; white) staying unchanged, the violet belonging only to the PROCESSION +; that precedes the Mass -- the same PER-ACTION colour nuance this +; project already documents as unmodelled for Palm Sunday's palm +; procession and Good Friday's Communion rite (temporal_ef.ml's own RG126/ +; RG128 citations), not a new kind of gap. +; +; NOT FIXED HERE: out of this task's own scope (Gloria/Te Deum, not the +; temporal cycle's colour assignment), and a real fix needs its own +; measured blast radius across 1583-9999 (every Rogation Monday/Tuesday +; not impeded by a stronger feast) plus a re-check against the +; differential/oracle layers, which already treat Rogation days as +; correctly violet on whatever data they compare against -- a +; cross-layer question, not a one-line patch. Recommended as a follow-on +; task's own first item.") diff --git a/lib/kernel/calendar.ml b/lib/kernel/calendar.ml index db6c58e..7178780 100644 --- a/lib/kernel/calendar.ml +++ b/lib/kernel/calendar.ml @@ -551,6 +551,9 @@ let build_day (rite : ('s, 'r) Rite.t) (idx : 'r Layer.index) let creed = rite.Rite.creed ~temporal ~observed:resolution.Precedence.observed.Precedence.cel ~date in + let gloria = + rite.Rite.gloria ~temporal ~observed:resolution.Precedence.observed.Precedence.cel ~date + in { Liturgical_day.date; rite = rite.Rite.id; @@ -564,6 +567,7 @@ let build_day (rite : ('s, 'r) Rite.t) (idx : 'r Layer.index) citations; formulary; creed; + gloria; } let year (rite : ('s, 'r) Rite.t) (layer : 'r Layer.t) (y : int) : diff --git a/lib/kernel/liturgical_day.ml b/lib/kernel/liturgical_day.ml index 09ac0a1..98c5084 100644 --- a/lib/kernel/liturgical_day.ml +++ b/lib/kernel/liturgical_day.ml @@ -27,5 +27,6 @@ type ('s, 'r) t = { (** which Mass the day says, and how that was decided; [None] only for a rite with no lectionary -- see {!Mass_formulary} *) creed : bool; (** whether the Creed is said at this day's Mass; see {!Rite.t.creed} *) + gloria : bool; (** whether the Gloria in excelsis is said; see {!Rite.t.gloria} *) } [@@deriving sexp] diff --git a/lib/kernel/liturgical_day.mli b/lib/kernel/liturgical_day.mli index eb45e61..939f8f5 100644 --- a/lib/kernel/liturgical_day.mli +++ b/lib/kernel/liturgical_day.mli @@ -37,5 +37,9 @@ type ('s, 'r) t = { (** Whether the Creed is said at this day's Mass -- {!Rite.t.creed}, EF: RG 475-476. A decision, not an [option]: [false] for a rite that has not implemented the rule, same as [creed] itself. *) + gloria : bool; + (** Whether the Gloria in excelsis is said at this day's Mass -- + {!Rite.t.gloria}, EF: RG 431-432. Same seam as [creed] in every + respect. *) } [@@deriving sexp] diff --git a/lib/kernel/rite.ml b/lib/kernel/rite.ml index 738785a..915941d 100644 --- a/lib/kernel/rite.ml +++ b/lib/kernel/rite.ml @@ -20,4 +20,5 @@ type ('s, 'r) t = { temporal_at:(Date.t -> ('s, 'r) Temporal.t) -> Mass_formulary.t option * Citation.t list; creed : temporal:('s, 'r) Temporal.t -> observed:'r Celebration.t -> date:Date.t -> bool; + gloria : temporal:('s, 'r) Temporal.t -> observed:'r Celebration.t -> date:Date.t -> bool; } diff --git a/lib/kernel/rite.mli b/lib/kernel/rite.mli index 0dcf17e..b9d1961 100644 --- a/lib/kernel/rite.mli +++ b/lib/kernel/rite.mli @@ -134,4 +134,10 @@ type ('s, 'r) t = { 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. *) } diff --git a/lib/rites/rite_ef/rite_ef.ml b/lib/rites/rite_ef/rite_ef.ml index ba1274b..d7b3d83 100644 --- a/lib/rites/rite_ef/rite_ef.ml +++ b/lib/rites/rite_ef/rite_ef.ml @@ -51,4 +51,5 @@ let context ~lectionary ~commons : (Vocab_ef.season, Vocab_ef.rank) Rite.t = season_runs = Vocab_ef.seasons; transfer_target = Precedence_ef.transfer_target; readings = Lectionary_ef.readings ~lectionary ~commons; - creed = Rubrics_ef.creed } + creed = Rubrics_ef.creed; + gloria = Rubrics_ef.gloria } diff --git a/lib/rites/rite_ef/rite_ef.mli b/lib/rites/rite_ef/rite_ef.mli index a4b5d87..7025143 100644 --- a/lib/rites/rite_ef/rite_ef.mli +++ b/lib/rites/rite_ef/rite_ef.mli @@ -36,6 +36,9 @@ module Rubrics_ef = Rubrics_ef - [creed]: {!Rubrics_ef.creed}, RG 475-476 -- whether the Creed is said. The first rubric in this phase governing a part of Mass rather than occurrence/precedence. + - [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. 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 ab9da32..a497b57 100644 --- a/lib/rites/rite_ef/rubrics_ef.ml +++ b/lib/rites/rite_ef/rubrics_ef.ml @@ -319,3 +319,381 @@ let creed ~(temporal : (Vocab_ef.season, Vocab_ef.rank) Temporal.t) entry on the list (Sts Peter & Paul) is already [true] via 475(b), so this branch is redundant, never wrong, for those. *) List.mem slug creed_apostle_slugs + +(* Breviarium Romanum, 1961 Codex Rubricarum, "N) De hymno Te Deum" + (docs/research/breviary/rubricae-breviarii-1961.txt; docs/research/ + breviary/PROVENANCE.md has this source's own provenance and weakness in + full), quoted here in full so every branch below can cite its own + letter without re-quoting the whole rubric: + + "237. Hymnus Te Deum dicitur ad Matutinum, post ultimam lectionem, loco + noni vel tertii responsorii: + a) in dominica in albis, in dominica Pentecostes, et in Matutino + dominicae Resurrectionis, quod recitatur ab iis qui Vigiliae paschali + non interfuerunt; + b) in dominicis II classis, exceptis dominicis in Septuagesima, in + Sexagesima et in Quinquagesima; + c) in omnibus festis; + d) per octavas Nativitatis Domini, Paschatis et Pentecostes; + e) in Officio feriali temporis natalicii et temporis paschalis; + f) in vigiliis Ascensionis et Pentecostes; + g) in Officio sanctae Mariae in sabbato. + + 238. Omittitur vero hymnus Te Deum: + a) in Officiis de Tempore a dominica I Adventus usque ad vigiliam + Nativitatis Domini inclusive; et a dominica in Septuagesima usque ad + Sabbatum sanctum inclusive; + b) in vigiliis II et III classis, excepta vigilia Ascensionis + Domini; + c) in omnibus feriis per annum; + d) in Officio defunctorum." + + THE WEAKNESS, restated (PROVENANCE.md has the full account): this is a + SINGLE WEB TRANSCRIPTION (ceremoniaire.net), not yet checked against a + photographic scan -- the weakest-sourced rule in this project. Mitigated, + not resolved, by the FIUV universal Ordo's own Te Deum column + (test/fixtures/fiuv-ordo-2025-2026.sexp, 262 "Te Deum" rows out of 400 -- + an independent day-level witness, never itself derived from this + transcription) -- see test_fiuv_ordo.ml, which compares [te_deum]'s own + output against it. A mismatch there may indict this transcription rather + than [te_deum]; adjudicated per that file's own allow-list, not assumed + either way. + + SCOPE: this predicate exists ONLY because RG 431(a) below defers a MASS + question to it. Building it is not the Divine Office arriving in scope -- + CLAUDE.md's own "Divine Office remains out of scope" line, and the + 2026-08-21 design spec's own SS1, are both unchanged: this borrows ONE + Breviary FACT per day (whether Te Deum was said at Matins), never models + Matins/Vespers/the psalter/concurrence. *) +let te_deum ~(temporal : (Vocab_ef.season, Vocab_ef.rank) Temporal.t) + ~(observed : Vocab_ef.rank Celebration.t) ~(date : Date.t) : bool = + 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 + (* 238(d): "in Officio defunctorum" -- checked first, the same position + and the same {!Colour.Black} proxy [creed]'s own 476(f) branch uses + (this file's own header has the full argument for why colour is a + sound proxy for "this is a Requiem" on the shipped data, and + {!test_colour_black_population_is_exactly_two} in test_rubrics_ef.ml + is the SAME two-member population this predicate also depends on -- + no separate test needed). *) + observed.Celebration.colour = Colour.Black + then false + else if + (* 237(a): the three explicitly named Paschaltide days -- Easter + Sunday's own Matins (n=0), Low Sunday (n=7), Pentecost Sunday + (n=49). Pure Easter-offset arithmetic, the same style [creed]'s own + 475(d) uses and for the identical reason: season/rank alone cannot + express "this exact day", and nothing else in 237/238 names these + three individually. + + HISTORY WORTH KEEPING: this task's own FIRST pass REPLACED this + branch (and 237(b) below) with a blanket "every Sunday" rule, + having found what looked like a clean 15-for-15 FIUV Ordo + contradiction of 237(b)'s own Septuagesima/Sexagesima/Quinquagesima + exception. That evidence was ITSELF corrupted: tools/extract_fiuv_ + ordo.ml's own Te Deum parser recognised only ONE of the source's two + negative phrasings ("non dicitur Te Deum"), so every "sine Te Deum" + occurrence -- which is how the source actually negates a SUNDAY's + own Te Deum, found only by reading the raw pdftotext dump by hand, + not by trusting the fixture's own coverage counts -- fell through to + a bare "Te Deum" substring match and was wrongly recorded [true]. + Fixed in the extractor (see its own citation, tools/extract_fiuv_ + ordo.ml); the fixture was regenerated; 24 of the fixture's 400 rows + flipped, EVERY ONE true->false, EVERY ONE a day this branch or + 237(b) below governs. The blanket rule was reverted the moment the + corrected data confirmed the ORIGINAL literal reading instead: + 238(a)'s own window DOES silence Advent/Septuagesima/Lent/ + Passiontide Sundays after all. Left as a worked example, not + scrubbed from history: the failure mode was believing a clean- + looking oracle correlation over re-deriving the primary text, + exactly backwards from what "adjudicate, don't assume" should have + produced -- caught only by cross-checking the raw source directly + once the shape looked suspiciously total. *) + n = 0 || n = 7 || n = 49 + then true + else if + (* 237(f): the vigils of Ascension (n=38) and Pentecost (n=48), checked + BEFORE 238(b)'s general vigil omission below -- both are otherwise + reachable by it (Ascension's vigil is [Class2], squarely inside + 238(b)'s own "II et III classis"; Pentecost's is [Class1], RG 91 + entry 9, so 238(b) could never have reached it regardless, but is + named here anyway rather than left to fall through to 237(c), the + same "cite the specific clause, not a catch-all" discipline this + whole module holds to). *) + n = 38 || n = 48 + then true + else if + (* 237(d): the three privileged octaves -- reuses [creed]'s own three + windows verbatim (that function's own 475(d) comment has the full + citation and the argument for why a season- or rank-based test + would wrongly include the Ascension/Pentecost-Vigil days this + window must exclude). Overlaps 237(a) at n=0/7/49 -- redundant, not + wrong, the same "never the FIRST branch to grant those [true]" + pattern 475(b) documents for I-class Sundays. *) + (m = 12 && dd >= 25 && dd <= 31) + || (m = 1 && dd = 1) + || (n >= 0 && n <= 7) + || (n >= 49 && n <= 56) + then true + else if + (* 238(b): "vigiliis II et III classis" -- {!Precedence_ef.is_omissible_vigil} + is exactly this rank test (Class2 or Class3), reused rather than + re-derived, paired with {!Precedence_ef.is_vigil} the same way + [creed]'s own RG 28-34 branch already pairs them. The Ascension + vigil (237(f) above, already [true]) can never reach this branch; + the four sanctoral vigils (StJohnBaptist, SsPeter&Paul, StLawrence, + the Assumption -- {!Precedence_ef.vigil_feast_table}'s own + population) are exactly what this branch excludes. *) + Precedence_ef.is_omissible_vigil observed.Celebration.rank && Precedence_ef.is_vigil slug + then false + else if + (* NOT 238(b)'s own text (which names only "II et III classis"): the + Nativity Vigil ([Class1], RG 91 entry 5) is excluded here on the + SAME RG 21/35 taxonomy argument [creed]'s own RG 28-34 comment + already makes for the Paschal Vigil -- "vigilia" is its own + liturgical-day category, distinct from "festum", regardless of + class; RG 30's "beyond losing" is a PRECEDENCE exemption (nothing + lesser can displace it), not a claim that a vigil IS a festum for + Breviary purposes. Flagged honestly as an INFERENCE, not a literal + 238(b) citation -- checked against the FIUV Ordo's own Te Deum + marker for 24 December in test_fiuv_ordo.ml, since this is exactly + the shape a transcription gap could get wrong either direction. *) + Precedence_ef.is_vigil slug + then false + else if + (* 238(c)/RG 23: Ash Wednesday and every feria of Holy Week, the Sacred + Triduum included -- reuses [creed]'s own RG 23 test verbatim (that + function's own comment has the full citation and the argument for + why this excludes feria I classis specifically, not ferias in + general). *) + n = -46 || (n >= -6 && n <= -1) + then false + else if + (* 237(b): "in dominicis II classis, exceptis dominicis in Septuagesima, + in Sexagesima et in Quinquagesima" -- colitur's own single + [Septuagesima] season covers exactly those three Sundays (see + [season_colour]'s own grouping, temporal_ef.ml), so the exception is + one season-equality test. RE-VERIFIED, not merely restored: the + corrected FIUV extraction (237(a)'s own comment above has the full + account) shows all three Septuagesima-season Sundays [false], and + every OTHER, ordinary Class2 Sunday the fixture's window reaches + [true] -- exactly this clause's own literal text, no correction + needed here after all. Reads [temporal.weekday]/[.season], not + [observed]'s slug: unlike [creed]'s own 475(a), the Breviary's text + carries NO "even when a feast displaces the Sunday's own Office" + exception -- when a feast genuinely takes the Sunday's place (RG + 16(a)), Matins says the FEAST's own Office, and 237(c) below decides + it on the feast's own terms, not this clause. Advent/Lent/ + Passiontide Sundays are [Class1], never [Class2] ([creed]'s own RG + 11-12 citation, temporal_ef.ml), so this guard correctly excludes + them without a separate season check; [observed.rank], not + [temporal]'s own season-derived rank, is read here on purpose, for + the same RG 16(a) reason [Precedence.rules.admit]'s own + [~temporal] parameter exists: a feast that wins the day can carry a + DIFFERENT rank than the Sunday it displaced. *) + temporal.Temporal.weekday = Date.Sun + && observed.Celebration.rank = Vocab_ef.Class2 + && temporal.Temporal.season <> Vocab_ef.Septuagesima + then true + else if + (* 237(g): the votive Office of the BVM on Saturday, RG 78/91 entry 27 + -- {!Temporal_ef}'s own [subject = Bvm]/[Class4] pairing, the same + shape [creed]'s own 476(d) comment and the register's RG 112(d) fix + already establish as unique to this office (every OTHER + [subject = Bvm] candidate in the shipped data is [Commemoration_only] + and can therefore never be [observed]). *) + observed.Celebration.subject = Subject.Bvm && observed.Celebration.rank = Vocab_ef.Class4 + then true + else if + (* 237(e): "Officio feriali temporis natalicii et temporis paschalis" -- + every remaining (non-octave, non-vigil, non-BVM-Saturday) FERIA of + Christmastide or Paschaltide: the 2-5 January ferias, and the + ordinary weeks of Paschaltide (Rogation Monday/Tuesday included). + [temporal.weekday <> Sun] keeps this to FERIAS only, matching the + clause's own "Officio FERIALI" text; a Sunday in either season is + already [true] via the Sunday rule above regardless, so this guard + changes no OUTCOME, only which clause gets credit for it. *) + (temporal.Temporal.season = Vocab_ef.Christmastide + || temporal.Temporal.season = Vocab_ef.Paschaltide) + && temporal.Temporal.weekday <> Date.Sun + then true + else + (* 237(c): "in omnibus festis" -- every remaining genuine festum. By + this point every named Paschaltide day, every ordinary Sunday + (Class2, outside Septuagesima), every vigil, every feria I classis, + every Christmastide/Paschaltide feria and every BVM Saturday Office + has already been excluded or granted above, so what reaches here is + exactly: {!Temporal_ef.named}'s remaining population + (Epiphany, Ascension, Corpus Christi, the Sacred Heart, Christ the + King -- tested by PRESENCE in that table, since every [named] entry + carries [subject = Temporal] like any other, see [creed]'s own + 475(c) comment); and every genuine sanctoral feast actually observed + ([subject = Saint], or one of the handful of [subject = Lord]/[Bvm] + entries -- Holy Family, Holy Name of Jesus, the six [Lord]-tagged + sanctoral feasts, [most-holy-name-of-mary] -- [creed]'s own 475(c) + comment has the full census). The two ferial exceptions that ALSO + carry [Lord]/[Bvm] (the Sacred Triduum, the BVM Saturday Office) are + unreachable here: both were already excluded above (feria I + classis; 237(g)). + + [Temporal_ef.named]'s FIRST disjunct EXCLUDES Passion Sunday and + Palm Sunday BY THEIR OWN SLUG -- not by [temporal.weekday <> Sun], + which a first pass of this fix tried and had to REVERT: Christ the + King is ALSO always a Sunday (its own [christ_the_king] anchor + IS "the last Sunday of October"), [Class1] like Passion/Palm + Sunday, so a blanket weekday guard wrongly excluded it too -- + caught immediately by the LMS Ordo's own Gloria axis + (2024-10-27, "colitur gloria=false, Ordo gloria=true"), a + regression a same-session review round found before this task + closed. Passion Sunday and Palm Sunday are excluded because + neither is a genuine "festum" (RG 35's own taxonomy makes + "dominica" its own category, distinct from "festum") -- {!Temporal_ + ef.named} carries them anyway (RG 91 entry 6, for its own + occurrence-table reasons), so without SOME exclusion both would + wrongly reach [true] here BY ACCIDENT of table membership -- + confirmed wrong directly against the corrected FIUV extraction + (237(a)'s own comment above has the full account of the extractor + bug this was found alongside): both dates are [false] in the + source. Epiphany, Ascension, Corpus Christi, the Sacred Heart and + Christ the King -- {!Temporal_ef.named}'s only OTHER population -- + are genuine festa and must NOT be excluded, which is exactly why + the exclusion is two named slugs, not a day-of-week predicate. The + SECOND disjunct (subject) carries no such guard: a genuine feast + that has fully displaced a Sunday's own Office (RG16(a)) still + deserves 237(c)'s grant on the FEAST's own terms, regardless of + what day of the week it falls on. + + A plain, unnamed weekday feria (no Sunday, no vigil, no octave, + [named] = [None], [subject = Temporal]) correctly falls through to + [false] here -- 238(c)'s own "in omnibus feriis". *) + (Temporal_ef.named date <> None && slug <> "ef-passion-sunday" && slug <> "ef-palm-sunday") + || observed.Celebration.subject = Subject.Saint + || observed.Celebration.subject = Subject.Lord + || observed.Celebration.subject = Subject.Bvm + +(* Missale Romanum, Rubricae Generales, Caput XVII("De Ritibus servandis in + celebratione Missae"), "C) De hymno Glória in excélsis" (docs/research/ + LT.txt, grep "Hymnus Glória"), quoted here in full: + + "431. Hymnus Gloria in excelsis dicitur: + a) in Missis quae respondent Officio diei, quotiescumque ad + Matutinum dictus est hymnus Te Deum; + b) in Missis festivis de quibus n. 302; + c) in Missis feriae V in Cena Domini, et in Missa Vigiliae + paschalis; + d) in Missis votivis I, II et III classis, nisi adhibeatur color + violaceus paramentorum; + e) in Missis votivis IV classis de Angelis, quocumque die, et de B. + Maria Virg. quae in sabbato celebrantur. + + 432. Hymnus Gloria in excelsis omittitur: + a) in Missis quae respondent Officio diei, quando ad Matutinum + omittitur hymnus Te Deum; + b) in omnibus Missis in quibus adhibetur color violaceus + paramentorum; + c) in Missis votivis IV classis, iis exceptis de quibus n. 431 e; + d) in Missis defunctorum." + + SCOPE NOTE, checked once here rather than at every clause, the same + discipline [creed]'s own header uses: this engine resolves ONE Mass per + civil day (Rite.t.readings' own doc comment) -- it has no separate + "which votive Mass is said" dimension. n. 301-303 (LT.txt, immediately + above 431), quoted in substance: 301 defines "Missa de festo" in the + NARROW sense as the Mass of the day's own Office -- exactly what + [Rite_ef.Lectionary_ef.readings] already resolves for every day, + including a BORROWED formulary (a weekday resuming the preceding + Sunday's Mass, a saint using his assigned Common): still "the Mass which + corresponds to the day's own Office" in 431(a)/432(a)'s own sense, so + 431(a)/432(a) alone already cover it. 302's WIDER sense -- (a) a + III-class feast's own Mass said despite being impeded by another + III-class feast, (b) a commemoration's own Mass said in place of the + day's Office, (c) a saint's Mass said on his Martyrology elogium day -- + are all cases of a DIFFERENT Mass than the day's own resolved Office + being said, which this engine does not model; 431(b) is therefore + genuinely N/A, not merely unread. 431(d)/(e) and 432(c) are about VOTIVE + MASS CLASSES (I-IV), a dimension this engine has no field for at all -- + also N/A, EXCEPT 431(e)'s own "de B. Maria Virg. quae in sabbato + celebrantur" half: colitur does not model that Office as a votive Mass + (it has no votive-Mass dimension to model it AS), it models it as an + ORDINARY Office (RG 78's own text, [te_deum]'s own 237(g) branch above), + so its Gloria is produced as a side effect of 431(a) reading [te_deum], + not by a dedicated 431(e) branch -- checked directly: [te_deum]'s 237(g) + branch is unconditional (not colour-gated), and this Office's own colour + is white (never violet), so 432(b) below can never suppress it either. + 431(e)'s "de Angelis" half (the votive Mass of the Angels) has no data + in this engine at all and stays N/A. *) +let gloria ~(temporal : (Vocab_ef.season, Vocab_ef.rank) Temporal.t) + ~(observed : Vocab_ef.rank Celebration.t) ~(date : Date.t) : bool = + let easter = Computus.gregorian_easter (Date.year date) in + let n = Date.to_rata date - Date.to_rata easter in + if + (* 432(d): "in Missis defunctorum" -- checked first, the same + {!Colour.Black} proxy [creed]'s own 476(f) and [te_deum]'s own + 238(d) branch both use. Correctly also excludes Good Friday + (n=-2, [Colour.Black], temporal_ef.ml's own RG 132 citation) -- + which has no Mass at all in the 1955-restored Holy Week, so the + question is moot there regardless; the same "belt and braces" + stance [creed]'s own 476(f) comment takes for the identical day. *) + observed.Celebration.colour = Colour.Black + then false + else if + (* 431(c): "in Missis feriae V in Cena Domini, et in Missa Vigiliae + paschalis" -- Holy Thursday (n=-3) and the Easter Vigil Mass (n=-1, + Holy Saturday's own date). Checked BEFORE 432(b)'s general violet + exclusion below and before [te_deum] is ever read: this clause is + lex specialis over both. It must outrank 432(b) specifically + because colitur's own per-day colour model gives Holy Saturday + [Colour.Violet] (Passiontide's [season_colour], temporal_ef.ml -- + the historical vestment change from violet to white happens AT the + Gloria itself, a per-action nuance this whole day/colour model + already cannot express, the same acknowledged gap RG 126's palm + procession and RG 128's Good Friday Communion carry, temporal_ef.ml's + own citations) -- without this clause checked first, 432(b) would + wrongly silence the one Mass whose own Gloria is historically + unmistakable (the bells and organ restored at the Vigil). It must + also outrank [te_deum]: neither day's own Matins says Te Deum + (both are governed by [te_deum]'s own feria-I-classis exclusion, + n=-46/[-6,-1], the Sacred Triduum included), so without this + explicit override the Gloria would be wrongly silenced there too. *) + n = -3 || n = -1 + then true + else if + (* 432(b): "in omnibus Missis in quibus adhibetur color violaceus + paramentorum" -- independent and colour-keyed, exactly as the task + brief states; NOT a substitute for [te_deum] below, which still + decides every Mass this clause does not itself silence. Genuinely + unconditional ("in omnibus Missis") -- checked directly against + every violet day in the domain-wide sweep (see the module's own + test file), never merely assumed. + + [Colour.Rose] found and DELIBERATELY NOT added here, a real + "checked, then reverted" episode kept for the record: a first pass + of this task, WHILE the (since-reverted) blanket "every Sunday + says Te Deum" mutation to [te_deum] was in place, found Gaudete + and Laetare ([is_rose_sunday]) wrongly getting [gloria]=true and + fixed it by unioning [Colour.Rose] into this branch. Once + [te_deum] reverted to 237(b)'s own literal [Class2] guard, the + fix became REDUNDANT, not merely coincidentally silent: Rose can + ONLY ever colour a Sunday of Advent or Lent + ({!Temporal_ef.is_rose_sunday}'s own two cases), and EVERY Sunday + of Advent or Lent is [Class1] BY CONSTRUCTION + ({!Temporal_ef.temporal}'s own [match s with Advent | Lent -> + Class1 | _ -> Class2]) -- a structural guarantee, not a + coincidence of the shipped data, so [te_deum]'s own [Class2] guard + ALREADY excludes every Rose day before this branch is ever + reached. Verified, not assumed: removing this branch's own Rose + arm and re-running the full suite (including the two LMS dates, + 2023-12-17 and 2024-03-10, this finding was originally pinned + against) left every test green. Left out rather than kept as + dead code that would misleadingly read as load-bearing. *) + observed.Celebration.colour = Colour.Violet + then false + else + (* 431(a)/432(a): "in Missis quae respondent Officio diei, + quotiescumque/quando... Te Deum [dictus est/omittitur]" -- the + 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 diff --git a/lib/rites/rite_ef/rubrics_ef.mli b/lib/rites/rite_ef/rubrics_ef.mli index 7a1284b..618af65 100644 --- a/lib/rites/rite_ef/rubrics_ef.mli +++ b/lib/rites/rite_ef/rubrics_ef.mli @@ -38,3 +38,33 @@ val creed : observed:Vocab_ef.rank Celebration.t -> date:Date.t -> bool + +(** Whether the Te Deum was said at Matins (Breviary 1961 Codex Rubricarum + nn. 237-238) -- NOT the Divine Office arriving in scope, but a single + Breviary fact {!gloria}'s own RG 431(a) defers a Mass question to. See + the .ml's own header for the rubric quoted in full, every branch's own + citation, and this source's own stated weakness (a single, not yet + scan-verified, web transcription -- docs/research/breviary/PROVENANCE.md). + Same three parameters as {!creed}, for the same reasons: [temporal] for + the day's own weekday/season, [observed] for the celebration whose + Office is actually kept, [date] for the Easter-relative window + questions. *) +val te_deum : + temporal:(Vocab_ef.season, Vocab_ef.rank) Temporal.t -> + observed:Vocab_ef.rank Celebration.t -> + date:Date.t -> + bool + +(** Whether the Gloria in excelsis is said at this day's Mass (RG 431-432). + 431(a)/432(a) defer to {!te_deum}; 431(c) (Holy Thursday, the Easter + Vigil Mass) and 432(b)/(d) (violet vestments; a Requiem) are + independent overrides, checked ahead of the Te Deum-derived answer -- + see the .ml's own header for the full account, including which of + 431/432's own clauses this engine has no votive-Mass-class dimension to + implement and are therefore marked not-applicable rather than silently + skipped. *) +val gloria : + temporal:(Vocab_ef.season, Vocab_ef.rank) Temporal.t -> + observed:Vocab_ef.rank Celebration.t -> + date:Date.t -> + bool diff --git a/man/colitur.1 b/man/colitur.1 index 09414ea..88c5fab 100644 --- a/man/colitur.1 +++ b/man/colitur.1 @@ -122,12 +122,13 @@ occurrence, commemoration and transfer. The Mass reading citations, one line per day. .TP .BI rubrics " YEAR" -Two rubrics of the Mass, one line per day: which formulary is actually +Three rubrics of the Mass, one line per day: which formulary is actually said \(em not always the day's own: a weekday with no proper resumes the preceding Sunday's, a saint with no proper says his assigned Common, and RG 78/309(a)'s votive Saturday Mass of Our Lady is said in place of an -unoccupied office's own \(em and whether the Creed is said (RG 475\-476). -See +unoccupied office's own \(em whether the Creed is said (RG 475\-476), and +whether the Gloria in excelsis is said (RG 431\-432, deferring to the +Breviary's own Te Deum rule, nn. 237\-238, for RG 431(a)). See .B OUTPUT FORMAT below. .TP @@ -460,12 +461,13 @@ own trailing field, above. .SS rubrics .RS .nf -date [TAB] formulary\-slug [TAB] source [TAB] creed +date [TAB] formulary\-slug [TAB] source [TAB] creed [TAB] gloria .fi .RE .PP The day's own Mass formulary (which slug's Mass is actually said, and how -that was decided), followed by whether the Creed is said (RG 475\-476). +that was decided), followed by whether the Creed is said (RG 475\-476) and +whether the Gloria in excelsis is said (RG 431\-432). .B rubrics separates its fields with a literal TAB \(em not a plain space like .B day @@ -489,7 +491,9 @@ leave it unsplittable by field number. is one of .BR proper ", " own ", " preceding\-sunday ", " common " or " votive . .I creed -is +and +.I gloria +are each .B true or .B false @@ -498,15 +502,15 @@ or or .RB \(lq 1/0 \(rq : this row has no other boolean field to be consistent with). A day with no -Mass at all for a rite that has not implemented the rule reads +Mass at all for a rite that has not implemented a rule reads .B false outright \(em it is a decision, never a third \(lqunknown\(rq state. .RS .nf -2026\-01\-01 [TAB] ef\-circumcision [TAB] own [TAB] true -2038\-03\-08 [TAB] john\-of\-god [TAB] proper [TAB] false -2025\-12\-01 [TAB] ef\-advent\-sunday\-1 [TAB] preceding\-sunday [TAB] false +2026\-01\-01 [TAB] ef\-circumcision [TAB] own [TAB] true [TAB] true +2038\-03\-08 [TAB] john\-of\-god [TAB] proper [TAB] false [TAB] true +2025\-12\-01 [TAB] ef\-advent\-sunday\-1 [TAB] preceding\-sunday [TAB] false [TAB] false .fi .RE .PP diff --git a/test/cli.t b/test/cli.t index 5bf8d83..8bd5b9f 100644 --- a/test/cli.t +++ b/test/cli.t @@ -210,9 +210,9 @@ separate command for the same mechanical reason `readings` is: `day`'s row is fixed-width space-separated with a variable-length "+slug" tail. $ colitur rubrics 2026 | head -3 - 2026-01-01 ef-circumcision own true - 2026-01-02 ef-christmas-1-friday own false - 2026-01-03 ef-christmas-1-saturday votive false + 2026-01-01 ef-circumcision own true true + 2026-01-02 ef-christmas-1-friday own false true + 2026-01-03 ef-christmas-1-saturday votive false true $ colitur rubrics 2026 | wc -l 365 @@ -224,19 +224,19 @@ apply to it -- step 2 does (the day's own temporal slug in the lectionary), tagged `own`. Contrast a real sanctoral saint with his own proper: $ colitur rubrics 2038 | grep '^2038-03-08' - 2038-03-08 john-of-god proper false + 2038-03-08 john-of-god proper false true A saint with no proper of his own says his assigned Common (step 4): $ colitur rubrics 2038 | grep '^2038-03-06' - 2038-03-06 common-of-non-virgins-1 common false + 2038-03-06 common-of-non-virgins-1 common false true A weekday with no proper of its own resumes the preceding Sunday's, never its own observed slug -- 1 December 2025 is the Monday after Advent I, and Advent's ferias have no Mass of their own (step 3): $ colitur rubrics 2025 | grep '^2025-12-01' - 2025-12-01 ef-advent-sunday-1 preceding-sunday false + 2025-12-01 ef-advent-sunday-1 preceding-sunday false false 3 January 2026 above ("votive") is the RG 78/309(a) Saturday Mass of Our Lady, said IN PLACE of the day's own office's Mass while the office (an @@ -257,9 +257,9 @@ diocesan overlay's local patron observed instead (no proper or Common of his own in the fixture), the chain falls all the way back to step 3: $ colitur rubrics 2026 --overlay fixtures/overlay-example-diocesan.sexp | grep '^2026-07-11' - 2026-07-11 ef-time-after-pentecost-sunday-6 preceding-sunday false + 2026-07-11 ef-time-after-pentecost-sunday-6 preceding-sunday false true $ colitur rubrics 2026 | grep '^2026-07-11' - 2026-07-11 ef-time-after-pentecost-6-saturday votive false + 2026-07-11 ef-time-after-pentecost-6-saturday votive false true `--lang`/`--raw`/`--sigla-*` are refused rather than silently ignored, unlike `readings`: this row resolves no display name and no citation for any of @@ -343,13 +343,13 @@ prints for the identical day, so the two cannot silently drift apart again in either direction: $ colitur --help | grep '^ rubrics date' - rubrics date, formulary slug, source, creed -- TAB-separated + rubrics date, formulary slug, source, creed, gloria -- TAB-separated $ colitur --help | sed -n '/^ rubrics date/{n;p}' - 2026-01-01[TAB]ef-circumcision[TAB]own[TAB]true + 2026-01-01[TAB]ef-circumcision[TAB]own[TAB]true[TAB]true $ colitur rubrics 2026 | grep '^2026-01-01' | sed $'s/\t/[TAB]/g' - 2026-01-01[TAB]ef-circumcision[TAB]own[TAB]true + 2026-01-01[TAB]ef-circumcision[TAB]own[TAB]true[TAB]true --version prints the version alone, to standard output, exit 0. Deliberately not embedded in the help text above: this pin would then have to be edited @@ -573,10 +573,24 @@ across many lines' own wrap points, not just the days whose DATA changed -- confirmed directly (diffed the full sexp output line by line): every difference is exactly this [said] shape change or a consequent wrap shift, nothing else. Not a claim that [emit]'s FORMAT changed, only that -individual records' pretty-printed SHAPE did: +individual records' pretty-printed SHAPE did. + +9025 -> 9197 (Gloria, celebrant-rubrics-phase1 Phase 2): {!Liturgical_day.t} +gained a [gloria] field, the same seam [creed] already used -- [emit +--format sexp] dumps the whole record ({!Sexplib.Sexp.to_string_hum} over +[Liturgical_day.sexp_of_t]) unlike [csv]/[json]/[xml] (a curated +[View]/[Record] projection that has never included [creed] either, hence +their own line counts above are UNCHANGED by this task -- confirmed by +this cram file's own diff touching only the [sexp] count). All 365 of +2027's records print a new [(gloria )] token (checked directly, +[grep -c gloria]), but the wrap-point mechanics are the same cosmetic +reflow the two entries above describe, not a fixed one-line-per-record +addition: 2027-01-01's own record wraps [gloria] onto its own new line, +while 2027-01-02's fits it on the same line as [creed] and [formulary] -- +172 of 365 records happened to cross a wrap boundary, the rest did not. $ colitur emit --format sexp --from 2027 --to 2027 | wc -l - 9025 + 9197 $ colitur emit --format xml --from 2027 --to 2027 | head -2 diff --git a/test/fixtures/fiuv-ordo-2025-2026.sexp b/test/fixtures/fiuv-ordo-2025-2026.sexp index 7b72ca3..d31c5d5 100644 --- a/test/fixtures/fiuv-ordo-2025-2026.sexp +++ b/test/fixtures/fiuv-ordo-2025-2026.sexp @@ -97,7 +97,24 @@ ; ; MEASURED DISTRIBUTION (this extraction, not the brief's figures): Gloria ; true=269 false=130 unresolved=1; Credo true=116 false=283 unresolved=1; -; Te Deum true=231 false=42 unresolved=127. +; Te Deum true=207 false=66 unresolved=127. +; +; RE-EXTRACTED (celebrant-rubrics-phase1 Phase 2, 2026-08-22): the FIRST +; extraction's own Te Deum parser recognised only ONE of the source's two +; negative phrasings ("non dicitur Te Deum") -- "sine Te Deum" (how the +; source actually negates a SUNDAY's own Te Deum, among others) fell +; through to a bare "Te Deum" substring match and was wrongly read +; [true]. Found by hand, comparing the raw pdftotext dump against this +; fixture's own values directly, not by any coverage check (both counted +; the same 127 unresolved rows before and after). Fixed in +; tools/extract_fiuv_ordo.ml's own [extract_te_deum] (see its own +; citation); this fixture re-extracted from the SAME pdftotext dump +; (SHA-256 of the source PDF unchanged, above). 24 of 400 rows changed, +; every one Te Deum true->false, every one independently confirmed +; against the raw text: true 231->207, false 42->66, unresolved 127 +; unchanged. See lib/rites/rite_ef/rubrics_ef.ml's own [te_deum] header +; (237(a)'s comment) for the full account of what this corrected, and +; the .superpowers task report for the complete before/after date list. (((date 2025-11-27) (class_ ("IV cl.")) (title "Vir Feria V post Dom. XXIV & Ultima post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) @@ -109,7 +126,7 @@ (title "Alb Sabb. S. Maria in Sabbato,") (te_deum (true)) (gloria (true)) (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147"))) ((date 2025-11-30) (class_ ("I cl.")) - (title "Viol DOM. I ADVENTUS, De ea,") (te_deum (true)) (gloria (false)) + (title "Viol DOM. I ADVENTUS, De ea,") (te_deum (false)) (gloria (false)) (credo (true)) (praef ("Trinit. Ad II"))) ((date 2025-12-01) (class_ ("III cl.")) (title "Viol Feria II post Dom. I Adventus, De ea,") (te_deum ()) @@ -134,8 +151,8 @@ (gloria (true)) (credo (false)) (praef ("comm. Sabbatum primum in mense. I"))) ((date 2025-12-07) (class_ ("I cl.")) - (title "Viol DOM. II ADVENTUS, De ea,") (te_deum (true)) (gloria (false)) - (credo (true)) (praef ("Trinit. Ad II"))) + (title "Viol DOM. II ADVENTUS, De ea,") (te_deum (false)) + (gloria (false)) (credo (true)) (praef ("Trinit. Ad II"))) ((date 2025-12-08) (class_ ("I cl.")) (title "Alb Feria II. IN CONCEPTIONE IMMACULATA B. MARIAE VIRGINIS,") (te_deum ()) (gloria (true)) (credo (true)) @@ -156,7 +173,7 @@ (title "Rub Sabb. S Luciae Virg. et Mart.,") (te_deum (true)) (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. I"))) ((date 2025-12-14) (class_ ("I cl.")) - (title "Viol/ DOM. III ADVENTUS (GAUDETE), De ea,") (te_deum (true)) + (title "Viol/ DOM. III ADVENTUS (GAUDETE), De ea,") (te_deum (false)) (gloria (false)) (credo (true)) (praef ("Trinit. Ad II"))) ((date 2025-12-15) (class_ ("III cl.")) (title "Viol Feria II post Dom. III Adventus (Gaudete), De ea,") @@ -180,8 +197,8 @@ (praef ("comm. \226\128\147 Quoad Flectamus genua vide RM 440. Quoad lectiones vide RM 468. I"))) ((date 2025-12-21) (class_ ("I cl.")) - (title "Viol DOM. IV ADVENTUS, De ea,") (te_deum (true)) (gloria (false)) - (credo (true)) (praef ("Trinit. Ad II"))) + (title "Viol DOM. IV ADVENTUS, De ea,") (te_deum (false)) + (gloria (false)) (credo (true)) (praef ("Trinit. Ad II"))) ((date 2025-12-22) (class_ ("II cl.")) (title "Viol FERIA II POST DOM. IV ADVENTUS, De ea,") (te_deum ()) (gloria (false)) (credo (false)) (praef (comm.))) @@ -189,7 +206,7 @@ (title "Viol FERIA III POST DOM. IV ADVENTUS, De ea,") (te_deum ()) (gloria (false)) (credo (false)) (praef (comm.))) ((date 2025-12-24) (class_ ("I cl.")) - (title "Viol Feria IV. VIGILIA NATIVITATIS DOMINI,") (te_deum (true)) + (title "Viol Feria IV. VIGILIA NATIVITATIS DOMINI,") (te_deum (false)) (gloria (false)) (credo (false)) (praef ("comm. I"))) ((date 2025-12-25) (class_ ("I cl.")) (title "Alb Feria V. IN NATIVITATE DOMINI,") (te_deum ()) (gloria (true)) @@ -331,7 +348,7 @@ (title "Alb Sabb. S Ioannis Bosco Conf.,") (te_deum (true)) (gloria (true)) (credo (false)) (praef ("comm. I"))) ((date 2026-02-01) (class_ ("II cl.")) - (title "Viol DOM. SEPTUAGESIMAE, De ea,") (te_deum (true)) + (title "Viol DOM. SEPTUAGESIMAE, De ea,") (te_deum (false)) (gloria (false)) (credo (true)) (praef ("Trinit. II"))) ((date 2026-02-02) (class_ ("II cl.")) (title "Alb Feria II. IN PURIFICATIONE B. MARIAE VIRG.,") (te_deum ()) @@ -354,8 +371,8 @@ (title "Alb Sabb. S Romualdi Abb.,") (te_deum (true)) (gloria (true)) (credo (false)) (praef ("comm. Sabbatum primum in mense. I"))) ((date 2026-02-08) (class_ ("II cl.")) - (title "Viol DOM. SEXAGESIMAE, De ea,") (te_deum (true)) (gloria (false)) - (credo (true)) (praef ("Trinit. II"))) + (title "Viol DOM. SEXAGESIMAE, De ea,") (te_deum (false)) + (gloria (false)) (credo (true)) (praef ("Trinit. II"))) ((date 2026-02-09) (class_ ("III cl.")) (title "Alb Feria II. S Cyrilli Ep. Alexandrini, Conf. et Eccl. Doct.,") (te_deum (true)) (gloria (true)) (credo (false)) @@ -379,7 +396,7 @@ (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147"))) ((date 2026-02-15) (class_ ("II cl.")) - (title "Viol DOM. QUINQUAGESIMAE, De ea,") (te_deum (true)) + (title "Viol DOM. QUINQUAGESIMAE, De ea,") (te_deum (false)) (gloria (false)) (credo (true)) (praef ("Trinit. II"))) ((date 2026-02-16) (class_ ("IV cl.")) (title "Viol Feria II Dom. Quinquagesimae, De ea,") (te_deum ()) @@ -403,7 +420,7 @@ (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum. I"))) ((date 2026-02-22) (class_ ("I cl.")) - (title "Viol DOM. I QUADRAGESIMAE, De ea,") (te_deum (true)) + (title "Viol DOM. I QUADRAGESIMAE, De ea,") (te_deum (false)) (gloria (false)) (credo (true)) (praef ("Quadr. II"))) ((date 2026-02-23) (class_ ("III cl.")) (title "Viol Feria II post Dom. I Quadragesimae, De ea,") (te_deum ()) @@ -428,7 +445,7 @@ (praef ("Quadr., or. super populum. \226\128\147 Quoad Flectamus genua vide RM 440. Quoad lectiones vide RM 468. I"))) ((date 2026-03-01) (class_ ("I cl.")) - (title "Viol DOM. II QUADRAGESIMAE, De ea,") (te_deum (true)) + (title "Viol DOM. II QUADRAGESIMAE, De ea,") (te_deum (false)) (gloria (false)) (credo (true)) (praef ("Quadr. II"))) ((date 2026-03-02) (class_ ("III cl.")) (title "Viol Feria II post Dom. II Quadragesimae, De ea,") (te_deum ()) @@ -451,7 +468,7 @@ (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum. Sabbatum primum in mense. I"))) ((date 2026-03-08) (class_ ("I cl.")) - (title "Viol DOM. III QUADRAGESIMAE, De ea,") (te_deum (true)) + (title "Viol DOM. III QUADRAGESIMAE, De ea,") (te_deum (false)) (gloria (false)) (credo (true)) (praef ("Quadr. II"))) ((date 2026-03-09) (class_ ("III cl.")) (title "Viol Feria II post Dom. III Quadragesimae, De ea,") @@ -475,7 +492,7 @@ (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum. I"))) ((date 2026-03-15) (class_ ("I cl.")) - (title "Viol/ DOM. IV QUADRAGESIMAE (LAETARE), De ea,") (te_deum (true)) + (title "Viol/ DOM. IV QUADRAGESIMAE (LAETARE), De ea,") (te_deum (false)) (gloria (false)) (credo (true)) (praef ("Quadr. II"))) ((date 2026-03-16) (class_ ("III cl.")) (title "Viol Feria II post Dom. IV Quadragesimae (Laetare), De ea,") @@ -503,8 +520,8 @@ (te_deum (true)) (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum. I"))) ((date 2026-03-22) (class_ ("I cl.")) - (title "Viol DOM. I PASSIONIS, De ea,") (te_deum (true)) (gloria (false)) - (credo (true)) (praef ("de Sancta Cruce. II"))) + (title "Viol DOM. I PASSIONIS, De ea,") (te_deum (false)) + (gloria (false)) (credo (true)) (praef ("de Sancta Cruce. II"))) ((date 2026-03-23) (class_ ("III cl.")) (title "Viol Feria II post Dom. I Passionis, De ea,") (te_deum ()) (gloria (false)) (credo (false)) @@ -533,7 +550,7 @@ ((date 2026-03-29) (class_ ("I cl.")) (title "Rub in Officio, Rub. ad Bened. ramorum et in Processione, Viol. in Missa. DOM. IN PALMIS, De ea,") - (te_deum (true)) (gloria (false)) (credo (true)) + (te_deum (false)) (gloria (false)) (credo (true)) (praef ("de Sancta Cruce. \194\171Asperges\194\187 omittitur. \226\128\147 Benedictio palmorum et processio ante missam principalem celebrandae sunt. \226\128\147 Orationes praeparatoriae omittuntur. \226\128\147 Evangelium de passione secundum S Matthiam 26, 36-75; 27,1-60 legitur. Munda cor dicitur, celebrans autem (vel diaconus chronista) signum crucis nec super libro nec super se facit, necque librum osculatur, necque Laus tibi Domine dicit. \226\128\147 Evangelium finale omittitur. \226\128\147 In Missis sine processione, legitur in fine Evangelium Cum appropinquasset de benedictione ramorum. Sacerdotibus plures quam unam missam dicentibus licet Evangelium S Matthi\195\166 27, 45-52 legere potius quam Evangelium Passionis. II"))) ((date 2026-03-30) (class_ ("I cl.")) @@ -858,7 +875,7 @@ (gloria (true)) (credo (false)) (praef (comm.))) ((date 2026-06-23) (class_ ("II cl.")) (title "Viol Feria III. VIGILIA NATIVITATIS S IOANNIS * BAPTISTAE,") - (te_deum (true)) (gloria (false)) (credo (false)) (praef ("comm. I"))) + (te_deum (false)) (gloria (false)) (credo (false)) (praef ("comm. I"))) ((date 2026-06-24) (class_ ("I cl.")) (title "Alb Feria IV. IN NATIVITATE S IOANNIS * BAPTISTAE,") (te_deum ()) (gloria (true)) (credo (true)) @@ -1041,7 +1058,7 @@ (praef ("comm. \226\128\147"))) ((date 2026-08-14) (class_ ("II cl.")) (title "Viol Feria VI. VIGILIA ASSUMPTIONIS B. MARIAE VIRG.,") - (te_deum (true)) (gloria (false)) (credo (false)) (praef ("comm. I"))) + (te_deum (false)) (gloria (false)) (credo (false)) (praef ("comm. I"))) ((date 2026-08-15) (class_ ("I cl.")) (title "Alb Sabb. IN ASSUMPTIONE B. MARIAE VIRG.,") (te_deum ()) (gloria (true)) (credo (true)) (praef ("BMV Et te in Assumptione. Ad"))) @@ -1176,7 +1193,7 @@ (praef ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa SS Mauritii et Sociorum Mm. (rub.) Intret in conspectu tuo, Gloria, ors. et Evangelium pr., comm. S Thomae de Villanova Ep. et Conf., praef. comm. vel de Martyribus."))) ((date 2026-09-23) (class_ ("II cl.")) - (title "Viol FERIA IV QUATTUOR TEMP., De ea,") (te_deum (true)) + (title "Viol FERIA IV QUATTUOR TEMP., De ea,") (te_deum (false)) (gloria (false)) (credo (false)) (praef ("comm. \226\128\147 Quoad Flectamus genua vide RM 440."))) ((date 2026-09-24) (class_ ("IV cl.")) @@ -1184,10 +1201,10 @@ (te_deum (false)) (gloria (false)) (credo (false)) (praef ("comm. \226\128\147"))) ((date 2026-09-25) (class_ ("II cl.")) - (title "Viol FERIA VI QUATTUOR TEMP., De ea,") (te_deum (true)) + (title "Viol FERIA VI QUATTUOR TEMP., De ea,") (te_deum (false)) (gloria (false)) (credo (false)) (praef (comm.))) ((date 2026-09-26) (class_ ("II cl.")) - (title "Viol SABB. QUATTUOR TEMP., De eo,") (te_deum (true)) + (title "Viol SABB. QUATTUOR TEMP., De eo,") (te_deum (false)) (gloria (false)) (credo (false)) (praef ("comm. \226\128\147 Quoad Flectamus genua vide RM 440. Quoad lectiones vide RM 468. I"))) @@ -1441,7 +1458,7 @@ (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) (credo (false)) (praef ("BMV Et te in Veneratione. I"))) ((date 2026-11-29) (class_ ("I cl.")) - (title "Viol DOM. I ADVENTUS, De ea,") (te_deum (true)) (gloria (false)) + (title "Viol DOM. I ADVENTUS, De ea,") (te_deum (false)) (gloria (false)) (credo (true)) (praef ("Trinit. Ad II"))) ((date 2026-11-30) (class_ ("II cl.")) (title "Rub Feria II. S ANDREAE * APOSTOLI,") (te_deum ()) @@ -1465,8 +1482,8 @@ (gloria (false)) (credo (false)) (praef ("comm. Sabbatum primum in mense. I"))) ((date 2026-12-06) (class_ ("I cl.")) - (title "Viol DOM. II ADVENTUS, De ea,") (te_deum (true)) (gloria (false)) - (credo (true)) (praef ("Trinit. Ad II"))) + (title "Viol DOM. II ADVENTUS, De ea,") (te_deum (false)) + (gloria (false)) (credo (true)) (praef ("Trinit. Ad II"))) ((date 2026-12-07) (class_ ("III cl. (Priv.)")) (title "Alb Feria II. S Ambrosii Ep., Conf. et Eccl. Doct.,") (te_deum (true)) (gloria (true)) (credo (false)) @@ -1488,7 +1505,7 @@ (title "Viol Sabb. post Dom. II Adventus, De eo,") (te_deum ()) (gloria (false)) (credo (false)) (praef ("comm. I"))) ((date 2026-12-13) (class_ ("I cl.")) - (title "DOM. III ADVENTUS (GAUDETE), De ea,") (te_deum (true)) + (title "DOM. III ADVENTUS (GAUDETE), De ea,") (te_deum (false)) (gloria (false)) (credo (true)) (praef ("Trinit. Ad II"))) ((date 2026-12-14) (class_ ("III cl.")) (title "Viol Feria II post Dom. III Adventus (Gaudete), De ea,") @@ -1512,8 +1529,8 @@ (praef ("comm. \226\128\147 Quoad Flectamus genua vide RM 440. Quoad lectiones vide RM 468. I"))) ((date 2026-12-20) (class_ ("I cl.")) - (title "Viol DOM. IV ADVENTUS, De ea,") (te_deum (true)) (gloria (false)) - (credo (true)) (praef ("Trinit. Ad II"))) + (title "Viol DOM. IV ADVENTUS, De ea,") (te_deum (false)) + (gloria (false)) (credo (true)) (praef ("Trinit. Ad II"))) ((date 2026-12-21) (class_ ("II cl.")) (title "Rub Feria II. S THOM\195\134 * APOSTOLI,") (te_deum ()) (gloria (true)) (credo (true)) (praef ("App. Ad"))) @@ -1524,7 +1541,7 @@ (title "Viol FERIA IV POST DOM. IV ADVENTUS, De ea,") (te_deum ()) (gloria (false)) (credo (false)) (praef (comm.))) ((date 2026-12-24) (class_ ("I cl.")) - (title "Viol Feria V. VIGILIA NATIVITATIS DOMINI,") (te_deum (true)) + (title "Viol Feria V. VIGILIA NATIVITATIS DOMINI,") (te_deum (false)) (gloria (false)) (credo (false)) (praef ("comm. I"))) ((date 2026-12-25) (class_ ("I cl.")) (title "Alb Feria VI. IN NATIVITATE DOMINI,") (te_deum ()) diff --git a/test/test_calendar.ml b/test/test_calendar.ml index 0d402e6..157841b 100644 --- a/test/test_calendar.ml +++ b/test/test_calendar.ml @@ -104,10 +104,11 @@ module Fixture = struct the sanctoral side. *) let readings ~observed:_ ~temporal:_ ~date:_ ~temporal_at:_ = (None, []) - (* No fixture here exercises the Creed rubric either -- a rite that has - not implemented it returns [false] explicitly, {!Rite.t.creed}'s own - documented default. *) + (* No fixture here exercises the Creed or Gloria rubrics either -- a rite + that has not implemented them returns [false] explicitly, + {!Rite.t.creed}/{!Rite.t.gloria}'s own documented default. *) let creed ~temporal:_ ~observed:_ ~date:_ = false + let gloria ~temporal:_ ~observed:_ ~date:_ = false let rite : (season, rank) Rite.t = { Rite.id = "synthetic-calendar"; vocab; year_start; temporal; anchors = (fun _ -> []); @@ -119,7 +120,7 @@ module Fixture = struct (* Not a Roman rite either, so no bissextile-doubling convention: identity, {!Rite.t.fixed_key}'s own documented default. *) fixed_key = (fun d -> Some (D.month d, D.day d)); - rules; season_runs = [ A; B ]; transfer_target; readings; creed } + rules; season_runs = [ A; B ]; transfer_target; readings; creed; gloria } let entry ~month ~day ~slug ~rank = { Layer.date = (match Date_spec.fixed ~month ~day with Ok d -> d | Error e -> failwith e); diff --git a/test/test_fiuv_ordo.ml b/test/test_fiuv_ordo.ml index 8b3e942..24eeed0 100644 --- a/test/test_fiuv_ordo.ml +++ b/test/test_fiuv_ordo.ml @@ -68,7 +68,7 @@ let sha256_of_file path = | Some i -> String.sub line 0 i | None -> Alcotest.failf "unexpected sha256sum output for %s: %S" path line) -let fixture_sha256 = "becadaad43b3a42c4eb820cb4e93d68f9b1c07a2c8e5273167cd599758af5c67" +let fixture_sha256 = "a52cc4dae32ce4d07446c9daa86287cb99796f6584b3d571e3a3cbdc93fca396" let real_layer () = let layer = @@ -132,7 +132,7 @@ let window_last = "2026-12-31" (* late). *) (* ---------------------------------------------------------------------- *) -type colitur_row = { c_date : string; c_creed : bool } +type colitur_row = { c_date : string; c_creed : bool; c_gloria : bool } let colitur_rows () = let layer = real_layer () in @@ -148,7 +148,50 @@ let colitur_rows () = let stop = mk window_last in while Date.compare !d stop <= 0 do (match Hashtbl.find_opt by_rata (Date.to_rata !d) with - | Some day -> rows := { c_date = Date.to_iso8601 day.LD.date; c_creed = day.LD.creed } :: !rows + | Some day -> + rows := + { c_date = Date.to_iso8601 day.LD.date; c_creed = day.LD.creed; c_gloria = day.LD.gloria } :: !rows + | None -> Alcotest.failf "no colitur day resolved for %s" (Date.to_iso8601 !d)); + d := Date.add_days !d 1 + done; + List.rev !rows + +(* Te Deum has no colitur-side [Liturgical_day.t] field of its own -- it is + a Breviary fact {!Rite_ef.Rubrics_ef.gloria} reads internally, not a Mass + part {!Colitur_kernel.Rite.t} exposes. Resolved separately, straight from + {!Rite_ef.Rubrics_ef.te_deum}, over the identical window/day set. *) +type colitur_te_deum_row = { + t_date : string; + t_te_deum : bool; + t_rank : V.rank; + t_slug : string; + t_has_commemoration : bool; +} + +let colitur_te_deum_rows () = + let layer = real_layer () in + let rite = Rite_ef.context ~lectionary:(real_lectionary ()) ~commons:(real_commons ()) in + let by_rata : (int, (V.season, V.rank) LD.t) Hashtbl.t = Hashtbl.create 800 in + for y = 2024 to 2027 do + let days = Cal.year rite layer y in + Array.iter (fun (d : (V.season, V.rank) LD.t) -> Hashtbl.replace by_rata (Date.to_rata d.LD.date) d) days + done; + let mk s = match Date.of_iso8601 s with Ok d -> d | Error e -> Alcotest.failf "%s: %s" s e in + let rows = ref [] in + let d = ref (mk window_first) in + let stop = mk window_last in + while Date.compare !d stop <= 0 do + (match Hashtbl.find_opt by_rata (Date.to_rata !d) with + | Some day -> + let te_deum = + Rite_ef.Rubrics_ef.te_deum ~temporal:day.LD.temporal ~observed:day.LD.observed ~date:day.LD.date + in + rows := + { t_date = Date.to_iso8601 day.LD.date; t_te_deum = te_deum; + t_rank = day.LD.observed.Colitur_kernel.Celebration.rank; + t_slug = Colitur_kernel.Slug.to_string day.LD.observed.Colitur_kernel.Celebration.slug; + t_has_commemoration = day.LD.commemorations <> [] } + :: !rows | None -> Alcotest.failf "no colitur day resolved for %s" (Date.to_iso8601 !d)); d := Date.add_days !d 1 done; @@ -258,11 +301,129 @@ let test_creed_matches_or_is_explained () = Alcotest.failf "allow-list entry %s is declared but never matched a real divergence" e.id) allow_list +(* ---------------------------------------------------------------------- *) +(* Gloria (RG 431-432, {!Rite_ef.Rubrics_ef.gloria}) -- Phase 2. Same shape *) +(* as the Creed comparison above, over the identical 400-row window. *) +(* ---------------------------------------------------------------------- *) + +let test_gloria_coverage () = + let ordo = ordo_rows () in + let no_gloria = List.filter (fun o -> o.gloria = None) ordo in + Alcotest.(check int) "exactly one day has no Ordo Gloria marker" 1 (List.length no_gloria) + +let describe_gloria_mismatch (o : ordo_row) (c : colitur_row) = + Printf.sprintf "%s %S: colitur gloria=%b, Ordo gloria=%b" o.date o.title c.c_gloria (Option.get o.gloria) + +(* F1 -- OPEN, adjudicated FOR colitur. The single Gloria mismatch found: + Good Friday (2026-04-03). See data/ef/expected-divergences-fiuv.sexp's + own F1 for the full citation and the raw source text this was checked + against directly (docs/research/ordo/fiuv-ordo-2025-2026.pdf, page 46). *) +let is_f1_good_friday (o : ordo_row) = String.equal o.date "2026-04-03" + +let test_gloria_matches_or_is_explained () = + let ordo = ordo_rows () in + let colitur = colitur_rows () in + let unexplained = ref [] in + let f1_count = ref 0 in + List.iter2 + (fun (o : ordo_row) (c : colitur_row) -> + if not (String.equal o.date c.c_date) then Alcotest.failf "misaligned: ordo %s vs colitur %s" o.date c.c_date; + match o.gloria with + | None -> () + | Some ogloria -> + if Bool.equal ogloria c.c_gloria then () + else if is_f1_good_friday o then incr f1_count + else unexplained := describe_gloria_mismatch o c :: !unexplained) + ordo colitur; + Alcotest.(check (list string)) "every Gloria mismatch is named in the allow-list -- none unexplained" [] + (List.rev !unexplained); + Alcotest.(check int) "F1 (Good Friday) count" 1 !f1_count + +(* ---------------------------------------------------------------------- *) +(* Te Deum (Breviary 237-238, {!Rite_ef.Rubrics_ef.te_deum}) -- Phase 2, *) +(* the mitigation the task brief names for this source's own stated *) +(* weakness (a single, not yet scan-verified, web transcription). A *) +(* SEPARATE colitur-side resolution ({!colitur_te_deum_rows}), since Te *) +(* Deum has no {!Colitur_kernel.Liturgical_day.t} field of its own. *) +(* *) +(* The SUNDAY shape this same comparison originally found (237(b)'s own *) +(* literal Septuagesima/Sexagesima/Quinquagesima exception, contradicted *) +(* 15/15) is FIXED at the source ({!Rite_ef.Rubrics_ef.te_deum}'s own *) +(* header has the correction and its full citation) -- not allow-listed, *) +(* because it no longer diverges. Three OTHER shapes remain OPEN, *) +(* single-witnessed (never captured by the LMS fixtures, which do not *) +(* record Te Deum at all) -- see data/ef/expected-divergences-fiuv.sexp's *) +(* own F2/F3/F4 for the full citations. Matched by PREDICATE, the same *) +(* "varies by shape, not by a fixed date list" reasoning L5/L6 already *) +(* establish for the LMS suite. *) +(* ---------------------------------------------------------------------- *) + +let test_te_deum_coverage () = + let ordo = ordo_rows () in + let no_te_deum = List.filter (fun o -> o.te_deum = None) ordo in + Alcotest.(check int) "the unresolved-Te-Deum population matches this fixture's own measured figure" 127 + (List.length no_te_deum) + +let describe_te_deum_mismatch (o : ordo_row) (t : colitur_te_deum_row) = + Printf.sprintf "%s %S: colitur te_deum=%b, Ordo te_deum=%b (rank=%s commemoration=%b)" o.date o.title t.t_te_deum + (Option.get o.te_deum) (V.rank_to_string t.t_rank) t.t_has_commemoration + +(* F2 (every I-class and omissible vigil) and F4 (the three September + Ember days) were BOTH found against the FIRST, buggy extraction (see + the fixture's own provenance header, "RE-EXTRACTED" note, and + {!Rite_ef.Rubrics_ef.te_deum}'s own 237(a) comment for the full + account of the extractor bug and its fix) -- re-run against the + corrected data, NEITHER fires any more: colitur's own answer already + matched the CORRECTED Ordo on every one of those 7 dates, all along. + Removed rather than kept as dead code with an [expected 0] pin, the + same "an entry that stops firing is a real change, not silently + absorbed" discipline data/ef/expected-divergences-lms.sexp's own L1/L3 + closures already establish -- see that file's own history for the + precedent this follows. + + F3, the privileged-Lenten/Passiontide-feria-plus-commemoration shape + L5 (data/ef/expected-divergences-lms.sexp) already found for Gloria, + REMAINS: 6 instances, unaffected by the extractor fix (none of the six + raw source lines used "sine Te Deum" at all -- confirmed directly + against the pdftotext dump, see F3's own citation). CONTRADICTS L5, + not corroborates it: FIUV's own [gloria] is [false] on all six dates + (agreeing with colitur), while its [te_deum] is [true] on the same six + -- see F3's own citation in data/ef/expected-divergences-fiuv.sexp for + the full account of why Gloria and Te Deum diverge on the identical + day. *) +let is_f3_lenten_commemoration (_ : ordo_row) (t : colitur_te_deum_row) = + t.t_has_commemoration && t.t_rank = V.Class3 + +let test_te_deum_matches_or_is_explained () = + let ordo = ordo_rows () in + let colitur = colitur_te_deum_rows () in + let unexplained = ref [] in + let f3_count = ref 0 in + List.iter2 + (fun (o : ordo_row) (t : colitur_te_deum_row) -> + if not (String.equal o.date t.t_date) then Alcotest.failf "misaligned: ordo %s vs colitur %s" o.date t.t_date; + match o.te_deum with + | None -> () + | Some otd -> + if Bool.equal otd t.t_te_deum then () + else if is_f3_lenten_commemoration o t then incr f3_count + else unexplained := describe_te_deum_mismatch o t :: !unexplained) + ordo colitur; + Alcotest.(check (list string)) "every Te Deum mismatch is named in the allow-list -- none unexplained" [] + (List.rev !unexplained); + Alcotest.(check int) "F3 (Lenten privileged feria + commemoration) count" 6 !f3_count + let suite = ( "fiuv-ordo", [ Alcotest.test_case "fixture SHA-256 matches its provenance note" `Quick test_fixture_checksum; Alcotest.test_case "streams are 400 rows each, dates aligned 1:1" `Quick test_dates_align; Alcotest.test_case "only Holy Saturday has no Ordo Creed marker" `Quick test_creed_coverage; Alcotest.test_case "every Creed difference is named in the cited allow-list -- none unexplained" `Quick - test_creed_matches_or_is_explained + test_creed_matches_or_is_explained; + Alcotest.test_case "Ordo Gloria coverage matches the measured figure" `Quick test_gloria_coverage; + Alcotest.test_case "every Gloria difference is named in the cited allow-list -- none unexplained" `Quick + test_gloria_matches_or_is_explained; + Alcotest.test_case "Ordo Te Deum coverage matches the measured figure" `Quick test_te_deum_coverage; + Alcotest.test_case "every Te Deum difference is named in the cited allow-list -- none unexplained" `Quick + test_te_deum_matches_or_is_explained ] ) diff --git a/test/test_lms_ordo.ml b/test/test_lms_ordo.ml index 219e51f..42dc31d 100644 --- a/test/test_lms_ordo.ml +++ b/test/test_lms_ordo.ml @@ -173,6 +173,13 @@ type colitur_row = { c_season : V.season; c_formulary : MF.t option; c_creed : bool; + c_gloria : bool; + c_rank : V.rank; + c_slug : string; + c_has_commemoration : bool; + (** whether {!Colitur_kernel.Liturgical_day.t.commemorations} is + non-empty -- needed by the Gloria comparison's own L5 shape + (RG 431(b)/n.302(b)), not by anything Task 6 built. *) } let colitur_rows ~year_lo ~year_hi ~window_first ~window_last = @@ -194,7 +201,10 @@ let colitur_rows ~year_lo ~year_hi ~window_first ~window_last = | Some day -> rows := { c_date = Date.to_iso8601 day.LD.date; c_season = day.LD.temporal.Colitur_kernel.Temporal.season; - c_formulary = day.LD.formulary; c_creed = day.LD.creed } + c_formulary = day.LD.formulary; c_creed = day.LD.creed; c_gloria = day.LD.gloria; + c_rank = day.LD.observed.Colitur_kernel.Celebration.rank; + c_slug = Colitur_kernel.Slug.to_string day.LD.observed.Colitur_kernel.Celebration.slug; + c_has_commemoration = day.LD.commemorations <> [] } :: !rows | None -> Alcotest.failf "no colitur day resolved for %s" (Date.to_iso8601 !d)); d := Date.add_days !d 1 @@ -434,9 +444,19 @@ let check_formulary_overrides ordo colitur = (* not noise to silence. *) (* ---------------------------------------------------------------------- *) +(* No Str/regex (frozen deps) -- the same hand-rolled substring test every + other file in this codebase reaches for (rubrics_ef.ml's own + [contains_substring], precedence_ef.ml's [contains_substring]). Local to + this file, not shared, on the same "no common .mli to hang it from" + footing those other copies already document. *) +let contains_substring s ~needle = + let ls = String.length s and ln = String.length needle in + let rec at i = i + ln <= ls && (String.sub s i ln = needle || at (i + 1)) in + ln = 0 || at 0 + let make_suite ~label ~fixture_path ~fixture_sha256 ~window_first ~window_last ~year_lo ~year_hi ~allow_list_path ~expected_rows ~expected_bvm_votive ~expected_proper ~expected_common ~expected_preceding_sunday - ~expected_ascension_week = + ~expected_ascension_week ~expected_gloria_l5 ~expected_gloria_l6 = let test_fixture_checksum () = Alcotest.(check string) "fixture SHA-256 matches its provenance note" fixture_sha256 (sha256_of_file fixture_path) @@ -540,6 +560,84 @@ let make_suite ~label ~fixture_path ~fixture_sha256 ~window_first ~window_last ~ Alcotest.(check int) (Printf.sprintf "%s: expected_rows matches the actual count" id) e.expected_rows n) explained_counts in + (* ---- Gloria (RG 431-432, {!Rite_ef.Rubrics_ef.gloria}) -- Phase 2 of + this task. Same shape as the Creed comparison immediately above: + coverage (which dates carry no Ordo "Gl"/"No Gl" marker at all) is + checked separately from the value comparison, and both are + date-keyed against their own allow-list ids, never a loose "some + divergence is fine" check. *) + let test_gloria_coverage () = + let ordo = ordo_rows fixture_path in + let no_gloria = List.filter (fun o -> o.gloria = None) ordo in + let expected = window_good_fridays () in + Alcotest.(check (list string)) "only this window's own Good Friday has no Ordo Gloria marker" expected + (List.map (fun o -> o.date) no_gloria) + in + let describe_gloria_mismatch (o : ordo_row) (c : colitur_row) = + Printf.sprintf "%s %S: colitur gloria=%b, Ordo gloria=%b (rank=%s commemoration=%b formulary=%s)" o.date o.title + c.c_gloria (Option.get o.gloria) (V.rank_to_string c.c_rank) c.c_has_commemoration + (match c.c_formulary with + | Some { MF.said = Some s; _ } -> Colitur_kernel.Slug.to_string s + | Some { MF.said = None; via = MF.Votive } -> "votive (said unnamed in the data)" + | Some { MF.said = None; _ } -> "NONE (said, unexpectedly outside Votive)" + | None -> "NONE") + in + (* Two REAL, STRUCTURAL shapes found running this comparison (see + data/ef/expected-divergences-lms.sexp's own L5/L6 for the full + citations) -- neither is a fixed date list, both a property of the + day itself, because both recur every year the underlying condition + holds, not on a fixed calendar date the way L4 above does. Matched + by PREDICATE, not by date, for the same reason L2's own note gives + for why it is prose-only rather than wired through the shared + [expected_rows] mechanism: the count varies window to window (L5: + 6/5/6; L6: 1/0/0), so a single static count cannot check it, and + [make_suite] threads the per-window expected totals directly + (~expected_gloria_l5/~expected_gloria_l6 below) instead. *) + let is_l5_lenten_commemoration (o : ordo_row) (c : colitur_row) = + (* RG 431(b)/n.302(b): "Missa de commemoratione in Officio diei + occurrente" says the Gloria. Every instance found is a privileged + Lenten/Passiontide feria (Class3, violet -- {!TE}'s own + [ferial_rank], RG25) carrying exactly one commemoration of an + impeded Class3 saint, colitur reading [gloria]=false (the ferial + Mass on its own) where the Ordo reads [true]. *) + (not c.c_gloria) && Option.value o.gloria ~default:false && c.c_has_commemoration && c.c_rank = V.Class3 + in + let is_l6_rogation_colour (o : ordo_row) (c : colitur_row) = + (* Root-caused to a DIFFERENT, pre-existing bug this comparison merely + surfaced -- {!Rite_ef.Temporal_ef.temporal}'s own Rogation Monday/ + Tuesday branch hardcodes [Colour.Violet] with no RG citation at + all, but the Ordo shows this exact date "FERIA IV Cl W" (white, + matching Paschaltide's own [season_colour] and RG88's "nihil fit in + Officio" -- the Office, hence its colour, is unchanged by the + Rogation, only the Mass TEXT is proper) -- so [gloria]'s own 432(b) + violet guard wrongly fires. NOT a Gloria defect and NOT fixed here + (out of this task's own scope; see the task report). *) + (not c.c_gloria) && Option.value o.gloria ~default:false + && (contains_substring c.c_slug ~needle:"rogation-monday" || contains_substring c.c_slug ~needle:"rogation-tuesday") + in + let test_gloria_matches_or_is_explained ~expected_gloria_l5 ~expected_gloria_l6 () = + let ordo = ordo_rows fixture_path in + let colitur = colitur_rows ~year_lo ~year_hi ~window_first ~window_last in + let unexplained = ref [] in + let l5_count = ref 0 and l6_count = ref 0 in + List.iter2 + (fun (o : ordo_row) (c : colitur_row) -> + if not (String.equal o.date c.c_date) then Alcotest.failf "misaligned: ordo %s vs colitur %s" o.date c.c_date; + match o.gloria with + | None -> () + | Some ogloria -> + if Bool.equal ogloria c.c_gloria then () + else if is_l5_lenten_commemoration o c then incr l5_count + else if is_l6_rogation_colour o c then incr l6_count + else unexplained := describe_gloria_mismatch o c :: !unexplained) + ordo colitur; + Alcotest.(check (list string)) (Printf.sprintf "[%s] every Gloria mismatch is named in the allow-list -- none unexplained" label) + [] (List.rev !unexplained); + Alcotest.(check int) (Printf.sprintf "[%s] L5 (Lenten privileged feria + commemoration) count" label) + expected_gloria_l5 !l5_count; + Alcotest.(check int) (Printf.sprintf "[%s] L6 (Rogation Monday/Tuesday colour bug) count" label) expected_gloria_l6 + !l6_count + in let test_bvm_seasonal_selection () = let ordo = ordo_rows fixture_path in let colitur = colitur_rows ~year_lo ~year_hi ~window_first ~window_last in @@ -635,6 +733,10 @@ let make_suite ~label ~fixture_path ~fixture_sha256 ~window_first ~window_last ~ Alcotest.test_case "only this window's own Good Friday has no Ordo Creed marker" `Quick test_creed_coverage; Alcotest.test_case "every Creed difference is named in the cited allow-list -- none unexplained" `Quick test_creed_matches_or_is_explained; + Alcotest.test_case "only this window's own Good Friday has no Ordo Gloria marker" `Quick + test_gloria_coverage; + Alcotest.test_case "every Gloria difference is named in the cited allow-list -- none unexplained" `Quick + (test_gloria_matches_or_is_explained ~expected_gloria_l5 ~expected_gloria_l6); Alcotest.test_case "every BVM-Saturday numeral matches its season" `Quick test_bvm_seasonal_selection; Alcotest.test_case "every Ordo BVM numeral day is a colitur Votive day" `Quick test_bvm_numeral_implies_votive; @@ -676,18 +778,18 @@ let suite_2023_2024 = I-class Sunday that admits him not even as a commemoration (RG16(a)), so his own Mass is not said anywhere in this window any more. *) ~expected_bvm_votive:12 ~expected_proper:181 ~expected_common:2 ~expected_preceding_sunday:61 - ~expected_ascension_week:1 + ~expected_ascension_week:1 ~expected_gloria_l5:5 ~expected_gloria_l6:1 let suite_2024_2025 = make_suite ~label:"lms-ordo-2024-2025" ~fixture_path:"fixtures/lms-ordo-2024-2025.sexp" ~fixture_sha256:"da817b75c5bf40ed3be1d5f6890b199705e02ce4d42111253ab8547bccabc3f7" ~window_first:"2024-11-27" ~window_last:"2025-12-31" ~year_lo:2023 ~year_hi:2026 ~allow_list_path ~expected_rows:400 ~expected_bvm_votive:14 ~expected_proper:179 ~expected_common:2 ~expected_preceding_sunday:66 - ~expected_ascension_week:3 + ~expected_ascension_week:3 ~expected_gloria_l5:5 ~expected_gloria_l6:0 let suite_2025_2026 = make_suite ~label:"lms-ordo-2025-2026" ~fixture_path:"fixtures/lms-ordo-2025-2026.sexp" ~fixture_sha256:"8839a61e0c7d1e6c8326114f4f45a5c183551287a88f4ed01127154add6ae5a5" ~window_first:"2025-11-28" ~window_last:"2026-12-31" ~year_lo:2024 ~year_hi:2027 ~allow_list_path ~expected_rows:399 ~expected_bvm_votive:13 ~expected_proper:174 ~expected_common:2 ~expected_preceding_sunday:68 - ~expected_ascension_week:2 + ~expected_ascension_week:2 ~expected_gloria_l5:6 ~expected_gloria_l6:0 diff --git a/test/test_rubrics_ef.ml b/test/test_rubrics_ef.ml index a778a5a..71f180d 100644 --- a/test/test_rubrics_ef.ml +++ b/test/test_rubrics_ef.ml @@ -46,6 +46,23 @@ let creed_on y m d = (Cal.day ctx layer (mk y m d)).LD.creed let check name y m d expected = Alcotest.(check bool) name expected (creed_on y m d) +(* ------------------------------------------------------------------------ *) +(* Breviary 237-238 (Te Deum) and RG 431-432 (Gloria) -- Phase 2 of the *) +(* celebrant-rubrics-phase1 design. See lib/rites/rite_ef/rubrics_ef.ml for *) +(* both rubrics quoted in full and every branch's own citation. One *) +(* end-to-end test per clause, resolved against REAL calendar dates through *) +(* the shipped data -- every expected value below was read off *) +(* `colitur rubrics `'s real output BEFORE being pinned here, the *) +(* same discipline the Creed tests above already establish. *) + +let day_on y m d = Cal.day ctx layer (mk y m d) +let gloria_on y m d = (day_on y m d).LD.gloria +let te_deum_on y m d = RE.te_deum ~temporal:(day_on y m d).LD.temporal ~observed:(day_on y m d).LD.observed + ~date:(mk y m d) + +let check_gloria name y m d expected = Alcotest.(check bool) name expected (gloria_on y m d) +let check_te_deum name y m d expected = Alcotest.(check bool) name expected (te_deum_on y m d) + (* ---- RG 475(a): "in qualibet dominica, etsi eius Officium alicui festo locum cedat" ---- *) @@ -440,6 +457,277 @@ let test_ferial_origin_never_carries_lord_bvm_or_apostle_slug () = Alcotest.(check bool) "span reached Lenten/Passiontide III-class ferias" true (!lenten_passiontide_class3 > 0) +(* ---- 237(a): the three named Paschaltide days ---- *) + +let test_237a_easter_sunday () = check_te_deum "237(a): Easter Sunday" 2026 4 5 true +let test_237a_low_sunday () = check_te_deum "237(a): Low Sunday" 2026 4 12 true +let test_237a_pentecost () = check_te_deum "237(a): Pentecost Sunday" 2026 5 24 true + +(* ---- 237(f): the vigils of Ascension and Pentecost, both otherwise + reachable by 238(b) (the Ascension vigil is Class2) or moot to it + (the Pentecost vigil is Class1) ---- *) + +let test_237f_ascension_vigil () = check_te_deum "237(f): Vigil of the Ascension" 2026 5 13 true +let test_237f_pentecost_vigil () = check_te_deum "237(f): Vigil of Pentecost" 2026 5 23 true + +(* ---- 237(d): the three privileged octaves, reusing [creed]'s own windows + -- a day within the Nativity octave whose OWN office is a real saint + (RG 67's "Com. octavae Nativitatis"), and an Easter-week feria outside + the narrower 237(a) list ---- *) + +let test_237d_nativity_octave_saint () = + check_te_deum "237(d): St John within the Nativity octave" 2026 12 27 true + +let test_237d_easter_week_feria () = check_te_deum "237(d): Easter Tuesday" 2026 4 7 true + +(* ---- 238(b): the omissible (Class2/Class3) vigils -- St Lawrence's own, + picked in a year where nothing displaces it, confirmed via + `colitur day 2026` first the same way the Creed tests were derived ---- *) + +let test_238b_omissible_vigil () = + (* 9 August 2026 is itself a Sunday (the vigil impeded, see 237(b)'s own + test below, which reuses that exact date) -- 2027 is picked instead, + confirmed via `colitur day 2027` first, the same discipline every + other date in this file follows. *) + check_te_deum "238(b): Vigil of St Lawrence" 2027 8 9 false + +(* ---- The Nativity Vigil (I class): NOT literally named by 238(b)'s own + "II et III classis" text -- excluded here on the structural RG 21/35 + taxonomy inference [te_deum]'s own comment states explicitly as an + inference, not a citation. Flagged the same way in the task report; + checked against the FIUV Ordo's own Te Deum marker for 24 December in + test_fiuv_ordo.ml, which is this inference's real corroboration. ---- *) + +let test_nativity_vigil_excluded_by_inference () = + check_te_deum "Nativity Vigil (I class): excluded, inference not literal 238(b)" 2026 12 24 false + +(* ---- 238(c)/RG23: Ash Wednesday and Good Friday (moot -- no Mass, but the + RG23 feria-I-classis exclusion still answers [false] regardless of + colour) ---- *) + +let test_238c_ash_wednesday () = check_te_deum "238(c)/RG23: Ash Wednesday" 2026 2 18 false +let test_238c_good_friday () = check_te_deum "238(c)/RG23: Good Friday" 2026 4 3 false + +(* ---- 237(g): the votive Office of the BVM on Saturday -- reused directly + from test/cli.t's own pinned example ---- *) + +let test_237g_bvm_saturday () = check_te_deum "237(g): BVM Saturday Office" 2026 7 11 true + +(* ---- 237(e): a plain, non-octave, non-Sunday feria of Christmastide (2-5 + January) ---- *) + +let test_237e_christmastide_feria () = + check_te_deum "237(e): 2 January, a Christmastide feria" 2026 1 2 true + +(* ---- 237(b): an ordinary II-class Sunday outside Septuagesima, and its + own explicit exception (a Septuagesima/Sexagesima Sunday, [Class2], + excepted by name) ---- *) + +let test_237b_ordinary_class2_sunday () = + check_te_deum "237(b): an ordinary Time-after-Pentecost Sunday" 2026 8 9 true + +(* RE-VERIFIED against the CORRECTED FIUV extraction ([te_deum]'s own + 237(a) comment has the full account of the extractor bug an earlier + pass of this task found and fixed): 237(b)'s own literal "exceptis + dominicis in Septuagesima, in Sexagesima et in Quinquagesima" holds + after all -- these two Sundays do NOT say the Te Deum, confirmed + against the corrected data, not merely the original transcription + alone. *) +let test_237b_septuagesima_exception () = + check_te_deum "237(b)'s own exception: Septuagesima Sunday" 2027 1 24 false + +let test_237b_sexagesima_exception () = + check_te_deum "237(b)'s own exception: Sexagesima Sunday" 2027 1 31 false + +(* ---- 237(c): a genuine sanctoral feast kept during a penitential season + (St Paul of the Cross, Class3, outside any privileged window) and one in + Ordinary Time (Lawrence, Class2) ---- *) + +let test_237c_sanctoral_feast () = check_te_deum "237(c): a sanctoral feast (Lawrence)" 2026 8 10 true + +(* Found alongside the FIUV extractor-bug fix ([te_deum]'s own 237(c) + comment has the full account): Passion Sunday and Palm Sunday are BOTH + entries in {!Temporal_ef.named} (named individually for RG 91 entry 6), + which without the [temporal.weekday <> Sun] guard on 237(c)'s own + [named<>None] disjunct would wrongly grant them [true] by ACCIDENT of + table membership -- neither is a genuine "festum" (RG 35's own "dies + dominica" is its own category), and both are [Class1] Sundays 237(b)'s + own [Class2] guard already excludes. Confirmed [false] directly against + the corrected FIUV extraction. *) +let test_passion_sunday_not_a_festum () = check_te_deum "Passion Sunday is not a festum for 237(c)" 2026 3 22 false +let test_palm_sunday_not_a_festum () = check_te_deum "Palm Sunday is not a festum for 237(c)" 2026 3 29 false + +(* ---- 238(d): the Requiem proxy, shared with [creed]'s own 476(f) and the + SAME two-member {!Colour.Black} population + {!test_colour_black_population_is_exactly_two} already asserts ---- *) + +let test_238d_all_souls () = check_te_deum "238(d): All Souls' Day (transferred)" 2025 11 3 false + +(* ---- RG 431(c): Holy Thursday and the Easter Vigil Mass say the Gloria + even though neither day's own Matins says the Te Deum (both are + feria-I-classis, [te_deum]'s own 238(c) branch) -- the one place [gloria] + and [te_deum] genuinely disagree on real data. Holy Saturday also proves + 431(c) outranks 432(b): its own colour is [Violet] + (Passiontide's [season_colour]), yet the Gloria is still said. ---- *) + +let test_431c_holy_thursday () = check_gloria "431(c): Holy Thursday" 2026 4 2 true +let test_431c_easter_vigil () = check_gloria "431(c): the Easter Vigil Mass (Holy Saturday)" 2026 4 4 true + +(* ---- RG 432(b): violet vestments -- independent of [te_deum], checked + against an Advent Sunday (I class, so [te_deum] would ALSO answer + [false] here via its own 237(b) rank guard: this is a same-answer + witness, not proof of independent teeth -- see the task report for why + no fully independent (te_deum=true, violet) witness exists anywhere in + the shipped 1583-9999 domain: every real [Colour.Violet] [Feast] entry + is one of the five sanctoral vigils, already excluded by [te_deum]'s + own [is_vigil] branch either way). ---- *) + +let test_432b_violet_sunday () = check_gloria "432(b): Advent I Sunday, violet" 2026 11 29 false + +(* ---- RG 432(d): the Requiem proxy, same population as 238(d) above ---- *) + +let test_432d_all_souls () = check_gloria "432(d): All Souls' Day (transferred)" 2025 11 3 false + +(* ---- RG 431(a)/432(a): mirrors [te_deum] for everything not already + decided above -- one true, one false, neither reachable via 431(c)/432(b)/ + 432(d) ---- *) + +let test_431a_mirrors_te_deum_true () = + check_gloria "431(a): mirrors [te_deum]=true (a sanctoral feast, Lawrence)" 2026 8 10 true + +let test_432a_mirrors_te_deum_false () = + check_gloria "432(a): mirrors [te_deum]=false (an ordinary Advent feria)" 2025 12 1 false + +(* ---- Domain-wide sanity, task requirement 5: "every violet day must be + false (RG 432 b), and every Requiem must be false (432 d)". Two + invariants, checked over every day {!Cal.year} resolves -- [Cal.year], + not [Cal.day] in a loop, for the same cost reason + {!test_every_sunday_in_2026_says_the_creed} above already gives. + + FAST (default suite): a fixed 200-year span, 1583-1782 -- large enough + to cross multiple Easter cycles and every season repeatedly, cheap + enough to stay in `dune test`'s own budget. EXHAUSTIVE (gated the same + way {!test_validate.test_exhaustive_domain_sweep} already is, via + COLITUR_EXHAUSTIVE_SWEEP): the full 1583-9999 domain, also tallying and + printing the true/false distribution so the measurement this task asks + for is not merely "did the invariant hold" but has a number attached -- + see the task report for the printed figures. *) +(* NOT a blanket "every violet day is [gloria]=false" (the task brief's own + phrasing, taken literally, is one exception too strong): RG 431(c) is a + NAMED, lex-specialis override for the Easter Vigil Mass, and colitur's + own per-day colour model gives Holy Saturday [Colour.Violet] + ([gloria]'s own header has the full argument for why -- the historical + violet-to-white vestment change happens AT the Gloria itself, a + per-action nuance this whole day/colour model already cannot express). + So the real invariant, checked here, is "every violet day is + [gloria]=false EXCEPT the Easter Vigil (Easter offset -1), which is + [gloria]=true BY DESIGN" -- and the exception is asserted to be EXACTLY + that one shape, every year, nothing else: [n = -1] is checked directly + rather than merely excluded, so a second, unexpected (violet, + gloria=true) day anywhere in the domain still fails loudly. Pushed back + on the task brief's own simplified phrasing rather than silently + special-cased -- see the task report. *) +let check_gloria_invariants_for_year y (counts : (int * int * int * int) ref) = + let days = Cal.year ctx layer y in + (* Per-date, NOT once per loop iteration off [y]: a liturgical year + "opening in civil year y" ({!Rite.t.year_start}'s own doc comment) + runs from that year's Advent into MOST of civil year y+1 -- so + [Cal.year ctx layer y]'s own array holds dates whose civil year is + y+1 for the whole Christmas-to-Pentecost span, governed by EASTER OF + y+1, not y. A single [Computus.gregorian_easter y] computed once here + wrongly used year y's own Easter for those dates -- found live: it + misidentified 1584-03-31 (Holy Saturday, governed by 1584's Easter, + surfaced while processing loop iteration y=1583) as an ordinary + violet day instead of the Vigil's own 431(c) exception, because + Easter 1583 (not 1584) was subtracted. Fixed by keying off + [Date.year d.LD.date] instead, which is always safe here: Holy + Saturday and Easter Sunday are never more than a few days apart and + never cross a civil-year boundary. *) + let violet, black, gloria_true, gloria_false = !counts in + let violet = ref violet + and black = ref black + and gloria_true = ref gloria_true + and gloria_false = ref gloria_false in + Array.iter + (fun (d : (V.season, V.rank) LD.t) -> + (if d.LD.gloria then incr gloria_true else incr gloria_false); + if d.LD.observed.Cel.colour = Colour.Violet then begin + incr violet; + let easter = Computus.gregorian_easter (Date.year d.LD.date) in + let n = Date.to_rata d.LD.date - Date.to_rata easter in + if n = -1 then + Alcotest.(check bool) + (Printf.sprintf "%s: the Easter Vigil's own 431(c) override, [gloria]=true despite violet" + (Date.to_iso8601 d.LD.date)) + true d.LD.gloria + else + Alcotest.(check bool) + (Printf.sprintf "%s: violet -> [gloria]=false (RG 432(b))" (Date.to_iso8601 d.LD.date)) + false d.LD.gloria + end; + if d.LD.observed.Cel.colour = Colour.Rose then + (* Gaudete/Laetare -- [gloria] reads [false] here via [te_deum]'s + own [Class2] guard on 237(b) (both Rose Sundays are [Class1] BY + CONSTRUCTION -- {!Rite_ef.Rubrics_ef.gloria}'s own 432(b) + citation has the full "checked, then found redundant, then + removed" account of why 432(b) itself does NOT need its own + Rose branch). Not folded into the [violet] counter above: + keeping the two colours separately tallied is what let this + invariant catch the Gaudete/Laetare gap live in the first place + (found via the LMS Ordo, 2023-12-17 and 2024-03-10) rather than + silently averaging it away inside one shared bucket. *) + Alcotest.(check bool) + (Printf.sprintf "%s: Rose (Gaudete/Laetare) -> [gloria]=false" (Date.to_iso8601 d.LD.date)) + false d.LD.gloria; + if d.LD.observed.Cel.colour = Colour.Black then begin + incr black; + Alcotest.(check bool) + (Printf.sprintf "%s: Requiem (black) -> [gloria]=false (RG 432(d))" (Date.to_iso8601 d.LD.date)) + false d.LD.gloria + end) + days; + counts := (!violet, !black, !gloria_true, !gloria_false) + +let test_domain_violet_implies_no_gloria_sample () = + let counts = ref (0, 0, 0, 0) in + for y = 1583 to 1782 do + check_gloria_invariants_for_year y counts + done; + let violet, _, _, _ = !counts in + Alcotest.(check bool) "the 200-year sample reached a real number of violet days" true (violet > 1000) + +let test_domain_requiem_implies_no_gloria_sample () = + (* Separate test name, same underlying sweep as the one immediately above + -- {!Cal.year} is only computed once per year regardless (module-level + [ctx]/[layer], no per-test reload), so this is not a second pass over + the domain, only a second, independently-named assertion on the same + tally, matching how {!test_colour_black_population_is_exactly_two} + above separates its own DATA and CODE checks into one function while + this pair keeps violet and black as two named outcomes. *) + let counts = ref (0, 0, 0, 0) in + for y = 1583 to 1782 do + check_gloria_invariants_for_year y counts + done; + let _, black, _, _ = !counts in + Alcotest.(check bool) "the 200-year sample reached at least one Requiem day" true (black > 0) + +let colitur_exhaustive_sweep_env = "COLITUR_EXHAUSTIVE_SWEEP" + +let test_exhaustive_gloria_domain_sweep () = + if Sys.getenv_opt colitur_exhaustive_sweep_env = None then Alcotest.skip () + else begin + let counts = ref (0, 0, 0, 0) in + for y = 1583 to 9999 do + check_gloria_invariants_for_year y counts + done; + let violet, black, gloria_true, gloria_false = !counts in + Printf.printf + "gloria domain sweep 1583..9999: violet=%d black=%d gloria_true=%d gloria_false=%d total=%d\n%!" + violet black gloria_true gloria_false (gloria_true + gloria_false); + Alcotest.(check bool) "the full domain reached a real number of violet days" true (violet > 100_000); + Alcotest.(check bool) "the full domain reached a real number of Requiem days" true (black > 1_000) + end + let suite = ( "Rubrics_ef", [ Alcotest.test_case "475(a): ordinary Sunday" `Quick test_475a_ordinary_sunday; @@ -477,4 +765,38 @@ let suite = Alcotest.test_case "every Sunday in 2026 says the Creed" `Quick test_every_sunday_in_2026_says_the_creed; Alcotest.test_case "RG 24/25: no ferial-origin office carries Lord/Bvm or an apostle slug" `Quick - test_ferial_origin_never_carries_lord_bvm_or_apostle_slug ] ) + test_ferial_origin_never_carries_lord_bvm_or_apostle_slug; + Alcotest.test_case "237(a): Easter Sunday" `Quick test_237a_easter_sunday; + Alcotest.test_case "237(a): Low Sunday" `Quick test_237a_low_sunday; + Alcotest.test_case "237(a): Pentecost Sunday" `Quick test_237a_pentecost; + Alcotest.test_case "237(f): Vigil of the Ascension" `Quick test_237f_ascension_vigil; + Alcotest.test_case "237(f): Vigil of Pentecost" `Quick test_237f_pentecost_vigil; + Alcotest.test_case "237(d): St John within the Nativity octave" `Quick + test_237d_nativity_octave_saint; + Alcotest.test_case "237(d): Easter Tuesday" `Quick test_237d_easter_week_feria; + Alcotest.test_case "238(b): Vigil of St Lawrence" `Quick test_238b_omissible_vigil; + Alcotest.test_case "Nativity Vigil excluded by structural inference, not literal 238(b)" `Quick + test_nativity_vigil_excluded_by_inference; + Alcotest.test_case "238(c)/RG23: Ash Wednesday" `Quick test_238c_ash_wednesday; + Alcotest.test_case "238(c)/RG23: Good Friday" `Quick test_238c_good_friday; + Alcotest.test_case "237(g): BVM Saturday Office" `Quick test_237g_bvm_saturday; + Alcotest.test_case "237(e): 2 January, a Christmastide feria" `Quick test_237e_christmastide_feria; + Alcotest.test_case "237(b): an ordinary Class2 Sunday" `Quick test_237b_ordinary_class2_sunday; + Alcotest.test_case "237(b)'s own exception: Septuagesima Sunday" `Quick test_237b_septuagesima_exception; + Alcotest.test_case "237(b)'s own exception: Sexagesima Sunday" `Quick test_237b_sexagesima_exception; + Alcotest.test_case "237(c): a sanctoral feast (Lawrence)" `Quick test_237c_sanctoral_feast; + Alcotest.test_case "Passion Sunday is not a festum for 237(c)" `Quick test_passion_sunday_not_a_festum; + Alcotest.test_case "Palm Sunday is not a festum for 237(c)" `Quick test_palm_sunday_not_a_festum; + Alcotest.test_case "238(d): All Souls' Day (transferred)" `Quick test_238d_all_souls; + Alcotest.test_case "431(c): Holy Thursday" `Quick test_431c_holy_thursday; + Alcotest.test_case "431(c): the Easter Vigil Mass" `Quick test_431c_easter_vigil; + Alcotest.test_case "432(b): Advent I Sunday, violet" `Quick test_432b_violet_sunday; + Alcotest.test_case "432(d): All Souls' Day (transferred)" `Quick test_432d_all_souls; + Alcotest.test_case "431(a): mirrors [te_deum]=true" `Quick test_431a_mirrors_te_deum_true; + Alcotest.test_case "432(a): mirrors [te_deum]=false" `Quick test_432a_mirrors_te_deum_false; + Alcotest.test_case "domain sanity: every violet day has [gloria]=false (sample)" `Quick + test_domain_violet_implies_no_gloria_sample; + Alcotest.test_case "domain sanity: every Requiem day has [gloria]=false (sample)" `Quick + test_domain_requiem_implies_no_gloria_sample; + Alcotest.test_case "domain sweep 1583..9999: violet/Requiem invariants, committed not sampled" + `Slow test_exhaustive_gloria_domain_sweep ] ) diff --git a/test/test_validate.ml b/test/test_validate.ml index 671c706..b53f915 100644 --- a/test/test_validate.ml +++ b/test/test_validate.ml @@ -324,15 +324,17 @@ module Synthetic = struct { Colitur_kernel.Mass_formulary.said = Some (Slug.of_string_exn "syn-formulary"); via = Colitur_kernel.Mass_formulary.Own_slug } - (* No fixture here exercises the Creed rubric -- a rite that has not - implemented it returns [false] explicitly, {!Rite.t.creed}'s own - documented default. Made overridable ([?creed] below) on the same - footing as [?readings] just above, for Task 6's own fixtures. *) + (* No fixture here exercises the Creed or Gloria rubrics -- a rite that + has not implemented them returns [false] explicitly, + {!Rite.t.creed}/{!Rite.t.gloria}'s own documented default. Made + overridable ([?creed]/[?gloria] below) on the same footing as + [?readings] just above, for Task 6's own fixtures. *) let creed ~temporal:_ ~observed:_ ~date:_ = false + let gloria ~temporal:_ ~observed:_ ~date:_ = false let rite ?(vocab = vocab) ?(anchors = fun _ -> []) ?(season_runs = [ A; B ]) ?(rules = rules) - ?(transfer_target = fun _ origin _ -> origin) ?(readings = readings) ?(creed = creed) temporal - : (season, rank) Rite.t = + ?(transfer_target = fun _ origin _ -> origin) ?(readings = readings) ?(creed = creed) + ?(gloria = gloria) temporal : (season, rank) Rite.t = { Rite.id = "synthetic"; vocab; year_start; temporal; anchors; rules; season_runs; (* Not a Roman rite, but a Rite.t must supply SOME Easter now that movable Date_spec variants exist. The Gregorian one is as good as @@ -342,7 +344,7 @@ module Synthetic = struct (* Not a Roman rite either, so no bissextile-doubling convention: identity, {!Rite.t.fixed_key}'s own documented default. *) fixed_key = (fun d -> Some (D.month d, D.day d)); - transfer_target; readings; creed } + transfer_target; readings; creed; gloria } (* Empty by default: every check built before Task 12 exercises the TEMPORAL-only pass, where an empty layer is exactly the fixture that diff --git a/tools/extract_fiuv_ordo.ml b/tools/extract_fiuv_ordo.ml index 42d3b96..c9688a7 100644 --- a/tools/extract_fiuv_ordo.ml +++ b/tools/extract_fiuv_ordo.ml @@ -292,7 +292,28 @@ let extract_te_deum full_text = | None -> String.length full_text in let span = String.sub full_text mat_start (laudes_start - mat_start) in + (* TWO negative phrasings the source actually uses, found live + (celebrant-rubrics-phase1 Phase 2, 2026-08-22): "non dicitur Te + Deum" (e.g. ordinary Time-after-Pentecost ferias, 27/28 November) + AND, separately, "sine Te Deum" (e.g. every Sunday, every Ember + day, every privileged Lenten/Passiontide feria carrying a + commemoration -- Advent I, 30 November: "...3a de homilia (cum + suo R), sine Te Deum."). The ORIGINAL version of this function + checked only the first phrasing, so "sine Te Deum" fell through + to the bare "Te Deum" substring test and was wrongly read as a + POSITIVE hit -- confirmed by grepping the raw pdftotext dump + directly against a first, uncorrected run's own output: EVERY + date this bug affected showed "sine Te Deum" in the source and + [Some true] in the fixture, a 100% correlation, not a handful of + coincidences. This is the SAME "does the source negate the + hymn's own name with a DIFFERENT word than the one this parser + already checks for" shape [find_word]'s own "Gloria Patri" + substring trap already documents for Gloria -- this trap simply + went unnoticed until Phase 2 actually compared the extracted + values against colitur's own output and against the raw text by + hand, rather than only checking coverage counts. *) if contains span ~sub:"non dicitur Te Deum" then Some false + else if contains span ~sub:"sine Te Deum" then Some false else if contains span ~sub:"Te Deum" then Some true else None) -- cgit v1.3 From 184b3d677764524f58a28d7b4683a2a91a689555 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Sat, 22 Aug 2026 17:59:45 +0200 Subject: docs(F1): settle the Good Friday Gloria on the source's own evidence F1 adjudicated the FIUV ordo's Good Friday "Gloria" against the ordo, but rested on external attestation and left a pdftotext misread unruled-out. The page image resolves both. The extraction is faithful: the printed book does carry that line. So the adjacent-block-misread possibility is ruled out rather than merely doubted. And the same page shows the compiler knew the distinction. Holy Saturday, its next entry, carries no Mass line at all -- correctly. Easter, the entry after, carries a full one -- correctly. Good Friday, which likewise has no Mass, wrongly receives one, word-for-word identical to Holy Thursday's on the preceding page, while its own Vespers rubric four lines below calls the day's rite an Actio liturgica rather than a Mass. Verdict unchanged. It now rests on internal evidence from the source rather than on every other authority disagreeing, which is the footing this project's own standard asks for. --- data/ef/expected-divergences-fiuv.sexp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'data/ef') diff --git a/data/ef/expected-divergences-fiuv.sexp b/data/ef/expected-divergences-fiuv.sexp index 6ed9a04..6a40838 100644 --- a/data/ef/expected-divergences-fiuv.sexp +++ b/data/ef/expected-divergences-fiuv.sexp @@ -81,6 +81,32 @@ ; misread (a stray line from an adjacent block folded into this one) is ; not fully ruled out either -- named as a real possibility, not ; silently excluded. +; +; RESOLVED 2026-08-22 (coordinator): the page IMAGE was rendered and read +; (pdftoppm -f 48, the PDF page bearing printed folio 46). TWO findings. +; FIRST, the pdftotext layer is FAITHFUL -- the printed book really does +; carry "Missa pr., (omittuntur ps. Iudica me et Gloria Patri), Gloria, +; sine Credo, praef. comm." under FERIA VI IN PASSIONE ET MORTE DOMINI, so +; the adjacent-block-misread possibility named above is RULED OUT, not +; merely unlikely. +; SECOND, and this is what settles the adjudication rather than resting it +; on external attestation: the SAME PAGE proves the compiler knew the +; distinction and lost it here specifically. Its next entry, "4. Viol ... +; SABBATUM SANCTUM", carries NO "Missa pr." line at all -- correctly, Holy +; Saturday's own Mass being the Vigil's. The entry after it, "5. Alb DOM. +; RESURRECTIONIS", carries a full one. So on one page the book omits the +; Mass line where there is no Mass, and supplies one where there is; Good +; Friday, which likewise has none, wrongly receives one. Its own Vespers +; rubric on the same entry calls the day's rite "Actioni liturgicae +; vespertinae" -- an Action, not a Mass -- contradicting the Mass line four +; lines above it. +; The line is also WORD-FOR-WORD identical to Holy Thursday's own on the +; preceding page ("(omittuntur ps. Iudica me et Gloria Patri), Gloria, sine +; Credo"), where every word of it is correct. A copied line, not a +; considered statement. +; Verdict unchanged (colitur), now on internal evidence from the source +; itself rather than on "every other authority disagrees" -- which is the +; stronger footing, and the one this project's own standard asks for. ; F3 -- OPEN, single-witnessed, colitur's own possible gap (Te Deum ; axis). Fires 6 times, every one of the six dates -- cgit v1.3 From e5e304c4004089ea75ea472ebd56414197a4190f Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Sat, 22 Aug 2026 18:46:27 +0200 Subject: fix(ordo): correct L5/F3 misadjudication -- Cum Sanctissima, not a gap data/ef/expected-divergences-lms.sexp's L5 (16 dates, LMS Ordo Gloria=true vs colitur's false) and data/ef/expected-divergences-fiuv.sexp's F3 (6 dates, FIUV Te Deum=true vs colitur's false) were both misadjudicated as colitur's own gap under an RG 302(b)/431(b) hypothesis. Both are wrong. These are occurrence differences from the 2020 decree Cum Sanctissima, which colitur excludes from its 1962 core by binding design (CLAUDE.md decision 2). RG 303(b) ("dici potest tantum si occurrit dies liturgicus IV classis") already prohibits 302(b) on the Class3 privileged ferias both entries cover -- the original text quoted 303(b) but never followed it to its conclusion. Decisively, the FIUV Ordo prints BOTH readings on the six shared dates, separated by a literal "-VEL-" token: the primary, strict- 1962 reading (feria wins, sine Gloria, no Te Deum) matches colitur exactly; the second, Cum-Sanctissima reading (saint kept, Gloria, Te Deum) matches the LMS Ordo exactly. F3 itself was never a real Te Deum finding: tools/extract_fiuv_ordo.ml's extract_te_deum scanned each block unbounded for "Ad Mat.", so on these six days -- whose primary office states no "Ad Mat." of its own -- it silently read the second office's own Te Deum instead. Fixed with a new split_at_alt_office, cutting every block at "-VEL-" before any field extraction runs; the alternative is captured, not discarded, in a new alt_te_deum field. A hard characterisation probe asserts the split fires on exactly the six known dates. Auditing for the same trap elsewhere (this is the third such manufactured divergence in this project) found a related but narrower marker, "Vel (sec. decretum <>) Missa ...", offering an alternate Mass formulary within a single office. It never corrupted Gloria/Credo (always stated before the marker on all 20 real instances, confirmed by diff), only the uncompared praef field; hardened defensively anyway, before it could ever fire live. The LMS Ordo (all three editions) carries no equivalent dual-print mechanism at all. expected-divergences-missalemeum.sexp's M27 is the same genus but was already correctly adjudicated, not touched. Both allow-list entries are rewritten, not deleted: the original SHAPE/ CITATION/WHY-NOT-FIXED-HERE reasoning is preserved verbatim as a recorded, superseded hypothesis, matching this project's own correction convention. test_lms_ordo.ml's matching predicate is unchanged (the 16-date population still fires, and always will, because it reflects a standing exclusion, not a bug); only its citation comment is corrected. test_fiuv_ordo.ml's F3-specific predicate/count assertion is removed, matching this file's own prior F2/F4 closure discipline. lib/ is untouched. dune test: 676/676. make check (COLITUR_EXHAUSTIVE_SWEEP=1, full 1583-9999 domain): 678/678. --- data/ef/expected-divergences-fiuv.sexp | 148 +++- data/ef/expected-divergences-lms.sexp | 140 +++- test/fixtures/fiuv-ordo-2025-2026.sexp | 1162 +++++++++++++++++++------------- test/test_fiuv_ordo.ml | 77 ++- test/test_lms_ordo.ml | 22 +- tools/extract_fiuv_ordo.ml | 221 +++++- 6 files changed, 1210 insertions(+), 560 deletions(-) (limited to 'data/ef') diff --git a/data/ef/expected-divergences-fiuv.sexp b/data/ef/expected-divergences-fiuv.sexp index 6a40838..c8f1e21 100644 --- a/data/ef/expected-divergences-fiuv.sexp +++ b/data/ef/expected-divergences-fiuv.sexp @@ -41,6 +41,14 @@ ; separate regression this same fix round found and reverted (a first ; attempt at "every Sunday says Te Deum" wrongly excluded Christ the ; King, caught by the LMS Ordo's own Gloria axis, 2024-10-27). +; +; F3 was ALSO found to be the same GENUS of extractor bug -- a different +; PARSER shape (not a negation word, an unbounded scan reading a second, +; "-VEL-"-separated printed office instead of the primary one) -- and is +; likewise now CLOSED (l5-f3-readjudication task, 2026-08-22). See F3's +; own rewritten entry below for the full account, including why the +; original finding was misadjudicated as "colitur's own gap" rather than +; recognised as an extraction defect from the start. ; F1 -- OPEN, adjudicated FOR colitur. Fired once: 2026-04-03, Good ; Friday. @@ -108,39 +116,111 @@ ; itself rather than on "every other authority disagrees" -- which is the ; stronger footing, and the one this project's own standard asks for. -; F3 -- OPEN, single-witnessed, colitur's own possible gap (Te Deum -; axis). Fires 6 times, every one of the six dates -; data/ef/expected-divergences-lms.sexp's own L5 already found for -; Gloria: 2026-03-06/07/09/12/21/24, a privileged Lenten or Passiontide -; feria (Class3, RG25) whose own office is impeded and carries exactly -; one commemoration of a Class3 saint. colitur's [te_deum] reads [false] -; (a plain ferial office by every branch {!Rite_ef.Rubrics_ef.te_deum} -; checks); FIUV reads [true] in all six -- confirmed directly against -; the raw pdftotext dump, not merely the fixture: e.g. 12 March, "Ll. 1a -; et 2a (= 2a+3a) de Scr. occ., 3a de festo, Te Deum." -- a genuine, -; unnegated "Te Deum" (neither of the two negative phrasings the -; extractor now checks for), so this is NOT the same failure mode F2/F4 -; were. +; F3 -- CLOSED, MISADJUDICATED, NOW FIXED AT THE SOURCE +; (l5-f3-readjudication task, 2026-08-22). This entry previously read +; "OPEN, single-witnessed, colitur's own possible gap" -- WRONG, and not +; a Te Deum question at all: it was tools/extract_fiuv_ordo.ml's own +; [extract_te_deum] reading the WRONG PRINTED OFFICE on these six dates. +; +; THE ORIGINAL, SUPERSEDED FINDING -- preserved below verbatim, the same +; "retain the wrong reading and say why it was wrong" convention this +; file's own F1 history and data/ef/expected-divergences-lms.sexp's own +; L3/L5 already establish, NOT deleted: fires 6 times, every one of the +; six dates data/ef/expected-divergences-lms.sexp's own L5 already found +; for Gloria: 2026-03-06/07/09/12/21/24, a privileged Lenten or +; Passiontide feria (Class3, RG25) whose own office is impeded and +; carries exactly one commemoration of a Class3 saint. colitur's +; [te_deum] reads [false] (a plain ferial office by every branch +; {!Rite_ef.Rubrics_ef.te_deum} checks); FIUV reads [true] in all six -- +; confirmed directly against the raw pdftotext dump, not merely the +; fixture: e.g. 12 March, "Ll. 1a et 2a (= 2a+3a) de Scr. occ., 3a de +; festo, Te Deum." -- a genuine, unnegated "Te Deum" (neither of the two +; negative phrasings the extractor now checks for), so this is NOT the +; same failure mode F2/F4 were. (This description of what the raw text +; SAYS is still accurate -- the error was reading it from the wrong +; PLACE in the block, below, not misreading the words themselves.) +; +; CITATION [SUPERSEDED, see THE CORRECTION below]: the same +; n.302(b)/RG431(b) text L5 already cites (LT.txt -- a MISSAL rubric, not +; a Breviary one, so its literal text governs the MASS's own Gloria, not +; Matins' Te Deum) does not directly license this finding at all -- +; 237/238 (the BREVIARY rubric {!Rite_ef.Rubrics_ef.te_deum} actually +; implements) has no clause naming a commemoration as grounds for Te +; Deum. What this finding suggested, not established: the DIVINE OFFICE +; may treat a commemorated day more generously than the MASS does for +; exactly this shape (a commemorated saint's own lessons are read at +; Matins even on an impeded day, which could plausibly extend to Te Deum +; by an unwritten or unlocated convention) -- genuinely speculative, +; offered as a research lead for a follow-on task, not a citation this +; entry treated as settled. (There was no such convention: see below.) +; +; WHY NOT FIXED HERE [SUPERSEDED]: SINGLE-WITNESSED (the LMS fixtures +; never captured Te Deum at all, so there is no second Ordo to +; corroborate this shape the way the Sacred-Triduum/BVM-Saturday/vigil +; findings elsewhere in this task were cross-checked). Fixing it would +; need the SAME kernel signature widening L5 already declines for the +; identical reason (`~commemorations` on {!Colitur_kernel.Rite.t.gloria}, +; and by extension a parallel widening of [te_deum] if the two were ever +; to diverge in their own inputs) -- out of a task briefed to follow +; creed's existing seam exactly. Left OPEN for the same follow-on task L5 +; recommends. (No kernel change was ever needed -- the bug was entirely +; inside the EXTRACTOR, tools/, never inside lib/.) +; +; THE CORRECTION, in full (l5-f3-readjudication task, 2026-08-22): FIUV +; prints a "-VEL-" ("or") separator on these exact six dates, dividing +; each day's block into a PRIMARY, strict-1962 office (the feria wins, +; "sine Gloria", the saint commemorated, no "Ad Mat." lessons mentioned +; at all -- an ordinary privileged feria's Matins needs no special note) +; and a SECOND, complete alternative office under the 2020 decree Cum +; Sanctissima (the saint kept outright, "Off. ordinarium", with its OWN +; "Ad Mat. ... Te Deum" lessons). tools/extract_fiuv_ordo.ml's own +; [extract_te_deum] scanned the WHOLE block for "Ad Mat." unbounded, so +; on these six days it silently read the SECOND office's own Te Deum +; instead of the PRIMARY's -- manufacturing a same-day contradiction with +; colitur that this entry first recorded as "colitur's own possible +; gap". There was never a genuine Office-vs-Mass question, and no +; DIVINE-OFFICE convention naming a commemoration as grounds for Te +; Deum: the "unnegated Te Deum" the original finding quoted was real +; text, just read from the wrong printed office. +; +; Fixed in tools/extract_fiuv_ordo.ml's own [split_at_alt_office] (see +; its own citation, module header point 5): every field extractor now +; reads the PRIMARY office only, cut at the "-VEL-" token before any +; field extraction runs. [te_deum] now reads [None] (unresolved) on +; these six dates -- the primary office states no "Ad Mat." of its own, +; so there is nothing to positively confirm either direction from, the +; same meaning [None] already carries elsewhere in this fixture. The +; alternative office's own Te Deum is captured, not discarded, in a new +; [alt_te_deum] field (still [true] on all six -- the extraction was +; never wrong about what the SECOND office says, only about which +; office [te_deum] itself should report). ; -; CITATION: the same n.302(b)/RG431(b) text L5 already cites (LT.txt -- -; a MISSAL rubric, not a Breviary one, so its literal text governs the -; MASS's own Gloria, not Matins' Te Deum) does not directly license this -; finding at all -- 237/238 (the BREVIARY rubric {!Rite_ef.Rubrics_ef. -; te_deum} actually implements) has no clause naming a commemoration as -; grounds for Te Deum. What this finding suggests, not yet established: -; the DIVINE OFFICE may treat a commemorated day more generously than the -; MASS does for exactly this shape (a commemorated saint's own lessons -; are read at Matins even on an impeded day, which could plausibly extend -; to Te Deum by an unwritten or unlocated convention) -- genuinely -; speculative, offered as a research lead for a follow-on task, not a -; citation this entry treats as settled. +; VERIFIED, not merely argued: re-extracted from the SAME pdftotext dump +; (SHA-256 of the source PDF unchanged, fixture header above). Exactly 6 +; of 400 rows changed, every one Te Deum true->unresolved, on precisely +; these six dates and no others (a hard characterisation probe in +; tools/extract_fiuv_ordo.ml now asserts this population is EXACTLY +; these six, not merely observed once). Gloria, Credo, class_, title and +; praef are UNCHANGED on all 400 rows, confirmed by a direct diff of the +; fixture before and after -- those fields were already correctly +; bounded to the primary office (a Vespers-line token always intervened +; before "-VEL-" on all six real instances), so this was never a +; Gloria-axis bug, consistent with F1 and with L5's own six-date subset +; agreeing with colitur throughout. ; -; WHY NOT FIXED HERE: SINGLE-WITNESSED (the LMS fixtures never captured -; Te Deum at all, so there is no second Ordo to corroborate this shape -; the way the Sacred-Triduum/BVM-Saturday/vigil findings elsewhere in -; this task were cross-checked). Fixing it would need the SAME kernel -; signature widening L5 already declines for the identical reason -; (`~commemorations` on {!Colitur_kernel.Rite.t.gloria}, and by extension -; a parallel widening of [te_deum] if the two were ever to diverge in -; their own inputs) -- out of a task briefed to follow creed's existing -; seam exactly. Left OPEN for the same follow-on task L5 recommends. +; VERDICT: colitur correct; the LMS Ordo (L5) and the FIUV Ordo's own +; "-VEL-" alternative both, correctly, describe the SAME Cum-Sanctissima +; calendar colitur excludes by binding design (CLAUDE.md decision 2). +; See L5's own rewritten entry (data/ef/expected-divergences-lms.sexp) +; for the full account, including the "-VEL-" dual printing quoted there +; as the decisive evidence for BOTH entries. NOT an active +; machine-checked [id] entry, matching this file's own F1/F2/F4 +; precedent -- the real enforcement was test_fiuv_ordo.ml's own +; [is_f3_lenten_commemoration] predicate and [f3_count] assertion, BOTH +; REMOVED (same task): with the extractor fixed, this shape produces no +; mismatch at all any more (matched by the general [None]-skips- +; comparison branch every other unresolved-Te-Deum row already uses), +; so a dedicated predicate/count pin would be dead code -- the same "an +; entry that stops firing is a real change, not silently absorbed" +; discipline data/ef/expected-divergences-lms.sexp's own L1/L3 closures, +; and this file's own F2/F4 closure, already establish. diff --git a/data/ef/expected-divergences-lms.sexp b/data/ef/expected-divergences-lms.sexp index df813f9..d91028a 100644 --- a/data/ef/expected-divergences-lms.sexp +++ b/data/ef/expected-divergences-lms.sexp @@ -10,6 +10,11 @@ ; Gloria (RG431-432) -- both fire in more than one window, at DIFFERENT ; counts per window, so both are prose-only (L2's own precedent), not ; machine-checked [id] records; see each for the real enforcement site. +; L5 was MISADJUDICATED as "colitur's own gap" and CORRECTED +; (l5-f3-readjudication task, 2026-08-22): see L5's own entry for the +; full account -- it is an OCCURRENCE difference (the LMS Ordo follows +; the 2020 decree Cum Sanctissima, colitur excludes it by binding +; design), not a Gloria defect. ; ; A SEPARATE file from data/ef/expected-divergences.sexp (the lectio ; allow-list) and data/ef/expected-divergences-missalemeum.sexp (the @@ -233,14 +238,32 @@ (note "2023-12-24 (the 4th Sunday of Advent AND Christmas Eve, a genuinely rare coincidence -- roughly 1 year in 7 -- absent from both the 2024-2025 and 2025-2026 windows, where Christmas Eve falls on a Tuesday and a Wednesday respectively). colitur says the Creed IS said (true), reading [temporal]'s own weekday (Sunday) per RG475(a)'s clause, positioned ahead of the vigil-exclusion check in {!Rite_ef.Rubrics_ef.creed} -- unconditionally, the same way it already does for RG16(a)'s Feast-of-the-Lord case. The Ordo says \"No Gl No Cr\" for this date. ADJUDICATED FOR COLITUR, not merely left open by default: RG30(a)'s own \"locum tenet ... nulla fit commemoratio\" language is textually closer to RG16(a) (which colitur already treats as Creed-preserving) than to an ordinary vigil superseding a Sunday -- the Vigil does not merely WIN THE DAY, it takes the SUNDAY'S OWN IDENTITY, the same shape RG475(a) was written to reach. The COUNTER-reading is real and not dismissed here: RG475(a)'s own text says \"locum cedat ... festo\" (gives way to a FEAST), and RG35 (Caput VI) classifies feria/vigilia/festum as three distinct liturgical-day categories -- a strict textual reading could confine 475(a)'s override to FEAST-displacement only, leaving a VIGIL-displaced Sunday to fall through to the general vigil exclusion (476, via RG33's own \"a vigil is a distinct category\" reasoning already coded elsewhere in {!Rite_ef.Rubrics_ef.creed}). Left OPEN rather than closed on this task's own authority: adjudicating scripture-grade primary-source questions is out of scope for a witness-wiring task, and the two readings are both defensible. Not fixable inside this task's own no-lib-changes constraint regardless of which reading eventually wins.") (expected_rows 1)) -; L5 -- OPEN, colitur's own gap, found extending this suite to the Gloria -; axis (celebrant-rubrics-phase1 Phase 2, 2026-08-22). NOT an active -; machine-checked [id] entry -- same reasoning L2 above gives: the count -; varies window to window (5 in 2023-2024, 5 in 2024-2025, 6 in -; 2025-2026), so a single static [expected_rows] cannot check it. The REAL -; enforcement is test_lms_ordo.ml's own [is_l5_lenten_commemoration] +; L5 -- MISADJUDICATED, NOW CORRECTED (l5-f3-readjudication task, +; 2026-08-22). This entry previously read "OPEN, colitur's own gap" -- +; WRONG, on two independent grounds (below). It is NOT a Gloria defect +; of colitur's. It is NOT a rubric dispute at all: it is an OCCURRENCE +; difference, because the LMS Ordo is compiled to the 2020 decree Cum +; Sanctissima (its own introduction says so, docs/research/ordo/ +; PROVENANCE-lms.md) and colitur excludes that decree from its 1962 core +; by BINDING DESIGN (CLAUDE.md decision 2: "Every addition [2020 Quo +; Magis/Cum Sanctissima, any community's proper] is an overlay, never +; core"). On these 16 dates colitur and the LMS Ordo each correctly +; describe a DIFFERENT, both genuine, calendar -- they were never +; disagreeing about the same one. VERDICT: colitur correct. NOT an +; active machine-checked [id] entry -- same reasoning L2 above gives: +; the count varies window to window (5 in 2023-2024, 5 in 2024-2025, 6 +; in 2025-2026), so a single static [expected_rows] cannot check it. The +; REAL enforcement is test_lms_ordo.ml's own [is_l5_lenten_commemoration] ; predicate plus [make_suite]'s own ~expected_gloria_l5 parameter, -; asserted per window directly. +; asserted per window directly -- KEPT, unlike a bug-driven divergence +; that stops firing once fixed (data/ef/expected-divergences-fiuv.sexp's +; own F3, closed by this same task, is that other shape): this one is +; EXPECTED TO RECUR IN EVERY FUTURE WINDOW, because the exclusion it +; reflects is a standing design decision, not a defect to remove. +; +; THE ORIGINAL, SUPERSEDED HYPOTHESIS -- preserved below verbatim, the +; same "retain the wrong reading and say why it was wrong" convention +; L3's and F1's own history in this file already establish, NOT deleted: ; ; SHAPE, identical in all 16 instances found (5+5+6, zero exceptions): ; a privileged Lenten or Passiontide feria (Class3, violet -- RG25, @@ -251,6 +274,8 @@ ; day is a plain ferial office by every test [Rite_ef.Rubrics_ef.te_deum] ; runs -- no Sunday, no vigil, no octave, [named] = [None], [subject] = ; [Temporal]); the Ordo reads [true] in every one of the 16 instances. +; (This description of the SHAPE is still accurate -- what was wrong is +; the CONCLUSION drawn from it, below.) ; ; CITATION (docs/research/LT.txt:2359-2361, "V - De Missis festivis", ; quoted in rubrics_ef.ml's own [gloria] header in full): "302. Sensu @@ -263,7 +288,9 @@ ; ferial Office, carrying a commemoration, is elevated to "festive" status ; for the Gloria specifically. ; -; WHY NOT FIXED HERE: n.303(b), the very next paragraph (LT.txt:2359-2367, +; WHY NOT FIXED HERE (the original text, which already quoted the very +; clause that defeats its own hypothesis, below, but did not follow it +; to its conclusion): n.303(b), the very next paragraph (LT.txt:2359-2367, ; same quote in rubrics_ef.ml), qualifies n.302(b)'s own Masses: "dici ; potest tantum si occurrit dies liturgicus IV classis" -- CAN ONLY BE ; SAID if the liturgical day occurring is IV class. Every instance found @@ -273,29 +300,29 @@ ; project's sources), which may clarify that 301-303 govern which Mass a ; priest may freely CHOOSE among several options in one church on one day ; (a dimension colitur does not model -- see [gloria]'s own SCOPE NOTE), -; a different question from \"does THE Mass actually said, once -; determined, say the Gloria\" (431(b)'s own question). Implementing this +; a different question from "does THE Mass actually said, once +; determined, say the Gloria" (431(b)'s own question). Implementing this ; also has a real architectural cost this task's own instructions ; explicitly avoided: [Rite_ef.Rubrics_ef.gloria] would need a FOURTH ; parameter, the day's own {!Colitur_kernel.Liturgical_day.t.commemorations} ; -- a kernel [Rite.t.gloria] signature change, the same shape RG16(a)'s ; own [admit] fix needed a [~temporal] parameter for, and squarely out of -; a task briefed to \"follow exactly how creed was wired -- same seam\". +; a task briefed to "follow exactly how creed was wired -- same seam". ; Left OPEN, not guessed into a possibly-wrong rule. Recommended for a ; follow-on task, ideally alongside Phase 3's Preface work (RG483 governs ; a DIFFERENT, but textually adjacent, commemoration-vs-Mass-part ; question, so the two may share the same kernel signature widening). ; -; UPDATE (same task, after wiring the FIUV Ordo's own Gloria and Te Deum -; axes, test_fiuv_ordo.ml): this paragraph previously said FIUV's own -; [gloria] axis was not compared at all. It now is, and the result +; UPDATE (same original task, after wiring the FIUV Ordo's own Gloria and +; Te Deum axes, test_fiuv_ordo.ml): this paragraph previously said FIUV's +; own [gloria] axis was not compared at all. It now is, and the result ; WEAKENS this entry's own case rather than strengthening it: FIUV's own ; [gloria] is [false] on all six of these exact dates in its window -- ; AGREEING WITH COLITUR, DIRECTLY CONTRADICTING the LMS Ordo's [true] -; above. So this is not \"colitur has a corroborated gap\", it is \"two +; above. So this is not "colitur has a corroborated gap", it is "two ; independent Ordos disagree with EACH OTHER on Gloria for this shape, ; and colitur happens to agree with the universal one, not the diocesan -; one\". What FIUV's OWN Te Deum axis DOES show for the identical six +; one". What FIUV's OWN Te Deum axis DOES show for the identical six ; dates: [true] -- Te Deum, unlike Gloria, genuinely IS said at Matins on ; these days (data/ef/expected-divergences-fiuv.sexp's own F3), a real, ; single-witness finding that this entry's own n.302(b)/431(b) citation @@ -303,8 +330,85 @@ ; mean L5 itself is answering the wrong question, not merely open. ; Genuinely uncertain which of the two Mass-Gloria witnesses (LMS or ; FIUV) is right for this shape; left OPEN, not adjudicated either way, -; for a follow-on task with more primary-source access than this one -; had. +; for a follow-on task with more primary-source access than this one had. +; (CORRECTED, l5-f3-readjudication task: F3's own "single-witness +; finding" was never a Te Deum finding at all -- it was +; tools/extract_fiuv_ordo.ml reading the WRONG PRINTED OFFICE, see below. +; There was no Office-vs-Mass question to be uncertain about.) +; +; THE CORRECTION, in full (l5-f3-readjudication task, 2026-08-22): +; +; 1. RG303(b) ALREADY DEFEATS the n.302(b)/431(b) hypothesis on its own +; terms -- the original text above quoted it but stopped short of the +; conclusion. Quoted again, in full, because it is the load-bearing +; sentence: "dici potest tantum si occurrit dies liturgicus IV +; classis" -- [a Mass "of a commemoration occurring in the day's own +; Office"] MAY BE SAID ONLY IF the liturgical day occurring is FOURTH +; class. A privileged Lenten or Passiontide feria is THIRD class +; (RG25) -- every one of these 16 instances. So n.302(b) is +; PROHIBITED, not merely inapplicable, on precisely the days this +; entry covers, and 431(b)'s own Gloria elevation, which depends on +; 302(b), can never reach them. Not "unresolved without n.304" as the +; original text guessed: 303(b) alone already closes the question, +; the wrong way for the original hypothesis. +; +; 2. THE FIUV ORDO PRINTS BOTH OPTIONS, and this is decisive on its own, +; independent of (1). All 16 LMS dates are Lenten/Passiontide +; privileged ferias; six of them fall inside the FIUV fixture's own +; 2025-2026 window (2026-03-06/07/09/12/21/24 -- the same six F3 +; named). For every one of the six, the raw FIUV source (verified +; directly against a fresh pdftotext -layout dump, not merely the +; fixture) prints TWO complete readings for the SAME civil date, +; separated by a literal "-VEL-" ("or") token. 24 March 2026, in +; full: +; +; 24. Viol Feria III post Dom. I Passionis, De ea, III cl. - Off. feriale temp. Passionis. +; Ad LAUDES ... comm. S Gabrielis Archangeli. +; Missa pr., (omittuntur ps. Iudica me et Gloria Patri), sine Gloria, comm. S +; Gabrielis Archangeli, sine Credo, praef. de Sancta Cruce or. super populum. +; I VESPERAE de seq., comm. huius diei. - Compl. de dom. +; -VEL- +; Feria III. S Gabrielis Archangeli, III cl. (Priv.) - Off. ordinarium. - Ad Mat. +; Ll. 1a et 2a (= 2a + 3a) de Scr. occ., 3a de festo, Te Deum. - Ad LAUDES comm. +; Feriae. +; Missa pr., Gloria, comm. Feriae, tractus, sine Credo, praef. de Sancta Cruce vel +; de Angelis. +; +; The FIRST option is strict 1962: the feria wins, "sine Gloria", no +; Te Deum stated, the saint merely commemorated -- EXACTLY colitur's +; own answer, field for field. The SECOND, after "-VEL-", is the +; Cum-Sanctissima-elevated option: the saint's own feast, "Off. +; ordinarium", Gloria, Te Deum, the feria commemorated instead -- +; EXACTLY the LMS Ordo's own answer. The FIUV Ordo's own title page +; states the convention this book uses throughout for exactly this +; distinction (N.B., page 1, verified directly against the PDF): +; "days of the third class to which the norms of the decree Cum +; santissima [sic] apply are marked 'III cl.' ... but days ... to +; which these norms do not apply are marked 'III cl. (Priv.)'." One +; document, compiled by a THIRD party independent of both colitur's +; own lineage and the LMS, prints BOTH engines' own answers side by +; side as two legitimate readings of two different calendars. There +; is no dispute left to adjudicate. +; +; So the Gloria and Te Deum RULES were never in dispute at all: each +; engine's answer follows correctly from its own occurrence result, on +; its own calendar. What this entry originally described as "colitur's +; own gap" is colitur correctly implementing the 1962 core it was built +; to implement, diverging from a printed book that, by its own +; introduction, deliberately implements something else. +; +; NOTE ALSO (so a reader arriving here from +; data/ef/expected-divergences-fiuv.sexp's own F3 does not draw the +; wrong conclusion from that entry's own closure): F3 did NOT +; "corroborate" or "contradict" L5 at any point in this history. Both +; were the same underlying fact read two different ways, and F3's own +; apparent Te Deum-true reading was never a real second data point in +; the first place -- it was tools/extract_fiuv_ordo.ml's own +; [extract_te_deum] silently reading the SECOND ("-VEL-") office's own +; Te Deum instead of the primary's, on exactly these six dates, closed +; by fixing the extractor (tools/extract_fiuv_ordo.ml's own +; [split_at_alt_office]), not by resolving any Office-vs-Mass question. +; See F3's own entry for the full account. ; L6 -- OPEN, root-caused to a DIFFERENT, PRE-EXISTING bug this Gloria ; comparison merely surfaced, not a Gloria defect itself. Fired once, diff --git a/test/fixtures/fiuv-ordo-2025-2026.sexp b/test/fixtures/fiuv-ordo-2025-2026.sexp index d31c5d5..2ea9913 100644 --- a/test/fixtures/fiuv-ordo-2025-2026.sexp +++ b/test/fixtures/fiuv-ordo-2025-2026.sexp @@ -95,1481 +95,1723 @@ ; below are what this fixture actually asserts, not a forced match to ; the brief's approximate figures. ; +; 5. THE ALTERNATIVE-OFFICE TRAP (celebrant-rubrics-phase1 Phase 2 +; correction, 2026-08-22, closing F3): six real days print BOTH a +; strict-1962 reading and a complete SECOND office (the same saint +; kept outright under the 2020 decree Cum Sanctissima), separated by +; a literal "-VEL-" token. [extract_te_deum] used to scan the WHOLE +; block unbounded, so on these six days -- whose PRIMARY office states +; no "Ad Mat." of its own -- it silently read the SECOND office's own +; Te Deum instead, manufacturing a same-day contradiction with colitur +; that F3 first recorded as "colitur's own possible gap". Every field +; now reads the PRIMARY office only (module header point 5 has the +; full account); the alternative is captured, not discarded, in its +; own [alt_te_deum] field. Confirmed to fire on EXACTLY six dates by a +; hard characterisation probe (this run's own output, above), not +; merely asserted here. +; ; MEASURED DISTRIBUTION (this extraction, not the brief's figures): Gloria ; true=269 false=130 unresolved=1; Credo true=116 false=283 unresolved=1; -; Te Deum true=207 false=66 unresolved=127. +; Te Deum true=201 false=66 unresolved=133; alt Te Deum (the six "-VEL-" +; Cum Sanctissima alternatives, point 5 above) true=6 false=0 none=394 +; (a day contributes to "none" here either because it has no "-VEL-" +; alternative at all -- 394 of 400 -- or, for a day that does, because +; that alternative's own text doesn't state Te Deum either; not +; distinguished by this one count). +; +; FIX HISTORY (fixed text, HISTORICAL counts from the run that found each +; bug, not re-verified live by every later run -- this section exists so +; regenerating this fixture from a fresh pdftotext dump, which rewrites +; this whole header from the template, does not silently erase either +; finding; earlier this header carried the first entry below as a +; hand-appended note that a regeneration between then and now had +; already dropped once): +; +; 1. RE-EXTRACTED (celebrant-rubrics-phase1 Phase 2, 2026-08-22): the FIRST +; extraction's own Te Deum parser recognised only ONE of the source's two +; negative phrasings ("non dicitur Te Deum") -- "sine Te Deum" (how the +; source actually negates a SUNDAY's own Te Deum, among others) fell +; through to a bare "Te Deum" substring match and was wrongly read +; [true]. Found by hand, comparing the raw pdftotext dump against this +; fixture's own values directly, not by any coverage check (both counted +; the same 127 unresolved rows before and after). Fixed in +; tools/extract_fiuv_ordo.ml's own [extract_te_deum] (see its own +; citation); this fixture re-extracted from the SAME pdftotext dump +; (SHA-256 of the source PDF unchanged, above). 24 of 400 rows changed, +; every one Te Deum true->false, every one independently confirmed +; against the raw text: true 231->207, false 42->66, unresolved 127 +; unchanged. See lib/rites/rite_ef/rubrics_ef.ml's own [te_deum] header +; (237(a)'s comment) for the full account of what this corrected, and +; the .superpowers task report for the complete before/after date list. ; -; RE-EXTRACTED (celebrant-rubrics-phase1 Phase 2, 2026-08-22): the FIRST -; extraction's own Te Deum parser recognised only ONE of the source's two -; negative phrasings ("non dicitur Te Deum") -- "sine Te Deum" (how the -; source actually negates a SUNDAY's own Te Deum, among others) fell -; through to a bare "Te Deum" substring match and was wrongly read -; [true]. Found by hand, comparing the raw pdftotext dump against this -; fixture's own values directly, not by any coverage check (both counted -; the same 127 unresolved rows before and after). Fixed in -; tools/extract_fiuv_ordo.ml's own [extract_te_deum] (see its own -; citation); this fixture re-extracted from the SAME pdftotext dump -; (SHA-256 of the source PDF unchanged, above). 24 of 400 rows changed, -; every one Te Deum true->false, every one independently confirmed -; against the raw text: true 231->207, false 42->66, unresolved 127 -; unchanged. See lib/rites/rite_ef/rubrics_ef.ml's own [te_deum] header -; (237(a)'s comment) for the full account of what this corrected, and -; the .superpowers task report for the complete before/after date list. +; 2. RE-EXTRACTED (celebrant-rubrics-phase1 Phase 2 correction, 2026-08-22): +; module header point 5 and CHARACTERISATION point 5 above have the +; full account of the "-VEL-" alternative-office bug this closes +; (data/ef/expected-divergences-fiuv.sexp's own F3). This fixture +; re-extracted from the SAME pdftotext dump (SHA-256 of the source PDF +; unchanged, above). 6 of 400 rows changed, every one Te Deum +; true->unresolved (2026-03-06/07/09/12/21/24), every one independently +; confirmed against the raw text: Te Deum true 207->201 (this run's own +; unresolved count went 127->133, consistent with those same 6 rows). +; Gloria/Credo/class_/title/praef are UNCHANGED on all 400 rows -- +; those fields were already correctly bounded to the primary office +; before this fix (a Vespers-line token always intervened before the +; "-VEL-" separator on all six real instances), confirmed by a direct +; diff of the fixture before and after, not merely by argument. +; +; 3. RE-EXTRACTED (celebrant-rubrics-phase1 same correction, defensive +; hardening, 2026-08-22): auditing for the SAME trap elsewhere (the +; task brief's own item 5) found a THIRD, narrower alternate-Mass +; marker, "Vel (sec. decretum <>) Missa ...", offering a +; Cum-Sanctissima Mass FORMULARY choice within a single office +; (unlike point 5 above, no second "Ad Mat." set of lessons -- a +; narrower thing than a full alternate office). 20 occurrences in the +; whole corpus, confirmed by direct grep; on all 20, Gloria/Credo were +; ALREADY stated before reaching this marker, so this was NEVER a +; live divergence for those two fields (confirmed by this same diff: +; 0 Gloria/Credo/class_/title/alt_te_deum rows changed). [praef] +; alone changed on 20 of 400 rows (its own "rest of the primary +; clause" capture no longer runs past this marker into the +; alternative's own text) -- harmless in itself ([praef] is +; documented CAPTURED, NOT VALIDATED, compared by nothing), but added +; as a defensive boundary in [extract_missa_fields] so a FUTURE year +; whose primary clause does not restate Gloria/Credo before this +; marker cannot silently read the alternative's own value instead -- +; the identical failure shape as point 2 above, closed before it was +; ever observed live rather than after. (((date 2025-11-27) (class_ ("IV cl.")) (title "Vir Feria V post Dom. XXIV & Ultima post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2025-11-28) (class_ ("IV cl.")) (title "Vir Feria VI post Dom. XXIV & Ultima post Pentecosten, De ea,") - (te_deum (false)) (gloria (false)) (credo (false)) (praef (comm.))) + (te_deum (false)) (gloria (false)) (credo (false)) (praef (comm.)) + (alt_te_deum ())) ((date 2025-11-29) (class_ ("IV cl.")) (title "Alb Sabb. S. Maria in Sabbato,") (te_deum (true)) (gloria (true)) - (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147"))) + (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147")) + (alt_te_deum ())) ((date 2025-11-30) (class_ ("I cl.")) (title "Viol DOM. I ADVENTUS, De ea,") (te_deum (false)) (gloria (false)) - (credo (true)) (praef ("Trinit. Ad II"))) + (credo (true)) (praef ("Trinit. Ad II")) (alt_te_deum ())) ((date 2025-12-01) (class_ ("III cl.")) (title "Viol Feria II post Dom. I Adventus, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef (comm.))) + (gloria (false)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2025-12-02) (class_ ("III cl.")) (title "Rub Feria III. S Bibianae Virg. et Mart.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. AD"))) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. AD")) + (alt_te_deum ())) ((date 2025-12-03) (class_ ("III cl. (Priv.)")) (title "Alb Feria IV. S Francisci Xavierii Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. AD"))) + (gloria (true)) (credo (false)) (praef ("comm. AD")) (alt_te_deum ())) ((date 2025-12-04) (class_ ("III cl.")) (title "Alb Feria V. S Petri Chrysologi Ep., Conf. et Eccl. Doct.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef - ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa S Barbarae Virg. et Mart. (rub.) Loquebar de testimoniis tuis, Gloria, comm. 1\194\170 Feriae, comm. 2\194\170 S Petri Chrysologi Ep., Conf. et Eccl. Doct., praef. comm. vel de Martyribus. AD"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2025-12-05) (class_ ("III cl.")) (title "Viol Feria VI post Dom. I Adventus, De ea,") (te_deum ()) (gloria (false)) (credo (false)) - (praef ("comm. Feria VI prima in mense."))) + (praef ("comm. Feria VI prima in mense.")) (alt_te_deum ())) ((date 2025-12-06) (class_ ("III cl. (Priv.)")) (title "Alb Sabb. S Nicolai Ep. et Conf.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. Sabbatum primum in mense. I"))) + (praef ("comm. Sabbatum primum in mense. I")) (alt_te_deum ())) ((date 2025-12-07) (class_ ("I cl.")) (title "Viol DOM. II ADVENTUS, De ea,") (te_deum (false)) - (gloria (false)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (false)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2025-12-08) (class_ ("I cl.")) (title "Alb Feria II. IN CONCEPTIONE IMMACULATA B. MARIAE VIRGINIS,") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("BMV Et te in Conceptione Immaculata. AD"))) + (praef ("BMV Et te in Conceptione Immaculata. AD")) (alt_te_deum ())) ((date 2025-12-09) (class_ ("III cl.")) (title "Viol Feria III post Dom. II Adventus, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef (comm.))) + (gloria (false)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2025-12-10) (class_ ("III cl.")) (title "Viol Feria IV post Dom. II Adventus, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef (comm.))) + (gloria (false)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2025-12-11) (class_ ("III cl. (Priv.)")) (title "Alb Feria V. S Damasi I Papae et Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. AD"))) + (gloria (true)) (credo (false)) (praef ("comm. AD")) (alt_te_deum ())) ((date 2025-12-12) (class_ ("III cl.")) (title "Viol Feria VI post Dom. II Adventus, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef (comm.))) + (gloria (false)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2025-12-13) (class_ ("III cl. (Priv.)")) (title "Rub Sabb. S Luciae Virg. et Mart.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. I"))) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. I")) + (alt_te_deum ())) ((date 2025-12-14) (class_ ("I cl.")) (title "Viol/ DOM. III ADVENTUS (GAUDETE), De ea,") (te_deum (false)) - (gloria (false)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (false)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2025-12-15) (class_ ("III cl.")) (title "Viol Feria II post Dom. III Adventus (Gaudete), De ea,") - (te_deum ()) (gloria (false)) (credo (false)) (praef (comm.))) + (te_deum ()) (gloria (false)) (credo (false)) (praef (comm.)) + (alt_te_deum ())) ((date 2025-12-16) (class_ ("III cl.")) (title "Alb Feria III. S Eusebii Ep. et Mart.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. AD"))) + (gloria (true)) (credo (false)) (praef ("comm. AD")) (alt_te_deum ())) ((date 2025-12-17) (class_ ("II cl.")) (title "Viol FERIA IV QUATTUOR TEMP., De ea,") (te_deum ()) (gloria (false)) (credo (false)) - (praef ("comm.\226\128\147 Quoad Flectamus genua vide RM 440."))) + (praef ("comm.\226\128\147 Quoad Flectamus genua vide RM 440.")) + (alt_te_deum ())) ((date 2025-12-18) (class_ ("II cl.")) (title "Viol FERIA V POST DOM. III ADVENTUS (GAUDETE), De ea,") - (te_deum ()) (gloria (false)) (credo (false)) (praef (comm.))) + (te_deum ()) (gloria (false)) (credo (false)) (praef (comm.)) + (alt_te_deum ())) ((date 2025-12-19) (class_ ("II cl.")) (title "Viol FERIA VI QUATTUOR TEMP., De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef (comm.))) + (gloria (false)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2025-12-20) (class_ ("II cl.")) (title "Viol SABB. QUATTUOR TEMP., De eo,") (te_deum ()) (gloria (false)) (credo (false)) (praef - ("comm. \226\128\147 Quoad Flectamus genua vide RM 440. Quoad lectiones vide RM 468. I"))) + ("comm. \226\128\147 Quoad Flectamus genua vide RM 440. Quoad lectiones vide RM 468. I")) + (alt_te_deum ())) ((date 2025-12-21) (class_ ("I cl.")) (title "Viol DOM. IV ADVENTUS, De ea,") (te_deum (false)) - (gloria (false)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (false)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2025-12-22) (class_ ("II cl.")) (title "Viol FERIA II POST DOM. IV ADVENTUS, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef (comm.))) + (gloria (false)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2025-12-23) (class_ ("II cl.")) (title "Viol FERIA III POST DOM. IV ADVENTUS, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef (comm.))) + (gloria (false)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2025-12-24) (class_ ("I cl.")) (title "Viol Feria IV. VIGILIA NATIVITATIS DOMINI,") (te_deum (false)) - (gloria (false)) (credo (false)) (praef ("comm. I"))) + (gloria (false)) (credo (false)) (praef ("comm. I")) (alt_te_deum ())) ((date 2025-12-25) (class_ ("I cl.")) (title "Alb Feria V. IN NATIVITATE DOMINI,") (te_deum ()) (gloria (true)) (credo (true)) (praef - ("et Communic. pr. per totam oct. \226\128\147 In Communicantes: in 1\194\170 Missa dicitur Noctem sacratissimam celebrantes, qua, in 2\194\170 et 3\194\170 Missa et per octavam Diem sacratissimum celebrantes, quo. \226\128\147 In 2\194\170 Missa (etiam in cantu) fit comm. S. Anastasi\195\166 * M. \226\128\147 In Missis in cantu, ad verba symboli Et incarnatus est\226\128\166 et homo factus est, omnes genuflectunt versus altare, non tantum cum a celebrante recitantur, sed etiam cum a choro canuntur (RM 518 b). II"))) + ("et Communic. pr. per totam oct. \226\128\147 In Communicantes: in 1\194\170 Missa dicitur Noctem sacratissimam celebrantes, qua, in 2\194\170 et 3\194\170 Missa et per octavam Diem sacratissimum celebrantes, quo. \226\128\147 In 2\194\170 Missa (etiam in cantu) fit comm. S. Anastasi\195\166 * M. \226\128\147 In Missis in cantu, ad verba symboli Et incarnatus est\226\128\166 et homo factus est, omnes genuflectunt versus altare, non tantum cum a celebrante recitantur, sed etiam cum a choro canuntur (RM 518 b). II")) + (alt_te_deum ())) ((date 2025-12-26) (class_ ("II cl.")) (title "Rub Feria VI. S STEPHANI * PROTOMARTYRIS,") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. AD"))) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. AD")) + (alt_te_deum ())) ((date 2025-12-27) (class_ ("II cl.")) (title "Alb Sabb. S IOANNIS * AP. ET EV.,") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. AD"))) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. AD")) + (alt_te_deum ())) ((date 2025-12-28) (class_ ("II cl.")) (title "Alb DOM. INFRA OCTAVAM NATIVITATIS, De ea,") (te_deum (true)) (gloria (true)) (credo (true)) - (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. Ad II"))) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. Ad II")) + (alt_te_deum ())) ((date 2025-12-29) (class_ ("II cl.")) (title "Alb FERIA II DOM. INFRA OCTAVAM NATIVITATIS, De ea,") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("de Nativ., Communic. de Nativ. diem sacratissimum."))) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum.")) + (alt_te_deum ())) ((date 2025-12-30) (class_ ("II cl.")) (title "Alb FERIA III DOM. INFRA OCTAVAM NATIVITATIS, De ea,") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("de Nativ., Communic. de Nativ. diem sacratissimum."))) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum.")) + (alt_te_deum ())) ((date 2025-12-31) (class_ ()) (title "Alb FERIA IV DOM. INFRA OCTAVAM NATIVITATIS, De ea. \226\128\147 Off. semifestivum. \226\128\147 Ad MAT. invit., hymnus, 9 antt. et 9 pss. cum ultimo V de festo Nativ., Ll. de Scr. occ. cum suis RR (ad 2um additur Gloria Patri)\226\128\147 Ad Laudes antt. de Nativ., pss. de dom., comm. S Silvestri I Papae et Conf. \226\128\147 Ad HORAS ant. et pss. de feria curr., rel ut in festo Nativ. \226\128\147 Ad Primam in R Br. V Qui natus es de Maria Virgine. Missa Puer natus de diebus infra octavam, Gloria, Credo, comm. S Silvestri I Papae et Conf., praef. de Nativ., Communic. de Nativ. diem sacratissimum. I VESPER\195\134 de seq. \226\128\147 Compl. de dom. Hodie ad solemnem recitationem hymni Te Deum, indulgentia plenaria lucrari potest. 16") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. I"))) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. I")) + (alt_te_deum ())) ((date 2026-01-01) (class_ ("I cl.")) (title "Al Feria V. OCTAVA NATIVITATIS,") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. II"))) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. II")) + (alt_te_deum ())) ((date 2026-01-02) (class_ ("IV cl.")) (title "Alb Feria VI post Octavam Nativitatis, De ea,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("de Nativ., sine Communic. pr. Feria VI prima in mense."))) + (praef ("de Nativ., sine Communic. pr. Feria VI prima in mense.")) + (alt_te_deum ())) ((date 2026-01-03) (class_ ("IV cl.")) (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) - (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147"))) + (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147")) + (alt_te_deum ())) ((date 2026-01-04) (class_ ("II cl.")) (title "Alb Dom. SS.MI NOMINIS IESU,") (te_deum ()) (gloria (true)) - (credo (true)) (praef ("de Nativ., sine Communic. pr. II"))) + (credo (true)) (praef ("de Nativ., sine Communic. pr. II")) + (alt_te_deum ())) ((date 2026-01-05) (class_ ("IV cl.")) (title "Alb Feria II post Octavam Nativitatis, De ea,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("de Nativ., sine Communic. pr. \226\128\147"))) + (praef ("de Nativ., sine Communic. pr. \226\128\147")) (alt_te_deum ())) ((date 2026-01-06) (class_ ("I cl.")) (title "Alb Feria III. IN EPIPHANIA DOMINI,") (te_deum ()) - (gloria (true)) (credo (true)) (praef ("et Communic pr. II"))) + (gloria (true)) (credo (true)) (praef ("et Communic pr. II")) + (alt_te_deum ())) ((date 2026-01-07) (class_ ("IV cl.")) (title "Alb Feria IV post Epiphaniam, De ea,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("de Epiphania."))) + (gloria (true)) (credo (false)) (praef ("de Epiphania.")) + (alt_te_deum ())) ((date 2026-01-08) (class_ ("IV cl.")) (title "Alb Feria V post Epiphaniam, De ea,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("de Epiphania."))) + (gloria (true)) (credo (false)) (praef ("de Epiphania.")) + (alt_te_deum ())) ((date 2026-01-09) (class_ ("IV cl.")) (title "Alb Feria VI post Epiphaniam, De ea,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("de Epiphania."))) + (gloria (true)) (credo (false)) (praef ("de Epiphania.")) + (alt_te_deum ())) ((date 2026-01-10) (class_ ("IV cl.")) (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) - (credo (false)) (praef ("BMV Et te in Veneratione. I"))) + (credo (false)) (praef ("BMV Et te in Veneratione. I")) (alt_te_deum ())) ((date 2026-01-11) (class_ ("II cl.")) (title "Alb Dom. I post Epiphaniam. SANCT\195\134 FAMILI\195\134 IESU, MARI\195\134, IOSEPH *,") - (te_deum ()) (gloria (true)) (credo (true)) (praef ("de Epiphania. II"))) + (te_deum ()) (gloria (true)) (credo (true)) (praef ("de Epiphania. II")) + (alt_te_deum ())) ((date 2026-01-12) (class_ ("IV cl.")) (title "Alb Feria II post Dom. I post Epiphaniam, De ea,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("de Epiphania."))) + (praef ("de Epiphania.")) (alt_te_deum ())) ((date 2026-01-13) (class_ ("II cl.")) (title "Alb Feria III. IN COMMEMORATIONE BAPTISMATIS D.N.I.C.,") - (te_deum ()) (gloria (true)) (credo (true)) (praef ("de Epiphania. Ad"))) + (te_deum ()) (gloria (true)) (credo (true)) (praef ("de Epiphania. Ad")) + (alt_te_deum ())) ((date 2026-01-14) (class_ ("III cl.")) (title "Alb Feria IV. S Hilarii Ep., Conf. et Eccl. Doct.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef - ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa S Felicis Presbyt. et Mart. (rub.) L\195\166tabitur iustus, Gloria, ors. pr., comm. S Hilarii Ep., Conf. et Eccl. Doct., praef. comm. vel de Martyribus. Ad"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-01-15) (class_ ("III cl.")) (title "Alb Feria V. S Pauli Primi Eremitae Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) - (praef - ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa S Mauri Abbatis. (alb.) Os iusti de Comm. Abb., Gloria, comm. S Pauli Primi Eremitae Conf., praef. comm."))) + (gloria (true)) (credo (false)) (praef ("comm. \226\128\147")) + (alt_te_deum ())) ((date 2026-01-16) (class_ ("III cl.")) (title "Rub Feria VI. S Marcelli I Papae et Mart.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus."))) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus.")) + (alt_te_deum ())) ((date 2026-01-17) (class_ ("III cl. (Priv.)")) (title "Alb Sabb. S Antonii Abb.,") (te_deum (true)) (gloria (true)) - (credo (false)) (praef ("comm. I"))) + (credo (false)) (praef ("comm. I")) (alt_te_deum ())) ((date 2026-01-18) (class_ ("II cl.")) (title "Vir DOM. II POST EPIPHANIAM, De ea,") (te_deum (true)) - (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-01-19) (class_ ("IV cl.")) (title "Vir Feria II post Dom. II post Epiphaniam, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-01-20) (class_ ("III cl. (Priv.)")) (title "Rub Feria III. SS Fabiani Papae et Sebastiani Mm.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. vel de Martyribus."))) + (praef ("comm. vel de Martyribus.")) (alt_te_deum ())) ((date 2026-01-21) (class_ ("III cl. (Priv.)")) (title "Rub Feria IV. S Agnetis * Virg. et Mart.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. Ad"))) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. Ad")) + (alt_te_deum ())) ((date 2026-01-22) (class_ ("III cl.")) (title "Rub Feria V. SS Vincentii et Anastasii Mm.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus."))) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus.")) + (alt_te_deum ())) ((date 2026-01-23) (class_ ("III cl.")) (title "Alb Feria VI. S Raymundi de Pe\195\177afort Conf.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef - ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa S Emerentianae Virg. et Mart. (rub.) Me exspectaverunt, Gloria, comm. S Raymundi de Pe\195\177afort Conf., praef. comm. vel de Martyribus. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-01-24) (class_ ("III cl. (Priv.)")) (title "Rub Sabb. S Timothei Ep. et Mart.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. I"))) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. I")) + (alt_te_deum ())) ((date 2026-01-25) (class_ ("II cl.")) (title "Vir DOM. III POST EPIPHANIAM, De ea,") (te_deum (true)) - (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-01-26) (class_ ("III cl. (Priv.)")) (title "Rub Feria II. S Polycarpi Ep. et Mart.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus."))) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus.")) + (alt_te_deum ())) ((date 2026-01-27) (class_ ("III cl. (Priv.)")) (title "Alb Feria III. S Ioannis Chrysostomi Ep., Conf. et Eccl. Doct.,") - (te_deum (true)) (gloria (true)) (credo (false)) (praef ("comm. Ad"))) + (te_deum (true)) (gloria (true)) (credo (false)) (praef ("comm. Ad")) + (alt_te_deum ())) ((date 2026-01-28) (class_ ("III cl.")) (title "Alb Feria IV. S Petri Nolasci Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) - (praef - ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa pr. S Agnetis * Virg. et Mart. secundo. (rub.), Gloria, comm. S Petri Nolasci Conf., praef. comm. vel de Martyribus."))) + (gloria (true)) (credo (false)) (praef ("comm. \226\128\147")) + (alt_te_deum ())) ((date 2026-01-29) (class_ ("III cl. (Priv.)")) (title "Alb Feria V. S Francisci Salesii Ep., Conf. et Eccl. Doct.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-01-30) (class_ ("III cl.")) (title "Rub Feria VI. S Martinae Virg. et Mart.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus."))) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus.")) + (alt_te_deum ())) ((date 2026-01-31) (class_ ("III cl. (Priv.)")) (title "Alb Sabb. S Ioannis Bosco Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. I"))) + (gloria (true)) (credo (false)) (praef ("comm. I")) (alt_te_deum ())) ((date 2026-02-01) (class_ ("II cl.")) (title "Viol DOM. SEPTUAGESIMAE, De ea,") (te_deum (false)) - (gloria (false)) (credo (true)) (praef ("Trinit. II"))) + (gloria (false)) (credo (true)) (praef ("Trinit. II")) (alt_te_deum ())) ((date 2026-02-02) (class_ ("II cl.")) (title "Alb Feria II. IN PURIFICATIONE B. MARIAE VIRG.,") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("de Nativ. Ad benedictionem candelarum: ut in Missali. Ad"))) + (praef ("de Nativ. Ad benedictionem candelarum: ut in Missali. Ad")) + (alt_te_deum ())) ((date 2026-02-03) (class_ ("IV cl.")) (title "Viol Feria III Dom. Septuagesimae, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef ("comm. \226\128\147"))) + (gloria (false)) (credo (false)) (praef ("comm. \226\128\147")) + (alt_te_deum ())) ((date 2026-02-04) (class_ ("III cl.")) (title "Alb Feria IV. S Andreae Corsini Ep. et Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef (comm.))) + (gloria (true)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-02-05) (class_ ("III cl. (Priv.)")) (title "Rub Feria V. S Agathae * Virg. et Mart.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. Ad"))) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. Ad")) + (alt_te_deum ())) ((date 2026-02-06) (class_ ("III cl. (Priv.)")) (title "Alb Feria VI. S Titi Ep. et Conf.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. Feria VI prima in mense."))) + (praef ("comm. Feria VI prima in mense.")) (alt_te_deum ())) ((date 2026-02-07) (class_ ("III cl.")) (title "Alb Sabb. S Romualdi Abb.,") (te_deum (true)) (gloria (true)) - (credo (false)) (praef ("comm. Sabbatum primum in mense. I"))) + (credo (false)) (praef ("comm. Sabbatum primum in mense. I")) + (alt_te_deum ())) ((date 2026-02-08) (class_ ("II cl.")) (title "Viol DOM. SEXAGESIMAE, De ea,") (te_deum (false)) - (gloria (false)) (credo (true)) (praef ("Trinit. II"))) + (gloria (false)) (credo (true)) (praef ("Trinit. II")) (alt_te_deum ())) ((date 2026-02-09) (class_ ("III cl.")) (title "Alb Feria II. S Cyrilli Ep. Alexandrini, Conf. et Eccl. Doct.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef - ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa S Apolloniae Virg. et Mart. (rub.) Loquebar de testimoniis tuis, Gloria, comm. S Cyrilli Ep. Alexandrini, Conf. et Eccl. Doct., tractus, praef. comm. vel de Martyribus. Ad"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-02-10) (class_ ("III cl.")) (title "Alb Feria III. S Scholasticae Virg.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef (comm.))) + (gloria (true)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-02-11) (class_ ("III cl.")) (title "Alb Feria IV. In Apparitione B. Mariae Virg. Immaculatae,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("BMV Et te in Conceptione Immaculata."))) + (praef ("BMV Et te in Conceptione Immaculata.")) (alt_te_deum ())) ((date 2026-02-12) (class_ ("III cl.")) (title "Alb Feria V. SS Septem Fundatorum Ordinis Servorum B. Mariae Virg., Cc.,") - (te_deum (true)) (gloria (true)) (credo (false)) (praef ("comm. Ad"))) + (te_deum (true)) (gloria (true)) (credo (false)) (praef ("comm. Ad")) + (alt_te_deum ())) ((date 2026-02-13) (class_ ("IV cl.")) (title "Viol Feria VI Dom. Sexagesimae, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef (comm.))) + (gloria (false)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-02-14) (class_ ("IV cl.")) (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) - (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147"))) + (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147")) + (alt_te_deum ())) ((date 2026-02-15) (class_ ("II cl.")) (title "Viol DOM. QUINQUAGESIMAE, De ea,") (te_deum (false)) - (gloria (false)) (credo (true)) (praef ("Trinit. II"))) + (gloria (false)) (credo (true)) (praef ("Trinit. II")) (alt_te_deum ())) ((date 2026-02-16) (class_ ("IV cl.")) (title "Viol Feria II Dom. Quinquagesimae, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef (comm.))) + (gloria (false)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-02-17) (class_ ("IV cl.")) (title "Viol Feria III Dom. Quinquagesimae, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef (comm.))) + (gloria (false)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-02-18) (class_ ("I cl.")) (title "Viol FERIA IV CINERUM, De ea,") (te_deum ()) (gloria (false)) (credo (false)) (praef - ("Quadr., or. super populum. In Missa qu\195\166 dicitur post benedictionem et impositionem cinerum omittuntur omnes preces ad gradus altaris dicend\195\166, necnon ors. Aufer a nobis et Oramus te, Domine, non autem osculum altaris (RM, 424 a)."))) + ("Quadr., or. super populum. In Missa qu\195\166 dicitur post benedictionem et impositionem cinerum omittuntur omnes preces ad gradus altaris dicend\195\166, necnon ors. Aufer a nobis et Oramus te, Domine, non autem osculum altaris (RM, 424 a).")) + (alt_te_deum ())) ((date 2026-02-19) (class_ ("III cl.")) (title "Viol Feria V Dom. Quinquagesimae, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum.")) + (alt_te_deum ())) ((date 2026-02-20) (class_ ("III cl.")) (title "Viol Feria VI Dom. Quinquagesimae, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum.")) + (alt_te_deum ())) ((date 2026-02-21) (class_ ("III cl.")) (title "Viol Sabb. Dom. Quinquagesimae, De eo,") (te_deum ()) - (gloria (false)) (credo (false)) - (praef ("Quadr., or. super populum. I"))) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum. I")) + (alt_te_deum ())) ((date 2026-02-22) (class_ ("I cl.")) (title "Viol DOM. I QUADRAGESIMAE, De ea,") (te_deum (false)) - (gloria (false)) (credo (true)) (praef ("Quadr. II"))) + (gloria (false)) (credo (true)) (praef ("Quadr. II")) (alt_te_deum ())) ((date 2026-02-23) (class_ ("III cl.")) (title "Viol Feria II post Dom. I Quadragesimae, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum.")) + (alt_te_deum ())) ((date 2026-02-24) (class_ ("II cl.")) (title "Rub Feria III. S MATTHIAE AP.,") (te_deum ()) (gloria (true)) - (credo (true)) (praef ("App. Ad"))) + (credo (true)) (praef ("App. Ad")) (alt_te_deum ())) ((date 2026-02-25) (class_ ("II cl.")) (title "Viol FERIA IV QUATTUOR TEMP., De ea,") (te_deum ()) (gloria (false)) (credo (false)) (praef - ("Quadr., or. super populum. \226\128\147 Quoad Flectamus genua vide RM 440."))) + ("Quadr., or. super populum. \226\128\147 Quoad Flectamus genua vide RM 440.")) + (alt_te_deum ())) ((date 2026-02-26) (class_ ("III cl.")) (title "Viol Feria V post Dom. I Quadragesimae, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum.")) + (alt_te_deum ())) ((date 2026-02-27) (class_ ("II cl.")) (title "Viol FERIA VI QUATTUOR TEMP., De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum.")) + (alt_te_deum ())) ((date 2026-02-28) (class_ ("II cl.")) (title "Viol SABB. QUATTUOR TEMP., De eo,") (te_deum ()) (gloria (false)) (credo (false)) (praef - ("Quadr., or. super populum. \226\128\147 Quoad Flectamus genua vide RM 440. Quoad lectiones vide RM 468. I"))) + ("Quadr., or. super populum. \226\128\147 Quoad Flectamus genua vide RM 440. Quoad lectiones vide RM 468. I")) + (alt_te_deum ())) ((date 2026-03-01) (class_ ("I cl.")) (title "Viol DOM. II QUADRAGESIMAE, De ea,") (te_deum (false)) - (gloria (false)) (credo (true)) (praef ("Quadr. II"))) + (gloria (false)) (credo (true)) (praef ("Quadr. II")) (alt_te_deum ())) ((date 2026-03-02) (class_ ("III cl.")) (title "Viol Feria II post Dom. II Quadragesimae, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum.")) + (alt_te_deum ())) ((date 2026-03-03) (class_ ("III cl.")) (title "Viol Feria III post Dom. II Quadragesimae, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum.")) + (alt_te_deum ())) ((date 2026-03-04) (class_ ("III cl.")) (title "Viol Feria IV post Dom. II Quadragesimae, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum.")) + (alt_te_deum ())) ((date 2026-03-05) (class_ ("III cl.")) (title "Viol Feria V post Dom. II Quadragesimae, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum.")) + (alt_te_deum ())) ((date 2026-03-06) (class_ ("III cl.")) - (title "Viol Feria VI post Dom. II Quadragesimae, De ea,") - (te_deum (true)) (gloria (false)) (credo (false)) - (praef ("Quadr., or. super populum. Feria VI prima in mense."))) + (title "Viol Feria VI post Dom. II Quadragesimae, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) + (praef ("Quadr., or. super populum. Feria VI prima in mense.")) + (alt_te_deum (true))) ((date 2026-03-07) (class_ ("III cl.")) - (title "Viol Sabb. post Dom. II Quadragesimae, De eo,") (te_deum (true)) + (title "Viol Sabb. post Dom. II Quadragesimae, De eo,") (te_deum ()) (gloria (false)) (credo (false)) - (praef ("Quadr., or. super populum. Sabbatum primum in mense. I"))) + (praef ("Quadr., or. super populum. Sabbatum primum in mense. I")) + (alt_te_deum (true))) ((date 2026-03-08) (class_ ("I cl.")) (title "Viol DOM. III QUADRAGESIMAE, De ea,") (te_deum (false)) - (gloria (false)) (credo (true)) (praef ("Quadr. II"))) + (gloria (false)) (credo (true)) (praef ("Quadr. II")) (alt_te_deum ())) ((date 2026-03-09) (class_ ("III cl.")) - (title "Viol Feria II post Dom. III Quadragesimae, De ea,") - (te_deum (true)) (gloria (false)) (credo (false)) - (praef ("Quadr., or. super populum."))) + (title "Viol Feria II post Dom. III Quadragesimae, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum.")) + (alt_te_deum (true))) ((date 2026-03-10) (class_ ("III cl.")) (title "Viol Feria III post Dom. III Quadragesimae, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum.")) + (alt_te_deum ())) ((date 2026-03-11) (class_ ("III cl.")) (title "Viol Feria IV post Dom. III Quadragesimae, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum.")) + (alt_te_deum ())) ((date 2026-03-12) (class_ ("III cl.")) - (title "Viol Feria V post Dom. III Quadragesimae, De ea,") - (te_deum (true)) (gloria (false)) (credo (false)) - (praef ("Quadr., or. super populum."))) + (title "Viol Feria V post Dom. III Quadragesimae, De ea,") (te_deum ()) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum.")) + (alt_te_deum (true))) ((date 2026-03-13) (class_ ("III cl.")) (title "Viol Feria VI post Dom. III Quadragesimae, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum."))) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum.")) + (alt_te_deum ())) ((date 2026-03-14) (class_ ("III cl.")) (title "Viol Sabb. post Dom. III Quadragesimae, De eo,") (te_deum ()) - (gloria (false)) (credo (false)) - (praef ("Quadr., or. super populum. I"))) + (gloria (false)) (credo (false)) (praef ("Quadr., or. super populum. I")) + (alt_te_deum ())) ((date 2026-03-15) (class_ ("I cl.")) (title "Viol/ DOM. IV QUADRAGESIMAE (LAETARE), De ea,") (te_deum (false)) - (gloria (false)) (credo (true)) (praef ("Quadr. II"))) + (gloria (false)) (credo (true)) (praef ("Quadr. II")) (alt_te_deum ())) ((date 2026-03-16) (class_ ("III cl.")) (title "Viol Feria II post Dom. IV Quadragesimae (Laetare), De ea,") (te_deum ()) (gloria (false)) (credo (false)) - (praef ("Quadr., or. super populum."))) + (praef ("Quadr., or. super populum.")) (alt_te_deum ())) ((date 2026-03-17) (class_ ("III cl.")) (title "Viol Feria III post Dom. IV Quadragesimae (Laetare), De ea,") (te_deum ()) (gloria (false)) (credo (false)) - (praef ("Quadr., or. super populum."))) + (praef ("Quadr., or. super populum.")) (alt_te_deum ())) ((date 2026-03-18) (class_ ("III cl.")) (title "Viol Feria IV post Dom. IV Quadragesimae (Laetare), De ea,") (te_deum ()) (gloria (false)) (credo (false)) - (praef ("Quadr., or. super populum. I"))) + (praef ("Quadr., or. super populum. I")) (alt_te_deum ())) ((date 2026-03-19) (class_ ("I cl.")) (title "Alb Feria V. S IOSEPH * SPONSI B. MARIAE VIRG., CONF. ET ECCLESIAE UNIVERSAE PATRONI,") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("de S Iosepho Et te in festivitate. II"))) + (praef ("de S Iosepho Et te in festivitate. II")) (alt_te_deum ())) ((date 2026-03-20) (class_ ("III cl.")) (title "Viol Feria VI post Dom. IV Quadragesimae (Laetare), De ea,") (te_deum ()) (gloria (false)) (credo (false)) - (praef ("Quadr., or. super populum."))) + (praef ("Quadr., or. super populum.")) (alt_te_deum ())) ((date 2026-03-21) (class_ ("III cl.")) (title "Viol Sabb. post Dom. IV Quadragesimae (Laetare), De eo,") - (te_deum (true)) (gloria (false)) (credo (false)) - (praef ("Quadr., or. super populum. I"))) + (te_deum ()) (gloria (false)) (credo (false)) + (praef ("Quadr., or. super populum. I")) (alt_te_deum (true))) ((date 2026-03-22) (class_ ("I cl.")) (title "Viol DOM. I PASSIONIS, De ea,") (te_deum (false)) - (gloria (false)) (credo (true)) (praef ("de Sancta Cruce. II"))) + (gloria (false)) (credo (true)) (praef ("de Sancta Cruce. II")) + (alt_te_deum ())) ((date 2026-03-23) (class_ ("III cl.")) (title "Viol Feria II post Dom. I Passionis, De ea,") (te_deum ()) (gloria (false)) (credo (false)) - (praef ("de Sancta Cruce or. super populum."))) + (praef ("de Sancta Cruce or. super populum.")) (alt_te_deum ())) ((date 2026-03-24) (class_ ("III cl.")) - (title "Viol Feria III post Dom. I Passionis, De ea,") (te_deum (true)) + (title "Viol Feria III post Dom. I Passionis, De ea,") (te_deum ()) (gloria (false)) (credo (false)) - (praef ("de Sancta Cruce or. super populum. I"))) + (praef ("de Sancta Cruce or. super populum. I")) (alt_te_deum (true))) ((date 2026-03-25) (class_ ("I cl.")) (title "Alb Feria IV. IN ANNUNTIATIONE B. MARIAE VIRG.,") (te_deum ()) (gloria (true)) (credo (true)) (praef - ("BMV Et te in Annuntiatione \226\128\147 In Missis in cantu, ad verba symboli Et incarnatus est\226\128\166 et homo factus est, omnes genuflectunt versus altare, non tantum cum a celebrante recitantur, sed etiam cum a choro canuntur (RM 518 b). II"))) + ("BMV Et te in Annuntiatione \226\128\147 In Missis in cantu, ad verba symboli Et incarnatus est\226\128\166 et homo factus est, omnes genuflectunt versus altare, non tantum cum a celebrante recitantur, sed etiam cum a choro canuntur (RM 518 b). II")) + (alt_te_deum ())) ((date 2026-03-26) (class_ ("III cl.")) (title "Viol Feria V post Dom. I Passionis, De ea,") (te_deum ()) (gloria (false)) (credo (false)) - (praef ("de Sancta Cruce or. super populum."))) + (praef ("de Sancta Cruce or. super populum.")) (alt_te_deum ())) ((date 2026-03-27) (class_ ("III cl.")) (title "Viol Feria VI post Dom. I Passionis, De ea,") (te_deum ()) (gloria (false)) (credo (false)) - (praef ("de Sancta Cruce or. super populum."))) + (praef ("de Sancta Cruce or. super populum.")) (alt_te_deum ())) ((date 2026-03-28) (class_ ("III cl.")) (title "Viol Sabb. post Dom. I Passionis, De eo,") (te_deum ()) (gloria (false)) (credo (false)) - (praef ("de Sancta Cruce or. super populum. I"))) + (praef ("de Sancta Cruce or. super populum. I")) (alt_te_deum ())) ((date 2026-03-29) (class_ ("I cl.")) (title "Rub in Officio, Rub. ad Bened. ramorum et in Processione, Viol. in Missa. DOM. IN PALMIS, De ea,") (te_deum (false)) (gloria (false)) (credo (true)) (praef - ("de Sancta Cruce. \194\171Asperges\194\187 omittitur. \226\128\147 Benedictio palmorum et processio ante missam principalem celebrandae sunt. \226\128\147 Orationes praeparatoriae omittuntur. \226\128\147 Evangelium de passione secundum S Matthiam 26, 36-75; 27,1-60 legitur. Munda cor dicitur, celebrans autem (vel diaconus chronista) signum crucis nec super libro nec super se facit, necque librum osculatur, necque Laus tibi Domine dicit. \226\128\147 Evangelium finale omittitur. \226\128\147 In Missis sine processione, legitur in fine Evangelium Cum appropinquasset de benedictione ramorum. Sacerdotibus plures quam unam missam dicentibus licet Evangelium S Matthi\195\166 27, 45-52 legere potius quam Evangelium Passionis. II"))) + ("de Sancta Cruce. \194\171Asperges\194\187 omittitur. \226\128\147 Benedictio palmorum et processio ante missam principalem celebrandae sunt. \226\128\147 Orationes praeparatoriae omittuntur. \226\128\147 Evangelium de passione secundum S Matthiam 26, 36-75; 27,1-60 legitur. Munda cor dicitur, celebrans autem (vel diaconus chronista) signum crucis nec super libro nec super se facit, necque librum osculatur, necque Laus tibi Domine dicit. \226\128\147 Evangelium finale omittitur. \226\128\147 In Missis sine processione, legitur in fine Evangelium Cum appropinquasset de benedictione ramorum. Sacerdotibus plures quam unam missam dicentibus licet Evangelium S Matthi\195\166 27, 45-52 legere potius quam Evangelium Passionis. II")) + (alt_te_deum ())) ((date 2026-03-30) (class_ ("I cl.")) (title "Viol FERIA II HEBDOMADAE SANCTAE, De ea,") (te_deum ()) (gloria (false)) (credo (false)) - (praef ("de Sancta Cruce or. super populum."))) + (praef ("de Sancta Cruce or. super populum.")) (alt_te_deum ())) ((date 2026-03-31) (class_ ("I cl.")) (title "Viol FERIA II HEBDOMADAE SANCTAE, De ea,") (te_deum ()) (gloria (false)) (credo (false)) (praef - ("de Sancta Cruce or. super populum. Passio secundum S Marcum 14, 32-72; 15,1-46. Munda cor dicitur, celebrans autem (vel diaconus chronista) signum crucis nec super libro nec super se facit, necque librum osculatur, necque Laus tibi Domine dicit."))) + ("de Sancta Cruce or. super populum. Passio secundum S Marcum 14, 32-72; 15,1-46. Munda cor dicitur, celebrans autem (vel diaconus chronista) signum crucis nec super libro nec super se facit, necque librum osculatur, necque Laus tibi Domine dicit.")) + (alt_te_deum ())) ((date 2026-04-01) (class_ ("I cl.")) (title "Viol FERIA IV HEBDOMADAE SANCTA, De ea,") (te_deum ()) (gloria (false)) (credo (false)) (praef - ("de Sancta Cruce or. super populum. Passio secundum S Lucam 22, 39-71; 23, 1-53. Munda cor dicitur, celebrans autem (vel diaconus chronista) signum crucis nec super libro nec super se facit, necque librum osculatur, necque Laus tibi Domine dicit."))) + ("de Sancta Cruce or. super populum. Passio secundum S Lucam 22, 39-71; 23, 1-53. Munda cor dicitur, celebrans autem (vel diaconus chronista) signum crucis nec super libro nec super se facit, necque librum osculatur, necque Laus tibi Domine dicit.")) + (alt_te_deum ())) ((date 2026-04-02) (class_ ("I cl.")) (title "Viol. in Off., Alb. in Missa. FERIA V IN CENA DOMINI, De ea,") (te_deum ()) (gloria (true)) (credo (false)) (praef - ("de Sancta Cruce, Communicantes, Hanc igitur et Qui pridie pr., ad triplex Agnus Dei ter respondetur miserere nobis. Osculum pacis non datur, et omittitur or. Domine Iesu Christe, qui dixisti."))) + ("de Sancta Cruce, Communicantes, Hanc igitur et Qui pridie pr., ad triplex Agnus Dei ter respondetur miserere nobis. Osculum pacis non datur, et omittitur or. Domine Iesu Christe, qui dixisti.")) + (alt_te_deum ())) ((date 2026-04-03) (class_ ("I cl.")) (title "Nig in Actione liturgica usque ad 4am partem, Viol. in S. Communione. FERIA VI IN PASSIONE ET MORTE DOMINI, De ea,") (te_deum ()) (gloria (true)) (credo (false)) - (praef ("comm. Feria VI prima in mense."))) + (praef ("comm. Feria VI prima in mense.")) (alt_te_deum ())) ((date 2026-04-04) (class_ ("I cl.")) (title "Viol in Vig. pasch., Alb. in Missa. SABBATUM SANCTUM, De eo,") - (te_deum ()) (gloria ()) (credo ()) (praef ())) + (te_deum ()) (gloria ()) (credo ()) (praef ()) (alt_te_deum ())) ((date 2026-04-05) (class_ ("I cl.")) (title "Alb DOM. RESURRECTIONIS, De ea,") (te_deum ()) (gloria (true)) (credo (true)) (praef - ("Pasch. (in hac potissimum die), Communic. et Hanc igitur pr., ad Ite, missa est additur duplex Alleluia. Hodie prohibentur omnes Missae defunctorum, etiam exsequialis."))) + ("Pasch. (in hac potissimum die), Communic. et Hanc igitur pr., ad Ite, missa est additur duplex Alleluia. Hodie prohibentur omnes Missae defunctorum, etiam exsequialis.")) + (alt_te_deum ())) ((date 2026-04-06) (class_ ("I cl.")) (title "Alb FERIA II INFRA OCTAVAM PASCHATIS, De ea,") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("etc. ut in festo., ad Ite, missa est additur duplex Alleluia."))) + (praef ("etc. ut in festo., ad Ite, missa est additur duplex Alleluia.")) + (alt_te_deum ())) ((date 2026-04-07) (class_ ("I cl.")) (title "Alb FERIA III INFRA OCTAVAM PASCHATIS, De ea,") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("etc. ut in festo., ad Ite, missa est additur duplex Alleluia."))) + (praef ("etc. ut in festo., ad Ite, missa est additur duplex Alleluia.")) + (alt_te_deum ())) ((date 2026-04-08) (class_ ("I cl.")) (title "Alb FERIA IV INFRA OCTAVAM PASCHATIS, De ea,") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("etc. ut in festo., ad Ite, missa est additur duplex Alleluia."))) + (praef ("etc. ut in festo., ad Ite, missa est additur duplex Alleluia.")) + (alt_te_deum ())) ((date 2026-04-09) (class_ ("I cl.")) (title "Alb FERIA V INFRA OCTAVAM PASCHATIS, De ea,") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("etc. ut in festo., ad Ite, missa est additur duplex Alleluia."))) + (praef ("etc. ut in festo., ad Ite, missa est additur duplex Alleluia.")) + (alt_te_deum ())) ((date 2026-04-10) (class_ ("I cl.")) (title "Alb FERIA VI INFRA OCTAVAM PASCHATIS, De ea,") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("etc. ut in festo., ad Ite, missa est additur duplex Alleluia."))) + (praef ("etc. ut in festo., ad Ite, missa est additur duplex Alleluia.")) + (alt_te_deum ())) ((date 2026-04-11) (class_ ("I cl.")) (title "Alb SABBATUM IN ALBIS, De eo,") (te_deum ()) (gloria (true)) (credo (true)) (praef - ("etc. ut in festo., ad Ite, missa est additur duplex Alleluia. I"))) + ("etc. ut in festo., ad Ite, missa est additur duplex Alleluia. I")) + (alt_te_deum ())) ((date 2026-04-12) (class_ ("I cl.")) (title "Alb DOM. IN ALBIS,") (te_deum (true)) (gloria (true)) (credo (true)) - (praef ("Pasch. \226\128\147 Ite Missa est sine Alleluia. II"))) + (praef ("Pasch. \226\128\147 Ite Missa est sine Alleluia. II")) + (alt_te_deum ())) ((date 2026-04-13) (class_ ("III cl.")) (title "Rub Feria II. S Hermenegildi Mart.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("Pasch. vel de Martyribus. Ad"))) + (gloria (true)) (credo (false)) (praef ("Pasch. vel de Martyribus. Ad")) + (alt_te_deum ())) ((date 2026-04-14) (class_ ("III cl. (Priv.)")) (title "Rub Feria III. S Iustini Mart.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("Pasch. vel de Martyribus."))) + (gloria (true)) (credo (false)) (praef ("Pasch. vel de Martyribus.")) + (alt_te_deum ())) ((date 2026-04-15) (class_ ("IV cl.")) (title "Alb Feria IV Dom. in Albis, De ea,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef (Pasch.))) + (gloria (true)) (credo (false)) (praef (Pasch.)) (alt_te_deum ())) ((date 2026-04-16) (class_ ("IV cl.")) (title "Alb Feria V Dom. in Albis, De ea,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("Pasch. \226\128\147"))) + (gloria (true)) (credo (false)) (praef ("Pasch. \226\128\147")) + (alt_te_deum ())) ((date 2026-04-17) (class_ ("IV cl.")) (title "Alb Feria VI Dom. in Albis, De ea,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("Pasch. \226\128\147"))) + (gloria (true)) (credo (false)) (praef ("Pasch. \226\128\147")) + (alt_te_deum ())) ((date 2026-04-18) (class_ ("IV cl.")) (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) - (credo (false)) (praef ("BMV Et te in Veneratione. I"))) + (credo (false)) (praef ("BMV Et te in Veneratione. I")) (alt_te_deum ())) ((date 2026-04-19) (class_ ("II cl.")) (title "Alb DOM. III PASCHATIS, De ea,") (te_deum (true)) (gloria (true)) - (credo (true)) (praef ("Pasch. II"))) + (credo (true)) (praef ("Pasch. II")) (alt_te_deum ())) ((date 2026-04-20) (class_ ("IV cl.")) (title "Alb Feria II post Dom. III Paschatis, De ea,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef (Pasch.))) + (gloria (true)) (credo (false)) (praef (Pasch.)) (alt_te_deum ())) ((date 2026-04-21) (class_ ("III cl.")) (title "Alb Feria III. S Anselmi Ep., Conf. et Eccl. Doct.,") - (te_deum (true)) (gloria (true)) (credo (false)) (praef ("Pasch. Ad"))) + (te_deum (true)) (gloria (true)) (credo (false)) (praef ("Pasch. Ad")) + (alt_te_deum ())) ((date 2026-04-22) (class_ ("III cl.")) (title "Rub Feria IV. SS Soteris et Caii Pp. et Mm.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("Pasch. vel de Martyribus."))) + (gloria (true)) (credo (false)) (praef ("Pasch. vel de Martyribus.")) + (alt_te_deum ())) ((date 2026-04-23) (class_ ("IV cl.")) (title "Alb Feria V post Dom. III Paschatis, De ea,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("Pasch. \226\128\147"))) + (gloria (true)) (credo (false)) (praef ("Pasch. \226\128\147")) + (alt_te_deum ())) ((date 2026-04-24) (class_ ("III cl.")) (title "Rub Feria VI. S Fidelis de Sigmaringa Mart.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("Pasch. vel de Martyribus."))) + (gloria (true)) (credo (false)) (praef ("Pasch. vel de Martyribus.")) + (alt_te_deum ())) ((date 2026-04-25) (class_ ("II cl.")) (title "Rub Sabb. LITANIA MAIOR. S MARCI EVANGELISTAE,") (te_deum ()) - (gloria (true)) (credo (true)) (praef ("App. Ad"))) + (gloria (true)) (credo (true)) (praef ("App. Ad")) (alt_te_deum ())) ((date 2026-04-26) (class_ ("II cl.")) (title "Alb DOM. IV PASCHATIS, De ea,") (te_deum (true)) (gloria (true)) - (credo (true)) (praef ("Pasch. II"))) + (credo (true)) (praef ("Pasch. II")) (alt_te_deum ())) ((date 2026-04-27) (class_ ("III cl.")) (title "Alb Feria II. S Petri Canisii Conf. et Eccl. Doct.,") - (te_deum (true)) (gloria (true)) (credo (false)) (praef ("Pasch. Ad"))) + (te_deum (true)) (gloria (true)) (credo (false)) (praef ("Pasch. Ad")) + (alt_te_deum ())) ((date 2026-04-28) (class_ ("III cl.")) (title "Alb Feria III. S Pauli a Cruce Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("Pasch. \226\128\147"))) + (gloria (true)) (credo (false)) (praef ("Pasch. \226\128\147")) + (alt_te_deum ())) ((date 2026-04-29) (class_ ("III cl.")) (title "Rub Feria IV. S Petri Mart.,") (te_deum (true)) (gloria (true)) - (credo (false)) (praef ("Pasch. vel de Martyribus \226\128\147"))) + (credo (false)) (praef ("Pasch. vel de Martyribus \226\128\147")) + (alt_te_deum ())) ((date 2026-04-30) (class_ ("III cl. (Priv.)")) (title "Alb Feria V. S Catharinae Senensis Virg.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("Pasch. I"))) + (gloria (true)) (credo (false)) (praef ("Pasch. I")) (alt_te_deum ())) ((date 2026-05-01) (class_ ("I cl.")) (title "Alb Feria VI. S IOSEPH * OPIFICIS SPONSI B. MARIAE VIRG., CONF.,") (te_deum ()) (gloria (true)) (credo (true)) (praef - ("de S Iosepho Et te in solemnitate \226\128\147 Etiam dici potest Missa Adiutor (cfr. in Missis votivis), cum Alleluia pasch., praef. S Ioseph Et et in solemnitate. Feria VI prima in mense. II"))) + ("de S Iosepho Et te in solemnitate \226\128\147 Etiam dici potest Missa Adiutor (cfr. in Missis votivis), cum Alleluia pasch., praef. S Ioseph Et et in solemnitate. Feria VI prima in mense. II")) + (alt_te_deum ())) ((date 2026-05-02) (class_ ("III cl. (Priv.)")) (title "Alb Sabb. S Athanasii Ep., Conf. et Eccl. Doct.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("Pasch. Sabbatum primum in mense. I"))) + (praef ("Pasch. Sabbatum primum in mense. I")) (alt_te_deum ())) ((date 2026-05-03) (class_ ("II cl.")) (title "Alb DOM. V PASCHATIS, De ea,") (te_deum (true)) (gloria (true)) - (credo (true)) (praef ("Pasch. II"))) + (credo (true)) (praef ("Pasch. II")) (alt_te_deum ())) ((date 2026-05-04) (class_ ("III cl. (Priv.)")) (title "Alb Feria II. S Monicae Vid.,") (te_deum (true)) (gloria (true)) - (credo (false)) (praef (Pasch.))) + (credo (false)) (praef (Pasch.)) (alt_te_deum ())) ((date 2026-05-05) (class_ ("III cl. (Priv.)")) (title "Alb Feria III. S Pii V Papae et Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("Pasch. Ad"))) + (gloria (true)) (credo (false)) (praef ("Pasch. Ad")) (alt_te_deum ())) ((date 2026-05-06) (class_ ("IV cl.")) (title "Alb Feria IV post Dom. V Paschatis, De ea,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("Pasch. \226\128\147"))) + (gloria (true)) (credo (false)) (praef ("Pasch. \226\128\147")) + (alt_te_deum ())) ((date 2026-05-07) (class_ ("III cl.")) (title "Rub Feria V. S Stanislai Ep. et Mart.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("Pasch. vel de Martyribus."))) + (gloria (true)) (credo (false)) (praef ("Pasch. vel de Martyribus.")) + (alt_te_deum ())) ((date 2026-05-08) (class_ ("IV cl.")) (title "Alb Feria VI post Dom. V Paschatis, De ea,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("Pasch. \226\128\147"))) + (gloria (true)) (credo (false)) (praef ("Pasch. \226\128\147")) + (alt_te_deum ())) ((date 2026-05-09) (class_ ("III cl. (Priv.)")) (title "Alb Sabb. S Gregorii Nazianzeni Ep., Conf. et Eccl. Doct.,") - (te_deum (true)) (gloria (true)) (credo (false)) (praef ("Pasch. I"))) + (te_deum (true)) (gloria (true)) (credo (false)) (praef ("Pasch. I")) + (alt_te_deum ())) ((date 2026-05-10) (class_ ("II cl.")) (title "Alb DOM. VI PASCHATIS, De ea,") (te_deum (true)) (gloria (true)) - (credo (true)) (praef ("Pasch. II"))) + (credo (true)) (praef ("Pasch. II")) (alt_te_deum ())) ((date 2026-05-11) (class_ ("II cl.")) (title "Rub Feria II. SS PHILIPPI * & IACOBI * APP,") (te_deum ()) - (gloria (true)) (credo (true)) (praef ("App. Ad"))) + (gloria (true)) (credo (true)) (praef ("App. Ad")) (alt_te_deum ())) ((date 2026-05-12) (class_ ("III cl.")) (title "Rub Feria III. SS Nerei, Achillei, Domitillae Virg., & Pancratii Mm.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("Pasch. vel de Martyribus."))) + (praef ("Pasch. vel de Martyribus.")) (alt_te_deum ())) ((date 2026-05-13) (class_ ("II cl.")) (title "Alb Feria IV. VIGILIA ASCENSIONIS,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("Pasch. I"))) + (gloria (true)) (credo (false)) (praef ("Pasch. I")) (alt_te_deum ())) ((date 2026-05-14) (class_ ("I cl.")) (title "Alb Feria V. IN ASCENSIONE DOMINI NOSTRI IESU CHRISTI,") (te_deum ()) (gloria (true)) (credo (true)) (praef - ("Ascensionis, Communic pr. In Missa principali post Evangelium exstinguitur cereus paschalis. II"))) + ("Ascensionis, Communic pr. In Missa principali post Evangelium exstinguitur cereus paschalis. II")) + (alt_te_deum ())) ((date 2026-05-15) (class_ ("III cl.")) (title "Alb Feria VI. S Ioannis Baptistae de la Salle Conf.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("Ascensionis \226\128\147"))) + (praef ("Ascensionis \226\128\147")) (alt_te_deum ())) ((date 2026-05-16) (class_ ("III cl.")) (title "Alb Sabb. S Ubaldi Ep. et Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("Ascensionis \226\128\147"))) + (gloria (true)) (credo (false)) (praef ("Ascensionis \226\128\147")) + (alt_te_deum ())) ((date 2026-05-17) (class_ ("II cl.")) (title "Alb DOM. POST ASCENSIONEM, De ea,") (te_deum (true)) (gloria (true)) (credo (true)) (praef - ("Ascensionis. Hodie prohibentur omnes Missae defunctorum, excepta exsequiali."))) + ("Ascensionis. Hodie prohibentur omnes Missae defunctorum, excepta exsequiali.")) + (alt_te_deum ())) ((date 2026-05-18) (class_ ("III cl.")) (title "Rub Feria II. S Venantii Mart.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("Ascensionis vel de Martyribus."))) + (praef ("Ascensionis vel de Martyribus.")) (alt_te_deum ())) ((date 2026-05-19) (class_ ("III cl.")) (title "Alb Feria III. S Petri Caelestini Papae et Conf.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef - ("Ascensionis \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa S Pudentianae Virg. (alb.) Dilexisti iustitiam, Gloria, comm. S Petri Caelestini Papae et Conf., praef. Ascensionis. Ad"))) + (praef ("Ascensionis \226\128\147")) (alt_te_deum ())) ((date 2026-05-20) (class_ ("III cl.")) (title "Alb Feria IV. S Bernardini Senensis Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef (Ascensionis.))) + (gloria (true)) (credo (false)) (praef (Ascensionis.)) (alt_te_deum ())) ((date 2026-05-21) (class_ ("IV cl.")) (title "Alb Feria V Dom. post Ascensionem, De ea,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef (Ascensionis.))) + (gloria (true)) (credo (false)) (praef (Ascensionis.)) (alt_te_deum ())) ((date 2026-05-22) (class_ ("IV cl.")) (title "Alb Feria VI Dom. post Ascensionem, De ea,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("Ascensionis \226\128\147"))) + (gloria (true)) (credo (false)) (praef ("Ascensionis \226\128\147")) + (alt_te_deum ())) ((date 2026-05-23) (class_ ("I cl.")) (title "Rub Sabb. VIGILIA PENTECOSTES,") (te_deum (true)) (gloria (true)) (credo (false)) (praef - ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. I"))) + ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. I")) + (alt_te_deum ())) ((date 2026-05-24) (class_ ("I cl.")) (title "Rub Dom. PENTECOSTES,") (te_deum ()) (gloria (true)) (credo (true)) (praef - ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. \226\128\147 Genu flectendum est cum Veni Sancte Spiritus in versu Alleluia dicitur. II"))) + ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. \226\128\147 Genu flectendum est cum Veni Sancte Spiritus in versu Alleluia dicitur. II")) + (alt_te_deum ())) ((date 2026-05-25) (class_ ("I cl.")) (title "Rub FERIA II INFRA OCTAVAM PENTECOSTES, De ea,") (te_deum ()) (gloria (true)) (credo (true)) (praef - ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. \226\128\147 Genu flectendum est cum Veni Sancte Spiritus in versu Alleluia dicitur."))) + ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. \226\128\147 Genu flectendum est cum Veni Sancte Spiritus in versu Alleluia dicitur.")) + (alt_te_deum ())) ((date 2026-05-26) (class_ ("I cl.")) (title "Rub FERIA III INFRA OCTAVAM PENTECOSTES, De ea,") (te_deum ()) (gloria (true)) (credo (true)) (praef - ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. \226\128\147 Genu flectendum est cum Veni Sancte Spiritus in versu Alleluia dicitur."))) + ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. \226\128\147 Genu flectendum est cum Veni Sancte Spiritus in versu Alleluia dicitur.")) + (alt_te_deum ())) ((date 2026-05-27) (class_ ("I cl.")) (title "Rub FERIA IV QUATTUOR TEMPORUM INFRA OCTAVAM PENTECOSTES, De ea,") (te_deum ()) (gloria (true)) (credo (true)) (praef - ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. \226\128\147 Genu flectendum est cum Veni Sancte Spiritus in versu Alleluia dicitur."))) + ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. \226\128\147 Genu flectendum est cum Veni Sancte Spiritus in versu Alleluia dicitur.")) + (alt_te_deum ())) ((date 2026-05-28) (class_ ("I cl.")) (title "Rub FERIA V INFRA OCTAVAM PENTECOSTES, De ea,") (te_deum ()) (gloria (true)) (credo (true)) (praef - ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. \226\128\147 Genu flectendum est cum Veni Sancte Spiritus in versu Alleluia dicitur."))) + ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. \226\128\147 Genu flectendum est cum Veni Sancte Spiritus in versu Alleluia dicitur.")) + (alt_te_deum ())) ((date 2026-05-29) (class_ ("I cl.")) (title "Rub FERIA VI QUATTUOR TEMPORUM INFRA OCTAVAM PENTECOSTES, De ea,") (te_deum ()) (gloria (true)) (credo (true)) (praef - ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. \226\128\147 Genu flectendum est cum Veni Sancte Spiritus in versu Alleluia dicitur."))) + ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. \226\128\147 Genu flectendum est cum Veni Sancte Spiritus in versu Alleluia dicitur.")) + (alt_te_deum ())) ((date 2026-05-30) (class_ ("I cl.")) (title "Rub SABBATUM QUATTUOR TEMPORUM II INFRA OCTAVAM PENTECOSTES, De eo,") (te_deum ()) (gloria (true)) (credo (true)) (praef - ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. \226\128\147 Genu flectendum est cum Veni Sancte Spiritus in versu Alleluia dicitur (quae in forma Miss\195\166 longiori post sixtam lectionem dicitur). Post Nonam exspirat tempus paschale. Compl de dom., cum antiphona finali de B. V. M. Salve Regina, quae dicitur ad Feriam VI ante Dom. I Adventus inclusive. Hodie prohibentur omnes Missae defunctorum, excepta exsequiali."))) + ("de Spirito Sancto hodierna die, Communic pr., Hanc igitur pr. \226\128\147 Genu flectendum est cum Veni Sancte Spiritus in versu Alleluia dicitur (quae in forma Miss\195\166 longiori post sixtam lectionem dicitur). Post Nonam exspirat tempus paschale. Compl de dom., cum antiphona finali de B. V. M. Salve Regina, quae dicitur ad Feriam VI ante Dom. I Adventus inclusive. Hodie prohibentur omnes Missae defunctorum, excepta exsequiali.")) + (alt_te_deum ())) ((date 2026-05-31) (class_ ("I cl.")) (title "Alb Dom. I post Pentecosten. IN FESTO SANCTISSIMAE TRINITATIS,") - (te_deum ()) (gloria (true)) (credo (true)) (praef ("Trinit. II"))) + (te_deum ()) (gloria (true)) (credo (true)) (praef ("Trinit. II")) + (alt_te_deum ())) ((date 2026-06-01) (class_ ("III cl.")) (title "Alb Feria II. S Angelae Mericiae Virg.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef (comm.))) + (gloria (true)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-06-02) (class_ ("IV cl.")) (title "Vir Feria III post Dom. I post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-06-03) (class_ ("IV cl.")) (title "Vir Feria IV post Dom. I post Pentecosten, De ea,") - (te_deum (false)) (gloria (false)) (credo (false)) (praef ("comm. I"))) + (te_deum (false)) (gloria (false)) (credo (false)) (praef ("comm. I")) + (alt_te_deum ())) ((date 2026-06-04) (class_ ("I cl.")) (title "Alb Feria V. CORPORIS CHRISTI,") (te_deum ()) (gloria (true)) (credo (true)) (praef - ("comm. vel de Cor Sacratissimo. \226\128\147 Si processio cum benedicto sacramento post missam principalem fit, in Missa Benedicamus Domino dicitur, sed benedictio et evangelium finale omittuntur. II"))) + ("comm. vel de Cor Sacratissimo. \226\128\147 Si processio cum benedicto sacramento post missam principalem fit, in Missa Benedicamus Domino dicitur, sed benedictio et evangelium finale omittuntur. II")) + (alt_te_deum ())) ((date 2026-06-05) (class_ ("III cl. (Priv.)")) (title "Rub Feria VI. S Bonifatii Ep. et Mart.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. vel de Martyribus. Feria VI prima in mense."))) + (praef ("comm. vel de Martyribus. Feria VI prima in mense.")) + (alt_te_deum ())) ((date 2026-06-06) (class_ ("III cl.")) (title "Alb Sabb. S Norberti Ep. et Conf.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. Sabbatum primum in mense. I"))) + (praef ("comm. Sabbatum primum in mense. I")) (alt_te_deum ())) ((date 2026-06-07) (class_ ("II cl.")) (title "Vir DOM. II POST PENTECOSTEN, De ea,") (te_deum (true)) - (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-06-08) (class_ ("IV cl.")) (title "Vir Feria II post Dom. II post Pentecosten, De ea,") - (te_deum (false)) (gloria (false)) (credo (false)) (praef (comm.))) + (te_deum (false)) (gloria (false)) (credo (false)) (praef (comm.)) + (alt_te_deum ())) ((date 2026-06-09) (class_ ("IV cl.")) (title "Vir Feria III post Dom. II post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-06-10) (class_ ("III cl.")) (title "Alb Feria IV. S Margaritae Reginae, Vid.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef (comm.))) + (gloria (true)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-06-11) (class_ ("III cl. (Priv.)")) (title "Rub Feria V. S Barnabae Apostoli,") (te_deum (true)) - (gloria (true)) (credo (true)) (praef ("App. I"))) + (gloria (true)) (credo (true)) (praef ("App. I")) (alt_te_deum ())) ((date 2026-06-12) (class_ ("I cl.")) (title "Alb Feria VI. SACRATISSIMI CORDIS IESU,") (te_deum ()) (gloria (true)) (credo (true)) (praef - ("de Ss.mi Corde Iesu. Hodie, in qualibet ecclesia, coram Ss. Sacramento exposito, legatur formula reparationis et cantentur vel recitentur Litani\195\166 Sacratissimi Cordis Iesu (cfr. Enchiridion Indulgentiarum. Preces et pia opera, 1952, n.256, p.163). II"))) + ("de Ss.mi Corde Iesu. Hodie, in qualibet ecclesia, coram Ss. Sacramento exposito, legatur formula reparationis et cantentur vel recitentur Litani\195\166 Sacratissimi Cordis Iesu (cfr. Enchiridion Indulgentiarum. Preces et pia opera, 1952, n.256, p.163). II")) + (alt_te_deum ())) ((date 2026-06-13) (class_ ("III cl. (Priv.)")) (title "Alb Sabb. S Antonii de Padua Conf. et Eccl. Doct.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-06-14) (class_ ("II cl.")) (title "Vir DOM. III POST PENTECOSTEN, De ea,") (te_deum (true)) - (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-06-15) (class_ ("IV cl.")) (title "Vir Feria II post Dom. III post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-06-16) (class_ ("IV cl.")) (title "Vir Feria III post Dom. III post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-06-17) (class_ ("III cl.")) (title "Alb Feria IV. S Gregorii Barbadici Ep. et Conf.,") - (te_deum (true)) (gloria (true)) (credo (false)) (praef (comm.))) + (te_deum (true)) (gloria (true)) (credo (false)) (praef (comm.)) + (alt_te_deum ())) ((date 2026-06-18) (class_ ("III cl.")) (title "Alb Feria V. S Ephraem Syri Diaconi, Conf. et Eccl. Doct.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef - ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa pr. SS Marci et Marcelliani Mm. (rub.), Gloria, comm. S Ephraem Syri Diaconi, Conf. et Eccl. Doct., praef. comm. vel de Martyribus. Ad"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-06-19) (class_ ("III cl.")) (title "Alb Feria VI. S Iulianae De Falconeriis Virg.,") (te_deum (true)) - (gloria (true)) (credo (false)) - (praef - ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa pr. SS Gervasii et Protasii Mm. (rub.), Gloria, comm. S Iulianae De Falconeriis Virg., praef. comm. vel de Martyribus."))) + (gloria (true)) (credo (false)) (praef ("comm. \226\128\147")) + (alt_te_deum ())) ((date 2026-06-20) (class_ ("IV cl.")) (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) - (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147"))) + (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147")) + (alt_te_deum ())) ((date 2026-06-21) (class_ ("II cl.")) (title "Vir DOM. IV POST PENTECOSTEN, De ea,") (te_deum (true)) - (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-06-22) (class_ ("III cl.")) (title "Alb Feria II. S Paulini Ep. et Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef (comm.))) + (gloria (true)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-06-23) (class_ ("II cl.")) (title "Viol Feria III. VIGILIA NATIVITATIS S IOANNIS * BAPTISTAE,") - (te_deum (false)) (gloria (false)) (credo (false)) (praef ("comm. I"))) + (te_deum (false)) (gloria (false)) (credo (false)) (praef ("comm. I")) + (alt_te_deum ())) ((date 2026-06-24) (class_ ("I cl.")) (title "Alb Feria IV. IN NATIVITATE S IOANNIS * BAPTISTAE,") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("comm. vel de S Ioanni Baptista. II"))) + (praef ("comm. vel de S Ioanni Baptista. II")) (alt_te_deum ())) ((date 2026-06-25) (class_ ("III cl.")) (title "Alb Feria V. S Gulielmi Abb.,") (te_deum (true)) (gloria (true)) - (credo (false)) (praef (comm.))) + (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-06-26) (class_ ("III cl.")) (title "Rub Feria VI. SS Ioannis * et Pauli * Mm.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus."))) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus.")) + (alt_te_deum ())) ((date 2026-06-27) (class_ ("IV cl.")) (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) - (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147"))) + (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147")) + (alt_te_deum ())) ((date 2026-06-28) (class_ ("II cl.")) (title "Vir DOM. V POST PENTECOSTEN, De ea,") (te_deum (true)) - (gloria (true)) (credo (true)) (praef ("Trinit. I"))) + (gloria (true)) (credo (true)) (praef ("Trinit. I")) (alt_te_deum ())) ((date 2026-06-29) (class_ ("I cl.")) (title "Rub Feria II. SS PETRI * ET PAULI * APP.,") (te_deum ()) - (gloria (true)) (credo (true)) (praef ("App. II"))) + (gloria (true)) (credo (true)) (praef ("App. II")) (alt_te_deum ())) ((date 2026-06-30) (class_ ("III cl. (Priv.)")) (title "Rub Feria III. In Commemoratione S Pauli * Ap.,") - (te_deum (true)) (gloria (true)) (credo (false)) (praef ("App. I"))) + (te_deum (true)) (gloria (true)) (credo (false)) (praef ("App. I")) + (alt_te_deum ())) ((date 2026-07-01) (class_ ("I cl.")) (title "Rub Feria IV. PRETIOSISSIMI SANGUINIS D. N. I. C.,") (te_deum ()) - (gloria (true)) (credo (true)) (praef ("de Sancta Cruce. II"))) + (gloria (true)) (credo (true)) (praef ("de Sancta Cruce. II")) + (alt_te_deum ())) ((date 2026-07-02) (class_ ("II cl.")) (title "Alb Feria V. IN VISITATIONE B. MARIAE VIRG.,") (te_deum ()) - (gloria (true)) (credo (true)) (praef ("BMV Et te in Visitatione. Ad"))) + (gloria (true)) (credo (true)) (praef ("BMV Et te in Visitatione. Ad")) + (alt_te_deum ())) ((date 2026-07-03) (class_ ("III cl.")) (title "Rub Feria VI. S Iren\195\166i Ep. et Mart.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. vel de Martyribus. Feria VI prima in mense."))) + (praef ("comm. vel de Martyribus. Feria VI prima in mense.")) + (alt_te_deum ())) ((date 2026-07-04) (class_ ("IV cl.")) (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) - (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147"))) + (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147")) + (alt_te_deum ())) ((date 2026-07-05) (class_ ("II cl.")) (title "Vir DOM. VI POST PENTECOSTEN, De ea,") (te_deum (true)) - (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-07-06) (class_ ("IV cl.")) (title "Vir Feria II post Dom. VI post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-07-07) (class_ ("III cl. (Priv.)")) (title "Alb Feria III. SS Cyrilli et Methodii Epp. et Cc.,") - (te_deum (true)) (gloria (true)) (credo (false)) (praef ("comm. Ad"))) + (te_deum (true)) (gloria (true)) (credo (false)) (praef ("comm. Ad")) + (alt_te_deum ())) ((date 2026-07-08) (class_ ("III cl.")) (title "Alb Feria IV. S Elisabeth Reginae, Vid.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. Ad"))) + (gloria (true)) (credo (false)) (praef ("comm. Ad")) (alt_te_deum ())) ((date 2026-07-09) (class_ ("IV cl.")) (title "Vir Feria V post Dom. VI post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-07-10) (class_ ("III cl.")) (title "Rub Feria VI. SS Septem Fratrum Mm., Ac SS Rufinae et Secundae Vv. et Mm.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. vel de Martyribus."))) + (praef ("comm. vel de Martyribus.")) (alt_te_deum ())) ((date 2026-07-11) (class_ ("IV cl.")) (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) - (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147"))) + (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147")) + (alt_te_deum ())) ((date 2026-07-12) (class_ ("II cl.")) (title "Vir DOM. VII POST PENTECOSTEN, De ea,") (te_deum (true)) - (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-07-13) (class_ ("IV cl.")) (title "Vir Feria II post Dom. VII post Pentecosten, De ea,") - (te_deum (false)) (gloria (false)) (credo (false)) (praef (comm.))) + (te_deum (false)) (gloria (false)) (credo (false)) (praef (comm.)) + (alt_te_deum ())) ((date 2026-07-14) (class_ ("III cl. (Priv.)")) (title "Alb Feria III. S Bonaventurae Ep., Conf. et Eccl. Doct.,") - (te_deum (true)) (gloria (true)) (credo (false)) (praef ("comm. Ad"))) + (te_deum (true)) (gloria (true)) (credo (false)) (praef ("comm. Ad")) + (alt_te_deum ())) ((date 2026-07-15) (class_ ("III cl.")) (title "Alb Feria IV. S Henrici Imperatoris Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef (comm.))) + (gloria (true)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-07-16) (class_ ("IV cl.")) (title "Vir Feria V post Dom. VII post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-07-17) (class_ ("IV cl.")) (title "Vir Feria VI post Dom. VII post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-07-18) (class_ ("III cl.")) (title "Alb Sabb. S Camilli de Lellis Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) - (praef - ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa SS Symphorosae et septem filiorum eius Mm. (rub.) Clamaverunt (ut in festo Ss. duodecim Fratrum Mm., die 1 sept.), Gloria, ors. pr., comm. S Camilli de Lellis Conf., praef. comm. vel de Martyribus. I"))) + (gloria (true)) (credo (false)) (praef ("comm. \226\128\147")) + (alt_te_deum ())) ((date 2026-07-19) (class_ ("II cl.")) (title "Vir DOM. VIII POST PENTECOSTEN, De ea,") (te_deum (true)) - (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-07-20) (class_ ("III cl.")) (title "Alb Feria II. S Hieronymi \211\148miliani Conf.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef - ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa S Margaritae Virg. et Mart. (rub.) Me exspectaverunt, Gloria, comm. S Hieronymi \211\148miliani Conf., praef. comm. vel de Martyribus."))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-07-21) (class_ ("III cl.")) (title "Alb Feria III. S Laurentii de Brundusio Conf. et Eccl. Doct.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef - ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa pr. S Praexedis Virg. (alb.), Gloria, comm. S Laurentii de Brundusio Conf. et Eccl. Doct., praef. comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-07-22) (class_ ("III cl. (Priv.)")) (title "Alb Feria IV. S Mariae Magdalenae P\197\147nitentis,") - (te_deum (true)) (gloria (true)) (credo (false)) (praef ("comm. Ad"))) + (te_deum (true)) (gloria (true)) (credo (false)) (praef ("comm. Ad")) + (alt_te_deum ())) ((date 2026-07-23) (class_ ("III cl.")) (title "Rub Feria V. S Apollinaris Ep. et Mart.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef - ("comm. vel de Martyribus \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa S Liborii Ep. et Conf. (alb.) Statuit de Comm. Confessoris Pontificis, Gloria, comm. S Apollinaris Ep. et Mart., praef. comm."))) + (praef ("comm. vel de Martyribus \226\128\147")) (alt_te_deum ())) ((date 2026-07-24) (class_ ("IV cl.")) (title "Vir Feria VI post Dom. VIII post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-07-25) (class_ ("II cl.")) (title "Rub Sabb. S IACOBI * APOSTOLI,") (te_deum ()) (gloria (true)) - (credo (true)) (praef ("App. Ad"))) + (credo (true)) (praef ("App. Ad")) (alt_te_deum ())) ((date 2026-07-26) (class_ ("II cl.")) (title "Vir DOM. IX POST PENTECOSTEN, De ea,") (te_deum (true)) - (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-07-27) (class_ ("IV cl.")) (title "Vir Feria II post Dom. IX post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-07-28) (class_ ("III cl.")) (title "Rub Feria III. SS Nazarii et Celsi, Mm., Victoris I Papae et Mart. ac Inocentii I Papae et Conf.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. vel de Martyribus."))) + (praef ("comm. vel de Martyribus.")) (alt_te_deum ())) ((date 2026-07-29) (class_ ("III cl. (Priv.)")) (title "Alb Feria IV. S Marthae Virg.,") (te_deum (true)) (gloria (true)) - (credo (false)) (praef (comm.))) + (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-07-30) (class_ ("IV cl.")) (title "Vir Feria V post Dom. IX post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-07-31) (class_ ("III cl. (Priv.)")) (title "Alb Feria VI. S Ignatii Conf.,") (te_deum (true)) (gloria (true)) - (credo (false)) (praef (comm.))) + (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-08-01) (class_ ("IV cl.")) (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) - (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147"))) + (credo (false)) (praef ("BMV Et te in Veneratione \226\128\147")) + (alt_te_deum ())) ((date 2026-08-02) (class_ ("II cl.")) (title "Vir DOM. X POST PENTECOSTEN, De ea,") (te_deum (true)) - (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-08-03) (class_ ("IV cl.")) (title "Vir Feria II post Dom. X post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-08-04) (class_ ("III cl. (Priv.)")) (title "Alb Feria III. S Dominici Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef (comm.))) + (gloria (true)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-08-05) (class_ ("III cl. (Priv.)")) (title "Alb Feria IV. In Dedicatione S Mariae ad Nives,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("BMV Et te in Festivitate."))) + (praef ("BMV Et te in Festivitate.")) (alt_te_deum ())) ((date 2026-08-06) (class_ ("II cl.")) (title "Alb Feria V. IN TRANSFIGURATIONE D. N. I. C.,") (te_deum ()) - (gloria (true)) (credo (true)) (praef ("comm. II"))) + (gloria (true)) (credo (true)) (praef ("comm. II")) (alt_te_deum ())) ((date 2026-08-07) (class_ ("III cl.")) (title "Alb Feria VI. S Caietani Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) - (praef - ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa pr. S Donati, Ep. et Mart. (rub.), Gloria, comm. S Caietani Conf., praef. comm. vel de Martyribus. Feria VI prima in mense."))) + (gloria (true)) (credo (false)) (praef ("comm. \226\128\147")) + (alt_te_deum ())) ((date 2026-08-08) (class_ ("III cl. (Priv.)")) (title "Alb Sabb. S Ioannis Mariae Vianney Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. \226\128\147"))) + (gloria (true)) (credo (false)) (praef ("comm. \226\128\147")) + (alt_te_deum ())) ((date 2026-08-09) (class_ ("II cl.")) (title "Vir DOM. XI POST PENTECOSTEN, De ea,") (te_deum (true)) - (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-08-10) (class_ ("II cl.")) (title "Rub Feria II. S LAURENTII * MART.,") (te_deum ()) (gloria (true)) - (credo (false)) (praef ("comm. vel de Martyribus. II"))) + (credo (false)) (praef ("comm. vel de Martyribus. II")) (alt_te_deum ())) ((date 2026-08-11) (class_ ("IV cl.")) (title "Vir Feria III post Dom. XI post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-08-12) (class_ ("III cl. (Priv.)")) (title "Alb Feria IV. S Clarae Virg.,") (te_deum (true)) (gloria (true)) - (credo (false)) (praef (comm.))) + (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-08-13) (class_ ("IV cl.")) (title "Vir Feria V post Dom. XI post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-08-14) (class_ ("II cl.")) (title "Viol Feria VI. VIGILIA ASSUMPTIONIS B. MARIAE VIRG.,") - (te_deum (false)) (gloria (false)) (credo (false)) (praef ("comm. I"))) + (te_deum (false)) (gloria (false)) (credo (false)) (praef ("comm. I")) + (alt_te_deum ())) ((date 2026-08-15) (class_ ("I cl.")) (title "Alb Sabb. IN ASSUMPTIONE B. MARIAE VIRG.,") (te_deum ()) - (gloria (true)) (credo (true)) (praef ("BMV Et te in Assumptione. Ad"))) + (gloria (true)) (credo (true)) (praef ("BMV Et te in Assumptione. Ad")) + (alt_te_deum ())) ((date 2026-08-16) (class_ ("II cl.")) (title "Vir DOM. XII POST PENTECOSTEN, De ea,") (te_deum (true)) - (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-08-17) (class_ ("III cl.")) (title "Alb Feria II. S Hyacinthi Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef (comm.))) + (gloria (true)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-08-18) (class_ ("IV cl.")) (title "Vir Feria III post Dom. XII post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-08-19) (class_ ("III cl.")) (title "Alb Feria IV. S Ioannis Eudes Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef (comm.))) + (gloria (true)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-08-20) (class_ ("III cl. (Priv.)")) (title "Alb Feria V. S Bernardi Abb. et Eccl. Doct.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. \226\128\147"))) + (gloria (true)) (credo (false)) (praef ("comm. \226\128\147")) + (alt_te_deum ())) ((date 2026-08-21) (class_ ("III cl.")) (title "Alb Feria VI. S Ioannae Franciscae Fr\195\169miot de Chantal Vid.,") - (te_deum (true)) (gloria (true)) (credo (false)) (praef (comm.))) + (te_deum (true)) (gloria (true)) (credo (false)) (praef (comm.)) + (alt_te_deum ())) ((date 2026-08-22) (class_ ("II cl.")) (title "Alb Sabb. IMMACULATI CORDIS B. MARIAE VIRG.,") (te_deum ()) - (gloria (true)) (credo (true)) (praef ("BMV Et te in Festivitate. Ad"))) + (gloria (true)) (credo (true)) (praef ("BMV Et te in Festivitate. Ad")) + (alt_te_deum ())) ((date 2026-08-23) (class_ ("II cl.")) (title "Vir DOM. XIII POST PENTECOSTEN, De ea,") (te_deum (true)) - (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-08-24) (class_ ("II cl.")) (title "Rub Feria II. S BARTHOLOMAEI * AP.,") (te_deum ()) - (gloria (true)) (credo (true)) (praef (App.))) + (gloria (true)) (credo (true)) (praef (App.)) (alt_te_deum ())) ((date 2026-08-25) (class_ ("III cl.")) (title "Alb Feria III. S Ludovici Regis Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef (comm.))) + (gloria (true)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-08-26) (class_ ("IV cl.")) (title "Vir Feria IV post Dom. XIII post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-08-27) (class_ ("III cl.")) (title "Alb Feria V. S Iosephi Calasanctii Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef (comm.))) + (gloria (true)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-08-28) (class_ ("III cl. (Priv.)")) (title "Alb Feria VI. S Augustini Ep., Conf. et Eccl. Doct.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-08-29) (class_ ("III cl. (Priv.)")) (title "Rub Sabb. In Decollatione S Ioannis * Baptistae,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. vel de S Ioanni Baptista \226\128\147"))) + (praef ("comm. vel de S Ioanni Baptista \226\128\147")) (alt_te_deum ())) ((date 2026-08-30) (class_ ("II cl.")) (title "Vir DOM. XIV POST PENTECOSTEN, De ea,") (te_deum (true)) - (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-08-31) (class_ ("III cl.")) (title "Alb Feria II. S Raymundi Nonnati Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef (comm.))) + (gloria (true)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-09-01) (class_ ("IV cl.")) (title "Vir Feria III post Dom. XIV post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-09-02) (class_ ("III cl.")) (title "Alb Feria IV. S Stephani Regis Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef (comm.))) + (gloria (true)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-09-03) (class_ ("III cl. (Priv.)")) (title "Alb Feria V. S Pii X Papae et Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. Ad"))) + (gloria (true)) (credo (false)) (praef ("comm. Ad")) (alt_te_deum ())) ((date 2026-09-04) (class_ ("IV cl.")) (title "Vir Feria VI post Dom. XIV post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-09-05) (class_ ("III cl.")) (title "Alb Sabb. S Laurentii Iustiniani Ep. et Conf.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. Sabbatum primum in mense. I"))) + (praef ("comm. Sabbatum primum in mense. I")) (alt_te_deum ())) ((date 2026-09-06) (class_ ("II cl.")) (title "Vir DOM. XV POST PENTECOSTEN, De ea,") (te_deum (true)) - (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-09-07) (class_ ("IV cl.")) (title "Vir Feria II post Dom. XV post Pentecosten, De ea,") - (te_deum (false)) (gloria (false)) (credo (false)) (praef (comm.))) + (te_deum (false)) (gloria (false)) (credo (false)) (praef (comm.)) + (alt_te_deum ())) ((date 2026-09-08) (class_ ("II cl.")) (title "Alb Feria III. IN NATIVITATE B. MARIAE VIRG.,") (te_deum ()) - (gloria (true)) (credo (true)) (praef ("BMV Et te in Nativitate. Ad"))) + (gloria (true)) (credo (true)) (praef ("BMV Et te in Nativitate. Ad")) + (alt_te_deum ())) ((date 2026-09-09) (class_ ("IV cl.")) (title "Vir Feria IV post Dom. XV post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-09-10) (class_ ("III cl.")) (title "Alb Feria V. S Nicolai de Tolentino Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef (comm.))) + (gloria (true)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-09-11) (class_ ("IV cl.")) (title "Vir Feria VI post Dom. XV post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-09-12) (class_ ("III cl. (Priv.)")) (title "Alb Sabb. Sanctissimi Nominis Mariae,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("BMV Et te in Festivitate. I"))) + (gloria (true)) (credo (false)) (praef ("BMV Et te in Festivitate. I")) + (alt_te_deum ())) ((date 2026-09-13) (class_ ("II cl.")) (title "Vir DOM. XVI POST PENTECOSTEN, De ea,") (te_deum (true)) - (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-09-14) (class_ ("II cl.")) (title "Rub Feria II. IN EXALTATIONE S CRUCIS,") (te_deum ()) (gloria (true)) (credo (true)) (praef - ("de Sancta Cruce. In Epistola ad verba Ut in nomine Iesu usque ad infernorum inclusive genuflectitur, item in Choro ab omnibus in Missa in cantu. II"))) + ("de Sancta Cruce. In Epistola ad verba Ut in nomine Iesu usque ad infernorum inclusive genuflectitur, item in Choro ab omnibus in Missa in cantu. II")) + (alt_te_deum ())) ((date 2026-09-15) (class_ ("II cl.")) (title "Alb Feria III. SEPTEM DOLORUM B. MARIAE VIRGINIS,") (te_deum ()) - (gloria (true)) (credo (true)) (praef ("BMV Et te in Transfixione. Ad"))) + (gloria (true)) (credo (true)) (praef ("BMV Et te in Transfixione. Ad")) + (alt_te_deum ())) ((date 2026-09-16) (class_ ("III cl. (Priv.)")) (title "Rub Feria IV. SS Cornelis * Papae et Cypriani * Ep., Mm.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. vel de Martyribus."))) + (praef ("comm. vel de Martyribus.")) (alt_te_deum ())) ((date 2026-09-17) (class_ ("IV cl.")) (title "Vir Feria V post Dom. XVI post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-09-18) (class_ ("III cl.")) (title "Alb Feria VI. S Iosephi de Cupertino Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef (comm.))) + (gloria (true)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-09-19) (class_ ("III cl.")) (title "Rub Sabb. SS Ianuarii Ep. et Sociorum Mm.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. I"))) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. I")) + (alt_te_deum ())) ((date 2026-09-20) (class_ ("II cl.")) (title "Vir DOM. XVII POST PENTECOSTEN, De ea,") (te_deum (true)) - (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-09-21) (class_ ("II cl.")) (title "Rub Feria II. S MATTHAEI * AP. ET EV.,") (te_deum ()) - (gloria (true)) (credo (true)) (praef (App.))) + (gloria (true)) (credo (true)) (praef (App.)) (alt_te_deum ())) ((date 2026-09-22) (class_ ("III cl.")) (title "Alb Feria III. S Thomae de Villanova Ep. et Conf.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef - ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa SS Mauritii et Sociorum Mm. (rub.) Intret in conspectu tuo, Gloria, ors. et Evangelium pr., comm. S Thomae de Villanova Ep. et Conf., praef. comm. vel de Martyribus."))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-09-23) (class_ ("II cl.")) (title "Viol FERIA IV QUATTUOR TEMP., De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147 Quoad Flectamus genua vide RM 440."))) + (praef ("comm. \226\128\147 Quoad Flectamus genua vide RM 440.")) + (alt_te_deum ())) ((date 2026-09-24) (class_ ("IV cl.")) (title "Vir Feria V post Dom. XVII post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-09-25) (class_ ("II cl.")) (title "Viol FERIA VI QUATTUOR TEMP., De ea,") (te_deum (false)) - (gloria (false)) (credo (false)) (praef (comm.))) + (gloria (false)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-09-26) (class_ ("II cl.")) (title "Viol SABB. QUATTUOR TEMP., De eo,") (te_deum (false)) (gloria (false)) (credo (false)) (praef - ("comm. \226\128\147 Quoad Flectamus genua vide RM 440. Quoad lectiones vide RM 468. I"))) + ("comm. \226\128\147 Quoad Flectamus genua vide RM 440. Quoad lectiones vide RM 468. I")) + (alt_te_deum ())) ((date 2026-09-27) (class_ ("II cl.")) (title "Vir DOM. XVIII POST PENTECOSTEN, De ea,") (te_deum (true)) - (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-09-28) (class_ ("III cl.")) (title "Rub Feria II. S Wenceslai Ducis Mart.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. I"))) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. I")) + (alt_te_deum ())) ((date 2026-09-29) (class_ ("I cl.")) (title "Alb Feria III. IN DEDICATIONE S MICHA\195\139LIS ARCHANGELI,") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("comm. vel de Angelis. II"))) + (praef ("comm. vel de Angelis. II")) (alt_te_deum ())) ((date 2026-09-30) (class_ ("III cl. (Priv.)")) (title "Alb Feria IV. S Hieronymi Presbyteri, Conf. et Eccl. Doct.,") - (te_deum (true)) (gloria (true)) (credo (false)) (praef ("comm. Ad"))) + (te_deum (true)) (gloria (true)) (credo (false)) (praef ("comm. Ad")) + (alt_te_deum ())) ((date 2026-10-01) (class_ ("IV cl.")) (title "Vir Feria V post Dom. XVIII post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-10-02) (class_ ("III cl. (Priv.)")) (title "Alb Feria VI. SS Angelorum Custodum,") (te_deum (true)) (gloria (true)) (credo (false)) (praef - ("comm. vel de Angelis. Feria VI prima in mense. Vesper\195\166 pr."))) + ("comm. vel de Angelis. Feria VI prima in mense. Vesper\195\166 pr.")) + (alt_te_deum ())) ((date 2026-10-03) (class_ ("III cl. (Priv.)")) (title "Alb Sabb. S Teresiae a Iesu Infante Virg.,") (te_deum (true)) (gloria (true)) (credo (false)) (praef - ("comm. Sabbatum primum in mense. I Vesper\195\166 de seq. dom., ut in Psalt. de sabb, ad Magn. ant. Adaperiat (dom. I octobris), or. pr., sine comm. \226\128\147 Compl. de sabb."))) + ("comm. Sabbatum primum in mense. I Vesper\195\166 de seq. dom., ut in Psalt. de sabb, ad Magn. ant. Adaperiat (dom. I octobris), or. pr., sine comm. \226\128\147 Compl. de sabb.")) + (alt_te_deum ())) ((date 2026-10-04) (class_ ("II cl.")) (title "Vir DOM. XIX POST PENTECOSTEN, De ea,") (te_deum (true)) - (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-10-05) (class_ ("IV cl.")) (title "Vir Feria II post Dom. XIX post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-10-06) (class_ ("III cl. (Priv.)")) (title "Alb Feria III. S Brunonis Conf.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. Vesper\195\166 de festo. 100"))) + (praef ("comm. Vesper\195\166 de festo. 100")) (alt_te_deum ())) ((date 2026-10-07) (class_ ("II cl.")) (title "Alb Feria IV. B. MARIAE VIRG. A ROSARIO,") (te_deum ()) - (gloria (true)) (credo (true)) (praef ("BMV Et te in Festivitate. Ad"))) + (gloria (true)) (credo (true)) (praef ("BMV Et te in Festivitate. Ad")) + (alt_te_deum ())) ((date 2026-10-08) (class_ ("III cl.")) (title "Alb Feria V. S Birgittae Vid.,") (te_deum (true)) (gloria (true)) - (credo (false)) - (praef - ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa SS Sergii, Bacchi, Marcelli et Apuleii Mm. (rub.) Sapientiam Sanctorum, Gloria, ors. pr., comm. S Birgittae Vid., praef. comm. vel de Martyribus. Vesper\195\166 de festo, sine comm."))) + (credo (false)) (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-10-09) (class_ ("III cl.")) (title "Alb Feria VI. S Ioannis Leonardi Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) - (praef - ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa pr. SS Dionysii Ep., Rustici et Eleutherii Mm. (rub.), Gloria, comm. S Ioannis Leonardi Conf., praef. comm. vel de Martyribus. Vesper\195\166 de festo, sine comm."))) + (gloria (true)) (credo (false)) (praef ("comm. \226\128\147")) + (alt_te_deum ())) ((date 2026-10-10) (class_ ("III cl.")) (title "Alb Sabb. S Francisci Borgiae Conf.,") (te_deum (true)) (gloria (true)) (credo (false)) (praef - ("comm. I Vesper\195\166 de seq. dom., ut in Psalt. de sabb, ad Magn. ant. Refulsit sol (dom. II octobris), or. pr., sine comm. \226\128\147 Compl. de sabb."))) + ("comm. I Vesper\195\166 de seq. dom., ut in Psalt. de sabb, ad Magn. ant. Refulsit sol (dom. II octobris), or. pr., sine comm. \226\128\147 Compl. de sabb.")) + (alt_te_deum ())) ((date 2026-10-11) (class_ ("II cl.")) (title "Vir DOM. XX POST PENTECOSTEN, De ea,") (te_deum (true)) - (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-10-12) (class_ ("IV cl.")) (title "Vir Feria II post Dom. XX post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. Vesper\195\166 de feria or. dom. pr\195\166c."))) + (praef ("comm. Vesper\195\166 de feria or. dom. pr\195\166c.")) + (alt_te_deum ())) ((date 2026-10-13) (class_ ("III cl.")) (title "Alb Feria III. S Eduardis Regis Conf.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. Vesper\195\166 de festo."))) + (praef ("comm. Vesper\195\166 de festo.")) (alt_te_deum ())) ((date 2026-10-14) (class_ ("III cl. (Priv.)")) (title "Rub Feria IV. S Callisti I Papae et Mart.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. vel de Martyribus. Vesper\195\166 de festo."))) + (praef ("comm. vel de Martyribus. Vesper\195\166 de festo.")) + (alt_te_deum ())) ((date 2026-10-15) (class_ ("III cl. (Priv.)")) (title "Alb Feria V. S Teresiae Virg.,") (te_deum (true)) (gloria (true)) - (credo (false)) (praef ("comm. \226\128\147"))) + (credo (false)) (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-10-16) (class_ ("III cl.")) (title "Alb Feria VI. S Hedwigis Vid.,") (te_deum (true)) (gloria (true)) - (credo (false)) (praef ("comm. Vesper\195\166 de festo."))) + (credo (false)) (praef ("comm. Vesper\195\166 de festo.")) + (alt_te_deum ())) ((date 2026-10-17) (class_ ("III cl.")) (title "Alb Sabb. S Margaritae Mariae Alacoque Virg.,") (te_deum (true)) (gloria (true)) (credo (false)) (praef - ("comm. I Vesper\195\166 de seq. dom., ut in Psalt. de sabb, ad Magn. ant. Exaudiat Dominus (dom. IV octobris), or. pr., sine comm. \226\128\147 Compl. de sabb."))) + ("comm. I Vesper\195\166 de seq. dom., ut in Psalt. de sabb, ad Magn. ant. Exaudiat Dominus (dom. IV octobris), or. pr., sine comm. \226\128\147 Compl. de sabb.")) + (alt_te_deum ())) ((date 2026-10-18) (class_ ("II cl.")) (title "Vir DOM. XXI POST PENTECOSTEN, De ea,") (te_deum (true)) - (gloria (true)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (true)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-10-19) (class_ ("III cl.")) (title "Alb Feria II. S Petri de Alcantara Conf.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. Vesper\195\166 de festo."))) + (praef ("comm. Vesper\195\166 de festo.")) (alt_te_deum ())) ((date 2026-10-20) (class_ ("III cl.")) (title "Alb Feria III. S Ioannis Cantii Conf.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. Vesper\195\166 de festo."))) + (praef ("comm. Vesper\195\166 de festo.")) (alt_te_deum ())) ((date 2026-10-21) (class_ ("IV cl.")) (title "Vir Feria IV post Dom. XXI post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-10-22) (class_ ("IV cl.")) (title "Vir Feria V post Dom. XXI post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. Vesper\195\166 de feria or. dom. pr\195\166c."))) + (praef ("comm. Vesper\195\166 de feria or. dom. pr\195\166c.")) + (alt_te_deum ())) ((date 2026-10-23) (class_ ("III cl.")) (title "Alb Feria VI. S Antonii Mariae Claret Ep. et Conf.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-10-24) (class_ ("III cl.")) (title "Alb Sabb. S Rapha\195\171lis Archangeli,") (te_deum (true)) (gloria (true)) (credo (false)) (praef - ("comm. vel de Angelis. I Vesper\195\166 de seq., sine comm. \226\128\147 Compl. de dom. 104"))) + ("comm. vel de Angelis. I Vesper\195\166 de seq., sine comm. \226\128\147 Compl. de dom. 104")) + (alt_te_deum ())) ((date 2026-10-25) (class_ ("I cl.")) (title "Alb Dom. DOMINI NOSTRI JESU CHRISTI REGIS,") (te_deum ()) (gloria (true)) (credo (true)) (praef - ("de Domino Nostro Jesu Rege. Hodie, in omnibus ecclesiis, coram Ss.mo Sacramento exposito, recitetur formula consecrationis generis humani Christo Regi, cum Litaniis de eodem Sacro Corde. II Vesper\195\166 pr. Hodie prohibentur omnes Missae defunctorum, etiam exsequialis."))) + ("de Domino Nostro Jesu Rege. Hodie, in omnibus ecclesiis, coram Ss.mo Sacramento exposito, recitetur formula consecrationis generis humani Christo Regi, cum Litaniis de eodem Sacro Corde. II Vesper\195\166 pr. Hodie prohibentur omnes Missae defunctorum, etiam exsequialis.")) + (alt_te_deum ())) ((date 2026-10-26) (class_ ("IV cl.")) (title "Vir Feria II post Dom. XXII post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-10-27) (class_ ("IV cl.")) (title "Vir Feria III post Dom. XXII post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. Vesper\195\166 de feria, or. dom. XXII post Pent."))) + (praef ("comm. Vesper\195\166 de feria, or. dom. XXII post Pent.")) + (alt_te_deum ())) ((date 2026-10-28) (class_ ("II cl.")) (title "Rub Feria IV. SS SIMONIS * ET IUD\195\134 * APP.,") (te_deum ()) (gloria (true)) (credo (true)) (praef - ("App. In Canone Miss\195\166, nomen S. Apostoli Iud\195\166 inscribitur cum nomine Thadd\195\166i: ergo inclinatur caput quando dicitur Thadd\195\166i. Vesper\195\166 de Comm. \226\128\147 Compl. de dom. Hodie permittuntur tantum Missae votivae et defunctorum I et II classis."))) + ("App. In Canone Miss\195\166, nomen S. Apostoli Iud\195\166 inscribitur cum nomine Thadd\195\166i: ergo inclinatur caput quando dicitur Thadd\195\166i. Vesper\195\166 de Comm. \226\128\147 Compl. de dom. Hodie permittuntur tantum Missae votivae et defunctorum I et II classis.")) + (alt_te_deum ())) ((date 2026-10-29) (class_ ("IV cl.")) (title "Vir Feria V post Dom. XXII post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. Vesper\195\166 de feria or. dom. XXII post Pent."))) + (praef ("comm. Vesper\195\166 de feria or. dom. XXII post Pent.")) + (alt_te_deum ())) ((date 2026-10-30) (class_ ("IV cl.")) (title "Vir Feria VI post Dom. XXII post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. Vesper\195\166 de feria or. dom. XXII post Pent."))) + (praef ("comm. Vesper\195\166 de feria or. dom. XXII post Pent.")) + (alt_te_deum ())) ((date 2026-10-31) (class_ ("IV cl.")) (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) (credo (false)) (praef - ("BMV Et te in Veneratione. I Vesper\195\166 de seq. \226\128\147 Compl. de dom. 106"))) + ("BMV Et te in Veneratione. I Vesper\195\166 de seq. \226\128\147 Compl. de dom. 106")) + (alt_te_deum ())) ((date 2026-11-01) (class_ ("I cl.")) (title "Alb Dom. OMNIUM SANCTORUM,") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("Trinit. vel de Omnibus Sanctis et Patronis. II"))) + (praef ("Trinit. vel de Omnibus Sanctis et Patronis. II")) + (alt_te_deum ())) ((date 2026-11-02) (class_ ("I cl.")) (title "Nig Feria II. IN COMMEMORATIONE OMNIUM FIDELIUM DEFUNCTORUM,") (te_deum ()) (gloria (false)) (credo (false)) (praef - ("defunctorum, unica or. \226\128\147 Benedictio non dicitur. \226\128\147 Si tres Miss\195\166 celebrantur sine intermissione, sequentia dici debet tantum in Missa principali; si minus, dici debet in Missa prima. In aliis Missis, nisi sint in cantu, sequentia omitti potest."))) + ("defunctorum, unica or. \226\128\147 Benedictio non dicitur. \226\128\147 Si tres Miss\195\166 celebrantur sine intermissione, sequentia dici debet tantum in Missa principali; si minus, dici debet in Missa prima. In aliis Missis, nisi sint in cantu, sequentia omitti potest.")) + (alt_te_deum ())) ((date 2026-11-03) (class_ ("IV cl.")) (title "Vir Feria III post Dom. XXIII post Pentecosten, De ea,") - (te_deum (false)) (gloria (false)) (credo (false)) (praef (comm.))) + (te_deum (false)) (gloria (false)) (credo (false)) (praef (comm.)) + (alt_te_deum ())) ((date 2026-11-04) (class_ ("III cl. (Priv.)")) (title "Alb Feria IV. S Caroli Ep. et Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. \226\128\147"))) + (gloria (true)) (credo (false)) (praef ("comm. \226\128\147")) + (alt_te_deum ())) ((date 2026-11-05) (class_ ("IV cl.")) (title "Vir Feria V post Dom. XXIII post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-11-06) (class_ ("IV cl.")) (title "Vir Feria VI post Dom. XXIII post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. Feria VI prima in mense."))) + (praef ("comm. Feria VI prima in mense.")) (alt_te_deum ())) ((date 2026-11-07) (class_ ("IV cl.")) (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("BMV Et te in Veneratione. Sabbatum primum in mense. I"))) + (praef ("BMV Et te in Veneratione. Sabbatum primum in mense. I")) + (alt_te_deum ())) ((date 2026-11-08) (class_ ("II cl.")) (title "Vir DOM. V QUI SUPERFUIT POST EPIPHANIAM, De ea,") (te_deum (true)) (gloria (true)) (credo (true)) (praef - ("Trinit. Dicitur Missa qu\195\166 inscribitur \194\171Dominica. V qui superfuit post Epiphaniam\194\187. Antiphonae ad Introitum, ad Offertorium et ad Communionem, necnon graduale et Alleluia cum suo versu, sumuntur e Dom. XXIII post Pent.; orationes, Epistola et Evangelium, e Dom. V qui superfuit post Epiphaniam. Ad II"))) + ("Trinit. Dicitur Missa qu\195\166 inscribitur \194\171Dominica. V qui superfuit post Epiphaniam\194\187. Antiphonae ad Introitum, ad Offertorium et ad Communionem, necnon graduale et Alleluia cum suo versu, sumuntur e Dom. XXIII post Pent.; orationes, Epistola et Evangelium, e Dom. V qui superfuit post Epiphaniam. Ad II")) + (alt_te_deum ())) ((date 2026-11-09) (class_ ("II cl.")) (title "Alb Feria II. IN DEDICATIONE ARCHIBASILICAE SANCTISSIMI SALVATORIS,") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("comm. vel de Dedicatione ecclesi\195\166."))) + (praef ("comm. vel de Dedicatione ecclesi\195\166.")) (alt_te_deum ())) ((date 2026-11-10) (class_ ("III cl.")) (title "Alb Feria III. S Andreae Avellini Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) - (praef - ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa pr. SS Tryphonis, Respicii et Nymphae Virg., Mm. (rub.), Gloria, comm. S Andreae Avellini Conf., praef. comm. vel de Martyribus."))) + (gloria (true)) (credo (false)) (praef ("comm. \226\128\147")) + (alt_te_deum ())) ((date 2026-11-11) (class_ ("III cl. (Priv.)")) (title "Alb Feria IV. S Martini Ep. et Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef (comm.))) + (gloria (true)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-11-12) (class_ ("III cl.")) (title "Rub Feria V. S Martini I Papae et Mart.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus."))) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus.")) + (alt_te_deum ())) ((date 2026-11-13) (class_ ("III cl.")) (title "Alb Feria VI. S Didaci Conf.,") (te_deum (true)) (gloria (true)) - (credo (false)) (praef ("comm. \226\128\147"))) + (credo (false)) (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-11-14) (class_ ("III cl. (Priv.)")) (title "Rub Sabb. S Iosaphat Ep. et Mart.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. vel de Martyribus \226\128\147"))) + (praef ("comm. vel de Martyribus \226\128\147")) (alt_te_deum ())) ((date 2026-11-15) (class_ ("II cl.")) (title "Vir DOM. VI QUI SUPERFUIT POST EPIPHANIAM, De ea,") (te_deum (true)) (gloria (true)) (credo (true)) (praef - ("Trinit. Dicitur Missa qu\195\166 inscribitur \194\171Dominica. VI qui superfuit post Epiphaniam\194\187. Antiphonae ad Introitum, ad Offertorium et ad Communionem, necnon graduale et Alleluia cum suo versu, sumuntur e Dom. XXIII post Pent.; orationes, Epistola et Evangelium, e Dom. VI qui superfuit post Epiphaniam. Ad II"))) + ("Trinit. Dicitur Missa qu\195\166 inscribitur \194\171Dominica. VI qui superfuit post Epiphaniam\194\187. Antiphonae ad Introitum, ad Offertorium et ad Communionem, necnon graduale et Alleluia cum suo versu, sumuntur e Dom. XXIII post Pent.; orationes, Epistola et Evangelium, e Dom. VI qui superfuit post Epiphaniam. Ad II")) + (alt_te_deum ())) ((date 2026-11-16) (class_ ("III cl.")) (title "Alb Feria II. S Gertrudis Virg.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef (comm.))) + (gloria (true)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-11-17) (class_ ("III cl.")) (title "Alb Feria III. S Gregorii Thaumaturgi Ep. et Conf.,") - (te_deum (true)) (gloria (true)) (credo (false)) (praef (comm.))) + (te_deum (true)) (gloria (true)) (credo (false)) (praef (comm.)) + (alt_te_deum ())) ((date 2026-11-18) (class_ ("III cl. (Priv.)")) (title "Alb Feria IV. In Dedicatione Basilicarum SS Petri et Pauli App.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. vel de Dedicatione ecclesi\195\166."))) + (praef ("comm. vel de Dedicatione ecclesi\195\166.")) (alt_te_deum ())) ((date 2026-11-19) (class_ ("III cl.")) (title "Alb Feria V. S Elisabeth Vid.,") (te_deum (true)) (gloria (true)) - (credo (false)) - (praef - ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa S Pontiani Papae et Mart. (rub.) Si diligis, Gloria, comm. S Elisabeth Vid., praef. comm. vel de Martyribus."))) + (credo (false)) (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-11-20) (class_ ("III cl.")) (title "Alb Feria VI. S Felicis de Valois Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef (comm.))) + (gloria (true)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-11-21) (class_ ("III cl.")) (title "Alb Sabb. In Praesentatione B. Mariae Virg.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("BMV Et te in Pr\195\166sentatione. I"))) + (praef ("BMV Et te in Pr\195\166sentatione. I")) (alt_te_deum ())) ((date 2026-11-22) (class_ ("II cl.")) (title "Vir DOM. XXIV & ULTIMA POST PENTECOSTEN, De ea,") - (te_deum (true)) (gloria (true)) (credo (true)) - (praef ("Trinit. Ad II"))) + (te_deum (true)) (gloria (true)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-11-23) (class_ ("III cl. (Priv.)")) (title "Rub Feria II. S Clementis I * Papae et Mart.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. Ad"))) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. Ad")) + (alt_te_deum ())) ((date 2026-11-24) (class_ ("III cl. (Priv.)")) (title "Alb Feria III. S Ioannis a Cruce Conf. et Eccl. Doct.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-11-25) (class_ ("III cl.")) (title "Rub Feria IV. S Catharinae Virg. et Mart.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus."))) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus.")) + (alt_te_deum ())) ((date 2026-11-26) (class_ ("III cl.")) (title "Alb Feria V. S Silvestri Abb.,") (te_deum (true)) (gloria (true)) - (credo (false)) - (praef - ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa S Petri Alexandrini Ep. et Mart. (rub.) Statuit ei, Gloria, comm. S Silvestri Abb., praef. comm. vel de Martyribus. \226\128\147"))) + (credo (false)) (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-11-27) (class_ ("IV cl.")) (title "Vir Feria VI post Dom. XXIV & Ultima post Pentecosten, De ea,") (te_deum (false)) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-11-28) (class_ ("IV cl.")) (title "Alb Sancta Maria in Sabbato,") (te_deum (true)) (gloria (true)) - (credo (false)) (praef ("BMV Et te in Veneratione. I"))) + (credo (false)) (praef ("BMV Et te in Veneratione. I")) (alt_te_deum ())) ((date 2026-11-29) (class_ ("I cl.")) (title "Viol DOM. I ADVENTUS, De ea,") (te_deum (false)) (gloria (false)) - (credo (true)) (praef ("Trinit. Ad II"))) + (credo (true)) (praef ("Trinit. Ad II")) (alt_te_deum ())) ((date 2026-11-30) (class_ ("II cl.")) (title "Rub Feria II. S ANDREAE * APOSTOLI,") (te_deum ()) - (gloria (true)) (credo (true)) (praef ("App. Ad"))) + (gloria (true)) (credo (true)) (praef ("App. Ad")) (alt_te_deum ())) ((date 2026-12-01) (class_ ("III cl.")) (title "Viol Feria III post Dom. I Adventus, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef (comm.))) + (gloria (false)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-12-02) (class_ ("III cl.")) (title "Rub Feria IV. S Bibianae Virg. et Mart.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. Ad"))) + (gloria (true)) (credo (false)) (praef ("comm. vel de Martyribus. Ad")) + (alt_te_deum ())) ((date 2026-12-03) (class_ ("III cl. (Priv.)")) (title "Alb Feria V. S Francisci Xavierii Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. Ad"))) + (gloria (true)) (credo (false)) (praef ("comm. Ad")) (alt_te_deum ())) ((date 2026-12-04) (class_ ("III cl.")) (title "Alb Feria VI. S Petri Chrysologi Ep., Conf. et Eccl. Doct.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef - ("comm. \226\128\147 Vel (sec. decretum \194\171Cum sanct.\194\187) Missa S Barbarae Virg. et Mart. (rub.) Loquebar de testimoniis tuis, Gloria, comm. 1\194\170 Feriae, comm. 2\194\170 S Petri Chrysologi Ep., Conf. et Eccl. Doct., praef. comm. vel de Martyribus. Feria VI prima in mense. Ad"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-12-05) (class_ ("III cl.")) (title "Viol Sabb. post Dom. I Adventus, De eo,") (te_deum ()) (gloria (false)) (credo (false)) - (praef ("comm. Sabbatum primum in mense. I"))) + (praef ("comm. Sabbatum primum in mense. I")) (alt_te_deum ())) ((date 2026-12-06) (class_ ("I cl.")) (title "Viol DOM. II ADVENTUS, De ea,") (te_deum (false)) - (gloria (false)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (false)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-12-07) (class_ ("III cl. (Priv.)")) (title "Alb Feria II. S Ambrosii Ep., Conf. et Eccl. Doct.,") (te_deum (true)) (gloria (true)) (credo (false)) - (praef ("comm. \226\128\147"))) + (praef ("comm. \226\128\147")) (alt_te_deum ())) ((date 2026-12-08) (class_ ("I cl.")) (title "Alb Feria III. IN CONCEPTIONE IMMACULATA B. MARIAE VIRGINIS,") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("BMV Et te in Conceptione Immaculata. Ad"))) + (praef ("BMV Et te in Conceptione Immaculata. Ad")) (alt_te_deum ())) ((date 2026-12-09) (class_ ("III cl.")) (title "Viol Feria IV post Dom. II Adventus, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef (comm.))) + (gloria (false)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-12-10) (class_ ("III cl.")) (title "Viol Feria V post Dom. II Adventus, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef (comm.))) + (gloria (false)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-12-11) (class_ ("III cl. (Priv.)")) (title "Alb Feria VI. S Damasi I Papae et Conf.,") (te_deum (true)) - (gloria (true)) (credo (false)) (praef ("comm. Ad"))) + (gloria (true)) (credo (false)) (praef ("comm. Ad")) (alt_te_deum ())) ((date 2026-12-12) (class_ ("III cl.")) (title "Viol Sabb. post Dom. II Adventus, De eo,") (te_deum ()) - (gloria (false)) (credo (false)) (praef ("comm. I"))) + (gloria (false)) (credo (false)) (praef ("comm. I")) (alt_te_deum ())) ((date 2026-12-13) (class_ ("I cl.")) (title "DOM. III ADVENTUS (GAUDETE), De ea,") (te_deum (false)) - (gloria (false)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (false)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-12-14) (class_ ("III cl.")) (title "Viol Feria II post Dom. III Adventus (Gaudete), De ea,") - (te_deum ()) (gloria (false)) (credo (false)) (praef (comm.))) + (te_deum ()) (gloria (false)) (credo (false)) (praef (comm.)) + (alt_te_deum ())) ((date 2026-12-15) (class_ ("III cl.")) (title "Viol Feria III post Dom. III Adventus (Gaudete), De ea,") - (te_deum ()) (gloria (false)) (credo (false)) (praef (comm.))) + (te_deum ()) (gloria (false)) (credo (false)) (praef (comm.)) + (alt_te_deum ())) ((date 2026-12-16) (class_ ("II cl.")) (title "Viol FERIA IV QUATTUOR TEMP., De ea,") (te_deum ()) (gloria (false)) (credo (false)) - (praef ("comm. \226\128\147 Quoad Flectamus genua vide RM 440."))) + (praef ("comm. \226\128\147 Quoad Flectamus genua vide RM 440.")) + (alt_te_deum ())) ((date 2026-12-17) (class_ ("II cl.")) (title "Viol FERIA V POST DOM. III ADVENTUS (GAUDETE), De ea,") - (te_deum ()) (gloria (false)) (credo (false)) (praef (comm.))) + (te_deum ()) (gloria (false)) (credo (false)) (praef (comm.)) + (alt_te_deum ())) ((date 2026-12-18) (class_ ("II cl.")) (title "Viol FERIA VI QUATTUOR TEMP., De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef (comm.))) + (gloria (false)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-12-19) (class_ ("II cl.")) (title "Viol SABB. QUATTUOR TEMP., De eo,") (te_deum ()) (gloria (false)) (credo (false)) (praef - ("comm. \226\128\147 Quoad Flectamus genua vide RM 440. Quoad lectiones vide RM 468. I"))) + ("comm. \226\128\147 Quoad Flectamus genua vide RM 440. Quoad lectiones vide RM 468. I")) + (alt_te_deum ())) ((date 2026-12-20) (class_ ("I cl.")) (title "Viol DOM. IV ADVENTUS, De ea,") (te_deum (false)) - (gloria (false)) (credo (true)) (praef ("Trinit. Ad II"))) + (gloria (false)) (credo (true)) (praef ("Trinit. Ad II")) + (alt_te_deum ())) ((date 2026-12-21) (class_ ("II cl.")) (title "Rub Feria II. S THOM\195\134 * APOSTOLI,") (te_deum ()) - (gloria (true)) (credo (true)) (praef ("App. Ad"))) + (gloria (true)) (credo (true)) (praef ("App. Ad")) (alt_te_deum ())) ((date 2026-12-22) (class_ ("II cl.")) (title "Viol FERIA III POST DOM. IV ADVENTUS, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef (comm.))) + (gloria (false)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-12-23) (class_ ("II cl.")) (title "Viol FERIA IV POST DOM. IV ADVENTUS, De ea,") (te_deum ()) - (gloria (false)) (credo (false)) (praef (comm.))) + (gloria (false)) (credo (false)) (praef (comm.)) (alt_te_deum ())) ((date 2026-12-24) (class_ ("I cl.")) (title "Viol Feria V. VIGILIA NATIVITATIS DOMINI,") (te_deum (false)) - (gloria (false)) (credo (false)) (praef ("comm. I"))) + (gloria (false)) (credo (false)) (praef ("comm. I")) (alt_te_deum ())) ((date 2026-12-25) (class_ ("I cl.")) (title "Alb Feria VI. IN NATIVITATE DOMINI,") (te_deum ()) (gloria (true)) (credo (true)) (praef - ("et Communic. pr. per totam oct. \226\128\147 In Communicantes: in 1\194\170 Missa dicitur Noctem sacratissimam celebrantes, qua, in 2\194\170 et 3\194\170 Missa et per octavam Diem sacratissimum celebrantes, quo. \226\128\147 In 2\194\170 Missa (etiam in cantu) fit comm. S. Anastasi\195\166 * M. \226\128\147 In Missis in cantu, ad verba symboli Et incarnatus est\226\128\166 et homo factus est, omnes genuflectunt versus altare, non tantum cum a celebrante recitantur, sed etiam cum a choro canuntur (RM 518 b). II"))) + ("et Communic. pr. per totam oct. \226\128\147 In Communicantes: in 1\194\170 Missa dicitur Noctem sacratissimam celebrantes, qua, in 2\194\170 et 3\194\170 Missa et per octavam Diem sacratissimum celebrantes, quo. \226\128\147 In 2\194\170 Missa (etiam in cantu) fit comm. S. Anastasi\195\166 * M. \226\128\147 In Missis in cantu, ad verba symboli Et incarnatus est\226\128\166 et homo factus est, omnes genuflectunt versus altare, non tantum cum a celebrante recitantur, sed etiam cum a choro canuntur (RM 518 b). II")) + (alt_te_deum ())) ((date 2026-12-26) (class_ ("II cl.")) (title "Rub Sabb. S STEPHANI * PROTOMARTYRIS,") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. Ad"))) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. Ad")) + (alt_te_deum ())) ((date 2026-12-27) (class_ ("II cl.")) (title "Alb DOM. INFRA OCTAVAM NATIVITATIS, De ea,") (te_deum (true)) (gloria (true)) (credo (true)) - (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. Ad II"))) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. Ad II")) + (alt_te_deum ())) ((date 2026-12-28) (class_ ("II cl.")) (title "Rub Feria II. SS INNOCENTIUM MM.,") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. Ad"))) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. Ad")) + (alt_te_deum ())) ((date 2026-12-29) (class_ ("II cl.")) (title "Alb FERIA III DOM. INFRA OCTAVAM NATIVITATIS, De ea,") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("de Nativ., Communic. de Nativ. diem sacratissimum."))) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum.")) + (alt_te_deum ())) ((date 2026-12-30) (class_ ("II cl.")) (title "Alb FERIA IV DOM. INFRA OCTAVAM NATIVITATIS, De ea,") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("de Nativ., Communic. de Nativ. diem sacratissimum."))) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum.")) + (alt_te_deum ())) ((date 2026-12-31) (class_ ()) (title "Alb FERIA V DOM. INFRA OCTAVAM NATIVITATIS, De ea. \226\128\147 Off. semifestivum. \226\128\147 Ad MAT. invit., hymnus, 9 antt. et 9 pss. cum ultimo V de festo Nativ., Ll. de Scr. occ. cum suis RR (ad 2um additur Gloria Patri)\226\128\147 Ad Laudes antt. de Nativ., pss. de dom., comm. S Silvestri I Papae et Conf. \226\128\147 Ad HORAS ant. et pss. de feria curr., rel ut in festo Nativ. \226\128\147 Ad Primam in R Br. V Qui natus es de Maria Virgine. Missa Puer natus de diebus infra octavam, Gloria, Credo, comm. S Silvestri I Papae et Conf., praef. de Nativ., Communic. de Nativ. diem sacratissimum. I VESPER\195\134 de seq. \226\128\147 Compl. de dom. Hodie ad solemnem recitationem hymni Te Deum, indulgentia plenaria lucrari potest. 126") (te_deum ()) (gloria (true)) (credo (true)) - (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. I")))) + (praef ("de Nativ., Communic. de Nativ. diem sacratissimum. I")) + (alt_te_deum ()))) diff --git a/test/test_fiuv_ordo.ml b/test/test_fiuv_ordo.ml index 24eeed0..5c009a9 100644 --- a/test/test_fiuv_ordo.ml +++ b/test/test_fiuv_ordo.ml @@ -68,7 +68,7 @@ let sha256_of_file path = | Some i -> String.sub line 0 i | None -> Alcotest.failf "unexpected sha256sum output for %s: %S" path line) -let fixture_sha256 = "a52cc4dae32ce4d07446c9daa86287cb99796f6584b3d571e3a3cbdc93fca396" +let fixture_sha256 = "a744a2dbc7c8cf09590005e956c973f316209f3cf102b8035edadebf764110de" let real_layer () = let layer = @@ -112,6 +112,12 @@ type ordo_row = { gloria : bool option; credo : bool option; praef : string option; + alt_te_deum : bool option; + (** the "-VEL-" Cum-Sanctissima-alternative office's own Te Deum, + when this day prints one -- see tools/extract_fiuv_ordo.ml's own + [row.alt_te_deum] citation. Captured, not compared here: closing + F3 needed [te_deum] itself to stop reading it, not a new + colitur-side axis to check it against. *) } [@@deriving sexp] @@ -361,57 +367,68 @@ let test_gloria_matches_or_is_explained () = let test_te_deum_coverage () = let ordo = ordo_rows () in let no_te_deum = List.filter (fun o -> o.te_deum = None) ordo in - Alcotest.(check int) "the unresolved-Te-Deum population matches this fixture's own measured figure" 127 + Alcotest.(check int) "the unresolved-Te-Deum population matches this fixture's own measured figure" 133 (List.length no_te_deum) let describe_te_deum_mismatch (o : ordo_row) (t : colitur_te_deum_row) = Printf.sprintf "%s %S: colitur te_deum=%b, Ordo te_deum=%b (rank=%s commemoration=%b)" o.date o.title t.t_te_deum (Option.get o.te_deum) (V.rank_to_string t.t_rank) t.t_has_commemoration -(* F2 (every I-class and omissible vigil) and F4 (the three September - Ember days) were BOTH found against the FIRST, buggy extraction (see - the fixture's own provenance header, "RE-EXTRACTED" note, and - {!Rite_ef.Rubrics_ef.te_deum}'s own 237(a) comment for the full - account of the extractor bug and its fix) -- re-run against the - corrected data, NEITHER fires any more: colitur's own answer already - matched the CORRECTED Ordo on every one of those 7 dates, all along. +(* F2 (every I-class and omissible vigil), F4 (the three September Ember + days) and NOW F3 (the privileged-Lenten/Passiontide-feria-plus- + commemoration shape) were ALL THREE found against a buggy extraction + (see the fixture's own provenance header, "FIX HISTORY" section, and + {!Rite_ef.Rubrics_ef.te_deum}'s own 237(a) comment for F2/F4's own + account) -- re-run against the corrected data, NONE of the three fires + any more. + + F3 specifically was NEVER a Te Deum defect on either side: the six + dates print a complete SECOND office after a literal "-VEL-" ("or") + separator -- the same saint kept outright under the 2020 decree Cum + Sanctissima, with its OWN "Ad Mat. ... Te Deum" lessons -- and + tools/extract_fiuv_ordo.ml's own [extract_te_deum] used to scan the + WHOLE block unbounded, so on these six days (whose PRIMARY, strict- + 1962 office states no "Ad Mat." of its own at all) it silently read + the SECOND office's Te Deum instead. Fixed at the source + (tools/extract_fiuv_ordo.ml's own [split_at_alt_office]); the fixture + re-extracted from the SAME pdftotext dump. colitur's own answer + ([false], the primary office's own ferial Matins) was never wrong -- + the OTHER side of the comparison was reading the wrong printed office. + [te_deum] now reads [None] (unresolved, not [false]) on these six + dates, because the PRIMARY office's own text states no "Ad Mat." at + all, so there is nothing to positively confirm either direction from + -- consistent with [te_deum]'s own documented meaning elsewhere in + this fixture. + + NOTE, so a reader arriving here from data/ef/expected-divergences-lms.sexp's + own L5 does not draw the wrong conclusion: F3 never "contradicted" L5 + in the first place, and its removal does not corroborate L5 either. + Both were the SAME underlying fact read two different ways -- L5's own + 16 LMS dates and these 6 FIUV dates are exactly the shape the 2020 + decree Cum Sanctissima changes, and colitur, by CLAUDE.md's own binding + decision 2, models the 1962 core without it. See L5's own rewritten + entry for the full account, including the FIUV "-VEL-" dual printing + as the decisive evidence for BOTH files. + Removed rather than kept as dead code with an [expected 0] pin, the same "an entry that stops firing is a real change, not silently absorbed" discipline data/ef/expected-divergences-lms.sexp's own L1/L3 closures already establish -- see that file's own history for the - precedent this follows. - - F3, the privileged-Lenten/Passiontide-feria-plus-commemoration shape - L5 (data/ef/expected-divergences-lms.sexp) already found for Gloria, - REMAINS: 6 instances, unaffected by the extractor fix (none of the six - raw source lines used "sine Te Deum" at all -- confirmed directly - against the pdftotext dump, see F3's own citation). CONTRADICTS L5, - not corroborates it: FIUV's own [gloria] is [false] on all six dates - (agreeing with colitur), while its [te_deum] is [true] on the same six - -- see F3's own citation in data/ef/expected-divergences-fiuv.sexp for - the full account of why Gloria and Te Deum diverge on the identical - day. *) -let is_f3_lenten_commemoration (_ : ordo_row) (t : colitur_te_deum_row) = - t.t_has_commemoration && t.t_rank = V.Class3 + precedent this follows. *) let test_te_deum_matches_or_is_explained () = let ordo = ordo_rows () in let colitur = colitur_te_deum_rows () in let unexplained = ref [] in - let f3_count = ref 0 in List.iter2 (fun (o : ordo_row) (t : colitur_te_deum_row) -> if not (String.equal o.date t.t_date) then Alcotest.failf "misaligned: ordo %s vs colitur %s" o.date t.t_date; match o.te_deum with | None -> () - | Some otd -> - if Bool.equal otd t.t_te_deum then () - else if is_f3_lenten_commemoration o t then incr f3_count - else unexplained := describe_te_deum_mismatch o t :: !unexplained) + | Some otd -> if Bool.equal otd t.t_te_deum then () else unexplained := describe_te_deum_mismatch o t :: !unexplained) ordo colitur; Alcotest.(check (list string)) "every Te Deum mismatch is named in the allow-list -- none unexplained" [] - (List.rev !unexplained); - Alcotest.(check int) "F3 (Lenten privileged feria + commemoration) count" 6 !f3_count + (List.rev !unexplained) let suite = ( "fiuv-ordo", diff --git a/test/test_lms_ordo.ml b/test/test_lms_ordo.ml index 42dc31d..00fb32c 100644 --- a/test/test_lms_ordo.ml +++ b/test/test_lms_ordo.ml @@ -594,12 +594,22 @@ let make_suite ~label ~fixture_path ~fixture_sha256 ~window_first ~window_last ~ [make_suite] threads the per-window expected totals directly (~expected_gloria_l5/~expected_gloria_l6 below) instead. *) let is_l5_lenten_commemoration (o : ordo_row) (c : colitur_row) = - (* RG 431(b)/n.302(b): "Missa de commemoratione in Officio diei - occurrente" says the Gloria. Every instance found is a privileged - Lenten/Passiontide feria (Class3, violet -- {!TE}'s own - [ferial_rank], RG25) carrying exactly one commemoration of an - impeded Class3 saint, colitur reading [gloria]=false (the ferial - Mass on its own) where the Ordo reads [true]. *) + (* NOT a Gloria defect (CORRECTED, l5-f3-readjudication task, + 2026-08-22 -- data/ef/expected-divergences-lms.sexp's own L5 has + the full account, including the RG 431(b)/n.302(b) hypothesis this + comment used to state as settled and RG 303(b)'s own "dici potest + tantum si occurrit dies liturgicus IV classis", which prohibits + 302(b) on exactly these THIRD-class privileged ferias). Every + instance is a privileged Lenten/Passiontide feria (Class3, violet + -- {!TE}'s own [ferial_rank], RG25) carrying exactly one + commemoration of an impeded Class3 saint, colitur reading + [gloria]=false (the ferial Mass, correctly, per the 1962 core) + where the Ordo reads [true] (the LMS Ordo follows the 2020 decree + Cum Sanctissima, colitur excludes it by binding design, CLAUDE.md + decision 2) -- an OCCURRENCE difference between two different, + both genuine, calendars, not a rule dispute. Predicate kept AS A + MATCHER (the 16-date population is unchanged); only the citation + explaining WHY it is allow-listed was wrong. *) (not c.c_gloria) && Option.value o.gloria ~default:false && c.c_has_commemoration && c.c_rank = V.Class3 in let is_l6_rogation_colour (o : ordo_row) (c : colitur_row) = diff --git a/tools/extract_fiuv_ordo.ml b/tools/extract_fiuv_ordo.ml index c9688a7..26f5b16 100644 --- a/tools/extract_fiuv_ordo.ml +++ b/tools/extract_fiuv_ordo.ml @@ -68,6 +68,40 @@ extract_lms_ordo.ml's own header describes for "V Mass of BVM" being a substring of "IV Mass of BVM". + 5. A WHOLE-SECOND-OFFICE TRAP, found and defended against + (celebrant-rubrics-phase1 Phase 2 correction, 2026-08-22, closing + data/ef/expected-divergences-fiuv.sexp's own F3): six real days + print BOTH a strict-1962 reading (a privileged Lenten/Passiontide + feria, saint reduced to a commemoration, "Off. feriale") AND, after + a literal separator token, a SECOND, complete alternative office + (the same saint kept outright under the 2020 decree Cum + Sanctissima, "Off. ordinarium", with its OWN "Ad Mat. ... Te Deum" + lessons). The separator is an en-dash, "VEL" (Latin "or"), another + en-dash, glued by pdftotext into ONE token with no internal spaces + -- "\xe2\x80\x93VEL\xe2\x80\x93" ("VEL" wrapped in en-dashes) -- + confirmed by direct byte inspection of the raw dump, NOT the same + shape as [extract_missa_fields]'s own "Vel"+"Missa" two-token + boundary above (a narrower "choice of Mass formulary within the + SAME office" marker, e.g. a Common vs a Proper Mass for one saint). + [extract_missa_fields]'s own Gloria/Credo/praef span happened to + stay correctly bounded to the PRIMARY office on all six real + instances even before this fix, because a Vespers line ("VESPER..." + -- already one of its own boundary tokens) always intervenes before + the separator in this corpus; [extract_te_deum] had NO such + protection at all -- it scans the WHOLE block's own text for "Ad + Mat." unbounded, so on these six days (whose PRIMARY office states + no "Ad Mat." of its own at all -- an ordinary privileged feria's + Matins needs no special note) it read the SECOND office's own "Ad + Mat. ... Te Deum." instead, manufacturing a same-day contradiction + that F3 first recorded as "colitur's own possible gap". [split_at_alt_office] + below cuts every block's own token array at this separator BEFORE + any field extraction runs, so every extractor now reads the PRIMARY + office only; the alternative is captured, not discarded, in its own + [alt_te_deum] field (the row type's own comment has the full + account of why only this one field, not a parallel alt_gloria/ + alt_credo/alt_class -- those three were never wrong, so widening + them now would be undirected scope creep, not a fix). + Usage: pdftotext -layout docs/research/ordo/fiuv-ordo-2025-2026.pdf /tmp/fiuv.txt dune exec tools/extract_fiuv_ordo.exe -- /tmp/fiuv.txt \ @@ -84,15 +118,46 @@ let die fmt = Printf.ksprintf (fun s -> prerr_endline ("extract_fiuv_ordo: " ^ s reasoning extract_lms_ordo.ml's own header already gives. *) type row = { date : string; (** ISO-8601 *) - class_ : string option; (** raw, e.g. "III cl.", "III cl. (Priv.)", "I cl." -- [None] only if genuinely unparseable *) - title : string; (** the day-start line's own text before the class marker *) - te_deum : bool option; (** [None] only if neither "Te Deum" nor "non dicitur Te Deum" is found *) - gloria : bool option; - credo : bool option; + class_ : string option; (** raw, e.g. "III cl.", "III cl. (Priv.)", "I cl." -- [None] only if genuinely unparseable, read off the PRIMARY office alone *) + title : string; (** the day-start line's own text before the class marker, PRIMARY office alone *) + te_deum : bool option; (** [None] only if neither "Te Deum" nor "non dicitur Te Deum"/"sine Te Deum" is found WITHIN THE PRIMARY OFFICE (see [split_at_alt_office]) *) + gloria : bool option; (** PRIMARY office *) + credo : bool option; (** PRIMARY office *) praef : string option; (** raw trailing text after "praef." within the primary Mass clause -- CAPTURED, NOT VALIDATED *) + alt_te_deum : bool option; + (** the SECOND, Cum-Sanctissima-alternative office's own Te Deum + status, when this day prints one (see [split_at_alt_office]'s + own citation) -- [None] both when the day has no such + alternative at all (394 of 400 real days) AND when it has one + but that alternative's own text doesn't state Te Deum either + (never observed live: on all six real instances the alternative + states it unnegated). Captured rather than discarded because a + FUTURE Cum-Sanctissima overlay (CLAUDE.md's own binding + decision 2 -- an addition, never core) would have exactly this + shape to compare against; not compared by anything in this + project yet. Deliberately NOT joined by an [alt_gloria]/ + [alt_credo]/[alt_class] -- see [split_at_alt_office]'s own + citation for why only this one field was ever wrong. *) } [@@deriving sexp] +(* The literal separator between a day's PRIMARY (strict 1962) office and + a printed SECOND, Cum-Sanctissima-2020 alternative -- see the module + header's own point 5 for the full account of the bug this closes + (data/ef/expected-divergences-fiuv.sexp's own F3) and why it is a + DIFFERENT token from [extract_missa_fields]'s own "Vel"+"Missa" + two-token boundary. Exactly 6 occurrences in the whole corpus, + confirmed by direct grep of the raw pdftotext dump -- all 6 on the + exact dates F3 named (2026-03-06/07/09/12/21/24). *) +let alt_office_marker = "\xe2\x80\x93VEL\xe2\x80\x93" + +let split_at_alt_office tokens = + let n = Array.length tokens in + let rec go i = if i >= n then None else if tokens.(i) = alt_office_marker then Some i else go (i + 1) in + match go 0 with + | None -> (tokens, None) + | Some i -> (Array.sub tokens 0 i, Some (Array.sub tokens (i + 1) (n - i - 1))) + (* --- tiny hand-rolled helpers, no Str/regex ------------------------------ *) let split_ws s = @@ -366,6 +431,29 @@ let extract_missa_fields tokens = let rec go i = if i >= n then n else if tokens.(i) = "Vel" && i + 1 < n && tokens.(i + 1) = "Missa" then i + (* A THIRD, narrower alternate-Mass marker, found while auditing + for the "-VEL-" trap above (celebrant-rubrics-phase1 Phase 2 + correction, 2026-08-22): "Vel (sec. decretum <>) + Missa ..." offers an alternate MASS FORMULARY under the 2020 + decree Cum Sanctissima WITHIN the same single printed office + (a narrower thing than [split_at_alt_office]'s own full + second-office split above -- there is no second "Ad Mat." set + of lessons here, just a second Mass choice). Checked against + the raw dump directly: 20 occurrences, ALL 20 of the + capitalised "Vel" + open-paren shape, zero false positives + (the ordinary lower-case "vel" conjunction, e.g. "praef. + comm. vel de Martyribus", never starts with an open-paren + token, so this check never fires on it). Every one of the 20 + real days already restates Gloria/Credo explicitly BEFORE + reaching this marker, so this was NEVER a live divergence + (confirmed by a direct diff of every field this fixture + compares, before and after this hardening: zero rows + changed) -- added defensively, so a FUTURE year whose + primary Mass clause happens not to restate Gloria/Credo + before this marker cannot silently read the Cum-Sanctissima + alternative's own value instead, the identical failure shape + as the "-VEL-" bug above, just not yet observed live here. *) + else if tokens.(i) = "Vel" && i + 1 < n && has_prefix ~prefix:"(" tokens.(i + 1) then i else if has_prefix ~prefix:"VESPER" tokens.(i) then i else go (i + 1) in @@ -475,12 +563,20 @@ let () = dropped before field extraction, kept for nothing (the day number is already known from [b_day]). *) let content = if Array.length tokens > 0 then Array.sub tokens 1 (Array.length tokens - 1) else tokens in - let class_ = extract_class content in - let title = extract_title content in - let full_text = String.concat " " (Array.to_list content) in + (* Cut at the "–VEL–" alternative-office boundary, if this day has + one, BEFORE any field extraction -- see [split_at_alt_office]'s + own citation. Every field below now reads the PRIMARY office + only; [alt_te_deum] alone also reads the second, when present. *) + let primary, alt = split_at_alt_office content in + let class_ = extract_class primary in + let title = extract_title primary in + let full_text = String.concat " " (Array.to_list primary) in let te_deum = extract_te_deum full_text in - let gloria, credo, praef = extract_missa_fields content in - { date = Date.to_iso8601 date; class_; title; te_deum; gloria; credo; praef }) + let alt_te_deum = + match alt with None -> None | Some alt_tokens -> extract_te_deum (String.concat " " (Array.to_list alt_tokens)) + in + let gloria, credo, praef = extract_missa_fields primary in + { date = Date.to_iso8601 date; class_; title; te_deum; gloria; credo; praef; alt_te_deum }) blocks in let missing_class = List.filter (fun r -> r.class_ = None) rows in @@ -517,6 +613,22 @@ let () = | None -> die "characterisation probe FAILED: %s (%s) -- no row extracted for this date at all" d desc) probes; Printf.printf "extract_fiuv_ordo: all %d characterisation probes confirmed\n" (List.length probes); + (* Second characterisation probe, same discipline: the "–VEL–" + alternative-office split (module header point 5) must fire on + EXACTLY these six dates, no more, no fewer -- a hard [die], not a + printed claim, so a future re-extraction against a re-flowed dump + silently gaining or losing an instance fails loudly rather than + quietly changing F3's own population. *) + let alt_office_dates = List.filter_map (fun r -> if r.alt_te_deum <> None then Some r.date else None) rows in + let expected_alt_office_dates = + [ "2026-03-06"; "2026-03-07"; "2026-03-09"; "2026-03-12"; "2026-03-21"; "2026-03-24" ] + in + if List.sort String.compare alt_office_dates <> expected_alt_office_dates then + die "alt-office-split characterisation probe FAILED: expected exactly %s, got %s" + (String.concat ", " expected_alt_office_dates) + (String.concat ", " (List.sort String.compare alt_office_dates)); + Printf.printf "extract_fiuv_ordo: alt-office-split characterisation probe confirmed (%d dates)\n" + (List.length expected_alt_office_dates); let probe_lines = String.concat "\n" (List.map @@ -542,6 +654,9 @@ let () = let credo_false = List.length (List.filter (fun r -> r.credo = Some false) rows) in let te_deum_true = List.length (List.filter (fun r -> r.te_deum = Some true) rows) in let te_deum_false = List.length (List.filter (fun r -> r.te_deum = Some false) rows) in + let alt_te_deum_true = List.length (List.filter (fun r -> r.alt_te_deum = Some true) rows) in + let alt_te_deum_false = List.length (List.filter (fun r -> r.alt_te_deum = Some false) rows) in + let alt_te_deum_none = List.length (List.filter (fun r -> r.alt_te_deum = None) rows) in let header = Printf.sprintf {|; %s -- Witnesses task (2026-08-22-colitur- @@ -637,15 +752,97 @@ let () = ; below are what this fixture actually asserts, not a forced match to ; the brief's approximate figures. ; +; 5. THE ALTERNATIVE-OFFICE TRAP (celebrant-rubrics-phase1 Phase 2 +; correction, 2026-08-22, closing F3): six real days print BOTH a +; strict-1962 reading and a complete SECOND office (the same saint +; kept outright under the 2020 decree Cum Sanctissima), separated by +; a literal "-VEL-" token. [extract_te_deum] used to scan the WHOLE +; block unbounded, so on these six days -- whose PRIMARY office states +; no "Ad Mat." of its own -- it silently read the SECOND office's own +; Te Deum instead, manufacturing a same-day contradiction with colitur +; that F3 first recorded as "colitur's own possible gap". Every field +; now reads the PRIMARY office only (module header point 5 has the +; full account); the alternative is captured, not discarded, in its +; own [alt_te_deum] field. Confirmed to fire on EXACTLY six dates by a +; hard characterisation probe (this run's own output, above), not +; merely asserted here. +; ; MEASURED DISTRIBUTION (this extraction, not the brief's figures): Gloria ; true=%d false=%d unresolved=%d; Credo true=%d false=%d unresolved=%d; -; Te Deum true=%d false=%d unresolved=%d. +; Te Deum true=%d false=%d unresolved=%d; alt Te Deum (the six "-VEL-" +; Cum Sanctissima alternatives, point 5 above) true=%d false=%d none=%d +; (a day contributes to "none" here either because it has no "-VEL-" +; alternative at all -- 394 of 400 -- or, for a day that does, because +; that alternative's own text doesn't state Te Deum either; not +; distinguished by this one count). +; +; FIX HISTORY (fixed text, HISTORICAL counts from the run that found each +; bug, not re-verified live by every later run -- this section exists so +; regenerating this fixture from a fresh pdftotext dump, which rewrites +; this whole header from the template, does not silently erase either +; finding; earlier this header carried the first entry below as a +; hand-appended note that a regeneration between then and now had +; already dropped once): +; +; 1. RE-EXTRACTED (celebrant-rubrics-phase1 Phase 2, 2026-08-22): the FIRST +; extraction's own Te Deum parser recognised only ONE of the source's two +; negative phrasings ("non dicitur Te Deum") -- "sine Te Deum" (how the +; source actually negates a SUNDAY's own Te Deum, among others) fell +; through to a bare "Te Deum" substring match and was wrongly read +; [true]. Found by hand, comparing the raw pdftotext dump against this +; fixture's own values directly, not by any coverage check (both counted +; the same 127 unresolved rows before and after). Fixed in +; tools/extract_fiuv_ordo.ml's own [extract_te_deum] (see its own +; citation); this fixture re-extracted from the SAME pdftotext dump +; (SHA-256 of the source PDF unchanged, above). 24 of 400 rows changed, +; every one Te Deum true->false, every one independently confirmed +; against the raw text: true 231->207, false 42->66, unresolved 127 +; unchanged. See lib/rites/rite_ef/rubrics_ef.ml's own [te_deum] header +; (237(a)'s comment) for the full account of what this corrected, and +; the .superpowers task report for the complete before/after date list. +; +; 2. RE-EXTRACTED (celebrant-rubrics-phase1 Phase 2 correction, 2026-08-22): +; module header point 5 and CHARACTERISATION point 5 above have the +; full account of the "-VEL-" alternative-office bug this closes +; (data/ef/expected-divergences-fiuv.sexp's own F3). This fixture +; re-extracted from the SAME pdftotext dump (SHA-256 of the source PDF +; unchanged, above). 6 of 400 rows changed, every one Te Deum +; true->unresolved (2026-03-06/07/09/12/21/24), every one independently +; confirmed against the raw text: Te Deum true 207->201 (this run's own +; unresolved count went 127->133, consistent with those same 6 rows). +; Gloria/Credo/class_/title/praef are UNCHANGED on all 400 rows -- +; those fields were already correctly bounded to the primary office +; before this fix (a Vespers-line token always intervened before the +; "-VEL-" separator on all six real instances), confirmed by a direct +; diff of the fixture before and after, not merely by argument. +; +; 3. RE-EXTRACTED (celebrant-rubrics-phase1 same correction, defensive +; hardening, 2026-08-22): auditing for the SAME trap elsewhere (the +; task brief's own item 5) found a THIRD, narrower alternate-Mass +; marker, "Vel (sec. decretum <>) Missa ...", offering a +; Cum-Sanctissima Mass FORMULARY choice within a single office +; (unlike point 5 above, no second "Ad Mat." set of lessons -- a +; narrower thing than a full alternate office). 20 occurrences in the +; whole corpus, confirmed by direct grep; on all 20, Gloria/Credo were +; ALREADY stated before reaching this marker, so this was NEVER a +; live divergence for those two fields (confirmed by this same diff: +; 0 Gloria/Credo/class_/title/alt_te_deum rows changed). [praef] +; alone changed on 20 of 400 rows (its own "rest of the primary +; clause" capture no longer runs past this marker into the +; alternative's own text) -- harmless in itself ([praef] is +; documented CAPTURED, NOT VALIDATED, compared by nothing), but added +; as a defensive boundary in [extract_missa_fields] so a FUTURE year +; whose primary clause does not restate Gloria/Credo before this +; marker cannot silently read the alternative's own value instead -- +; the identical failure shape as point 2 above, closed before it was +; ever observed live rather than after. |} dest pdf_base pdf_base pdf_sha (today ()) pdf_base pdf_base dest (List.length rows) (match rows with r :: _ -> r.date | [] -> "?") (match List.rev rows with r :: _ -> r.date | [] -> "?") probe_lines (List.length probes) gloria_true gloria_false (List.length missing_gloria) credo_true credo_false - (List.length missing_credo) te_deum_true te_deum_false (List.length missing_te_deum) + (List.length missing_credo) te_deum_true te_deum_false (List.length missing_te_deum) alt_te_deum_true + alt_te_deum_false alt_te_deum_none in let body = Sexplib.Sexp.to_string_hum ~indent:2 (sexp_of_list sexp_of_row rows) in let oc = open_out dest in -- cgit v1.3 From cd3e03bf3e5b040786838fc3c5639d7c29e9b3b8 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Sat, 22 Aug 2026 20:15:56 +0200 Subject: fix(ef): Rogation Monday/Tuesday are white, not violet (RG 119) Temporal_ef.temporal's Rogation Monday/Tuesday branch hardcoded Colour.Violet with no citation (data/ef/expected-divergences-lms.sexp's L6, surfaced by the LMS Ordo). RG 119 assigns white to the de-Tempore Office and Mass from the Paschal Vigil Mass to the Pentecost Vigil Mass exclusive; Easter+36/+37 sit inside that window. RG 128's own exhaustive four-case violet list never names Rogation days, and its vigil clause (d) is doubly inapplicable: these are not vigils, and they are inside Paschaltide, not outside it. RG 88 explains the violet actually seen in print sources: "de Litaniis minoribus nihil fit in Officio, sed tantum in Missa" -- the violet belongs to the Rogation Mass/procession, a distinct votive text this engine does not model, not to the day's own Office. Witnessed directly: LMS Ordo 2023-2024, 2024-05-06, "FERIA IV Cl W" with "Gl", the Office and Mass printed separately from the optional violet votive Mass of the Rogations. Cascade verified, not assumed: RG 432(b) omits the Gloria on every violet Mass, so the wrong colour was also silencing the Gloria on these two weekdays even though RG 237(e) (Breviary, ordinary Paschaltide ferias say Te Deum) already made it true underneath. White removes the 432(b) block, and the Gloria now follows Te Deum via 431(a), matching the Ordo's own "Gl" -- confirmed with dedicated golden pins in both test_golden.ml (colour) and test_rubrics_ef.ml (the Gloria flip), 2028-05-22/23 (neither day impeded that year). Closed L6 in data/ef/expected-divergences-lms.sexp. Reopened C8 in data/ef/expected-divergences.sexp (26 of 16801 rows, 2005-2050): lectio independently computes these two days violet too, so the two engines used to agree by sharing the same uncited assumption; colitur's colour is now correct and lectio's is not, so the comparator disagrees again, for the opposite reason. While reopening C8, found and corrected a genuine misattribution in its own prior closure note, which claimed lectio's violet was "RG 128(d)" -- 128(d) governs vigils outside Paschaltide and has nothing to do with Rogation days. Checked docs/research/rules-register.md for the same claim: not present there, but a related conflation was found and corrected at its O'Connell section 4(d) note, which had used a Rogation MASS/procession citation to "confirm" the day's own OFFICE colour. Blast radius measured in-process across the full 1583-9999 domain (throwaway probe, not committed): 4722 days total (2368 Rogation Mondays + 2354 Rogation Tuesdays actually observed outright, i.e. not impeded by a stronger sanctoral feast that year), all Violet->White, all with the Gloria flipping false->true alongside, zero anomalies. Mutation-tested: reverting the branch to Colour.Violet reddens 16 tests across Rubrics_ef, the lectio differential, the LMS Ordo suite and both golden pin files; restored and reconfirmed green (680 tests). --- data/ef/expected-divergences.sexp | 20 +++++++++------ lib/rites/rite_ef/temporal_ef.ml | 28 +++++++++++++++++++-- test/golden/grid-2027.html | 2 +- test/golden/grid-2027.tex | 2 +- test/golden/grid-2027.typ | 2 +- test/golden/ordo-2027.adoc | 2 +- test/golden/ordo-2027.html | 4 +-- test/golden/ordo-2027.md | 2 +- test/golden/ordo-2027.ms | 2 +- test/golden/ordo-2027.tex | 4 +-- test/golden/ordo-2027.txt | 2 +- test/golden/ordo-2027.typ | 4 +-- test/test_golden.ml | 32 ++++++++++++++++++++++++ test/test_lms_ordo.ml | 52 +++++++++++++++++++++++---------------- test/test_rubrics_ef.ml | 20 +++++++++++++++ 15 files changed, 135 insertions(+), 43 deletions(-) (limited to 'data/ef') diff --git a/data/ef/expected-divergences.sexp b/data/ef/expected-divergences.sexp index 632854c..f98409b 100644 --- a/data/ef/expected-divergences.sexp +++ b/data/ef/expected-divergences.sexp @@ -131,13 +131,19 @@ Diff shapes: most rows carry [Slug_f; Rank; Colour_f; First_f; Gospel_f] (the te BLAST RADIUS, MEASURED, full 1583-9999 domain (not merely this fixture's 2005-2050 window): 6 983 liturgical days change, zero unclassified, across all 2 041 leap years in the domain -- see data/ef/expected-divergences-lms.sexp's own now-closed L3 entry for the full figures (this entry's own 21-row 2005-2050 population is the expected subset of that domain-wide count landing inside the fixture's own window: 11 leap years x up to 2 new rows each, minus the three already-explained overlaps above).") (expected_rows 21)) - ; C8 -- CLOSED, REMOVED (2026-08-18): 0 of 16801 rows, was 26. lectio builds - ; Rogation Monday and Tuesday now (RG 87, Easter+36/+37, violet under - ; RG 128(d)). The Wednesday is NOT built there and deliberately so: Easter+38 - ; is the Ascension's Vigil, which wins the day, and the rubric asks for a - ; commemoration -- a channel lectio's one-office-per-day temporal function - ; does not have. That is the same reason this entry never covered the - ; Wednesday either. Citation preserved in the register. + ((id C8) + (citation "RG 119 (Caput XVIII, \"De Colore Paramentorum\"): white is used \"in Officio et Missa de Tempore ... a Missa Vigiliae paschalis usque ad Missam vigiliae Pentecostes exclusive\" -- the de-Tempore Office and Mass are white from the Paschal Vigil Mass until the Pentecost Vigil Mass exclusive, and Rogation Monday/Tuesday (Easter+36/+37) sit inside that window. RG 128's own exhaustive four-case list for violet (Advent I-Christmas Eve; Septuagesima-Paschal Vigil; the September Ember ferias; vigils of II/III class OUTSIDE Paschaltide) never names Rogation days. RG 88 (\"de Litaniis minoribus nihil fit in Officio, sed tantum in Missa\"): the violet belongs to the Rogation MASS/procession, a distinct votive text this engine does not model, not to the day's own Office. Fixed in Rite_ef.Temporal_ef.temporal's Rogation branch, celebrant-rubrics-phase1 Bug 1, 2026-08-22 -- see that branch's own citation and data/ef/expected-divergences-lms.sexp's now-closed L6 entry, which is what surfaced it (LMS Ordo 2023-2024, 2024-05-06, \"FERIA IV Cl W\").") + (verdict colitur) + (note "REOPENED (2026-08-22, celebrant-rubrics-phase1, Bug 1 fix). Previously CLOSED, REMOVED (2026-08-18): 0 of 16801 rows, was 26, with this note, PRESERVED VERBATIM because it contains a misattribution now corrected rather than silently dropped: \"lectio builds Rogation Monday and Tuesday now (RG 87, Easter+36/+37, violet under RG 128(d)). The Wednesday is NOT built there and deliberately so: Easter+38 is the Ascension's Vigil, which wins the day, and the rubric asks for a commemoration -- a channel lectio's one-office-per-day temporal function does not have. That is the same reason this entry never covered the Wednesday either. Citation preserved in the register.\" + +THE MISATTRIBUTION: \"violet under RG 128(d)\" is wrong. RG 128(d) governs vigils of II/III class OUTSIDE Paschaltide; Rogation Monday/Tuesday are neither vigils nor outside Paschaltide. Checked against docs/research/rules-register.md (gitignored, local) while researching Bug 1: no claim of an RG 128(d) basis for Rogation colour exists there -- the misattribution was confined to this file's own closure note. It traces to Rite_ef.Temporal_ef.temporal's own Rogation branch, which hardcoded [Colour.Violet] with NO citation at all before this fix; whoever wrote this entry's closure note in 2026-08-18 apparently backfilled a plausible-looking but wrong citation for behaviour that was never actually cited in the code it described. + +WHY THIS REOPENS RATHER THAN STAYS CLOSED: the entry closed in 2026-08-18 because lectio, independently, ALSO computes these two days violet -- not because either engine's violet was ever verified against the Missal. Both engines shared the same uncited assumption, so the comparator saw agreement and the entry went to zero. Bug 1 corrected COLITUR's side to white (RG 119); lectio's own violet is unchanged (a sibling project, out of this repo, not modified here). The comparator now disagrees again, on the same 26 rows, for the OPPOSITE reason: previously colitur was wrong and lectio was wrong the same way; now colitur is right and lectio still carries the old, uncited assumption forward -- consistent with CLAUDE.md's own \"colitur vs missalemeum\" base-rate note for a different lineage, applied here to lectio directly: a fresh divergence is not presumptively colitur's fault once colitur has just been corrected FROM the shared error. + +MEASURED (test_differential.ml's own [classify], 2005-2050 fixture, DEBUGC8 probe run and reverted): exactly 26 rows, all with diffs=[Colour_f] alone -- season and slug already agree (lectio's own [easter]/colitur's [paschaltide] season labels are Layer A vocabulary synonyms, not a diff), and on every row lectio=violet, colitur=white. Dates: 2005-05-03, 2006-05-22/23, 2007-05-14, 2011-05-30, 2012-05-14, 2013-05-06, 2016-05-03, 2017-05-22/23, 2018-05-08, 2022-05-23/24, 2024-05-06, 2027-05-03, 2028-05-22/23, 2029-05-08, 2032-05-03, 2033-05-23/24, 2040-05-08, 2044-05-23/24, 2047-05-21, 2049-05-24. Fewer than the 2-per-year x 23-year x ~2 ceiling because a competing sanctoral feast impedes the Rogation office outright in some years on one or both of the two days (unchanged by this fix, gated on colitur's own [rogation-monday]/[rogation-tuesday] slug in [layer_c_reason] the same as before). The Wednesday remains absent from this entry for the same reason the pre-2026-08-18 and post-2026-08-18 notes both already gave: Easter+38 is the Ascension Vigil (RG 91 entry 21), which outranks the Rogation Wednesday commemoration outright on colitur's side, and lectio has no Rogation-Wednesday concept at all to compare against regardless. + +Gated on [(String.equal c.slug \"ef-rogation-monday\" || String.equal c.slug \"ef-rogation-tuesday\") && subset diffs [ Season; Slug_f; Colour_f ]] in [layer_c_reason] -- unchanged code, present since before this entry's 2026-08-18 closure and never removed; only the sexp record was removed when the count hit zero, per this file's own \"closed = 0 rows, not code deleted\" convention.") + (expected_rows 26)) ; C14 -- CLOSED, REMOVED (2026-08-18): 0 of 16801 rows, was 3. lectio has ; adopted RG 96(a)/97/98. Its transferIfImpededEF resolved each impeded ; I-class feast independently, so in 2008, 2035 and 2046 St Joseph and the diff --git a/lib/rites/rite_ef/temporal_ef.ml b/lib/rites/rite_ef/temporal_ef.ml index 1c916f4..fe08b2e 100644 --- a/lib/rites/rite_ef/temporal_ef.ml +++ b/lib/rites/rite_ef/temporal_ef.ml @@ -823,12 +823,36 @@ let temporal d = "ef-rogation-monday"/"-tuesday" are colitur-only keys and a lectionary gap for Plan 4 (CORRECTED, final fix wave, item 7 -- the lectionary bootstrap is Plan 4, not Plan 3), like the Ember - and Nativity-vigil keys above. *) + and Nativity-vigil keys above. + + COLOUR (L6, data/ef/expected-divergences-lms.sexp, CLOSED by this + fix): this branch used to hardcode [Colour.Violet] with no + citation at all. RG 119 (Caput XVIII, "De Colore Paramentorum"): + white is used "in Officio et Missa de Tempore ... a Missa Vigiliae + paschalis usque ad Missam vigiliae Pentecostes exclusive" -- the + de-Tempore Office AND Mass are white from the Paschal Vigil Mass + until the Pentecost Vigil Mass exclusive, and days 36/37 (Rogation + Monday/Tuesday) sit squarely inside that window. RG 128's own + exhaustive four-case list for violet (Advent I-Christmas Eve; + Septuagesima-Paschal Vigil; the September Ember ferias; vigils of + II/III class OUTSIDE Paschaltide) names Rogation days nowhere, and + its vigil clause is inapplicable twice over -- these are not + vigils, and they ARE inside Paschaltide. RG 88 ("de Litaniis + minoribus nihil fit in Officio, sed tantum in Missa") is why: the + violet belongs to the ROGATION MASS/procession alone, a distinct + votive text this engine does not model as a separate Mass (the + same per-action colour nuance temporal_ef.ml's own RG 126/RG 128 + Good-Friday-Communion citations already flag as unmodelled + elsewhere) -- the day's own OFFICE, which is what [colour] here + expresses, stays [season_colour s] like any other Paschaltide + feria. Witnessed directly: LMS 2023-2024, 2024-05-06 (Rogation + Monday), "FERIA IV Cl W" (white), "Mass of 5th Sunday after + Easter". *) let rogation = days_between easter d in if rogation = 36 || rogation = 37 then build ~season:s ~slug:(if rogation = 36 then "ef-rogation-monday" else "ef-rogation-tuesday") - ~colour:Colour.Violet ~rank:(ferial_rank d s) ~week:(week d) () + ~colour:(season_colour s) ~rank:(ferial_rank d s) ~week:(week d) () else match ember d with | Some (slug, rank, colour) -> build ~season:s ~slug ~colour ~rank ~week:(week d) () diff --git a/test/golden/grid-2027.html b/test/golden/grid-2027.html index daa6ba5..6741ad7 100644 --- a/test/golden/grid-2027.html +++ b/test/golden/grid-2027.html @@ -131,7 +131,7 @@ 1St. Joseph the WorkmanCol 3:14-15, 17, 23-24 · Matt 13:54-58 - 25th Sunday after EasterJas 1:22-27 · John 16:23-303Rogation MondayJas 1:22-27 · John 16:23-304St. Monica1 Tim 5:3-10 · Luke 7:11-165Vigil of the AscensionEph 4:7-13 · John 17:1-116The Ascension of Our LordActs 1:1-11 · Mark 16:14-207St. StanislausWis 5:1-5 · John 15:1-78Our Lady's Saturday OfficeEcclus 24:14-16 · John 19:25-27 + 25th Sunday after EasterJas 1:22-27 · John 16:23-303Rogation MondayJas 1:22-27 · John 16:23-304St. Monica1 Tim 5:3-10 · Luke 7:11-165Vigil of the AscensionEph 4:7-13 · John 17:1-116The Ascension of Our LordActs 1:1-11 · Mark 16:14-207St. StanislausWis 5:1-5 · John 15:1-78Our Lady's Saturday OfficeEcclus 24:14-16 · John 19:25-27 9Sunday after the Ascension1 Pet 4:7-11 · John 15:26-27; 16:1-410St. AntoninusEcclus 44:16-27; 45:3-20 · Matt 25:14-2311Sts. Philip & JamesWis 5:1-5 · John 14:1-1312Sts. Nereus, Achilleus, Domitilla, & PancrasWis 5:1-5 · John 4:46-5313St. Robert BellarmineWis 7:7-14 · Matt 5:13-1914Friday of the 7th Week of Eastertide1 Pet 4:7-11 · John 15:26-27; 16:1-415Vigil of PentecostActs 19:1-8 · John 14:15-21 diff --git a/test/golden/grid-2027.tex b/test/golden/grid-2027.tex index 674b9c4..d81bdb4 100644 --- a/test/golden/grid-2027.tex +++ b/test/golden/grid-2027.tex @@ -151,7 +151,7 @@ \begin{tabular}{|*{7}{p{\cellw}|}}\hline \textbf{ Sunday } & \textbf{ Monday } & \textbf{ Tuesday } & \textbf{ Wednesday } & \textbf{ Thursday } & \textbf{ Friday } & \textbf{ Saturday } \\ \hline & & & & & & \cellcolor{cwhite}\daycell{ 1 }{ St. Joseph the Workman }{ 1st Class }{ Col 3:14-15, 17, 23-24\ \textperiodcentered\ Matt 13:54-58 } \\ \hline -\cellcolor{cwhite}\daycell{ 2 }{ 5th Sunday after Easter }{ 2nd Class }{ Jas 1:22-27\ \textperiodcentered\ John 16:23-30 } & \cellcolor{cviolet}\daycell{ 3 }{ Rogation Monday }{ 4th Class }{ Jas 1:22-27\ \textperiodcentered\ John 16:23-30 } & \cellcolor{cwhite}\daycell{ 4 }{ St. Monica }{ 3rd Class }{ 1 Tim 5:3-10\ \textperiodcentered\ Luke 7:11-16 } & \cellcolor{cwhite}\daycell{ 5 }{ Vigil of the Ascension }{ 2nd Class }{ Eph 4:7-13\ \textperiodcentered\ John 17:1-11 } & \cellcolor{cwhite}\daycell{ 6 }{ The Ascension of Our Lord }{ 1st Class }{ Acts 1:1-11\ \textperiodcentered\ Mark 16:14-20 } & \cellcolor{cred}\daycell{ 7 }{ St. Stanislaus }{ 3rd Class }{ Wis 5:1-5\ \textperiodcentered\ John 15:1-7 } & \cellcolor{cwhite}\daycell{ 8 }{ Our Lady's Saturday Office }{ 4th Class }{ Ecclus 24:14-16\ \textperiodcentered\ John 19:25-27 } \\ \hline +\cellcolor{cwhite}\daycell{ 2 }{ 5th Sunday after Easter }{ 2nd Class }{ Jas 1:22-27\ \textperiodcentered\ John 16:23-30 } & \cellcolor{cwhite}\daycell{ 3 }{ Rogation Monday }{ 4th Class }{ Jas 1:22-27\ \textperiodcentered\ John 16:23-30 } & \cellcolor{cwhite}\daycell{ 4 }{ St. Monica }{ 3rd Class }{ 1 Tim 5:3-10\ \textperiodcentered\ Luke 7:11-16 } & \cellcolor{cwhite}\daycell{ 5 }{ Vigil of the Ascension }{ 2nd Class }{ Eph 4:7-13\ \textperiodcentered\ John 17:1-11 } & \cellcolor{cwhite}\daycell{ 6 }{ The Ascension of Our Lord }{ 1st Class }{ Acts 1:1-11\ \textperiodcentered\ Mark 16:14-20 } & \cellcolor{cred}\daycell{ 7 }{ St. Stanislaus }{ 3rd Class }{ Wis 5:1-5\ \textperiodcentered\ John 15:1-7 } & \cellcolor{cwhite}\daycell{ 8 }{ Our Lady's Saturday Office }{ 4th Class }{ Ecclus 24:14-16\ \textperiodcentered\ John 19:25-27 } \\ \hline \cellcolor{cwhite}\daycell{ 9 }{ Sunday after the Ascension }{ 2nd Class }{ 1 Pet 4:7-11\ \textperiodcentered\ John 15:26-27; 16:1-4 } & \cellcolor{cwhite}\daycell{ 10 }{ St. Antoninus }{ 3rd Class }{ Ecclus 44:16-27; 45:3-20\ \textperiodcentered\ Matt 25:14-23 } & \cellcolor{cred}\daycell{ 11 }{ Sts. Philip \& James }{ 2nd Class }{ Wis 5:1-5\ \textperiodcentered\ John 14:1-13 } & \cellcolor{cred}\daycell{ 12 }{ Sts. Nereus, Achilleus, Domitilla, \& Pancras }{ 3rd Class }{ Wis 5:1-5\ \textperiodcentered\ John 4:46-53 } & \cellcolor{cwhite}\daycell{ 13 }{ St. Robert Bellarmine }{ 3rd Class }{ Wis 7:7-14\ \textperiodcentered\ Matt 5:13-19 } & \cellcolor{cwhite}\daycell{ 14 }{ Friday of the 7th Week of Eastertide }{ 4th Class }{ 1 Pet 4:7-11\ \textperiodcentered\ John 15:26-27; 16:1-4 } & \cellcolor{cred}\daycell{ 15 }{ Vigil of Pentecost }{ 1st Class }{ Acts 19:1-8\ \textperiodcentered\ John 14:15-21 } \\ \hline \cellcolor{cred}\daycell{ 16 }{ Pentecost Sunday (Whitsunday) }{ 1st Class }{ Acts 2:1-11\ \textperiodcentered\ John 14:23-31 } & \cellcolor{cred}\daycell{ 17 }{ Monday of Pentecost Week }{ 1st Class }{ Acts 10:34, 42-48\ \textperiodcentered\ John 3:16-21 } & \cellcolor{cred}\daycell{ 18 }{ Tuesday of Pentecost Week }{ 1st Class }{ Acts 8:14-17\ \textperiodcentered\ John 10:1-10 } & \cellcolor{cred}\daycell{ 19 }{ Pentecost Ember Wednesday }{ 1st Class }{ Acts 5:12-16\ \textperiodcentered\ John 6:44-52 } & \cellcolor{cred}\daycell{ 20 }{ Thursday of Pentecost Week }{ 1st Class }{ Acts 8:5-8\ \textperiodcentered\ Luke 9:1-6 } & \cellcolor{cred}\daycell{ 21 }{ Pentecost Ember Friday }{ 1st Class }{ Joel 2:23-24; 2:26-27\ \textperiodcentered\ Luke 5:17-26 } & \cellcolor{cred}\daycell{ 22 }{ Pentecost Ember Saturday }{ 1st Class }{ Rom 5:1-5\ \textperiodcentered\ Luke 4:38-44 } \\ \hline \cellcolor{cwhite}\daycell{ 23 }{ Trinity Sunday }{ 1st Class }{ Rom 11:33-36\ \textperiodcentered\ Matt 28:18-20 } & \cellcolor{cgreen}\daycell{ 24 }{ Monday of the 1st Week of the Time after Pentecost }{ 4th Class }{ 1 John 4:8-21\ \textperiodcentered\ Luke 6:36-42 } & \cellcolor{cwhite}\daycell{ 25 }{ St. Gregory VII }{ 3rd Class }{ 1 Pet 5:1-4; 5:10-11\ \textperiodcentered\ Matt 16:13-19 } & \cellcolor{cwhite}\daycell{ 26 }{ St. Philip Neri }{ 3rd Class }{ Wis 7:7-14\ \textperiodcentered\ Luke 12:35-40 } & \cellcolor{cwhite}\daycell{ 27 }{ Corpus Christi }{ 1st Class }{ 1 Cor 11:23-29\ \textperiodcentered\ John 6:56-59 } & \cellcolor{cwhite}\daycell{ 28 }{ St. Augustine of Canterbury }{ 3rd Class }{ 1 Thess 2:2-9\ \textperiodcentered\ Luke 10:1-9 } & \cellcolor{cwhite}\daycell{ 29 }{ St. Mary Magdalene de Pazzi }{ 3rd Class }{ 2 Cor 10:17-18; 11:1-2\ \textperiodcentered\ Matt 25:1-13 } \\ \hline diff --git a/test/golden/grid-2027.typ b/test/golden/grid-2027.typ index 800edf9..b9e1d0e 100644 --- a/test/golden/grid-2027.typ +++ b/test/golden/grid-2027.typ @@ -2056,7 +2056,7 @@ - table.cell(fill: cgrid.at("violet"))[ + table.cell(fill: cgrid.at("white"))[ #block(height: cellh - 2 * cellinset, clip: true)[ #set par(leading: 0.3em) #text(weight: "bold")[3] #text(size: 6.5pt)[Rogation Monday] diff --git a/test/golden/ordo-2027.adoc b/test/golden/ordo-2027.adoc index 39e5ae4..d5660a0 100644 --- a/test/golden/ordo-2027.adoc +++ b/test/golden/ordo-2027.adoc @@ -879,7 +879,7 @@ Epistle Jas 1:22-27 Gospel John 16:23-30 *3* Rogation Monday + -class-4 · violet + +class-4 · white + Epistle Jas 1:22-27 Gospel John 16:23-30 + Commemoration Sts. Alexander & Companions diff --git a/test/golden/ordo-2027.html b/test/golden/ordo-2027.html index 8513909..1b621e4 100644 --- a/test/golden/ordo-2027.html +++ b/test/golden/ordo-2027.html @@ -672,9 +672,9 @@
class-2 · white · Epistle Jas 1:22-27 · Gospel John 16:23-30
-
+
3Rogation Monday -
class-4 · violet · Epistle Jas 1:22-27 · Gospel John 16:23-30
+
class-4 · white · Epistle Jas 1:22-27 · Gospel John 16:23-30
Commemoration Sts. Alexander & Companions
diff --git a/test/golden/ordo-2027.md b/test/golden/ordo-2027.md index 3d96240..d4acf1d 100644 --- a/test/golden/ordo-2027.md +++ b/test/golden/ordo-2027.md @@ -789,7 +789,7 @@ **3** Rogation Monday -`class-4` · violet · Epistle Jas 1:22-27 · Gospel John 16:23-30 +`class-4` · white · Epistle Jas 1:22-27 · Gospel John 16:23-30 - Commemoration Sts. Alexander & Companions diff --git a/test/golden/ordo-2027.ms b/test/golden/ordo-2027.ms index e029a76..7bc8c89 100644 --- a/test/golden/ordo-2027.ms +++ b/test/golden/ordo-2027.ms @@ -1354,7 +1354,7 @@ May .IP "3" 4 \fBRogation Monday\fR .br -\s74th Class \(bu Violet\s9 +\s74th Class \(bu White\s9 .br \s7Epistle Jas 1:22-27\s9 .br diff --git a/test/golden/ordo-2027.tex b/test/golden/ordo-2027.tex index 0db4121..e8ec59f 100644 --- a/test/golden/ordo-2027.tex +++ b/test/golden/ordo-2027.tex @@ -1548,9 +1548,9 @@ \begin{tcolorbox}[colback=white,colframe=black!35,boxrule=0.3pt,sharp corners,boxsep=0mm,left=1.6mm,right=1.6mm,top=0.4mm,bottom=0.4mm,before skip=0.3mm,after skip=0mm] -\fontsize{9}{9}\selectfont\bfseries 3 \fontsize{7}{9}\selectfont\mdseries\;Monday\hfill\swatch{licolviolet}\\ +\fontsize{9}{9}\selectfont\bfseries 3 \fontsize{7}{9}\selectfont\mdseries\;Monday\hfill\swatch{licolwhite}\\ \fontsize{9}{9.7}\selectfont\bfseries Rogation Monday\\ -\fontsize{6.5}{7.4}\selectfont\mdseries 4th Class \textperiodcentered\ Violet \quad Epistle\ Jas 1:22-27 \quad Gospel\ John 16:23-30 \\ +\fontsize{6.5}{7.4}\selectfont\mdseries 4th Class \textperiodcentered\ White \quad Epistle\ Jas 1:22-27 \quad Gospel\ John 16:23-30 \\ \fontsize{6.5}{7.4}\selectfont\mdseries Commemoration\ Sts. Alexander \& Companions \end{tcolorbox} diff --git a/test/golden/ordo-2027.txt b/test/golden/ordo-2027.txt index 0af67b3..e0073ec 100644 --- a/test/golden/ordo-2027.txt +++ b/test/golden/ordo-2027.txt @@ -728,7 +728,7 @@ May 2027 Gospel John 16:23-30 3 Rogation Monday - class-4 · violet + class-4 · white Epistle Jas 1:22-27 Gospel John 16:23-30 Commemoration Sts. Alexander & Companions diff --git a/test/golden/ordo-2027.typ b/test/golden/ordo-2027.typ index 0d87f04..ce5e0ca 100644 --- a/test/golden/ordo-2027.typ +++ b/test/golden/ordo-2027.typ @@ -1480,9 +1480,9 @@ #block(width: 100%, above: 0.4mm, below: 0mm, breakable: false, stroke: 0.4pt + luma(160), inset: (x: 1.6mm, y: 0.4mm))[ #set par(leading: 0.36em) - #text(weight: "bold")[3] #h(2mm) #text(size: 7pt)[Monday] #h(1fr) #swatch("violet") \ + #text(weight: "bold")[3] #h(2mm) #text(size: 7pt)[Monday] #h(1fr) #swatch("white") \ #text(weight: "bold")[Rogation Monday] \ - #text(size: 6.5pt)[4th Class #sym.dot.c Violet #h(2mm) Epistle Jas 1:22\-27 #h(2mm) Gospel John 16:23\-30] \ + #text(size: 6.5pt)[4th Class #sym.dot.c White #h(2mm) Epistle Jas 1:22\-27 #h(2mm) Gospel John 16:23\-30] \ #text(size: 6.5pt)[Commemoration Sts. Alexander & Companions] ] diff --git a/test/test_golden.ml b/test/test_golden.ml index d680720..3a6f3f5 100644 --- a/test/test_golden.ml +++ b/test/test_golden.ml @@ -1315,6 +1315,34 @@ let test_rogation_wednesday_yields_to_a_feast_2026 () = "2026-05-13 wednesday season=paschaltide week=6 slug=ef-ascension-vigil rank=class-2 colour=white \ subject=temporal name_la=- comms=[robert-bellarmine:ordinary] in=- out=[]" +(* ---- Rogation Monday/Tuesday colour, RG 119/128/88 (celebrant-rubrics- + phase1 Bug 1 fix, 2026-08-22; data/ef/expected-divergences-lms.sexp's + now-closed L6, data/ef/expected-divergences.sexp's reopened C8) ---- + + {!Rite_ef.Temporal_ef.temporal}'s Rogation Monday/Tuesday branch used to + hardcode [Colour.Violet] with no citation. RG 119 assigns white to the + de-Tempore Office and Mass from the Paschal Vigil to the Pentecost Vigil + exclusive -- Easter+36/+37 sit inside that window -- and RG 128's own + exhaustive four-case violet list never names Rogation days; RG 88 ("de + Litaniis minoribus nihil fit in Officio") is why -- the violet belongs + to the Rogation MASS/procession alone, not the day's own Office. Fixed + to [season_colour s], the same call every other Paschaltide feria makes. + + 2028 pins BOTH days at once (unlike the LMS witness, which only reaches + one day per fixture window): neither is impeded by a competing + sanctoral feast that year, so both are observed outright, both white. + Verified directly against `date -d`: Easter 2028-04-16, so 22/23 May are + Easter+36/+37. *) +let test_rogation_monday_white_2028 () = + check ~msg:"2028: Rogation Monday is white (RG 119), not violet" 2028 5 22 + "2028-05-22 monday season=paschaltide week=6 slug=ef-rogation-monday rank=class-4 colour=white \ + subject=temporal name_la=- comms=[] in=- out=[]" + +let test_rogation_tuesday_white_2028 () = + check ~msg:"2028: Rogation Tuesday is white (RG 119), not violet" 2028 5 23 + "2028-05-23 tuesday season=paschaltide week=6 slug=ef-rogation-tuesday rank=class-4 colour=white \ + subject=temporal name_la=- comms=[] in=- out=[]" + (* ---- The bissextile (leap-year) calendarium footnote, bissextile-shift task, 2026-08-22 ---- @@ -1572,6 +1600,10 @@ let suite = test_rogation_wednesday_admitted_2024; Alcotest.test_case "RG87/113: Rogation Wednesday yields to an impeded feast (2026)" `Quick test_rogation_wednesday_yields_to_a_feast_2026; + Alcotest.test_case "RG119/128: Rogation Monday is white, not violet (2028)" `Quick + test_rogation_monday_white_2028; + Alcotest.test_case "RG119/128: Rogation Tuesday is white, not violet (2028)" `Quick + test_rogation_tuesday_white_2028; Alcotest.test_case "bissextile footnote: Matthias moves 24->25 February (leap, 2044)" `Quick test_bissextile_matthias_leap_2044; Alcotest.test_case "bissextile footnote: Matthias unaffected (common, 2025)" `Quick diff --git a/test/test_lms_ordo.ml b/test/test_lms_ordo.ml index 00fb32c..ed1c871 100644 --- a/test/test_lms_ordo.ml +++ b/test/test_lms_ordo.ml @@ -582,17 +582,25 @@ let make_suite ~label ~fixture_path ~fixture_sha256 ~window_first ~window_last ~ | Some { MF.said = None; _ } -> "NONE (said, unexpectedly outside Votive)" | None -> "NONE") in - (* Two REAL, STRUCTURAL shapes found running this comparison (see - data/ef/expected-divergences-lms.sexp's own L5/L6 for the full - citations) -- neither is a fixed date list, both a property of the - day itself, because both recur every year the underlying condition - holds, not on a fixed calendar date the way L4 above does. Matched - by PREDICATE, not by date, for the same reason L2's own note gives - for why it is prose-only rather than wired through the shared - [expected_rows] mechanism: the count varies window to window (L5: - 6/5/6; L6: 1/0/0), so a single static count cannot check it, and - [make_suite] threads the per-window expected totals directly - (~expected_gloria_l5/~expected_gloria_l6 below) instead. *) + (* L5 is the one REAL, STRUCTURAL shape still open (see + data/ef/expected-divergences-lms.sexp's own L5 for the full + citation) -- not a fixed date list, a property of the day itself, + because it recurs every year the underlying condition holds, not on a + fixed calendar date the way L4 above does. Matched by PREDICATE, not + by date, for the same reason L2's own note gives for why it is + prose-only rather than wired through the shared [expected_rows] + mechanism: the count varies window to window (L5: 6/5/6), so a single + static count cannot check it, and [make_suite] threads the per-window + expected total directly (~expected_gloria_l5 below) instead. + + L6 is CLOSED (celebrant-rubrics-phase1, Bug 1 fix, this task): + {!Rite_ef.Temporal_ef.temporal}'s Rogation Monday/Tuesday branch no + longer hardcodes [Colour.Violet] -- see temporal_ef.ml's own citation + on that branch and data/ef/expected-divergences-lms.sexp's L6 entry + for the fix and its measured blast radius. [is_l6_rogation_colour] and + ~expected_gloria_l6 are kept, at 0 in every window, as the regression + net the same way L3's own bissextile fix keeps a predicate whose count + is now provably zero rather than deleting it. *) let is_l5_lenten_commemoration (o : ordo_row) (c : colitur_row) = (* NOT a Gloria defect (CORRECTED, l5-f3-readjudication task, 2026-08-22 -- data/ef/expected-divergences-lms.sexp's own L5 has @@ -613,15 +621,17 @@ let make_suite ~label ~fixture_path ~fixture_sha256 ~window_first ~window_last ~ (not c.c_gloria) && Option.value o.gloria ~default:false && c.c_has_commemoration && c.c_rank = V.Class3 in let is_l6_rogation_colour (o : ordo_row) (c : colitur_row) = - (* Root-caused to a DIFFERENT, pre-existing bug this comparison merely - surfaced -- {!Rite_ef.Temporal_ef.temporal}'s own Rogation Monday/ - Tuesday branch hardcodes [Colour.Violet] with no RG citation at - all, but the Ordo shows this exact date "FERIA IV Cl W" (white, - matching Paschaltide's own [season_colour] and RG88's "nihil fit in - Officio" -- the Office, hence its colour, is unchanged by the - Rogation, only the Mass TEXT is proper) -- so [gloria]'s own 432(b) - violet guard wrongly fires. NOT a Gloria defect and NOT fixed here - (out of this task's own scope; see the task report). *) + (* CLOSED (celebrant-rubrics-phase1, Bug 1 fix). Was root-caused to a + DIFFERENT, pre-existing bug this comparison merely surfaced -- + {!Rite_ef.Temporal_ef.temporal}'s own Rogation Monday/Tuesday branch + used to hardcode [Colour.Violet] with no RG citation at all, where + the Ordo shows this exact date "FERIA IV Cl W" (white, matching + Paschaltide's own [season_colour] and RG88's "nihil fit in Officio" + -- the Office, hence its colour, is unchanged by the Rogation, only + the Mass TEXT is proper) -- so [gloria]'s own 432(b) violet guard + wrongly fired. Now fixed at the source (temporal_ef.ml); this + predicate and its own ~expected_gloria_l6 count (0 in every window) + are kept as the regression net, not deleted. *) (not c.c_gloria) && Option.value o.gloria ~default:false && (contains_substring c.c_slug ~needle:"rogation-monday" || contains_substring c.c_slug ~needle:"rogation-tuesday") in @@ -788,7 +798,7 @@ let suite_2023_2024 = I-class Sunday that admits him not even as a commemoration (RG16(a)), so his own Mass is not said anywhere in this window any more. *) ~expected_bvm_votive:12 ~expected_proper:181 ~expected_common:2 ~expected_preceding_sunday:61 - ~expected_ascension_week:1 ~expected_gloria_l5:5 ~expected_gloria_l6:1 + ~expected_ascension_week:1 ~expected_gloria_l5:5 ~expected_gloria_l6:0 let suite_2024_2025 = make_suite ~label:"lms-ordo-2024-2025" ~fixture_path:"fixtures/lms-ordo-2024-2025.sexp" diff --git a/test/test_rubrics_ef.ml b/test/test_rubrics_ef.ml index 71f180d..6679702 100644 --- a/test/test_rubrics_ef.ml +++ b/test/test_rubrics_ef.ml @@ -598,6 +598,24 @@ let test_431a_mirrors_te_deum_true () = let test_432a_mirrors_te_deum_false () = check_gloria "432(a): mirrors [te_deum]=false (an ordinary Advent feria)" 2025 12 1 false +(* ---- The Rogation Monday/Tuesday cascade (celebrant-rubrics-phase1 Bug 1 + fix, 2026-08-22): {!Rite_ef.Temporal_ef.temporal} used to hardcode + [Colour.Violet] on these two days with no citation, which silenced + [gloria] via 432(b) even though 237(e)'s own Paschaltide-feria branch + already said [te_deum]=true underneath. Fixed to [season_colour] (RG + 119: white from the Paschal Vigil to the Pentecost Vigil exclusive; RG + 128's own violet list never names Rogation days; RG 88 -- the violet + belongs to the Rogation MASS, not the Office this field describes). + 2028-05-22/23: neither day is impeded that year (test_golden.ml's own + [test_rogation_{monday,tuesday}_white_2028] pins the colour side of the + same fix), so both resolve to white and both now say the Gloria, MIRROR + OF [te_deum] via 431(a) once 432(b)'s violet guard no longer fires -- + MATCHING the LMS Ordo witness (2023-2024, 2024-05-06, "FERIA IV Cl W + ... Gl"). Reverting temporal_ef.ml's fix alone (mutation-checked while + building this task) turns both [false], the pre-fix answer. *) +let test_rogation_monday_gloria_2028 () = check_gloria "Rogation Monday: white -> Gloria said (2028)" 2028 5 22 true +let test_rogation_tuesday_gloria_2028 () = check_gloria "Rogation Tuesday: white -> Gloria said (2028)" 2028 5 23 true + (* ---- Domain-wide sanity, task requirement 5: "every violet day must be false (RG 432 b), and every Requiem must be false (432 d)". Two invariants, checked over every day {!Cal.year} resolves -- [Cal.year], @@ -794,6 +812,8 @@ let suite = Alcotest.test_case "432(d): All Souls' Day (transferred)" `Quick test_432d_all_souls; Alcotest.test_case "431(a): mirrors [te_deum]=true" `Quick test_431a_mirrors_te_deum_true; Alcotest.test_case "432(a): mirrors [te_deum]=false" `Quick test_432a_mirrors_te_deum_false; + Alcotest.test_case "Rogation Monday: white -> Gloria said (2028)" `Quick test_rogation_monday_gloria_2028; + Alcotest.test_case "Rogation Tuesday: white -> Gloria said (2028)" `Quick test_rogation_tuesday_gloria_2028; Alcotest.test_case "domain sanity: every violet day has [gloria]=false (sample)" `Quick test_domain_violet_implies_no_gloria_sample; Alcotest.test_case "domain sanity: every Requiem day has [gloria]=false (sample)" `Quick -- cgit v1.3 From 9c96e0afc19925b651e0dfee3bc9182dee72acf0 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Sat, 22 Aug 2026 20:55:18 +0200 Subject: fix(ef): ferias after the Ascension repeat its own Mass, not a Sunday's Ascension has no octave under the 1960 rubrics -- confirmed structurally: the Proprium de Tempore's own table of contents runs straight from "In Ascensione Domini" to "Dominica post Ascensionem" with no per-feria headings in between. Step 3 of the reading chain therefore fell through to Preceding_sunday on every unoccupied weekday in that stretch, walking each one back to the 5th or 6th Sunday after Easter's own citation. The Missal's own Proprium de Tempore carries an explicit marginal rubric immediately after the Ascension's Mass propers, before "Dominica post Ascensionem" begins: "Diebus a feria VI post Ascensionem usque ad feriam VI ante vigiliam Pentecostes inclusive, dicitur Missa de festo Ascensionis, cum Gloria et praefatione de Ascensione, sine Credo et Communicantes proprio" -- every feria without its own proper, from the Friday after the Ascension through the Friday before the Vigil of Pentecost, repeats the Ascension's own Mass. RG 490(b) corroborates independently: it assigns the Ascension preface "tamquam de Tempore" across that identical window, which only makes sense if the Mass actually repeated there is the Ascension's, not a numbered Sunday's (whose own Mass would carry no need for a preface override at all). Witnessed directly, not only inferred from the rubric: the LMS Ordo prints "Mass of the Ascension" literally on every affected day across all three of its fixture windows, in BOTH the tail of Ascension's own week and the following week -- ruling out the alternative reading (that the second week instead resumes "Dominica post Ascensionem"'s own Mass, which a first pass over the FIUV Ordo's own week-labelled titles could suggest at a glance; its own [praef] field for the same two dates independently reads "Ascensionis", resolving the apparent conflict). Implemented as data, not logic, matching this codebase's own established precedent for the identical RG 299 shape (the week after Trinity Sunday, data/ef/lectionary.sexp's [trinity_week_entries]): six new hand-authored entries, [ascension_week_entries] in tools/bootstrap_lectionary.ml, regenerated against a git-pinned copy of lectio's own source ini (SHA-256 verified unchanged) so the regeneration carries no unrelated drift. The window's two Saturdays are deliberately excluded -- RG 78's votive Office of Our Lady on Saturday always wins an otherwise-unoccupied Class4 Saturday first, before step 2 (this fix's own entry point) is ever reached, so an entry for either slug would be dead data. Blast radius measured in-process across the full 1583-9999 domain (throwaway probe, not committed): 16 350 days total across the six slugs, every one resolved via step 2 (Own_slug), zero anomalies, and the window's two Saturdays confirmed to contribute zero hits via this cause across the whole domain, corroborating the RG78-interception reasoning by direct sweep. Closed L2 in data/ef/expected-divergences-lms.sexp. New cited entries: C41 in data/ef/expected-divergences.sexp (95 of 16801 rows, 2005-2050 -- lectio has no equivalent rubric and still walks these ferias back); M31 in data/ef/expected-divergences-missalemeum.sexp (3 rows in the 2026-2027 window, plus the same shape independently reconfirmed in the 2035 and 2038 live-capture windows) -- missalemeum, Divinum Officium's lineage, still gives the same wrong answer colitur itself used to give, which is why these rows used to agree with M18's shape and now escape it (M18 373 -> 370, the same mechanism M23-M27 established when the citation axis was first built). Golden pin: 2031-05-23, the exact date the bug report was filed against. Mutation-tested: reverting data/ef/lectionary.sexp alone (a git-diff capture/restore, not a source-code revert, since the fix is data) reddens 19 tests across the differential, both oracle fixtures, all three LMS Ordo windows, the golden pin, the lectionary unit test and every Render golden template; restored and reconfirmed green (681 tests; 683 under COLITUR_EXHAUSTIVE_SWEEP=1, ~175s). --- data/ef/expected-divergences-missalemeum.sexp | 11 +++- data/ef/expected-divergences.sexp | 11 ++++ data/ef/lectionary.sexp | 20 +++++- test/golden/grid-2027.html | 2 +- test/golden/grid-2027.ms | 2 +- test/golden/grid-2027.tex | 2 +- test/golden/grid-2027.typ | 2 +- test/golden/ordo-2027.adoc | 2 +- test/golden/ordo-2027.html | 2 +- test/golden/ordo-2027.md | 2 +- test/golden/ordo-2027.ms | 4 +- test/golden/ordo-2027.tex | 2 +- test/golden/ordo-2027.txt | 4 +- test/golden/ordo-2027.typ | 2 +- test/test_differential.ml | 18 ++++++ test/test_golden.ml | 29 +++++++++ test/test_lectionary.ml | 38 ++++++++++- test/test_lms_ordo.ml | 91 ++++++++++++++++++++++++--- test/test_oracle.ml | 47 +++++++++++++- tools/bootstrap_lectionary.ml | 70 +++++++++++++++++++++ 20 files changed, 334 insertions(+), 27 deletions(-) (limited to 'data/ef') diff --git a/data/ef/expected-divergences-missalemeum.sexp b/data/ef/expected-divergences-missalemeum.sexp index dfee36c..d1995e2 100644 --- a/data/ef/expected-divergences-missalemeum.sexp +++ b/data/ef/expected-divergences-missalemeum.sexp @@ -257,8 +257,10 @@ REVISED, ef-bvm-saturday task: 395 of the 730 days in this window used to carry REVISED AGAIN, Task 9 (branch ef-lectionary, layer-4 oracle): 352, down by 42 from 394. NOT a change to this entry's own guard (still, and only, [diffs = [ Observed_identity_unresolved ]] exactly) -- this task compared reading citations for the first time, and 42 of the former 394 rows now ALSO carry a real [First_mismatch]/[Gospel_mismatch] alongside the pre-existing observed-identity gap, so they escape this entry's own EXACT-match guard and move to the FIVE new entries below (M23 2, M24 4, M25 4, M26 30, M27 2 -- 2+4+4+30+2=42, exactly accounting for the drop, verified against the comparator's own failure output, not assumed from the arithmetic alone -- CORRECTED, fix round 1, coordinator review: this note previously miscounted them as \"six\"). -CORRECTED, fix round 1 (coordinator review): the remaining 352 were previously described as every day whose citation \"ALREADY agreed with missalemeum before this task and still does\" -- imprecise for 18 of them. Before this task the citation axis did not exist at all, so NO row's citation was ever actually checked; \"already agreed\" wrongly implies the pre-task VALUE was correct on all 352, when for 18 it was not -- it only became correct, and therefore only started agreeing, because of this task's own three fixes (Holy Name Sunday's own two dates, 2026-01-04/2027-01-03; 12 more January-window ferias across the three RG-17(a)/Holy-Family-propers-rubric families that now resolve at step 2 instead of the walkback, one full list: 2026-01-02/05/07/08/09/12, 2027-01-04/05/07/08/11/12; and Corpus Christi/Sacred Heart in both years, 2026-06-04/06-12, 2027-05-27/06-04 -- 2+12+4=18, independently re-derived against the real resolver, not merely arithmetic). The other 334 were genuinely unaffected by this task, matching both before and after (or, more precisely, would have matched on the day this axis existed either way). WIDENED 352 -> 355 (movable-date-specs follow-up, 2026-08-17): the three Trinity-week ferias that M26 shape 2(a) used to cover now agree with the oracle on their citations and differ only on observed-identity, which is this entry own generic shape -- a temporal-origin day for which colitur sets no English name. Not a new divergence: the same three days, one of their two causes removed. WIDENED 355 -> 376 (BVM Saturday Mass, 2026-08-17): the BVM Saturday days M26 shape 1 used to cover now agree with the oracle on their citations and differ only on observed identity, which is this entry's own generic shape -- the office is temporal-origin and deliberately carries no English name. Not new divergences: the same days, their citation cause removed. CORRECTED, ef-sanctoral-status: 376 -> 373. Three rows left this entry for M30 when `ubaldus` and `didacus` were promoted to Feast on the Missal's own calendarium. They were unresolved here precisely because the observed office was TEMPORAL-origin (a feria) and carries no English name; now the observed office is the SAINT, which is sanctoral-origin and does resolve, so the comparator can state a real identity mismatch instead of declining to compare. The entry shrinks because its shape stopped occurring on those days, not because the days stopped diverging.") - (expected_rows 373)) +CORRECTED, fix round 1 (coordinator review): the remaining 352 were previously described as every day whose citation \"ALREADY agreed with missalemeum before this task and still does\" -- imprecise for 18 of them. Before this task the citation axis did not exist at all, so NO row's citation was ever actually checked; \"already agreed\" wrongly implies the pre-task VALUE was correct on all 352, when for 18 it was not -- it only became correct, and therefore only started agreeing, because of this task's own three fixes (Holy Name Sunday's own two dates, 2026-01-04/2027-01-03; 12 more January-window ferias across the three RG-17(a)/Holy-Family-propers-rubric families that now resolve at step 2 instead of the walkback, one full list: 2026-01-02/05/07/08/09/12, 2027-01-04/05/07/08/11/12; and Corpus Christi/Sacred Heart in both years, 2026-06-04/06-12, 2027-05-27/06-04 -- 2+12+4=18, independently re-derived against the real resolver, not merely arithmetic). The other 334 were genuinely unaffected by this task, matching both before and after (or, more precisely, would have matched on the day this axis existed either way). WIDENED 352 -> 355 (movable-date-specs follow-up, 2026-08-17): the three Trinity-week ferias that M26 shape 2(a) used to cover now agree with the oracle on their citations and differ only on observed-identity, which is this entry own generic shape -- a temporal-origin day for which colitur sets no English name. Not a new divergence: the same three days, one of their two causes removed. WIDENED 355 -> 376 (BVM Saturday Mass, 2026-08-17): the BVM Saturday days M26 shape 1 used to cover now agree with the oracle on their citations and differ only on observed identity, which is this entry's own generic shape -- the office is temporal-origin and deliberately carries no English name. Not new divergences: the same days, their citation cause removed. CORRECTED, ef-sanctoral-status: 376 -> 373. Three rows left this entry for M30 when `ubaldus` and `didacus` were promoted to Feast on the Missal's own calendarium. They were unresolved here precisely because the observed office was TEMPORAL-origin (a feria) and carries no English name; now the observed office is the SAINT, which is sanctoral-origin and does resolve, so the comparator can state a real identity mismatch instead of declining to compare. The entry shrinks because its shape stopped occurring on those days, not because the days stopped diverging. + +NARROWED, celebrant-rubrics-phase1 Bug 2 (2026-08-22): 373 -> 370. The three Ascension-week days (2026-05-21, 2026-05-22, 2027-05-14) move to the new M31: before this fix colitur's own citation on these three days was ALSO wrong (the same Preceding_sunday walkback missalemeum still uses), so it happened to already agree with missalemeum's, leaving [Observed_identity_unresolved] as the ONLY diff -- this entry's own shape. The fix corrected colitur's side, so these three now ALSO carry a real citation mismatch and escape this entry's exact-match guard, the identical mechanism M23-M27 above already used when the citation axis was first built. See M31's own note for the full account.") + (expected_rows 370)) ((id M19) (citation "RG 110's OTHER direction: \"In Officio et Missa S. Petri semper fit commemoratio S. Pauli, ET VICISSIM\" -- the SAME rule M12 used to cite, applied here to Paul's own office commemorating Peter, not Peter's own office commemorating Paul; confirmed a third time by the calendarium's own June table, both photographic scans, word for word: \"In Commemoratione S. Pauli Ap., III classis. / Commemoratio S. Petri Ap.\"") (verdict colitur) @@ -308,3 +310,8 @@ CORRECTED, fix round 1 (coordinator review): the remaining 352 were previously d (verdict colitur) (note "ef-sanctoral-status branch. As with M29, the oracle here is not an independent witness against colitur but colitur's own discarded ancestor: colitur was bootstrapped from lectio, lectio's ini is generated from missalemeum, and missalemeum uses Divinum Officium's data files, so all three carried the same wrong status. Found by auditing ALL 290 fixed-date sanctoral entries against the calendarium; these two were the only status defects in the file. 3 rows in this window: 2026-05-16, 2026-11-13, 2027-11-13. Where colitur now observes the saint the oracle still observes the feria, so rank, observed identity and both citations differ together and the commemoration colitur used to emit is gone. Colour differs only on 13 November, the ferial green giving way to the confessor's white; 16 May is in Paschaltide and already white. Gated on the exact dates and on a subset of that named field list, so a divergence of any other shape on these days would still surface unexplained. Three rows also leave M18 (376 to 373): they were unresolved there only because the observed office was a temporal-origin feria with no English name, and the observed office is now sanctoral and resolves.") (expected_rows 3)) + ((id M31) + (citation "The Missale Romanum's own Proprium de Tempore carries an explicit marginal rubric immediately after the Ascension's own Mass propers, before \"Dominica post Ascensionem\" begins (scan1.txt:20749-20754, both scans corroborate): \"Diebus a feria VI post Ascensionem usque ad feriam VI ante vigiliam Pentecostes inclusive, dicitur Missa de festo Ascensionis\" -- on the days from the Friday after the Ascension until the Friday before the Vigil of Pentecost inclusive, the Mass OF THE FEAST OF THE ASCENSION is said. Corroborated by RG 490(b), which assigns the Ascension preface as de Tempore across the identical window. Full account in C41, data/ef/expected-divergences.sexp. Implemented in data/ef/lectionary.sexp's [ascension_week_entries] (tools/bootstrap_lectionary.ml), celebrant-rubrics-phase1 Bug 2, 2026-08-22.") + (verdict colitur) + (note "As with M29/M30, the oracle here is colitur's own discarded ancestor, not an independent witness: missalemeum -- Divinum Officium's lineage -- still walks these ferias back to the preceding Sunday's Mass, the SAME wrong answer colitur itself gave before this fix. 3 rows in this window: 2026-05-21, 2026-05-22, 2027-05-14. Of the twelve candidate civil dates the six slugs reach across 2026 and 2027 (six per year), the other nine are occupied by real sanctoral feasts both engines already agree on: 2026-05-15/18/19/20 (John Baptist de la Salle, Venantius, Peter Celestine, Bernardine of Siena) and 2027-05-07/10/11/12/13 (Stanislaus, Antoninus, Sts Philip & James, Sts Nereus/Achilleus/Domitilla/Pancras, Robert Bellarmine) -- checked directly against `colitur day`, not assumed. [Observed_identity_unresolved] fires alongside on all three: none is a sanctoral-origin day, M18's own pre-existing limit, unrelated to this cause. Gated on the exact dates and on a subset of [Observed_identity_unresolved; First_mismatch; Gospel_mismatch] (2027-05-14 also carries a real, AGREEING commemoration -- St Boniface -- on both sides, so Comm_count/Comm_presence never differ there and stay outside this diff set). Three rows leave M18 (373 to 370): they used to carry [Observed_identity_unresolved] alone (colitur's own pre-fix citation happened to already match missalemeum's, both walking back the same wrong way) and now also carry the citation mismatch this fix corrected colitur's own side of.") + (expected_rows 3)) diff --git a/data/ef/expected-divergences.sexp b/data/ef/expected-divergences.sexp index f98409b..ca0d6a3 100644 --- a/data/ef/expected-divergences.sexp +++ b/data/ef/expected-divergences.sexp @@ -131,6 +131,17 @@ Diff shapes: most rows carry [Slug_f; Rank; Colour_f; First_f; Gospel_f] (the te BLAST RADIUS, MEASURED, full 1583-9999 domain (not merely this fixture's 2005-2050 window): 6 983 liturgical days change, zero unclassified, across all 2 041 leap years in the domain -- see data/ef/expected-divergences-lms.sexp's own now-closed L3 entry for the full figures (this entry's own 21-row 2005-2050 population is the expected subset of that domain-wide count landing inside the fixture's own window: 11 leap years x up to 2 new rows each, minus the three already-explained overlaps above).") (expected_rows 21)) + ((id C41) + (citation "The Missale Romanum's own Proprium de Tempore carries an explicit marginal rubric immediately after the Ascension's own Mass propers, before \"Dominica post Ascensionem\" begins (scan1.txt:20749-20754, both scans corroborate): \"Diebus a feria VI post Ascensionem usque ad feriam VI ante vigiliam Pentecostes inclusive, dicitur Missa de festo Ascensionis, cum Gloria et praefatione de Ascensione, sine Credo et Communicantes proprio\" -- on the days from the Friday after the Ascension until the Friday before the Vigil of Pentecost inclusive, the Mass OF THE FEAST OF THE ASCENSION is said. Corroborated by RG 490(b) (LT.txt:3981-3985), which assigns the Ascension preface \"tamquam de Tempore\" to every Mass in that same window lacking a proper preface -- consistent only if the Mass repeated is the Ascension's own, not a numbered Sunday's. Witnessed directly: the LMS Ordo prints \"Mass of the Ascension\" literally across all three fixture windows (data/ef/expected-divergences-lms.sexp's own L2, closed by this entry) on every affected day of BOTH weeks, and the FIUV Ordo's own [praef] field independently reads \"Ascensionis\" on the two analogous 2025-2026 dates its title labels by week rather than by formulary. Implemented in data/ef/lectionary.sexp's [ascension_week_entries] (tools/bootstrap_lectionary.ml), celebrant-rubrics-phase1 Bug 2, 2026-08-22.") + (verdict colitur) + (note "lectio has no equivalent rubric: it walks the six affected ferias back to the nearest preceding Sunday's Mass (5th Sunday after Easter for [ef-easter-6-friday], Dominica post Ascensionem for the five [ef-easter-7-*] weekdays), the SAME wrong answer colitur used to give before this fix. Both sides agree on slug, season (Layer A normalises colitur's [paschaltide] and lectio's [easter] as the same vocabulary), rank and colour throughout -- only the citation text differs, so every row carries [First_f; Gospel_f] alone. + +MEASURED (test_differential.ml's own [classify], 2005-2050 fixture, run directly): 95 rows, all six slugs represented, zero unclassified. Population varies year to year (0-3 of the six slugs fire per year) because most years have a real sanctoral feast occupying one or more of the six candidate civil dates -- the same reason data/ef/expected-divergences-lms.sexp's own L2 found only 1-3 affected days per its own one-year fixture windows, now confirmed at scale across the full 46-year differential window. + +The window's two Saturdays (Easter+41, Easter+48) never reach this entry: Easter+48 is the Vigil of Pentecost, a named day with its own Mass, outside the rubric's own upper bound; Easter+41 is an ordinary Class4 Saturday, so RG 78's votive Office of Our Lady on Saturday intercepts it before the lectionary lookup this entry's own fix touches is ever reached (readings' own step ordering) -- confirmed directly: no row in the 95 carries [ef-easter-6-saturday] or [ef-easter-7-saturday]. + +BLAST RADIUS, MEASURED (full 1583-9999 sweep, in-process against {!Colitur_kernel.Calendar.year}, throwaway probe, not committed): 16 350 days total, split ef-easter-6-friday 2 562, ef-easter-7-monday 2 618, ef-easter-7-tuesday 2 744, ef-easter-7-wednesday 2 776, ef-easter-7-thursday 2 781, ef-easter-7-friday 2 869 -- every one resolved via step 2's Own_slug, zero anomalies, and the window's two Saturdays confirmed to contribute zero Own_slug hits via this cause across the whole domain (RG 78's votive Office of Our Lady always intercepts first), corroborating the code-level reasoning above by direct sweep rather than inspection alone.") + (expected_rows 95)) ((id C8) (citation "RG 119 (Caput XVIII, \"De Colore Paramentorum\"): white is used \"in Officio et Missa de Tempore ... a Missa Vigiliae paschalis usque ad Missam vigiliae Pentecostes exclusive\" -- the de-Tempore Office and Mass are white from the Paschal Vigil Mass until the Pentecost Vigil Mass exclusive, and Rogation Monday/Tuesday (Easter+36/+37) sit inside that window. RG 128's own exhaustive four-case list for violet (Advent I-Christmas Eve; Septuagesima-Paschal Vigil; the September Ember ferias; vigils of II/III class OUTSIDE Paschaltide) never names Rogation days. RG 88 (\"de Litaniis minoribus nihil fit in Officio, sed tantum in Missa\"): the violet belongs to the Rogation MASS/procession, a distinct votive text this engine does not model, not to the day's own Office. Fixed in Rite_ef.Temporal_ef.temporal's Rogation branch, celebrant-rubrics-phase1 Bug 1, 2026-08-22 -- see that branch's own citation and data/ef/expected-divergences-lms.sexp's now-closed L6 entry, which is what surfaced it (LMS Ordo 2023-2024, 2024-05-06, \"FERIA IV Cl W\").") (verdict colitur) diff --git a/data/ef/lectionary.sexp b/data/ef/lectionary.sexp index a83e12e..e34622d 100644 --- a/data/ef/lectionary.sexp +++ b/data/ef/lectionary.sexp @@ -10,7 +10,7 @@ ; ; Source: ../lectio/internal/caldata/tridentine-lectionary.ini ; SHA-256: ccd6640e8c2ae4d260e62c55cfe2b3ea14ab996e8e5a82cc1b9a37bc65ac8591 -; 153 entries (119 ini sections translated/widened into colitur's own +; 159 entries (119 ini sections translated/widened into colitur's own ; Temporal_ef vocabulary via [colitur_keys]; 1 hand-authored from a ; second source file [vigil_entries]; 6 hand-authored directly from ; the Missal [holy_week_entries]; 1 hand-authored directly from the @@ -134,9 +134,27 @@ (ef-easter-5-saturday (((part First) (reference "Ecclus 24:14-16")) ((part Gospel) (reference "John 19:25-27")))) + (ef-easter-6-friday + (((part First) (reference "Acts 1:1-11")) + ((part Gospel) (reference "Mark 16:14-20")))) (ef-easter-6-saturday (((part First) (reference "Ecclus 24:14-16")) ((part Gospel) (reference "John 19:25-27")))) + (ef-easter-7-friday + (((part First) (reference "Acts 1:1-11")) + ((part Gospel) (reference "Mark 16:14-20")))) + (ef-easter-7-monday + (((part First) (reference "Acts 1:1-11")) + ((part Gospel) (reference "Mark 16:14-20")))) + (ef-easter-7-thursday + (((part First) (reference "Acts 1:1-11")) + ((part Gospel) (reference "Mark 16:14-20")))) + (ef-easter-7-tuesday + (((part First) (reference "Acts 1:1-11")) + ((part Gospel) (reference "Mark 16:14-20")))) + (ef-easter-7-wednesday + (((part First) (reference "Acts 1:1-11")) + ((part Gospel) (reference "Mark 16:14-20")))) (ef-easter-8-monday (((part First) (reference "Acts 10:34, 42-48")) ((part Gospel) (reference "John 3:16-21")))) diff --git a/test/golden/grid-2027.html b/test/golden/grid-2027.html index 6741ad7..92a73ec 100644 --- a/test/golden/grid-2027.html +++ b/test/golden/grid-2027.html @@ -134,7 +134,7 @@ 25th Sunday after EasterJas 1:22-27 · John 16:23-303Rogation MondayJas 1:22-27 · John 16:23-304St. Monica1 Tim 5:3-10 · Luke 7:11-165Vigil of the AscensionEph 4:7-13 · John 17:1-116The Ascension of Our LordActs 1:1-11 · Mark 16:14-207St. StanislausWis 5:1-5 · John 15:1-78Our Lady's Saturday OfficeEcclus 24:14-16 · John 19:25-27 - 9Sunday after the Ascension1 Pet 4:7-11 · John 15:26-27; 16:1-410St. AntoninusEcclus 44:16-27; 45:3-20 · Matt 25:14-2311Sts. Philip & JamesWis 5:1-5 · John 14:1-1312Sts. Nereus, Achilleus, Domitilla, & PancrasWis 5:1-5 · John 4:46-5313St. Robert BellarmineWis 7:7-14 · Matt 5:13-1914Friday of the 7th Week of Eastertide1 Pet 4:7-11 · John 15:26-27; 16:1-415Vigil of PentecostActs 19:1-8 · John 14:15-21 + 9Sunday after the Ascension1 Pet 4:7-11 · John 15:26-27; 16:1-410St. AntoninusEcclus 44:16-27; 45:3-20 · Matt 25:14-2311Sts. Philip & JamesWis 5:1-5 · John 14:1-1312Sts. Nereus, Achilleus, Domitilla, & PancrasWis 5:1-5 · John 4:46-5313St. Robert BellarmineWis 7:7-14 · Matt 5:13-1914Friday of the 7th Week of EastertideActs 1:1-11 · Mark 16:14-2015Vigil of PentecostActs 19:1-8 · John 14:15-21 16Pentecost Sunday (Whitsunday)Acts 2:1-11 · John 14:23-3117Monday of Pentecost WeekActs 10:34, 42-48 · John 3:16-2118Tuesday of Pentecost WeekActs 8:14-17 · John 10:1-1019Pentecost Ember WednesdayActs 5:12-16 · John 6:44-5220Thursday of Pentecost WeekActs 8:5-8 · Luke 9:1-621Pentecost Ember FridayJoel 2:23-24; 2:26-27 · Luke 5:17-2622Pentecost Ember SaturdayRom 5:1-5 · Luke 4:38-44 diff --git a/test/golden/grid-2027.ms b/test/golden/grid-2027.ms index 4f71416..3432d8f 100644 --- a/test/golden/grid-2027.ms +++ b/test/golden/grid-2027.ms @@ -767,7 +767,7 @@ T} T{ T} T{ \fB14\fP \s-2Friday of the 7th Week of Eastertide\s+2 .br -\s-21 Pet 4:7-11 \(bu John 15:26-27; 16:1-4\s+2 +\s-2Acts 1:1-11 \(bu Mark 16:14-20\s+2 T} T{ \fB15\fP \s-2Vigil of Pentecost\s+2 .br diff --git a/test/golden/grid-2027.tex b/test/golden/grid-2027.tex index d81bdb4..1585bda 100644 --- a/test/golden/grid-2027.tex +++ b/test/golden/grid-2027.tex @@ -152,7 +152,7 @@ \textbf{ Sunday } & \textbf{ Monday } & \textbf{ Tuesday } & \textbf{ Wednesday } & \textbf{ Thursday } & \textbf{ Friday } & \textbf{ Saturday } \\ \hline & & & & & & \cellcolor{cwhite}\daycell{ 1 }{ St. Joseph the Workman }{ 1st Class }{ Col 3:14-15, 17, 23-24\ \textperiodcentered\ Matt 13:54-58 } \\ \hline \cellcolor{cwhite}\daycell{ 2 }{ 5th Sunday after Easter }{ 2nd Class }{ Jas 1:22-27\ \textperiodcentered\ John 16:23-30 } & \cellcolor{cwhite}\daycell{ 3 }{ Rogation Monday }{ 4th Class }{ Jas 1:22-27\ \textperiodcentered\ John 16:23-30 } & \cellcolor{cwhite}\daycell{ 4 }{ St. Monica }{ 3rd Class }{ 1 Tim 5:3-10\ \textperiodcentered\ Luke 7:11-16 } & \cellcolor{cwhite}\daycell{ 5 }{ Vigil of the Ascension }{ 2nd Class }{ Eph 4:7-13\ \textperiodcentered\ John 17:1-11 } & \cellcolor{cwhite}\daycell{ 6 }{ The Ascension of Our Lord }{ 1st Class }{ Acts 1:1-11\ \textperiodcentered\ Mark 16:14-20 } & \cellcolor{cred}\daycell{ 7 }{ St. Stanislaus }{ 3rd Class }{ Wis 5:1-5\ \textperiodcentered\ John 15:1-7 } & \cellcolor{cwhite}\daycell{ 8 }{ Our Lady's Saturday Office }{ 4th Class }{ Ecclus 24:14-16\ \textperiodcentered\ John 19:25-27 } \\ \hline -\cellcolor{cwhite}\daycell{ 9 }{ Sunday after the Ascension }{ 2nd Class }{ 1 Pet 4:7-11\ \textperiodcentered\ John 15:26-27; 16:1-4 } & \cellcolor{cwhite}\daycell{ 10 }{ St. Antoninus }{ 3rd Class }{ Ecclus 44:16-27; 45:3-20\ \textperiodcentered\ Matt 25:14-23 } & \cellcolor{cred}\daycell{ 11 }{ Sts. Philip \& James }{ 2nd Class }{ Wis 5:1-5\ \textperiodcentered\ John 14:1-13 } & \cellcolor{cred}\daycell{ 12 }{ Sts. Nereus, Achilleus, Domitilla, \& Pancras }{ 3rd Class }{ Wis 5:1-5\ \textperiodcentered\ John 4:46-53 } & \cellcolor{cwhite}\daycell{ 13 }{ St. Robert Bellarmine }{ 3rd Class }{ Wis 7:7-14\ \textperiodcentered\ Matt 5:13-19 } & \cellcolor{cwhite}\daycell{ 14 }{ Friday of the 7th Week of Eastertide }{ 4th Class }{ 1 Pet 4:7-11\ \textperiodcentered\ John 15:26-27; 16:1-4 } & \cellcolor{cred}\daycell{ 15 }{ Vigil of Pentecost }{ 1st Class }{ Acts 19:1-8\ \textperiodcentered\ John 14:15-21 } \\ \hline +\cellcolor{cwhite}\daycell{ 9 }{ Sunday after the Ascension }{ 2nd Class }{ 1 Pet 4:7-11\ \textperiodcentered\ John 15:26-27; 16:1-4 } & \cellcolor{cwhite}\daycell{ 10 }{ St. Antoninus }{ 3rd Class }{ Ecclus 44:16-27; 45:3-20\ \textperiodcentered\ Matt 25:14-23 } & \cellcolor{cred}\daycell{ 11 }{ Sts. Philip \& James }{ 2nd Class }{ Wis 5:1-5\ \textperiodcentered\ John 14:1-13 } & \cellcolor{cred}\daycell{ 12 }{ Sts. Nereus, Achilleus, Domitilla, \& Pancras }{ 3rd Class }{ Wis 5:1-5\ \textperiodcentered\ John 4:46-53 } & \cellcolor{cwhite}\daycell{ 13 }{ St. Robert Bellarmine }{ 3rd Class }{ Wis 7:7-14\ \textperiodcentered\ Matt 5:13-19 } & \cellcolor{cwhite}\daycell{ 14 }{ Friday of the 7th Week of Eastertide }{ 4th Class }{ Acts 1:1-11\ \textperiodcentered\ Mark 16:14-20 } & \cellcolor{cred}\daycell{ 15 }{ Vigil of Pentecost }{ 1st Class }{ Acts 19:1-8\ \textperiodcentered\ John 14:15-21 } \\ \hline \cellcolor{cred}\daycell{ 16 }{ Pentecost Sunday (Whitsunday) }{ 1st Class }{ Acts 2:1-11\ \textperiodcentered\ John 14:23-31 } & \cellcolor{cred}\daycell{ 17 }{ Monday of Pentecost Week }{ 1st Class }{ Acts 10:34, 42-48\ \textperiodcentered\ John 3:16-21 } & \cellcolor{cred}\daycell{ 18 }{ Tuesday of Pentecost Week }{ 1st Class }{ Acts 8:14-17\ \textperiodcentered\ John 10:1-10 } & \cellcolor{cred}\daycell{ 19 }{ Pentecost Ember Wednesday }{ 1st Class }{ Acts 5:12-16\ \textperiodcentered\ John 6:44-52 } & \cellcolor{cred}\daycell{ 20 }{ Thursday of Pentecost Week }{ 1st Class }{ Acts 8:5-8\ \textperiodcentered\ Luke 9:1-6 } & \cellcolor{cred}\daycell{ 21 }{ Pentecost Ember Friday }{ 1st Class }{ Joel 2:23-24; 2:26-27\ \textperiodcentered\ Luke 5:17-26 } & \cellcolor{cred}\daycell{ 22 }{ Pentecost Ember Saturday }{ 1st Class }{ Rom 5:1-5\ \textperiodcentered\ Luke 4:38-44 } \\ \hline \cellcolor{cwhite}\daycell{ 23 }{ Trinity Sunday }{ 1st Class }{ Rom 11:33-36\ \textperiodcentered\ Matt 28:18-20 } & \cellcolor{cgreen}\daycell{ 24 }{ Monday of the 1st Week of the Time after Pentecost }{ 4th Class }{ 1 John 4:8-21\ \textperiodcentered\ Luke 6:36-42 } & \cellcolor{cwhite}\daycell{ 25 }{ St. Gregory VII }{ 3rd Class }{ 1 Pet 5:1-4; 5:10-11\ \textperiodcentered\ Matt 16:13-19 } & \cellcolor{cwhite}\daycell{ 26 }{ St. Philip Neri }{ 3rd Class }{ Wis 7:7-14\ \textperiodcentered\ Luke 12:35-40 } & \cellcolor{cwhite}\daycell{ 27 }{ Corpus Christi }{ 1st Class }{ 1 Cor 11:23-29\ \textperiodcentered\ John 6:56-59 } & \cellcolor{cwhite}\daycell{ 28 }{ St. Augustine of Canterbury }{ 3rd Class }{ 1 Thess 2:2-9\ \textperiodcentered\ Luke 10:1-9 } & \cellcolor{cwhite}\daycell{ 29 }{ St. Mary Magdalene de Pazzi }{ 3rd Class }{ 2 Cor 10:17-18; 11:1-2\ \textperiodcentered\ Matt 25:1-13 } \\ \hline \cellcolor{cgreen}\daycell{ 30 }{ 2nd Sunday after Pentecost }{ 2nd Class }{ 1 John 3:13-18\ \textperiodcentered\ Luke 14:16-24 } & \cellcolor{cwhite}\daycell{ 31 }{ Queenship of the Blessed Virgin Mary }{ 2nd Class }{ Ecclus 24:5; 14:7; 14:9-11; 24:30-31\ \textperiodcentered\ Luke 1:26-33 } & & & & & \\ \hline diff --git a/test/golden/grid-2027.typ b/test/golden/grid-2027.typ index b9e1d0e..cc4d440 100644 --- a/test/golden/grid-2027.typ +++ b/test/golden/grid-2027.typ @@ -2207,7 +2207,7 @@ #text(weight: "bold")[14] #text(size: 6.5pt)[Friday of the 7th Week of Eastertide] #v(1fr) #text(size: 6pt)[4th Class] \ - #text(size: 6pt)[1 Pet 4:7\-11 #sym.dot.c John 15:26\-27; 16:1\-4] + #text(size: 6pt)[Acts 1:1\-11 #sym.dot.c Mark 16:14\-20] ] ], diff --git a/test/golden/ordo-2027.adoc b/test/golden/ordo-2027.adoc index d5660a0..93a233d 100644 --- a/test/golden/ordo-2027.adoc +++ b/test/golden/ordo-2027.adoc @@ -952,7 +952,7 @@ Epistle Wis 7:7-14 Gospel Matt 5:13-19 *14* Friday of the 7th Week of Eastertide + class-4 · white + -Epistle 1 Pet 4:7-11 Gospel John 15:26-27; 16:1-4 +Epistle Acts 1:1-11 Gospel Mark 16:14-20 + Commemoration St. Boniface diff --git a/test/golden/ordo-2027.html b/test/golden/ordo-2027.html index 1b621e4..2a3f5e1 100644 --- a/test/golden/ordo-2027.html +++ b/test/golden/ordo-2027.html @@ -730,7 +730,7 @@
14Friday of the 7th Week of Eastertide -
class-4 · white · Epistle 1 Pet 4:7-11 · Gospel John 15:26-27; 16:1-4
+
class-4 · white · Epistle Acts 1:1-11 · Gospel Mark 16:14-20
Commemoration St. Boniface
diff --git a/test/golden/ordo-2027.md b/test/golden/ordo-2027.md index d4acf1d..c90b65e 100644 --- a/test/golden/ordo-2027.md +++ b/test/golden/ordo-2027.md @@ -853,7 +853,7 @@ **14** Friday of the 7th Week of Eastertide -`class-4` · white · Epistle 1 Pet 4:7-11 · Gospel John 15:26-27; 16:1-4 +`class-4` · white · Epistle Acts 1:1-11 · Gospel Mark 16:14-20 - Commemoration St. Boniface diff --git a/test/golden/ordo-2027.ms b/test/golden/ordo-2027.ms index 7bc8c89..c9e6f5e 100644 --- a/test/golden/ordo-2027.ms +++ b/test/golden/ordo-2027.ms @@ -1464,9 +1464,9 @@ May .br \s74th Class \(bu White\s9 .br -\s7Epistle 1 Pet 4:7-11\s9 +\s7Epistle Acts 1:1-11\s9 .br -\s7Gospel John 15:26-27; 16:1-4\s9 +\s7Gospel Mark 16:14-20\s9 .br \s7Commemoration St. Boniface\s9 .sp 0.25v diff --git a/test/golden/ordo-2027.tex b/test/golden/ordo-2027.tex index e8ec59f..0debd17 100644 --- a/test/golden/ordo-2027.tex +++ b/test/golden/ordo-2027.tex @@ -1648,7 +1648,7 @@ \begin{tcolorbox}[colback=white,colframe=black!35,boxrule=0.3pt,sharp corners,boxsep=0mm,left=1.6mm,right=1.6mm,top=0.4mm,bottom=0.4mm,before skip=0.3mm,after skip=0mm] \fontsize{9}{9}\selectfont\bfseries 14 \fontsize{7}{9}\selectfont\mdseries\;Friday\hfill\swatch{licolwhite}\\ \fontsize{9}{9.7}\selectfont\bfseries Friday of the 7th Week of Eastertide\\ -\fontsize{6.5}{7.4}\selectfont\mdseries 4th Class \textperiodcentered\ White \quad Epistle\ 1 Pet 4:7-11 \quad Gospel\ John 15:26-27; 16:1-4 \\ +\fontsize{6.5}{7.4}\selectfont\mdseries 4th Class \textperiodcentered\ White \quad Epistle\ Acts 1:1-11 \quad Gospel\ Mark 16:14-20 \\ \fontsize{6.5}{7.4}\selectfont\mdseries Commemoration\ St. Boniface \end{tcolorbox} diff --git a/test/golden/ordo-2027.txt b/test/golden/ordo-2027.txt index e0073ec..b2c68a3 100644 --- a/test/golden/ordo-2027.txt +++ b/test/golden/ordo-2027.txt @@ -790,8 +790,8 @@ May 2027 14 Friday of the 7th Week of Eastertide class-4 · white - Epistle 1 Pet 4:7-11 - Gospel John 15:26-27; 16:1-4 + Epistle Acts 1:1-11 + Gospel Mark 16:14-20 Commemoration St. Boniface 15 Vigil of Pentecost diff --git a/test/golden/ordo-2027.typ b/test/golden/ordo-2027.typ index ce5e0ca..23afb88 100644 --- a/test/golden/ordo-2027.typ +++ b/test/golden/ordo-2027.typ @@ -1589,7 +1589,7 @@ #set par(leading: 0.36em) #text(weight: "bold")[14] #h(2mm) #text(size: 7pt)[Friday] #h(1fr) #swatch("white") \ #text(weight: "bold")[Friday of the 7th Week of Eastertide] \ - #text(size: 6.5pt)[4th Class #sym.dot.c White #h(2mm) Epistle 1 Pet 4:7\-11 #h(2mm) Gospel John 15:26\-27; 16:1\-4] \ + #text(size: 6.5pt)[4th Class #sym.dot.c White #h(2mm) Epistle Acts 1:1\-11 #h(2mm) Gospel Mark 16:14\-20] \ #text(size: 6.5pt)[Commemoration St. Boniface] ] diff --git a/test/test_differential.ml b/test/test_differential.ml index 2f63df6..222328b 100644 --- a/test/test_differential.ml +++ b/test/test_differential.ml @@ -550,6 +550,17 @@ let jan_6_13_slug slug = let nativity_octave_day_slugs = [ "ef-nativity-octave-day-5"; "ef-nativity-octave-day-6"; "ef-nativity-octave-day-7" ] +(* C41 (celebrant-rubrics-phase1, Bug 2, 2026-08-22): the six ferias + between the Ascension and the Friday before the Vigil of Pentecost that + repeat the Ascension's own Mass (data/ef/lectionary.sexp's own + [ascension_week_entries], bootstrap_lectionary.ml). The window's two + Saturdays are excluded here too, for the identical reason they carry no + lectionary entry: RG 78's votive Office of Our Lady wins first. *) +let ascension_week_slugs = + [ "ef-easter-6-friday"; "ef-easter-7-monday"; "ef-easter-7-tuesday"; "ef-easter-7-wednesday"; + "ef-easter-7-thursday"; "ef-easter-7-friday" + ] + (* C18 (ef-sanctoral-audit, 2026-08-14): the closed set of colitur [status = Feast] sanctoral slugs whose bootstrapped [colour] was corrected against RG 124 (data/ef/adjustments.sexp's own audit-block @@ -1190,6 +1201,13 @@ let layer_c_reason (l : row) (c : row) diffs = then Some "C39" else if is_bissextile_shift_row l c ~month:m ~day:d && subset diffs [ Slug_f; Rank; Colour_f; First_f; Gospel_f ] then Some "C40" + (* C41 -- the Ascension-repeat rubric (see [ascension_week_slugs]'s own + citation above). SAME slug both sides ([Slug_f] never diffs here: the + six slugs already exist in lectio's own EF walkback, only their + resolved TEXT differs), rank/season/colour agree (both an ordinary + Class4 Paschaltide feria), and only the citation itself changes. *) + else if List.mem c.slug ascension_week_slugs && subset diffs [ First_f; Gospel_f ] + then Some "C41" (* C25 -- CLOSED, BVM Saturday Mass (2026-08-17), predicate removed: 0 rows. Its days are unoccupied IV-class Saturdays, so they carry RG 78's office and now RG 309(a)'s Mass for it, which answers before step 3's walkback diff --git a/test/test_golden.ml b/test/test_golden.ml index 3a6f3f5..c916a54 100644 --- a/test/test_golden.ml +++ b/test/test_golden.ml @@ -1281,6 +1281,33 @@ let test_readings_displaced_sunday_feria_known_divergent () = 2026 10 26 "2026-10-26 slug=ef-time-after-pentecost-22-monday first=Col 1:12-20. gospel=John 18:33-37" +(* ---- The Ascension-repeat rubric (celebrant-rubrics-phase1 Bug 2 fix, + 2026-08-22) ---- + + The Missale Romanum's own Proprium de Tempore carries an explicit + marginal rubric immediately after the Ascension's own Mass propers + (scan1.txt:20749-20754, both scans corroborate): "Diebus a feria VI post + Ascensionem usque ad feriam VI ante vigiliam Pentecostes inclusive, + dicitur Missa de festo Ascensionis" -- every feria without its own + proper, from the Friday after the Ascension through the Friday before + the Vigil of Pentecost, repeats the Ascension's own Mass (Acts 1:1-11 / + Mark 16:14-20), not the preceding Sunday's. Witnessed directly: the LMS + Ordo prints "Mass of the Ascension" literally on every affected day of + this shape across all three of its own fixture windows + (data/ef/expected-divergences-lms.sexp's own now-closed L2). + + 2031-05-23 is the exact day the bug report this task fixed was filed + against: the day after Ascension Thursday (2031-05-22, Easter+39), an + unoccupied Friday that step 3 used to walk back to + "ef-easter-sunday-6" -- the 5th Sunday after Easter, the wrong answer + -- instead of resolving at step 2 through the new + data/ef/lectionary.sexp entry. WHEN THIS PIN'S OWN VALUE WOULD REVERT TO + "Iac 1:22-27"/"Ioann 16:23-30" the fix has regressed; update it + deliberately then, never to make the suite pass again without checking + why. *) +let test_readings_ascension_week_repeat () = + check_readings ~msg:"the day after Ascension repeats the Ascension's own Mass, not the 5th Sunday after Easter's" + 2031 5 23 "2031-05-23 slug=ef-easter-6-friday first=Acts 1:1-11 gospel=Mark 16:14-20" (* ---- Rogation Wednesday (RG 87/88/89), movable-date-specs task ---- @@ -1596,6 +1623,8 @@ let suite = Alcotest.test_case "readings: displaced-Sunday feria pins M26 shape 2(b)'s KNOWN-WRONG walkback (2026-10-26)" `Quick test_readings_displaced_sunday_feria_known_divergent; + Alcotest.test_case "readings: the Ascension-repeat rubric, the reported bug's own date (2031-05-23)" `Quick + test_readings_ascension_week_repeat; Alcotest.test_case "RG87: Rogation Wednesday admitted (2024)" `Quick test_rogation_wednesday_admitted_2024; Alcotest.test_case "RG87/113: Rogation Wednesday yields to an impeded feast (2026)" `Quick diff --git a/test/test_lectionary.ml b/test/test_lectionary.ml index 7dbb253..59c739d 100644 --- a/test/test_lectionary.ml +++ b/test/test_lectionary.ml @@ -115,8 +115,14 @@ let test_ef_data_file_loads () = ([epiphanytide_opening_entries], +15); TWO hand-authored directly from the Missal, two major movable feasts with previously no entry at all ([movable_feast_entries], +2). - 116 + 1 + 6 + 1 + 2 + 3 + 2 + 15 + 2 = 148. *) - Alcotest.(check int) "entry count" 153 + 116 + 1 + 6 + 1 + 2 + 3 + 2 + 15 + 2 = 148. + celebrant-rubrics-phase1, Bug 2 (2026-08-22): SIX hand-authored + directly from the Missal's own marginal Ascension-repeat rubric + ([ascension_week_entries], +6, 153 -> 159) -- see that + function's own comment in bootstrap_lectionary.ml for the + citation and why the window's two Saturdays are deliberately + excluded. *) + Alcotest.(check int) "entry count" 159 (List.length (Lectionary.entries l)); (match Lectionary.find l (slug "ef-lent-1-monday") with | Some [ a; b ] -> @@ -179,6 +185,34 @@ let test_ef_data_file_loads () = scans). *) check_entry "ef-corpus-christi" "1 Cor 11:23-29" "John 6:56-59"; check_entry "ef-sacred-heart" "Eph 3:8-12, 14-19" "John 19:31-37"; + (* celebrant-rubrics-phase1, Bug 2: the Missal's own marginal rubric + after the Ascension's own Mass propers ("Diebus a feria VI post + Ascensionem usque ad feriam VI ante vigiliam Pentecostes + inclusive, dicitur Missa de festo Ascensionis") repeats the + Ascension's own citation on the ferias that would otherwise walk + back to the wrong Sunday. Two families pinned (the tail of + Ascension's own week; the following week), not merely one, the + same "more than one weekday" discipline this file already uses + for the Lent Ember pins above. *) + check_entry "ef-easter-6-friday" "Acts 1:1-11" "Mark 16:14-20"; + check_entry "ef-easter-7-monday" "Acts 1:1-11" "Mark 16:14-20"; + check_entry "ef-easter-7-friday" "Acts 1:1-11" "Mark 16:14-20"; + (* [ef-easter-6-saturday] keeps its own PRE-EXISTING entry, unchanged + by this task -- RG 78's votive Office of Our Lady always wins an + otherwise-unoccupied Class4 Saturday first ([readings]' own step + ordering runs that branch before step 2 is ever reached), so this + table's own value for that slug is dead data on shipped data, but + it was already there before this task and touching it is out of + scope. [ef-easter-7-saturday] must stay ABSENT instead: that civil + day is the Vigil of Pentecost, a NAMED day with its own slug and + Mass (temporal_ef.ml's own [named]), so the generic + [ef---] ferial slug this table's new + entries key off never gets produced there at all -- an entry + would be unreachable data [assert_reachable] would have refused + to emit, checked here too as a direct regression net. *) + (match Lectionary.find l (slug "ef-easter-7-saturday") with + | None -> () + | Some _ -> Alcotest.fail "ef-easter-7-saturday: must stay absent -- the Vigil of Pentecost, named, never a ferial slug"); check_entry "ef-nativity-vigil" "Rom 1:1-6" "Matt 1:18-21"; check_entry "ef-pentecost-ember-wed" "Acts 5:12-16" "John 6:44-52."; check_entry "ef-pentecost-ember-fri" "Joel 2:23-24; 26-27" "Luke 5:17-26"; diff --git a/test/test_lms_ordo.ml b/test/test_lms_ordo.ml index ed1c871..32ecfbc 100644 --- a/test/test_lms_ordo.ml +++ b/test/test_lms_ordo.ml @@ -333,7 +333,8 @@ let expected_named_sunday_override slug ~year = else None (* See Task 6's own [ascension_week_override] citation (test_lms_ordo.ml - history, expected-divergences-lms.sexp L2): STRUCTURAL, not a fixture + history, data/ef/expected-divergences-lms.sexp's own now-CLOSED L2, + celebrant-rubrics-phase1 Bug 2, 2026-08-22): STRUCTURAL, not a fixture artefact -- the Ascension is a fixed Easter+39, so every feria whose own [Preceding_sunday] fallback would otherwise resolve to a week-6/7 Sunday falls, in SOME years, between Ascension Thursday and the following @@ -341,11 +342,39 @@ let expected_named_sunday_override slug ~year = the finding: it is specifically the days AFTER Ascension (not merely "any week-6/7 Preceding_sunday day") that get this treatment -- see [expected_preceding_sunday_override]'s own citation for the Rogation - Monday counter-example that exposed the difference. [is_ascension_week] + Monday counter-example that exposed the difference. [is_after_ascension] below is the corrected predicate: the day's own DATE compared against - {!Computus.ascension} for its own year, not [n]. *) + {!Computus.ascension} for its own year, not [n]. + + FIXED (celebrant-rubrics-phase1, Bug 2): data/ef/lectionary.sexp's new + [ascension_week_entries] now answers these six ferial slugs directly at + step 2 (Own_slug), so [check_formulary_overrides]'s own [Preceding_sunday] + branch below never reaches them any more -- moved to a dedicated + [Own_slug] branch in that same function, which still asserts the Ordo's + override reads exactly [ascension_week_override], now as a genuine + confirmation that colitur's OWN citation matches (previously this + predicate only served to EXCLUDE the population from the general + Preceding_sunday mapping, because colitur had no correct answer to + compare). This constant and [is_after_ascension] itself are still load- + bearing for that confirmation -- kept, not deleted, the same "the + regression net survives its own fix" discipline + data/ef/expected-divergences-lms.sexp's own L6 note states for + [is_l6_rogation_colour]. *) let ascension_week_override = "Mass of the Ascension" +(* The exact six slugs data/ef/lectionary.sexp's own [ascension_week_entries] + (tools/bootstrap_lectionary.ml) now answers at step 2 -- gated on SLUG + IDENTITY, not merely [is_after_ascension date], because that date range + also covers "Dominica post Ascensionem" and the Vigil of Pentecost, both + genuinely [Own_slug] and both carrying their OWN, different citation, not + the Ascension's (caught live: an earlier, date-only version of this gate + wrongly flagged both as missing an Ordo override before this list was + added). *) +let ascension_week_slugs = + [ "ef-easter-6-friday"; "ef-easter-7-monday"; "ef-easter-7-tuesday"; "ef-easter-7-wednesday"; + "ef-easter-7-thursday"; "ef-easter-7-friday" + ] + (* Bounded ABOVE by Pentecost, not merely "later than Ascension" -- a bare lower bound is wrong for any date past Ascension in the SAME civil year (every date from June to December satisfies "> Ascension", which a @@ -431,7 +460,34 @@ let check_formulary_overrides ordo colitur = :: !bad | None -> bad := Printf.sprintf "%s: unmapped (colitur resumed %S) and Ordo shows no override" o.date slug :: !bad)) - | Some { MF.via = MF.Votive; _ } | Some { MF.via = MF.Own_slug; _ } | None -> ()) + | Some { MF.via = MF.Own_slug; said } -> ( + (* celebrant-rubrics-phase1, Bug 2 fix: the six Ascension-week + ferias moved from [Preceding_sunday] (the branch above, which + used to special-case them via [is_after_ascension]) to + [Own_slug] -- data/ef/lectionary.sexp's own + [ascension_week_entries] now answers at step 2, before step 3 + is ever reached. Checked HERE, not merely left to fall through + silently the way every OTHER [Own_slug] day already does + (RG 299's ordinary case, a real proper Mass, needs no Ordo + cross-check because nothing about it is adjudicated): this is + the one [Own_slug] population this suite has an OUTSIDE + witness for, and losing that check when the fix landed would + have been a silent regression net, not merely dead code -- the + Ordo's own override text must still read "Mass of the + Ascension" on exactly these days. *) + let slug = match said with Some s -> Colitur_kernel.Slug.to_string s | None -> "" in + if List.mem slug ascension_week_slugs then + match o.formulary_override with + | Some got when String.equal got ascension_week_override -> incr ascension_week + | Some got -> + bad := + Printf.sprintf "%s: colitur resolved %S via Own_slug (after Ascension), Ordo shows %S, not %S" + o.date slug got ascension_week_override + :: !bad + | None -> + bad := Printf.sprintf "%s: colitur resolved %S via Own_slug (after Ascension), Ordo shows no override" + o.date slug :: !bad) + | Some { MF.via = MF.Votive; _ } | None -> ()) pairs; { fc_bad = List.rev !bad; fc_proper = !proper; fc_common = !common; fc_preceding_sunday = !preceding_sunday; fc_ascension_week = !ascension_week } @@ -733,7 +789,7 @@ let make_suite ~label ~fixture_path ~fixture_sha256 ~window_first ~window_last ~ Alcotest.(check int) (Printf.sprintf "%d Preceding_sunday days in the window" expected_preceding_sunday) expected_preceding_sunday r.fc_preceding_sunday; Alcotest.(check int) - (Printf.sprintf "%d Preceding_sunday days fall in the Ascension-week exclusion, no more, no fewer" + (Printf.sprintf "%d Ascension-week days resolve via Own_slug and match the Ordo's own override, no more, no fewer" expected_ascension_week) expected_ascension_week r.fc_ascension_week in @@ -797,19 +853,38 @@ let suite_2023_2024 = Own_slug is excluded). Matthias himself moves to 25 February, an I-class Sunday that admits him not even as a commemoration (RG16(a)), so his own Mass is not said anywhere in this window any more. *) - ~expected_bvm_votive:12 ~expected_proper:181 ~expected_common:2 ~expected_preceding_sunday:61 + (* expected_preceding_sunday 61 -> 60 (celebrant-rubrics-phase1, Bug 2 + fix, 2026-08-22): the window's own single Ascension-week day + (2024-05-06 was BEFORE Ascension that year and never counted here in + the first place -- see [ascension_week_override]'s own citation; the + real Ascension-week day this window carries is elsewhere in May) + now resolves via Own_slug (step 2, data/ef/lectionary.sexp's new + [ascension_week_entries]), not Preceding_sunday -- it leaves this + bucket's population the same way a Proper day already does, while + expected_ascension_week itself is UNCHANGED (1): the same day is + still counted, just via check_formulary_overrides' own new + Own_slug branch instead of its Preceding_sunday one. *) + ~expected_bvm_votive:12 ~expected_proper:181 ~expected_common:2 ~expected_preceding_sunday:60 ~expected_ascension_week:1 ~expected_gloria_l5:5 ~expected_gloria_l6:0 let suite_2024_2025 = make_suite ~label:"lms-ordo-2024-2025" ~fixture_path:"fixtures/lms-ordo-2024-2025.sexp" ~fixture_sha256:"da817b75c5bf40ed3be1d5f6890b199705e02ce4d42111253ab8547bccabc3f7" ~window_first:"2024-11-27" ~window_last:"2025-12-31" ~year_lo:2023 ~year_hi:2026 ~allow_list_path ~expected_rows:400 - ~expected_bvm_votive:14 ~expected_proper:179 ~expected_common:2 ~expected_preceding_sunday:66 + (* expected_preceding_sunday 66 -> 63 (celebrant-rubrics-phase1, Bug 2 + fix): this window's own three Ascension-week days move from + Preceding_sunday to Own_slug, the same reasoning as the 2023-2024 + window's own note above; expected_ascension_week stays 3. *) + ~expected_bvm_votive:14 ~expected_proper:179 ~expected_common:2 ~expected_preceding_sunday:63 ~expected_ascension_week:3 ~expected_gloria_l5:5 ~expected_gloria_l6:0 let suite_2025_2026 = make_suite ~label:"lms-ordo-2025-2026" ~fixture_path:"fixtures/lms-ordo-2025-2026.sexp" ~fixture_sha256:"8839a61e0c7d1e6c8326114f4f45a5c183551287a88f4ed01127154add6ae5a5" ~window_first:"2025-11-28" ~window_last:"2026-12-31" ~year_lo:2024 ~year_hi:2027 ~allow_list_path ~expected_rows:399 - ~expected_bvm_votive:13 ~expected_proper:174 ~expected_common:2 ~expected_preceding_sunday:68 + (* expected_preceding_sunday 68 -> 66 (celebrant-rubrics-phase1, Bug 2 + fix): this window's own two Ascension-week days move from + Preceding_sunday to Own_slug, the same reasoning as the 2023-2024 + window's own note above; expected_ascension_week stays 2. *) + ~expected_bvm_votive:13 ~expected_proper:174 ~expected_common:2 ~expected_preceding_sunday:66 ~expected_ascension_week:2 ~expected_gloria_l5:6 ~expected_gloria_l6:0 diff --git a/test/test_oracle.ml b/test/test_oracle.ml index f1d1a89..01938e1 100644 --- a/test/test_oracle.ml +++ b/test/test_oracle.ml @@ -1381,6 +1381,33 @@ let m26_dates = citation fields are not, discovered by this task). *) let m27_dates = [ "2026-12-25"; "2027-12-25" ] +(* M31 (celebrant-rubrics-phase1, Bug 2, 2026-08-22) -- the six ferias + between the Ascension and the Friday before the Vigil of Pentecost that + repeat the Ascension's own Mass by an explicit marginal rubric in the + Proprium de Tempore (data/ef/lectionary.sexp's own [ascension_week_ + entries], full citation there and in this file's sibling + data/ef/expected-divergences.sexp's own C41). Only three of the six + civil dates this window's own [c_date] range can reach are actually + unoccupied in 2026-2027: 2026-05-21, 2026-05-22 and 2027-05-14 (the + other three fall to a real sanctoral feast both engines already agree + on). missalemeum -- Divinum Officium's own lineage, the SAME lineage + lectio inherited this defect from before colitur's own bootstrap -- + still walks these ferias back to the preceding Sunday's Mass, the + pre-fix answer colitur itself used to give; [Observed_identity_ + unresolved] fires alongside because none of the three is a SANCTORAL- + origin day (the mapping this whole file's own header describes cannot + name a TEMPORAL office's title either way, unrelated to this cause). *) +let m31_dates = [ "2026-05-21"; "2026-05-22"; "2027-05-14" ] + +(* The exact six slugs data/ef/lectionary.sexp's own [ascension_week_entries] + answers -- reused by [classify_2038]/[classify_2035] below, which key on + slug identity rather than a date list (those two live windows are not + scoped the way the 2026-2027 fixture is). *) +let ascension_week_slugs = + [ "ef-easter-6-friday"; "ef-easter-7-monday"; "ef-easter-7-tuesday"; "ef-easter-7-wednesday"; + "ef-easter-7-thursday"; "ef-easter-7-friday" + ] + (* The oracle's own row went unused when M2 -- its one reader, via [o.o_title] -- was closed/removed (see the comment above [m1_dates]), and was kept as a named, typed parameter rather than dropped from the @@ -1512,6 +1539,8 @@ let layer_m_reason (c : colitur_row) (o : oracle_row) diffs = [ Rank; Colour_f; Comm_presence; Comm_count; Observed_identity_mismatch; Comm_identity_unresolved; First_mismatch; Gospel_mismatch ] then Some "M30" + else if List.mem c.c_date m31_dates && subset diffs [ Observed_identity_unresolved; First_mismatch; Gospel_mismatch ] + then Some "M31" else None (* ---------------------------------------------------------------------- *) @@ -1992,6 +2021,16 @@ let classify_2038 (c : colitur_row) (o : oracle_row) diffs = List.mem c.c_date [ "2035-08-09"; "2035-08-14"; "2038-08-09"; "2038-08-14" ] && diffs = [ Colour_f ] then Some "VIGIL-COLOUR-RG128 (M29, colitur; see C37)" + (* The Ascension-repeat rubric (celebrant-rubrics-phase1, Bug 2; see M31 + in this file's own 2026-2027 [layer_m_reason] and C41 in + data/ef/expected-divergences.sexp for the full citation). 2038 carries + three unoccupied instances the 2026-2027 window did not (2038-06-07/ + 08/09, all week-7 weekdays); 2035 carries one (2035-05-08). Gated on + colitur's own slug rather than on the date list this window's sibling + windows use, the same style [m21_2038_slugs] already establishes for + a live-window slug-keyed class. *) + else if List.mem c.c_observed_slug ascension_week_slugs && diffs = [ First_mismatch; Gospel_mismatch ] then + Some "ASCENSION-WEEK-REPEAT (M31, colitur; register, Bug 2)" else None (* COMMEMORATIONS join the live-window comparison (2026-08-18). @@ -2129,7 +2168,13 @@ let test_2038_class_counts () = ("MISSAL-TWO-PART-CITATION (register 6.9)", 1); ("COMM-IDENTITY-UNRESOLVED (temporal-origin, no English name -- M15's limit)", 2); ("PERPETUA-COMMON (register 6.8)", 1); - ("PETER-COMPANION-ABSENT-UPSTREAM (M19)", 1) + ("PETER-COMPANION-ABSENT-UPSTREAM (M19)", 1); + (* celebrant-rubrics-phase1, Bug 2: 2038-06-07/08/09 (the Monday, + Tuesday and Wednesday of the week after the Sunday after the + Ascension) are unoccupied that year, all three landing on the + Ascension-repeat rubric -- see M31 (2026-2027 window) and C41 + (data/ef/expected-divergences.sexp) for the full citation. *) + ("ASCENSION-WEEK-REPEAT (M31, colitur; register, Bug 2)", 3) ] |> List.sort compare in diff --git a/tools/bootstrap_lectionary.ml b/tools/bootstrap_lectionary.ml index 7df290b..1e9b8ed 100644 --- a/tools/bootstrap_lectionary.ml +++ b/tools/bootstrap_lectionary.ml @@ -637,6 +637,75 @@ let trinity_week_entries = lectionary has been bitten by before. *) [ "monday"; "tuesday"; "wednesday"; "friday"; "saturday" ] +(* RG 299's own escape clause, second instance (celebrant-rubrics-phase1, + Bug 2, 2026-08-22). The Proprium de Tempore carries an explicit + marginal rubric immediately after the Ascension's own Mass propers, + before "Dominica post Ascensionem" begins (scan1.txt:20749-20754, both + scans corroborate): "Diebus a feria VI post Ascensionem usque ad + feriam VI ante vigiliam Pentecostes inclusive, dicitur Missa de festo + Ascensionis, cum Gloria et praefatione de Ascensione, sine Credo et + Communicantes proprio" -- on the days from the Friday after the + Ascension until the Friday before the Vigil of Pentecost INCLUSIVE, + the MASS OF THE FEAST OF THE ASCENSION is said (with the Gloria and + the Ascension preface, without the Creed and the proper + Communicantes). Corroborated independently by RG 490(b) (LT.txt:3981- + 3985), which assigns the Ascension preface "tamquam de Tempore" to + every Mass in that same window lacking a proper preface of its own -- + consistent only if the Mass repeated there is the Ascension's own, + not a numbered Sunday's (which would need no preface override at + all). + + Witnessed directly, not merely inferred from the rubric: the LMS Ordo + prints "Mass of the Ascension" literally, across all three fixture + windows this project has built (2023-2024: 1 day; 2024-2025: 3 days; + 2025-2026: 2 days -- data/ef/expected-divergences-lms.sexp's own L2, + closed by this entry), on EVERY affected day in BOTH the remainder of + Ascension's own week and the following week, not only the first -- + ruling out the alternative reading that the second week instead + resumes "Dominica post Ascensionem"'s own Mass. The FIUV Ordo's own + title convention for these days (2025-2026 fixture, 2026-05-21/22, + "Feria V/VI Dom. post Ascensionem, De ea") could look like the + opposite at a glance -- it is not: FIUV's title names which WEEK a + feria belongs to (a bookkeeping label, the same role colitur's own + week-numbered slug plays), while its own [praef] field for those + exact two days independently reads "Ascensionis", confirming the Mass + actually said is still the Ascension's, exactly as the marginal + rubric and RG 490(b) both require. + + The window's two Saturdays (Easter+41, Easter+48) are DELIBERATELY + NOT given entries here. Easter+48 is the Vigil of Pentecost, a named + day with its own Mass ({!Rite_ef.Temporal_ef.named}), outside the + rubric's own "usque ad feriam VI" upper bound. Easter+41 is an + ordinary IV-class Saturday, so {!Rite_ef.Lectionary_ef.readings}'s + own RG 78/RG 309(a) votive-Mass-of-Our-Lady-on-Saturday branch ALWAYS + intercepts it before step 2 is ever reached (checked directly: + [is_bvm_saturday_office] fires unconditionally on any unoccupied + Class4 Saturday, which every ordinary Paschaltide Saturday is) -- an + entry for either Saturday slug would be dead data that + [assert_reachable] cannot catch (both slugs it would name ARE real, + reachable Temporal_ef offices; the shadowing happens one level up, in + [readings]' own step ordering, not in slug reachability). + + Six ferias, matching the Ascension's own citation already given above + (Act. 1, 1-11 / Marc. 16, 14-20, scan1.txt:20701-20730, + [ef-ascension]'s own entry): the one remaining non-Saturday day of + Ascension's own week (Easter+40) and the five weekdays of the + following week (Easter+43..47), bounded above by that week's own + Friday -- the Saturday after it is the Vigil of Pentecost, named, + never reaching this table. *) +let ascension_week_citations = pair ~first:"Acts 1:1-11" ~gospel:"Mark 16:14-20" + +let ascension_week_entries = + List.map + (fun slug -> (slug_or_die slug, ascension_week_citations)) + [ "ef-easter-6-friday"; + "ef-easter-7-monday"; + "ef-easter-7-tuesday"; + "ef-easter-7-wednesday"; + "ef-easter-7-thursday"; + "ef-easter-7-friday" + ] + let epiphanytide_opening_entries = List.concat_map (fun (family, wds, cs) -> @@ -789,6 +858,7 @@ let () = translated @ vigil_entries @ holy_week_entries @ passion_tuesday_entry @ ember_saturday_corrections @ nativity_octave_entries @ holy_name_entries @ epiphanytide_opening_entries @ trinity_week_entries @ movable_feast_entries + @ ascension_week_entries in assert_reachable entries; let lect = -- cgit v1.3 From 0d061abc7cc5cdc51ded6ee69e00e187813f5e1b Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Mon, 24 Aug 2026 16:16:59 +0200 Subject: feat(ordo): wire the extraordinaryform.org preface column in as a third witness Extends the preface comparison (RG 482-499) with a third, independent publisher, extraordinaryform.org's three annual Ordo editions (2024-2025, 2025-2026, 2026-2027), previously declined for two reasons that are now resolved: - "Advent" is not a preface: RG 494(b) grants the Trinity preface on every Advent SUNDAY, RG 498 the residual Common on every Advent FERIA; this source's own "Advent" label covers both indiscriminately (confirmed live on all 11 non-impeded Advent Sundays in the corpus). Classified by the day's own civil weekday, not a static table. - The known Vigil-of-St-Lawrence gap is reconfirmed, with a nuance not present in the earlier audits: colitur's own RG33-third-trigger now omits the vigil in some years too, so the corpus's gap and colitur's answer coincide in 2025 (a full match, not a coincidence) while 2027 still shows the classic identity-wrong-but-preface-invisible shape. Re-derives the known menu-trap office filter (Requiem-skip, "and "-chain) against the live JSON and finds a second, general pattern: "Saturday of Our Lady" (RG78's BVM Saturday Office), whenever listed, is unconditionally the office -- checked exhaustively across all 38 instances in the corpus, zero counter-examples. A third, generic "absorption" rule was deliberately not built: it would resolve 2 of the 11 residual divergences but wrongly misfires on a structurally identical but semantically different shape (an optional Rogation-day Mass option). The JSON's own extraction carries a genuine classifier gap: parse_ordo.py's hardcoded PREFACES set omits "Christ the King", misfiling it into comms; recovered in the generator, not left blank. 11 of 1088 comparable rows diverge, resolving to 7 adjudicated root causes (E1-E7): two Commemoration_only Marian titles reduced to commemorations (Mt Carmel, Ransom), two genuine sanctoral data gaps cross-confirmed absent by the FIUV/LMS witnesses (Miraculous Medal, St John before the Latin Gate), two single-witnessed efdotorg outliers against FIUV/LMS agreement (St Michael's Dedication, All Saints on a Sunday), and one isolated source labelling slip. Mutation-tested: corrupting the RG495 BVM-Saturday clause reddens 9 tests across this new layer and both existing Ordo witnesses. Per-edition agreement: 358/363 (2024-2025), 358/363 (2025-2026), 361/362 (2026-2027). --- data/ef/expected-divergences-efdotorg.sexp | 175 +++++++++++++ test/dune | 4 + test/fixtures/efdotorg-ordo-2024-2025.sexp | 398 ++++++++++++++++++++++++++++ test/fixtures/efdotorg-ordo-2025-2026.sexp | 398 ++++++++++++++++++++++++++++ test/fixtures/efdotorg-ordo-2026-2027.sexp | 398 ++++++++++++++++++++++++++++ test/test_colitur.ml | 2 + test/test_efdotorg_ordo.ml | 403 +++++++++++++++++++++++++++++ tools/extract_efdotorg_ordo.py | 336 ++++++++++++++++++++++++ 8 files changed, 2114 insertions(+) create mode 100644 data/ef/expected-divergences-efdotorg.sexp create mode 100644 test/fixtures/efdotorg-ordo-2024-2025.sexp create mode 100644 test/fixtures/efdotorg-ordo-2025-2026.sexp create mode 100644 test/fixtures/efdotorg-ordo-2026-2027.sexp create mode 100644 test/test_efdotorg_ordo.ml create mode 100644 tools/extract_efdotorg_ordo.py (limited to 'data/ef') diff --git a/data/ef/expected-divergences-efdotorg.sexp b/data/ef/expected-divergences-efdotorg.sexp new file mode 100644 index 0000000..7c9eea7 --- /dev/null +++ b/data/ef/expected-divergences-efdotorg.sexp @@ -0,0 +1,175 @@ +; data/ef/expected-divergences-efdotorg.sexp -- efdotorg-preface task +; (2026-08-24-colitur-celebrant-rubrics-phase1)'s cited allow-list for the +; extraordinaryform.org Ordo preface comparison (test/test_efdotorg_ordo.ml), +; three editions (2024-2025, 2025-2026, 2026-2027), 1091 day-rows total. +; +; A SEPARATE file from data/ef/expected-divergences.sexp (lectio), +; data/ef/expected-divergences-missalemeum.sexp (missalemeum/Divinum- +; Officium lineage), data/ef/expected-divergences-lms.sexp (Latin Mass +; Society, England & Wales, Peter Day-Milne) and +; data/ef/expected-divergences-fiuv.sexp (FIUV, universal, Joseph Shaw): +; this is a FIFTH lineage, a third distinct publisher/compiler. +; +; Two things resolved BEFORE any divergence below was adjudicated, per the +; task's own "characterise first" discipline -- neither is an allow-list +; entry, because neither is a disagreement: +; - "Advent" is not a static mapping (RG 494(b) grants Trinity on every +; Advent SUNDAY, RG 498 the residual Common on every Advent FERIA) -- +; see tools/extract_efdotorg_ordo.py's own header, finding 3, and +; test_efdotorg_ordo.ml's own [classify_praef]. Zero mismatches. +; - The "Christ the King" classifier gap in parse_ordo.py's own hardcoded +; PREFACES set is RECOVERED in the fixture generator (finding 2), not +; allow-listed. +; +; Of 1088 comparable rows (1091 minus Good Friday x3 minus the one source +; gap, 2027-03-03), 11 diverge, all found ONLY after building +; tools/extract_efdotorg_ordo.py's own Rule A (finding 6: "Saturday of Our +; Lady", whenever listed, IS the office, checked exhaustively across all +; 38 instances in the corpus) -- without Rule A the apparent divergence +; count was far higher (dominated by the BVM-Saturday-Office population), +; which is why Rule A belongs in the generator, not the allow-list: it is +; a general, well-evidenced STRUCTURAL rule, not a per-date adjudication. +; +; The 11 residual rows resolve to exactly SEVEN root causes, E1-E7 below. + +; E1 -- colitur correct. "Our Lady of Mt. Carmel" (16 July) is +; `Commemoration_only` status in data/ef/sanctoral.sexp (confirmed +; directly: `grep our-lady-of-mt-carmel data/ef/sanctoral.sexp`, and +; already cited elsewhere in this codebase -- +; lib/rites/rite_ef/precedence_ef.ml's own `marian_slugs`/RG112(d) +; citation names it explicitly), so it can NEVER be the day's own +; OBSERVED office in colitur's model -- only ever a commemoration. This +; source nonetheless lists it as a standalone Mass option (the same +; "priest's menu, not office order" convention +; .superpowers/ordo-class-report.md already established for the votive +; Requiem population), with the day's real office (an ordinary feria/ +; resumed Sunday) listed alongside, its own `comms` field naming Mt +; Carmel as what IT commemorates -- exactly matching colitur's own +; `+our-lady-of-mt-carmel` commemoration on all three dates. Fires once +; per edition, unchanged: 2025-07-16, 2026-07-16, 2027-07-16. +((id E1) (citation "RG91 table (Commemoration_only has no table row); data/ef/sanctoral.sexp") + (verdict colitur) + (note "Our Lady of Mt Carmel (16 July) is Commemoration_only-status data, never the observed office; the corpus lists it as an optional votive Mass regardless. Fires 2025-07-16, 2026-07-16, 2027-07-16 (one row per edition).") + (expected_rows 1)) + + ; E2 -- colitur correct, the SAME shape as E1. "Our Lady of Ransom" (24 + ; September) is also `Commemoration_only` status + ; (data/ef/sanctoral.sexp), and CLAUDE.md's own record already notes it + ; "forces the September Ember Saturday every time, by construction" -- + ; confirmed live here: the true office on every instance checked (2025, + ; 2027) is the September Ember day itself (Ember Wednesday/Friday), with + ; Ransom correctly reduced to ITS OWN commemoration -- matching colitur + ; exactly and producing NO divergence those two years. Only 2026-09-24 + ; diverges, because that entry happens to be listed first in the + ; option list with an empty comms field of its own while the true + ; office (the Ember Saturday) is a separate, later entry -- the same + ; "named votive Mass listed ahead of the real office" shape as E1, just + ; without a Saturday-of-Our-Lady-style structural marker to catch it + ; generically. + ((id E2) (citation "RG91 table (Commemoration_only has no table row); data/ef/sanctoral.sexp; September Ember Saturday, RG26") + (verdict colitur) + (note "Our Lady of Ransom (24 September) is Commemoration_only-status data; the September Ember Saturday always wins the day outright. Fires once, 2026-09-24 (2025 and 2027's own 24 September already match colitur without needing this entry -- the Ember day is listed first there).") + (expected_rows 1)) + + ; E3 -- colitur correct (a genuine sanctoral DATA GAP, not a rule bug). + ; "Our Lady of the Miraculous Medal" (27 November) does not appear + ; anywhere in data/ef/sanctoral.sexp (`grep -i medal` / `grep -i + ; miraculous`: zero hits) -- CROSS-CONFIRMED independently by BOTH + ; already-validated witnesses on the identical civil date: the FIUV + ; Ordo (test/fixtures/fiuv-ordo-2025-2026.sexp, 2025-11-27: plain + ; "IV cl." feria, "comm.") and the LMS Ordo (both the 2023-2024 and + ; 2024-2025 editions, 2024-11-27/2025-11-27: "Mass of 24th & Last + ; Sunday After Pentecost", "Common Pr") show no such feast at all. Not a + ; feast of the UNIVERSAL 1962 General Roman Calendar (the Miraculous + ; Medal apparition, 1830, is a devotional/particular-calendar + ; commemoration in some places, never added to the GENERAL calendar) -- + ; worth flagging alongside CLAUDE.md's own existing list of missing + ; sanctoral entries (Agnes secundo, Boniface 14 May, Evaristus, + ; Theodore) as a FIFTH candidate, but NOT fixed here: out of this task's + ; own scope (preface-comparison wiring, not sanctoral completeness), and + ; unlike those four, this one is independently corroborated as + ; genuinely absent from the UNIVERSAL calendar, not merely missing from + ; colitur's own bootstrap. Fires 2025-11-27, 2026-11-27 (one row per + ; edition where it recurs; 2027-11-27 does not reach this entry at all). + ((id E3) (citation "data/ef/sanctoral.sexp (no entry); cross-confirmed absent in both the FIUV and LMS Ordos on the same civil date") + (verdict colitur) + (note "Our Lady of the Miraculous Medal (27 November) is genuinely absent from the universal 1962 calendar colitur models -- not merely a colitur bootstrap gap. Fires 2025-11-27, 2026-11-27.") + (expected_rows 1)) + + ; E4 -- colitur correct (a second genuine sanctoral DATA GAP). "St. John + ; before the Latin Gate" (6 May) is likewise absent from + ; data/ef/sanctoral.sexp entirely -- CROSS-CONFIRMED by the LMS Ordo on + ; the identical civil date in TWO separate editions + ; (test/fixtures/lms-ordo-2023-2024.sexp, 2024-05-06, and + ; lms-ordo-2024-2025.sexp, 2025-05-06): both show only "Mass of Nth + ; Sunday after Easter", "Pr of Easter" -- matching colitur's own answer + ; exactly, with no trace of this feast. A genuine SIXTH candidate for + ; CLAUDE.md's known-missing-sanctoral-entries list, not fixed here for + ; the same out-of-scope reason as E3. Fires 2025-05-06, 2026-05-06; + ; 2027-05-06 does not diverge (that date is a Saturday, and Rule A's own + ; "Saturday of Our Lady" preference resolves it correctly without ever + ; needing to know this feast is missing). + ((id E4) (citation "data/ef/sanctoral.sexp (no entry); cross-confirmed absent in the LMS Ordo (2024-05-06 and 2025-05-06) on the same civil date") + (verdict colitur) + (note "St John before the Latin Gate (6 May) is genuinely absent from the universal 1962 calendar colitur models. Fires 2025-05-06, 2026-05-06 (2027-05-06 is a Saturday and is resolved by Rule A instead).") + (expected_rows 1)) + + ; E5 -- colitur correct, extraordinaryform.org is the OUTLIER. St + ; Michael's Dedication (29 September) has no dedicated preface among RG + ; 484-497's fourteen, so RG 482's chain falls through to RG 498's Common + ; -- and this is DOUBLY corroborated already, in + ; lib/rites/rite_ef/rubrics_ef.ml's own [preface] header: the FIUV Ordo + ; reads "comm. vel de Angelis" and the LMS Ordo reads "Pr of the Angels + ; or Common Pr" for this exact feast ("of the Angels" being one of the + ; several non-RG-482 "extra" preface names both those sources are + ; already documented to carry, alongside the genuine Common answer). + ; extraordinaryform.org's bare "Holy Trinity" is a single, uncorroborated + ; reading against two independent, already-validated witnesses that both + ; agree with colitur. Fires once, 2025-09-29 (the only occurrence in + ; this corpus where 29 September is NOT itself a Sunday reaching RG + ; 494(b) by a different route -- see E6 for that shape). + ((id E5) (citation "RG482/RG498; lib/rites/rite_ef/rubrics_ef.ml's own [preface], corroborated by both the FIUV and LMS Ordos on this exact feast") + (verdict colitur) + (note "St Michael's Dedication (29 September 2025) has no dedicated preface; colitur's Common answer is independently confirmed by both the FIUV and LMS Ordos (\"... or Common Pr\"/\"comm. vel ...\"). extraordinaryform.org's bare \"Holy Trinity\" is single-witnessed and outvoted.") + (expected_rows 1)) + + ; E6 -- colitur correct, extraordinaryform.org is the OUTLIER, the SAME + ; shape as E5 but for RG 494(b)'s own Sunday grant rather than RG 498. + ; All Saints falls on a Sunday in 2026 (confirmed: the corpus's own + ; entry carries `comms: ["Twenty-third Sunday after Pentecost"]`, + ; matching colitur's own `+ef-time-after-pentecost-sunday-23`), so RG + ; 494(b) ("in omnibus dominicis II classis... praefatio de Ss.ma + ; Trinitate") grants the TRINITY preface -- independently confirmed by + ; the FIUV Ordo on the SAME civil date (test/fixtures/fiuv-ordo-2025- + ; 2026.sexp, 2026-11-01: "Trinit. vel de Omnibus Sanctis et Patronis.", + ; Trinity again being the genuine RG-482 answer and "of All Saints and + ; Patrons" the same kind of non-RG-482 extra E5 already documents). + ; extraordinaryform.org's bare "Common" is single-witnessed here too. + ; Fires once, 2026-11-01 (the only Sunday occurrence of All Saints this + ; corpus's own window covers). + ((id E6) (citation "RG494(b); test/fixtures/fiuv-ordo-2025-2026.sexp, 2026-11-01 (\"Trinit. vel de Omnibus Sanctis...\")") + (verdict colitur) + (note "All Saints falls on a Sunday in 2026, so RG494(b) grants the Trinity preface -- independently confirmed by the FIUV Ordo on the same date. extraordinaryform.org's bare \"Common\" is single-witnessed and outvoted.") + (expected_rows 1)) + + ; E7 -- a single-row SOURCE DATA INCONSISTENCY, not a rule question. + ; 2025-11-29 is a "Saturday of Our Lady" day like the other 37 in this + ; corpus (Rule A correctly selects it as the office, matching colitur's + ; own BVM answer on office IDENTITY), but this ONE row's own `preface` + ; field reads "Common" where every other "Saturday of Our Lady" entry + ; in the whole corpus reads "BVM" (checked directly: 37 of 38 read + ; "BVM", this is the sole exception) -- an isolated compiler slip in the + ; source, not a pattern. + ((id E7) (citation "internal corpus consistency check: 37 of 38 \"Saturday of Our Lady\" entries read \"BVM\"; this is the sole exception") + (verdict colitur) + (note "2025-11-29's own \"Saturday of Our Lady\" entry reads \"Common\" where every other instance in the corpus (37 of 38) reads \"BVM\" -- an isolated source labelling slip, not a rule disagreement.") + (expected_rows 1)) + +; Per-edition agreement, reported separately, never merged (each row count +; is 364 total minus that edition's own no-praef coverage bucket -- Good +; Friday plus, for 2026-2027 only, the known 2027-03-03 source gap): +; 2024-2025: 358/363 (E1 x1, E3 x1, E4 x1, E5 x1, E7 x1) +; 2025-2026: 358/363 (E1 x1, E2 x1, E3 x1, E4 x1, E6 x1) +; 2026-2027: 361/362 (E1 x1) +; Full account: .superpowers/sdd/2026-08-21-colitur-celebrant-rubrics- +; phase1/efdotorg-preface-report.md. diff --git a/test/dune b/test/dune index 374fa8f..840f0d1 100644 --- a/test/dune +++ b/test/dune @@ -11,6 +11,7 @@ ../data/ef/expected-divergences-missalemeum.sexp ../data/ef/expected-divergences-lms.sexp ../data/ef/expected-divergences-fiuv.sexp + ../data/ef/expected-divergences-efdotorg.sexp ../data/ef/lectionary.sexp ../data/ef/commons.sexp ../data/ef/examples/diocesan-example.sexp @@ -22,6 +23,9 @@ fixtures/lms-ordo-2024-2025.sexp fixtures/lms-ordo-2025-2026.sexp fixtures/fiuv-ordo-2025-2026.sexp + fixtures/efdotorg-ordo-2024-2025.sexp + fixtures/efdotorg-ordo-2025-2026.sexp + fixtures/efdotorg-ordo-2026-2027.sexp ../templates/ef/ordo.tex ../templates/ef/ordo.ms ../templates/ef/ordo.html diff --git a/test/fixtures/efdotorg-ordo-2024-2025.sexp b/test/fixtures/efdotorg-ordo-2024-2025.sexp new file mode 100644 index 0000000..be69daa --- /dev/null +++ b/test/fixtures/efdotorg-ordo-2024-2025.sexp @@ -0,0 +1,398 @@ +; test/fixtures/efdotorg-ordo-2024-2025.sexp -- efdotorg-preface task +; (2026-08-24-colitur-celebrant-rubrics-phase1): the THIRD independent +; preface witness (RG 482-499), extraordinaryform.org's 2024-2025 Ordo, +; extracted from the already-parsed, fidelity-audited corpus +; docs/research/ordo/ordo-2024-2027.json (SHA-256 18a417fb8b30dc438c3f12f64b43dfdf5e2e9313857f2eccd04bf02072ca7e3c) rather than +; re-parsed from the PDF -- see tools/extract_efdotorg_ordo.py's own +; header for the full characterisation this fixture rests on (the menu- +; trap office filter, the Christ-the-King classifier-gap recovery, why +; "Advent" is not baked into a single mapping here, the known Vigil-of- +; St-Lawrence gap, and the two source-PDF defects that turn out not to +; touch this field). +; +; Generator: tools/extract_efdotorg_ordo.py -- do not hand-edit; re-run +; against the same JSON and commit the diff instead. +; python3 tools/extract_efdotorg_ordo.py docs/research/ordo/ordo-2024-2027.json test/fixtures +; +; Source PDF (gitignored, CLAUDE.md: "docs/ is gitignored", see +; docs/research/ordo/SHA256SUMS for its own hash): 2024-2025Ordo.pdf, +; extraordinaryform.org. +; +; COVERAGE: 364 day-rows, 2024-12-01..2025-11-29 (this edition's own civil-date +; span, re-derived from the JSON's own seams -- see the generator's own +; EDITIONS comment). 0 row(s) are a genuine SOURCE GAP (2027-03-03 +; only, a PDF row-drop, ordo-fidelity-report.md) -- mass/cls/colour/praef +; all absent, the same shape a structurally blank day (Good Friday) uses. +; 1 further row(s) have mass/cls/colour but no praef at all +; (Good Friday -- RG 28, no Mass in the 1955-restored Holy Week). +; +; Each row's `praef` is RAW TEXT from the day's own OFFICE (after the +; menu-trap filter, with the Christ-the-King recovery already applied) -- +; classified against {!Colitur_kernel.Preface.t} by +; test/test_efdotorg_ordo.ml, not here. +( + ((date 2024-12-01) (mass ("First Sunday of Advent")) (cls (1)) (colour ("violet")) (praef ("Advent"))) + ((date 2024-12-02) (mass ("St. Bibiana, Virgin & Martyr")) (cls (3)) (colour ("red")) (praef ("Advent"))) + ((date 2024-12-03) (mass ("St. Francis Xavier, Confessor")) (cls (3)) (colour ("white")) (praef ("Advent"))) + ((date 2024-12-04) (mass ("St. Peter Chrysologus, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Advent"))) + ((date 2024-12-05) (mass ("Feria \226\128\147 First Sunday of Advent")) (cls (3)) (colour ("violet")) (praef ("Advent"))) + ((date 2024-12-06) (mass ("St. Nicholas, Confessor & Bishop")) (cls (3)) (colour ("white")) (praef ("Advent"))) + ((date 2024-12-07) (mass ("St. Ambrose, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Advent"))) + ((date 2024-12-08) (mass ("Immaculate Conception")) (cls (1)) (colour ("white")) (praef ("BVM"))) + ((date 2024-12-09) (mass ("Feria \226\128\147 Second Sunday of Advent")) (cls (3)) (colour ("violet")) (praef ("Advent"))) + ((date 2024-12-10) (mass ("Feria \226\128\147 Second Sunday of Advent")) (cls (3)) (colour ("violet")) (praef ("Advent"))) + ((date 2024-12-11) (mass ("St. Damasus I, Pope")) (cls (3)) (colour ("white")) (praef ("Advent"))) + ((date 2024-12-12) (mass ("Feria \226\128\147 Second Sunday of Advent")) (cls (3)) (colour ("violet")) (praef ("Advent"))) + ((date 2024-12-13) (mass ("St. Lucy, Virgin & Martyr")) (cls (3)) (colour ("red")) (praef ("Advent"))) + ((date 2024-12-14) (mass ("Feria \226\128\147 Second Sunday of Advent")) (cls (3)) (colour ("violet")) (praef ("Advent"))) + ((date 2024-12-15) (mass ("Third Sunday of Advent \226\128\147 Gaudete")) (cls (1)) (colour ("rose")) (praef ("Advent"))) + ((date 2024-12-16) (mass ("St. Eusebius, Bishop & Martyr")) (cls (3)) (colour ("red")) (praef ("Advent"))) + ((date 2024-12-17) (mass ("Feria \226\128\147 Third Sunday of Advent")) (cls (2)) (colour ("violet")) (praef ("Advent"))) + ((date 2024-12-18) (mass ("Ember Wednesday of Advent")) (cls (2)) (colour ("violet")) (praef ("Advent"))) + ((date 2024-12-19) (mass ("Feria \226\128\147 Third Sunday of Advent")) (cls (2)) (colour ("violet")) (praef ("Advent"))) + ((date 2024-12-20) (mass ("Ember Friday of Advent")) (cls (2)) (colour ("violet")) (praef ("Advent"))) + ((date 2024-12-21) (mass ("St. Thomas, Apostle")) (cls (2)) (colour ("red")) (praef ("Apostles"))) + ((date 2024-12-22) (mass ("Fourth Sunday of Advent")) (cls (1)) (colour ("violet")) (praef ("Advent"))) + ((date 2024-12-23) (mass ("Feria - Fourth Sunday of Advent")) (cls (2)) (colour ("violet")) (praef ("Advent"))) + ((date 2024-12-24) (mass ("Vigil of Nativity of Our Lord")) (cls (1)) (colour ("violet")) (praef ("Advent"))) + ((date 2024-12-25) (mass ("Nativity of Our Lord - Mass at Midnight")) (cls (1)) (colour ("white")) (praef ("Nativity"))) + ((date 2024-12-26) (mass ("Day II in the Octave, St. Stephen, Protomartyr")) (cls (2)) (colour ("red")) (praef ("Nativity"))) + ((date 2024-12-27) (mass ("Day III in the Octave, St. John, Apostle & Evangelist")) (cls (2)) (colour ("white")) (praef ("Nativity"))) + ((date 2024-12-28) (mass ("Day IV in the Octave, Holy Innocents")) (cls (2)) (colour ("red")) (praef ("Nativity"))) + ((date 2024-12-29) (mass ("Sunday within the Octave of Christmas")) (cls (2)) (colour ("white")) (praef ("Nativity"))) + ((date 2024-12-30) (mass ("Day VI in the Octave")) (cls (2)) (colour ("white")) (praef ("Nativity"))) + ((date 2024-12-31) (mass ("Day VII in the Octave")) (cls (2)) (colour ("white")) (praef ("Nativity"))) + ((date 2025-01-01) (mass ("Day VIII in the Octave, Circumcision of Our Lord")) (cls (1)) (colour ("white")) (praef ("Nativity"))) + ((date 2025-01-02) (mass ("Feria in Christmastide")) (cls (4)) (colour ("white")) (praef ("Nativity"))) + ((date 2025-01-03) (mass ("Feria in Christmastide")) (cls (4)) (colour ("white")) (praef ("Nativity"))) + ((date 2025-01-04) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2025-01-05) (mass ("Holy Name of Jesus")) (cls (2)) (colour ("white")) (praef ("Nativity"))) + ((date 2025-01-06) (mass ("Epiphany of Our Lord")) (cls (1)) (colour ("white")) (praef ("Epiphany"))) + ((date 2025-01-07) (mass ("Feria of Epiphany")) (cls (4)) (colour ("white")) (praef ("Epiphany"))) + ((date 2025-01-08) (mass ("Feria of Epiphany")) (cls (4)) (colour ("white")) (praef ("Epiphany"))) + ((date 2025-01-09) (mass ("Feria of Epiphany")) (cls (4)) (colour ("white")) (praef ("Epiphany"))) + ((date 2025-01-10) (mass ("Feria of Epiphany")) (cls (4)) (colour ("white")) (praef ("Epiphany"))) + ((date 2025-01-11) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2025-01-12) (mass ("Holy Family")) (cls (2)) (colour ("white")) (praef ("Epiphany"))) + ((date 2025-01-13) (mass ("Baptism of Our Lord")) (cls (2)) (colour ("white")) (praef ("Epiphany"))) + ((date 2025-01-14) (mass ("St. Hilary, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-01-15) (mass ("St. Paul, First Hermit, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-01-16) (mass ("St. Marcellus I, Pope & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2025-01-17) (mass ("St. Anthony, Abbot")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-01-18) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2025-01-19) (mass ("Second Sunday after Epiphany")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2025-01-20) (mass ("Ss. Fabian, Pope, & Sebastian, Martyrs")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2025-01-21) (mass ("St. Agnes, Virgin & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2025-01-22) (mass ("Ss. Vincent & Anastasius, Martyrs")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2025-01-23) (mass ("St. Raymund of Pennafort, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-01-24) (mass ("St. Timothy, Bishop & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2025-01-25) (mass ("Conversion of St. Paul, Apostle")) (cls (3)) (colour ("white")) (praef ("Apostles"))) + ((date 2025-01-26) (mass ("Third Sunday after Epiphany")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2025-01-27) (mass ("St. John Chrysostom, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-01-28) (mass ("St. Peter Nolasco, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-01-29) (mass ("St. Francis de Sales, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-01-30) (mass ("St. Martina, Virgin & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2025-01-31) (mass ("St. John Bosco, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-02-01) (mass ("St. Ignatius of Antioch, Bishop & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2025-02-02) (mass ("and Purification of the BVM")) (cls (2)) (colour ("white")) (praef ("Nativity"))) + ((date 2025-02-03) (mass ("St. Blase, Bishop & Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2025-02-04) (mass ("St. Andrew Corsini, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-02-05) (mass ("St. Agatha, Virgin & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2025-02-06) (mass ("St. Titus, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-02-07) (mass ("St. Romuald, Abbot")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-02-08) (mass ("St. John of Matha, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-02-09) (mass ("Fifth Sunday after Epiphany")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2025-02-10) (mass ("St. Scholastica, Virgin")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-02-11) (mass ("Our Lady of Lourdes")) (cls (3)) (colour ("white")) (praef ("BVM"))) + ((date 2025-02-12) (mass ("Seven Holy Founders, Confessors")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-02-13) (mass ("Feria \226\128\147 Fifth Sunday after Epiphany")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2025-02-14) (mass ("St. Valentine, Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2025-02-15) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2025-02-16) (mass ("Septuagesima")) (cls (2)) (colour ("violet")) (praef ("Holy Trinity"))) + ((date 2025-02-17) (mass ("Feria - Septuagesima")) (cls (4)) (colour ("violet")) (praef ("Common"))) + ((date 2025-02-18) (mass ("St. Simeon, Bishop & Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2025-02-19) (mass ("Feria - Septuagesima")) (cls (4)) (colour ("violet")) (praef ("Common"))) + ((date 2025-02-20) (mass ("Feria - Septuagesima")) (cls (4)) (colour ("violet")) (praef ("Common"))) + ((date 2025-02-21) (mass ("Feria - Septuagesima")) (cls (4)) (colour ("violet")) (praef ("Common"))) + ((date 2025-02-22) (mass ("Chair of St. Peter")) (cls (2)) (colour ("white")) (praef ("Apostles"))) + ((date 2025-02-23) (mass ("Sexagesima")) (cls (2)) (colour ("violet")) (praef ("Holy Trinity"))) + ((date 2025-02-24) (mass ("St. Matthias, Apostle")) (cls (2)) (colour ("red")) (praef ("Apostles"))) + ((date 2025-02-25) (mass ("Feria - Sexagesima")) (cls (4)) (colour ("violet")) (praef ("Common"))) + ((date 2025-02-26) (mass ("Feria - Sexagesima")) (cls (4)) (colour ("violet")) (praef ("Common"))) + ((date 2025-02-27) (mass ("St. Gabriel of Our Lady of Sorrows")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-02-28) (mass ("Feria - Sexagesima")) (cls (4)) (colour ("violet")) (praef ("Common"))) + ((date 2025-03-01) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2025-03-02) (mass ("Quinquagesima")) (cls (2)) (colour ("violet")) (praef ("Holy Trinity"))) + ((date 2025-03-03) (mass ("Feria - Quinquagesima")) (cls (4)) (colour ("violet")) (praef ("Common"))) + ((date 2025-03-04) (mass ("St. Casimir, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-03-05) (mass ("and Ash Wednesday")) (cls (1)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-03-06) (mass ("Thursday after Ash Wednesday")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-03-07) (mass ("Friday after Ash Wednesday")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-03-08) (mass ("Saturday after Ash Wednesday")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-03-09) (mass ("1st Sunday of Lent")) (cls (1)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-03-10) (mass ("Monday after the 1st Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-03-11) (mass ("Tuesday after the 1st Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-03-12) (mass ("Ember Wednesday of Lent")) (cls (2)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-03-13) (mass ("Thursday after the 1st Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-03-14) (mass ("Ember Friday of Lent")) (cls (2)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-03-15) (mass ("Ember Saturday of Lent")) (cls (2)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-03-16) (mass ("2nd Sunday of Lent")) (cls (1)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-03-17) (mass ("Monday after the 2nd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-03-18) (mass ("Tuesday after the 2nd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-03-19) (mass ("St. Joseph, Spouse of the BVM")) (cls (1)) (colour ("white")) (praef ("St. Joseph"))) + ((date 2025-03-20) (mass ("Thursday after the 2nd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-03-21) (mass ("Friday after the 2nd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-03-22) (mass ("Saturday after the 2nd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-03-23) (mass ("3rd Sunday of Lent")) (cls (1)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-03-24) (mass ("Monday after the 3rd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-03-25) (mass ("Annunciation of the BVM")) (cls (1)) (colour ("white")) (praef ("BVM"))) + ((date 2025-03-26) (mass ("Wednesday after the 3rd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-03-27) (mass ("Thursday after the 3rd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-03-28) (mass ("Friday after the 3rd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-03-29) (mass ("Saturday after the 3rd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-03-30) (mass ("4th Sunday of Lent \226\128\147 L\195\166tare Sunday")) (cls (1)) (colour ("rose")) (praef ("Lent"))) + ((date 2025-03-31) (mass ("Monday after the 4th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-04-01) (mass ("Tuesday after the 4th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-04-02) (mass ("Wednesday after the 4th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-04-03) (mass ("Thursday after the 4th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-04-04) (mass ("Friday after the 4th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-04-05) (mass ("Saturday after the 4th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2025-04-06) (mass ("Passion Sunday")) (cls (1)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2025-04-07) (mass ("Monday after the 5th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2025-04-08) (mass ("Tuesday after the 5th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2025-04-09) (mass ("Wednesday after the 5th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2025-04-10) (mass ("Thursday after the 5th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2025-04-11) (mass ("Friday after the 5th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2025-04-12) (mass ("Saturday after the 5th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2025-04-13) (mass ("and Palm Sunday")) (cls (1)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2025-04-14) (mass ("Monday of Holy Week")) (cls (1)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2025-04-15) (mass ("Tuesday of Holy Week")) (cls (1)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2025-04-16) (mass ("Wednesday of Holy Week")) (cls (1)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2025-04-17) (mass ("Holy Thursday")) (cls (1)) (colour ("white")) (praef ("Holy Cross"))) + ((date 2025-04-18) (mass ("Good Friday")) (cls (1)) (colour ("black")) (praef ())) + ((date 2025-04-19) (mass ("and Easter Vigil Mass")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2025-04-20) (mass ("Easter Sunday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2025-04-21) (mass ("Easter Monday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2025-04-22) (mass ("Easter Tuesday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2025-04-23) (mass ("Easter Wednesday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2025-04-24) (mass ("Easter Thursday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2025-04-25) (mass ("Easter Friday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2025-04-26) (mass ("Easter Saturday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2025-04-27) (mass ("Low Sunday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2025-04-28) (mass ("St. Paul of the Cross, Confessor")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2025-04-29) (mass ("St. Peter of Verona, Martyr")) (cls (3)) (colour ("red")) (praef ("Easter"))) + ((date 2025-04-30) (mass ("St. Catherine of Siena, Virgin")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2025-05-01) (mass ("St. Joseph the Workman, Confessor")) (cls (1)) (colour ("white")) (praef ("St. Joseph"))) + ((date 2025-05-02) (mass ("St. Athanasius, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2025-05-03) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2025-05-04) (mass ("Second Sunday after Easter")) (cls (2)) (colour ("white")) (praef ("Easter"))) + ((date 2025-05-05) (mass ("St. Pius V, Pope & Confessor")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2025-05-06) (mass ("St. John before the Latin Gate")) (cls (4)) (colour ("red")) (praef ("Apostles"))) + ((date 2025-05-07) (mass ("St. Stanislaus, Bishop & Martyr")) (cls (3)) (colour ("red")) (praef ("Easter"))) + ((date 2025-05-08) (mass ("Apparition of St. Michael")) (cls (4)) (colour ("white")) (praef ("Easter"))) + ((date 2025-05-09) (mass ("St. Gregory Nanzianzen, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2025-05-10) (mass ("St. Antoninus, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2025-05-11) (mass ("Third Sunday after Easter")) (cls (2)) (colour ("white")) (praef ("Easter"))) + ((date 2025-05-12) (mass ("Ss. Nereus, Achilleus, Domitila, & Pancras, Martyrs")) (cls (3)) (colour ("red")) (praef ("Easter"))) + ((date 2025-05-13) (mass ("St. Robert Bellarmine, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2025-05-14) (mass ("St. Boniface, Martyr")) (cls (4)) (colour ("red")) (praef ("Easter"))) + ((date 2025-05-15) (mass ("St. John Baptist de la Salle, Confessor")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2025-05-16) (mass ("St. Ubald, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2025-05-17) (mass ("St. Paschal Baylon, Confessor")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2025-05-18) (mass ("Fourth Sunday after Easter")) (cls (2)) (colour ("white")) (praef ("Easter"))) + ((date 2025-05-19) (mass ("St. Peter Celestine, Pope & Confessor")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2025-05-20) (mass ("St. Bernardine of Siena, Confessor")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2025-05-21) (mass ("Feria - Fourth Sunday after Easter")) (cls (4)) (colour ("white")) (praef ("Easter"))) + ((date 2025-05-22) (mass ("Feria - Fourth Sunday after Easter")) (cls (4)) (colour ("white")) (praef ("Easter"))) + ((date 2025-05-23) (mass ("Feria - Fourth Sunday after Easter")) (cls (4)) (colour ("white")) (praef ("Easter"))) + ((date 2025-05-24) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2025-05-25) (mass ("5th Sunday after Easter")) (cls (2)) (colour ("white")) (praef ("Easter"))) + ((date 2025-05-26) (mass ("St. Philip Neri, Confessor")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2025-05-27) (mass ("St. Bede the Venerable, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2025-05-28) (mass ("Vigil of Ascension")) (cls (2)) (colour ("white")) (praef ("Easter"))) + ((date 2025-05-29) (mass ("Ascension of Our Lord")) (cls (1)) (colour ("white")) (praef ("Ascension"))) + ((date 2025-05-30) (mass ("St. Felix I, Pope & Martyr")) (cls (4)) (colour ("red")) (praef ("Ascension"))) + ((date 2025-05-31) (mass ("Queenship of the BVM")) (cls (2)) (colour ("white")) (praef ("BVM"))) + ((date 2025-06-01) (mass ("Sunday after the Ascension")) (cls (2)) (colour ("white")) (praef ("Ascension"))) + ((date 2025-06-02) (mass ("Ss. Marcellinus, Peter, & Erasmus, Martyrs")) (cls (4)) (colour ("red")) (praef ("Ascension"))) + ((date 2025-06-03) (mass ("Feria - Ascension")) (cls (4)) (colour ("white")) (praef ("Ascension"))) + ((date 2025-06-04) (mass ("St. Francis Caracciolo, Confessor")) (cls (3)) (colour ("white")) (praef ("Ascension"))) + ((date 2025-06-05) (mass ("St. Boniface, Bishop & Martyr")) (cls (3)) (colour ("red")) (praef ("Ascension"))) + ((date 2025-06-06) (mass ("St. Norbert, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Ascension"))) + ((date 2025-06-07) (mass ("Vigil of Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2025-06-08) (mass ("Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2025-06-09) (mass ("Monday after Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2025-06-10) (mass ("Tuesday after Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2025-06-11) (mass ("Ember Wednesday of Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2025-06-12) (mass ("Thursday after Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2025-06-13) (mass ("Ember Friday of Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2025-06-14) (mass ("Ember Saturday of Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2025-06-15) (mass ("Trinity Sunday")) (cls (1)) (colour ("white")) (praef ("Holy Trinity"))) + ((date 2025-06-16) (mass ("Feria - First Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2025-06-17) (mass ("St. Gregory Barbarigo, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-06-18) (mass ("St. Ephrem of Syria, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-06-19) (mass ("Corpus Christi")) (cls (1)) (colour ("white")) (praef ("Common"))) + ((date 2025-06-20) (mass ("St. Silverius, Pope & Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2025-06-21) (mass ("St. Aloyisius Gonzaga, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-06-22) (mass ("Second Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2025-06-23) (mass ("Vigil of Nativity of St. John the Baptist")) (cls (2)) (colour ("violet")) (praef ("Common"))) + ((date 2025-06-24) (mass ("Nativity of St. John the Baptist")) (cls (1)) (colour ("white")) (praef ("Common"))) + ((date 2025-06-25) (mass ("St. William, Abbot")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-06-26) (mass ("Ss. John & Paul, Martyrs")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2025-06-27) (mass ("Most Sacred Heart of Jesus")) (cls (1)) (colour ("white")) (praef ("Sacred Heart"))) + ((date 2025-06-28) (mass ("Vigil of Ss. Peter & Paul")) (cls (2)) (colour ("violet")) (praef ("Common"))) + ((date 2025-06-29) (mass ("Ss. Peter & Paul, Apostles")) (cls (1)) (colour ("red")) (praef ("Apostles"))) + ((date 2025-06-30) (mass ("Commemoration of St. Paul, Apostle")) (cls (3)) (colour ("red")) (praef ("Apostles"))) + ((date 2025-07-01) (mass ("Most Precious Blood of Our Lord")) (cls (1)) (colour ("red")) (praef ("Holy Cross"))) + ((date 2025-07-02) (mass ("Visitation of the BVM")) (cls (2)) (colour ("white")) (praef ("BVM"))) + ((date 2025-07-03) (mass ("St. Irenaeus, Doctor of the Church")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2025-07-04) (mass ("In Commemoration of All Holy Popes")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2025-07-05) (mass ("St. Anthony Mary Zaccaria, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-07-06) (mass ("Fourth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2025-07-07) (mass ("Ss. Cyril & Methodius, Bishops & Confessors")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-07-08) (mass ("St. Elizabeth of Portugal, Queen & Widow")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-07-09) (mass ("Feria - Fourth Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2025-07-10) (mass ("Seven Holy Brothers, & Ss. Rufina & Secunda, Martyrs")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2025-07-11) (mass ("St. Pius I, Pope & Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2025-07-12) (mass ("St. John Gualbert, Abbot")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-07-13) (mass ("Fifth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2025-07-14) (mass ("St. Bonaventure, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-07-15) (mass ("St. Henry II, Emperor, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-07-16) (mass ("Our Lady of Mt. Carmel")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2025-07-17) (mass ("St. Alexius, Confessor")) (cls (4)) (colour ("white")) (praef ("Common"))) + ((date 2025-07-18) (mass ("St. Camillus de Lellis, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-07-19) (mass ("St. Vincent de Paul, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-07-20) (mass ("Sixth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2025-07-21) (mass ("St. Lawrence of Brindisi, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-07-22) (mass ("St. Mary Magdalene, Penitent")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-07-23) (mass ("St. Apollinarus, Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2025-07-24) (mass ("St. Christina, Virgin & Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2025-07-25) (mass ("St. James the Greater, Apostle")) (cls (2)) (colour ("red")) (praef ("Apostles"))) + ((date 2025-07-26) (mass ("St. Anne, Mother of the BVM")) (cls (2)) (colour ("white")) (praef ("Common"))) + ((date 2025-07-27) (mass ("Seventh Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2025-07-28) (mass ("Ss. Nazarius & Celsus, Martyrs, Victor I, Pope & Martyr,")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2025-07-29) (mass ("St. Martha, Virgin")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-07-30) (mass ("Ss. Abdon & Sennen, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2025-07-31) (mass ("St. Ignatius, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-08-01) (mass ("Holy Machabees, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2025-08-02) (mass ("St. Alphonsus of Liguori, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-08-03) (mass ("Eighth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2025-08-04) (mass ("St. Dominic, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-08-05) (mass ("Our Lady of the Snows")) (cls (3)) (colour ("white")) (praef ("BVM"))) + ((date 2025-08-06) (mass ("Transfiguration of Our Lord")) (cls (2)) (colour ("white")) (praef ("Common"))) + ((date 2025-08-07) (mass ("St. Cajetan, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-08-08) (mass ("St. John Mary Vianney, Confessor & Priest")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-08-09) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2025-08-10) (mass ("Ninth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2025-08-11) (mass ("Ss. Tiburtius & Susanna, Virgin, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2025-08-12) (mass ("St. Clare, Virgin")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-08-13) (mass ("Ss. Hippolytus & Cassian, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2025-08-14) (mass ("Vigil of the Assumption")) (cls (2)) (colour ("violet")) (praef ("Common"))) + ((date 2025-08-15) (mass ("Assumption of the BVM")) (cls (1)) (colour ("white")) (praef ("BVM"))) + ((date 2025-08-16) (mass ("St. Joachim, Father of the BVM")) (cls (2)) (colour ("white")) (praef ("Common"))) + ((date 2025-08-17) (mass ("Tenth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2025-08-18) (mass ("St. Agapitus, Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2025-08-19) (mass ("St. John Eudes, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-08-20) (mass ("St. Bernard of Clairvaux, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-08-21) (mass ("St. Jane Frances de Chantal, Widow")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-08-22) (mass ("Immaculate Heart of Mary")) (cls (2)) (colour ("white")) (praef ("BVM"))) + ((date 2025-08-23) (mass ("St. Philip Benizi, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-08-24) (mass ("Eleventh Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2025-08-25) (mass ("St. Louis IX, King, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-08-26) (mass ("St. Zephirynus, Pope & Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2025-08-27) (mass ("St. Joseph Calasanctius, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-08-28) (mass ("St. Augustine, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-08-29) (mass ("Beheading of St. John the Baptist")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2025-08-30) (mass ("St. Rose of Lima, Virgin")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-08-31) (mass ("Twelfth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2025-09-01) (mass ("St. Giles, Abbot")) (cls (4)) (colour ("white")) (praef ("Common"))) + ((date 2025-09-02) (mass ("St. Stephen, King, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-09-03) (mass ("St. Pius X, Pope & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-09-04) (mass ("Feria - Twelfth Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2025-09-05) (mass ("St. Lawrence Justinian, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-09-06) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2025-09-07) (mass ("Thirteenth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2025-09-08) (mass ("Nativity of the BVM")) (cls (2)) (colour ("white")) (praef ("BVM"))) + ((date 2025-09-09) (mass ("St. Gorgonius, Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2025-09-10) (mass ("St. Nicholas of Tolentino, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-09-11) (mass ("Ss. Protus & Hyacinth, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2025-09-12) (mass ("Most Holy Name of Mary")) (cls (3)) (colour ("white")) (praef ("BVM"))) + ((date 2025-09-13) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2025-09-14) (mass ("Exaltation of the Holy Cross")) (cls (2)) (colour ("red")) (praef ("Holy Cross"))) + ((date 2025-09-15) (mass ("Seven Sorrows of the BVM")) (cls (2)) (colour ("white")) (praef ("BVM"))) + ((date 2025-09-16) (mass ("St. Cornelius, Pope, & St. Cyprian, Bishop, Martyrs")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2025-09-17) (mass ("Stigmata of St. Francis")) (cls (4)) (colour ("white")) (praef ("Common"))) + ((date 2025-09-18) (mass ("St. Joseph of Cupertino, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-09-19) (mass ("St. Januarius, Bishop, & Companions, Martyrs")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2025-09-20) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2025-09-21) (mass ("Fifteenth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2025-09-22) (mass ("St. Thomas of Villanova, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-09-23) (mass ("St. Linus, Pope & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2025-09-24) (mass ("Ember Wednesday")) (cls (2)) (colour ("violet")) (praef ("Common"))) + ((date 2025-09-25) (mass ("Feria - Fifteenth Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2025-09-26) (mass ("Ember Friday")) (cls (2)) (colour ("violet")) (praef ("Common"))) + ((date 2025-09-27) (mass ("Ember Saturday")) (cls (2)) (colour ("violet")) (praef ("Common"))) + ((date 2025-09-28) (mass ("Sixteenth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2025-09-29) (mass ("St. Michael the Archangel")) (cls (1)) (colour ("white")) (praef ("Holy Trinity"))) + ((date 2025-09-30) (mass ("St. Jerome, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-10-01) (mass ("St. Remigius, Bishop & Confessor")) (cls (4)) (colour ("white")) (praef ("Common"))) + ((date 2025-10-02) (mass ("Holy Guardian Angels")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-10-03) (mass ("St. Teresa of the Child Jesus, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-10-04) (mass ("St. Francis of Assisi, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-10-05) (mass ("Seventeenth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2025-10-06) (mass ("St. Bruno, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-10-07) (mass ("Our Lady of the Rosary")) (cls (2)) (colour ("white")) (praef ("BVM"))) + ((date 2025-10-08) (mass ("St. Bridget, Widow")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-10-09) (mass ("St. John Leonard, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-10-10) (mass ("St. Francis Borgia, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-10-11) (mass ("Maternity of the BVM")) (cls (2)) (colour ("white")) (praef ("BVM"))) + ((date 2025-10-12) (mass ("Eighteenth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2025-10-13) (mass ("St. Edward, King, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-10-14) (mass ("St. Callistus I, Pope & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2025-10-15) (mass ("St. Teresa of Avila, Virgin")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-10-16) (mass ("St. Hedwig, Widow")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-10-17) (mass ("St. Margaret Mary Alacoque, Virgin")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-10-18) (mass ("St. Luke the Evangelist")) (cls (2)) (colour ("red")) (praef ("Apostles"))) + ((date 2025-10-19) (mass ("Nineteenth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2025-10-20) (mass ("St. John Cantius, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-10-21) (mass ("St. Hilarion, Abbot")) (cls (4)) (colour ("white")) (praef ("Common"))) + ((date 2025-10-22) (mass ("Feria - Nineteenth Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2025-10-23) (mass ("St. Anthony Mary Claret, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-10-24) (mass ("St. Raphael the Archangel")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-10-25) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2025-10-26) (mass ("Christ the King")) (cls (1)) (colour ("white")) (praef ("Christ the King"))) + ((date 2025-10-27) (mass ("Feria - Twentieth Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2025-10-28) (mass ("Ss. Simon & Jude, Apostles")) (cls (2)) (colour ("red")) (praef ("Apostles"))) + ((date 2025-10-29) (mass ("Feria - Twentieth Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2025-10-30) (mass ("Feria - Twentieth Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2025-10-31) (mass ("Feria - Twentieth Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2025-11-01) (mass ("All Saints")) (cls (1)) (colour ("white")) (praef ("Common"))) + ((date 2025-11-02) (mass ("Twenty-first Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2025-11-03) (mass ("All Souls - Mass 1")) (cls (1)) (colour ("black")) (praef ("For the Dead"))) + ((date 2025-11-04) (mass ("St. Charles Borromeo, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-11-05) (mass ("The Holy Relics")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2025-11-06) (mass ("Feria - Twenty-first Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2025-11-07) (mass ("Feria - Twenty-first Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2025-11-08) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2025-11-09) (mass ("Dedication of the Archbasilica of Our Holy Savior")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2025-11-10) (mass ("St. Andrew Avellino, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-11-11) (mass ("St. Martin of Tours, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-11-12) (mass ("St. Martin I, Pope & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2025-11-13) (mass ("St. Didacus, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-11-14) (mass ("St. Josaphat, Bishop & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2025-11-15) (mass ("St. Albert the Great, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-11-16) (mass ("Twenty-third Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2025-11-17) (mass ("St. Gregory Thaumaturgus, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-11-18) (mass ("Dedication of the Basilicas of Ss. Peter & Paul")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-11-19) (mass ("St. Elizabeth of Hungary, Widow")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-11-20) (mass ("St. Felix of Valois, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-11-21) (mass ("Presentation of the BVM")) (cls (3)) (colour ("white")) (praef ("BVM"))) + ((date 2025-11-22) (mass ("St. Cecilia, Virgin & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2025-11-23) (mass ("Last Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2025-11-24) (mass ("St. John of the Cross, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-11-25) (mass ("St. Catherine of Alexandria, Virgin & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2025-11-26) (mass ("St. Sylvester, Abbot")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2025-11-27) (mass ("Our Lady of the Miraculous Medal")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2025-11-28) (mass ("Feria - Last Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2025-11-29) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("Common"))) +) diff --git a/test/fixtures/efdotorg-ordo-2025-2026.sexp b/test/fixtures/efdotorg-ordo-2025-2026.sexp new file mode 100644 index 0000000..c94a0a8 --- /dev/null +++ b/test/fixtures/efdotorg-ordo-2025-2026.sexp @@ -0,0 +1,398 @@ +; test/fixtures/efdotorg-ordo-2025-2026.sexp -- efdotorg-preface task +; (2026-08-24-colitur-celebrant-rubrics-phase1): the THIRD independent +; preface witness (RG 482-499), extraordinaryform.org's 2025-2026 Ordo, +; extracted from the already-parsed, fidelity-audited corpus +; docs/research/ordo/ordo-2024-2027.json (SHA-256 18a417fb8b30dc438c3f12f64b43dfdf5e2e9313857f2eccd04bf02072ca7e3c) rather than +; re-parsed from the PDF -- see tools/extract_efdotorg_ordo.py's own +; header for the full characterisation this fixture rests on (the menu- +; trap office filter, the Christ-the-King classifier-gap recovery, why +; "Advent" is not baked into a single mapping here, the known Vigil-of- +; St-Lawrence gap, and the two source-PDF defects that turn out not to +; touch this field). +; +; Generator: tools/extract_efdotorg_ordo.py -- do not hand-edit; re-run +; against the same JSON and commit the diff instead. +; python3 tools/extract_efdotorg_ordo.py docs/research/ordo/ordo-2024-2027.json test/fixtures +; +; Source PDF (gitignored, CLAUDE.md: "docs/ is gitignored", see +; docs/research/ordo/SHA256SUMS for its own hash): 2025-2026Ordo.pdf, +; extraordinaryform.org. +; +; COVERAGE: 364 day-rows, 2025-11-30..2026-11-28 (this edition's own civil-date +; span, re-derived from the JSON's own seams -- see the generator's own +; EDITIONS comment). 0 row(s) are a genuine SOURCE GAP (2027-03-03 +; only, a PDF row-drop, ordo-fidelity-report.md) -- mass/cls/colour/praef +; all absent, the same shape a structurally blank day (Good Friday) uses. +; 1 further row(s) have mass/cls/colour but no praef at all +; (Good Friday -- RG 28, no Mass in the 1955-restored Holy Week). +; +; Each row's `praef` is RAW TEXT from the day's own OFFICE (after the +; menu-trap filter, with the Christ-the-King recovery already applied) -- +; classified against {!Colitur_kernel.Preface.t} by +; test/test_efdotorg_ordo.ml, not here. +( + ((date 2025-11-30) (mass ("First Sunday of Advent")) (cls (1)) (colour ("violet")) (praef ("Advent"))) + ((date 2025-12-01) (mass ("Feria \226\128\147 First Sunday of Advent")) (cls (3)) (colour ("violet")) (praef ("Advent"))) + ((date 2025-12-02) (mass ("St. Bibiana, Virgin & Martyr")) (cls (3)) (colour ("red")) (praef ("Advent"))) + ((date 2025-12-03) (mass ("St. Francis Xavier, Confessor")) (cls (3)) (colour ("white")) (praef ("Advent"))) + ((date 2025-12-04) (mass ("St. Peter Chrysologus, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Advent"))) + ((date 2025-12-05) (mass ("Feria \226\128\147 First Sunday of Advent")) (cls (3)) (colour ("violet")) (praef ("Advent"))) + ((date 2025-12-06) (mass ("St. Nicholas, Confessor & Bishop")) (cls (3)) (colour ("white")) (praef ("Advent"))) + ((date 2025-12-07) (mass ("Second Sunday of Advent")) (cls (1)) (colour ("violet")) (praef ("Advent"))) + ((date 2025-12-08) (mass ("Immaculate Conception")) (cls (1)) (colour ("white")) (praef ("BVM"))) + ((date 2025-12-09) (mass ("Feria \226\128\147 Second Sunday of Advent")) (cls (3)) (colour ("violet")) (praef ("Advent"))) + ((date 2025-12-10) (mass ("Feria \226\128\147 Second Sunday of Advent")) (cls (3)) (colour ("violet")) (praef ("Advent"))) + ((date 2025-12-11) (mass ("St. Damasus I, Pope")) (cls (3)) (colour ("white")) (praef ("Advent"))) + ((date 2025-12-12) (mass ("Feria \226\128\147 Second Sunday of Advent")) (cls (3)) (colour ("violet")) (praef ("Advent"))) + ((date 2025-12-13) (mass ("St. Lucy, Virgin & Martyr")) (cls (3)) (colour ("red")) (praef ("Advent"))) + ((date 2025-12-14) (mass ("Third Sunday of Advent \226\128\147 Gaudete")) (cls (1)) (colour ("rose")) (praef ("Advent"))) + ((date 2025-12-15) (mass ("Feria \226\128\147 Third Sunday of Advent")) (cls (3)) (colour ("violet")) (praef ("Advent"))) + ((date 2025-12-16) (mass ("St. Eusebius, Bishop & Martyr")) (cls (3)) (colour ("red")) (praef ("Advent"))) + ((date 2025-12-17) (mass ("Ember Wednesday of Advent")) (cls (2)) (colour ("violet")) (praef ("Advent"))) + ((date 2025-12-18) (mass ("Feria \226\128\147 Third Sunday of Advent")) (cls (2)) (colour ("violet")) (praef ("Advent"))) + ((date 2025-12-19) (mass ("Ember Friday of Advent")) (cls (2)) (colour ("violet")) (praef ("Advent"))) + ((date 2025-12-20) (mass ("Ember Saturday of Advent")) (cls (2)) (colour ("violet")) (praef ("Advent"))) + ((date 2025-12-21) (mass ("Fourth Sunday of Advent")) (cls (1)) (colour ("violet")) (praef ("Advent"))) + ((date 2025-12-22) (mass ("Feria - Fourth Sunday of Advent")) (cls (2)) (colour ("violet")) (praef ("Advent"))) + ((date 2025-12-23) (mass ("Feria - Fourth Sunday of Advent")) (cls (2)) (colour ("violet")) (praef ("Advent"))) + ((date 2025-12-24) (mass ("Vigil of Nativity of Our Lord")) (cls (1)) (colour ("violet")) (praef ("Advent"))) + ((date 2025-12-25) (mass ("Nativity of Our Lord - Mass at Midnight")) (cls (1)) (colour ("white")) (praef ("Nativity"))) + ((date 2025-12-26) (mass ("Day II in the Octave, St. Stephen, Protomartyr")) (cls (2)) (colour ("red")) (praef ("Nativity"))) + ((date 2025-12-27) (mass ("Day III in the Octave, St. John, Apostle & Evangelist")) (cls (2)) (colour ("white")) (praef ("Nativity"))) + ((date 2025-12-28) (mass ("Sunday within the Octave of Christmas")) (cls (2)) (colour ("white")) (praef ("Nativity"))) + ((date 2025-12-29) (mass ("Day V in the Octave")) (cls (2)) (colour ("white")) (praef ("Nativity"))) + ((date 2025-12-30) (mass ("Day VI in the Octave")) (cls (2)) (colour ("white")) (praef ("Nativity"))) + ((date 2025-12-31) (mass ("Day VII in the Octave")) (cls (2)) (colour ("white")) (praef ("Nativity"))) + ((date 2026-01-01) (mass ("Day VIII in the Octave, Circumcision of Our Lord")) (cls (1)) (colour ("white")) (praef ("Nativity"))) + ((date 2026-01-02) (mass ("Feria in Christmastide")) (cls (4)) (colour ("white")) (praef ("Nativity"))) + ((date 2026-01-03) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2026-01-04) (mass ("Holy Name of Jesus")) (cls (2)) (colour ("white")) (praef ("Nativity"))) + ((date 2026-01-05) (mass ("St. Telesphorus, Pope & Martyr")) (cls (4)) (colour ("red")) (praef ("Nativity"))) + ((date 2026-01-06) (mass ("Epiphany of Our Lord")) (cls (1)) (colour ("white")) (praef ("Epiphany"))) + ((date 2026-01-07) (mass ("Feria of Epiphany")) (cls (4)) (colour ("white")) (praef ("Epiphany"))) + ((date 2026-01-08) (mass ("Feria of Epiphany")) (cls (4)) (colour ("white")) (praef ("Epiphany"))) + ((date 2026-01-09) (mass ("Feria of Epiphany")) (cls (4)) (colour ("white")) (praef ("Epiphany"))) + ((date 2026-01-10) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2026-01-11) (mass ("Holy Family")) (cls (2)) (colour ("white")) (praef ("Epiphany"))) + ((date 2026-01-12) (mass ("Feria after Epiphany")) (cls (4)) (colour ("white")) (praef ("Epiphany"))) + ((date 2026-01-13) (mass ("Baptism of Our Lord")) (cls (2)) (colour ("white")) (praef ("Epiphany"))) + ((date 2026-01-14) (mass ("St. Hilary, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-01-15) (mass ("St. Paul, First Hermit, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-01-16) (mass ("St. Marcellus I, Pope & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2026-01-17) (mass ("St. Anthony, Abbot")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-01-18) (mass ("Second Sunday after Epiphany")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-01-19) (mass ("Ss. Marius, Martha, Audifax, & Abachum, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2026-01-20) (mass ("Ss. Fabian, Pope, & Sebastian, Martyrs")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2026-01-21) (mass ("St. Agnes, Virgin & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2026-01-22) (mass ("Ss. Vincent & Anastasius, Martyrs")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2026-01-23) (mass ("St. Raymund of Pennafort, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-01-24) (mass ("St. Timothy, Bishop & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2026-01-25) (mass ("Third Sunday after Epiphany")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-01-26) (mass ("St. Polycarp, Bishop & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2026-01-27) (mass ("St. John Chrysostom, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-01-28) (mass ("St. Peter Nolasco, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-01-29) (mass ("St. Francis de Sales, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-01-30) (mass ("St. Martina, Virgin & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2026-01-31) (mass ("St. John Bosco, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-02-01) (mass ("Septuagesima")) (cls (2)) (colour ("violet")) (praef ("Holy Trinity"))) + ((date 2026-02-02) (mass ("and Purification of BVM")) (cls (2)) (colour ("white")) (praef ("Nativity"))) + ((date 2026-02-03) (mass ("St. Blaise, Bishop & Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2026-02-04) (mass ("St. Andrew Corsini, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-02-05) (mass ("St. Agatha, Virgin & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2026-02-06) (mass ("St. Titus, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-02-07) (mass ("St. Romuald, Abbot")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-02-08) (mass ("Sexagesima")) (cls (2)) (colour ("violet")) (praef ("Holy Trinity"))) + ((date 2026-02-09) (mass ("St. Cyril, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-02-10) (mass ("St. Scholastica, Virgin")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-02-11) (mass ("Our Lady of Lourdes")) (cls (3)) (colour ("white")) (praef ("BVM"))) + ((date 2026-02-12) (mass ("Seven Holy Founders, Confessors")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-02-13) (mass ("Feria - Sexagesima")) (cls (4)) (colour ("violet")) (praef ("Common"))) + ((date 2026-02-14) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2026-02-15) (mass ("Quinquagesima")) (cls (2)) (colour ("violet")) (praef ("Holy Trinity"))) + ((date 2026-02-16) (mass ("Feria - Quinquagesima")) (cls (4)) (colour ("violet")) (praef ("Common"))) + ((date 2026-02-17) (mass ("Feria - Quinquagesima")) (cls (4)) (colour ("violet")) (praef ("Common"))) + ((date 2026-02-18) (mass ("and Ash Wednesday")) (cls (1)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-02-19) (mass ("Thursday after Ash Wednesday")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-02-20) (mass ("Friday after Ash Wednesday")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-02-21) (mass ("Saturday after Ash Wednesday")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-02-22) (mass ("1st Sunday of Lent")) (cls (1)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-02-23) (mass ("Monday after the 1st Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-02-24) (mass ("St. Matthias, Apostle")) (cls (2)) (colour ("red")) (praef ("Apostles"))) + ((date 2026-02-25) (mass ("Ember Wednesday of Lent")) (cls (2)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-02-26) (mass ("Thursday after the 1st Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-02-27) (mass ("Ember Friday of Lent")) (cls (2)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-02-28) (mass ("Ember Saturday of Lent")) (cls (2)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-03-01) (mass ("2nd Sunday of Lent")) (cls (1)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-03-02) (mass ("Monday after the 2nd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-03-03) (mass ("Tuesday after the 2nd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-03-04) (mass ("Wednesday after the 2nd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-03-05) (mass ("Thursday after the 2nd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-03-06) (mass ("Friday after the 2nd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-03-07) (mass ("Saturday after the 2nd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-03-08) (mass ("3rd Sunday of Lent")) (cls (1)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-03-09) (mass ("Monday after the 3rd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-03-10) (mass ("Tuesday after the 3rd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-03-11) (mass ("Wednesday after the 3rd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-03-12) (mass ("Thursday after the 3rd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-03-13) (mass ("Friday after the 3rd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-03-14) (mass ("Saturday after the 3rd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-03-15) (mass ("4th Sunday of Lent \226\128\147 L\195\166tare Sunday")) (cls (1)) (colour ("rose")) (praef ("Lent"))) + ((date 2026-03-16) (mass ("Monday after the 4th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-03-17) (mass ("Tuesday after the 4th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-03-18) (mass ("Wednesday after the 4th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-03-19) (mass ("St. Joseph, Spouse of the BVM")) (cls (1)) (colour ("white")) (praef ("St. Joseph"))) + ((date 2026-03-20) (mass ("Friday after the 4th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-03-21) (mass ("Saturday after the 4th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2026-03-22) (mass ("Passion Sunday")) (cls (1)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2026-03-23) (mass ("Monday after the 5th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2026-03-24) (mass ("Tuesday after the 5th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2026-03-25) (mass ("Annunciation of the BVM")) (cls (1)) (colour ("white")) (praef ("BVM"))) + ((date 2026-03-26) (mass ("Thursday after the 5th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2026-03-27) (mass ("Friday after the 5th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2026-03-28) (mass ("Saturday after the 5th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2026-03-29) (mass ("and Palm Sunday")) (cls (1)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2026-03-30) (mass ("Monday of Holy Week")) (cls (1)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2026-03-31) (mass ("Tuesday of Holy Week")) (cls (1)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2026-04-01) (mass ("Wednesday of Holy Week")) (cls (1)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2026-04-02) (mass ("Holy Thursday")) (cls (1)) (colour ("white")) (praef ("Holy Cross"))) + ((date 2026-04-03) (mass ("Good Friday")) (cls (1)) (colour ("black")) (praef ())) + ((date 2026-04-04) (mass ("and Easter Vigil Mass")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2026-04-05) (mass ("Easter Sunday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2026-04-06) (mass ("Easter Monday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2026-04-07) (mass ("Easter Tuesday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2026-04-08) (mass ("Easter Wednesday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2026-04-09) (mass ("Easter Thursday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2026-04-10) (mass ("Easter Friday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2026-04-11) (mass ("Easter Saturday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2026-04-12) (mass ("Low Sunday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2026-04-13) (mass ("St.Hermenegild, Martyr")) (cls (3)) (colour ("red")) (praef ("Easter"))) + ((date 2026-04-14) (mass ("St. Justin, Martyr")) (cls (3)) (colour ("red")) (praef ("Easter"))) + ((date 2026-04-15) (mass ("Feria - First Sunday after Easter")) (cls (4)) (colour ("white")) (praef ("Easter"))) + ((date 2026-04-16) (mass ("Feria - First Sunday after Easter")) (cls (4)) (colour ("white")) (praef ("Easter"))) + ((date 2026-04-17) (mass ("St. Anicetus, Pope & Martyr")) (cls (4)) (colour ("red")) (praef ("Easter"))) + ((date 2026-04-18) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2026-04-19) (mass ("Second Sunday after Easter")) (cls (2)) (colour ("white")) (praef ("Easter"))) + ((date 2026-04-20) (mass ("Feria - Second Sunday after Easter")) (cls (4)) (colour ("white")) (praef ("Easter"))) + ((date 2026-04-21) (mass ("St. Anselm, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2026-04-22) (mass ("Ss. Soter & Cajus, Popes & Martyrs")) (cls (3)) (colour ("red")) (praef ("Easter"))) + ((date 2026-04-23) (mass ("St. George, Martyr")) (cls (4)) (colour ("red")) (praef ("Easter"))) + ((date 2026-04-24) (mass ("St. Fidelis. Martyr")) (cls (3)) (colour ("red")) (praef ("Easter"))) + ((date 2026-04-25) (mass ("St. Mark, Evangelist")) (cls (2)) (colour ("red")) (praef ("Apostles"))) + ((date 2026-04-26) (mass ("Third Sunday after Easter")) (cls (2)) (colour ("white")) (praef ("Easter"))) + ((date 2026-04-27) (mass ("St. Peter Canisius, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2026-04-28) (mass ("St. Paul of the Cross, Confessor")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2026-04-29) (mass ("St. Peter of Verona, Martyr")) (cls (3)) (colour ("red")) (praef ("Easter"))) + ((date 2026-04-30) (mass ("St. Catherine of Siena, Virgin")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2026-05-01) (mass ("St. Joseph the Workman, Confessor")) (cls (1)) (colour ("white")) (praef ("St. Joseph"))) + ((date 2026-05-02) (mass ("St. Athanasius, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2026-05-03) (mass ("Fourth Sunday after Easter")) (cls (2)) (colour ("white")) (praef ("Easter"))) + ((date 2026-05-04) (mass ("St. Monica, Widow")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2026-05-05) (mass ("St. Pius V, Pope & Confessor")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2026-05-06) (mass ("St. John before the Latin Gate")) (cls (4)) (colour ("red")) (praef ("Apostles"))) + ((date 2026-05-07) (mass ("St. Stanislaus, Bishop & Martyr")) (cls (3)) (colour ("red")) (praef ("Easter"))) + ((date 2026-05-08) (mass ("Apparition of St. Michael")) (cls (4)) (colour ("white")) (praef ("Easter"))) + ((date 2026-05-09) (mass ("St. Gregory Nanzianzen, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2026-05-10) (mass ("5th Sunday after Easter")) (cls (2)) (colour ("white")) (praef ("Easter"))) + ((date 2026-05-11) (mass ("Ss. Philip & James, Apostles")) (cls (2)) (colour ("red")) (praef ("Apostles"))) + ((date 2026-05-12) (mass ("Ss. Nereus, Achilleus, Domitila, & Pancras, Martyrs")) (cls (3)) (colour ("red")) (praef ("Easter"))) + ((date 2026-05-13) (mass ("Vigil of Ascension")) (cls (2)) (colour ("white")) (praef ("Easter"))) + ((date 2026-05-14) (mass ("Ascension of Our Lord")) (cls (1)) (colour ("white")) (praef ("Ascension"))) + ((date 2026-05-15) (mass ("St. John Baptist de la Salle, Confessor")) (cls (3)) (colour ("white")) (praef ("Ascension"))) + ((date 2026-05-16) (mass ("St. Ubald, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Ascension"))) + ((date 2026-05-17) (mass ("Sunday after the Ascension")) (cls (2)) (colour ("white")) (praef ("Ascension"))) + ((date 2026-05-18) (mass ("St. Venantius, Martyr")) (cls (3)) (colour ("red")) (praef ("Ascension"))) + ((date 2026-05-19) (mass ("St. Peter Celestine, Pope & Confessor")) (cls (3)) (colour ("white")) (praef ("Ascension"))) + ((date 2026-05-20) (mass ("St. Bernardine of Siena, Confessor")) (cls (3)) (colour ("white")) (praef ("Ascension"))) + ((date 2026-05-21) (mass ("Feria - Ascension")) (cls (4)) (colour ("white")) (praef ("Ascension"))) + ((date 2026-05-22) (mass ("Feria - Ascension")) (cls (4)) (colour ("white")) (praef ("Ascension"))) + ((date 2026-05-23) (mass ("Vigil of Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2026-05-24) (mass ("Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2026-05-25) (mass ("Monday after Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2026-05-26) (mass ("Tuesday after Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2026-05-27) (mass ("Ember Wednesday of Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2026-05-28) (mass ("Thursday after Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2026-05-29) (mass ("Ember Friday of Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2026-05-30) (mass ("Ember Saturday of Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2026-05-31) (mass ("Trinity Sunday")) (cls (1)) (colour ("white")) (praef ("Holy Trinity"))) + ((date 2026-06-01) (mass ("St. Angela Merici, Virgin")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-06-02) (mass ("Ss. Marcellinus, Peter, & Erasmus, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2026-06-03) (mass ("Feria - First Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2026-06-04) (mass ("Corpus Christi")) (cls (1)) (colour ("white")) (praef ("Common"))) + ((date 2026-06-05) (mass ("St. Boniface, Bishop & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2026-06-06) (mass ("St. Norbert, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-06-07) (mass ("Second Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-06-08) (mass ("Feria - Second Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2026-06-09) (mass ("Ss. Primus & Felician, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2026-06-10) (mass ("St. Margaret, Queen of Scotland, Widow")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-06-11) (mass ("St. Barnabas, Apostle")) (cls (3)) (colour ("red")) (praef ("Apostles"))) + ((date 2026-06-12) (mass ("Most Sacred Heart of Jesus")) (cls (1)) (colour ("white")) (praef ("Sacred Heart"))) + ((date 2026-06-13) (mass ("St. Anthony of Padua, Doctor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-06-14) (mass ("Third Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-06-15) (mass ("Ss. Vitus, Modestus, & Crescentia, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2026-06-16) (mass ("Feria - Third Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2026-06-17) (mass ("St. Gregory Barbarigo, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-06-18) (mass ("St. Ephrem of Syria, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-06-19) (mass ("St. Juliana Falconieri, Virgin")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-06-20) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2026-06-21) (mass ("Fourth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-06-22) (mass ("St. Paulinus, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-06-23) (mass ("Vigil of Nativity of St. John the Baptist")) (cls (2)) (colour ("violet")) (praef ("Common"))) + ((date 2026-06-24) (mass ("Nativity of St. John the Baptist")) (cls (1)) (colour ("white")) (praef ("Common"))) + ((date 2026-06-25) (mass ("St. William, Abbot")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-06-26) (mass ("Ss. John & Paul, Martyrs")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2026-06-27) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2026-06-28) (mass ("Fifth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-06-29) (mass ("Ss. Peter & Paul, Apostles")) (cls (1)) (colour ("red")) (praef ("Apostles"))) + ((date 2026-06-30) (mass ("Commemoration of St. Paul, Apostle")) (cls (3)) (colour ("red")) (praef ("Apostles"))) + ((date 2026-07-01) (mass ("Most Precious Blood of Our Lord")) (cls (1)) (colour ("red")) (praef ("Holy Cross"))) + ((date 2026-07-02) (mass ("Visitation of the BVM")) (cls (2)) (colour ("white")) (praef ("BVM"))) + ((date 2026-07-03) (mass ("St. Irenaeus, Doctor of the Church")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2026-07-04) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2026-07-05) (mass ("Sixth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-07-06) (mass ("St. Maria Goretti, Virgin Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2026-07-07) (mass ("Ss. Cyril & Methodius, Bishops & Confessors")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-07-08) (mass ("St. Elizabeth of Portugal, Queen & Widow")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-07-09) (mass ("Feria - Sixth Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2026-07-10) (mass ("Seven Holy Brothers, & Ss. Rufina & Secunda, Martyrs")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2026-07-11) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2026-07-12) (mass ("Seventh Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-07-13) (mass ("Feria - Seventh Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2026-07-14) (mass ("St. Bonaventure, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-07-15) (mass ("St. Henry II, Emperor, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-07-16) (mass ("Our Lady of Mt. Carmel")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2026-07-17) (mass ("St. Alexius, Confessor")) (cls (4)) (colour ("white")) (praef ("Common"))) + ((date 2026-07-18) (mass ("St. Camillus de Lellis, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-07-19) (mass ("Eighth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-07-20) (mass ("St. Jerome Emiliani, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-07-21) (mass ("St. Lawrence of Brindisi, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-07-22) (mass ("St. Mary Magdalene, Penitent")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-07-23) (mass ("St. Apollinarus, Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2026-07-24) (mass ("St. Christina, Virgin & Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2026-07-25) (mass ("St. James the Greater, Apostle")) (cls (2)) (colour ("red")) (praef ("Apostles"))) + ((date 2026-07-26) (mass ("Ninth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-07-27) (mass ("St. Pantaleon, Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2026-07-28) (mass ("Ss. Nazarius & Celsus, Martyrs, Victor I, Pope & Martyr,")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2026-07-29) (mass ("St. Martha, Virgin")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-07-30) (mass ("Ss. Abdon & Sennen, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2026-07-31) (mass ("St. Ignatius, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-08-01) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2026-08-02) (mass ("Tenth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-08-03) (mass ("The Finding of the Body of St. Stephen")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2026-08-04) (mass ("St. Dominic, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-08-05) (mass ("Our Lady of the Snows")) (cls (3)) (colour ("white")) (praef ("BVM"))) + ((date 2026-08-06) (mass ("Transfiguration of Our Lord")) (cls (2)) (colour ("white")) (praef ("Common"))) + ((date 2026-08-07) (mass ("St. Cajetan, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-08-08) (mass ("St. John Mary Vianney, Confessor & Priest")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-08-09) (mass ("Eleventh Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-08-10) (mass ("St. Lawrence, Deacon & Martyr")) (cls (2)) (colour ("red")) (praef ("Common"))) + ((date 2026-08-11) (mass ("Ss. Tiburtius & Susanna, Virgin, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2026-08-12) (mass ("St. Clare, Virgin")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-08-13) (mass ("Ss. Hippolytus & Cassian, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2026-08-14) (mass ("Vigil of the Assumption")) (cls (2)) (colour ("violet")) (praef ("Common"))) + ((date 2026-08-15) (mass ("Assumption of the BVM")) (cls (1)) (colour ("white")) (praef ("BVM"))) + ((date 2026-08-16) (mass ("Twelfth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-08-17) (mass ("St. Hyacinth of Poland, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-08-18) (mass ("St. Agapitus, Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2026-08-19) (mass ("St. John Eudes, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-08-20) (mass ("St. Bernard of Clairvaux, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-08-21) (mass ("St. Jane Frances de Chantal, Widow")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-08-22) (mass ("Immaculate Heart of Mary")) (cls (2)) (colour ("white")) (praef ("BVM"))) + ((date 2026-08-23) (mass ("Thirteenth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-08-24) (mass ("St. Bartholomew, Apostle")) (cls (2)) (colour ("red")) (praef ("Apostles"))) + ((date 2026-08-25) (mass ("St. Louis IX, King, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-08-26) (mass ("St. Zephirynus, Pope & Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2026-08-27) (mass ("St. Joseph Calasanctius, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-08-28) (mass ("St. Augustine, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-08-29) (mass ("Beheading of St. John the Baptist")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2026-08-30) (mass ("Fourteenth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-08-31) (mass ("St. Raymond Nonnatus, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-09-01) (mass ("St. Giles, Abbot")) (cls (4)) (colour ("white")) (praef ("Common"))) + ((date 2026-09-02) (mass ("St. Stephen, King, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-09-03) (mass ("St. Pius X, Pope & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-09-04) (mass ("Feria - Fourteenth Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2026-09-05) (mass ("St. Lawrence Justinian, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-09-06) (mass ("Fifteenth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-09-07) (mass ("Feria - Fifteenth Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2026-09-08) (mass ("Nativity of the BVM")) (cls (2)) (colour ("white")) (praef ("BVM"))) + ((date 2026-09-09) (mass ("St. Gorgonius, Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2026-09-10) (mass ("St. Nicholas of Tolentino, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-09-11) (mass ("Ss. Protus & Hyacinth, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2026-09-12) (mass ("Most Holy Name of Mary")) (cls (3)) (colour ("white")) (praef ("BVM"))) + ((date 2026-09-13) (mass ("Sixteenth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-09-14) (mass ("Exaltation of the Holy Cross")) (cls (2)) (colour ("red")) (praef ("Holy Cross"))) + ((date 2026-09-15) (mass ("Seven Sorrows of the BVM")) (cls (2)) (colour ("white")) (praef ("BVM"))) + ((date 2026-09-16) (mass ("St. Cornelius, Pope, & St. Cyprian, Bishop, Martyrs")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2026-09-17) (mass ("Stigmata of St. Francis")) (cls (4)) (colour ("white")) (praef ("Common"))) + ((date 2026-09-18) (mass ("St. Joseph of Cupertino, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-09-19) (mass ("St. Januarius, Bishop, & Companions, Martyrs")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2026-09-20) (mass ("Seventeenth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-09-21) (mass ("St. Matthew, Apostle & Evangelist")) (cls (2)) (colour ("red")) (praef ("Apostles"))) + ((date 2026-09-22) (mass ("St. Thomas of Villanova, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-09-23) (mass ("Ember Wednesday")) (cls (2)) (colour ("violet")) (praef ("Common"))) + ((date 2026-09-24) (mass ("Our Lady of Ransom")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2026-09-25) (mass ("Ember Friday")) (cls (2)) (colour ("violet")) (praef ("Common"))) + ((date 2026-09-26) (mass ("Ember Saturday")) (cls (2)) (colour ("violet")) (praef ("Common"))) + ((date 2026-09-27) (mass ("Eighteenth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-09-28) (mass ("St. Wenceslaus, Duke, Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2026-09-29) (mass ("St. Michael the Archangel")) (cls (1)) (colour ("white")) (praef ("Common"))) + ((date 2026-09-30) (mass ("St. Jerome, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-10-01) (mass ("St. Remigius, Bishop & Confessor")) (cls (4)) (colour ("white")) (praef ("Common"))) + ((date 2026-10-02) (mass ("Holy Guardian Angels")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-10-03) (mass ("St. Teresa of the Child Jesus, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-10-04) (mass ("Nineteenth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-10-05) (mass ("Ss. Placid & Companions, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2026-10-06) (mass ("St. Bruno, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-10-07) (mass ("Our Lady of the Rosary")) (cls (2)) (colour ("white")) (praef ("BVM"))) + ((date 2026-10-08) (mass ("St. Bridget, Widow")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-10-09) (mass ("St. John Leonard, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-10-10) (mass ("St. Francis Borgia, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-10-11) (mass ("Twentieth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-10-12) (mass ("Feria - Twentieth Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2026-10-13) (mass ("St. Edward, King, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-10-14) (mass ("St. Callistus I, Pope & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2026-10-15) (mass ("St. Teresa of Avila, Virgin")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-10-16) (mass ("St. Hedwig, Widow")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-10-17) (mass ("St. Margaret Mary Alacoque, Virgin")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-10-18) (mass ("Twenty-first Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-10-19) (mass ("St. Peter of Alcantara, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-10-20) (mass ("St. John Cantius, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-10-21) (mass ("St. Hilarion, Abbot")) (cls (4)) (colour ("white")) (praef ("Common"))) + ((date 2026-10-22) (mass ("Feria - Twenty-first Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2026-10-23) (mass ("St. Anthony Mary Claret, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-10-24) (mass ("St. Raphael the Archangel")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-10-25) (mass ("Christ the King")) (cls (1)) (colour ("white")) (praef ("Christ the King"))) + ((date 2026-10-26) (mass ("St. Evaristus, Pope & Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2026-10-27) (mass ("Feria - Twenty-second Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2026-10-28) (mass ("Ss. Simon & Jude, Apostles")) (cls (2)) (colour ("red")) (praef ("Apostles"))) + ((date 2026-10-29) (mass ("Feria - Twenty-second Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2026-10-30) (mass ("Feria - Twenty-second Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2026-10-31) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2026-11-01) (mass ("All Saints")) (cls (1)) (colour ("white")) (praef ("Common"))) + ((date 2026-11-02) (mass ("All Souls - Mass 1")) (cls (1)) (colour ("black")) (praef ("For the Dead"))) + ((date 2026-11-03) (mass ("Feria - Twenty-third Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2026-11-04) (mass ("St. Charles Borromeo, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-11-05) (mass ("The Holy Relics")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2026-11-06) (mass ("Feria - Twenty-third Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2026-11-07) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2026-11-08) (mass ("Resumed 5th Sunday after Epiphany")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-11-09) (mass ("Dedication of the Archbasilica of Our Holy Savior")) (cls (2)) (colour ("white")) (praef ("Common"))) + ((date 2026-11-10) (mass ("St. Andrew Avellino, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-11-11) (mass ("St. Martin of Tours, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-11-12) (mass ("St. Martin I, Pope & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2026-11-13) (mass ("St. Didacus, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-11-14) (mass ("St. Josaphat, Bishop & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2026-11-15) (mass ("Resumed 6th Sunday after Epiphany")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-11-16) (mass ("St. Gertrude, Virgin")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-11-17) (mass ("St. Gregory Thaumaturgus, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-11-18) (mass ("Dedication of the Basilicas of Ss. Peter & Paul")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-11-19) (mass ("St. Elizabeth of Hungary, Widow")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-11-20) (mass ("St. Felix of Valois, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-11-21) (mass ("Presentation of the BVM")) (cls (3)) (colour ("white")) (praef ("BVM"))) + ((date 2026-11-22) (mass ("Last Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2026-11-23) (mass ("St. Clement I, Pope & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2026-11-24) (mass ("St. John of the Cross, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-11-25) (mass ("St. Catherine of Alexandria, Virgin & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2026-11-26) (mass ("St. Sylvester, Abbot")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2026-11-27) (mass ("Our Lady of the Miraculous Medal")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2026-11-28) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) +) diff --git a/test/fixtures/efdotorg-ordo-2026-2027.sexp b/test/fixtures/efdotorg-ordo-2026-2027.sexp new file mode 100644 index 0000000..dc95641 --- /dev/null +++ b/test/fixtures/efdotorg-ordo-2026-2027.sexp @@ -0,0 +1,398 @@ +; test/fixtures/efdotorg-ordo-2026-2027.sexp -- efdotorg-preface task +; (2026-08-24-colitur-celebrant-rubrics-phase1): the THIRD independent +; preface witness (RG 482-499), extraordinaryform.org's 2026-2027 Ordo, +; extracted from the already-parsed, fidelity-audited corpus +; docs/research/ordo/ordo-2024-2027.json (SHA-256 18a417fb8b30dc438c3f12f64b43dfdf5e2e9313857f2eccd04bf02072ca7e3c) rather than +; re-parsed from the PDF -- see tools/extract_efdotorg_ordo.py's own +; header for the full characterisation this fixture rests on (the menu- +; trap office filter, the Christ-the-King classifier-gap recovery, why +; "Advent" is not baked into a single mapping here, the known Vigil-of- +; St-Lawrence gap, and the two source-PDF defects that turn out not to +; touch this field). +; +; Generator: tools/extract_efdotorg_ordo.py -- do not hand-edit; re-run +; against the same JSON and commit the diff instead. +; python3 tools/extract_efdotorg_ordo.py docs/research/ordo/ordo-2024-2027.json test/fixtures +; +; Source PDF (gitignored, CLAUDE.md: "docs/ is gitignored", see +; docs/research/ordo/SHA256SUMS for its own hash): 2026-2027Ordo.pdf, +; extraordinaryform.org. +; +; COVERAGE: 364 day-rows, 2026-11-29..2027-11-27 (this edition's own civil-date +; span, re-derived from the JSON's own seams -- see the generator's own +; EDITIONS comment). 1 row(s) are a genuine SOURCE GAP (2027-03-03 +; only, a PDF row-drop, ordo-fidelity-report.md) -- mass/cls/colour/praef +; all absent, the same shape a structurally blank day (Good Friday) uses. +; 1 further row(s) have mass/cls/colour but no praef at all +; (Good Friday -- RG 28, no Mass in the 1955-restored Holy Week). +; +; Each row's `praef` is RAW TEXT from the day's own OFFICE (after the +; menu-trap filter, with the Christ-the-King recovery already applied) -- +; classified against {!Colitur_kernel.Preface.t} by +; test/test_efdotorg_ordo.ml, not here. +( + ((date 2026-11-29) (mass ("First Sunday of Advent")) (cls (1)) (colour ("violet")) (praef ("Advent"))) + ((date 2026-11-30) (mass ("St. Andrew, Apostle")) (cls (2)) (colour ("red")) (praef ("Apostles"))) + ((date 2026-12-01) (mass ("Feria \226\128\147 First Sunday of Advent")) (cls (3)) (colour ("violet")) (praef ("Advent"))) + ((date 2026-12-02) (mass ("St. Bibiana, Virgin & Martyr")) (cls (3)) (colour ("red")) (praef ("Advent"))) + ((date 2026-12-03) (mass ("St. Francis Xavier, Confessor")) (cls (3)) (colour ("white")) (praef ("Advent"))) + ((date 2026-12-04) (mass ("St. Peter Chrysologus, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Advent"))) + ((date 2026-12-05) (mass ("Feria \226\128\147 First Sunday of Advent")) (cls (3)) (colour ("violet")) (praef ("Advent"))) + ((date 2026-12-06) (mass ("Second Sunday of Advent")) (cls (1)) (colour ("violet")) (praef ("Advent"))) + ((date 2026-12-07) (mass ("St. Ambrose, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Advent"))) + ((date 2026-12-08) (mass ("Immaculate Conception")) (cls (1)) (colour ("white")) (praef ("BVM"))) + ((date 2026-12-09) (mass ("Feria \226\128\147 Second Sunday of Advent")) (cls (3)) (colour ("violet")) (praef ("Advent"))) + ((date 2026-12-10) (mass ("Feria \226\128\147 Second Sunday of Advent")) (cls (3)) (colour ("violet")) (praef ("Advent"))) + ((date 2026-12-11) (mass ("St. Damasus I, Pope")) (cls (3)) (colour ("white")) (praef ("Advent"))) + ((date 2026-12-12) (mass ("Feria \226\128\147 Second Sunday of Advent")) (cls (3)) (colour ("rose")) (praef ("Advent"))) + ((date 2026-12-13) (mass ("Third Sunday of Advent \226\128\147 Gaudete")) (cls (1)) (colour ("violet")) (praef ("Advent"))) + ((date 2026-12-14) (mass ("Feria \226\128\147 Third Sunday of Advent")) (cls (3)) (colour ("violet")) (praef ("Advent"))) + ((date 2026-12-15) (mass ("Feria \226\128\147 Third Sunday of Advent")) (cls (3)) (colour ("violet")) (praef ("Advent"))) + ((date 2026-12-16) (mass ("Ember Wednesday of Advent")) (cls (2)) (colour ("violet")) (praef ("Advent"))) + ((date 2026-12-17) (mass ("Feria \226\128\147 Third Sunday of Advent")) (cls (2)) (colour ("violet")) (praef ("Advent"))) + ((date 2026-12-18) (mass ("Ember Friday of Advent")) (cls (2)) (colour ("violet")) (praef ("Advent"))) + ((date 2026-12-19) (mass ("Ember Saturday of Advent")) (cls (2)) (colour ("violet")) (praef ("Advent"))) + ((date 2026-12-20) (mass ("Fourth Sunday of Advent")) (cls (1)) (colour ("violet")) (praef ("Advent"))) + ((date 2026-12-21) (mass ("St. Thomas, Apostle")) (cls (2)) (colour ("red")) (praef ("Apostles"))) + ((date 2026-12-22) (mass ("Feria - Fourth Sunday of Advent")) (cls (2)) (colour ("violet")) (praef ("Advent"))) + ((date 2026-12-23) (mass ("Feria - Fourth Sunday of Advent")) (cls (2)) (colour ("violet")) (praef ("Advent"))) + ((date 2026-12-24) (mass ("Vigil of Nativity of Our Lord")) (cls (1)) (colour ("violet")) (praef ("Advent"))) + ((date 2026-12-25) (mass ("Nativity of Our Lord - Mass at Midnight")) (cls (1)) (colour ("white")) (praef ("Nativity"))) + ((date 2026-12-26) (mass ("Day II in the Octave, St. Stephen, Protomartyr")) (cls (2)) (colour ("red")) (praef ("Nativity"))) + ((date 2026-12-27) (mass ("Sunday within the Octave of Christmas")) (cls (2)) (colour ("white")) (praef ("Nativity"))) + ((date 2026-12-28) (mass ("Day IV in the Octave, Holy Innocents")) (cls (2)) (colour ("red")) (praef ("Nativity"))) + ((date 2026-12-29) (mass ("Day V in the Octave")) (cls (2)) (colour ("white")) (praef ("Nativity"))) + ((date 2026-12-30) (mass ("Day VI in the Octave")) (cls (2)) (colour ("white")) (praef ("Nativity"))) + ((date 2026-12-31) (mass ("Day VII in the Octave")) (cls (2)) (colour ("white")) (praef ("Nativity"))) + ((date 2027-01-01) (mass ("Day VIII in the Octave, Circumcision of Our Lord")) (cls (1)) (colour ("white")) (praef ("Nativity"))) + ((date 2027-01-02) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2027-01-03) (mass ("Holy Name of Jesus")) (cls (2)) (colour ("white")) (praef ("Nativity"))) + ((date 2027-01-04) (mass ("Feria in Christmastide")) (cls (4)) (colour ("white")) (praef ("Nativity"))) + ((date 2027-01-05) (mass ("St. Telesphorus, Pope & Martyr")) (cls (4)) (colour ("red")) (praef ("Nativity"))) + ((date 2027-01-06) (mass ("Epiphany of Our Lord")) (cls (1)) (colour ("white")) (praef ("Epiphany"))) + ((date 2027-01-07) (mass ("Feria of Epiphany")) (cls (4)) (colour ("white")) (praef ("Epiphany"))) + ((date 2027-01-08) (mass ("Feria of Epiphany")) (cls (4)) (colour ("white")) (praef ("Epiphany"))) + ((date 2027-01-09) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2027-01-10) (mass ("Holy Family")) (cls (2)) (colour ("white")) (praef ("Epiphany"))) + ((date 2027-01-11) (mass ("St. Hyginus, Pope & Martyr")) (cls (4)) (colour ("red")) (praef ("Epiphany"))) + ((date 2027-01-12) (mass ("Feria after Epiphany")) (cls (4)) (colour ("white")) (praef ("Epiphany"))) + ((date 2027-01-13) (mass ("Baptism of Our Lord")) (cls (2)) (colour ("white")) (praef ("Epiphany"))) + ((date 2027-01-14) (mass ("St. Hilary, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-01-15) (mass ("St. Paul, First Hermit, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-01-16) (mass ("St. Marcellus I, Pope & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2027-01-17) (mass ("Second Sunday after Epiphany")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-01-18) (mass ("St. Prisca, Virgin & Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2027-01-19) (mass ("Ss. Marius, Martha, Audifax, & Abachum, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2027-01-20) (mass ("Ss. Fabian, Pope, & Sebastian, Martyrs")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2027-01-21) (mass ("St. Agnes, Virgin & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2027-01-22) (mass ("Ss. Vincent & Anastasius, Martyrs")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2027-01-23) (mass ("St. Raymund of Pennafort, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-01-24) (mass ("Septuagesima")) (cls (2)) (colour ("violet")) (praef ("Holy Trinity"))) + ((date 2027-01-25) (mass ("Conversion of St. Paul, Apostle")) (cls (3)) (colour ("white")) (praef ("Apostles"))) + ((date 2027-01-26) (mass ("St. Polycarp, Bishop & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2027-01-27) (mass ("St. John Chrysostom, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-01-28) (mass ("St. Peter Nolasco, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-01-29) (mass ("St. Francis de Sales, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-01-30) (mass ("St. Martina, Virgin & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2027-01-31) (mass ("Sexagesima")) (cls (2)) (colour ("violet")) (praef ("Holy Trinity"))) + ((date 2027-02-01) (mass ("St. Ignatius of Antioch, Bishop & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2027-02-02) (mass ("and Purification of BVM")) (cls (2)) (colour ("white")) (praef ("Nativity"))) + ((date 2027-02-03) (mass ("St. Blaise, Bishop & Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2027-02-04) (mass ("St. Andrew Corsini, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-02-05) (mass ("St. Agatha, Virgin & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2027-02-06) (mass ("St. Titus, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-02-07) (mass ("Quinquagesima")) (cls (2)) (colour ("violet")) (praef ("Holy Trinity"))) + ((date 2027-02-08) (mass ("St. John of Matha, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-02-09) (mass ("St. Cyril, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-02-10) (mass ("and Ash Wednesday")) (cls (1)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-02-11) (mass ("Thursday after Ash Wednesday")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-02-12) (mass ("Friday after Ash Wednesday")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-02-13) (mass ("Saturday after Ash Wednesday")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-02-14) (mass ("1st Sunday of Lent")) (cls (1)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-02-15) (mass ("Monday after the 1st Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-02-16) (mass ("Tuesday after the 1st Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-02-17) (mass ("Ember Wednesday of Lent")) (cls (2)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-02-18) (mass ("Thursday after the 1st Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-02-19) (mass ("Ember Friday of Lent")) (cls (2)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-02-20) (mass ("Ember Saturday of Lent")) (cls (2)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-02-21) (mass ("2nd Sunday of Lent")) (cls (1)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-02-22) (mass ("Chair of St. Peter")) (cls (2)) (colour ("white")) (praef ("Apostles"))) + ((date 2027-02-23) (mass ("Tuesday after the 2nd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-02-24) (mass ("St. Matthias, Apostle")) (cls (2)) (colour ("red")) (praef ("Apostles"))) + ((date 2027-02-25) (mass ("Thursday after the 2nd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-02-26) (mass ("Friday after the 2nd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-02-27) (mass ("Saturday after the 2nd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-02-28) (mass ("3rd Sunday of Lent")) (cls (1)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-03-01) (mass ("Monday after the 3rd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-03-02) (mass ("Wednesday after the 3rd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-03-03) (mass ()) (cls ()) (colour ()) (praef ())) + ((date 2027-03-04) (mass ("Thursday after the 3rd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-03-05) (mass ("Friday after the 3rd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-03-06) (mass ("Saturday after the 3rd Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-03-07) (mass ("4th Sunday of Lent \226\128\147 L\195\166tare Sunday")) (cls (1)) (colour ("rose")) (praef ("Lent"))) + ((date 2027-03-08) (mass ("Monday after the 4th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-03-09) (mass ("Tuesday after the 4th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-03-10) (mass ("Wednesday after the 4th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-03-11) (mass ("Thursday after the 4th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-03-12) (mass ("Friday after the 4th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-03-13) (mass ("Saturday after the 4th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Lent"))) + ((date 2027-03-14) (mass ("Passion Sunday")) (cls (1)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2027-03-15) (mass ("Monday after the 5th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2027-03-16) (mass ("Tuesday after the 5th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2027-03-17) (mass ("Wednesday after the 5th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2027-03-18) (mass ("Thursday after the 5th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2027-03-19) (mass ("St. Joseph, Spouse of the BVM")) (cls (1)) (colour ("white")) (praef ("St. Joseph"))) + ((date 2027-03-20) (mass ("Saturday after the 5th Sunday of Lent")) (cls (3)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2027-03-21) (mass ("and Palm Sunday")) (cls (1)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2027-03-22) (mass ("Monday of Holy Week")) (cls (1)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2027-03-23) (mass ("Tuesday of Holy Week")) (cls (1)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2027-03-24) (mass ("Wednesday of Holy Week")) (cls (1)) (colour ("violet")) (praef ("Holy Cross"))) + ((date 2027-03-25) (mass ("Holy Thursday")) (cls (1)) (colour ("white")) (praef ("Holy Cross"))) + ((date 2027-03-26) (mass ("Good Friday")) (cls (1)) (colour ("black")) (praef ())) + ((date 2027-03-27) (mass ("and Easter Vigil Mass (circa midnight)")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2027-03-28) (mass ("Easter Sunday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2027-03-29) (mass ("Easter Monday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2027-03-30) (mass ("Easter Tuesday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2027-03-31) (mass ("Easter Wednesday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2027-04-01) (mass ("Easter Thursday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2027-04-02) (mass ("Easter Friday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2027-04-03) (mass ("Easter Saturday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2027-04-04) (mass ("Low Sunday")) (cls (1)) (colour ("white")) (praef ("Easter"))) + ((date 2027-04-05) (mass ("Annunciation of the BVM")) (cls (1)) (colour ("white")) (praef ("BVM"))) + ((date 2027-04-06) (mass ("Feria - First Sunday after Easter")) (cls (4)) (colour ("white")) (praef ("Easter"))) + ((date 2027-04-07) (mass ("Feria - First Sunday after Easter")) (cls (4)) (colour ("white")) (praef ("Easter"))) + ((date 2027-04-08) (mass ("Feria - First Sunday after Easter")) (cls (4)) (colour ("white")) (praef ("Easter"))) + ((date 2027-04-09) (mass ("Feria - First Sunday after Easter")) (cls (4)) (colour ("white")) (praef ("Easter"))) + ((date 2027-04-10) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2027-04-11) (mass ("Second Sunday after Easter")) (cls (2)) (colour ("white")) (praef ("Easter"))) + ((date 2027-04-12) (mass ("Feria - Second Sunday after Easter")) (cls (4)) (colour ("white")) (praef ("Easter"))) + ((date 2027-04-13) (mass ("St.Hermenegild, Martyr")) (cls (3)) (colour ("red")) (praef ("Easter"))) + ((date 2027-04-14) (mass ("St. Justin, Martyr")) (cls (3)) (colour ("red")) (praef ("Easter"))) + ((date 2027-04-15) (mass ("Feria - Second Sunday after Easter")) (cls (4)) (colour ("white")) (praef ("Easter"))) + ((date 2027-04-16) (mass ("Feria - Second Sunday after Easter")) (cls (4)) (colour ("white")) (praef ("Easter"))) + ((date 2027-04-17) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2027-04-18) (mass ("Third Sunday after Easter")) (cls (2)) (colour ("white")) (praef ("Easter"))) + ((date 2027-04-19) (mass ("Feria - Third Sunday after Easter")) (cls (4)) (colour ("white")) (praef ("Easter"))) + ((date 2027-04-20) (mass ("Feria - Third Sunday after Easter")) (cls (4)) (colour ("white")) (praef ("Easter"))) + ((date 2027-04-21) (mass ("St. Anselm, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2027-04-22) (mass ("Ss. Soter & Cajus, Popes & Martyrs")) (cls (3)) (colour ("red")) (praef ("Easter"))) + ((date 2027-04-23) (mass ("St. George, Martyr")) (cls (4)) (colour ("red")) (praef ("Easter"))) + ((date 2027-04-24) (mass ("St. Fidelis. Martyr")) (cls (3)) (colour ("red")) (praef ("Easter"))) + ((date 2027-04-25) (mass ("Fourth Sunday after Easter")) (cls (2)) (colour ("white")) (praef ("Easter"))) + ((date 2027-04-26) (mass ("Ss. Cletus & Marcellinus, Popes & Martyrs")) (cls (3)) (colour ("red")) (praef ("Easter"))) + ((date 2027-04-27) (mass ("St. Peter Canisius, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2027-04-28) (mass ("St. Paul of the Cross, Confessor")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2027-04-29) (mass ("St. Peter of Verona, Martyr")) (cls (3)) (colour ("red")) (praef ("Easter"))) + ((date 2027-04-30) (mass ("St. Catherine of Siena, Virgin")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2027-05-01) (mass ("St. Joseph the Workman, Confessor")) (cls (1)) (colour ("white")) (praef ("St. Joseph"))) + ((date 2027-05-02) (mass ("5th Sunday after Easter")) (cls (2)) (colour ("white")) (praef ("Easter"))) + ((date 2027-05-03) (mass ("Ss. Alexander, Eventius, & Theodulus, Martyrs")) (cls (4)) (colour ("red")) (praef ("Easter"))) + ((date 2027-05-04) (mass ("St. Monica, Widow")) (cls (3)) (colour ("white")) (praef ("Easter"))) + ((date 2027-05-05) (mass ("Vigil of Ascension")) (cls (2)) (colour ("white")) (praef ("Easter"))) + ((date 2027-05-06) (mass ("Ascension of Our Lord")) (cls (1)) (colour ("white")) (praef ("Ascension"))) + ((date 2027-05-07) (mass ("St. Stanislaus, Bishop & Martyr")) (cls (3)) (colour ("red")) (praef ("Ascension"))) + ((date 2027-05-08) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2027-05-09) (mass ("Sunday after the Ascension")) (cls (2)) (colour ("white")) (praef ("Ascension"))) + ((date 2027-05-10) (mass ("St. Antoninus, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Ascension"))) + ((date 2027-05-11) (mass ("Ss. Philip & James, Apostles")) (cls (2)) (colour ("red")) (praef ("Apostles"))) + ((date 2027-05-12) (mass ("Ss. Nereus, Achilleus, Domitila, & Pancras, Martyrs")) (cls (3)) (colour ("red")) (praef ("Ascension"))) + ((date 2027-05-13) (mass ("St. Robert Bellarmine, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Ascension"))) + ((date 2027-05-14) (mass ("St. Boniface, Martyr")) (cls (4)) (colour ("red")) (praef ("Ascension"))) + ((date 2027-05-15) (mass ("Vigil of Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2027-05-16) (mass ("Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2027-05-17) (mass ("Monday after Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2027-05-18) (mass ("Tuesday after Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2027-05-19) (mass ("Ember Wednesday of Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2027-05-20) (mass ("Thursday after Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2027-05-21) (mass ("Ember Friday of Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2027-05-22) (mass ("Ember Saturday of Pentecost")) (cls (1)) (colour ("red")) (praef ("Holy Spirit"))) + ((date 2027-05-23) (mass ("Trinity Sunday")) (cls (1)) (colour ("white")) (praef ("Holy Trinity"))) + ((date 2027-05-24) (mass ("Feria - First Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2027-05-25) (mass ("St. Gregory VII, Pope & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-05-26) (mass ("St. Philip Neri, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-05-27) (mass ("Corpus Christi")) (cls (1)) (colour ("white")) (praef ("Common"))) + ((date 2027-05-28) (mass ("St. Augustine of Canterbury, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-05-29) (mass ("St. Mary Magdalen de Pazzi, Virgin")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-05-30) (mass ("Second Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-05-31) (mass ("Queenship of the BVM")) (cls (2)) (colour ("white")) (praef ("BVM"))) + ((date 2027-06-01) (mass ("St. Angela Merici, Virgin")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-06-02) (mass ("Ss. Marcellinus, Peter, & Erasmus, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2027-06-03) (mass ("Feria - Second Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2027-06-04) (mass ("Most Sacred Heart of Jesus")) (cls (1)) (colour ("white")) (praef ("Sacred Heart"))) + ((date 2027-06-05) (mass ("St. Boniface, Bishop & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2027-06-06) (mass ("Third Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-06-07) (mass ("Feria - Third Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2027-06-08) (mass ("Feria - Third Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2027-06-09) (mass ("Ss. Primus & Felician, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2027-06-10) (mass ("St. Margaret, Queen of Scotland, Widow")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-06-11) (mass ("St. Barnabas, Apostle")) (cls (3)) (colour ("red")) (praef ("Apostles"))) + ((date 2027-06-12) (mass ("St. John of San Facundo, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-06-13) (mass ("Fourth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-06-14) (mass ("St. Basil the Great, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-06-15) (mass ("Ss. Vitus, Modestus, & Crescentia, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2027-06-16) (mass ("Feria - Fourth Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2027-06-17) (mass ("St. Gregory Barbarigo, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-06-18) (mass ("St. Ephrem of Syria, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-06-19) (mass ("St. Juliana Falconieri, Virgin")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-06-20) (mass ("Fifth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-06-21) (mass ("St. Aloysius Gonzaga, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-06-22) (mass ("St. Paulinus, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-06-23) (mass ("Vigil of Nativity of St. John the Baptist")) (cls (2)) (colour ("violet")) (praef ("Common"))) + ((date 2027-06-24) (mass ("Nativity of St. John the Baptist")) (cls (1)) (colour ("white")) (praef ("Common"))) + ((date 2027-06-25) (mass ("St. William, Abbot")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-06-26) (mass ("Ss. John & Paul, Martyrs")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2027-06-27) (mass ("Sixth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-06-28) (mass ("Vigil of Ss. Peter & Paul")) (cls (2)) (colour ("violet")) (praef ("Common"))) + ((date 2027-06-29) (mass ("Ss. Peter & Paul, Apostles")) (cls (1)) (colour ("red")) (praef ("Apostles"))) + ((date 2027-06-30) (mass ("Commemoration of St. Paul, Apostle")) (cls (3)) (colour ("red")) (praef ("Apostles"))) + ((date 2027-07-01) (mass ("Most Precious Blood of Our Lord")) (cls (1)) (colour ("red")) (praef ("Holy Cross"))) + ((date 2027-07-02) (mass ("Visitation of the BVM")) (cls (2)) (colour ("white")) (praef ("BVM"))) + ((date 2027-07-03) (mass ("St. Irenaeus, Doctor of the Church")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2027-07-04) (mass ("Seventh Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-07-05) (mass ("St. Anthony Mary Zaccaria, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-07-06) (mass ("St. Maria Goretti, Virgin Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2027-07-07) (mass ("Ss. Cyril & Methodius, Bishops & Confessors")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-07-08) (mass ("St. Elizabeth of Portugal, Queen & Widow")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-07-09) (mass ("Feria - Seventh Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2027-07-10) (mass ("Seven Holy Brothers, & Ss. Rufina & Secunda, Martyrs")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2027-07-11) (mass ("Eighth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-07-12) (mass ("St. John Gualbert, Abbot")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-07-13) (mass ("Feria - Eighth Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2027-07-14) (mass ("St. Bonaventure, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-07-15) (mass ("St. Henry II, Emperor, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-07-16) (mass ("Our Lady of Mt. Carmel")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2027-07-17) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2027-07-18) (mass ("Ninth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-07-19) (mass ("St. Vincent de Paul, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-07-20) (mass ("St. Jerome Emiliani, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-07-21) (mass ("St. Lawrence of Brindisi, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-07-22) (mass ("St. Mary Magdalene, Penitent")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-07-23) (mass ("St. Apollinarus, Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2027-07-24) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2027-07-25) (mass ("Tenth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-07-26) (mass ("St. Anne, Mother of the BVM")) (cls (2)) (colour ("white")) (praef ("Common"))) + ((date 2027-07-27) (mass ("St. Pantaleon, Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2027-07-28) (mass ("Ss. Nazarius & Celsus, Martyrs, Victor I, Pope & Martyr,")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2027-07-29) (mass ("St. Martha, Virgin")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-07-30) (mass ("Ss. Abdon & Sennen, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2027-07-31) (mass ("St. Ignatius, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-08-01) (mass ("Eleventh Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-08-02) (mass ("St. Alphonsus of Liguori, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-08-03) (mass ("The Finding of the Body of St. Stephen")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2027-08-04) (mass ("St. Dominic, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-08-05) (mass ("Our Lady of the Snows")) (cls (3)) (colour ("white")) (praef ("BVM"))) + ((date 2027-08-06) (mass ("Transfiguration of Our Lord")) (cls (2)) (colour ("white")) (praef ("Common"))) + ((date 2027-08-07) (mass ("St. Cajetan, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-08-08) (mass ("Twelfth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-08-09) (mass ("St. Romanus, Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2027-08-10) (mass ("St. Lawrence, Deacon & Martyr")) (cls (2)) (colour ("red")) (praef ("Common"))) + ((date 2027-08-11) (mass ("Ss. Tiburtius & Susanna, Virgin, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2027-08-12) (mass ("St. Clare, Virgin")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-08-13) (mass ("Ss. Hippolytus & Cassian, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2027-08-14) (mass ("Vigil of the Assumption")) (cls (2)) (colour ("violet")) (praef ("Common"))) + ((date 2027-08-15) (mass ("Assumption of the BVM")) (cls (1)) (colour ("white")) (praef ("BVM"))) + ((date 2027-08-16) (mass ("St. Joachim, Father of the BVM")) (cls (2)) (colour ("white")) (praef ("Common"))) + ((date 2027-08-17) (mass ("St. Hyacinth of Poland, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-08-18) (mass ("St. Agapitus, Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2027-08-19) (mass ("St. John Eudes, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-08-20) (mass ("St. Bernard of Clairvaux, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-08-21) (mass ("St. Jane Frances de Chantal, Widow")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-08-22) (mass ("Fourteenth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-08-23) (mass ("St. Philip Benizi, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-08-24) (mass ("St. Bartholomew, Apostle")) (cls (2)) (colour ("red")) (praef ("Apostles"))) + ((date 2027-08-25) (mass ("St. Louis IX, King, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-08-26) (mass ("St. Zephirynus, Pope & Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2027-08-27) (mass ("St. Joseph Calasanctius, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-08-28) (mass ("St. Augustine, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-08-29) (mass ("Fifteenth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-08-30) (mass ("St. Rose of Lima, Virgin")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-08-31) (mass ("St. Raymond Nonnatus, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-09-01) (mass ("St. Giles, Abbot")) (cls (4)) (colour ("white")) (praef ("Common"))) + ((date 2027-09-02) (mass ("St. Stephen, King, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-09-03) (mass ("St. Pius X, Pope & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-09-04) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2027-09-05) (mass ("Sixteenth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-09-06) (mass ("Feria - Sixteenth Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2027-09-07) (mass ("Feria - Sixteenth Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2027-09-08) (mass ("Nativity of the BVM")) (cls (2)) (colour ("white")) (praef ("BVM"))) + ((date 2027-09-09) (mass ("St. Gorgonius, Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2027-09-10) (mass ("St. Nicholas of Tolentino, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-09-11) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2027-09-12) (mass ("Seventeenth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-09-13) (mass ("Feria - Seventeenth Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2027-09-14) (mass ("Exaltation of the Holy Cross")) (cls (2)) (colour ("red")) (praef ("Holy Cross"))) + ((date 2027-09-15) (mass ("Seven Sorrows of the BVM")) (cls (2)) (colour ("white")) (praef ("BVM"))) + ((date 2027-09-16) (mass ("St. Cornelius, Pope, & St. Cyprian, Bishop, Martyrs")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2027-09-17) (mass ("Stigmata of St. Francis")) (cls (4)) (colour ("white")) (praef ("Common"))) + ((date 2027-09-18) (mass ("St. Joseph of Cupertino, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-09-19) (mass ("Eighteenth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-09-20) (mass ("St. Eustace & Companions, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2027-09-21) (mass ("St. Matthew, Apostle & Evangelist")) (cls (2)) (colour ("red")) (praef ("Apostles"))) + ((date 2027-09-22) (mass ("Ember Wednesday")) (cls (2)) (colour ("violet")) (praef ("Common"))) + ((date 2027-09-23) (mass ("St. Linus, Pope & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2027-09-24) (mass ("Ember Friday")) (cls (2)) (colour ("violet")) (praef ("Common"))) + ((date 2027-09-25) (mass ("Ember Saturday")) (cls (2)) (colour ("violet")) (praef ("Common"))) + ((date 2027-09-26) (mass ("Nineteenth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-09-27) (mass ("Ss. Cosmas & Damian, Martyrs")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2027-09-28) (mass ("St. Wenceslaus, Duke, Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2027-09-29) (mass ("St. Michael the Archangel")) (cls (1)) (colour ("white")) (praef ("Common"))) + ((date 2027-09-30) (mass ("St. Jerome, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-10-01) (mass ("St. Remigius, Bishop & Confessor")) (cls (4)) (colour ("white")) (praef ("Common"))) + ((date 2027-10-02) (mass ("Holy Guardian Angels")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-10-03) (mass ("Twentieth Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-10-04) (mass ("St. Francis of Assisi, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-10-05) (mass ("Ss. Placid & Companions, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2027-10-06) (mass ("St. Bruno, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-10-07) (mass ("Our Lady of the Rosary")) (cls (2)) (colour ("white")) (praef ("BVM"))) + ((date 2027-10-08) (mass ("St. Bridget, Widow")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-10-09) (mass ("St. John Leonard, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-10-10) (mass ("Twenty-first Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-10-11) (mass ("Maternity of the BVM")) (cls (2)) (colour ("white")) (praef ("BVM"))) + ((date 2027-10-12) (mass ("Feria - Twenty-first Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2027-10-13) (mass ("St. Edward, King, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-10-14) (mass ("St. Callistus I, Pope & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2027-10-15) (mass ("St. Teresa of Avila, Virgin")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-10-16) (mass ("St. Hedwig, Widow")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-10-17) (mass ("Twenty-second Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-10-18) (mass ("St. Luke the Evangelist")) (cls (2)) (colour ("red")) (praef ("Apostles"))) + ((date 2027-10-19) (mass ("St. Peter of Alcantara, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-10-20) (mass ("St. John Cantius, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-10-21) (mass ("St. Hilarion, Abbot")) (cls (4)) (colour ("white")) (praef ("Common"))) + ((date 2027-10-22) (mass ("Feria - Twenty-second Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2027-10-23) (mass ("St. Anthony Mary Claret, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-10-24) (mass ("Twenty-third Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-10-25) (mass ("Ss. Chrysanthus & Darius, Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2027-10-26) (mass ("St. Evaristus, Pope & Martyr")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2027-10-27) (mass ("Feria - Twenty-third Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2027-10-28) (mass ("Ss. Simon & Jude, Apostles")) (cls (2)) (colour ("red")) (praef ("Apostles"))) + ((date 2027-10-29) (mass ("Feria - Twenty-third Sunday after Pentecost")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2027-10-30) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2027-10-31) (mass ("Christ the King")) (cls (1)) (colour ("white")) (praef ("Christ the King"))) + ((date 2027-11-01) (mass ("All Saints")) (cls (1)) (colour ("white")) (praef ("Common"))) + ((date 2027-11-02) (mass ("All Souls - Mass 1")) (cls (1)) (colour ("black")) (praef ("For the Dead"))) + ((date 2027-11-03) (mass ("Feria - Resumed 4th Sunday after Epiphany")) (cls (4)) (colour ("green")) (praef ("Common"))) + ((date 2027-11-04) (mass ("St. Charles Borromeo, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-11-05) (mass ("The Holy Relics")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2027-11-06) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) + ((date 2027-11-07) (mass ("Resumed 5th Sunday after Epiphany")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-11-08) (mass ("Four Holy Crowned Martyrs")) (cls (4)) (colour ("red")) (praef ("Common"))) + ((date 2027-11-09) (mass ("Dedication of the Archbasilica of Our Holy Savior")) (cls (2)) (colour ("white")) (praef ("Common"))) + ((date 2027-11-10) (mass ("St. Andrew Avellino, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-11-11) (mass ("St. Martin of Tours, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-11-12) (mass ("St. Martin I, Pope & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2027-11-13) (mass ("St. Didacus, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-11-14) (mass ("Resumed 6th Sunday after Epiphany")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-11-15) (mass ("St. Albert the Great, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-11-16) (mass ("St. Gertrude, Virgin")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-11-17) (mass ("St. Gregory Thaumaturgus, Bishop & Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-11-18) (mass ("Dedication of the Basilicas of Ss. Peter & Paul")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-11-19) (mass ("St. Elizabeth of Hungary, Widow")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-11-20) (mass ("St. Felix of Valois, Confessor")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-11-21) (mass ("Last Sunday after Pentecost")) (cls (2)) (colour ("green")) (praef ("Holy Trinity"))) + ((date 2027-11-22) (mass ("St. Cecilia, Virgin & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2027-11-23) (mass ("St. Clement I, Pope & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2027-11-24) (mass ("St. John of the Cross, Doctor of the Church")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-11-25) (mass ("St. Catherine of Alexandria, Virgin & Martyr")) (cls (3)) (colour ("red")) (praef ("Common"))) + ((date 2027-11-26) (mass ("St. Sylvester, Abbot")) (cls (3)) (colour ("white")) (praef ("Common"))) + ((date 2027-11-27) (mass ("Saturday of Our Lady")) (cls (4)) (colour ("white")) (praef ("BVM"))) +) diff --git a/test/test_colitur.ml b/test/test_colitur.ml index 7708fef..9eefecd 100644 --- a/test/test_colitur.ml +++ b/test/test_colitur.ml @@ -17,6 +17,8 @@ let () = Test_differential.suite; Test_oracle.suite; Test_oracle.suite_2038; Test_oracle.suite_2035; Test_lms_ordo.suite_2023_2024; Test_lms_ordo.suite_2024_2025; Test_lms_ordo.suite_2025_2026; Test_lms_ordo.suite_allow_list; Test_fiuv_ordo.suite; + Test_efdotorg_ordo.suite_2024_2025; Test_efdotorg_ordo.suite_2025_2026; Test_efdotorg_ordo.suite_2026_2027; + Test_efdotorg_ordo.suite_allow_list; Test_golden.suite; ("lectionary", Test_lectionary.suite); ("lectionary-ef", Test_lectionary_ef.suite); diff --git a/test/test_efdotorg_ordo.ml b/test/test_efdotorg_ordo.ml new file mode 100644 index 0000000..6200cd9 --- /dev/null +++ b/test/test_efdotorg_ordo.ml @@ -0,0 +1,403 @@ +(* efdotorg-preface task (2026-08-24-colitur-celebrant-rubrics-phase1): the + THIRD independent preface witness, extraordinaryform.org's own three + annual Ordo editions (2024-2025, 2025-2026, 2026-2027). A prior task + (2026-08-21-colitur-celebrant-rubrics-phase1, see + .superpowers/sdd/2026-08-21-colitur-celebrant-rubrics-phase1/preface- + witnesses-report.md) DECLINED to wire this source in, for two reasons: + an unexplained "Advent" label in the preface column, and this corpus's + own known Vigil-of-St-Lawrence gap. Both are now characterisation work, + not blockers -- see tools/extract_efdotorg_ordo.py's own header for the + full account this file's own comparator relies on. + + WHY THIS LAYER IS DIFFERENT FROM test_fiuv_ordo.ml/test_lms_ordo.ml: + this source prints ONE preface value per day (unlike the LMS Ordo's own + option lists), already reduced to the day's own real OFFICE by the + menu-trap filter baked into the generator (see that script's own + header, finding 1) -- so the comparison here is a single equality + check per day, not a membership check. It is also the only one of the + three witnesses whose own JSON, not a fresh pdftotext dump, is the + input -- the JSON is already fidelity-audited + (.superpowers/ordo-fidelity-report.md, 1091/1091 against an + independently-written parser) and is treated as the source; this file + does not re-parse the PDFs. + + SCOPE: preface only (RG 482-499, {!Rite_ef.Rubrics_ef.preface}) -- this + source carries no Creed/Gloria/Te Deum data at all + (docs/research/ordo/PROVENANCE-ordo-corpus.md: "The extraordinaryform.org + editions carry NO Gloria or Creed"), so there is nothing else to + compare it against. *) + +module Cal = Colitur_kernel.Calendar +module Layer = Colitur_kernel.Layer +module Overlay = Colitur_kernel.Overlay +module LD = Colitur_kernel.Liturgical_day +module Date = Colitur_kernel.Date +module V = Rite_ef.Vocab_ef +module Preface = Colitur_kernel.Preface + +let sanctoral_path = "../data/ef/sanctoral.sexp" +let adjustments_path = "../data/ef/adjustments.sexp" + +(* Duplicated, not shared -- test_fiuv_ordo.ml/test_lms_ordo.ml's own + identical function carries the same "no shared .mli" reasoning. *) +let sha256_of_file path = + let tmp = Filename.temp_file "colitur_efdotorg_ordo_sha256" ".txt" in + Fun.protect + ~finally:(fun () -> try Sys.remove tmp with Sys_error _ -> ()) + (fun () -> + let cmd = Printf.sprintf "sha256sum %s > %s" (Filename.quote path) (Filename.quote tmp) in + let rc = Sys.command cmd in + if rc <> 0 then Alcotest.failf "sha256sum exited %d for %s (is it on PATH?)" rc path; + let ic = open_in tmp in + let line = + try input_line ic + with End_of_file -> + close_in ic; + Alcotest.failf "sha256sum produced no output for %s" path + in + close_in ic; + match String.index_opt line ' ' with + | Some i -> String.sub line 0 i + | None -> Alcotest.failf "unexpected sha256sum output for %s: %S" path line) + +let real_layer () = + let layer = + match Layer.load V.rank_of_sexp sanctoral_path with + | Ok l -> l + | Error e -> Alcotest.failf "%s: failed to load: %s" sanctoral_path e + in + let overlay = + match Overlay.load V.rank_of_sexp adjustments_path with + | Ok o -> o + | Error e -> Alcotest.failf "%s: failed to load: %s" adjustments_path e + in + let layer, diagnostics = Overlay.apply layer overlay in + Alcotest.(check (list string)) "the committed overlay applies cleanly, no diagnostics" [] + (List.map Overlay.diagnostic_to_string diagnostics); + layer + +let real_lectionary () = + match Colitur_kernel.Lectionary.load "../data/ef/lectionary.sexp" with + | Ok l -> l + | Error e -> Alcotest.failf "../data/ef/lectionary.sexp: failed to load: %s" e + +let real_commons () = + match Rite_ef.Lectionary_ef.Commons.load "../data/ef/commons.sexp" with + | Ok c -> c + | Error e -> Alcotest.failf "../data/ef/commons.sexp: failed to load: %s" e + +(* ---------------------------------------------------------------------- *) +(* The Ordo side: the sexp row, mirrored from tools/extract_efdotorg_ordo.py's *) +(* own row shape. *) +(* ---------------------------------------------------------------------- *) + +open Sexplib0.Sexp_conv + +type ordo_row = { date : string; mass : string option; cls : int option; colour : string option; praef : string option } +[@@deriving sexp] + +let ordo_rows fixture_path = + let sexp = + try Sexplib.Sexp.load_sexp fixture_path + with e -> Alcotest.failf "%s: failed to load: %s" fixture_path (Printexc.to_string e) + in + list_of_sexp ordo_row_of_sexp sexp + +(* ---------------------------------------------------------------------- *) +(* The colitur side, over the same window -- mirrors test_fiuv_ordo.ml's *) +(* own [colitur_rows]. *) +(* ---------------------------------------------------------------------- *) + +type colitur_row = { c_date : string; c_weekday : Date.weekday; c_preface : Preface.t option } + +let colitur_rows ~year_lo ~year_hi ~window_first ~window_last = + let layer = real_layer () in + let rite = Rite_ef.context ~lectionary:(real_lectionary ()) ~commons:(real_commons ()) in + let by_rata : (int, (V.season, V.rank) LD.t) Hashtbl.t = Hashtbl.create 800 in + for y = year_lo to year_hi do + let days = Cal.year rite layer y in + Array.iter (fun (d : (V.season, V.rank) LD.t) -> Hashtbl.replace by_rata (Date.to_rata d.LD.date) d) days + done; + let mk s = match Date.of_iso8601 s with Ok d -> d | Error e -> Alcotest.failf "%s: %s" s e in + let rows = ref [] in + let d = ref (mk window_first) in + let stop = mk window_last in + while Date.compare !d stop <= 0 do + (match Hashtbl.find_opt by_rata (Date.to_rata !d) with + | Some day -> + rows := + { c_date = Date.to_iso8601 day.LD.date; c_weekday = Date.weekday day.LD.date; c_preface = day.LD.preface } + :: !rows + | None -> Alcotest.failf "no colitur day resolved for %s" (Date.to_iso8601 !d)); + d := Date.add_days !d 1 + done; + List.rev !rows + +(* ---------------------------------------------------------------------- *) +(* Classification -- see tools/extract_efdotorg_ordo.py's own header, *) +(* finding 3, for why "Advent" needs the day's own weekday rather than a *) +(* static table entry: RG 494(b) grants the TRINITY preface on every *) +(* Advent SUNDAY, RG 498 the residual COMMON on every Advent FERIA, and *) +(* this source's own "Advent" label does not distinguish the two. Every *) +(* other raw value maps 1:1 onto exactly one {!Preface.t} constructor -- *) +(* verified exhaustive over the whole 1091-day office-selected population *) +(* while building this comparison (16 distinct raw values: these 14 fixed *) +(* mappings, "Advent" itself, and [None]) -- unlike the FIUV/LMS sources, *) +(* nothing here is genuinely unclassifiable. *) +(* ---------------------------------------------------------------------- *) + +let classify_praef ~(weekday : Date.weekday) (raw : string) : Preface.t option = + match raw with + | "Common" -> Some Preface.Common + | "For the Dead" -> Some Preface.Requiem + | "Easter" -> Some Preface.Easter + | "Lent" -> Some Preface.Lent + | "BVM" -> Some Preface.Bvm + | "Holy Trinity" -> Some Preface.Trinity + | "Holy Cross" -> Some Preface.Holy_cross + | "Nativity" -> Some Preface.Nativity + | "Apostles" -> Some Preface.Apostles + | "Ascension" -> Some Preface.Ascension + | "Holy Spirit" -> Some Preface.Holy_spirit + | "Epiphany" -> Some Preface.Epiphany + | "St. Joseph" -> Some Preface.St_joseph + | "Sacred Heart" -> Some Preface.Sacred_heart + | "Christ the King" -> Some Preface.Christ_the_king + | "Advent" -> Some (if weekday = Date.Sun then Preface.Trinity else Preface.Common) + | _ -> None + +(* ---------------------------------------------------------------------- *) +(* data/ef/expected-divergences-efdotorg.sexp -- same shape as the other *) +(* Ordo allow-lists' own [allow_entry]. A SEPARATE file: this Ordo is a *) +(* FIFTH lineage (lectio/missalemeum, LMS, FIUV, and now this one), a *) +(* different publisher and a different compiler from all three others. *) +(* ---------------------------------------------------------------------- *) + +type allow_entry = { id : string; citation : string; verdict : string; note : string; expected_rows : int } +[@@deriving sexp] + +let load_allow_list allow_list_path = + let sexps = + try Sexplib.Sexp.load_sexps allow_list_path + with e -> Alcotest.failf "%s: failed to load: %s" allow_list_path (Printexc.to_string e) + in + List.map allow_entry_of_sexp sexps + +let allow_list_path = "../data/ef/expected-divergences-efdotorg.sexp" + +(* ---------------------------------------------------------------------- *) +(* [make_suite]: one edition's worth of tests, parameterised -- mirrors *) +(* test_lms_ordo.ml's own shape. *) +(* ---------------------------------------------------------------------- *) + +let make_suite ~label ~fixture_path ~fixture_sha256 ~window_first ~window_last ~year_lo ~year_hi ~expected_rows + ~expected_no_data ~allow_list_id_for_date = + let test_fixture_checksum () = + Alcotest.(check string) "fixture SHA-256 matches its provenance note" fixture_sha256 + (sha256_of_file fixture_path) + in + let test_dates_align () = + let ordo = ordo_rows fixture_path in + let colitur = colitur_rows ~year_lo ~year_hi ~window_first ~window_last in + Alcotest.(check int) (Printf.sprintf "the Ordo fixture has %d rows (%s..%s)" expected_rows window_first window_last) + expected_rows (List.length ordo); + Alcotest.(check int) "colitur resolved the same number of days" (List.length ordo) (List.length colitur); + (match ordo with o :: _ -> Alcotest.(check string) "first date" window_first o.date | [] -> Alcotest.fail "empty"); + (match List.rev ordo with + | o :: _ -> Alcotest.(check string) "last date" window_last o.date + | [] -> Alcotest.fail "empty"); + let mismatched = + List.filter_map + (fun (o, c) -> if String.equal o.date c.c_date then None else Some (o.date, c.c_date)) + (List.combine ordo colitur) + in + Alcotest.(check (list (pair string string))) "no misaligned dates" [] mismatched + in + (* This window's own Good Friday(s), RE-DERIVED from + {!Colitur_kernel.Computus.gregorian_easter} for every civil year the + window touches (never hardcoded), plus this edition's own share of + the single known SOURCE GAP (2027-03-03) -- the only two shapes a row + can have no [praef] at all for (see tools/extract_efdotorg_ordo.py's + own header, findings 2 and 5). *) + let window_no_praef () = + let first_year = int_of_string (String.sub window_first 0 4) in + let last_year = int_of_string (String.sub window_last 0 4) in + let good_fridays = + List.map + (fun y -> Date.to_iso8601 (Date.add_days (Colitur_kernel.Computus.gregorian_easter y) (-2))) + (List.init (last_year - first_year + 1) (fun i -> first_year + i)) + in + let candidates = good_fridays @ [ "2027-03-03" ] in + List.filter (fun d -> String.compare d window_first >= 0 && String.compare d window_last <= 0) candidates + |> List.sort_uniq String.compare + in + let test_praef_coverage () = + let ordo = ordo_rows fixture_path in + let no_praef = List.filter (fun o -> o.praef = None) ordo in + let expected = window_no_praef () in + Alcotest.(check int) "the no-praef population matches this window's own Good-Friday-plus-source-gap count" + expected_no_data (List.length no_praef); + Alcotest.(check (list string)) "every no-praef row is either this window's own Good Friday or the known source gap" + expected (List.map (fun o -> o.date) no_praef) + in + let describe_praef_mismatch (o : ordo_row) (c : colitur_row) (expected : Preface.t) = + Printf.sprintf "%s %S: colitur preface=%s, %s praef=%S (classified %s, weekday %s)" o.date + (Option.value o.mass ~default:"?") + (match c.c_preface with Some p -> Preface.to_string p | None -> "NONE") + label (Option.get o.praef) (Preface.to_string expected) (Date.weekday_to_string c.c_weekday) + in + let test_praef_matches_or_is_explained () = + let ordo = ordo_rows fixture_path in + let colitur = colitur_rows ~year_lo ~year_hi ~window_first ~window_last in + let allow_list = load_allow_list allow_list_path in + let by_id = List.map (fun e -> (e.id, e)) allow_list in + let unexplained = ref [] in + let unclassifiable = ref [] in + let explained_counts = Hashtbl.create 8 in + List.iter2 + (fun (o : ordo_row) (c : colitur_row) -> + if not (String.equal o.date c.c_date) then Alcotest.failf "misaligned: ordo %s vs colitur %s" o.date c.c_date; + match o.praef with + | None -> () + | Some raw -> ( + match classify_praef ~weekday:c.c_weekday raw with + | None -> unclassifiable := o.date :: !unclassifiable + | Some expected -> + if c.c_preface = Some expected then () + else + match allow_list_id_for_date o.date with + | Some id -> + Hashtbl.replace explained_counts id (1 + try Hashtbl.find explained_counts id with Not_found -> 0) + | None -> unexplained := describe_praef_mismatch o c expected :: !unexplained)) + ordo colitur; + Alcotest.(check (list string)) + (Printf.sprintf "[%s] every preface mismatch is named in the allow-list -- none unexplained" label) + [] (List.rev !unexplained); + Alcotest.(check (list string)) + (Printf.sprintf "[%s] every raw praef value classifies -- none dropped" label) + [] (List.rev !unclassifiable); + Hashtbl.iter + (fun id n -> + match List.assoc_opt id by_id with + | None -> Alcotest.failf "allow-list entry %s used by the comparator but not declared in %s" id allow_list_path + | Some e -> Alcotest.(check int) (Printf.sprintf "%s: expected_rows matches the actual count" id) e.expected_rows n) + explained_counts + in + (* The known Vigil-of-St-Lawrence corpus gap (tools/extract_efdotorg_ordo.py's + own header, finding 4; docs/research/ordo/PROVENANCE-ordo-corpus.md; + .superpowers/ordo-class-report.md) is RECONFIRMED present, but its + effect on THIS axis now differs by year -- checked per date, not + assumed uniform, because colitur's own CURRENT behaviour (RG 33's + third trigger, which landed after the reports above were written -- + CLAUDE.md's own warning that `day`/`readings` output is not stable + across commits is exactly this) already omits the vigil in SOME of + these years for its own, entirely independent reason: + - 2025-08-09 (Saturday): colitur's own RG33-third-trigger ALSO + omits the vigil this year (RG 78's BVM Saturday Office wins + outright), and Rule A (this generator's own finding 6) picks the + SAME office from the corpus's own listing -- a full, direct + match (office identity AND preface), not a lucky coincidence + limited to preface alone. + - 2027-08-09 (Monday): colitur's own vigil IS genuinely observed + this year (RG33's trigger does not fire); the corpus still shows + no trace of it at all -- STILL the known gap, reconfirmed, naming + St Romanus instead -- but both the true Vigil (Class3, no + title-preface trigger) and the corpus's own substitute fall + through RG 482's chain to the identical Common preface, so the + identity error stays invisible to this one axis. Asserted + POSITIVELY (not merely "no failure occurred") so a future change + giving either office a real trigger would surface here. + - 2026-08-09 (Sunday): the vigil is impeded on every source (a + Sunday outranks a Class3 vigil outright); no special case is + needed and none is asserted here. *) + let test_known_vigil_of_st_lawrence_shape () = + let ordo = ordo_rows fixture_path in + let colitur = colitur_rows ~year_lo ~year_hi ~window_first ~window_last in + let by_date = List.combine ordo colitur in + let find d = List.find_opt (fun ((o : ordo_row), _) -> String.equal o.date d) by_date in + let in_window d = String.compare d window_first >= 0 && String.compare d window_last <= 0 in + (match find "2025-08-09" with + | Some (o, c) when in_window "2025-08-09" -> + Alcotest.(check (option string)) "2025-08-09: Rule A selects the BVM Saturday Office directly" (Some "BVM") + o.praef; + Alcotest.(check (option string)) + "2025-08-09: colitur's own answer is the same office (RG33 3rd trigger + RG78)" (Some "bvm") + (Option.map Preface.to_string c.c_preface) + | _ -> ()); + match find "2027-08-09" with + | Some (o, c) when in_window "2027-08-09" -> + Alcotest.(check (option string)) + "2027-08-09: the known gap is reconfirmed -- the corpus still shows no Vigil of St Lawrence" + (Some "Common") o.praef; + Alcotest.(check (option string)) + "2027-08-09: colitur's own real Vigil office also reads Common -- the identity error stays invisible here" + (Some "common") (Option.map Preface.to_string c.c_preface) + | _ -> () + in + ( label, + [ Alcotest.test_case "fixture SHA-256 matches its provenance note" `Quick test_fixture_checksum; + Alcotest.test_case "streams are N rows each, dates aligned 1:1" `Quick test_dates_align; + Alcotest.test_case "no-praef population matches Good Friday plus the known source gap" `Quick + test_praef_coverage; + Alcotest.test_case "every preface mismatch is named in the allow-list -- none unexplained" `Quick + test_praef_matches_or_is_explained; + Alcotest.test_case "the known Vigil-of-St-Lawrence gap: reconfirmed in 2027, resolved by Rule A in 2025" `Quick + test_known_vigil_of_st_lawrence_shape + ] ) + +(* The seven adjudicated root causes behind this comparison's own 11 row- + level divergences (three editions combined) -- see + data/ef/expected-divergences-efdotorg.sexp for the full citation of + each. Date-keyed, the same discipline test_lms_ordo.ml's own + [allow_list_id_for_date] and test_fiuv_ordo.ml's own + [fiuv_allow_list_id_for_date] use, and for the identical reason: an + entry that starts firing on an unexpected new date must be visible as + a real change, not silently absorbed. Shared across all three editions + (unlike the LMS file's per-window function) because every id here is + adjudicated against colitur's own DATA or RULES, not against a single + edition's own printing quirk -- E1/E3/E4 each recur, unchanged, in + more than one edition. *) +let allow_list_id_for_date = function + | "2025-07-16" | "2026-07-16" | "2027-07-16" -> Some "E1" + | "2026-09-24" -> Some "E2" + | "2025-11-27" | "2026-11-27" -> Some "E3" + | "2025-05-06" | "2026-05-06" -> Some "E4" + | "2025-09-29" -> Some "E5" + | "2026-11-01" -> Some "E6" + | "2025-11-29" -> Some "E7" + | _ -> None + +let suite_2024_2025 = + make_suite ~label:"efdotorg-ordo-2024-2025" ~fixture_path:"fixtures/efdotorg-ordo-2024-2025.sexp" + ~fixture_sha256:"7de633e292fdb85415dd3ad87fcf9414fbb8f34c42772663b78e107e68c6e571" ~window_first:"2024-12-01" + ~window_last:"2025-11-29" ~year_lo:2023 ~year_hi:2026 ~expected_rows:364 ~expected_no_data:1 + ~allow_list_id_for_date + +let suite_2025_2026 = + make_suite ~label:"efdotorg-ordo-2025-2026" ~fixture_path:"fixtures/efdotorg-ordo-2025-2026.sexp" + ~fixture_sha256:"c810ec437cae9fde785f6b3453f77e667644fb82f465b3652040bb2a3b888b9b" ~window_first:"2025-11-30" + ~window_last:"2026-11-28" ~year_lo:2024 ~year_hi:2027 ~expected_rows:364 ~expected_no_data:1 + ~allow_list_id_for_date + +let suite_2026_2027 = + make_suite ~label:"efdotorg-ordo-2026-2027" ~fixture_path:"fixtures/efdotorg-ordo-2026-2027.sexp" + ~fixture_sha256:"19c35b45d7964dd357f92a871e81423af8217dff6c40178f3a95d3ec9c4091ea" ~window_first:"2026-11-29" + ~window_last:"2027-11-27" ~year_lo:2025 ~year_hi:2028 ~expected_rows:364 ~expected_no_data:2 + ~allow_list_id_for_date + +(* Guards against a stale allow-list entry, the same discipline + test_lms_ordo.ml's own [test_allow_list_ids_are_exactly_l4] uses: a + STATIC check that the sexp file's own declared ids are exactly this + set -- not a cross-edition "did every id actually fire" proof (neither + test_lms_ordo.ml nor test_fiuv_ordo.ml's own analogous guard attempts + that either; each edition's own [test_praef_matches_or_is_explained] + already fails loudly if an id fires the WRONG number of times, or if a + real divergence names an id that does not exist at all). *) +let test_allow_list_ids_are_exactly_e1_to_e7 () = + let ids = List.sort String.compare (List.map (fun e -> e.id) (load_allow_list allow_list_path)) in + Alcotest.(check (list string)) "the efdotorg allow-list declares exactly E1..E7" + [ "E1"; "E2"; "E3"; "E4"; "E5"; "E6"; "E7" ] ids + +let suite_allow_list = + ( "efdotorg-ordo-allow-list", + [ Alcotest.test_case "declares exactly E1..E7" `Quick test_allow_list_ids_are_exactly_e1_to_e7 ] ) diff --git a/tools/extract_efdotorg_ordo.py b/tools/extract_efdotorg_ordo.py new file mode 100644 index 0000000..05ef014 --- /dev/null +++ b/tools/extract_efdotorg_ordo.py @@ -0,0 +1,336 @@ +#!/usr/bin/env python3 +# tools/extract_efdotorg_ordo.py -- efdotorg-preface task +# (2026-08-24-colitur-celebrant-rubrics-phase1). Turns the ALREADY-PARSED +# extraordinaryform.org corpus (docs/research/ordo/ordo-2024-2027.json, +# 1091 days, produced by docs/research/ordo/parse_ordo.py and audited for +# fidelity in .superpowers/ordo-fidelity-report.md -- 1091/1091 against an +# independently-written parser) into three sexp fixtures, +# test/fixtures/efdotorg-ordo-{2024-2025,2025-2026,2026-2027}.sexp, one row +# per calendar day, mirroring how tools/extract_fiuv_ordo.ml and +# tools/extract_lms_ordo.ml shape their own fixtures. +# +# PYTHON, NOT OCAML -- same reasoning tools/extract_missalemeum_oracle.py's +# own header already gives: there is no JSON library in this project's +# frozen deps (dune alcotest qcheck qcheck-alcotest sexplib ppx_sexp_conv), +# and hand-writing one is out of scope ("no hand-written JSON parser" is +# about colitur's OWN sexp format, not a licence to reimplement JSON). The +# JSON itself is already the parsed artefact ("do not rebuild the parser" -- +# this script does not re-read the PDFs at all, only the JSON parse_ordo.py +# already produced from them). +# +# Usage: +# python3 tools/extract_efdotorg_ordo.py \ +# docs/research/ordo/ordo-2024-2027.json test/fixtures +# +# Writes the three fixtures named above into the given output directory. +# +# --------------------------------------------------------------------------- +# CHARACTERISATION (re-derived independently against the live JSON below, +# not copied from .superpowers/ordo-fidelity-report.md's own prose summary +# -- that report's own filter was RE-RUN here and its counts reproduced +# exactly, which is the independent confirmation, not a citation of trust): +# +# 1. THE MENU TRAP (element [0] is not reliably the day's own office). +# Re-derived over the whole 1091-day JSON: walk each day's Mass-option +# list; skip a leading entry whose `mass` starts with "Requiem:" (a +# votive Mass for the Dead, listed ahead of the real office on an +# unimpeded low-class day -- 99 instances, confirmed never the SOLE +# option and never followed by a second Requiem entry); then, if the +# NEXT entry's `mass` starts with "and " (a preliminary rite -- Blessing +# of Ashes/Palms, Candlemas, Holy Saturday's daytime office -- joined to +# its real companion Mass by that literal prefix), treat that next entry +# as the office instead (12 instances). 99 + 12 = 111, exactly the +# figure ordo-fidelity-report.md's own independent audit already found +# -- reproduced, not merely trusted. +# +# 2. THE "CHRIST THE KING" CLASSIFIER GAP -- a NEW finding, not in the +# prior fidelity audit. Of the 1091 office-selected rows, exactly 6 have +# `preface: null`: 3 Good Friday (genuinely no preface -- the +# 1955-restored Holy Week's Good Friday has no Mass at all, RG 28) and 3 +# Christ the King (25/26/31 October across the three editions). The +# latter is a real extraction-classifier gap, not a source blank: +# docs/research/ordo/parse_ordo.py's own hardcoded `PREFACES` set (its +# module-level constant) does not include "Christ the King" as a +# recognised preface name, so its own `opt()` function's `pref = f[0] if +# f and f[0] in PREFACES else None` falls through and files the literal +# string "Christ the King" into `comms` instead of `preface` -- checked +# directly against all three instances, `comms == ['Christ the King']` +# on every one, no other None-preface row has this shape. RECOVERED +# here (reading `comms` when `preface` is null and `comms` is exactly +# `['Christ the King']`), not silently left blank, and not a parser +# rewrite -- parse_ordo.py itself and its JSON output are untouched; +# this is a documented, characterised repair applied only inside this +# comparison-layer generator, reading a field the JSON already carries. +# +# 3. "ADVENT" IS NOT A PREFACE, AND NEITHER IS ITS MAPPING A CONSTANT. +# RG 484-499 name no Advent preface among the fourteen; this source's +# own "Advent" label is an informal convention (plausibly Novus-Ordo- +# influenced) covering BOTH of two genuinely different 1962 outcomes: +# - RG 494(b), "in dominicis Adventus... praefatio de Ss.ma +# Trinitate" -- every ADVENT SUNDAY takes the TRINITY preface as +# its own de-Tempore grant (lib/rites/rite_ef/rubrics_ef.ml's own +# [preface] function already implements this, cross-checked against +# the FIUV and LMS Ordos independently -- see that function's own +# header). Confirmed live in this JSON: "Advent" is the raw label on +# every Advent Sunday in the corpus too (11 of the 12 possible +# Advent-Sunday instances across three editions; the twelfth, +# 2024-12-08, is impeded by the Immaculate Conception, a fixed +# I-class BVM feast, and correctly carries "BVM" instead). +# - RG 498 (the residual Common) governs every Advent FERIA (a +# non-Sunday day with no proper of its own). +# So "Advent" is NOT simply "colitur's Common" (an earlier, declined +# version of this task's own reasoning) -- it is Trinity on a Sunday, +# Common otherwise, decided by the civil weekday alone (never by +# parsing this source's own text further, and never by trusting +# colitur's own answer circularly: the civil weekday is public, +# independently computable information). Encoded in the comparator +# (test/test_efdotorg_ordo.ml), not baked into this generator, because +# it needs the day's own weekday, which this fixture's `date` field +# already carries losslessly. +# +# 4. THE KNOWN VIGIL-OF-ST-LAWRENCE DEFECT (docs/research/ordo/ +# PROVENANCE-ordo-corpus.md, .superpowers/ordo-class-report.md) is +# RECONFIRMED present at the same two dates, unchanged: 2025-08-09 and +# 2027-08-09 both list "St. Romanus, Martyr" (cls 4) as the day's own +# office, with no Vigil of St Lawrence entry anywhere in either day's +# option list (2026-08-09 is a Sunday, impeding the vigil on every +# source, so it is not part of this population). NOT re-derived from +# scratch -- already fully adjudicated in the class/colour layers +# named above; carried forward here as a known fact to characterise +# against, not a new investigation. +# +# 5. TWO ALREADY-DOCUMENTED SOURCE-PDF DEFECTS (ordo-fidelity-report.md) +# do not need a fresh finding here, only a check of whether they touch +# the preface field at all -- they do not, checked directly: +# - 2027-03-03 is missing from the JSON outright (a source PDF +# row-drop); 2027-03-02 carries 03-03's own Wednesday content under +# 03-02's date instead. Both dates' own `preface` value happens to +# read "Lent" regardless of which day's content is attached (both +# are ordinary Lenten ferias in the same week), so the mislabelling +# does not propagate into a preface divergence -- checked, not +# assumed. 2027-03-03 (the missing day) is still emitted as its own +# "no data" row below (mass/cls/colour/praef all absent), the same +# shape Good Friday's genuine blank already uses, so the fixture +# keeps one row per calendar day. +# - 2026-12-13 (Gaudete Sunday) carries the wrong COLOUR/commemoration +# in the source PDF (a known, isolated editorial error, already +# allow-listed for class/colour purposes elsewhere) -- its own +# `preface` value is untouched ("Advent", exactly like every other +# Advent Sunday), confirmed directly against this JSON. +# +# 6. RULE A -- "SATURDAY OF OUR LADY" IS UNCONDITIONALLY THE OFFICE. A +# second, NEW office-selection finding, beyond the two patterns in +# finding 1 above: 38 days across the whole corpus list an entry whose +# `mass` is exactly "Saturday of Our Lady" (RG 78's own votive BVM +# Saturday Office) ALONGSIDE another named saint's own optional Mass +# (structurally identical to the Requiem pattern -- a low-class +# "priest's menu" option printed ahead of, or beside, the real office). +# Checked EXHAUSTIVELY, not sampled: on all 38, colitur's own real +# computed office is this BVM Office (`dune exec bin/main.exe -- +# rubrics `, cross-checked against `day`'s own "Officium sanctae +# Mariae in sabbato" line) -- including the ONE case where a further +# listed entry outranks every OTHER candidate on the page by class +# number (18 January 2025's own "Chair of St. Peter (for Church +# Unity)", cls 2): that entry is not even part of the 1962 General +# Roman Calendar at all (the single Roman Chair-of-Peter feast was +# consolidated to 22 February by the 1960 Rubricae Generales; colitur's +# own sanctoral data has no 18 January entry for it, and neither the +# LMS nor the FIUV Ordo -- both already-validated witnesses -- ever +# name it), so its presence does not defeat the rule. UNCONDITIONAL, +# not merely "no lower-class competitor": empirically the simpler, +# equally correct reading of the whole 38-instance population. +# +# (USA)/(Can)-TAGGED REGIONAL INDULTS were checked and found NEVER to be +# the JSON's own element [0] anywhere in the whole 1091-day corpus (0 +# instances) -- so, unlike ordo-fidelity-report.md's own +# class/colour-comparison method, THIS generator needs no indult- +# stripping step: Rules 1/6 above never reach far enough into an +# option list for an indult's presence to matter. Checked, not assumed. +# +# 7. THE RESIDUAL -- 11 rows, all 3 editions combined, 7 distinct root +# causes, every one individually adjudicated in +# data/ef/expected-divergences-efdotorg.sexp (not attempted here, a +# THIRD, generic "absorption" rule was deliberately NOT built: it would +# have resolved 2 of these 11 rows (Our Lady of Mt Carmel, 16 July) but +# ALSO wrongly mis-fired on a genuinely different shape (Ss Philip & +# James/Rogation Day, 11 May, where an equal-CLASS "Rogation Day" +# option's own [comms] names the real feast for the OPPOSITE reason -- +# an optional votive substitution, not a rank-based demotion -- and the +# JSON alone cannot distinguish the two shapes without already knowing +# colitur's own Commemoration_only/Feast status distinction, which +# would defeat the point of an independent witness). Manufacturing a +# rule that fixes 2 cases while breaking a 3rd is a worse trade than +# leaving all of them to individual adjudication. +# +# --------------------------------------------------------------------------- +import datetime +import json +import subprocess +import sys + +EDITIONS = [ + ("2024-2025", "2024-12-01", "2025-11-29"), + ("2025-2026", "2025-11-30", "2026-11-28"), + ("2026-2027", "2026-11-29", "2027-11-27"), +] +# Boundaries re-derived, not copied: both PDF-to-PDF seams are exact (no +# overlap, no gap) and 364 + 364 + 363 = 1091, the JSON's own total day +# count -- checked below in main(), not merely asserted here. + + +def sha256_of(path): + out = subprocess.run(["sha256sum", path], capture_output=True, text=True, check=True) + return out.stdout.split()[0] + + +def pick_office(opts): + """The menu-trap filter -- see this module's own header, findings 1 and 6.""" + i = 0 + if opts[0]["mass"].startswith("Requiem:"): + i = 1 + if i < len(opts) - 1 and opts[i + 1]["mass"].startswith("and "): + i += 1 + # Rule A (finding 6): "Saturday of Our Lady", whenever listed at all, IS + # the office -- checked exhaustively over all 38 instances across the + # whole 1091-day corpus (not a sample): colitur's own RG 78 BVM-Saturday + # Office wins on every single one, including the one case where a + # competing entry outranks every OTHER real candidate on the page (a + # Chair-of-St-Peter, 18 January, entry that is not even part of the + # 1962 calendar at all -- see finding 6). No guard/condition needed; + # unconditional preference is the empirically safe rule. + bvm_saturday = next((o for o in opts if o["mass"] == "Saturday of Our Lady"), None) + if bvm_saturday is not None: + return bvm_saturday + return opts[i] + + +def sexp_string(s): + out = [] + for ch in s: + b = ch.encode("utf-8") + if ch == '"': + out.append('\\"') + elif ch == "\\": + out.append("\\\\") + elif len(b) == 1 and 32 <= b[0] < 127: + out.append(ch) + else: + for byte in b: + out.append("\\%03d" % byte) + return '"' + "".join(out) + '"' + + +def sexp_opt_string(s): + return "(" + sexp_string(s) + ")" if s is not None else "()" + + +def sexp_opt_int(n): + return f"({n})" if n is not None else "()" + + +def daterange(lo, hi): + d = datetime.date.fromisoformat(lo) + end = datetime.date.fromisoformat(hi) + while d <= end: + yield d.isoformat() + d += datetime.timedelta(days=1) + + +def build_rows(data, lo, hi): + rows = [] + for date in daterange(lo, hi): + opts = data.get(date) + if opts is None: + # 2027-03-03 only -- see this module's own header, finding 5. + rows.append((date, None, None, None, None)) + continue + office = pick_office(opts) + praef = office["preface"] + if praef is None and office.get("comms") == ["Christ the King"]: + praef = "Christ the King" # RECOVERED -- see finding 2 above. + rows.append((date, office["mass"], office["cls"], office["colour"], praef)) + return rows + + +def write_fixture(out_path, label, lo, hi, rows, json_path, json_sha): + n_missing = sum(1 for r in rows if r[1] is None) + n_none_praef = sum(1 for r in rows if r[1] is not None and r[4] is None) + with open(out_path, "w") as f: + f.write(f"""; test/fixtures/efdotorg-ordo-{label}.sexp -- efdotorg-preface task +; (2026-08-24-colitur-celebrant-rubrics-phase1): the THIRD independent +; preface witness (RG 482-499), extraordinaryform.org's {label} Ordo, +; extracted from the already-parsed, fidelity-audited corpus +; docs/research/ordo/ordo-2024-2027.json (SHA-256 {json_sha}) rather than +; re-parsed from the PDF -- see tools/extract_efdotorg_ordo.py's own +; header for the full characterisation this fixture rests on (the menu- +; trap office filter, the Christ-the-King classifier-gap recovery, why +; "Advent" is not baked into a single mapping here, the known Vigil-of- +; St-Lawrence gap, and the two source-PDF defects that turn out not to +; touch this field). +; +; Generator: tools/extract_efdotorg_ordo.py -- do not hand-edit; re-run +; against the same JSON and commit the diff instead. +; python3 tools/extract_efdotorg_ordo.py {json_path} test/fixtures +; +; Source PDF (gitignored, CLAUDE.md: "docs/ is gitignored", see +; docs/research/ordo/SHA256SUMS for its own hash): {label}Ordo.pdf, +; extraordinaryform.org. +; +; COVERAGE: {len(rows)} day-rows, {lo}..{hi} (this edition's own civil-date +; span, re-derived from the JSON's own seams -- see the generator's own +; EDITIONS comment). {n_missing} row(s) are a genuine SOURCE GAP (2027-03-03 +; only, a PDF row-drop, ordo-fidelity-report.md) -- mass/cls/colour/praef +; all absent, the same shape a structurally blank day (Good Friday) uses. +; {n_none_praef} further row(s) have mass/cls/colour but no praef at all +; (Good Friday -- RG 28, no Mass in the 1955-restored Holy Week). +; +; Each row's `praef` is RAW TEXT from the day's own OFFICE (after the +; menu-trap filter, with the Christ-the-King recovery already applied) -- +; classified against {{!Colitur_kernel.Preface.t}} by +; test/test_efdotorg_ordo.ml, not here. +""") + f.write("(\n") + for date, mass, cls, colour, praef in rows: + f.write( + f" ((date {date}) (mass {sexp_opt_string(mass)}) (cls {sexp_opt_int(cls)}) " + f"(colour {sexp_opt_string(colour)}) (praef {sexp_opt_string(praef)}))\n" + ) + f.write(")\n") + print(f"wrote {len(rows)} rows to {out_path}", file=sys.stderr) + print(f"SHA-256 of {out_path}: {sha256_of(out_path)}", file=sys.stderr) + + +def main(): + if len(sys.argv) != 3: + print(f"usage: {sys.argv[0]} ", file=sys.stderr) + sys.exit(2) + json_path, out_dir = sys.argv[1], sys.argv[2] + with open(json_path) as f: + data = json.load(f) + json_sha = sha256_of(json_path) + + # The three windows span 1092 CALENDAR days (one more than the JSON's + # own 1091 keys, because 2027-03-03 is a genuine source gap -- see + # finding 5 above); of those, exactly 1091 must be present as JSON + # keys and exactly 1 (2027-03-03 alone) absent, or the boundaries are + # wrong. + all_dates = [d for _, lo, hi in EDITIONS for d in daterange(lo, hi)] + present = [d for d in all_dates if d in data] + missing = [d for d in all_dates if d not in data] + if len(all_dates) != 1092 or len(present) != 1091 or missing != ["2027-03-03"]: + print( + f"ERROR: edition boundaries cover {len(all_dates)} calendar days, " + f"{len(present)} present in the JSON, missing={missing} " + "(expected 1092/1091/['2027-03-03'])", + file=sys.stderr, + ) + sys.exit(1) + + for label, lo, hi in EDITIONS: + rows = build_rows(data, lo, hi) + out_path = f"{out_dir}/efdotorg-ordo-{label}.sexp" + write_fixture(out_path, label, lo, hi, rows, json_path, json_sha) + + +if __name__ == "__main__": + main() -- cgit v1.3 From 73b15551804bb63ee0081005e2869d36afb54be2 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Mon, 24 Aug 2026 16:22:24 +0200 Subject: docs(E3,E4): pro aliquibus locis, not sanctoral gaps Both entries reasoned correctly that these feasts are not in the universal calendar, then recommended adding them to CLAUDE.md's list of sanctoral entries MISSING from colitur. Those cannot both be true, and acting on the recommendation would add a particular-calendar feast to the universal core -- what binding decision 2 exists to forbid. The Missal classifies both itself, under "Missae pro aliquibus locis": scan1.txt:52019 for the Miraculous Medal, 48793 for St John before the Latin Gate. Masses for some places. So they are not gaps. They are particular feasts colitur correctly excludes and an overlay would supply, the shape poland.ini and benedictine.ini already demonstrate; the ordos carry them because those ordos serve communities that keep them. Verdicts unchanged, now resting on the Missal's own words rather than on background knowledge of the apparition. --- data/ef/expected-divergences-efdotorg.sexp | 32 ++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'data/ef') diff --git a/data/ef/expected-divergences-efdotorg.sexp b/data/ef/expected-divergences-efdotorg.sexp index 7c9eea7..addecfe 100644 --- a/data/ef/expected-divergences-efdotorg.sexp +++ b/data/ef/expected-divergences-efdotorg.sexp @@ -71,6 +71,38 @@ (note "Our Lady of Ransom (24 September) is Commemoration_only-status data; the September Ember Saturday always wins the day outright. Fires once, 2026-09-24 (2025 and 2027's own 24 September already match colitur without needing this entry -- the Ember day is listed first there).") (expected_rows 1)) + + ; CORRECTED 2026-08-24 (coordinator): this entry reasoned correctly and + ; then recommended the opposite. It concludes, rightly, that the feast was + ; "never added to the GENERAL calendar" -- and then proposes it as a + ; candidate for CLAUDE.md's list of sanctoral entries MISSING from + ; colitur's universal data. Those cannot both be true, and acting on the + ; recommendation would be a REGRESSION: adding a particular-calendar feast + ; to the universal core is precisely what binding decision 2 forbids + ; ("any community's proper is an overlay, never core"). + ; + ; The Missal settles it from the primary source rather than from general + ; knowledge of the 1830 apparition. BOTH feasts named in E3 and E4 appear + ; in the Missal under its own heading "Missae pro aliquibus locis" -- + ; Masses FOR SOME PLACES: + ; docs/research/scan1.txt:52019, 52077, 52129 + ; "Missae pro aliquibus locis (B. M. V. Immaculatae a sacro Numismate)" + ; docs/research/scan1.txt:48793 + ; "Missae pro aliquibus locis (S. Ioannis Ap. et Ev. ante Portam Latinam)" + ; This is the Missal's OWN classification, and it is the same structural + ; test the register already relies on for universality: the calendarium + ; carries no "pro aliquibus locis" marker in its own lines, while the + ; wider Missal carries the marker elsewhere for exactly this class of + ; feast. + ; + ; So E3 and E4 are NOT sanctoral gaps and are NOT candidates for any + ; missing-entry list. They are particular-calendar feasts that colitur + ; correctly excludes from the universal core, and that belong in an + ; overlay -- the shape data/ef/examples/poland.ini and benedictine.ini + ; already demonstrate. The ordos carry them because those ordos serve + ; communities that keep them. Verdict [colitur] is unchanged and now rests + ; on the Missal's own words. + ; E3 -- colitur correct (a genuine sanctoral DATA GAP, not a rule bug). ; "Our Lady of the Miraculous Medal" (27 November) does not appear ; anywhere in data/ef/sanctoral.sexp (`grep -i medal` / `grep -i -- cgit v1.3