diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-22 20:55:18 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-22 20:55:18 +0200 |
| commit | 9c96e0afc19925b651e0dfee3bc9182dee72acf0 (patch) | |
| tree | 5f1fe05d495ddea61f585311f3dbca8bb1062cd8 | |
| parent | cd3e03bf3e5b040786838fc3c5639d7c29e9b3b8 (diff) | |
| download | colitur-9c96e0afc19925b651e0dfee3bc9182dee72acf0.tar.gz colitur-9c96e0afc19925b651e0dfee3bc9182dee72acf0.zip | |
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).
| -rw-r--r-- | data/ef/expected-divergences-missalemeum.sexp | 11 | ||||
| -rw-r--r-- | data/ef/expected-divergences.sexp | 11 | ||||
| -rw-r--r-- | data/ef/lectionary.sexp | 20 | ||||
| -rw-r--r-- | test/golden/grid-2027.html | 2 | ||||
| -rw-r--r-- | test/golden/grid-2027.ms | 2 | ||||
| -rw-r--r-- | test/golden/grid-2027.tex | 2 | ||||
| -rw-r--r-- | test/golden/grid-2027.typ | 2 | ||||
| -rw-r--r-- | test/golden/ordo-2027.adoc | 2 | ||||
| -rw-r--r-- | test/golden/ordo-2027.html | 2 | ||||
| -rw-r--r-- | test/golden/ordo-2027.md | 2 | ||||
| -rw-r--r-- | test/golden/ordo-2027.ms | 4 | ||||
| -rw-r--r-- | test/golden/ordo-2027.tex | 2 | ||||
| -rw-r--r-- | test/golden/ordo-2027.txt | 4 | ||||
| -rw-r--r-- | test/golden/ordo-2027.typ | 2 | ||||
| -rw-r--r-- | test/test_differential.ml | 18 | ||||
| -rw-r--r-- | test/test_golden.ml | 29 | ||||
| -rw-r--r-- | test/test_lectionary.ml | 38 | ||||
| -rw-r--r-- | test/test_lms_ordo.ml | 91 | ||||
| -rw-r--r-- | test/test_oracle.ml | 47 | ||||
| -rw-r--r-- | tools/bootstrap_lectionary.ml | 70 |
20 files changed, 334 insertions, 27 deletions
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 @@ <td class="white"><span class="dom">2</span>5th Sunday after Easter<span class="sigla">Jas 1:22-27 · John 16:23-30</span></td><td class="white"><span class="dom">3</span>Rogation Monday<span class="sigla">Jas 1:22-27 · John 16:23-30</span></td><td class="white"><span class="dom">4</span>St. Monica<span class="sigla">1 Tim 5:3-10 · Luke 7:11-16</span></td><td class="white"><span class="dom">5</span>Vigil of the Ascension<span class="sigla">Eph 4:7-13 · John 17:1-11</span></td><td class="white"><span class="dom">6</span>The Ascension of Our Lord<span class="sigla">Acts 1:1-11 · Mark 16:14-20</span></td><td class="red"><span class="dom">7</span>St. Stanislaus<span class="sigla">Wis 5:1-5 · John 15:1-7</span></td><td class="white"><span class="dom">8</span>Our Lady's Saturday Office<span class="sigla">Ecclus 24:14-16 · John 19:25-27</span></td> </tr> <tr> - <td class="white"><span class="dom">9</span>Sunday after the Ascension<span class="sigla">1 Pet 4:7-11 · John 15:26-27; 16:1-4</span></td><td class="white"><span class="dom">10</span>St. Antoninus<span class="sigla">Ecclus 44:16-27; 45:3-20 · Matt 25:14-23</span></td><td class="red"><span class="dom">11</span>Sts. Philip & James<span class="sigla">Wis 5:1-5 · John 14:1-13</span></td><td class="red"><span class="dom">12</span>Sts. Nereus, Achilleus, Domitilla, & Pancras<span class="sigla">Wis 5:1-5 · John 4:46-53</span></td><td class="white"><span class="dom">13</span>St. Robert Bellarmine<span class="sigla">Wis 7:7-14 · Matt 5:13-19</span></td><td class="white"><span class="dom">14</span>Friday of the 7th Week of Eastertide<span class="sigla">1 Pet 4:7-11 · John 15:26-27; 16:1-4</span></td><td class="red"><span class="dom">15</span>Vigil of Pentecost<span class="sigla">Acts 19:1-8 · John 14:15-21</span></td> + <td class="white"><span class="dom">9</span>Sunday after the Ascension<span class="sigla">1 Pet 4:7-11 · John 15:26-27; 16:1-4</span></td><td class="white"><span class="dom">10</span>St. Antoninus<span class="sigla">Ecclus 44:16-27; 45:3-20 · Matt 25:14-23</span></td><td class="red"><span class="dom">11</span>Sts. Philip & James<span class="sigla">Wis 5:1-5 · John 14:1-13</span></td><td class="red"><span class="dom">12</span>Sts. Nereus, Achilleus, Domitilla, & Pancras<span class="sigla">Wis 5:1-5 · John 4:46-53</span></td><td class="white"><span class="dom">13</span>St. Robert Bellarmine<span class="sigla">Wis 7:7-14 · Matt 5:13-19</span></td><td class="white"><span class="dom">14</span>Friday of the 7th Week of Eastertide<span class="sigla">Acts 1:1-11 · Mark 16:14-20</span></td><td class="red"><span class="dom">15</span>Vigil of Pentecost<span class="sigla">Acts 19:1-8 · John 14:15-21</span></td> </tr> <tr> <td class="red"><span class="dom">16</span>Pentecost Sunday (Whitsunday)<span class="sigla">Acts 2:1-11 · John 14:23-31</span></td><td class="red"><span class="dom">17</span>Monday of Pentecost Week<span class="sigla">Acts 10:34, 42-48 · John 3:16-21</span></td><td class="red"><span class="dom">18</span>Tuesday of Pentecost Week<span class="sigla">Acts 8:14-17 · John 10:1-10</span></td><td class="red"><span class="dom">19</span>Pentecost Ember Wednesday<span class="sigla">Acts 5:12-16 · John 6:44-52</span></td><td class="red"><span class="dom">20</span>Thursday of Pentecost Week<span class="sigla">Acts 8:5-8 · Luke 9:1-6</span></td><td class="red"><span class="dom">21</span>Pentecost Ember Friday<span class="sigla">Joel 2:23-24; 2:26-27 · Luke 5:17-26</span></td><td class="red"><span class="dom">22</span>Pentecost Ember Saturday<span class="sigla">Rom 5:1-5 · Luke 4:38-44</span></td> 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 @@ </div> <div class="day white"> <span class="dom">14</span>Friday of the 7th Week of Eastertide - <div class="meta">class-4 · white · Epistle 1 Pet 4:7-11 · Gospel John 15:26-27; 16:1-4</div> + <div class="meta">class-4 · white · Epistle Acts 1:1-11 · Gospel Mark 16:14-20</div> <div class="meta">Commemoration St. Boniface</div> </div> <div class="day red"> 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-<season>-<week>-<weekday>] 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 = |
