summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-08-17 16:00:23 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-08-17 16:00:23 +0200
commitf03567a04b68ab19b5f16f0b6d56d9c08b14c818 (patch)
treeb6ea189657c866c1d3ba435398c4d19395f0a143
parentc06ebb7344b7f267c325b832632f7cd4e81939e7 (diff)
downloadcolitur-f03567a04b68ab19b5f16f0b6d56d9c08b14c818.tar.gz
colitur-f03567a04b68ab19b5f16f0b6d56d9c08b14c818.zip
test(oracle): a second oracle year, 2038, closing step 4's blind spot
Register section 6.7 recorded that step 4 of the reading chain -- the Common route -- had no external witness of any kind, and proved it by mutation: corrupting a Common citation left both the 16801-day differential and the 730-day oracle green. This closes that. 2038 is the only year in 2005-2050 in which two of the five Common-routed saints are the observed office (Perpetua and Felicitas on 6 March, Frances of Rome on 9 March). 365 days were captured live, one request per day, zero failures. A separate fixture, not more rows on the existing one. sources.md already records that the live endpoint has drifted from lectio's archived 2026-2027 snapshot; merging two versions of one source behind a single set of expectations would make any future disagreement unattributable -- calendar or drift, no way to tell. Nothing in the 2038 comparison is checked against the older fixture, and its provenance file says so, along with the fact that a live capture is not reproducible byte-for-byte on demand the way a snapshot-derived one is. 338 of 365 days match. 27 differ, every one of them in a named, already-adjudicated class, none unexplained: 13 the BVM Saturday votive Mass (M26 shape 1), 7 colour (M21), 2 Judith (M28), 2 Christ the King's week (M26 shape 2b), 1 Christmas multi-Mass (M27), 1 Perpetua's Common, 1 new. Each was decided in a different year, so 2038 re-confirms them independently -- the point of a second window is not new rulings but evidence the old ones are not artefacts of their own year. Two findings came out of it. Perpetua and Felicitas: missalemeum serves the Common of Virgins and calls them "Virgins and Martyrs" in its own oration, where the Missal directs "Missa Me exspectaverunt, de Communi non Virginum I loco" (scan1:27634-27635). Both Commons share the Introit Ps 118:95-96, which is exactly why the calendarium qualifies its direction, and both women were mothers. Verdict colitur; the mechanism is located on missalemeum's side, not merely asserted. Passion Tuesday: the Missal prints "Dan. 14, 27 et 28-42" (scan1:11106) and colitur reproduces that two-part form where missalemeum collapses it to 27-42. Same verses; the convention is deliberate, appearing also in the Seven Sorrows and the Common of Non-Virgins. Verdict colitur, cosmetic. Citations are notation-normalised before comparing, as layer 3 already does: Ecclus/Sir, Joann/John, Luc/Luke, Matth/Matt. Each pair was added because a real row needed it, and no target contains its own source as a substring, so the set is idempotent. Not compared, stated rather than left to be found: commemorations and observed-identity. That machinery is built around a date-literal 28-entry allow-list specific to 2026-2027, and re-deriving it for a second year is its own task. 2038 compares rank, colour, Epistle, Gospel. The extractor's day count was hardcoded to 730, which silently forbade any other window. It is now a parameter defaulting to 730, so the existing documented command keeps its guard and a partial fetch still fails loudly instead of producing a short fixture that passes a comparison it never ran. Teeth, by re-running section 6.7's own experiment: corrupting the Common of Non-Virgins II now reddens four tests, two of them external-oracle, where the same mutation previously reddened neither oracle layer. Residual: isidore-of-seville is still unwitnessed and needs 2035 or 2046; gregory-the-great and patrick are never the observed office in any year 2005-2050, so no fixture in that range can reach them. Register section 6.8 and 6.9.
-rw-r--r--CLAUDE.md21
-rw-r--r--test/dune3
-rw-r--r--test/fixtures/missalemeum-ef-2038.provenance80
-rw-r--r--test/fixtures/missalemeum-ef-2038.txt365
-rw-r--r--test/test_colitur.ml2
-rw-r--r--test/test_oracle.ml224
-rw-r--r--tools/extract_missalemeum_oracle.py17
7 files changed, 697 insertions, 15 deletions
diff --git a/CLAUDE.md b/CLAUDE.md
index 9f8352c..f49f2d8 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -169,8 +169,21 @@ against missalemeum; layer 5 pins ~30 dates.
`band`'s own `Commemoration_only` guard (below) also turns it red, on the same
date this whole gap was originally found through — both reverted after
confirming.
-- **Step 4 of the reading chain (the Common route) has NO oracle witness at
- all** (register §6.7, `ef-lectionary` fix round 2). Only five saints route
+- **Step 4 of the reading chain (the Common route) — CLOSED** (register §6.9,
+ `ef-oracle-2038`, 2026-08-17). Layer 4 gained a SECOND fixture, 2038
+ (365 days, live-captured, its own provenance/SHA/suite, deliberately kept
+ apart from the 2026–2027 one because the live endpoint has drifted from
+ lectio's archived snapshot). 2038 is the only year in 2005–2050 covering
+ two Common-routed saints as the observed office. 338/365 match; 27 differ;
+ all 27 in already-adjudicated classes; zero unexplained — an independent
+ year re-confirming rulings made in a different one. Proved by re-running
+ §6.7's own mutation: corrupting a Common citation now reddens four tests,
+ two of them external-oracle, where it previously reddened none of them.
+ Residual: `isidore-of-seville` still unwitnessed (needs 2035/2046), and
+ `gregory-the-great`/`patrick` are never observed in 2005–2050 at all, so no
+ fixture in that range can reach them.
+ **The original gap, for the record** (register §6.7, `ef-lectionary` fix
+ round 2). Only five saints route
through `data/ef/commons.sexp`, and across all of 2005–2050 they are the
*observed* office on five days total — `isidore-of-seville` 2008/2035/2046,
`frances-rome` and `sts-felicitas-perpetua` both 2038, while
@@ -229,8 +242,8 @@ against missalemeum; layer 5 pins ~30 dates.
**Plans 1 + 2 are on `main` (35 commits). Plan 3 and its follow-on fix/feature
tasks (RG 16(a), Holy Family/RG 112(a), Holy Name/RG 110, the Sacred Triduum,
the BVM Saturday Office, the Major Litanies) have landed on a chain of feature
-branches since — test count keeps climbing task by task (369 tests green, 370
-with the exhaustive sweep, as of `ef-lectionary`; this line is not kept in
+branches since — test count keeps climbing task by task (374 tests green, 375
+with the exhaustive sweep, as of `ef-oracle-2038`; this line is not kept in
lockstep with every task, `git log`/`dune test` are the actual source of
truth).** The kernel, the **complete EF
temporal cycle**, the **resolution engine**, the **sanctoral data**, and **all five
diff --git a/test/dune b/test/dune
index 9ca2cf6..0851e34 100644
--- a/test/dune
+++ b/test/dune
@@ -9,7 +9,8 @@
../data/ef/lectionary.sexp
../data/ef/commons.sexp
fixtures/lectio-ef-2005-2050.txt
- fixtures/missalemeum-ef-2026-2027.txt)
+ fixtures/missalemeum-ef-2026-2027.txt
+ fixtures/missalemeum-ef-2038.txt)
(preprocess
(pps ppx_sexp_conv)))
diff --git a/test/fixtures/missalemeum-ef-2038.provenance b/test/fixtures/missalemeum-ef-2038.provenance
new file mode 100644
index 0000000..a69c558
--- /dev/null
+++ b/test/fixtures/missalemeum-ef-2038.provenance
@@ -0,0 +1,80 @@
+Fixture: missalemeum-ef-2038.txt
+Task: the 2038 oracle extension, 2026-08-17 (branch ef-oracle-2038).
+
+WHY 2038 AND NOT ANOTHER YEAR
+----------------------------
+docs/research/rules-register.md §6.7 recorded that step 4 of the reading-
+resolution chain -- the Common route, data/ef/commons.sexp -- had NO external
+witness of any kind. Only five saints route through a Common, and across all
+of 2005-2050 they are the OBSERVED office on five days total:
+
+ isidore-of-seville 2008, 2035, 2046
+ frances-rome 2038
+ sts-felicitas-perpetua 2038
+ gregory-the-great never (impeded by Lent's privileged ferias every year)
+ patrick never (same)
+
+None falls inside the 2026-2027 fixture's own window, so layer 4 had never
+once compared a Common-routed citation. 2038 is the year that covers TWO of
+the five at once, which is why it was chosen over 2035 or 2046.
+
+SOURCE, AND HOW IT DIFFERS FROM THE 2026-2027 FIXTURE'S
+-------------------------------------------------------
+This fixture is a LIVE capture, not an archived snapshot, and that is a
+material difference from missalemeum-ef-2026-2027.provenance's own source:
+
+ endpoint : https://www.missalemeum.com/en/api/v5/proper/YYYY-MM-DD
+ fetched : 2026-08-17, one request per day, 2038-01-01..2038-12-31,
+ 365 files, 0 failures, 0.25s between requests
+ local : the JSON was written into a scratch directory laid out as
+ <dir>/missalemeum/en/YYYY-MM-DD.json so the existing extractor
+ could read it unchanged
+
+docs/research/sources.md already records that **the live endpoint HAS DRIFTED
+from lectio's archived 2026-2027 snapshot, so the two are not
+interchangeable.** That is why this is a SEPARATE fixture with its own
+comparison and its own allow-list rather than extra rows appended to the
+2026-2027 one: merging them would put two different versions of the same
+source behind a single set of expectations, and a future disagreement could
+not be attributed to either the calendar or the drift. Nothing here is
+compared against the 2026-2027 fixture.
+
+Because it is a live capture of a third-party service, it is also NOT
+reproducible byte-for-byte on demand the way the snapshot-derived fixture is:
+re-running the fetch tomorrow may legitimately return different content if
+missalemeum changes. The SHA below pins WHAT WAS COMPARED, and a mismatch
+means the fixture file changed, not that missalemeum did.
+
+SHA-256 of the extracted fixture:
+ 2ac17136be5f6a831bb115ab62f0bb993f69973fdd847d269b43915746ef2151
+Asserted by test_oracle.ml's own 2038 fixture-SHA test, the same discipline
+the 2026-2027 fixture uses. Regenerate deliberately; never copy a mismatch's
+actual value back in, which defeats the pin.
+
+Exact commands:
+ # fetch (365 requests, be polite -- this is someone else's server)
+ d=2038-01-01
+ while [ "$d" != "2039-01-01" ]; do
+ curl -s -A "colitur-validation/0.1" \
+ "https://www.missalemeum.com/en/api/v5/proper/$d" \
+ -o <dir>/missalemeum/en/$d.json
+ sleep 0.25
+ d=$(date -I -d "$d + 1 day")
+ done
+ # extract (the third argument is the expected day count -- see the tool's
+ # own header; it used to be hardcoded to 730 and was generalised for this)
+ python3 tools/extract_missalemeum_oracle.py <dir> \
+ test/fixtures/missalemeum-ef-2038.txt 365
+
+Output: one line per civil day, 2038-01-01 through 2038-12-31 inclusive
+(365 lines), pipe-separated, IDENTICAL schema to the 2026-2027 fixture:
+ date|rank|colors|title|tempora|commemorations|displaced|n_masses|commemoration_ids|first|gospel
+
+Known extraction warnings for this year, checked rather than suppressed:
+ 2038-04-23 has no "Lectio" and no "Evangelium" section -- it is Good
+ Friday (Easter 2038 is 25 April, the latest date Easter can fall), whose
+ "Missa Praesanctificatorum" has a multi-lesson structure with no single
+ reading in the Epistle/Gospel slot this schema assumes. Both fields are
+ "-", with a warning on stderr naming the date, never a silent guess --
+ exactly the shape the 2026-2027 fixture already records for its own two
+ Good Friday rows.
diff --git a/test/fixtures/missalemeum-ef-2038.txt b/test/fixtures/missalemeum-ef-2038.txt
new file mode 100644
index 0000000..125e9bd
--- /dev/null
+++ b/test/fixtures/missalemeum-ef-2038.txt
@@ -0,0 +1,365 @@
+2038-01-01|1|w|Octave Day of Christmas|-|-|-|1|-|Titus 2:11-15|Luke 2:21
+2038-01-02|4|w|II Mass of the B. V. M. – Vultum Tuum|-|-|-|1|-|Titus 3:4-7|Luke 2:15-20
+2038-01-03|2|w|Holy Name of Jesus|-|-|-|1|-|Acts 4:8-12|Luke 2:21
+2038-01-04|4|w|Feria|-|-|-|1|-|Titus 2:11-15|Luke 2:21
+2038-01-05|4|w|Feria|-|St. Telesphorus Pope and Martyr|-|1|sancti:01-05:4:r|Titus 2:11-15|Luke 2:21
+2038-01-06|1|w|Epiphany of the Lord|-|-|-|1|-|Isa 60:1-6|Matt 2:1-12
+2038-01-07|4|w|Feria|-|-|-|1|-|Isa 60:1-6|Matt 2:1-12
+2038-01-08|4|w|Feria|-|-|-|1|-|Isa 60:1-6|Matt 2:1-12
+2038-01-09|4|w|II Mass of the B. V. M. – Vultum Tuum|-|-|-|1|-|Titus 3:4-7|Luke 2:15-20
+2038-01-10|2|w|The Holy Family: Jesus, Mary & Joseph|-|-|-|1|-|Col 3:12-17|Luke 2:42-52
+2038-01-11|4|w|Feria|Feria_II_after_Epiphany|St. Hyginus Pope and Martyr|-|1|sancti:01-11cc:4:r|Rom 12:1-5|Luke 2:42-52
+2038-01-12|4|w|Feria|Feria_III_after_Epiphany|-|-|1|-|Rom 12:1-5|Luke 2:42-52
+2038-01-13|2|w|Commemoration of the Baptism of the Lord|Feria_IV_after_Epiphany|-|-|1|-|Isa 60:1-6|John 1:29-34
+2038-01-14|3|w|St. Hilary|Feria_V_after_Epiphany|S. Felicis|-|1|sancti:01-14cc:4:r|2 Tim 4:1-8|Matt 5:13-19
+2038-01-15|3|w|St. Paul, the First Hermit|Feria_VI_after_Epiphany|St. Maur, Abbot|-|1|sancti:01-15cc:4:w|Phil 3:7-12|Matt 11:25-30
+2038-01-16|3|r|St. Marcellus I|Saturday_after_Epiphany|-|-|1|-|1 Pet 5:1-4; 5:10-11.|Matt 16:13-19
+2038-01-17|2|g|II Sunday after Epiphany|-|-|St. Anthony|1|-|Rom 12:6-16|John 2:1-11
+2038-01-18|4|g|Feria|Feria_II_after_II_Sunday_after_Epiphany|St. Prisca|-|1|sancti:01-18r:4:w|Rom 12:6-16|John 2:1-11
+2038-01-19|4|g|Feria|Feria_III_after_II_Sunday_after_Epiphany|Sts. Marius, Martha, Audifax & Abachum;St. Canute, Martyr|-|1|sancti:01-19:4:r;sancti:01-19o:4:r|Rom 12:6-16|John 2:1-11
+2038-01-20|3|r|Sts. Fabian & Sebastian|Feria_IV_after_II_Sunday_after_Epiphany|-|-|1|-|Heb 11:33-39|Luke 6:17-23
+2038-01-21|3|r|St. Agnes|Feria_V_after_II_Sunday_after_Epiphany|-|-|1|-|Sir 51:1-8; 51:12|Matt 25:1-13.
+2038-01-22|3|r|Sts. Vincent & Anastasius|Feria_VI_after_II_Sunday_after_Epiphany|-|-|1|-|Wis 3:1-8|Luke 21:9-19
+2038-01-23|3|w|St. Raymond of Peñafort|Saturday_after_II_Sunday_after_Epiphany|St. Emerentiana|-|1|sancti:01-23o:4:r|Sir 31:8-11|Luke 12:35-40
+2038-01-24|2|g|III Sunday after Epiphany|-|-|St. Timothy|1|-|Rom 12:16-21|Matt 8:1-13
+2038-01-25|3|w|Conversion of St. Paul|Feria_II_after_III_Sunday_after_Epiphany|St. Peter|-|1|sancti:01-25c:4:w|Acts 9:1-22|Matt 19:27-29.
+2038-01-26|3|r|St. Polycarp|Feria_III_after_III_Sunday_after_Epiphany|-|-|1|-|1 John 3:10-16|Matt 10:26-32.
+2038-01-27|3|w|St. John Chrysostom|Feria_IV_after_III_Sunday_after_Epiphany|-|-|1|-|2 Tim 4:1-8|Matt 5:13-19
+2038-01-28|3|w|St. Peter Nolasco|Feria_V_after_III_Sunday_after_Epiphany|St. Agnes|-|1|sancti:01-28t:4:r|1 Cor. 4:9-14|Luke 12:32-34
+2038-01-29|3|w|St. Francis de Sales|Feria_VI_after_III_Sunday_after_Epiphany|-|-|1|-|2 Tim 4:1-8|Matt 5:13-19
+2038-01-30|3|r|St. Martina|Saturday_after_III_Sunday_after_Epiphany|-|-|1|-|Sir 51:1-8; 51:12|Matt 25:1-13.
+2038-01-31|2|g|IV Sunday after Epiphany|-|-|St. John Bosco|1|-|Rom 13:8-10|Matt 8:23-27
+2038-02-01|3|r|St. Ignatius of Antioch|Feria_II_after_IV_Sunday_after_Epiphany|-|-|1|-|Rom 8:35-39|John 12:24-26
+2038-02-02|2|w|Purification of the Blessed Virgin Mary|Feria_III_after_IV_Sunday_after_Epiphany|-|-|1|-|Mal 3:1-4|Luke 2:22-32
+2038-02-03|4|g|Feria|Feria_IV_after_IV_Sunday_after_Epiphany|St. Blaise|-|1|sancti:02-03:4:r|Rom 13:8-10|Matt 8:23-27
+2038-02-04|3|w|St. Andrew Corsini|Feria_V_after_IV_Sunday_after_Epiphany|-|-|1|-|Sir 44:16-27; 45:3-20|Matt 25:14-23
+2038-02-05|3|r|St. Agatha|Feria_VI_after_IV_Sunday_after_Epiphany|-|-|1|-|1 Cor. 1:26-31|Matt 19:3-12.
+2038-02-06|3|w|St. Titus|Saturday_after_IV_Sunday_after_Epiphany|St. Dorothy|-|1|sancti:02-06o:4:r|Sir 44:16-27; 45:3-20|Luke 10:1-9
+2038-02-07|2|g|V Sunday after Epiphany|-|-|St. Romuald|1|-|Col 3:12-17|Matt 13:24-30
+2038-02-08|3|w|St. John of Matha|Feria_II_after_V_Sunday_after_Epiphany|-|-|1|-|Sir 31:8-11|Luke 12:35-40
+2038-02-09|3|w|St. Cyril of Alexandria|Feria_III_after_V_Sunday_after_Epiphany|St. Appollonia|-|1|sancti:02-09o:4:r|2 Tim 4:1-8|Matt 5:13-19
+2038-02-10|3|w|St. Scholastica|Feria_IV_after_V_Sunday_after_Epiphany|-|-|1|-|2 Cor 10:17-18; 11:1-2|Matt 25:1-13.
+2038-02-11|3|w|Our Lady of Lourdes|Feria_V_after_V_Sunday_after_Epiphany|-|-|1|-|Apoc 11:19; 12:1, 10|Luke 1:26-31.
+2038-02-12|3|w|Seven Holy Servite Founders|Feria_VI_after_V_Sunday_after_Epiphany|-|-|1|-|Ecclus 44:1-15|Matt 19:27-29.
+2038-02-13|4|w|III Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_V_Sunday_after_Epiphany|-|-|1|-|Ecclus 24:14-16|Luke 11:27-28
+2038-02-14|2|g|VI Sunday after Epiphany|-|-|St. Valentine|1|-|1 Thess. 1:2-10|Matt 13:31-35
+2038-02-15|4|g|Feria|Feria_II_after_VI_Sunday_after_Epiphany|Sts. Faustinus & Jovita|-|1|sancti:02-15:4:r|1 Thess. 1:2-10|Matt 13:31-35
+2038-02-16|4|g|Feria|Feria_III_after_VI_Sunday_after_Epiphany|-|-|1|-|1 Thess. 1:2-10|Matt 13:31-35
+2038-02-17|4|g|Feria|Feria_IV_after_VI_Sunday_after_Epiphany|-|-|1|-|1 Thess. 1:2-10|Matt 13:31-35
+2038-02-18|4|g|Feria|Feria_V_after_VI_Sunday_after_Epiphany|St. Simeon|-|1|sancti:02-18:4:r|1 Thess. 1:2-10|Matt 13:31-35
+2038-02-19|4|g|Feria|Feria_VI_after_VI_Sunday_after_Epiphany|-|-|1|-|1 Thess. 1:2-10|Matt 13:31-35
+2038-02-20|4|w|III Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_VI_Sunday_after_Epiphany|-|-|1|-|Ecclus 24:14-16|Luke 11:27-28
+2038-02-21|2|v|Septuagesima Sunday|-|-|-|1|-|1 Cor. 9:24-27; 10:1-5|Matt 20:1-16
+2038-02-22|2|w|Chair of St. Peter|Feria_II_after_Septuagesima|St. Paul|-|1|sancti:02-22c:4:r|1 Pet 1:1-7|Matt 16:13-19
+2038-02-23|3|w|St. Peter Damien|Feria_III_after_Septuagesima|-|-|1|-|2 Tim 4:1-8|Matt 5:13-19
+2038-02-24|2|r|St. Matthias|Feria_IV_after_Septuagesima|-|-|1|-|Acts 1:15-26|Matt 11:25-30
+2038-02-25|4|v|Feria|Feria_V_after_Septuagesima|-|-|1|-|1 Cor. 9:24-27; 10:1-5|Matt 20:1-16
+2038-02-26|4|v|Feria|Feria_VI_after_Septuagesima|-|-|1|-|1 Cor. 9:24-27; 10:1-5|Matt 20:1-16
+2038-02-27|3|w|St. Gabriel of Our Lady of Sorrows|Saturday_after_Septuagesima|-|-|1|-|1 John 2:14-17|Mark 10:13-21
+2038-02-28|2|v|Sexagesima Sunday|-|-|-|1|-|2 Cor. 11:19-33; 12:1-9|Luke 8:4-15
+2038-03-01|4|v|Feria|Feria_II_after_Sexagesima|-|-|1|-|2 Cor. 11:19-33; 12:1-9|Luke 8:4-15
+2038-03-02|4|v|Feria|Feria_III_after_Sexagesimæ|-|-|1|-|2 Cor. 11:19-33; 12:1-9|Luke 8:4-15
+2038-03-03|4|v|Feria|Feria_IV_after_Sexagesimæ|-|-|1|-|2 Cor. 11:19-33; 12:1-9|Luke 8:4-15
+2038-03-04|3|w|St. Casimir|Feria_V_after_Sexagesimæ|St. Lucius|-|1|sancti:03-04cc:4:r|Sir 31:8-11|Luke 12:35-40
+2038-03-05|4|v|Feria|Feria_VI_after_Sexagesimæ|-|-|1|-|2 Cor. 11:19-33; 12:1-9|Luke 8:4-15
+2038-03-06|3|r|Sts. Felicitas & Perpetua|Saturday_after_Sexagesimæ|-|-|1|-|Sir 51:13-17.|Matt 13:44-52.
+2038-03-07|2|v|Quinquagesima Sunday|-|-|St. Thomas Aquinas|1|-|1 Cor. 13:1-13|Luke 18:31-43
+2038-03-08|3|w|St. John of God|Feria_II_after_Quinquagesima|-|-|1|-|Sir 31:8-11|Matt 22:34-46
+2038-03-09|3|w|St. Frances Rome|Feria_III_after_Quinquagesima|-|-|1|-|Prov 31:10-31|Matt 13:44-52.
+2038-03-10|1|v|Ash Wednesday|-|-|Forty Holy Martyrs of Sebaste|1|-|Joel 2:12-19|Matt 6:16-21
+2038-03-11|3|v|Feria V after Ash Wednesday|-|-|-|1|-|Isa 38:1-6|Matt 8:5-13
+2038-03-12|3|v|Feria VI after Ash Wednesday|-|St. Gregory the Great|-|1|sancti:03-12:3:w|Isa 58:1-9|Matt 5:43-48; 6:1-4
+2038-03-13|3|v|Saturday after Ash Wednesday|-|-|-|1|-|Isa 58:9-14|Mark 6:47-56
+2038-03-14|1|v|I Sunday of Lent|-|-|-|1|-|2 Cor. 6:1-10|Matt 4:1-11
+2038-03-15|3|v|Feria II after the I Sunday of Lent|-|-|-|1|-|Ezech 34:11-16|Matt 25:31-46
+2038-03-16|3|v|Feria III after the I Sunday of Lent|-|-|-|1|-|Isa 55:6-11|Matt 21:10-17
+2038-03-17|2|v|Ember Wednesday of Lent|-|St. Patrick|-|1|sancti:03-17:3:w|3 Kgs. 19:3-8|Matt 12:38-50
+2038-03-18|3|v|Feria V after the I Sunday of Lent|-|St. Cyril of Jerusalem|-|1|sancti:03-18:3:w|Ezech 18:1-9|Matt 15:21-28
+2038-03-19|1|w|St. Joseph, Spouse of the Bl. Virgin Mary|Ember_Friday_of_Lent|Ember Friday of Lent|-|1|tempora:Quad1-5:2:v|Ecclus 45:1-6|Matt 1:18-21
+2038-03-20|2|v|Ember Saturday of Lent|-|-|-|1|-|1 Thess. 5:14-23|Matt 17:1-9
+2038-03-21|1|v|II Sunday of Lent|-|-|St. Benedict|1|-|1 Thess. 4:1-7|Matt 17:1-9
+2038-03-22|3|v|Feria II after the II Sunday of Lent|-|-|-|1|-|Dan 9:15-19|John 8:21-29
+2038-03-23|3|v|Feria III after the II Sunday of Lent|-|-|-|1|-|3 Kings 17:8-16|Matt 23:1-12
+2038-03-24|3|v|Feria IV after the II Sunday of Lent|-|St. Gabriel the Archangel|-|1|sancti:03-24:3:w|Esther 13:8-11; 15-17.|Matt 20:17-28
+2038-03-25|1|w|Annunciation of the Blessed Virgin Mary|Feria_V_after_the_II_Sunday_of_Lent|Feria V after the II Sunday of Lent|-|1|tempora:Quad2-4:3:v|Isa 7:10-15|Luke 1:26-38
+2038-03-26|3|v|Feria VI after the II Sunday of Lent|-|-|-|1|-|Gen 37:6-22|Matt 21:33-46
+2038-03-27|3|v|Saturday after the II Sunday of Lent|-|St. John Damascene|-|1|sancti:03-27:3:w|Gen 27:6-40|Luke 15:11-32
+2038-03-28|1|v|III Sunday of Lent|-|-|St. John of Capistrano|1|-|Eph 5:1-9|Luke 11:14-28
+2038-03-29|3|v|Feria II after the III Sunday of Lent|-|-|-|1|-|4 Kings, 5:1-15|Luke 4:23-30
+2038-03-30|3|v|Feria III after the III Sunday of Lent|-|-|-|1|-|4 Kings 4:1-7|Matt 18:15-22
+2038-03-31|3|v|Feria IV after the III Sunday of Lent|-|-|-|1|-|Ex 20:12-24|Matt 15:1-20
+2038-04-01|3|v|Feria V after the III Sunday of Lent|-|-|-|1|-|Jer 7:1-7|Luke 4:38-44.
+2038-04-02|3|v|Feria VI after the III Sunday of Lent|-|St. Francis of Paola|-|1|sancti:04-02:3:w|Num 20:1, 3; 6-13.|John 4:5-42
+2038-04-03|3|v|Saturday after the III Sunday of Lent|-|-|-|1|-|Dan 13:1-9, 15-17, 19-30, 33-62.|John 8:1-11
+2038-04-04|1|pv|IV Sunday of Lent|-|-|St. Isidore of Seville|1|-|Gal 4:22-31|John 6:1-15
+2038-04-05|3|v|Feria II after the IV Sunday of Lent|-|St. Vincent Ferrer|-|1|sancti:04-05:3:w|3 Kings 3:16-28|John 2:13-25
+2038-04-06|3|v|Feria III after the IV Sunday of Lent|-|-|-|1|-|Ex 32:7-14|John 7:14-31
+2038-04-07|3|v|Feria IV after the IV Sunday of Lent|-|-|-|1|-|Isa. 1:16-19|John 9:1-38
+2038-04-08|3|v|Feria V after the IV Sunday of Lent|-|-|-|1|-|4 Kings 4:25-38|Luke 7:11-16
+2038-04-09|3|v|Feria VI after the IV Sunday of Lent|-|-|-|1|-|3 Kings 17:17-24|John 11:1-45
+2038-04-10|3|v|Saturday after the IV Sunday of Lent|-|-|-|1|-|Isa 49:8-15|John 8:12-20
+2038-04-11|1|v|Passion Sunday|-|-|St. Leo the Great|1|-|Heb 9:11-15.|John 8:46-59.
+2038-04-12|3|v|Feria II of Passion Week|-|-|-|1|-|Jonas 3:1-10|John 7:32-39
+2038-04-13|3|v|Feria III of Passion Week|-|St. Hermenegild|-|1|sancti:04-13:3:r|Dan 14:27-42|John 7:1-13
+2038-04-14|3|v|Feria IV of Passion Week|-|St. Justin;Sts. Tiburtius, Valerian et Maximus, Martyrs|-|1|sancti:04-14:3:r;sancti:04-14t:4:r|Lev 19:1-2, 11-19, 25|John 10:22-38
+2038-04-15|3|v|Feria V of Passion Week|-|-|-|1|-|Dan 3:25, 34-45.|Luke 7:36-50
+2038-04-16|3|v|Feria VI of Passion Week|-|For Our Lady of the Seven Sorrows|-|1|tempora:Quad5-5Feriac:4:w|Jer 17:13-18|John 11:47-54
+2038-04-17|3|v|Saturday of Passion Week|-|St. Anicetus|-|1|sancti:04-17:4:r|Jer 18:18-23|John 12:10-36
+2038-04-18|1|rv|Palm Sunday|-|-|-|1|-|Phil 2:5-11|Matt. 26:36-75; 27:1-60.
+2038-04-19|1|v|Feria II of Holy Week|-|-|-|1|-|Isa 50:5-10|John 12:1-9
+2038-04-20|1|v|Feria III of Holy Week|-|-|-|1|-|Jer 11:18-20|Mark 14:32-72; 15, 1-46
+2038-04-21|1|v|Feria IV of Holy Week|-|-|St. Anselm|1|-|Isa 53:1-12|Luc 22:39-71; 23:1-53
+2038-04-22|1|w|Holy Thursday|-|-|Sts. Soter & Caius|1|-|1 Cor 11:20-32.|Joann 13:1-15
+2038-04-23|1|bv|Good Friday|-|-|St. George|1|-|-|-
+2038-04-24|1|vw|Holy Saturday|-|-|St. Fidelis of Sigmaringen|1|-|Col 3:1-4|Matt 28:1-7
+2038-04-25|1|w|Easter Sunday|-|-|St. Mark;Pro rogationibus|1|-|1 Cor 5:7-8|Mark 16:1-7
+2038-04-26|1|w|Monday in the Octave of Easter|-|-|Sts. Cletus & Marcellinus|1|-|Acts 10:37-43.|Luke 24:13-35
+2038-04-27|1|w|Tuesday in the Octave of Easter|-|-|St. Peter Canisius|1|-|Acts 13:16; 13:26-33|Luke 24:36-47
+2038-04-28|1|w|Wednesday in the Octave of Easter|-|-|St. Paul of the Cross|1|-|Acts 3:13-15; 3:17-19|John 21:1-14
+2038-04-29|1|w|Thursday in the Octave of Easter|-|-|St. Peter of Verona|1|-|Acts 8:26-40|John 20:11-18
+2038-04-30|1|w|Friday in the Octave of Easter|-|-|St. Catherine of Siena|1|-|1 Pet 3:18-22|Matt 28:16-20
+2038-05-01|1|w|Saturday in the Octave of Easter|-|-|St. Joseph the Workman|1|-|1 Pet 2:1-10|John 20:1-9
+2038-05-02|1|w|Low Sunday|-|-|St. Athanasius|1|-|1 John 5:4-10|John 20. 19-31
+2038-05-03|1|w|St. Joseph the Workman|Monday_after_I_Sunday_after_Easter|-|Sts. Alexander & Companions|1|-|Col. 3:14-15, 17, 23-24|Matt 13:54-58
+2038-05-04|3|w|St. Monica|Tuesday_after_I_Sunday_after_Easter|-|-|1|-|1 Tim. 5:3-10.|Luke 7:11-16
+2038-05-05|3|w|St. Pius V|Wednesday_after_I_Sunday_after_Easter|-|-|1|-|1 Pet 5:1-4; 5:10-11.|Matt 16:13-19
+2038-05-06|4|w|Feria|Thursday_after_I_Sunday_after_Easter|-|-|1|-|1 John 5:4-10|John 20. 19-31
+2038-05-07|3|r|St. Stanislaus|Friday_after_I_Sunday_after_Easter|-|-|1|-|Wis 5:1-5|John 15:1-7
+2038-05-08|4|w|IV Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_I_Sunday_after_Easter|-|-|1|-|Ecclus 24:14-16|John 19:25-27
+2038-05-09|2|w|II Sunday after Easter|-|-|St. Gregory of Nazianzen|1|-|1 Pet 2:21-25|John 10:11-16
+2038-05-10|3|w|St. Antoninus|Monday_after_II_Sunday_after_Easter|St. Gordiano and Epimacho|-|1|sancti:05-10o:4:r|Sir 44:16-27; 45:3-20|Matt 25:14-23
+2038-05-11|2|r|Sts. Philip & James|Tuesday_after_II_Sunday_after_Easter|-|-|1|-|Wis. 5:1-5|John 14:1-13
+2038-05-12|3|r|Sts. Nereus, Achilleus, Domitilla, & Pancras|Wednesday_after_II_Sunday_after_Easter|-|-|1|-|Wis. 5:1-5|John 4:46-53
+2038-05-13|3|w|St. Robert Bellarmine|Thursday_after_II_Sunday_after_Easter|-|-|1|-|Wis 7:7-14.|Matt 5:13-19
+2038-05-14|4|w|Feria|Friday_after_II_Sunday_after_Easter|St. Boniface|-|1|sancti:05-14:4:r|1 Pet 2:21-25|John 10:11-16
+2038-05-15|3|w|St. John Baptist de la Salle|Saturday_after_II_Sunday_after_Easter|-|-|1|-|Sir 31:8-11|Matt 18:1-5
+2038-05-16|2|w|III Sunday after Easter|-|-|St. Ubaldus|1|-|1 Pet 2:11-19|John 16:16-22
+2038-05-17|3|w|St. Paschal Baylon|Monday_after_III_Sunday_after_Easter|-|-|1|-|Sir 31:8-11|Luke 12:35-40
+2038-05-18|3|r|St. Venantius|Tuesday_after_III_Sunday_after_Easter|-|-|1|-|Wis 5:1-5|John 15:1-7
+2038-05-19|3|w|St. Peter Celestine|Wednesday_after_III_Sunday_after_Easter|St. Pudentiana Virginis|-|1|sancti:05-19o:4:w|1 Pet 5:1-4; 5:10-11.|Matt 16:13-19
+2038-05-20|3|w|St. Bernardine of Siena|Thursday_after_III_Sunday_after_Easter|-|-|1|-|Sir 31:8-11|Matt 19:27-29.
+2038-05-21|4|w|Feria|Friday_after_III_Sunday_after_Easter|-|-|1|-|1 Pet 2:11-19|John 16:16-22
+2038-05-22|4|w|IV Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_III_Sunday_after_Easter|-|-|1|-|Ecclus 24:14-16|John 19:25-27
+2038-05-23|2|w|IV Sunday after Easter|-|-|-|1|-|Jas 1:17-21|John 16:5-14
+2038-05-24|4|w|Feria|Monday_after_IV_Sunday_after_Easter|-|-|1|-|Jas 1:17-21|John 16:5-14
+2038-05-25|3|w|St. Gregory VII|Tuesday_after_IV_Sunday_after_Easter|St. Urban, Pope and Martyr|-|1|sancti:05-25o:4:r|1 Pet 5:1-4; 5:10-11.|Matt 16:13-19
+2038-05-26|3|w|St. Philip Neri|Wednesday_after_IV_Sunday_after_Easter|S. Eleutherius|-|1|sancti:05-26o:4:r|Wis 7:7-14.|Luke 12:35-40
+2038-05-27|3|w|St. Bede the Venerable|Thursday_after_IV_Sunday_after_Easter|St. John I|-|1|sancti:05-27o:4:r|2 Tim 4:1-8|Matt 5:13-19
+2038-05-28|3|w|St. Augustine of Canterbury|Friday_after_IV_Sunday_after_Easter|-|-|1|-|1 Thess 2:2-9|Luke 10:1-9
+2038-05-29|3|w|St. Mary Magdalene de Pazzi|Saturday_after_IV_Sunday_after_Easter|-|-|1|-|2 Cor 10:17-18; 11:1-2|Matt 25:1-13.
+2038-05-30|2|w|V Sunday after Easter|-|-|St. Felix I|1|-|Jas 1:22-27|John 16:23-30
+2038-05-31|2|w|Queenship of the Blessed Virgin Mary|The_Minor_Litanies_–_Rogations|St. Petronilla|-|1|sancti:05-31c:4:w|Eccli 24:5; 14:7; 14:9-11; 24:30-31|Luke 1:26-33
+2038-06-01|3|w|St. Angela Merici|The_Minor_Litanies_–_Rogations|-|-|1|-|2 Cor 10:17-18; 11:1-2|Matt 25:1-13.
+2038-06-02|2|w|Vigil of the Ascension|-|Sts. Marcellinus, Peter, & Erasmus|-|1|sancti:06-02:4:r|Eph. 4:7-13.|John 17:1-11.
+2038-06-03|1|w|Ascension of the Lord|-|-|-|1|-|Acts 1:1-11|Mark 16:14-20
+2038-06-04|3|w|St. Francis Caracciolo|Feria_VI_after_the_Ascension|-|-|1|-|Wis. 4:7-14.|Luke 12:35-40
+2038-06-05|3|r|St. Boniface|Saturday_after_the_Ascension|-|-|1|-|Ecclus 44:1-15|Matt 5:1-12
+2038-06-06|2|w|Sunday after the Ascension|-|-|St. Norbert|1|-|1 Pet 4:7-11.|John 15:26-27; 16:1-4.
+2038-06-07|4|w|Feria|Feria_II_after_the_Ascension|-|-|1|-|1 Pet 4:7-11.|John 15:26-27; 16:1-4.
+2038-06-08|4|w|Feria|Feria_III_after_the_Ascension|-|-|1|-|1 Pet 4:7-11.|John 15:26-27; 16:1-4.
+2038-06-09|4|w|Feria|Feria_IV_after_the_Ascension|Sts. Primus & Felicianus|-|1|sancti:06-09:4:r|1 Pet 4:7-11.|John 15:26-27; 16:1-4.
+2038-06-10|3|w|St. Margaret of Scotland|Feria_V_after_the_Ascension|-|-|1|-|Prov 31:10-31|Matt 13:44-52.
+2038-06-11|3|r|St. Barnabas|Feria_VI_after_the_Ascension|-|-|1|-|Acts 11:21-26; 13:1-3|Matt 10:16-22
+2038-06-12|1|r|Saturday after the Ascension|-|-|St. John of San Fecundo;St. Basilidus|1|-|Acts 19:1-8.|John 14:15-21.
+2038-06-13|1|r|Pentecost Sunday|-|-|St. Anthony of Padua|1|-|Acts 2:1-11.|John 14:23-31.
+2038-06-14|1|r|Monday after Pentecost|-|-|St. Basil the Great|1|-|Acts 10:34, 42-48|John 3:16-21
+2038-06-15|1|r|Tuesday after Pentecost|-|-|St. Vitus|1|-|Acts 8:14-17.|John 10:1-10.
+2038-06-16|1|r|Ember Wednesday of Pentecost|-|-|-|1|-|Acts 5:12-16|John 6:44-52.
+2038-06-17|1|r|Thursday after Pentecost|-|-|St. Gregory Barbarigo|1|-|Acts 8:5-8|Luke 9:1-6
+2038-06-18|1|r|Ember Friday of Pentecost|-|-|St. Ephrem of Syria;Ss. Marcus and Marcellianus|1|-|Joel 2:23-24; 26-27|Luke 5:17-26
+2038-06-19|1|r|Ember Saturday of Pentecost|-|-|St. Julia of Falconieri;Sts. Gervasius and Protasius|1|-|Rom 5:1-5.|Luke 4:38-44.
+2038-06-20|1|w|Trinity Sunday|-|-|St. Silverius|1|-|Rom 11:33-36.|Matt 28:18-20
+2038-06-21|3|w|St. Aloysius Gongzaga|Feria_II_after_I_Sunday_after_Pentecost|-|-|1|-|Sir 31:8-11|Matt 22:29-40
+2038-06-22|3|w|St. Paulinus of Nola|Feria_III_after_I_Sunday_after_Pentecost|-|-|1|-|2 Cor. 8:9-15|Luke 12:32-34
+2038-06-23|2|v|Vigil of the Nativity of St. John the Baptist|Feria_IV_after_I_Sunday_after_Pentecost|-|-|1|-|Jer 1:4-10|Luke 1:5-17
+2038-06-24|1|w|Corpus Christi|-|-|Nativity of St. John the Baptist|1|-|1 Cor. 11:23-29.|John 6:56-59.
+2038-06-25|1|w|Nativity of St. John the Baptist|Feria_V_after_I_Sunday_after_Pentecost|-|St. William|1|-|Isa 49:1-3, 5-7.|Luke 1:57-68
+2038-06-26|3|r|Sts. John & Paul|Saturday_after_I_Sunday_after_Pentecost|-|-|1|-|Eccli 44:10-15|Luke 12:1-8
+2038-06-27|2|g|II Sunday after Pentecost|-|-|-|1|-|1 John 3:13-18.|Luke 14:16-24.
+2038-06-28|2|v|Vigil of Sts. Peter & Paul|Feria_II_after_II_Sunday_after_Pentecost|-|-|1|-|Acts 3:1-10|John 21:15-19
+2038-06-29|1|r|Sts. Peter & Paul|Feria_III_after_II_Sunday_after_Pentecost|-|-|1|-|Acts 12:1-11|Matt 16:13-19
+2038-06-30|3|r|In Commemoratione Sancti Pauli Apostoli|Feria_IV_after_II_Sunday_after_Pentecost|-|-|1|-|Gal 1:11-20|Matt 10:16-22
+2038-07-01|1|r|The Precious Blood of Our Lord Jesus Christ|Feria_V_after_II_Sunday_after_Pentecost|-|-|1|-|Heb 9:11-15.|John 19:30-35
+2038-07-02|1|w|Sacred Heart of Jesus|-|-|Visitation of the Blessed Virgin Mary;SS. Processus and Martinian|1|-|Eph. 3:8-12, 14-19|John 19:31-37
+2038-07-03|3|r|St. Irenaeus|Saturday_after_II_Sunday_after_Pentecost|-|-|1|-|2 Tim. 3:14-17; 4:1-5|Matt 10:28-33
+2038-07-04|2|g|III Sunday after Pentecost|-|-|-|1|-|1 Pet. 5:6-11|Luke 15:1-10
+2038-07-05|3|w|St. Anthony Mary Zaccariah|Feria_II_after_III_Sunday_after_Pentecost|-|-|1|-|1 Tim. 4:8-16|Mark 10:15-21
+2038-07-06|4|g|Feria|Feria_III_after_III_Sunday_after_Pentecost|-|-|1|-|1 Pet. 5:6-11|Luke 15:1-10
+2038-07-07|3|w|Sts. Cyril & Methodius|Feria_IV_after_III_Sunday_after_Pentecost|-|-|1|-|Heb 7:23-27|Luke 10:1-9
+2038-07-08|3|w|St. Elizabeth of Portugal|Feria_V_after_III_Sunday_after_Pentecost|-|-|1|-|Prov 31:10-31|Matt 13:44-52.
+2038-07-09|4|g|Feria|Feria_VI_after_III_Sunday_after_Pentecost|-|-|1|-|1 Pet. 5:6-11|Luke 15:1-10
+2038-07-10|3|r|Seven Holy Brothers and Sts. Rufina & Secunda|Saturday_after_III_Sunday_after_Pentecost|-|-|1|-|Prov 31:10-31|Matt 12:46-50
+2038-07-11|2|g|IV Sunday after Pentecost|-|-|St. Pius I|1|-|Rom 8:18-23|Luke 5:1-11
+2038-07-12|3|r|St. John Gualbert|Feria_II_after_IV_Sunday_after_Pentecost|Ss. Naboris et Felicis|-|1|sancti:07-12o:4:r|Ecclus 45:1-6|Matt 5:43-48
+2038-07-13|4|g|Feria|Feria_III_after_IV_Sunday_after_Pentecost|-|-|1|-|Rom 8:18-23|Luke 5:1-11
+2038-07-14|3|w|St. Bonaventure|Feria_IV_after_IV_Sunday_after_Pentecost|-|-|1|-|2 Tim 4:1-8|Matt 5:13-19
+2038-07-15|3|w|St. Henry the Emperor|Feria_V_after_IV_Sunday_after_Pentecost|-|-|1|-|Sir 31:8-11|Luke 12:35-40
+2038-07-16|4|g|Feria|Feria_VI_after_IV_Sunday_after_Pentecost|Our Lady of Mt. Carmel|-|1|sancti:07-16:4:w|Rom 8:18-23|Luke 5:1-11
+2038-07-17|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_IV_Sunday_after_Pentecost|St. Alexis|-|1|sancti:07-17:4:w|Ecclus 24:14-16|Luke 11:27-28
+2038-07-18|2|g|V Sunday after Pentecost|-|-|Camillus de Lellis;Ss. Symphorosa and sons|1|-|1 Pet 3:8-15.|Matt 5:20-24.
+2038-07-19|3|w|St. Vincent de Paul|Feria_II_after_V_Sunday_after_Pentecost|-|-|1|-|1 Cor. 4:9-14|Luke 10:1-9
+2038-07-20|3|r|St. Jerome Emiliani|Feria_III_after_V_Sunday_after_Pentecost|St. Margaret|-|1|sancti:07-20o:4:w|Isa 58:7-11|Matt 19:13-21
+2038-07-21|3|w|St. Laurence of Brindisi|Feria_IV_after_V_Sunday_after_Pentecost|St. Praxedis Virginis|-|1|sancti:07-21:4:w|2 Tim 4:1-8|Matt 5:13-19
+2038-07-22|3|w|St. Mary Magdalene|Feria_V_after_V_Sunday_after_Pentecost|-|-|1|-|Song 3:2-5; 8:6-7|Luke 7:36-50
+2038-07-23|3|w|St. Apollinaris|Feria_VI_after_V_Sunday_after_Pentecost|S. Liborii|-|1|sancti:07-23cc:4:r|1 Pet. 5:1-11|Luke 22:24-30
+2038-07-24|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_V_Sunday_after_Pentecost|St. Christina|-|1|sancti:07-24r:4:r|Ecclus 24:14-16|Luke 11:27-28
+2038-07-25|2|g|VI Sunday after Pentecost|-|St. James the Greater|St. Christopher|1|sancti:07-25:2:r|Rom 6:3-11.|Mark 8:1-9
+2038-07-26|2|w|St. Anne, Mother of the Blessed Virgin|Feria_II_after_VI_Sunday_after_Pentecost|-|-|1|-|Prov 31:10-31|Matt 13:44-52.
+2038-07-27|4|g|Feria|Feria_III_after_VI_Sunday_after_Pentecost|St. Pantaleon|-|1|sancti:07-27:4:r|Rom 6:3-11.|Mark 8:1-9
+2038-07-28|3|r|Sts. Nazarius & Celsus, St. Victor I & St. Innocent I|Feria_IV_after_VI_Sunday_after_Pentecost|-|-|1|-|Wis 10:17-20|Luke 21:9-19
+2038-07-29|3|r|St. Martha|Feria_V_after_VI_Sunday_after_Pentecost|Ss. Felicis, Simplicii, Faustini et Beatricis|-|1|sancti:07-29cc:4:r|2 Cor 10:17-18; 11:1-2|Luke 10:38-42
+2038-07-30|4|g|Feria|Feria_VI_after_VI_Sunday_after_Pentecost|Sts. Abdon & Sennen|-|1|sancti:07-30:4:r|Rom 6:3-11.|Mark 8:1-9
+2038-07-31|3|w|St. Ignatius Loyola|Saturday_after_VI_Sunday_after_Pentecost|-|-|1|-|2 Tim. 2:8-10; 3:10-12.|Luke 10:1-9
+2038-08-01|2|g|VII Sunday after Pentecost|-|-|Holy Machabees|1|-|Rom 6:19-23|Matt 7:15-21
+2038-08-02|3|r|St. Alphonsus Liguori|Feria_II_after_VII_Sunday_after_Pentecost|St. Stephen I, Pope and Martyr|-|1|sancti:08-02o:4:r|2 Tim. 2:1-7|Luke 10:1-9
+2038-08-03|4|g|Feria|Feria_III_after_VII_Sunday_after_Pentecost|-|-|1|-|Rom 6:19-23|Matt 7:15-21
+2038-08-04|3|w|St. Dominic|Feria_IV_after_VII_Sunday_after_Pentecost|-|-|1|-|2 Tim. 4:1-8|Luke 12:35-40
+2038-08-05|3|w|Dedication of the Basilica of St. Mary Major|Feria_V_after_VII_Sunday_after_Pentecost|-|-|1|-|Ecclus 24:14-16|Luke 11:27-28
+2038-08-06|2|w|Transfiguration of Our Lord|Feria_VI_after_VII_Sunday_after_Pentecost|Pope Sixtus II, Felicissimus and Agapitus, Martyrs|-|1|sancti:08-06cc:4:r|2 Pet. 1:16-19|Matt 17:1-9
+2038-08-07|3|w|St. Cajetan|Saturday_after_VII_Sunday_after_Pentecost|St. Donatus|-|1|sancti:08-07o:4:r|Sir 31:8-11|Matt 6:24-33
+2038-08-08|2|g|VIII Sunday after Pentecost|-|-|St. John Mary Vianney;Ss. Cyriacus, Largus and Smaragdus, Martyrs|1|-|Rom 8:12-17|Luke 16:1-9
+2038-08-09|3|r|Vigil of St. Lawrence|Feria_II_after_VIII_Sunday_after_Pentecost|St. Romanus|-|1|sancti:08-09cc:4:r|Ecclus 51:1-8, 12|Matt 16:24-27
+2038-08-10|2|r|St. Lawrence|Feria_III_after_VIII_Sunday_after_Pentecost|-|-|1|-|2 Cor. 9:6-10|John 12:24-26
+2038-08-11|4|g|Feria|Feria_IV_after_VIII_Sunday_after_Pentecost|Sts. Tiburtius & Susanna|-|1|sancti:08-11:4:r|Rom 8:12-17|Luke 16:1-9
+2038-08-12|3|w|St. Clare|Feria_V_after_VIII_Sunday_after_Pentecost|-|-|1|-|2 Cor 10:17-18; 11:1-2|Matt 25:1-13.
+2038-08-13|4|g|Feria|Feria_VI_after_VIII_Sunday_after_Pentecost|Sts. Hippolytus & Cassian|-|1|sancti:08-13:4:r|Rom 8:12-17|Luke 16:1-9
+2038-08-14|2|w|Vigil of the Assumption|Saturday_after_VIII_Sunday_after_Pentecost|St. Eusebius|-|1|sancti:08-14cc:4:r|Sir 24:23-31|Luke 11:27-28
+2038-08-15|1|w|Assumption of the Blessed Virgin Mary|IX_Sunday_after_Pentecost|-|-|1|-|Judith 13:22-25; 13:15; 13:10|Luke 1:41-50
+2038-08-16|2|w|St. Joachim, Father of the Blessed Virgin|Feria_II_after_IX_Sunday_after_Pentecost|-|-|1|-|Sir 31:8-11|Matt 1:1-16
+2038-08-17|3|w|St. Hyacinth|Feria_III_after_IX_Sunday_after_Pentecost|-|-|1|-|Sir 31:8-11|Luke 12:35-40
+2038-08-18|4|g|Feria|Feria_IV_after_IX_Sunday_after_Pentecost|St. Agapitus|-|1|sancti:08-18r:4:w|1 Cor. 10:6-13|Luke 19:41-47
+2038-08-19|3|w|St. John Eudes|Feria_V_after_IX_Sunday_after_Pentecost|-|-|1|-|Sir 31:8-11|Luke 12:35-40
+2038-08-20|3|w|St. Bernard of Clairvaux|Feria_VI_after_IX_Sunday_after_Pentecost|-|-|1|-|Ecclus 39:6-14|Matt 5:13-19
+2038-08-21|3|w|St. Jane Frances de Chantal|Saturday_after_IX_Sunday_after_Pentecost|-|-|1|-|Prov 31:10-31|Matt 13:44-52.
+2038-08-22|2|g|X Sunday after Pentecost|-|Immaculate Heart of Mary|Sts. Timothy, Hippolytus and Symphorianus, Martyrs|1|sancti:08-22:2:w|1 Cor. 12:2-11|Luke 18:9-14
+2038-08-23|3|w|St. Philip Benizi|Feria_II_after_X_Sunday_after_Pentecost|-|-|1|-|1 Cor. 4:9-14|Luke 12:32-34
+2038-08-24|2|r|St. Bartholomew|Feria_III_after_X_Sunday_after_Pentecost|-|-|1|-|1 Cor. 12:27-31|Luke 6:12-19
+2038-08-25|3|w|St. Louis IX|Feria_IV_after_X_Sunday_after_Pentecost|-|-|1|-|Wis 10:10-14|Luke 19:12-26
+2038-08-26|4|g|Feria|Feria_V_after_X_Sunday_after_Pentecost|St. Zephyrinus|-|1|sancti:08-26:4:r|1 Cor. 12:2-11|Luke 18:9-14
+2038-08-27|3|w|St. Joseph Calasance|Feria_VI_after_X_Sunday_after_Pentecost|-|-|1|-|Wis 10:10-14|Matt 18:1-5
+2038-08-28|3|r|St. Augustine|Saturday_after_X_Sunday_after_Pentecost|St. Hermes|-|1|sancti:08-28cc:4:r|2 Tim 4:1-8|Matt 5:13-19
+2038-08-29|2|g|XI Sunday after Pentecost|-|-|Beheading of St. John the Baptist;St. Sabina|1|-|1 Cor. 15:1-10|Mark 7:31-37
+2038-08-30|3|r|St. Rose of Lima|Feria_II_after_XI_Sunday_after_Pentecost|Sts. Felix and Adauctus|-|1|sancti:08-30o:4:r|2 Cor 10:17-18; 11:1-2|Matt 25:1-13.
+2038-08-31|3|w|St. Raymond Nonnatus|Feria_III_after_XI_Sunday_after_Pentecost|-|-|1|-|Sir 31:8-11|Luke 12:35-40
+2038-09-01|4|g|Feria|Feria_IV_after_XI_Sunday_after_Pentecost|St. Giles;Twelve Holy Brothers, Martyrs|-|1|sancti:09-01:4:w;sancti:09-01cc:4:r|1 Cor. 15:1-10|Mark 7:31-37
+2038-09-02|3|w|St. Stephen of Hungary|Feria_V_after_XI_Sunday_after_Pentecost|-|-|1|-|Sir 31:8-11|Luke 19:12-26
+2038-09-03|3|w|St. Pius X|Feria_VI_after_XI_Sunday_after_Pentecost|-|-|1|-|1 Thess. 2:2-8|John 21:15-17
+2038-09-04|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_XI_Sunday_after_Pentecost|-|-|1|-|Ecclus 24:14-16|Luke 11:27-28
+2038-09-05|2|g|XII Sunday after Pentecost|-|-|St. Lawrence Justinian|1|-|2 Cor. 3:4-9|Luke 10:23-37
+2038-09-06|4|g|Feria|Feria_II_after_XII_Sunday_after_Pentecost|-|-|1|-|2 Cor. 3:4-9|Luke 10:23-37
+2038-09-07|4|g|Feria|Feria_III_after_XII_Sunday_after_Pentecost|-|-|1|-|2 Cor. 3:4-9|Luke 10:23-37
+2038-09-08|2|w|Nativity of the Blessed Virgin Mary|Feria_IV_after_XII_Sunday_after_Pentecost|S. Hadriani|-|1|sancti:09-08cc:4:r|Prov 8:22-35|Matt 1:1-16
+2038-09-09|4|g|Feria|Feria_V_after_XII_Sunday_after_Pentecost|St. Gorgonius|-|1|sancti:09-09:4:r|2 Cor. 3:4-9|Luke 10:23-37
+2038-09-10|3|w|St. Nicholas of Tolentino|Feria_VI_after_XII_Sunday_after_Pentecost|-|-|1|-|1 Cor. 4:9-14|Luke 12:32-34
+2038-09-11|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_XII_Sunday_after_Pentecost|Sts. Protus & Hyacinth|-|1|sancti:09-11:4:r|Ecclus 24:14-16|Luke 11:27-28
+2038-09-12|2|g|XIII Sunday after Pentecost|-|-|Most Holy Name of Mary|1|-|Gal 3:16-22|Luke 17:11-19
+2038-09-13|4|g|Feria|Feria_II_after_XIII_Sunday_after_Pentecost|-|-|1|-|Gal 3:16-22|Luke 17:11-19
+2038-09-14|2|r|Exaltation of the Holy Cross|Feria_III_after_XIII_Sunday_after_Pentecost|-|-|1|-|Phil 2:5-11|John 12:31-36
+2038-09-15|2|w|Seven Sorrows of the Blessed Virgin Mary|Feria_IV_after_XIII_Sunday_after_Pentecost|S. Nicomedes|-|1|sancti:09-15cc:4:r|Judith 13:22; 13:25|John 19:25-27
+2038-09-16|3|r|Sts. Cornelius & Cyprian|Feria_V_after_XIII_Sunday_after_Pentecost|Sts. Euphemia, Lucy and Geminianus|-|1|sancti:09-16cc:4:r|Wis 3:1-8|Luke 21:9-19
+2038-09-17|4|g|Feria|Feria_VI_after_XIII_Sunday_after_Pentecost|Stigmata of St. Francis|-|1|sancti:09-17:4:w|Gal 3:16-22|Luke 17:11-19
+2038-09-18|3|w|St. Joseph of Cupertino|Saturday_after_XIII_Sunday_after_Pentecost|-|-|1|-|1 Cor 13:1-8|Matt 22:1-14
+2038-09-19|2|g|XIV Sunday after Pentecost|-|-|St. Januarius & Companions|1|-|Gal 5:16-24|Matt 6:24-33
+2038-09-20|4|g|Feria|Feria_II_after_XIV_Sunday_after_Pentecost|Sts. Eustace & Companions|-|1|sancti:09-20:4:r|Gal 5:16-24|Matt 6:24-33
+2038-09-21|2|r|St. Matthew|Feria_III_after_XIV_Sunday_after_Pentecost|-|-|1|-|Ezek 1:10-14|Matt 9:9-13
+2038-09-22|2|v|Ember Wednesday of September|-|St. Thomas of Villanova|St. Maurice and Companions, Martyrs|1|sancti:09-22:3:w|2 Esd. 8:1-10|Mark 9:16-28
+2038-09-23|3|r|St. Linus|Feria_V_after_XIV_Sunday_after_Pentecost|St. Thecla|-|1|sancti:09-23cc:4:r|1 Pet 5:1-4; 5:10-11.|Matt 16:13-19
+2038-09-24|2|v|Ember Friday of September|-|Our Lady of Ransom|-|1|sancti:09-24:4:w|Osee 14:2-10|Luke 7:36-50
+2038-09-25|2|v|Ember Saturday of September|-|-|-|1|-|Heb 9:2-12|Luke 13:6-17
+2038-09-26|2|g|XV Sunday after Pentecost|-|-|Sts. Cyprian & Justina|1|-|Gal 5:25-26; 6:1-10|Luke 7:11-16
+2038-09-27|3|r|Sts. Cosmas & Damian|Feria_II_after_XV_Sunday_after_Pentecost|-|-|1|-|Wis 5:16-20|Luke 6:17-23
+2038-09-28|3|r|St. Wenceslaus|Feria_III_after_XV_Sunday_after_Pentecost|-|-|1|-|Wis 10:10-14|Matt 10:34-42
+2038-09-29|1|w|Dedication of St. Michael the Archangel|Feria_IV_after_XV_Sunday_after_Pentecost|-|-|1|-|Rev 1:1-5|Matt 18:1-10
+2038-09-30|3|w|St. Jerome|Feria_V_after_XV_Sunday_after_Pentecost|-|-|1|-|2 Tim 4:1-8|Matt 5:13-19
+2038-10-01|4|g|Feria|Feria_VI_after_XV_Sunday_after_Pentecost|St. Remigius|-|1|sancti:10-01:4:w|Gal 5:25-26; 6:1-10|Luke 7:11-16
+2038-10-02|3|w|Holy Guardian Angels|Saturday_after_XV_Sunday_after_Pentecost|-|-|1|-|Exod 23:20-23|Matt 18:1-10
+2038-10-03|2|g|XVI Sunday after Pentecost|-|-|St. Theresa of the Infant Jesus|1|-|Eph 3:13-21|Luke 14:1-11
+2038-10-04|3|w|St. Francis of Assisi|Feria_II_after_XVI_Sunday_after_Pentecost|-|-|1|-|Gal 6:14-18|Matt 11:25-30
+2038-10-05|4|g|Feria|Feria_III_after_XVI_Sunday_after_Pentecost|St. Placid & Companions|-|1|sancti:10-05:4:r|Eph 3:13-21|Luke 14:1-11
+2038-10-06|3|w|St. Bruno|Feria_IV_after_XVI_Sunday_after_Pentecost|-|-|1|-|Sir 31:8-11|Luke 12:35-40
+2038-10-07|2|w|Our Lady of the Rosary|Feria_V_after_XVI_Sunday_after_Pentecost|St. Mark I|-|1|sancti:10-07t:4:r|Prov 8:22-24, 32-35.|Luke 1:26-38
+2038-10-08|3|w|St. Bridget of Sweden|Feria_VI_after_XVI_Sunday_after_Pentecost|Ss. Sergio, Baccho, Marcello and Apulejo Martyrs|-|1|sancti:10-08c:4:r|1 Tim. 5:3-10.|Matt 13:44-52.
+2038-10-09|3|w|St. John Leonardi|Saturday_after_XVI_Sunday_after_Pentecost|St. Dionysius and companions|-|1|sancti:10-09t:4:r|2 Cor 4:1-6; 4:15-18|Luke 10:1-9
+2038-10-10|2|g|XVII Sunday after Pentecost|-|-|St. Francis Borgia|1|-|Eph 4:1-6|Matt 22:34-46
+2038-10-11|2|w|Maternity of the Blessed Virgin Mary|Feria_II_after_XVII_Sunday_after_Pentecost|-|-|1|-|Sir 24:23-31|Luke 2:43-51
+2038-10-12|4|g|Feria|Feria_III_after_XVII_Sunday_after_Pentecost|-|-|1|-|Eph 4:1-6|Matt 22:34-46
+2038-10-13|3|w|St. Edward|Feria_IV_after_XVII_Sunday_after_Pentecost|-|-|1|-|Sir 31:8-11|Luke 12:35-40
+2038-10-14|3|r|St. Callistus I|Feria_V_after_XVII_Sunday_after_Pentecost|-|-|1|-|1 Pet 5:1-4; 5:10-11.|Matt 16:13-19
+2038-10-15|3|w|St. Teresa of Avila|Feria_VI_after_XVII_Sunday_after_Pentecost|-|-|1|-|2 Cor 10:17-18; 11:1-2|Matt 25:1-13.
+2038-10-16|3|w|St. Hedwig|Saturday_after_XVII_Sunday_after_Pentecost|-|-|1|-|Prov 31:10-31|Matt 13:44-52.
+2038-10-17|2|g|XVIII Sunday after Pentecost|-|-|St. Margaret Mary Alacoque|1|-|1 Cor. 1:4-8|Matt 9:1-8
+2038-10-18|2|r|St. Luke the Evangelist|Feria_II_after_XVIII_Sunday_after_Pentecost|-|-|1|-|2 Cor. 8:16-24|Luke 10:1-9
+2038-10-19|3|w|St. Peter of Alcantara|Feria_III_after_XVIII_Sunday_after_Pentecost|-|-|1|-|Phil 3:7-12|Luke 12:32-34
+2038-10-20|3|w|St. John Cantius|Feria_IV_after_XVIII_Sunday_after_Pentecost|-|-|1|-|James 2:12-17|Luke 12:35-40
+2038-10-21|4|g|Feria|Feria_V_after_XVIII_Sunday_after_Pentecost|St. Hilarion;St. Ursula and Companions|-|1|sancti:10-21:4:w;sancti:10-21cc:4:r|1 Cor. 1:4-8|Matt 9:1-8
+2038-10-22|4|g|Feria|Feria_VI_after_XVIII_Sunday_after_Pentecost|-|-|1|-|1 Cor. 1:4-8|Matt 9:1-8
+2038-10-23|3|w|St. Anthony Mary Claret|Saturday_after_XVIII_Sunday_after_Pentecost|-|-|1|-|Heb 7:23-27|Matt 24:42-47
+2038-10-24|2|g|XIX Sunday after Pentecost|-|-|St. Raphael the Archangel|1|-|Eph 4:23-28|Matt 22:1-14
+2038-10-25|4|g|Feria|Feria_II_after_XIX_Sunday_after_Pentecost|Sts. Chrysanthus & Daria|-|1|sancti:10-25:4:r|Eph 4:23-28|Matt 22:1-14
+2038-10-26|4|g|Feria|Feria_III_after_XIX_Sunday_after_Pentecost|St. Evaristus|-|1|sancti:10-26:4:r|Eph 4:23-28|Matt 22:1-14
+2038-10-27|4|g|Feria|Feria_IV_after_XIX_Sunday_after_Pentecost|-|-|1|-|Eph 4:23-28|Matt 22:1-14
+2038-10-28|2|r|Sts. Simon & Jude|Feria_V_after_XIX_Sunday_after_Pentecost|-|-|1|-|Eph. 4:7-13.|John 15:17-25
+2038-10-29|4|g|Feria|Feria_VI_after_XIX_Sunday_after_Pentecost|-|-|1|-|Eph 4:23-28|Matt 22:1-14
+2038-10-30|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_XIX_Sunday_after_Pentecost|-|-|1|-|Ecclus 24:14-16|Luke 11:27-28
+2038-10-31|1|w|Christ the King|XX_Sunday_after_Pentecost|-|-|1|-|Col 1:12-20.|John 18:33-37
+2038-11-01|1|w|All Saints|Feria_II_after_XX_Sunday_after_Pentecost|-|-|1|-|Apoc 7:2-12|Matt 5:1-12
+2038-11-02|1|b|Commemoration of All Souls|Feria_III_after_XX_Sunday_after_Pentecost|-|-|3|-|1 Cor. 15:51-57|John 5:25-29
+2038-11-03|4|g|Feria|Feria_IV_after_XX_Sunday_after_Pentecost|-|-|1|-|Eph 5:15-21|John 4:46-53
+2038-11-04|3|w|St. Charles Borromeo|Feria_V_after_XX_Sunday_after_Pentecost|Sts. Vitalis and Agricola, Martyrs|-|1|sancti:11-04cc:4:r|Sir 44:16-27; 45:3-20|Matt 25:14-23
+2038-11-05|4|g|Feria|Feria_VI_after_XX_Sunday_after_Pentecost|-|-|1|-|Eph 5:15-21|John 4:46-53
+2038-11-06|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_XX_Sunday_after_Pentecost|-|-|1|-|Ecclus 24:14-16|Luke 11:27-28
+2038-11-07|2|g|XXI Sunday after Pentecost|-|-|-|1|-|Eph 6:10-17|Matt 18:23-35
+2038-11-08|4|g|Feria|Feria_II_after_XXI_Sunday_after_Pentecost|Four Holy Crowned Martyrs|-|1|sancti:11-08r:4:r|Eph 6:10-17|Matt 18:23-35
+2038-11-09|2|w|Dedication of the Archbasilica of Our Holy Savior|Feria_III_after_XXI_Sunday_after_Pentecost|St. Theodore|-|1|sancti:11-09cc:4:r|Rev 21:2-5|Luke 19:1-10
+2038-11-10|3|w|St. Andrew Avellino|Feria_IV_after_XXI_Sunday_after_Pentecost|Sts. Tryphonis, Respicii, et Nymphae|-|1|sancti:11-10o:4:r|Sir 31:8-11|Luke 12:35-40
+2038-11-11|3|w|St. Martin of Tours|Feria_V_after_XXI_Sunday_after_Pentecost|St. Menna|-|1|sancti:11-11cc:4:r|Sir 44:16-27; 45:3-20|Luke 11:33-36
+2038-11-12|3|r|St. Martin I|Feria_VI_after_XXI_Sunday_after_Pentecost|-|-|1|-|1 Pet 5:1-4; 5:10-11.|Matt 16:13-19
+2038-11-13|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_XXI_Sunday_after_Pentecost|St. Didacus|-|1|sancti:11-13:4:w|Ecclus 24:14-16|Luke 11:27-28
+2038-11-14|2|g|XXII Sunday after Pentecost|-|-|St. Josaphat|1|-|Phil 1:6-11|Matt 22:15-21
+2038-11-15|3|w|St. Albert the Great|Feria_II_after_XXII_Sunday_after_Pentecost|-|-|1|-|2 Tim 4:1-8|Matt 5:13-19
+2038-11-16|3|w|St. Gertrude the Great|Feria_III_after_XXII_Sunday_after_Pentecost|-|-|1|-|2 Cor 10:17-18; 11:1-2|Matt 25:1-13.
+2038-11-17|3|w|St. Gregory the Wonderworker|Feria_IV_after_XXII_Sunday_after_Pentecost|-|-|1|-|Sir 44:16-27; 45:3-20|Mark 11:22-24
+2038-11-18|3|w|Dedication of the Basilicas of Sts. Peter & Paul|Feria_V_after_XXII_Sunday_after_Pentecost|-|-|1|-|Rev 21:2-5|Luke 19:1-10
+2038-11-19|3|w|St. Elizabeth of Hungary|Feria_VI_after_XXII_Sunday_after_Pentecost|St. Pontian|-|1|sancti:11-19o:4:r|Prov 31:10-31|Matt 13:44-52.
+2038-11-20|3|w|St. Felix of Valois|Saturday_after_XXII_Sunday_after_Pentecost|-|-|1|-|1 Cor. 4:9-14|Luke 12:32-34
+2038-11-21|2|g|XXIV Sunday after Pentecost|-|-|Presentation of the Blessed Virgin Mary|1|-|Col 1:9-14|Matt 24:15-35
+2038-11-22|3|r|St. Cecilia|Feria_II_after_XXIV_Sunday_after_Pentecost|-|-|1|-|Sir 51:13-17.|Matt 25:1-13.
+2038-11-23|3|r|St. Clement I|Feria_III_after_XXIV_Sunday_after_Pentecost|St. Felicity|-|1|sancti:11-23cc:4:r|Phil 3:17-21; 4:1-3|Matt 16:13-19
+2038-11-24|3|w|St. John of the Cross|Feria_IV_after_XXIV_Sunday_after_Pentecost|St. Chrysogonus|-|1|sancti:11-24o:4:r|2 Tim 4:1-8|Matt 5:13-19
+2038-11-25|3|r|St. Catherine of Alexandria|Feria_V_after_XXIV_Sunday_after_Pentecost|-|-|1|-|Sir 51:1-8; 51:12|Matt 25:1-13.
+2038-11-26|3|w|St. Sylvester|Feria_VI_after_XXIV_Sunday_after_Pentecost|St. Peter of Alexandria|-|1|sancti:11-26t:4:r|Ecclus 45:1-6|Matt 19:27-29.
+2038-11-27|4|w|V Mass of the B. V. M. – Salve, Sancta Parens|Saturday_after_XXIV_Sunday_after_Pentecost|-|-|1|-|Ecclus 24:14-16|Luke 11:27-28
+2038-11-28|1|v|I Sunday of Advent|-|-|-|1|-|Rom 13:11-14|Luke 21:25-33
+2038-11-29|3|v|Feria II after I Sunday of Advent|-|St. Saturninus|-|1|sancti:11-29r:4:r|Rom 13:11-14|Luke 21:25-33
+2038-11-30|2|r|St. Andrew|Feria_III_after_I_Sunday_of_Advent|-|-|1|-|Rom 10:10-18|Matt 4:18-22
+2038-12-01|3|v|Feria IV after I Sunday of Advent|-|-|-|1|-|Rom 13:11-14|Luke 21:25-33
+2038-12-02|3|r|St. Vivian|Feria_V_after_I_Sunday_of_Advent|Feria V after I Sunday of Advent|-|1|tempora:Adv1-4:3:v|Sir 51:13-17.|Matt 13:44-52.
+2038-12-03|3|w|St. Francis Xavier|Feria_VI_after_I_Sunday_of_Advent|Feria VI after I Sunday of Advent|-|1|tempora:Adv1-5:3:v|Rom 10:10-18|Mark 16:15-18
+2038-12-04|3|w|St. Peter Chrysologus|Sabbato_after_I_Sunday_of_Advent|Sabbato after I Sunday of Advent|-|1|tempora:Adv1-6:3:v|2 Tim 4:1-8|Matt 5:13-19
+2038-12-05|1|v|II Sunday of Advent|-|-|St. Sabbas|1|-|Rom 15:4-13|Matt 11:2-10
+2038-12-06|3|w|St. Nicholas|Feria_II_after_II_Sunday_of_Advent|Feria II after II Sunday of Advent|-|1|tempora:Adv2-1:3:v|Heb 13:7-17|Matt 25:14-23
+2038-12-07|3|w|St. Ambrose|Feria_III_after_II_Sunday_of_Advent|Feria III after II Sunday of Advent|-|1|tempora:Adv2-2:3:v|2 Tim 4:1-8|Matt 5:13-19
+2038-12-08|1|w|Immaculate Conception of the Blessed Virgin Mary|Feria_IV_after_II_Sunday_of_Advent|-|-|1|-|Prov 8:22-35|Luke 1:26-28
+2038-12-09|3|v|Feria V after II Sunday of Advent|-|-|-|1|-|Rom 15:4-13|Matt 11:2-10
+2038-12-10|3|v|Feria VI after II Sunday of Advent|-|St. Melchiades|-|1|sancti:12-10o:4:r|Rom 15:4-13|Matt 11:2-10
+2038-12-11|3|w|St. Damasus I|Sabbato_after_II_Sunday_of_Advent|Sabbato after II Sunday of Advent|-|1|tempora:Adv2-6:3:v|1 Pet 5:1-4; 5:10-11.|Matt 16:13-19
+2038-12-12|1|pv|III Sunday of Advent|-|-|-|1|-|Phil 4:4-7|John 1:19-28
+2038-12-13|3|r|St. Lucy|Feria_II_after_III_Sunday_of_Advent|Feria II after III Sunday of Advent|-|1|tempora:Adv3-1:3:v|2 Cor 10:17-18; 11:1-2|Matt 13:44-52.
+2038-12-14|3|pv|Feria III after III Sunday of Advent|-|-|-|1|-|Phil 4:4-7|John 1:19-28
+2038-12-15|2|v|Ember Wednesday of Advent|-|-|-|1|-|Isa 7:10-15|Luke 1:26-38
+2038-12-16|3|r|St. Eusebius|Feria_V_after_III_Sunday_of_Advent|Feria V after III Sunday of Advent|-|1|tempora:Adv3-4:3:v|2 Cor. 1:3-7|Matt 16:24-27.
+2038-12-17|2|v|Ember Friday of Advent|-|-|-|1|-|Isa 11:1-5|Luke 1:39-47
+2038-12-18|2|v|Ember Saturday of Advent|-|-|-|1|-|2 Thess. 2:1-8|Luke 3:1-6
+2038-12-19|1|v|IV Sunday of Advent|-|-|-|1|-|1 Cor. 4:1-5|Luke 3:1-6
+2038-12-20|2|v|Feria II after IV Sunday of Advent|-|-|-|1|-|1 Cor. 4:1-5|Luke 3:1-6
+2038-12-21|2|r|St. Thomas|Feria_III_after_IV_Sunday_of_Advent|Feria III after IV Sunday of Advent|-|1|tempora:Adv4-2:2:v|Eph 2:19-22|John 20:24-29
+2038-12-22|2|v|Feria IV after IV Sunday of Advent|-|-|-|1|-|1 Cor. 4:1-5|Luke 3:1-6
+2038-12-23|2|v|Feria V after IV Sunday of Advent|-|-|-|1|-|1 Cor. 4:1-5|Luke 3:1-6
+2038-12-24|1|v|Vigil of Christmas|-|-|-|1|-|Rom 1:1-6|Matt 1:18-21
+2038-12-25|1|w|The Nativity of Our Lord|-|-|-|3|-|Titus 2:11-15|Luke 2:1-14
+2038-12-26|2|w|Sunday in the Octave of Christmas|-|St. Stephen|For Octave of the Nativity|1|sancti:12-26:2:r|Gal 4:1-7|Luke 2:33-40
+2038-12-27|2|w|St. John the Evangelist|-|For Octave of the Nativity|-|1|sancti:12-27c:4:w|Ecclus 15:1-6|John 21:19-24
+2038-12-28|2|r|Holy Innocents|-|For Octave of the Nativity|-|1|sancti:12-28c:4:w|Apoc 14:1-5|Matt 2:13-18
+2038-12-29|2|w|Feria in the Octave of Christmas|-|St. Thomas Becket|-|1|sancti:12-29:4:r|Titus 3:4-7|Luke 2:15-20
+2038-12-30|2|w|Feria in the Octave of Christmas|-|-|-|1|-|Titus 3:4-7|Luke 2:15-20
+2038-12-31|2|w|Feria in the Octave of Christmas|-|St. Silvester|-|1|sancti:12-31:4:w|Titus 3:4-7|Luke 2:15-20
diff --git a/test/test_colitur.ml b/test/test_colitur.ml
index db2d41c..c6cca8f 100644
--- a/test/test_colitur.ml
+++ b/test/test_colitur.ml
@@ -4,6 +4,6 @@ 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_oracle.suite; Test_golden.suite;
+ Test_differential.suite; Test_oracle.suite; Test_oracle.suite_2038; Test_golden.suite;
("lectionary", Test_lectionary.suite);
("lectionary-ef", Test_lectionary_ef.suite) ]
diff --git a/test/test_oracle.ml b/test/test_oracle.ml
index 2d7060b..656a437 100644
--- a/test/test_oracle.ml
+++ b/test/test_oracle.ml
@@ -377,18 +377,25 @@ let colour_to_char = function
let en = Lang.of_string_exn "en"
-let colitur_rows_2026_2027 () =
+(* Parameterised by year (the 2038 oracle extension, 2026-08-17): this used
+ to be [colitur_rows_2026_2027], hardcoded to the one fixture window. The
+ resolution walk starts a year EARLY -- [from_year - 1] -- because a
+ liturgical year is Advent-anchored and straddles two civil years, so
+ 1 January of [from_year] belongs to the liturgical year that opened the
+ previous November (calendar.mli, and bin/main.ml's own [day_report] does
+ exactly the same for the same reason). *)
+let colitur_rows ~from_year ~to_year =
let layer = real_layer () in
let rite = Rite_ef.context ~lectionary:(real_lectionary ()) ~commons:(real_commons ()) in
let by_rata : (int, (V.season, V.rank) LD.t) Hashtbl.t = Hashtbl.create 800 in
- for y = 2025 to 2027 do
+ for y = from_year - 1 to to_year do
let days = Cal.year rite layer y in
Array.iter (fun (d : (V.season, V.rank) LD.t) -> Hashtbl.replace by_rata (Date.to_rata d.LD.date) d) days
done;
let mk y m d = match Date.make ~year:y ~month:m ~day:d with Ok t -> t | Error e -> failwith e in
let rows = ref [] in
- let d = ref (mk 2026 1 1) in
- let stop = mk 2027 12 31 in
+ let d = ref (mk from_year 1 1) in
+ let stop = mk to_year 12 31 in
while Date.compare !d stop <= 0 do
(match Hashtbl.find_opt by_rata (Date.to_rata !d) with
| Some day ->
@@ -1476,7 +1483,7 @@ 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
+ let colitur = colitur_rows ~from_year:2026 ~to_year:2027 in
(oracle, colitur)
let classify oracle colitur =
@@ -1714,3 +1721,210 @@ let suite =
"identity corroboration: matched titles' oracle id-rank agrees with colitur's own rank" `Quick
test_identity_rank_corroboration
] )
+
+(* ====================================================================== *)
+(* The 2038 oracle extension (2026-08-17) *)
+(* ====================================================================== *)
+
+(* A SECOND, INDEPENDENT oracle year, deliberately kept apart from the
+ 2026-2027 comparison above rather than folded into it.
+
+ WHY 2038. Register §6.7 recorded that step 4 of the reading chain -- the
+ Common route -- had no external witness at all. Only five saints route
+ through a Common, and across 2005-2050 they are the OBSERVED office on
+ five days total; not one falls in the 2026-2027 window. 2038 is the year
+ covering TWO of the five at once (`sts-felicitas-perpetua` 6 March,
+ `frances-rome` 9 March), which is why it and not 2035 or 2046.
+
+ WHY SEPARATE. This fixture is a LIVE capture of missalemeum, where the
+ 2026-2027 one is derived from lectio's archived snapshot, and
+ docs/research/sources.md already records that the live endpoint HAS
+ DRIFTED from that snapshot. Merging them would put two versions of the
+ same source behind one set of expectations, and a future disagreement
+ could not be attributed to either the calendar or the drift.
+
+ WHY A NARROWER COMPARISON. This compares rank, colour, and the two
+ reading citations -- NOT commemorations or observed-identity. Those axes
+ are worth having, but the machinery above that implements them is built
+ around a hand-built, date-literal allow-list of 28 entries specific to
+ 2026-2027, and re-deriving an equivalent for a second year is its own
+ task. What is asserted here is asserted fully; what is not compared is
+ named, here, rather than left to be discovered. *)
+
+let fixture_2038_path = "fixtures/missalemeum-ef-2038.txt"
+let fixture_2038_sha256 = "2ac17136be5f6a831bb115ab62f0bb993f69973fdd847d269b43915746ef2151"
+
+(* Citation notation differs between the two sources in ways that are not
+ calendar disagreements at all: book abbreviations ("Ecclus"/"Sir",
+ "Joann"/"John", "Luc"/"Luke") and punctuation of the same verse range.
+ Layer 3 normalises the same way and for the same reason
+ (test_differential.ml's own A/B normalisation). Normalising here keeps
+ this comparison about WHICH VERSES, which is the thing under test. *)
+let norm_citation s =
+ let s = String.lowercase_ascii s in
+ (* Each pair maps the LONGER/rarer spelling onto the shorter one used by
+ the other side. Checked for self-collision: no replacement's target
+ contains its own source as a substring ("luke" does not contain "luc",
+ "mark" does not contain "marc"), so applying them is idempotent and
+ order-independent. Every entry here was added because a real 2038 row
+ needed it, never speculatively. *)
+ let subst =
+ [ ("ecclus", "sir"); ("eccli", "sir"); ("joann", "john"); ("matth", "matt");
+ ("luc", "luke"); ("marc", "mark") ]
+ in
+ let s = List.fold_left (fun acc (a, b) ->
+ let bl = String.length a in
+ let buf = Buffer.create (String.length acc) in
+ let i = ref 0 in
+ while !i < String.length acc do
+ if !i + bl <= String.length acc && String.sub acc !i bl = a then begin
+ Buffer.add_string buf b; i := !i + bl end
+ else begin Buffer.add_char buf acc.[!i]; incr i end
+ done;
+ Buffer.contents buf) s subst
+ in
+ String.to_seq s
+ |> Seq.filter (fun ch -> (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9'))
+ |> String.of_seq
+
+(* Every 2038 divergence class, each pointing at where it is adjudicated.
+ These are NOT new rulings: all six were already decided, and 2038 is an
+ independent year re-confirming them. The counts are pinned so a change in
+ any class fails loudly. *)
+let m21_2038_slugs = m21_colour_slugs
+
+let classify_2038 (c : colitur_row) (o : oracle_row) diffs =
+ let title = o.o_title in
+ let contains hay needle =
+ let nh = String.length needle and lh = String.length hay in
+ let rec at i = i + nh <= lh && (String.sub hay i nh = needle || at (i + 1)) in
+ nh = 0 || at 0
+ in
+ let first_is s = match c.c_first with Some f -> contains f s | None -> false in
+ if contains title "Mass of the B. V. M." then Some "BVM-SATURDAY-MASS (M26 shape 1)"
+ else if first_is "Col 1:12-20" then Some "CHRIST-THE-KING-WEEK (M26 shape 2b)"
+ else if diffs = [ Colour_f ] && List.mem c.c_observed_slug m21_2038_slugs then Some "COLOUR (M21)"
+ else if first_is "Judith" then Some "JUDITH (M28, register 6.6)"
+ else if c.c_observed_slug = "sts-felicitas-perpetua" then Some "PERPETUA-COMMON (register 6.8)"
+ else if c.c_observed_slug = "ef-nativity" then Some "CHRISTMAS-MULTI-MASS (M27)"
+ else if first_is "Dan 14:27, 28-42" then Some "MISSAL-TWO-PART-CITATION (register 6.9)"
+ else None
+
+let diffs_2038 (c : colitur_row) (o : oracle_row) =
+ let d = ref [] in
+ if c.c_rank <> o.o_rank then d := Rank :: !d;
+ if not (List.mem c.c_colour o.o_colours) then d := Colour_f :: !d;
+ (match (c.c_first, o.o_first) with
+ | Some a, Some b when norm_citation a <> norm_citation b -> d := First_mismatch :: !d
+ | _ -> ());
+ (match (c.c_gospel, o.o_gospel) with
+ | Some a, Some b when norm_citation a <> norm_citation b -> d := Gospel_mismatch :: !d
+ | _ -> ());
+ List.rev !d
+
+let compare_2038 () =
+ let oracle = List.map oracle_row_of_line (read_lines fixture_2038_path) in
+ let colitur = colitur_rows ~from_year:2038 ~to_year:2038 in
+ let by_date = Hashtbl.create 400 in
+ List.iter (fun (c : colitur_row) -> Hashtbl.replace by_date c.c_date c) colitur;
+ List.filter_map
+ (fun (o : oracle_row) ->
+ match Hashtbl.find_opt by_date o.o_date with
+ | None -> None
+ | Some c ->
+ let diffs = diffs_2038 c o in
+ if diffs = [] then None else Some (o.o_date, diffs, classify_2038 c o diffs, c, o))
+ oracle
+
+let test_2038_fixture_checksum () =
+ Alcotest.(check string) "2038 fixture SHA-256 matches its provenance note" fixture_2038_sha256
+ (sha256_of_file fixture_2038_path)
+
+let test_2038_dates_align () =
+ let oracle = List.map oracle_row_of_line (read_lines fixture_2038_path) in
+ let colitur = colitur_rows ~from_year:2038 ~to_year:2038 in
+ Alcotest.(check int) "oracle is 365 rows" 365 (List.length oracle);
+ Alcotest.(check int) "colitur is 365 rows" 365 (List.length colitur);
+ Alcotest.(check (list string)) "dates align 1:1"
+ (List.map (fun (o : oracle_row) -> o.o_date) oracle)
+ (List.map (fun (c : colitur_row) -> c.c_date) colitur)
+
+let test_2038_every_difference_is_classified () =
+ let unexplained =
+ compare_2038 ()
+ |> List.filter_map (fun (date, diffs, cls, c, o) ->
+ match cls with
+ | Some _ -> None
+ | None ->
+ Some
+ (Printf.sprintf "%s: %s -- colitur=(%s rank=%d colour=%c first=%s) oracle=(%s rank=%d first=%s)"
+ date
+ (String.concat "," (List.map field_name diffs))
+ c.c_observed_slug c.c_rank c.c_colour
+ (Option.value c.c_first ~default:"-")
+ o.o_title o.o_rank
+ (Option.value o.o_first ~default:"-")))
+ in
+ Alcotest.(check (list string)) "every 2038 difference falls in a named, adjudicated class" []
+ unexplained
+
+let test_2038_class_counts () =
+ let tbl = Hashtbl.create 8 in
+ List.iter
+ (fun (_, _, cls, _, _) ->
+ match cls with
+ | Some k -> Hashtbl.replace tbl k (1 + Option.value (Hashtbl.find_opt tbl k) ~default:0)
+ | None -> ())
+ (compare_2038 ());
+ let actual = Hashtbl.fold (fun k n acc -> (k, n) :: acc) tbl [] |> List.sort compare in
+ (* Measured 2026-08-17 against the live capture this fixture pins. Each
+ class is adjudicated elsewhere and merely RE-CONFIRMED here, in a year
+ entirely independent of the one those rulings were made in. *)
+ let expected =
+ [ ("BVM-SATURDAY-MASS (M26 shape 1)", 13);
+ ("CHRIST-THE-KING-WEEK (M26 shape 2b)", 2);
+ ("CHRISTMAS-MULTI-MASS (M27)", 1);
+ ("COLOUR (M21)", 7);
+ ("JUDITH (M28, register 6.6)", 2);
+ ("MISSAL-TWO-PART-CITATION (register 6.9)", 1);
+ ("PERPETUA-COMMON (register 6.8)", 1)
+ ]
+ |> List.sort compare
+ in
+ Alcotest.(check (list (pair string int))) "2038 divergence classes and their counts" expected actual
+
+(* The point of the whole exercise: 2038 is the only year in 2005-2050 where
+ a Common-routed saint is the observed office AND an oracle exists for it.
+ Both days are asserted directly, by date, so a regression in step 4 cannot
+ hide inside an aggregate count. Perpetua is a KNOWN divergence (register
+ §6.8 -- missalemeum has the two martyrs classified as Virgins and serves
+ the Virgins Common; the Missal directs "de Communi non Virginum I loco",
+ scan1:27634-27635); Frances of Rome must MATCH outright. *)
+let test_2038_common_route_days () =
+ let rows = compare_2038 () in
+ let diff_for d = List.find_opt (fun (date, _, _, _, _) -> date = d) rows in
+ (match diff_for "2038-03-09" with
+ | None -> ()
+ | Some (_, diffs, _, c, o) ->
+ Alcotest.failf "2038-03-09 (frances-rome, Common of Non-Virgins II) should agree: %s (colitur first=%s, oracle first=%s, oracle title=%s)"
+ (String.concat "," (List.map field_name diffs))
+ (Option.value c.c_first ~default:"-")
+ (Option.value o.o_first ~default:"-")
+ o.o_title);
+ match diff_for "2038-03-06" with
+ | Some (_, _, Some cls, _, _) ->
+ Alcotest.(check string) "2038-03-06 is the adjudicated Perpetua divergence"
+ "PERPETUA-COMMON (register 6.8)" cls
+ | _ -> Alcotest.fail "2038-03-06 was expected to differ (register §6.8) and did not"
+
+let suite_2038 =
+ ( "oracle (missalemeum, EF, 2038 -- the Common route)",
+ [ Alcotest.test_case "2038 fixture SHA-256 matches its provenance note" `Quick
+ test_2038_fixture_checksum;
+ Alcotest.test_case "streams are 365 rows each, dates aligned 1:1" `Quick test_2038_dates_align;
+ Alcotest.test_case "every difference falls in a named, adjudicated class" `Quick
+ test_2038_every_difference_is_classified;
+ Alcotest.test_case "divergence classes and their counts are pinned" `Quick test_2038_class_counts;
+ Alcotest.test_case "the two Common-route days: Frances agrees, Perpetua is the known divergence"
+ `Quick test_2038_common_route_days
+ ] )
diff --git a/tools/extract_missalemeum_oracle.py b/tools/extract_missalemeum_oracle.py
index 1abc574..6d3f8f0 100644
--- a/tools/extract_missalemeum_oracle.py
+++ b/tools/extract_missalemeum_oracle.py
@@ -111,10 +111,19 @@ def extract_citation(sections, section_id, date, label):
def main():
- if len(sys.argv) != 3:
- print(f"usage: {sys.argv[0]} <snapshot-dir> <out-file>", file=sys.stderr)
+ # <expected-days> (added 2026-08-17, the 2038 oracle extension) is the
+ # number of day-files this run MUST produce, stated by the caller rather
+ # than hardcoded. It used to be a bare `!= 730`, which silently forbade
+ # extracting any window other than the original 2026-2027 pair. It stays
+ # MANDATORY-in-effect via its default so the existing documented command
+ # keeps its own guard unchanged: a partial fetch (a dropped HTTP request,
+ # an interrupted unpack) must fail loudly here rather than quietly
+ # produce a short fixture that then "passes" a comparison it never ran.
+ if len(sys.argv) not in (3, 4):
+ print(f"usage: {sys.argv[0]} <snapshot-dir> <out-file> [expected-days]", file=sys.stderr)
return 2
snapshot_dir, out_path = sys.argv[1], sys.argv[2]
+ expected_days = int(sys.argv[3]) if len(sys.argv) == 4 else 730
src = os.path.join(snapshot_dir, "missalemeum", "en")
rows = []
for fname in sorted(os.listdir(src)):
@@ -153,8 +162,8 @@ def main():
f"|{cit_first}|{cit_gospel}"
)
- if len(rows) != 730:
- print(f"ERROR: expected 730 days, got {len(rows)}", file=sys.stderr)
+ if len(rows) != expected_days:
+ print(f"ERROR: expected {expected_days} days, got {len(rows)}", file=sys.stderr)
return 1
with open(out_path, "w", encoding="utf-8") as f: