diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/dune | 4 | ||||
| -rw-r--r-- | test/fixtures/missalemeum-ef-2026-2027.provenance | 39 | ||||
| -rw-r--r-- | test/fixtures/missalemeum-ef-2026-2027.txt | 730 | ||||
| -rw-r--r-- | test/test_colitur.ml | 2 | ||||
| -rw-r--r-- | test/test_oracle.ml | 607 |
5 files changed, 1380 insertions, 2 deletions
@@ -5,7 +5,9 @@ ../data/ef/sanctoral.sexp ../data/ef/adjustments.sexp ../data/ef/expected-divergences.sexp - fixtures/lectio-ef-2005-2050.txt) + ../data/ef/expected-divergences-missalemeum.sexp + fixtures/lectio-ef-2005-2050.txt + fixtures/missalemeum-ef-2026-2027.txt) (preprocess (pps ppx_sexp_conv))) diff --git a/test/fixtures/missalemeum-ef-2026-2027.provenance b/test/fixtures/missalemeum-ef-2026-2027.provenance new file mode 100644 index 0000000..576093d --- /dev/null +++ b/test/fixtures/missalemeum-ef-2026-2027.provenance @@ -0,0 +1,39 @@ +Fixture: missalemeum-ef-2026-2027.txt +Task: 2026-08-11-colitur-plan3-resolution-engine, Task 16 (oracle harness + +data audit) + +Source: missalemeum.com (Divinum Officium data), archived by the sibling +project ~/git/projects/lectio at: + commit d7da4b0 "sources: store the snapshot as one compressed archive" + path sources/snapshot.tar.gz, entries missalemeum/en/YYYY-MM-DD.json + (lectio/sources/README.md: "First archived 2026-07-29") + +SHA-256 of the extracted fixture: 718eff1a03fa09c3927ef18d19fe7921c2d4d7611890c22566058b81fd7cc5ea +(same digest as [fixture_sha256] in test/test_oracle.ml, ASSERTED by that +suite's own "fixture SHA-256 matches its provenance note" test -- this line +documents the pin for a reader who never runs the suite; that test is what +actually enforces it. Regenerate both together, deliberately, after +re-running the exact command below -- never by copying a mismatch's actual +value back in, which would defeat the pin's purpose.) + +Exact commands: + cd ~/git/projects/lectio && sh scripts/snapshot-sources.sh unpack + python3 ~/git/projects/colitur/tools/extract_missalemeum_oracle.py \ + ~/git/projects/lectio/sources \ + ~/git/projects/colitur/test/fixtures/missalemeum-ef-2026-2027.txt + +Output: one line per civil day, 2026-01-01 through 2027-12-31 inclusive +(730 lines = 365 + 365, both non-leap years), pipe-separated: + date|rank|colors|title|tempora|commemorations|displaced|n_masses +See tools/extract_missalemeum_oracle.py's own header for the exact field +semantics (info.rank/colors/title/tempora/commemorations/displaced, +verbatim English strings, not translated or slugified) and the two things +verified during extraction, not merely assumed: no field collides with the +"|"/";" delimiters, and all 4 multi-Mass days (info is an array on +2026-11-02, 2026-12-25, 2027-11-02, 2027-12-25) carry an IDENTICAL info +block (rank/colors/tempora/commemorations/displaced) across every Mass of +the day, so taking entry[0] throughout (this fixture's own convention) +loses nothing the comparator or a human auditor needs. + +Regenerate with the same commands if the missalemeum snapshot is refreshed +and the fixture needs updating; do not hand-edit this file or the fixture. diff --git a/test/fixtures/missalemeum-ef-2026-2027.txt b/test/fixtures/missalemeum-ef-2026-2027.txt new file mode 100644 index 0000000..d000212 --- /dev/null +++ b/test/fixtures/missalemeum-ef-2026-2027.txt @@ -0,0 +1,730 @@ +2026-01-01|1|w|Octave Day of Christmas|-|-|-|1 +2026-01-02|4|w|Feria|-|-|-|1 +2026-01-03|4|w|II Mass of the B. V. M. – Vultum Tuum|-|-|-|1 +2026-01-04|2|w|Holy Name of Jesus|-|-|-|1 +2026-01-05|4|w|Feria|-|St. Telesphorus Pope and Martyr|-|1 +2026-01-06|1|w|Epiphany of the Lord|-|-|-|1 +2026-01-07|4|w|Feria|-|-|-|1 +2026-01-08|4|w|Feria|-|-|-|1 +2026-01-09|4|w|Feria|-|-|-|1 +2026-01-10|4|w|II Mass of the B. V. M. – Vultum Tuum|-|-|-|1 +2026-01-11|2|w|The Holy Family: Jesus, Mary & Joseph|-|-|St. Hyginus Pope and Martyr|1 +2026-01-12|4|w|Feria|Feria_II_after_Epiphany|-|-|1 +2026-01-13|2|w|Commemoration of the Baptism of the Lord|Feria_III_after_Epiphany|-|-|1 +2026-01-14|3|w|St. Hilary|Feria_IV_after_Epiphany|S. Felicis|-|1 +2026-01-15|3|w|St. Paul, the First Hermit|Feria_V_after_Epiphany|St. Maur, Abbot|-|1 +2026-01-16|3|r|St. Marcellus I|Feria_VI_after_Epiphany|-|-|1 +2026-01-17|3|w|St. Anthony|Saturday_after_Epiphany|-|-|1 +2026-01-18|2|g|II Sunday after Epiphany|-|-|St. Prisca|1 +2026-01-19|4|g|Feria|Feria_II_after_II_Sunday_after_Epiphany|Sts. Marius, Martha, Audifax & Abachum;St. Canute, Martyr|-|1 +2026-01-20|3|r|Sts. Fabian & Sebastian|Feria_III_after_II_Sunday_after_Epiphany|-|-|1 +2026-01-21|3|r|St. Agnes|Feria_IV_after_II_Sunday_after_Epiphany|-|-|1 +2026-01-22|3|r|Sts. Vincent & Anastasius|Feria_V_after_II_Sunday_after_Epiphany|-|-|1 +2026-01-23|3|w|St. Raymond of Peñafort|Feria_VI_after_II_Sunday_after_Epiphany|St. Emerentiana|-|1 +2026-01-24|3|r|St. Timothy|Saturday_after_II_Sunday_after_Epiphany|-|-|1 +2026-01-25|2|g|III Sunday after Epiphany|-|-|Conversion of St. Paul;St. Peter|1 +2026-01-26|3|r|St. Polycarp|Feria_II_after_III_Sunday_after_Epiphany|-|-|1 +2026-01-27|3|w|St. John Chrysostom|Feria_III_after_III_Sunday_after_Epiphany|-|-|1 +2026-01-28|3|w|St. Peter Nolasco|Feria_IV_after_III_Sunday_after_Epiphany|St. Agnes|-|1 +2026-01-29|3|w|St. Francis de Sales|Feria_V_after_III_Sunday_after_Epiphany|-|-|1 +2026-01-30|3|r|St. Martina|Feria_VI_after_III_Sunday_after_Epiphany|-|-|1 +2026-01-31|3|w|St. John Bosco|Saturday_after_III_Sunday_after_Epiphany|-|-|1 +2026-02-01|2|v|Septuagesima Sunday|-|-|St. Ignatius of Antioch|1 +2026-02-02|2|w|Purification of the Blessed Virgin Mary|Feria_II_after_Septuagesima|-|-|1 +2026-02-03|4|v|Feria|Feria_III_after_Septuagesima|St. Blaise|-|1 +2026-02-04|3|w|St. Andrew Corsini|Feria_IV_after_Septuagesima|-|-|1 +2026-02-05|3|r|St. Agatha|Feria_V_after_Septuagesima|-|-|1 +2026-02-06|3|w|St. Titus|Feria_VI_after_Septuagesima|St. Dorothy|-|1 +2026-02-07|3|w|St. Romuald|Saturday_after_Septuagesima|-|-|1 +2026-02-08|2|v|Sexagesima Sunday|-|-|St. John of Matha|1 +2026-02-09|3|w|St. Cyril of Alexandria|Feria_II_after_Sexagesima|St. Appollonia|-|1 +2026-02-10|3|w|St. Scholastica|Feria_III_after_Sexagesimæ|-|-|1 +2026-02-11|3|w|Our Lady of Lourdes|Feria_IV_after_Sexagesimæ|-|-|1 +2026-02-12|3|w|Seven Holy Servite Founders|Feria_V_after_Sexagesimæ|-|-|1 +2026-02-13|4|v|Feria|Feria_VI_after_Sexagesimæ|-|-|1 +2026-02-14|4|w|III Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_Sexagesimæ|St. Valentine|-|1 +2026-02-15|2|v|Quinquagesima Sunday|-|-|Sts. Faustinus & Jovita|1 +2026-02-16|4|v|Feria|Feria_II_after_Quinquagesima|-|-|1 +2026-02-17|4|v|Feria|Feria_III_after_Quinquagesima|-|-|1 +2026-02-18|1|v|Ash Wednesday|-|-|St. Simeon|1 +2026-02-19|3|v|Feria V after Ash Wednesday|-|-|-|1 +2026-02-20|3|v|Feria VI after Ash Wednesday|-|-|-|1 +2026-02-21|3|v|Saturday after Ash Wednesday|-|-|-|1 +2026-02-22|1|v|I Sunday of Lent|-|-|Chair of St. Peter;St. Paul|1 +2026-02-23|3|v|Feria II after the I Sunday of Lent|-|St. Peter Damien|-|1 +2026-02-24|2|r|St. Matthias|Feria_III_after_the_I_Sunday_of_Lent|Feria III after the I Sunday of Lent|-|1 +2026-02-25|2|v|Ember Wednesday of Lent|-|-|-|1 +2026-02-26|3|v|Feria V after the I Sunday of Lent|-|-|-|1 +2026-02-27|2|v|Ember Friday of Lent|-|St. Gabriel of Our Lady of Sorrows|-|1 +2026-02-28|2|v|Ember Saturday of Lent|-|-|-|1 +2026-03-01|1|v|II Sunday of Lent|-|-|-|1 +2026-03-02|3|v|Feria II after the II Sunday of Lent|-|-|-|1 +2026-03-03|3|v|Feria III after the II Sunday of Lent|-|-|-|1 +2026-03-04|3|v|Feria IV after the II Sunday of Lent|-|St. Casimir;St. Lucius|-|1 +2026-03-05|3|v|Feria V after the II Sunday of Lent|-|-|-|1 +2026-03-06|3|v|Feria VI after the II Sunday of Lent|-|Sts. Felicitas & Perpetua|-|1 +2026-03-07|3|v|Saturday after the II Sunday of Lent|-|St. Thomas Aquinas|-|1 +2026-03-08|1|v|III Sunday of Lent|-|-|St. John of God|1 +2026-03-09|3|v|Feria II after the III Sunday of Lent|-|St. Frances Rome|-|1 +2026-03-10|3|v|Feria III after the III Sunday of Lent|-|Forty Holy Martyrs of Sebaste|-|1 +2026-03-11|3|v|Feria IV after the III Sunday of Lent|-|-|-|1 +2026-03-12|3|v|Feria V after the III Sunday of Lent|-|St. Gregory the Great|-|1 +2026-03-13|3|v|Feria VI after the III Sunday of Lent|-|-|-|1 +2026-03-14|3|v|Saturday after the III Sunday of Lent|-|-|-|1 +2026-03-15|1|pv|IV Sunday of Lent|-|-|-|1 +2026-03-16|3|v|Feria II after the IV Sunday of Lent|-|-|-|1 +2026-03-17|3|v|Feria III after the IV Sunday of Lent|-|St. Patrick|-|1 +2026-03-18|3|v|Feria IV after the IV Sunday of Lent|-|St. Cyril of Jerusalem|-|1 +2026-03-19|1|w|St. Joseph, Spouse of the Bl. Virgin Mary|Feria_V_after_the_IV_Sunday_of_Lent|Feria V after the IV Sunday of Lent|-|1 +2026-03-20|3|v|Feria VI after the IV Sunday of Lent|-|-|-|1 +2026-03-21|3|v|Saturday after the IV Sunday of Lent|-|St. Benedict|-|1 +2026-03-22|1|v|Passion Sunday|-|-|-|1 +2026-03-23|3|v|Feria II of Passion Week|-|-|-|1 +2026-03-24|3|v|Feria III of Passion Week|-|St. Gabriel the Archangel|-|1 +2026-03-25|1|w|Annunciation of the Blessed Virgin Mary|Feria_IV_of_Passion_Week|Feria IV of Passion Week|-|1 +2026-03-26|3|v|Feria V of Passion Week|-|-|-|1 +2026-03-27|3|v|Feria VI of Passion Week|-|For Our Lady of the Seven Sorrows|St. John Damascene|1 +2026-03-28|3|v|Saturday of Passion Week|-|St. John of Capistrano|-|1 +2026-03-29|1|rv|Palm Sunday|-|-|-|1 +2026-03-30|1|v|Feria II of Holy Week|-|-|-|1 +2026-03-31|1|v|Feria III of Holy Week|-|-|-|1 +2026-04-01|1|v|Feria IV of Holy Week|-|-|-|1 +2026-04-02|1|w|Holy Thursday|-|-|St. Francis of Paola|1 +2026-04-03|1|bv|Good Friday|-|-|-|1 +2026-04-04|1|vw|Holy Saturday|-|-|St. Isidore of Seville|1 +2026-04-05|1|w|Easter Sunday|-|-|St. Vincent Ferrer|1 +2026-04-06|1|w|Monday in the Octave of Easter|-|-|-|1 +2026-04-07|1|w|Tuesday in the Octave of Easter|-|-|-|1 +2026-04-08|1|w|Wednesday in the Octave of Easter|-|-|-|1 +2026-04-09|1|w|Thursday in the Octave of Easter|-|-|-|1 +2026-04-10|1|w|Friday in the Octave of Easter|-|-|-|1 +2026-04-11|1|w|Saturday in the Octave of Easter|-|-|St. Leo the Great|1 +2026-04-12|1|w|Low Sunday|-|-|-|1 +2026-04-13|3|r|St. Hermenegild|Monday_after_I_Sunday_after_Easter|-|-|1 +2026-04-14|3|r|St. Justin|Tuesday_after_I_Sunday_after_Easter|Sts. Tiburtius, Valerian et Maximus, Martyrs|-|1 +2026-04-15|4|w|Feria|Wednesday_after_I_Sunday_after_Easter|-|-|1 +2026-04-16|4|w|Feria|Thursday_after_I_Sunday_after_Easter|-|-|1 +2026-04-17|4|w|Feria|Friday_after_I_Sunday_after_Easter|St. Anicetus|-|1 +2026-04-18|4|w|IV Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_I_Sunday_after_Easter|-|-|1 +2026-04-19|2|w|II Sunday after Easter|-|-|-|1 +2026-04-20|4|w|Feria|Monday_after_II_Sunday_after_Easter|-|-|1 +2026-04-21|3|w|St. Anselm|Tuesday_after_II_Sunday_after_Easter|-|-|1 +2026-04-22|3|r|Sts. Soter & Caius|Wednesday_after_II_Sunday_after_Easter|-|-|1 +2026-04-23|4|w|Feria|Thursday_after_II_Sunday_after_Easter|St. George|-|1 +2026-04-24|3|r|St. Fidelis of Sigmaringen|Friday_after_II_Sunday_after_Easter|-|-|1 +2026-04-25|2|r|St. Mark|Saturday_after_II_Sunday_after_Easter|Pro rogationibus|-|1 +2026-04-26|2|w|III Sunday after Easter|-|-|Sts. Cletus & Marcellinus|1 +2026-04-27|3|w|St. Peter Canisius|Monday_after_III_Sunday_after_Easter|-|-|1 +2026-04-28|3|w|St. Paul of the Cross|Tuesday_after_III_Sunday_after_Easter|-|-|1 +2026-04-29|3|r|St. Peter of Verona|Wednesday_after_III_Sunday_after_Easter|-|-|1 +2026-04-30|3|w|St. Catherine of Siena|Thursday_after_III_Sunday_after_Easter|-|-|1 +2026-05-01|1|w|St. Joseph the Workman|Friday_after_III_Sunday_after_Easter|-|-|1 +2026-05-02|3|w|St. Athanasius|Saturday_after_III_Sunday_after_Easter|-|-|1 +2026-05-03|2|w|IV Sunday after Easter|-|-|Sts. Alexander & Companions|1 +2026-05-04|3|w|St. Monica|Monday_after_IV_Sunday_after_Easter|-|-|1 +2026-05-05|3|w|St. Pius V|Tuesday_after_IV_Sunday_after_Easter|-|-|1 +2026-05-06|4|w|Feria|Wednesday_after_IV_Sunday_after_Easter|-|-|1 +2026-05-07|3|r|St. Stanislaus|Thursday_after_IV_Sunday_after_Easter|-|-|1 +2026-05-08|4|w|Feria|Friday_after_IV_Sunday_after_Easter|-|-|1 +2026-05-09|3|w|St. Gregory of Nazianzen|Saturday_after_IV_Sunday_after_Easter|-|-|1 +2026-05-10|2|w|V Sunday after Easter|-|-|St. Antoninus;St. Gordiano and Epimacho|1 +2026-05-11|2|r|Sts. Philip & James|The_Minor_Litanies_–_Rogations|-|-|1 +2026-05-12|3|r|Sts. Nereus, Achilleus, Domitilla, & Pancras|The_Minor_Litanies_–_Rogations|-|-|1 +2026-05-13|2|w|Vigil of the Ascension|-|St. Robert Bellarmine|-|1 +2026-05-14|1|w|Ascension of the Lord|-|-|St. Boniface|1 +2026-05-15|3|w|St. John Baptist de la Salle|Feria_VI_after_the_Ascension|-|-|1 +2026-05-16|4|w|IV Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_the_Ascension|St. Ubaldus|-|1 +2026-05-17|2|w|Sunday after the Ascension|-|-|St. Paschal Baylon|1 +2026-05-18|3|r|St. Venantius|Feria_II_after_the_Ascension|-|-|1 +2026-05-19|3|w|St. Peter Celestine|Feria_III_after_the_Ascension|St. Pudentiana Virginis|-|1 +2026-05-20|3|w|St. Bernardine of Siena|Feria_IV_after_the_Ascension|-|-|1 +2026-05-21|4|w|Feria|Feria_V_after_the_Ascension|-|-|1 +2026-05-22|4|w|Feria|Feria_VI_after_the_Ascension|-|-|1 +2026-05-23|1|r|Saturday after the Ascension|-|-|-|1 +2026-05-24|1|r|Pentecost Sunday|-|-|-|1 +2026-05-25|1|r|Monday after Pentecost|-|-|St. Gregory VII;St. Urban, Pope and Martyr|1 +2026-05-26|1|r|Tuesday after Pentecost|-|-|St. Philip Neri;S. Eleutherius|1 +2026-05-27|1|r|Ember Wednesday of Pentecost|-|-|St. Bede the Venerable;St. John I|1 +2026-05-28|1|r|Thursday after Pentecost|-|-|St. Augustine of Canterbury|1 +2026-05-29|1|r|Ember Friday of Pentecost|-|-|St. Mary Magdalene de Pazzi|1 +2026-05-30|1|r|Ember Saturday of Pentecost|-|-|St. Felix I|1 +2026-05-31|1|w|Trinity Sunday|-|-|Queenship of the Blessed Virgin Mary;St. Petronilla|1 +2026-06-01|3|w|St. Angela Merici|Feria_II_after_I_Sunday_after_Pentecost|-|-|1 +2026-06-02|4|g|Feria|Feria_III_after_I_Sunday_after_Pentecost|Sts. Marcellinus, Peter, & Erasmus|-|1 +2026-06-03|4|g|Feria|Feria_IV_after_I_Sunday_after_Pentecost|-|-|1 +2026-06-04|1|w|Corpus Christi|-|-|St. Francis Caracciolo|1 +2026-06-05|3|r|St. Boniface|Feria_V_after_I_Sunday_after_Pentecost|-|-|1 +2026-06-06|3|w|St. Norbert|Saturday_after_I_Sunday_after_Pentecost|-|-|1 +2026-06-07|2|g|II Sunday after Pentecost|-|-|-|1 +2026-06-08|4|g|Feria|Feria_II_after_II_Sunday_after_Pentecost|-|-|1 +2026-06-09|4|g|Feria|Feria_III_after_II_Sunday_after_Pentecost|Sts. Primus & Felicianus|-|1 +2026-06-10|3|w|St. Margaret of Scotland|Feria_IV_after_II_Sunday_after_Pentecost|-|-|1 +2026-06-11|3|r|St. Barnabas|Feria_V_after_II_Sunday_after_Pentecost|-|-|1 +2026-06-12|1|w|Sacred Heart of Jesus|-|-|St. John of San Fecundo;St. Basilidus|1 +2026-06-13|3|w|St. Anthony of Padua|Saturday_after_II_Sunday_after_Pentecost|-|-|1 +2026-06-14|2|g|III Sunday after Pentecost|-|-|St. Basil the Great|1 +2026-06-15|4|g|Feria|Feria_II_after_III_Sunday_after_Pentecost|St. Vitus|-|1 +2026-06-16|4|g|Feria|Feria_III_after_III_Sunday_after_Pentecost|-|-|1 +2026-06-17|3|w|St. Gregory Barbarigo|Feria_IV_after_III_Sunday_after_Pentecost|-|-|1 +2026-06-18|3|r|St. Ephrem of Syria|Feria_V_after_III_Sunday_after_Pentecost|Ss. Marcus and Marcellianus|-|1 +2026-06-19|3|r|St. Julia of Falconieri|Feria_VI_after_III_Sunday_after_Pentecost|Sts. Gervasius and Protasius|-|1 +2026-06-20|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_III_Sunday_after_Pentecost|St. Silverius|-|1 +2026-06-21|2|g|IV Sunday after Pentecost|-|-|St. Aloysius Gongzaga|1 +2026-06-22|3|w|St. Paulinus of Nola|Feria_II_after_IV_Sunday_after_Pentecost|-|-|1 +2026-06-23|2|v|Vigil of the Nativity of St. John the Baptist|Feria_III_after_IV_Sunday_after_Pentecost|-|-|1 +2026-06-24|1|w|Nativity of St. John the Baptist|Feria_IV_after_IV_Sunday_after_Pentecost|-|-|1 +2026-06-25|3|w|St. William|Feria_V_after_IV_Sunday_after_Pentecost|-|-|1 +2026-06-26|3|r|Sts. John & Paul|Feria_VI_after_IV_Sunday_after_Pentecost|-|-|1 +2026-06-27|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_IV_Sunday_after_Pentecost|-|-|1 +2026-06-28|2|g|V Sunday after Pentecost|-|Vigil of Sts. Peter & Paul|-|1 +2026-06-29|1|r|Sts. Peter & Paul|Feria_II_after_V_Sunday_after_Pentecost|-|-|1 +2026-06-30|3|r|In Commemoratione Sancti Pauli Apostoli|Feria_III_after_V_Sunday_after_Pentecost|-|-|1 +2026-07-01|1|r|The Precious Blood of Our Lord Jesus Christ|Feria_IV_after_V_Sunday_after_Pentecost|-|-|1 +2026-07-02|2|w|Visitation of the Blessed Virgin Mary|Feria_V_after_V_Sunday_after_Pentecost|SS. Processus and Martinian|-|1 +2026-07-03|3|r|St. Irenaeus|Feria_VI_after_V_Sunday_after_Pentecost|-|-|1 +2026-07-04|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_V_Sunday_after_Pentecost|-|-|1 +2026-07-05|2|g|VI Sunday after Pentecost|-|-|St. Anthony Mary Zaccariah|1 +2026-07-06|4|g|Feria|Feria_II_after_VI_Sunday_after_Pentecost|-|-|1 +2026-07-07|3|w|Sts. Cyril & Methodius|Feria_III_after_VI_Sunday_after_Pentecost|-|-|1 +2026-07-08|3|w|St. Elizabeth of Portugal|Feria_IV_after_VI_Sunday_after_Pentecost|-|-|1 +2026-07-09|4|g|Feria|Feria_V_after_VI_Sunday_after_Pentecost|-|-|1 +2026-07-10|3|r|Seven Holy Brothers and Sts. Rufina & Secunda|Feria_VI_after_VI_Sunday_after_Pentecost|-|-|1 +2026-07-11|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_VI_Sunday_after_Pentecost|St. Pius I|-|1 +2026-07-12|2|g|VII Sunday after Pentecost|-|-|St. John Gualbert;Ss. Naboris et Felicis|1 +2026-07-13|4|g|Feria|Feria_II_after_VII_Sunday_after_Pentecost|-|-|1 +2026-07-14|3|w|St. Bonaventure|Feria_III_after_VII_Sunday_after_Pentecost|-|-|1 +2026-07-15|3|w|St. Henry the Emperor|Feria_IV_after_VII_Sunday_after_Pentecost|-|-|1 +2026-07-16|4|g|Feria|Feria_V_after_VII_Sunday_after_Pentecost|Our Lady of Mt. Carmel|-|1 +2026-07-17|4|g|Feria|Feria_VI_after_VII_Sunday_after_Pentecost|St. Alexis|-|1 +2026-07-18|3|r|Camillus de Lellis|Saturday_after_VII_Sunday_after_Pentecost|Ss. Symphorosa and sons|-|1 +2026-07-19|2|g|VIII Sunday after Pentecost|-|-|St. Vincent de Paul|1 +2026-07-20|3|r|St. Jerome Emiliani|Feria_II_after_VIII_Sunday_after_Pentecost|St. Margaret|-|1 +2026-07-21|3|w|St. Laurence of Brindisi|Feria_III_after_VIII_Sunday_after_Pentecost|St. Praxedis Virginis|-|1 +2026-07-22|3|w|St. Mary Magdalene|Feria_IV_after_VIII_Sunday_after_Pentecost|-|-|1 +2026-07-23|3|w|St. Apollinaris|Feria_V_after_VIII_Sunday_after_Pentecost|S. Liborii|-|1 +2026-07-24|4|g|Feria|Feria_VI_after_VIII_Sunday_after_Pentecost|St. Christina|-|1 +2026-07-25|2|r|St. James the Greater|Saturday_after_VIII_Sunday_after_Pentecost|St. Christopher|-|1 +2026-07-26|2|g|IX Sunday after Pentecost|-|St. Anne, Mother of the Blessed Virgin|-|1 +2026-07-27|4|g|Feria|Feria_II_after_IX_Sunday_after_Pentecost|St. Pantaleon|-|1 +2026-07-28|3|r|Sts. Nazarius & Celsus, St. Victor I & St. Innocent I|Feria_III_after_IX_Sunday_after_Pentecost|-|-|1 +2026-07-29|3|r|St. Martha|Feria_IV_after_IX_Sunday_after_Pentecost|Ss. Felicis, Simplicii, Faustini et Beatricis|-|1 +2026-07-30|4|g|Feria|Feria_V_after_IX_Sunday_after_Pentecost|Sts. Abdon & Sennen|-|1 +2026-07-31|3|w|St. Ignatius Loyola|Feria_VI_after_IX_Sunday_after_Pentecost|-|-|1 +2026-08-01|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_IX_Sunday_after_Pentecost|Holy Machabees|-|1 +2026-08-02|2|g|X Sunday after Pentecost|-|-|St. Alphonsus Liguori;St. Stephen I, Pope and Martyr|1 +2026-08-03|4|g|Feria|Feria_II_after_X_Sunday_after_Pentecost|-|-|1 +2026-08-04|3|w|St. Dominic|Feria_III_after_X_Sunday_after_Pentecost|-|-|1 +2026-08-05|3|w|Dedication of the Basilica of St. Mary Major|Feria_IV_after_X_Sunday_after_Pentecost|-|-|1 +2026-08-06|2|w|Transfiguration of Our Lord|Feria_V_after_X_Sunday_after_Pentecost|Pope Sixtus II, Felicissimus and Agapitus, Martyrs|-|1 +2026-08-07|3|w|St. Cajetan|Feria_VI_after_X_Sunday_after_Pentecost|St. Donatus|-|1 +2026-08-08|3|w|St. John Mary Vianney|Saturday_after_X_Sunday_after_Pentecost|Ss. Cyriacus, Largus and Smaragdus, Martyrs|-|1 +2026-08-09|3|r|Vigil of St. Lawrence|XI_Sunday_after_Pentecost|St. Romanus|-|1 +2026-08-10|2|r|St. Lawrence|Feria_II_after_XI_Sunday_after_Pentecost|-|-|1 +2026-08-11|4|g|Feria|Feria_III_after_XI_Sunday_after_Pentecost|Sts. Tiburtius & Susanna|-|1 +2026-08-12|3|w|St. Clare|Feria_IV_after_XI_Sunday_after_Pentecost|-|-|1 +2026-08-13|4|g|Feria|Feria_V_after_XI_Sunday_after_Pentecost|Sts. Hippolytus & Cassian|-|1 +2026-08-14|2|w|Vigil of the Assumption|Feria_VI_after_XI_Sunday_after_Pentecost|St. Eusebius|-|1 +2026-08-15|1|w|Assumption of the Blessed Virgin Mary|Saturday_after_XI_Sunday_after_Pentecost|-|-|1 +2026-08-16|2|g|XII Sunday after Pentecost|-|St. Joachim, Father of the Blessed Virgin|-|1 +2026-08-17|3|w|St. Hyacinth|Feria_II_after_XII_Sunday_after_Pentecost|-|-|1 +2026-08-18|4|g|Feria|Feria_III_after_XII_Sunday_after_Pentecost|St. Agapitus|-|1 +2026-08-19|3|w|St. John Eudes|Feria_IV_after_XII_Sunday_after_Pentecost|-|-|1 +2026-08-20|3|w|St. Bernard of Clairvaux|Feria_V_after_XII_Sunday_after_Pentecost|-|-|1 +2026-08-21|3|w|St. Jane Frances de Chantal|Feria_VI_after_XII_Sunday_after_Pentecost|-|-|1 +2026-08-22|2|w|Immaculate Heart of Mary|Saturday_after_XII_Sunday_after_Pentecost|Sts. Timothy, Hippolytus and Symphorianus, Martyrs|-|1 +2026-08-23|2|g|XIII Sunday after Pentecost|-|-|St. Philip Benizi|1 +2026-08-24|2|r|St. Bartholomew|Feria_II_after_XIII_Sunday_after_Pentecost|-|-|1 +2026-08-25|3|w|St. Louis IX|Feria_III_after_XIII_Sunday_after_Pentecost|-|-|1 +2026-08-26|4|g|Feria|Feria_IV_after_XIII_Sunday_after_Pentecost|St. Zephyrinus|-|1 +2026-08-27|3|w|St. Joseph Calasance|Feria_V_after_XIII_Sunday_after_Pentecost|-|-|1 +2026-08-28|3|r|St. Augustine|Feria_VI_after_XIII_Sunday_after_Pentecost|St. Hermes|-|1 +2026-08-29|3|r|Beheading of St. John the Baptist|Saturday_after_XIII_Sunday_after_Pentecost|St. Sabina|-|1 +2026-08-30|2|g|XIV Sunday after Pentecost|-|-|St. Rose of Lima;Sts. Felix and Adauctus|1 +2026-08-31|3|w|St. Raymond Nonnatus|Feria_II_after_XIV_Sunday_after_Pentecost|-|-|1 +2026-09-01|4|g|Feria|Feria_III_after_XIV_Sunday_after_Pentecost|St. Giles;Twelve Holy Brothers, Martyrs|-|1 +2026-09-02|3|w|St. Stephen of Hungary|Feria_IV_after_XIV_Sunday_after_Pentecost|-|-|1 +2026-09-03|3|w|St. Pius X|Feria_V_after_XIV_Sunday_after_Pentecost|-|-|1 +2026-09-04|4|g|Feria|Feria_VI_after_XIV_Sunday_after_Pentecost|-|-|1 +2026-09-05|3|w|St. Lawrence Justinian|Saturday_after_XIV_Sunday_after_Pentecost|-|-|1 +2026-09-06|2|g|XV Sunday after Pentecost|-|-|-|1 +2026-09-07|4|g|Feria|Feria_II_after_XV_Sunday_after_Pentecost|-|-|1 +2026-09-08|2|w|Nativity of the Blessed Virgin Mary|Feria_III_after_XV_Sunday_after_Pentecost|S. Hadriani|-|1 +2026-09-09|4|g|Feria|Feria_IV_after_XV_Sunday_after_Pentecost|St. Gorgonius|-|1 +2026-09-10|3|w|St. Nicholas of Tolentino|Feria_V_after_XV_Sunday_after_Pentecost|-|-|1 +2026-09-11|4|g|Feria|Feria_VI_after_XV_Sunday_after_Pentecost|Sts. Protus & Hyacinth|-|1 +2026-09-12|3|w|Most Holy Name of Mary|Saturday_after_XV_Sunday_after_Pentecost|-|-|1 +2026-09-13|2|g|XVI Sunday after Pentecost|-|-|-|1 +2026-09-14|2|r|Exaltation of the Holy Cross|Feria_II_after_XVI_Sunday_after_Pentecost|-|-|1 +2026-09-15|2|w|Seven Sorrows of the Blessed Virgin Mary|Feria_III_after_XVI_Sunday_after_Pentecost|S. Nicomedes|-|1 +2026-09-16|3|r|Sts. Cornelius & Cyprian|Feria_IV_after_XVI_Sunday_after_Pentecost|Sts. Euphemia, Lucy and Geminianus|-|1 +2026-09-17|4|g|Feria|Feria_V_after_XVI_Sunday_after_Pentecost|Stigmata of St. Francis|-|1 +2026-09-18|3|w|St. Joseph of Cupertino|Feria_VI_after_XVI_Sunday_after_Pentecost|-|-|1 +2026-09-19|3|r|St. Januarius & Companions|Saturday_after_XVI_Sunday_after_Pentecost|-|-|1 +2026-09-20|2|g|XVII Sunday after Pentecost|-|-|Sts. Eustace & Companions|1 +2026-09-21|2|r|St. Matthew|Feria_II_after_XVII_Sunday_after_Pentecost|-|-|1 +2026-09-22|3|w|St. Thomas of Villanova|Feria_III_after_XVII_Sunday_after_Pentecost|St. Maurice and Companions, Martyrs|-|1 +2026-09-23|2|v|Ember Wednesday of September|-|St. Linus|St. Thecla|1 +2026-09-24|4|g|Feria|Feria_V_after_XVII_Sunday_after_Pentecost|Our Lady of Ransom|-|1 +2026-09-25|2|v|Ember Friday of September|-|-|-|1 +2026-09-26|2|v|Ember Saturday of September|-|Sts. Cyprian & Justina|-|1 +2026-09-27|2|g|XVIII Sunday after Pentecost|-|-|Sts. Cosmas & Damian|1 +2026-09-28|3|r|St. Wenceslaus|Feria_II_after_XVIII_Sunday_after_Pentecost|-|-|1 +2026-09-29|1|w|Dedication of St. Michael the Archangel|Feria_III_after_XVIII_Sunday_after_Pentecost|-|-|1 +2026-09-30|3|w|St. Jerome|Feria_IV_after_XVIII_Sunday_after_Pentecost|-|-|1 +2026-10-01|4|g|Feria|Feria_V_after_XVIII_Sunday_after_Pentecost|St. Remigius|-|1 +2026-10-02|3|w|Holy Guardian Angels|Feria_VI_after_XVIII_Sunday_after_Pentecost|-|-|1 +2026-10-03|3|w|St. Theresa of the Infant Jesus|Saturday_after_XVIII_Sunday_after_Pentecost|-|-|1 +2026-10-04|2|g|XIX Sunday after Pentecost|-|-|St. Francis of Assisi|1 +2026-10-05|4|g|Feria|Feria_II_after_XIX_Sunday_after_Pentecost|St. Placid & Companions|-|1 +2026-10-06|3|w|St. Bruno|Feria_III_after_XIX_Sunday_after_Pentecost|-|-|1 +2026-10-07|2|w|Our Lady of the Rosary|Feria_IV_after_XIX_Sunday_after_Pentecost|St. Mark I|-|1 +2026-10-08|3|w|St. Bridget of Sweden|Feria_V_after_XIX_Sunday_after_Pentecost|Ss. Sergio, Baccho, Marcello and Apulejo Martyrs|-|1 +2026-10-09|3|w|St. John Leonardi|Feria_VI_after_XIX_Sunday_after_Pentecost|St. Dionysius and companions|-|1 +2026-10-10|3|w|St. Francis Borgia|Saturday_after_XIX_Sunday_after_Pentecost|-|-|1 +2026-10-11|2|g|XX Sunday after Pentecost|-|Maternity of the Blessed Virgin Mary|-|1 +2026-10-12|4|g|Feria|Feria_II_after_XX_Sunday_after_Pentecost|-|-|1 +2026-10-13|3|w|St. Edward|Feria_III_after_XX_Sunday_after_Pentecost|-|-|1 +2026-10-14|3|r|St. Callistus I|Feria_IV_after_XX_Sunday_after_Pentecost|-|-|1 +2026-10-15|3|w|St. Teresa of Avila|Feria_V_after_XX_Sunday_after_Pentecost|-|-|1 +2026-10-16|3|w|St. Hedwig|Feria_VI_after_XX_Sunday_after_Pentecost|-|-|1 +2026-10-17|3|w|St. Margaret Mary Alacoque|Saturday_after_XX_Sunday_after_Pentecost|-|-|1 +2026-10-18|2|g|XXI Sunday after Pentecost|-|St. Luke the Evangelist|-|1 +2026-10-19|3|w|St. Peter of Alcantara|Feria_II_after_XXI_Sunday_after_Pentecost|-|-|1 +2026-10-20|3|w|St. John Cantius|Feria_III_after_XXI_Sunday_after_Pentecost|-|-|1 +2026-10-21|4|g|Feria|Feria_IV_after_XXI_Sunday_after_Pentecost|St. Hilarion;St. Ursula and Companions|-|1 +2026-10-22|4|g|Feria|Feria_V_after_XXI_Sunday_after_Pentecost|-|-|1 +2026-10-23|3|w|St. Anthony Mary Claret|Feria_VI_after_XXI_Sunday_after_Pentecost|-|-|1 +2026-10-24|3|w|St. Raphael the Archangel|Saturday_after_XXI_Sunday_after_Pentecost|-|-|1 +2026-10-25|1|w|Christ the King|XXII_Sunday_after_Pentecost|-|Sts. Chrysanthus & Daria|1 +2026-10-26|4|g|Feria|Feria_II_after_XXII_Sunday_after_Pentecost|St. Evaristus|-|1 +2026-10-27|4|g|Feria|Feria_III_after_XXII_Sunday_after_Pentecost|-|-|1 +2026-10-28|2|r|Sts. Simon & Jude|Feria_IV_after_XXII_Sunday_after_Pentecost|-|-|1 +2026-10-29|4|g|Feria|Feria_V_after_XXII_Sunday_after_Pentecost|-|-|1 +2026-10-30|4|g|Feria|Feria_VI_after_XXII_Sunday_after_Pentecost|-|-|1 +2026-10-31|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_XXII_Sunday_after_Pentecost|-|-|1 +2026-11-01|1|w|All Saints|XXIII_Sunday_after_Pentecost|-|-|1 +2026-11-02|1|b|Commemoration of All Souls|Feria_II_after_XXIII_Sunday_after_Pentecost|-|-|3 +2026-11-03|4|g|Feria|Feria_III_after_XXIII_Sunday_after_Pentecost|-|-|1 +2026-11-04|3|w|St. Charles Borromeo|Feria_IV_after_XXIII_Sunday_after_Pentecost|Sts. Vitalis and Agricola, Martyrs|-|1 +2026-11-05|4|g|Feria|Feria_V_after_XXIII_Sunday_after_Pentecost|-|-|1 +2026-11-06|4|g|Feria|Feria_VI_after_XXIII_Sunday_after_Pentecost|-|-|1 +2026-11-07|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_XXIII_Sunday_after_Pentecost|-|-|1 +2026-11-08|2|g|V Sunday after Epiphany|-|-|Four Holy Crowned Martyrs|1 +2026-11-09|2|w|Dedication of the Archbasilica of Our Holy Savior|Feria_II_after_V_Sunday_after_Epiphany|St. Theodore|-|1 +2026-11-10|3|w|St. Andrew Avellino|Feria_III_after_V_Sunday_after_Epiphany|Sts. Tryphonis, Respicii, et Nymphae|-|1 +2026-11-11|3|w|St. Martin of Tours|Feria_IV_after_V_Sunday_after_Epiphany|St. Menna|-|1 +2026-11-12|3|r|St. Martin I|Feria_V_after_V_Sunday_after_Epiphany|-|-|1 +2026-11-13|4|g|Feria|Feria_VI_after_V_Sunday_after_Epiphany|St. Didacus|-|1 +2026-11-14|3|w|St. Josaphat|Saturday_after_V_Sunday_after_Epiphany|-|-|1 +2026-11-15|2|g|VI Sunday after Epiphany|-|-|St. Albert the Great|1 +2026-11-16|3|w|St. Gertrude the Great|Feria_II_after_VI_Sunday_after_Epiphany|-|-|1 +2026-11-17|3|w|St. Gregory the Wonderworker|Feria_III_after_VI_Sunday_after_Epiphany|-|-|1 +2026-11-18|3|w|Dedication of the Basilicas of Sts. Peter & Paul|Feria_IV_after_VI_Sunday_after_Epiphany|-|-|1 +2026-11-19|3|w|St. Elizabeth of Hungary|Feria_V_after_VI_Sunday_after_Epiphany|St. Pontian|-|1 +2026-11-20|3|w|St. Felix of Valois|Feria_VI_after_VI_Sunday_after_Epiphany|-|-|1 +2026-11-21|3|w|Presentation of the Blessed Virgin Mary|Saturday_after_VI_Sunday_after_Epiphany|-|-|1 +2026-11-22|2|g|XXIV Sunday after Pentecost|-|-|St. Cecilia|1 +2026-11-23|3|r|St. Clement I|Feria_II_after_XXIV_Sunday_after_Pentecost|St. Felicity|-|1 +2026-11-24|3|w|St. John of the Cross|Feria_III_after_XXIV_Sunday_after_Pentecost|St. Chrysogonus|-|1 +2026-11-25|3|r|St. Catherine of Alexandria|Feria_IV_after_XXIV_Sunday_after_Pentecost|-|-|1 +2026-11-26|3|w|St. Sylvester|Feria_V_after_XXIV_Sunday_after_Pentecost|St. Peter of Alexandria|-|1 +2026-11-27|4|g|Feria|Feria_VI_after_XXIV_Sunday_after_Pentecost|-|-|1 +2026-11-28|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_XXIV_Sunday_after_Pentecost|-|-|1 +2026-11-29|1|v|I Sunday of Advent|-|-|St. Saturninus|1 +2026-11-30|2|r|St. Andrew|Feria_II_after_I_Sunday_of_Advent|-|-|1 +2026-12-01|3|v|Feria III after I Sunday of Advent|-|-|-|1 +2026-12-02|3|r|St. Vivian|Feria_IV_after_I_Sunday_of_Advent|Feria IV after I Sunday of Advent|-|1 +2026-12-03|3|w|St. Francis Xavier|Feria_V_after_I_Sunday_of_Advent|Feria V after I Sunday of Advent|-|1 +2026-12-04|3|w|St. Peter Chrysologus|Feria_VI_after_I_Sunday_of_Advent|Feria VI after I Sunday of Advent|-|1 +2026-12-05|3|v|Sabbato after I Sunday of Advent|-|St. Sabbas|-|1 +2026-12-06|1|v|II Sunday of Advent|-|-|St. Nicholas|1 +2026-12-07|3|w|St. Ambrose|Feria_II_after_II_Sunday_of_Advent|Feria II after II Sunday of Advent|-|1 +2026-12-08|1|w|Immaculate Conception of the Blessed Virgin Mary|Feria_III_after_II_Sunday_of_Advent|-|-|1 +2026-12-09|3|v|Feria IV after II Sunday of Advent|-|-|-|1 +2026-12-10|3|v|Feria V after II Sunday of Advent|-|St. Melchiades|-|1 +2026-12-11|3|w|St. Damasus I|Feria_VI_after_II_Sunday_of_Advent|Feria VI after II Sunday of Advent|-|1 +2026-12-12|3|v|Sabbato after II Sunday of Advent|-|-|-|1 +2026-12-13|1|pv|III Sunday of Advent|-|-|St. Lucy|1 +2026-12-14|3|pv|Feria II after III Sunday of Advent|-|-|-|1 +2026-12-15|3|pv|Feria III after III Sunday of Advent|-|-|-|1 +2026-12-16|2|v|Ember Wednesday of Advent|-|St. Eusebius|-|1 +2026-12-17|2|pv|Feria V after III Sunday of Advent|-|-|-|1 +2026-12-18|2|v|Ember Friday of Advent|-|-|-|1 +2026-12-19|2|v|Ember Saturday of Advent|-|-|-|1 +2026-12-20|1|v|IV Sunday of Advent|-|-|-|1 +2026-12-21|2|r|St. Thomas|Feria_II_after_IV_Sunday_of_Advent|Feria II after IV Sunday of Advent|-|1 +2026-12-22|2|v|Feria III after IV Sunday of Advent|-|-|-|1 +2026-12-23|2|v|Feria IV after IV Sunday of Advent|-|-|-|1 +2026-12-24|1|v|Vigil of Christmas|-|-|-|1 +2026-12-25|1|w|The Nativity of Our Lord|-|-|-|3 +2026-12-26|2|r|St. Stephen|-|For Octave of the Nativity|-|1 +2026-12-27|2|w|Sunday in the Octave of Christmas|-|St. John the Evangelist|For Octave of the Nativity|1 +2026-12-28|2|r|Holy Innocents|-|For Octave of the Nativity|-|1 +2026-12-29|2|w|Feria in the Octave of Christmas|-|St. Thomas Becket|-|1 +2026-12-30|2|w|Feria in the Octave of Christmas|-|-|-|1 +2026-12-31|2|w|Feria in the Octave of Christmas|-|St. Silvester|-|1 +2027-01-01|1|w|Octave Day of Christmas|-|-|-|1 +2027-01-02|4|w|II Mass of the B. V. M. – Vultum Tuum|-|-|-|1 +2027-01-03|2|w|Holy Name of Jesus|-|-|-|1 +2027-01-04|4|w|Feria|-|-|-|1 +2027-01-05|4|w|Feria|-|St. Telesphorus Pope and Martyr|-|1 +2027-01-06|1|w|Epiphany of the Lord|-|-|-|1 +2027-01-07|4|w|Feria|-|-|-|1 +2027-01-08|4|w|Feria|-|-|-|1 +2027-01-09|4|w|II Mass of the B. V. M. – Vultum Tuum|-|-|-|1 +2027-01-10|2|w|The Holy Family: Jesus, Mary & Joseph|-|-|-|1 +2027-01-11|4|w|Feria|Feria_II_after_Epiphany|St. Hyginus Pope and Martyr|-|1 +2027-01-12|4|w|Feria|Feria_III_after_Epiphany|-|-|1 +2027-01-13|2|w|Commemoration of the Baptism of the Lord|Feria_IV_after_Epiphany|-|-|1 +2027-01-14|3|w|St. Hilary|Feria_V_after_Epiphany|S. Felicis|-|1 +2027-01-15|3|w|St. Paul, the First Hermit|Feria_VI_after_Epiphany|St. Maur, Abbot|-|1 +2027-01-16|3|r|St. Marcellus I|Saturday_after_Epiphany|-|-|1 +2027-01-17|2|g|II Sunday after Epiphany|-|-|St. Anthony|1 +2027-01-18|4|g|Feria|Feria_II_after_II_Sunday_after_Epiphany|St. Prisca|-|1 +2027-01-19|4|g|Feria|Feria_III_after_II_Sunday_after_Epiphany|Sts. Marius, Martha, Audifax & Abachum;St. Canute, Martyr|-|1 +2027-01-20|3|r|Sts. Fabian & Sebastian|Feria_IV_after_II_Sunday_after_Epiphany|-|-|1 +2027-01-21|3|r|St. Agnes|Feria_V_after_II_Sunday_after_Epiphany|-|-|1 +2027-01-22|3|r|Sts. Vincent & Anastasius|Feria_VI_after_II_Sunday_after_Epiphany|-|-|1 +2027-01-23|3|w|St. Raymond of Peñafort|Saturday_after_II_Sunday_after_Epiphany|St. Emerentiana|-|1 +2027-01-24|2|v|Septuagesima Sunday|-|-|St. Timothy|1 +2027-01-25|3|w|Conversion of St. Paul|Feria_II_after_Septuagesima|St. Peter|-|1 +2027-01-26|3|r|St. Polycarp|Feria_III_after_Septuagesima|-|-|1 +2027-01-27|3|w|St. John Chrysostom|Feria_IV_after_Septuagesima|-|-|1 +2027-01-28|3|w|St. Peter Nolasco|Feria_V_after_Septuagesima|St. Agnes|-|1 +2027-01-29|3|w|St. Francis de Sales|Feria_VI_after_Septuagesima|-|-|1 +2027-01-30|3|r|St. Martina|Saturday_after_Septuagesima|-|-|1 +2027-01-31|2|v|Sexagesima Sunday|-|-|St. John Bosco|1 +2027-02-01|3|r|St. Ignatius of Antioch|Feria_II_after_Sexagesima|-|-|1 +2027-02-02|2|w|Purification of the Blessed Virgin Mary|Feria_III_after_Sexagesimæ|-|-|1 +2027-02-03|4|v|Feria|Feria_IV_after_Sexagesimæ|St. Blaise|-|1 +2027-02-04|3|w|St. Andrew Corsini|Feria_V_after_Sexagesimæ|-|-|1 +2027-02-05|3|r|St. Agatha|Feria_VI_after_Sexagesimæ|-|-|1 +2027-02-06|3|w|St. Titus|Saturday_after_Sexagesimæ|St. Dorothy|-|1 +2027-02-07|2|v|Quinquagesima Sunday|-|-|St. Romuald|1 +2027-02-08|3|w|St. John of Matha|Feria_II_after_Quinquagesima|-|-|1 +2027-02-09|3|w|St. Cyril of Alexandria|Feria_III_after_Quinquagesima|St. Appollonia|-|1 +2027-02-10|1|v|Ash Wednesday|-|-|St. Scholastica|1 +2027-02-11|3|v|Feria V after Ash Wednesday|-|Our Lady of Lourdes|-|1 +2027-02-12|3|v|Feria VI after Ash Wednesday|-|Seven Holy Servite Founders|-|1 +2027-02-13|3|v|Saturday after Ash Wednesday|-|-|-|1 +2027-02-14|1|v|I Sunday of Lent|-|-|St. Valentine|1 +2027-02-15|3|v|Feria II after the I Sunday of Lent|-|Sts. Faustinus & Jovita|-|1 +2027-02-16|3|v|Feria III after the I Sunday of Lent|-|-|-|1 +2027-02-17|2|v|Ember Wednesday of Lent|-|-|-|1 +2027-02-18|3|v|Feria V after the I Sunday of Lent|-|St. Simeon|-|1 +2027-02-19|2|v|Ember Friday of Lent|-|-|-|1 +2027-02-20|2|v|Ember Saturday of Lent|-|-|-|1 +2027-02-21|1|v|II Sunday of Lent|-|-|-|1 +2027-02-22|2|w|Chair of St. Peter|Feria_II_after_the_II_Sunday_of_Lent|St. Paul;Feria II after the II Sunday of Lent|-|1 +2027-02-23|3|v|Feria III after the II Sunday of Lent|-|St. Peter Damien|-|1 +2027-02-24|2|r|St. Matthias|Feria_IV_after_the_II_Sunday_of_Lent|Feria IV after the II Sunday of Lent|-|1 +2027-02-25|3|v|Feria V after the II Sunday of Lent|-|-|-|1 +2027-02-26|3|v|Feria VI after the II Sunday of Lent|-|-|-|1 +2027-02-27|3|v|Saturday after the II Sunday of Lent|-|St. Gabriel of Our Lady of Sorrows|-|1 +2027-02-28|1|v|III Sunday of Lent|-|-|-|1 +2027-03-01|3|v|Feria II after the III Sunday of Lent|-|-|-|1 +2027-03-02|3|v|Feria III after the III Sunday of Lent|-|-|-|1 +2027-03-03|3|v|Feria IV after the III Sunday of Lent|-|-|-|1 +2027-03-04|3|v|Feria V after the III Sunday of Lent|-|St. Casimir;St. Lucius|-|1 +2027-03-05|3|v|Feria VI after the III Sunday of Lent|-|-|-|1 +2027-03-06|3|v|Saturday after the III Sunday of Lent|-|Sts. Felicitas & Perpetua|-|1 +2027-03-07|1|pv|IV Sunday of Lent|-|-|St. Thomas Aquinas|1 +2027-03-08|3|v|Feria II after the IV Sunday of Lent|-|St. John of God|-|1 +2027-03-09|3|v|Feria III after the IV Sunday of Lent|-|St. Frances Rome|-|1 +2027-03-10|3|v|Feria IV after the IV Sunday of Lent|-|Forty Holy Martyrs of Sebaste|-|1 +2027-03-11|3|v|Feria V after the IV Sunday of Lent|-|-|-|1 +2027-03-12|3|v|Feria VI after the IV Sunday of Lent|-|St. Gregory the Great|-|1 +2027-03-13|3|v|Saturday after the IV Sunday of Lent|-|-|-|1 +2027-03-14|1|v|Passion Sunday|-|-|-|1 +2027-03-15|3|v|Feria II of Passion Week|-|-|-|1 +2027-03-16|3|v|Feria III of Passion Week|-|-|-|1 +2027-03-17|3|v|Feria IV of Passion Week|-|St. Patrick|-|1 +2027-03-18|3|v|Feria V of Passion Week|-|St. Cyril of Jerusalem|-|1 +2027-03-19|3|v|Feria VI of Passion Week|-|For Our Lady of the Seven Sorrows|St. Joseph, Spouse of the Bl. Virgin Mary|1 +2027-03-20|3|v|Saturday of Passion Week|-|-|-|1 +2027-03-21|1|rv|Palm Sunday|-|-|St. Benedict|1 +2027-03-22|1|v|Feria II of Holy Week|-|-|-|1 +2027-03-23|1|v|Feria III of Holy Week|-|-|-|1 +2027-03-24|1|v|Feria IV of Holy Week|-|-|St. Gabriel the Archangel|1 +2027-03-25|1|w|Holy Thursday|-|-|Annunciation of the Blessed Virgin Mary|1 +2027-03-26|1|bv|Good Friday|-|-|-|1 +2027-03-27|1|vw|Holy Saturday|-|-|St. John Damascene|1 +2027-03-28|1|w|Easter Sunday|-|-|St. John of Capistrano|1 +2027-03-29|1|w|Monday in the Octave of Easter|-|-|-|1 +2027-03-30|1|w|Tuesday in the Octave of Easter|-|-|-|1 +2027-03-31|1|w|Wednesday in the Octave of Easter|-|-|-|1 +2027-04-01|1|w|Thursday in the Octave of Easter|-|-|-|1 +2027-04-02|1|w|Friday in the Octave of Easter|-|-|St. Francis of Paola|1 +2027-04-03|1|w|Saturday in the Octave of Easter|-|-|-|1 +2027-04-04|1|w|Low Sunday|-|-|St. Isidore of Seville|1 +2027-04-05|1|w|Annunciation of the Blessed Virgin Mary|Monday_after_I_Sunday_after_Easter|-|St. Vincent Ferrer|1 +2027-04-06|4|w|Feria|Tuesday_after_I_Sunday_after_Easter|-|-|1 +2027-04-07|4|w|Feria|Wednesday_after_I_Sunday_after_Easter|-|-|1 +2027-04-08|4|w|Feria|Thursday_after_I_Sunday_after_Easter|-|-|1 +2027-04-09|4|w|Feria|Friday_after_I_Sunday_after_Easter|-|-|1 +2027-04-10|4|w|IV Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_I_Sunday_after_Easter|-|-|1 +2027-04-11|2|w|II Sunday after Easter|-|-|St. Leo the Great|1 +2027-04-12|4|w|Feria|Monday_after_II_Sunday_after_Easter|-|-|1 +2027-04-13|3|r|St. Hermenegild|Tuesday_after_II_Sunday_after_Easter|-|-|1 +2027-04-14|3|r|St. Justin|Wednesday_after_II_Sunday_after_Easter|Sts. Tiburtius, Valerian et Maximus, Martyrs|-|1 +2027-04-15|4|w|Feria|Thursday_after_II_Sunday_after_Easter|-|-|1 +2027-04-16|4|w|Feria|Friday_after_II_Sunday_after_Easter|-|-|1 +2027-04-17|4|w|IV Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_II_Sunday_after_Easter|St. Anicetus|-|1 +2027-04-18|2|w|III Sunday after Easter|-|-|-|1 +2027-04-19|4|w|Feria|Monday_after_III_Sunday_after_Easter|-|-|1 +2027-04-20|4|w|Feria|Tuesday_after_III_Sunday_after_Easter|-|-|1 +2027-04-21|3|w|St. Anselm|Wednesday_after_III_Sunday_after_Easter|-|-|1 +2027-04-22|3|r|Sts. Soter & Caius|Thursday_after_III_Sunday_after_Easter|-|-|1 +2027-04-23|4|w|Feria|Friday_after_III_Sunday_after_Easter|St. George|-|1 +2027-04-24|3|r|St. Fidelis of Sigmaringen|Saturday_after_III_Sunday_after_Easter|-|-|1 +2027-04-25|2|w|IV Sunday after Easter|-|St. Mark|Pro rogationibus|1 +2027-04-26|3|r|Sts. Cletus & Marcellinus|Monday_after_IV_Sunday_after_Easter|-|-|1 +2027-04-27|3|w|St. Peter Canisius|Tuesday_after_IV_Sunday_after_Easter|-|-|1 +2027-04-28|3|w|St. Paul of the Cross|Wednesday_after_IV_Sunday_after_Easter|-|-|1 +2027-04-29|3|r|St. Peter of Verona|Thursday_after_IV_Sunday_after_Easter|-|-|1 +2027-04-30|3|w|St. Catherine of Siena|Friday_after_IV_Sunday_after_Easter|-|-|1 +2027-05-01|1|w|St. Joseph the Workman|Saturday_after_IV_Sunday_after_Easter|-|-|1 +2027-05-02|2|w|V Sunday after Easter|-|-|St. Athanasius|1 +2027-05-03|4|w|Feria|The_Minor_Litanies_–_Rogations|Sts. Alexander & Companions|-|1 +2027-05-04|3|w|St. Monica|The_Minor_Litanies_–_Rogations|-|-|1 +2027-05-05|2|w|Vigil of the Ascension|-|St. Pius V|-|1 +2027-05-06|1|w|Ascension of the Lord|-|-|-|1 +2027-05-07|3|r|St. Stanislaus|Feria_VI_after_the_Ascension|-|-|1 +2027-05-08|4|w|IV Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_the_Ascension|-|-|1 +2027-05-09|2|w|Sunday after the Ascension|-|-|St. Gregory of Nazianzen|1 +2027-05-10|3|w|St. Antoninus|Feria_II_after_the_Ascension|St. Gordiano and Epimacho|-|1 +2027-05-11|2|r|Sts. Philip & James|Feria_III_after_the_Ascension|-|-|1 +2027-05-12|3|r|Sts. Nereus, Achilleus, Domitilla, & Pancras|Feria_IV_after_the_Ascension|-|-|1 +2027-05-13|3|w|St. Robert Bellarmine|Feria_V_after_the_Ascension|-|-|1 +2027-05-14|4|w|Feria|Feria_VI_after_the_Ascension|St. Boniface|-|1 +2027-05-15|1|r|Saturday after the Ascension|-|-|St. John Baptist de la Salle|1 +2027-05-16|1|r|Pentecost Sunday|-|-|St. Ubaldus|1 +2027-05-17|1|r|Monday after Pentecost|-|-|St. Paschal Baylon|1 +2027-05-18|1|r|Tuesday after Pentecost|-|-|St. Venantius|1 +2027-05-19|1|r|Ember Wednesday of Pentecost|-|-|St. Peter Celestine;St. Pudentiana Virginis|1 +2027-05-20|1|r|Thursday after Pentecost|-|-|St. Bernardine of Siena|1 +2027-05-21|1|r|Ember Friday of Pentecost|-|-|-|1 +2027-05-22|1|r|Ember Saturday of Pentecost|-|-|-|1 +2027-05-23|1|w|Trinity Sunday|-|-|-|1 +2027-05-24|4|g|Feria|Feria_II_after_I_Sunday_after_Pentecost|-|-|1 +2027-05-25|3|w|St. Gregory VII|Feria_III_after_I_Sunday_after_Pentecost|St. Urban, Pope and Martyr|-|1 +2027-05-26|3|w|St. Philip Neri|Feria_IV_after_I_Sunday_after_Pentecost|S. Eleutherius|-|1 +2027-05-27|1|w|Corpus Christi|-|-|St. Bede the Venerable;St. John I|1 +2027-05-28|3|w|St. Augustine of Canterbury|Feria_V_after_I_Sunday_after_Pentecost|-|-|1 +2027-05-29|3|w|St. Mary Magdalene de Pazzi|Saturday_after_I_Sunday_after_Pentecost|-|-|1 +2027-05-30|2|g|II Sunday after Pentecost|-|-|St. Felix I|1 +2027-05-31|2|w|Queenship of the Blessed Virgin Mary|Feria_II_after_II_Sunday_after_Pentecost|St. Petronilla|-|1 +2027-06-01|3|w|St. Angela Merici|Feria_III_after_II_Sunday_after_Pentecost|-|-|1 +2027-06-02|4|g|Feria|Feria_IV_after_II_Sunday_after_Pentecost|Sts. Marcellinus, Peter, & Erasmus|-|1 +2027-06-03|4|g|Feria|Feria_V_after_II_Sunday_after_Pentecost|-|-|1 +2027-06-04|1|w|Sacred Heart of Jesus|-|-|St. Francis Caracciolo|1 +2027-06-05|3|r|St. Boniface|Saturday_after_II_Sunday_after_Pentecost|-|-|1 +2027-06-06|2|g|III Sunday after Pentecost|-|-|St. Norbert|1 +2027-06-07|4|g|Feria|Feria_II_after_III_Sunday_after_Pentecost|-|-|1 +2027-06-08|4|g|Feria|Feria_III_after_III_Sunday_after_Pentecost|-|-|1 +2027-06-09|4|g|Feria|Feria_IV_after_III_Sunday_after_Pentecost|Sts. Primus & Felicianus|-|1 +2027-06-10|3|w|St. Margaret of Scotland|Feria_V_after_III_Sunday_after_Pentecost|-|-|1 +2027-06-11|3|r|St. Barnabas|Feria_VI_after_III_Sunday_after_Pentecost|-|-|1 +2027-06-12|3|r|St. John of San Fecundo|Saturday_after_III_Sunday_after_Pentecost|St. Basilidus|-|1 +2027-06-13|2|g|IV Sunday after Pentecost|-|-|St. Anthony of Padua|1 +2027-06-14|3|w|St. Basil the Great|Feria_II_after_IV_Sunday_after_Pentecost|-|-|1 +2027-06-15|4|g|Feria|Feria_III_after_IV_Sunday_after_Pentecost|St. Vitus|-|1 +2027-06-16|4|g|Feria|Feria_IV_after_IV_Sunday_after_Pentecost|-|-|1 +2027-06-17|3|w|St. Gregory Barbarigo|Feria_V_after_IV_Sunday_after_Pentecost|-|-|1 +2027-06-18|3|r|St. Ephrem of Syria|Feria_VI_after_IV_Sunday_after_Pentecost|Ss. Marcus and Marcellianus|-|1 +2027-06-19|3|r|St. Julia of Falconieri|Saturday_after_IV_Sunday_after_Pentecost|Sts. Gervasius and Protasius|-|1 +2027-06-20|2|g|V Sunday after Pentecost|-|-|St. Silverius|1 +2027-06-21|3|w|St. Aloysius Gongzaga|Feria_II_after_V_Sunday_after_Pentecost|-|-|1 +2027-06-22|3|w|St. Paulinus of Nola|Feria_III_after_V_Sunday_after_Pentecost|-|-|1 +2027-06-23|2|v|Vigil of the Nativity of St. John the Baptist|Feria_IV_after_V_Sunday_after_Pentecost|-|-|1 +2027-06-24|1|w|Nativity of St. John the Baptist|Feria_V_after_V_Sunday_after_Pentecost|-|-|1 +2027-06-25|3|w|St. William|Feria_VI_after_V_Sunday_after_Pentecost|-|-|1 +2027-06-26|3|r|Sts. John & Paul|Saturday_after_V_Sunday_after_Pentecost|-|-|1 +2027-06-27|2|g|VI Sunday after Pentecost|-|-|-|1 +2027-06-28|2|v|Vigil of Sts. Peter & Paul|Feria_II_after_VI_Sunday_after_Pentecost|-|-|1 +2027-06-29|1|r|Sts. Peter & Paul|Feria_III_after_VI_Sunday_after_Pentecost|-|-|1 +2027-06-30|3|r|In Commemoratione Sancti Pauli Apostoli|Feria_IV_after_VI_Sunday_after_Pentecost|-|-|1 +2027-07-01|1|r|The Precious Blood of Our Lord Jesus Christ|Feria_V_after_VI_Sunday_after_Pentecost|-|-|1 +2027-07-02|2|w|Visitation of the Blessed Virgin Mary|Feria_VI_after_VI_Sunday_after_Pentecost|SS. Processus and Martinian|-|1 +2027-07-03|3|r|St. Irenaeus|Saturday_after_VI_Sunday_after_Pentecost|-|-|1 +2027-07-04|2|g|VII Sunday after Pentecost|-|-|-|1 +2027-07-05|3|w|St. Anthony Mary Zaccariah|Feria_II_after_VII_Sunday_after_Pentecost|-|-|1 +2027-07-06|4|g|Feria|Feria_III_after_VII_Sunday_after_Pentecost|-|-|1 +2027-07-07|3|w|Sts. Cyril & Methodius|Feria_IV_after_VII_Sunday_after_Pentecost|-|-|1 +2027-07-08|3|w|St. Elizabeth of Portugal|Feria_V_after_VII_Sunday_after_Pentecost|-|-|1 +2027-07-09|4|g|Feria|Feria_VI_after_VII_Sunday_after_Pentecost|-|-|1 +2027-07-10|3|r|Seven Holy Brothers and Sts. Rufina & Secunda|Saturday_after_VII_Sunday_after_Pentecost|-|-|1 +2027-07-11|2|g|VIII Sunday after Pentecost|-|-|St. Pius I|1 +2027-07-12|3|r|St. John Gualbert|Feria_II_after_VIII_Sunday_after_Pentecost|Ss. Naboris et Felicis|-|1 +2027-07-13|4|g|Feria|Feria_III_after_VIII_Sunday_after_Pentecost|-|-|1 +2027-07-14|3|w|St. Bonaventure|Feria_IV_after_VIII_Sunday_after_Pentecost|-|-|1 +2027-07-15|3|w|St. Henry the Emperor|Feria_V_after_VIII_Sunday_after_Pentecost|-|-|1 +2027-07-16|4|g|Feria|Feria_VI_after_VIII_Sunday_after_Pentecost|Our Lady of Mt. Carmel|-|1 +2027-07-17|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_VIII_Sunday_after_Pentecost|St. Alexis|-|1 +2027-07-18|2|g|IX Sunday after Pentecost|-|-|Camillus de Lellis;Ss. Symphorosa and sons|1 +2027-07-19|3|w|St. Vincent de Paul|Feria_II_after_IX_Sunday_after_Pentecost|-|-|1 +2027-07-20|3|r|St. Jerome Emiliani|Feria_III_after_IX_Sunday_after_Pentecost|St. Margaret|-|1 +2027-07-21|3|w|St. Laurence of Brindisi|Feria_IV_after_IX_Sunday_after_Pentecost|St. Praxedis Virginis|-|1 +2027-07-22|3|w|St. Mary Magdalene|Feria_V_after_IX_Sunday_after_Pentecost|-|-|1 +2027-07-23|3|w|St. Apollinaris|Feria_VI_after_IX_Sunday_after_Pentecost|S. Liborii|-|1 +2027-07-24|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_IX_Sunday_after_Pentecost|St. Christina|-|1 +2027-07-25|2|g|X Sunday after Pentecost|-|St. James the Greater|St. Christopher|1 +2027-07-26|2|w|St. Anne, Mother of the Blessed Virgin|Feria_II_after_X_Sunday_after_Pentecost|-|-|1 +2027-07-27|4|g|Feria|Feria_III_after_X_Sunday_after_Pentecost|St. Pantaleon|-|1 +2027-07-28|3|r|Sts. Nazarius & Celsus, St. Victor I & St. Innocent I|Feria_IV_after_X_Sunday_after_Pentecost|-|-|1 +2027-07-29|3|r|St. Martha|Feria_V_after_X_Sunday_after_Pentecost|Ss. Felicis, Simplicii, Faustini et Beatricis|-|1 +2027-07-30|4|g|Feria|Feria_VI_after_X_Sunday_after_Pentecost|Sts. Abdon & Sennen|-|1 +2027-07-31|3|w|St. Ignatius Loyola|Saturday_after_X_Sunday_after_Pentecost|-|-|1 +2027-08-01|2|g|XI Sunday after Pentecost|-|-|Holy Machabees|1 +2027-08-02|3|r|St. Alphonsus Liguori|Feria_II_after_XI_Sunday_after_Pentecost|St. Stephen I, Pope and Martyr|-|1 +2027-08-03|4|g|Feria|Feria_III_after_XI_Sunday_after_Pentecost|-|-|1 +2027-08-04|3|w|St. Dominic|Feria_IV_after_XI_Sunday_after_Pentecost|-|-|1 +2027-08-05|3|w|Dedication of the Basilica of St. Mary Major|Feria_V_after_XI_Sunday_after_Pentecost|-|-|1 +2027-08-06|2|w|Transfiguration of Our Lord|Feria_VI_after_XI_Sunday_after_Pentecost|Pope Sixtus II, Felicissimus and Agapitus, Martyrs|-|1 +2027-08-07|3|w|St. Cajetan|Saturday_after_XI_Sunday_after_Pentecost|St. Donatus|-|1 +2027-08-08|2|g|XII Sunday after Pentecost|-|-|St. John Mary Vianney;Ss. Cyriacus, Largus and Smaragdus, Martyrs|1 +2027-08-09|3|r|Vigil of St. Lawrence|Feria_II_after_XII_Sunday_after_Pentecost|St. Romanus|-|1 +2027-08-10|2|r|St. Lawrence|Feria_III_after_XII_Sunday_after_Pentecost|-|-|1 +2027-08-11|4|g|Feria|Feria_IV_after_XII_Sunday_after_Pentecost|Sts. Tiburtius & Susanna|-|1 +2027-08-12|3|w|St. Clare|Feria_V_after_XII_Sunday_after_Pentecost|-|-|1 +2027-08-13|4|g|Feria|Feria_VI_after_XII_Sunday_after_Pentecost|Sts. Hippolytus & Cassian|-|1 +2027-08-14|2|w|Vigil of the Assumption|Saturday_after_XII_Sunday_after_Pentecost|St. Eusebius|-|1 +2027-08-15|1|w|Assumption of the Blessed Virgin Mary|XIII_Sunday_after_Pentecost|-|-|1 +2027-08-16|2|w|St. Joachim, Father of the Blessed Virgin|Feria_II_after_XIII_Sunday_after_Pentecost|-|-|1 +2027-08-17|3|w|St. Hyacinth|Feria_III_after_XIII_Sunday_after_Pentecost|-|-|1 +2027-08-18|4|g|Feria|Feria_IV_after_XIII_Sunday_after_Pentecost|St. Agapitus|-|1 +2027-08-19|3|w|St. John Eudes|Feria_V_after_XIII_Sunday_after_Pentecost|-|-|1 +2027-08-20|3|w|St. Bernard of Clairvaux|Feria_VI_after_XIII_Sunday_after_Pentecost|-|-|1 +2027-08-21|3|w|St. Jane Frances de Chantal|Saturday_after_XIII_Sunday_after_Pentecost|-|-|1 +2027-08-22|2|g|XIV Sunday after Pentecost|-|Immaculate Heart of Mary|Sts. Timothy, Hippolytus and Symphorianus, Martyrs|1 +2027-08-23|3|w|St. Philip Benizi|Feria_II_after_XIV_Sunday_after_Pentecost|-|-|1 +2027-08-24|2|r|St. Bartholomew|Feria_III_after_XIV_Sunday_after_Pentecost|-|-|1 +2027-08-25|3|w|St. Louis IX|Feria_IV_after_XIV_Sunday_after_Pentecost|-|-|1 +2027-08-26|4|g|Feria|Feria_V_after_XIV_Sunday_after_Pentecost|St. Zephyrinus|-|1 +2027-08-27|3|w|St. Joseph Calasance|Feria_VI_after_XIV_Sunday_after_Pentecost|-|-|1 +2027-08-28|3|r|St. Augustine|Saturday_after_XIV_Sunday_after_Pentecost|St. Hermes|-|1 +2027-08-29|2|g|XV Sunday after Pentecost|-|-|Beheading of St. John the Baptist;St. Sabina|1 +2027-08-30|3|r|St. Rose of Lima|Feria_II_after_XV_Sunday_after_Pentecost|Sts. Felix and Adauctus|-|1 +2027-08-31|3|w|St. Raymond Nonnatus|Feria_III_after_XV_Sunday_after_Pentecost|-|-|1 +2027-09-01|4|g|Feria|Feria_IV_after_XV_Sunday_after_Pentecost|St. Giles;Twelve Holy Brothers, Martyrs|-|1 +2027-09-02|3|w|St. Stephen of Hungary|Feria_V_after_XV_Sunday_after_Pentecost|-|-|1 +2027-09-03|3|w|St. Pius X|Feria_VI_after_XV_Sunday_after_Pentecost|-|-|1 +2027-09-04|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_XV_Sunday_after_Pentecost|-|-|1 +2027-09-05|2|g|XVI Sunday after Pentecost|-|-|St. Lawrence Justinian|1 +2027-09-06|4|g|Feria|Feria_II_after_XVI_Sunday_after_Pentecost|-|-|1 +2027-09-07|4|g|Feria|Feria_III_after_XVI_Sunday_after_Pentecost|-|-|1 +2027-09-08|2|w|Nativity of the Blessed Virgin Mary|Feria_IV_after_XVI_Sunday_after_Pentecost|S. Hadriani|-|1 +2027-09-09|4|g|Feria|Feria_V_after_XVI_Sunday_after_Pentecost|St. Gorgonius|-|1 +2027-09-10|3|w|St. Nicholas of Tolentino|Feria_VI_after_XVI_Sunday_after_Pentecost|-|-|1 +2027-09-11|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_XVI_Sunday_after_Pentecost|Sts. Protus & Hyacinth|-|1 +2027-09-12|2|g|XVII Sunday after Pentecost|-|-|Most Holy Name of Mary|1 +2027-09-13|4|g|Feria|Feria_II_after_XVII_Sunday_after_Pentecost|-|-|1 +2027-09-14|2|r|Exaltation of the Holy Cross|Feria_III_after_XVII_Sunday_after_Pentecost|-|-|1 +2027-09-15|2|w|Seven Sorrows of the Blessed Virgin Mary|Feria_IV_after_XVII_Sunday_after_Pentecost|S. Nicomedes|-|1 +2027-09-16|3|r|Sts. Cornelius & Cyprian|Feria_V_after_XVII_Sunday_after_Pentecost|Sts. Euphemia, Lucy and Geminianus|-|1 +2027-09-17|4|g|Feria|Feria_VI_after_XVII_Sunday_after_Pentecost|Stigmata of St. Francis|-|1 +2027-09-18|3|w|St. Joseph of Cupertino|Saturday_after_XVII_Sunday_after_Pentecost|-|-|1 +2027-09-19|2|g|XVIII Sunday after Pentecost|-|-|St. Januarius & Companions|1 +2027-09-20|4|g|Feria|Feria_II_after_XVIII_Sunday_after_Pentecost|Sts. Eustace & Companions|-|1 +2027-09-21|2|r|St. Matthew|Feria_III_after_XVIII_Sunday_after_Pentecost|-|-|1 +2027-09-22|2|v|Ember Wednesday of September|-|St. Thomas of Villanova|St. Maurice and Companions, Martyrs|1 +2027-09-23|3|r|St. Linus|Feria_V_after_XVIII_Sunday_after_Pentecost|St. Thecla|-|1 +2027-09-24|2|v|Ember Friday of September|-|Our Lady of Ransom|-|1 +2027-09-25|2|v|Ember Saturday of September|-|-|-|1 +2027-09-26|2|g|XIX Sunday after Pentecost|-|-|Sts. Cyprian & Justina|1 +2027-09-27|3|r|Sts. Cosmas & Damian|Feria_II_after_XIX_Sunday_after_Pentecost|-|-|1 +2027-09-28|3|r|St. Wenceslaus|Feria_III_after_XIX_Sunday_after_Pentecost|-|-|1 +2027-09-29|1|w|Dedication of St. Michael the Archangel|Feria_IV_after_XIX_Sunday_after_Pentecost|-|-|1 +2027-09-30|3|w|St. Jerome|Feria_V_after_XIX_Sunday_after_Pentecost|-|-|1 +2027-10-01|4|g|Feria|Feria_VI_after_XIX_Sunday_after_Pentecost|St. Remigius|-|1 +2027-10-02|3|w|Holy Guardian Angels|Saturday_after_XIX_Sunday_after_Pentecost|-|-|1 +2027-10-03|2|g|XX Sunday after Pentecost|-|-|St. Theresa of the Infant Jesus|1 +2027-10-04|3|w|St. Francis of Assisi|Feria_II_after_XX_Sunday_after_Pentecost|-|-|1 +2027-10-05|4|g|Feria|Feria_III_after_XX_Sunday_after_Pentecost|St. Placid & Companions|-|1 +2027-10-06|3|w|St. Bruno|Feria_IV_after_XX_Sunday_after_Pentecost|-|-|1 +2027-10-07|2|w|Our Lady of the Rosary|Feria_V_after_XX_Sunday_after_Pentecost|St. Mark I|-|1 +2027-10-08|3|w|St. Bridget of Sweden|Feria_VI_after_XX_Sunday_after_Pentecost|Ss. Sergio, Baccho, Marcello and Apulejo Martyrs|-|1 +2027-10-09|3|w|St. John Leonardi|Saturday_after_XX_Sunday_after_Pentecost|St. Dionysius and companions|-|1 +2027-10-10|2|g|XXI Sunday after Pentecost|-|-|St. Francis Borgia|1 +2027-10-11|2|w|Maternity of the Blessed Virgin Mary|Feria_II_after_XXI_Sunday_after_Pentecost|-|-|1 +2027-10-12|4|g|Feria|Feria_III_after_XXI_Sunday_after_Pentecost|-|-|1 +2027-10-13|3|w|St. Edward|Feria_IV_after_XXI_Sunday_after_Pentecost|-|-|1 +2027-10-14|3|r|St. Callistus I|Feria_V_after_XXI_Sunday_after_Pentecost|-|-|1 +2027-10-15|3|w|St. Teresa of Avila|Feria_VI_after_XXI_Sunday_after_Pentecost|-|-|1 +2027-10-16|3|w|St. Hedwig|Saturday_after_XXI_Sunday_after_Pentecost|-|-|1 +2027-10-17|2|g|XXII Sunday after Pentecost|-|-|St. Margaret Mary Alacoque|1 +2027-10-18|2|r|St. Luke the Evangelist|Feria_II_after_XXII_Sunday_after_Pentecost|-|-|1 +2027-10-19|3|w|St. Peter of Alcantara|Feria_III_after_XXII_Sunday_after_Pentecost|-|-|1 +2027-10-20|3|w|St. John Cantius|Feria_IV_after_XXII_Sunday_after_Pentecost|-|-|1 +2027-10-21|4|g|Feria|Feria_V_after_XXII_Sunday_after_Pentecost|St. Hilarion;St. Ursula and Companions|-|1 +2027-10-22|4|g|Feria|Feria_VI_after_XXII_Sunday_after_Pentecost|-|-|1 +2027-10-23|3|w|St. Anthony Mary Claret|Saturday_after_XXII_Sunday_after_Pentecost|-|-|1 +2027-10-24|2|g|XXIII Sunday after Pentecost|-|-|St. Raphael the Archangel|1 +2027-10-25|4|g|Feria|Feria_II_after_XXIII_Sunday_after_Pentecost|Sts. Chrysanthus & Daria|-|1 +2027-10-26|4|g|Feria|Feria_III_after_XXIII_Sunday_after_Pentecost|St. Evaristus|-|1 +2027-10-27|4|g|Feria|Feria_IV_after_XXIII_Sunday_after_Pentecost|-|-|1 +2027-10-28|2|r|Sts. Simon & Jude|Feria_V_after_XXIII_Sunday_after_Pentecost|-|-|1 +2027-10-29|4|g|Feria|Feria_VI_after_XXIII_Sunday_after_Pentecost|-|-|1 +2027-10-30|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_XXIII_Sunday_after_Pentecost|-|-|1 +2027-10-31|1|w|Christ the King|IV_Sunday_after_Epiphany|-|-|1 +2027-11-01|1|w|All Saints|Feria_II_after_IV_Sunday_after_Epiphany|-|-|1 +2027-11-02|1|b|Commemoration of All Souls|Feria_III_after_IV_Sunday_after_Epiphany|-|-|3 +2027-11-03|4|g|Feria|Feria_IV_after_IV_Sunday_after_Epiphany|-|-|1 +2027-11-04|3|w|St. Charles Borromeo|Feria_V_after_IV_Sunday_after_Epiphany|Sts. Vitalis and Agricola, Martyrs|-|1 +2027-11-05|4|g|Feria|Feria_VI_after_IV_Sunday_after_Epiphany|-|-|1 +2027-11-06|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_IV_Sunday_after_Epiphany|-|-|1 +2027-11-07|2|g|V Sunday after Epiphany|-|-|-|1 +2027-11-08|4|g|Feria|Feria_II_after_V_Sunday_after_Epiphany|Four Holy Crowned Martyrs|-|1 +2027-11-09|2|w|Dedication of the Archbasilica of Our Holy Savior|Feria_III_after_V_Sunday_after_Epiphany|St. Theodore|-|1 +2027-11-10|3|w|St. Andrew Avellino|Feria_IV_after_V_Sunday_after_Epiphany|Sts. Tryphonis, Respicii, et Nymphae|-|1 +2027-11-11|3|w|St. Martin of Tours|Feria_V_after_V_Sunday_after_Epiphany|St. Menna|-|1 +2027-11-12|3|r|St. Martin I|Feria_VI_after_V_Sunday_after_Epiphany|-|-|1 +2027-11-13|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_V_Sunday_after_Epiphany|St. Didacus|-|1 +2027-11-14|2|g|VI Sunday after Epiphany|-|-|St. Josaphat|1 +2027-11-15|3|w|St. Albert the Great|Feria_II_after_VI_Sunday_after_Epiphany|-|-|1 +2027-11-16|3|w|St. Gertrude the Great|Feria_III_after_VI_Sunday_after_Epiphany|-|-|1 +2027-11-17|3|w|St. Gregory the Wonderworker|Feria_IV_after_VI_Sunday_after_Epiphany|-|-|1 +2027-11-18|3|w|Dedication of the Basilicas of Sts. Peter & Paul|Feria_V_after_VI_Sunday_after_Epiphany|-|-|1 +2027-11-19|3|w|St. Elizabeth of Hungary|Feria_VI_after_VI_Sunday_after_Epiphany|St. Pontian|-|1 +2027-11-20|3|w|St. Felix of Valois|Saturday_after_VI_Sunday_after_Epiphany|-|-|1 +2027-11-21|2|g|XXIV Sunday after Pentecost|-|-|Presentation of the Blessed Virgin Mary|1 +2027-11-22|3|r|St. Cecilia|Feria_II_after_XXIV_Sunday_after_Pentecost|-|-|1 +2027-11-23|3|r|St. Clement I|Feria_III_after_XXIV_Sunday_after_Pentecost|St. Felicity|-|1 +2027-11-24|3|w|St. John of the Cross|Feria_IV_after_XXIV_Sunday_after_Pentecost|St. Chrysogonus|-|1 +2027-11-25|3|r|St. Catherine of Alexandria|Feria_V_after_XXIV_Sunday_after_Pentecost|-|-|1 +2027-11-26|3|w|St. Sylvester|Feria_VI_after_XXIV_Sunday_after_Pentecost|St. Peter of Alexandria|-|1 +2027-11-27|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_XXIV_Sunday_after_Pentecost|-|-|1 +2027-11-28|1|v|I Sunday of Advent|-|-|-|1 +2027-11-29|3|v|Feria II after I Sunday of Advent|-|St. Saturninus|-|1 +2027-11-30|2|r|St. Andrew|Feria_III_after_I_Sunday_of_Advent|-|-|1 +2027-12-01|3|v|Feria IV after I Sunday of Advent|-|-|-|1 +2027-12-02|3|r|St. Vivian|Feria_V_after_I_Sunday_of_Advent|Feria V after I Sunday of Advent|-|1 +2027-12-03|3|w|St. Francis Xavier|Feria_VI_after_I_Sunday_of_Advent|Feria VI after I Sunday of Advent|-|1 +2027-12-04|3|w|St. Peter Chrysologus|Sabbato_after_I_Sunday_of_Advent|Sabbato after I Sunday of Advent|-|1 +2027-12-05|1|v|II Sunday of Advent|-|-|St. Sabbas|1 +2027-12-06|3|w|St. Nicholas|Feria_II_after_II_Sunday_of_Advent|Feria II after II Sunday of Advent|-|1 +2027-12-07|3|w|St. Ambrose|Feria_III_after_II_Sunday_of_Advent|Feria III after II Sunday of Advent|-|1 +2027-12-08|1|w|Immaculate Conception of the Blessed Virgin Mary|Feria_IV_after_II_Sunday_of_Advent|-|-|1 +2027-12-09|3|v|Feria V after II Sunday of Advent|-|-|-|1 +2027-12-10|3|v|Feria VI after II Sunday of Advent|-|St. Melchiades|-|1 +2027-12-11|3|w|St. Damasus I|Sabbato_after_II_Sunday_of_Advent|Sabbato after II Sunday of Advent|-|1 +2027-12-12|1|pv|III Sunday of Advent|-|-|-|1 +2027-12-13|3|r|St. Lucy|Feria_II_after_III_Sunday_of_Advent|Feria II after III Sunday of Advent|-|1 +2027-12-14|3|pv|Feria III after III Sunday of Advent|-|-|-|1 +2027-12-15|2|v|Ember Wednesday of Advent|-|-|-|1 +2027-12-16|3|r|St. Eusebius|Feria_V_after_III_Sunday_of_Advent|Feria V after III Sunday of Advent|-|1 +2027-12-17|2|v|Ember Friday of Advent|-|-|-|1 +2027-12-18|2|v|Ember Saturday of Advent|-|-|-|1 +2027-12-19|1|v|IV Sunday of Advent|-|-|-|1 +2027-12-20|2|v|Feria II after IV Sunday of Advent|-|-|-|1 +2027-12-21|2|r|St. Thomas|Feria_III_after_IV_Sunday_of_Advent|Feria III after IV Sunday of Advent|-|1 +2027-12-22|2|v|Feria IV after IV Sunday of Advent|-|-|-|1 +2027-12-23|2|v|Feria V after IV Sunday of Advent|-|-|-|1 +2027-12-24|1|v|Vigil of Christmas|-|-|-|1 +2027-12-25|1|w|The Nativity of Our Lord|-|-|-|3 +2027-12-26|2|w|Sunday in the Octave of Christmas|-|St. Stephen|For Octave of the Nativity|1 +2027-12-27|2|w|St. John the Evangelist|-|For Octave of the Nativity|-|1 +2027-12-28|2|r|Holy Innocents|-|For Octave of the Nativity|-|1 +2027-12-29|2|w|Feria in the Octave of Christmas|-|St. Thomas Becket|-|1 +2027-12-30|2|w|Feria in the Octave of Christmas|-|-|-|1 +2027-12-31|2|w|Feria in the Octave of Christmas|-|St. Silvester|-|1 diff --git a/test/test_colitur.ml b/test/test_colitur.ml index 4e32e04..b1c8a34 100644 --- a/test/test_colitur.ml +++ b/test/test_colitur.ml @@ -4,4 +4,4 @@ let () = [ Test_date.suite; Test_computus.suite; Test_colour.suite; Test_slug.suite; Test_names.suite; Test_overlay.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_differential.suite ] + Test_differential.suite; Test_oracle.suite ] diff --git a/test/test_oracle.ml b/test/test_oracle.ml new file mode 100644 index 0000000..2cc9972 --- /dev/null +++ b/test/test_oracle.ml @@ -0,0 +1,607 @@ +(* Task 16: oracle harness vs missalemeum (sibling project's snapshot of + missalemeum.com/Divinum Officium data), EF only, 2026-2027 -- validation + layer 4 of the design spec's five (colitur CLAUDE.md "Validation" section; + layer 3, the lectio differential, is test_differential.ml, already green). + + *** WHY THIS LAYER EXISTS, AND WHAT IT CAN DO THAT THE LECTIO DIFFERENTIAL + CANNOT (test_differential.ml's own header comment, limit 1) *** + + The lectio differential compares colitur against data colitur was itself + BOOTSTRAPPED from (data/ef/sanctoral.sexp comes from lectio's tridentine- + calendar.ini) -- it cannot catch an error inherited from that bootstrap, + and it explicitly does not compare commemorations at all (lectio's + trailing tokens are losing candidates, not an RG 111 admitted set, per + that file's own limit 1). missalemeum is INDEPENDENT of colitur's + bootstrap chain, and its JSON carries a real admitted-commemorations + array (its own RG 111-shaped selection, not lectio's rejects) -- so this + file compares THREE axes the lectio differential cannot touch at all: + rank, colour (as SET membership, see below), and commemoration presence/ + count. Slug IDENTITY is deliberately NOT compared (the brief: needs a + title->slug mapping, which is the data audit's business -- see the task + report -- not this automated comparator's). + + *** THE FIXTURE'S OWN SHAPE (fixtures/missalemeum-ef-2026-2027.txt, + fixtures/missalemeum-ef-2026-2027.provenance, tools/ + extract_missalemeum_oracle.py) *** + + info.id (e.g. "sancti:01-02:1:w") encodes the PROPERS REUSED that day, + not the day's own rank or colour -- 137 of 730 days (19%) disagree + between the id-embedded rank and info.rank itself (task brief's own + premise was wrong here; the brief's extraction note has been corrected). + This file, like the extraction script, reads ONLY info.rank and + info.colors, never parses anything out of info.id. + + info.colors is an ARRAY -- 14 of 730 days carry two colours (rose+violet + on Gaudete/Laetare per RG 131's indult, red+violet on Palm Sunday, black+ + violet on Good Friday, violet+white on Holy Saturday -- one colour per + liturgical ACTION within that one civil day, which colitur's one-colour- + per-day model cannot represent, register §3b's own RG 126 note). So the + colour axis below is MEMBERSHIP (colitur's single colour must be one of + the oracle's set), never equality. + + Four days carry more than one Mass in the JSON array (Christmas, All + Souls) -- the extraction script takes entry[0] throughout, VERIFIED + (not assumed) identical to every other Mass of the same day on every + field this file reads (see that script's own header and the task + report). + + *** THE ALLOW-LIST (data/ef/expected-divergences-missalemeum.sexp) *** + + A SEPARATE file from data/ef/expected-divergences.sexp (the lectio + allow-list): the two oracles disagree with colitur in different places + and for different reasons, and this file's own convention differs in one + deliberate way -- [verdict] is not always "colitur". Some entries are + genuine DATA GAPS this task found and could not fix here (data/ef/ + sanctoral.sexp is bootstrapped from lectio, which is itself missing the + entries; RG 110's inseparable-Peter/Paul commemoration is unimplemented + code, a real feature this task did not build) -- honestly verdicted + [missalemeum] (colitur is short a feature or a row, not right), never + silently absorbed as if colitur were correct. One entry (M13) is + [verdict open]: adjudicated as unresolved, not resolved either way -- + the brief's own explicit permission ("say so as an open item") used for + real, not defaulted past. See the task report for every entry's full + reasoning and primary-source citation. *) + +module Cal = Colitur_kernel.Calendar +module Layer = Colitur_kernel.Layer +module Overlay = Colitur_kernel.Overlay +module LD = Colitur_kernel.Liturgical_day +module Slug = Colitur_kernel.Slug +module Date = Colitur_kernel.Date +module Cel = Colitur_kernel.Celebration +module Colour = Colitur_kernel.Colour +module V = Rite_ef.Vocab_ef + +(* Same relative paths test_differential.ml uses: dune test runs from + _build/default/test/. *) +let sanctoral_path = "../data/ef/sanctoral.sexp" +let adjustments_path = "../data/ef/adjustments.sexp" +let fixture_path = "fixtures/missalemeum-ef-2026-2027.txt" +let allow_list_path = "../data/ef/expected-divergences-missalemeum.sexp" + +(* fixtures/missalemeum-ef-2026-2027.provenance carries the same digest and + the exact regeneration command. Asserted (not merely documented) for the + same reason test_differential.ml's own [fixture_sha256] is: a hand-edit + or partial re-extraction would otherwise silently turn the oracle into + an unlabelled snapshot of whatever someone last ran. *) +let fixture_sha256 = "718eff1a03fa09c3927ef18d19fe7921c2d4d7611890c22566058b81fd7cc5ea" + +(* Identical technique to test_differential.ml's own [sha256_of_file] + (that file's own comment explains why: shelling out to [sha256sum] + rather than adding a crypto library dependency Task 15/16's frozen deps + do not include). Duplicated, not shared, for the same reason + [real_layer] below is -- neither file exposes an .mli the other could + depend on, and this is three lines. *) +let sha256_of_file path = + let tmp = Filename.temp_file "colitur_oracle_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 + +(* ---------------------------------------------------------------------- *) +(* The oracle side: one line per day, as tools/extract_missalemeum_oracle *) +(* .py's own header documents. *) +(* ---------------------------------------------------------------------- *) + +type oracle_row = { + o_date : string; + o_rank : int; + o_colours : char list; + o_title : string; + o_commemorations : string list; + o_displaced : string list; +} + +let explode s = List.init (String.length s) (String.get s) + +let split_list_field f = if f = "-" then [] else String.split_on_char ';' f + +let oracle_row_of_line line = + match String.split_on_char '|' line with + | [ date; rank; colours; title; _tempora; commemorations; displaced; _n_masses ] -> + { o_date = date; + o_rank = int_of_string rank; + o_colours = explode colours; + o_title = title; + o_commemorations = split_list_field commemorations; + o_displaced = split_list_field displaced } + | _ -> Alcotest.failf "malformed fixture line (expected 8 '|'-separated fields): %S" line + +let read_lines path = + let ic = open_in path in + let rec loop acc = + match input_line ic with + | line -> loop (line :: acc) + | exception End_of_file -> + close_in ic; + List.rev acc + in + loop [] + +let oracle_rows () = List.map oracle_row_of_line (read_lines fixture_path) + +(* ---------------------------------------------------------------------- *) +(* The colitur side: the SAME pipeline bin/main.ml's `colitur day` and *) +(* test_differential.ml's own [colitur_rows_2005_2050] use -- *) +(* Colitur_kernel.Calendar over the real committed data. Restricted to *) +(* 2026-2027 (indexing 2025 too, for the same reason test_differential.ml *) +(* indexes [y-1]: Calendar.year resolves one Advent-anchored liturgical *) +(* year, which straddles two civil years). *) +(* ---------------------------------------------------------------------- *) + +type colitur_row = { c_date : string; c_rank : int; c_colour : char; c_commemorations : string list } + +let rank_to_int = function V.Class1 -> 1 | V.Class2 -> 2 | V.Class3 -> 3 | V.Class4 -> 4 + +let colour_to_char = function + | Colour.White -> 'w' + | Colour.Red -> 'r' + | Colour.Green -> 'g' + | Colour.Violet -> 'v' + | Colour.Rose -> 'p' + | Colour.Black -> 'b' + +let colitur_rows_2026_2027 () = + let layer = real_layer () in + let by_rata : (int, (V.season, V.rank) LD.t) Hashtbl.t = Hashtbl.create 800 in + for y = 2025 to 2027 do + let days = Cal.year Rite_ef.context 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 rows = ref [] in + let d = ref (mk 2026 1 1) in + let stop = mk 2027 12 31 in + while Date.compare !d stop <= 0 do + (match Hashtbl.find_opt by_rata (Date.to_rata !d) with + | Some day -> + let cel = day.LD.observed in + let commemoration_slugs = + List.map (fun (c, _) -> Slug.to_string c.Cel.slug) day.LD.commemorations + in + rows := + { c_date = Date.to_iso8601 day.LD.date; + c_rank = rank_to_int cel.Cel.rank; + c_colour = colour_to_char cel.Cel.colour; + c_commemorations = commemoration_slugs + } + :: !rows + | None -> Alcotest.failf "internal error: no resolved day for %s" (Date.to_iso8601 !d)); + d := Date.add_days !d 1 + done; + List.rev !rows + +(* ---------------------------------------------------------------------- *) +(* Field-diff computation: the four axes the oracle actually supports *) +(* (identity-by-slug is deliberately out of scope, see this file's own *) +(* header). *) +(* ---------------------------------------------------------------------- *) + +type field = Rank | Colour_f | Comm_presence | Comm_count + +let field_name = function + | Rank -> "rank" + | Colour_f -> "colour" + | Comm_presence -> "commemoration-presence" + | Comm_count -> "commemoration-count" + +let diff_fields (c : colitur_row) (o : oracle_row) = + let c_has = c.c_commemorations <> [] and o_has = o.o_commemorations <> [] in + List.filter_map + (fun x -> x) + [ (if c.c_rank = o.o_rank then None else Some Rank); + (if List.mem c.c_colour o.o_colours then None else Some Colour_f); + (if c_has = o_has then None else Some Comm_presence); + (* Count is only meaningful once presence already agrees (both non-empty): + a presence mismatch already flags the row via [Comm_presence] above, + and comparing lengths across a 0-vs-N split would just restate that + same disagreement under a second name. *) + (if c_has && o_has && List.length c.c_commemorations <> List.length o.o_commemorations then + Some Comm_count + else None) + ] + +(* ---------------------------------------------------------------------- *) +(* The cited allow-list (data/ef/expected-divergences-missalemeum.sexp). *) +(* Each predicate is gated on an EXACT, literal date set (never a date *) +(* range or a slug pattern -- with at most 4 dates per id, a literal list *) +(* costs nothing and cannot silently widen to absorb an unrelated future *) +(* mismatch the way a range could), AND an exact/subset diff shape, the *) +(* same double-gate test_differential.ml's own [layer_c_reason] uses. *) +(* ---------------------------------------------------------------------- *) + +let subset xs ys = List.for_all (fun x -> List.mem x ys) xs + +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 + +(* M1 -- RG 33 (corrected, precedence_ef.ml's own [is_omissible_vigil]): + missalemeum does not implement RG 33's mandatory omission of a II/III- + class vigil impeded by a Sunday -- 28 June 2026 (Vigil of Sts Peter & + Paul, II class) still shows a commemoration of the vigil on the V Sunday + after Pentecost; 9 August 2026 (Vigil of St Lawrence, III class) shows + the vigil as the day's FULL OBSERVED OFFICE, not merely a commemoration, + displacing the XI Sunday after Pentecost entirely. Both wrong per RG 33's + own "in dominica quavis" (ANY Sunday, unqualified) -- verdict colitur. *) +let m1_dates = [ "2026-06-28"; "2026-08-09" ] + +(* M2 -- RG 91 entry 27 ("Officium sanctae Mariae in sabbato"): every + otherwise-unoccupied IV-class Saturday should carry the votive Office of + the BVM (white; missalemeum's own title cycles "I".."V Mass of the + B. V. M. - Salve, Sancta Parens"), a genuinely DISTINCT office from an + ordinary green/violet feria. temporal_ef.ml's [band] already carries an + entry-27 comment acknowledging this row of RG 91 exists, but nothing in + [Temporal_ef.temporal]'s actual CONSTRUCTION builds this office -- an + unimpeded Time-after-Epiphany/-Pentecost Saturday still gets the bare + ferial slug and [season_colour]'s green. A genuine, primary-attested + FEATURE GAP (not a citation dispute) -- verdict missalemeum: colitur is + short a whole office here, not merely differently-opinioned. Registered + as an open item (register §6) rather than built in this task: it needs + its own proper texts/citations, the same scope line "Major Litanies" + (M5 below) already sits on. Matched on the oracle's own title substring, + not a hardcoded date list -- the title IS the distinguishing evidence, + and every Paschaltide occurrence (where colitur's season colour is + already white, RG 119) never reaches this predicate at all, since its + diffs are already empty before [layer_m_reason] is ever called. *) +let bvm_saturday_title = "Salve, Sancta Parens" + +(* M3 -- RG 87 (Minor Litanies/Rogations): the SAME gap the lectio + differential's own C8 already names (data/ef/expected-divergences.sexp) + -- missalemeum, like lectio, computes no Rogation day at all and shows + the plain paschaltide-week feria instead. Only ONE date in this window + shows it (3 May 2027, Rogation Monday) because every other Rogation day + here is won by a saint anyway (both sides then agree on the SAINT's own + identity, with only the underlying temporal identity differing, which + this comparator's rank/colour/commemoration axes do not expose). Verdict + colitur, same citation as lectio's own C8. *) +let m3_dates = [ "2027-05-03" ] + +(* M4 -- a genuine DATA GAP, primary-source-confirmed: the 1962 calendarium + itself lists, under 28 January, "S. Petri Nolasci Conf., III classis. / + Com. S. Agnetis Virg. et Mart., secundo" -- a second commemoration of + St Agnes (distinct from her main 21 January feast) that data/ef/ + sanctoral.sexp does not carry at all. Traced upstream: lectio's own + tridentine-calendar.ini has no 01-28 entry beyond [peter-nolasco] + either, so colitur inherited the gap from its bootstrap source, not + from the bootstrap tool mis-reading a present entry. Cannot be fixed in + this task (data/ef/sanctoral.sexp is bootstrapped from lectio, per + CLAUDE.md's binding decision 3; lectio itself needs the entry first, + and this task does not touch ~/git/projects/lectio) -- verdict + missalemeum, tracked as a register §6 open item. *) +let m4_dates = [ "2026-01-28"; "2027-01-28" ] + +(* M5 -- register §6's OWN already-open item, independently confirmed by + the oracle: "Major Litanies (25 April, RG 80) are not yet computed" -- + missalemeum's commemoration "Pro rogationibus" ("for the Rogations") on + St Mark's day (25 April, the Major Litanies' fixed date) is exactly the + missing office. Not a new finding; recorded here so the automated + comparator does not report it as an unexplained mismatch, and cross- + referenced from the register so a reader sees both. Verdict missalemeum + (colitur is missing a real, cited office; register §6 already tracks + it). Only ONE date below, not two: 25 April 2026 is a Saturday (Mark + wins outright, colitur's commemoration list is empty where the oracle's + is not -- a visible presence gap); 25 April 2027 is a Sunday, where the + Sunday wins on BOTH sides and each side's own single slot goes to a + DIFFERENT candidate (colitur: Mark himself, admitted under RG 111(b)'s + "de festo II classis"; missalemeum: the Major Litanies) -- both + non-empty, same count, so this comparator's deliberately-not-slug- + identity axes cannot see that year's instance at all (see the task + report). *) +let m5_dates = [ "2026-04-25" ] + +(* M6 -- the reverse of M4/M7/M9: the primary calendarium's own row for 14 + August reads, in full, "Vigilia, II classis." -- nothing else. No + commemoration is listed for that date anywhere in the source this + project treats as authoritative (CLAUDE.md binding decision 1). data/ef/ + sanctoral.sexp agrees (a single entry, [vigil-of-the-assumption], 14 + Aug). missalemeum's own "St. Eusebius" commemoration for that date has + no support in the 1962 universal calendar found here (a DIFFERENT St + Eusebius, bishop and martyr, is genuinely commemorated 16 December, + matching lectio's own [eusebius] entry at that date -- not this one). + Verdict colitur: this is the one direction among M4/M6/M7/M9 where the + oracle itself appears to be carrying data outside the 1962 universal + calendar (a pre-1955 survival or a different edition), not colitur + missing something real. *) +let m6_dates = [ "2026-08-14"; "2027-08-14" ] + +(* M7 -- a genuine DATA GAP, primary-source-confirmed, the same shape as + M4: the calendarium's own 26 October row reads "Com. S. Evaristi Papæ + et Mart." (Commemoration of St Evaristus, Pope and Martyr) -- absent + from data/ef/sanctoral.sexp, and absent from lectio's own tridentine- + calendar.ini for 10-26 (no entry at all for that date), so this is + another bootstrap-source gap, not fixable without touching lectio. + Verdict missalemeum, register §6 open item. *) +let m7_dates = [ "2026-10-26"; "2027-10-26" ] + +(* M8 -- RG 109(a) ("of a Sunday" is always privileged) + RG 111(a) ("on + I-class days... none save one privileged"): when a FIXED I-class feast + (All Saints, 1 Nov; the Assumption, 15 Aug) lands on an ordinary Sunday, + the impeded Sunday IS the one privileged commemoration RG 111(a) admits + -- already an established, independently-tested rule in this codebase + (test_precedence_ef.ml's "RG95/RG109(a): an impeded I-class SUNDAY does + NOT transfer -- it is Commemorated and Privileged"). missalemeum shows + no commemoration at all on either occurrence in this window. Verdict + colitur. *) +let m8_dates = [ "2026-11-01"; "2027-08-15" ] + +(* M9 -- a genuine DATA GAP, the same shape as M4/M7: the calendarium's own + 9 November row reads, alongside the Dedication of the Archbasilica (II + class), "Com. S. Theodori Mart." (Commemoration of St Theodore, + Martyr) -- absent from data/ef/sanctoral.sexp and from lectio's own + 11-09 entry (dedication-of-the-archbasilica-of-our-holy-savior alone, + no second entry for that date). Verdict missalemeum, register §6 open + item. *) +let m9_dates = [ "2026-11-09"; "2027-11-09" ] + +(* M14 -- a genuine DATA GAP, the same shape as M4/M7/M9: the calendarium's + own 14 May row reads "Com. S. Bonifatii Mart." (a commemoration-only St + Boniface, Martyr -- DIFFERENT from the II-class St Boniface, Bishop and + Martyr, of 5 June, which data/ef/sanctoral.sexp and lectio both already + carry correctly) -- absent from data/ef/sanctoral.sexp and from lectio's + own tridentine-calendar.ini for 05-14 (no entry at all for that date). + Verdict missalemeum, register §6 open item. *) +let m14_dates = [ "2027-05-14" ] + +(* M10 -- RG 109(e), unqualified text ("de feriis Adventus, Quadragesimae + et Passionis" -- OF THE FERIAS OF ADVENT, not "of the Advent ferias 17- + 23 December only"; that narrower window is RG 91 entry 18's own + OCCURRENCE-table dignity, a different axis from RG 109's commemoration- + privilege list, register §4's own citations keep the two separate). + colitur commemorates the losing early-Advent feria (the Monday after + Advent I, 30 Nov; the Tuesday/Wednesday after Advent II, 8 Dec) when a + saint wins those days -- missalemeum shows nothing on these specific + four rows, even though it DOES show equivalent later-Advent-feria + commemorations elsewhere in this same window (2-21 December, matching + colitur exactly on every one of those -- see the task report), which is + why this reads as a missalemeum-side inconsistency on these four + particular rows rather than a textually-narrower rule this task missed. + Verdict colitur. *) +let m10_dates = [ "2026-11-30"; "2027-11-30"; "2026-12-08"; "2027-12-08" ] + +(* M11 -- missalemeum's own "For Octave of the Nativity" commemoration/ + displaced entry on 26, 27(2027)/28 December carries info.rank 4 in the + raw JSON (checked directly, not inferred) -- a generic, always-present, + lowest-dignity placeholder its OWN data model seems to attach to every + day within the Nativity Octave, distinct from RG 91 entry 17's real + "days within the Octave" office (which colitur already models correctly + -- but only for 29-31 December, since 26-28 are the NAMED feasts + Stephen/John/the Innocents themselves, sanctoral not temporal, + temporal_ef.ml's own comment on [named]). No RG paragraph found here + supports a SEPARATE rank-4 commemoration alongside Stephen/John/the + Innocents' own (much higher) offices. Verdict colitur: read as + missalemeum's own bookkeeping artifact, not a liturgical fact -- flagged + as an open item rather than confidently dismissed, since the primary- + source search for this specific point was not exhaustive (see the task + report). *) +let m11_dates = [ "2026-12-26"; "2026-12-28"; "2027-12-27"; "2027-12-28" ] + +(* M12 -- RG 110, primary text: "In Officio et Missa S. Petri semper fit + commemoratio S. Pauli, et vicissim" -- in the Office and Mass of EITHER + Peter or Paul, a commemoration of the OTHER is ALWAYS made (the + "inseparable commemoration"), uncapped by RG 111's ordinary admission + count ("in numero orationum computando, pro unica habeantur" -- counted + as one for counting purposes, i.e. it rides alongside whatever RG 111 + already admits). Unimplemented in this codebase -- confirmed by the one + row in this window where it is visible: 22 February 2027 (Chair of + St Peter) shows only the privileged Lent feria commemorated in colitur, + while missalemeum shows that AND "St. Paul". A genuine, primary-cited + feature gap -- verdict missalemeum, register §6 open item. Real but + NARROW: every other Peter/Paul office in this window (29 June, both + years; 1 August M4-adjacent dates were checked and found clean) either + had no room for the extra commemoration to become visible against this + comparator's axes, or fell on a day this predicate does not otherwise + touch -- see the task report for the specific check. *) +let m12_dates = [ "2027-02-22" ] + +(* M13 -- OPEN, NOT adjudicated (the brief's own explicit permission, + "say so as an open item rather than absorbing it"). 19 March 2027: St + Joseph (I class, 19 March) falls on the Friday of Passion Week. The + 1962 calendarium's own March table carries a standing note, "Feria VI + post dominicam I Passionis: Commemoratio septem Dolorum B. Mariae + Virg." (a fixed commemoration of Our Lady's Seven Sorrows for that + Friday, EVERY year, confirmed real) -- and missalemeum shows Joseph + entirely DISPLACED that year, with the Friday's own office (III class, + violet) observed and the Seven Sorrows commemorated instead. RG 91's + plain table (entry 11-13, I-class feast, vs entry 22, an ordinary III- + class Passiontide feria) gives Joseph the day outright, with no general + RG 96 collision requiring a transfer -- so either (a) colitur's plain + reading is right and missalemeum is wrong, (b) a MORE SPECIFIC rubric + (most plausibly attached to St Joseph's own Proprium Sanctorum entry, + the same shape as the Annunciation's own Attamen clause, register §4) + overrides the general table for this exact collision and this task did + not find its text, or (c) the Seven Sorrows commemoration itself + somehow outranks an ordinary I-class feast on this one Friday, which + nothing found here supports either. Extensive but non-exhaustive + primary-source search (see the task report) did not settle it. + Separately, but confirmed regardless of the adjudication above: colitur + does not implement the Seven-Sorrows-of-Passion-Friday commemoration at + all, in any year -- a real, primary-attested gap, register §6 open + item. *) +let m13_dates = [ "2027-03-19" ] + +let layer_m_reason (c : colitur_row) (o : oracle_row) diffs = + if diffs = [] then None + else if List.mem c.c_date m1_dates && subset diffs [ Rank; Colour_f; Comm_presence ] then Some "M1" + else if contains_substring o.o_title ~needle:bvm_saturday_title && diffs = [ Colour_f ] then Some "M2" + else if List.mem c.c_date m3_dates && diffs = [ Colour_f ] then Some "M3" + else if List.mem c.c_date m4_dates && diffs = [ Comm_presence ] then Some "M4" + else if List.mem c.c_date m5_dates && diffs = [ Comm_presence ] then Some "M5" + else if List.mem c.c_date m6_dates && diffs = [ Comm_presence ] then Some "M6" + else if List.mem c.c_date m7_dates && diffs = [ Comm_presence ] then Some "M7" + else if List.mem c.c_date m8_dates && diffs = [ Comm_presence ] then Some "M8" + else if List.mem c.c_date m9_dates && diffs = [ Comm_presence ] then Some "M9" + else if List.mem c.c_date m14_dates && diffs = [ Comm_presence ] then Some "M14" + else if List.mem c.c_date m10_dates && diffs = [ Comm_presence ] then Some "M10" + else if List.mem c.c_date m11_dates && diffs = [ Comm_presence ] then Some "M11" + else if List.mem c.c_date m12_dates && diffs = [ Comm_count ] then Some "M12" + else if List.mem c.c_date m13_dates && subset diffs [ Rank; Colour_f ] then Some "M13" + else None + +(* ---------------------------------------------------------------------- *) +(* data/ef/expected-divergences-missalemeum.sexp loading -- same shape as *) +(* test_differential.ml's own [allow_entry]/[load_allow_list]. *) +(* ---------------------------------------------------------------------- *) + +open Sexplib0.Sexp_conv + +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 + +(* ---------------------------------------------------------------------- *) +(* The comparison itself. *) +(* ---------------------------------------------------------------------- *) + +type outcome = Matched | Explained of string | Unexplained of field list + +let compare_streams () = + let oracle = oracle_rows () in + let colitur = colitur_rows_2026_2027 () in + (oracle, colitur) + +let classify oracle colitur = + List.map2 + (fun (o : oracle_row) (c : colitur_row) -> + if not (String.equal o.o_date c.c_date) then + Alcotest.failf "streams misaligned: oracle %s vs colitur %s" o.o_date c.c_date; + let diffs = diff_fields c o in + if diffs = [] then (c, o, Matched) + else + match layer_m_reason c o diffs with + | Some id -> (c, o, Explained id) + | None -> (c, o, Unexplained diffs)) + oracle colitur + +let describe_unexplained (c : colitur_row) (o : oracle_row) diffs = + Printf.sprintf "%s: %s differ -- colitur=(rank=%d colour=%c comms=[%s]) oracle=(rank=%d colours=[%s] \ + title=%S comms=[%s] displaced=[%s])" + c.c_date + (String.concat "," (List.map field_name diffs)) + c.c_rank c.c_colour + (String.concat ";" c.c_commemorations) + o.o_rank + (String.concat "" (List.map (String.make 1) o.o_colours)) + o.o_title + (String.concat ";" o.o_commemorations) + (String.concat ";" o.o_displaced) + +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 oracle, colitur = compare_streams () in + Alcotest.(check int) "both streams have 730 rows (2026 + 2027, both non-leap)" 730 (List.length oracle); + Alcotest.(check int) "colitur recomputed the same number of rows" (List.length oracle) (List.length colitur); + let mismatched = + List.filter_map + (fun (o, c) -> if String.equal o.o_date c.c_date then None else Some (o.o_date, c.c_date)) + (List.combine oracle colitur) + in + Alcotest.(check (list (pair string string))) "no misaligned dates" [] mismatched + +(* The core assertion: every one of the 42 raw differences across all four + axes (rank, colour-membership, commemoration-presence, commemoration- + count) is named in the cited allow-list. Nothing else passes silently. *) +let test_no_unexplained_differences () = + let oracle, colitur = compare_streams () in + let classified = classify oracle colitur in + let unexplained = + List.filter_map + (fun (c, o, outcome) -> + match outcome with Unexplained diffs -> Some (describe_unexplained c o diffs) | _ -> None) + classified + in + Alcotest.(check (list string)) "no differences outside the cited allow-list" [] unexplained + +(* Teeth, not just green: EVERY allow-list id's actual row count over this + fixture must equal what data/ef/expected-divergences-missalemeum.sexp + declares, in BOTH directions -- the same double-check test_differential + .ml's own "Layer C counts match citations" test makes for the lectio + allow-list. *) +let test_layer_m_counts_match_citations () = + let oracle, colitur = compare_streams () in + let classified = classify oracle colitur in + let actual_counts = Hashtbl.create 16 in + List.iter + (fun (_, _, outcome) -> + match outcome with + | Explained id -> + Hashtbl.replace actual_counts id (1 + Option.value ~default:0 (Hashtbl.find_opt actual_counts id)) + | _ -> ()) + classified; + let declared = load_allow_list () in + let expected = List.sort compare (List.map (fun e -> (e.id, e.expected_rows)) declared) in + let actual = List.sort compare (Hashtbl.fold (fun id n acc -> (id, n) :: acc) actual_counts []) in + Alcotest.(check (list (pair string int))) + "every allow-list id's actual row count matches its citation's expected_rows, and no id is unused or \ + undeclared" + expected actual + +let suite = + ( "oracle (missalemeum, EF, 2026-2027)", + [ Alcotest.test_case "fixture SHA-256 matches its provenance note" `Quick test_fixture_checksum; + Alcotest.test_case "streams are 730 rows each, dates aligned 1:1" `Quick test_dates_align; + Alcotest.test_case "every difference is named in the cited allow-list -- none unexplained" `Quick + test_no_unexplained_differences; + Alcotest.test_case "allow-list counts match data/ef/expected-divergences-missalemeum.sexp exactly" + `Quick test_layer_m_counts_match_citations + ] ) |
