From b7036edb35ef676ce655127100e4f778ebcf041a Mon Sep 17 00:00:00 2001 From: Will Estes Date: Wed, 26 Aug 2026 08:52:41 -0400 Subject: [PATCH] Confirm Vigils are ferial-by-design; author Common-of-the-BVM Lauds/Vespers bundle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Finished the "ferial/other" audit bucket via each saint's own source file. Vigils (9 saints) are not a gap at all: every vigil's own [Rule] explicitly says "Responsory Feria"/"Versum Feria" -- deliberate rubric, matching this app's existing isFerialOrVigil convention. Even the "ex C1v" tag on the 6 apostle vigils resolves to the same plain ferial text when live-queried, confirming no override applies to the Lauds/Vespers bundle for any vigil. Common-of-the-BVM (5 feasts) is a real category: each source file says plain "ex C11"/"vide C11". Live-verified votive=C11: chapter Sir 24:14, Lauds hymn "O gloriósa Dómina" (the same pre-Urban-VIII text as the Annunciation's own separate proper), Vespers hymn "Ave maris stella," same responsory at both hours, distinct versicles per hour. Surfaced one masked collision: the Annunciation now resolves through this Common instead of the ferial default (real improvement, still interim until its own proper content is imported). Moved the Passiontide-seasonal-office Vespers test off its date (Mar 25) onto the clean Mar 30. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc --- TODO.md | 33 +++++ .../lauds-capitulum-common-of-the-bvm.yml | 19 +++ .../common/lauds-hymn-common-of-the-bvm.yml | 81 +++++++++++ .../lauds-responsory-common-of-the-bvm.yml | 24 ++++ .../lauds-versicle-common-of-the-bvm.yml | 15 ++ .../common/vespers-hymn-common-of-the-bvm.yml | 135 ++++++++++++++++++ .../vespers-responsory-common-of-the-bvm.yml | 23 +++ .../vespers-versicle-common-of-the-bvm.yml | 14 ++ tests/hours/lauds.test.ts | 12 ++ tests/hours/vespers.test.ts | 20 ++- 10 files changed, 373 insertions(+), 3 deletions(-) create mode 100644 src/data/propers/common/lauds-capitulum-common-of-the-bvm.yml create mode 100644 src/data/propers/common/lauds-hymn-common-of-the-bvm.yml create mode 100644 src/data/propers/common/lauds-responsory-common-of-the-bvm.yml create mode 100644 src/data/propers/common/lauds-versicle-common-of-the-bvm.yml create mode 100644 src/data/propers/common/vespers-hymn-common-of-the-bvm.yml create mode 100644 src/data/propers/common/vespers-responsory-common-of-the-bvm.yml create mode 100644 src/data/propers/common/vespers-versicle-common-of-the-bvm.yml diff --git a/TODO.md b/TODO.md index 4327466..a6dba89 100644 --- a/TODO.md +++ b/TODO.md @@ -3037,6 +3037,39 @@ found to have their own real `ex Proprio Sanctorum` content (need per-saint impo category-level fix), plus Vigils and the remaining BVM feasts, not yet checked against their own source files. +### Vigils confirmed ferial-by-design (not a gap); Common-of-the-BVM authored (2026-08-26) + +Finished the "ferial/other" bucket, reading each saint's own source file (`[Rank]`/`[Rule]`) +directly rather than hunting per-saint clean years, per the methodology upgrade above. + +**Vigils (9 saints): not a gap at all.** Every vigil's own `[Rule]` explicitly says "Responsory +Feria" / "Versum Feria" — plain ferial content by deliberate rubric, live-confirmed on Vigil of +St. Lawrence's real day (2025-08-09, Simplex, un-outranked): genuinely `ex Psalterio secundum +diem`, not a masked gap. The 6 apostle vigils (James, Simon & Jude, Andrew, Bartholomew, +Thomas, Matthew) carry an "ex C1v" tag, but `votive=C1v` itself resolves to the same plain +ferial text — confirming C1v doesn't override the Lauds/Vespers bundle either. Matches this +app's own already-established `isFerialOrVigil` convention (`resolve-common.ts`). No content +authored, correctly. + +**Common-of-the-BVM (5 feasts: Apparition of the Immaculate BVM, Queenship, Our Lady of Mount +Carmel, Our Lady of Ransom, the Maternity): real category, authored.** Each one's own source +file says plain "ex C11"/"vide C11". Live-verified `votive=C11`: chapter Sir 24:14 ("Ab inítio +et ante sǽcula creáta sum"), Lauds hymn "O gloriósa Dómina" (same pre-Urban-VIII text already +found for the Annunciation's own separate proper — a real overlap, not a mix-up), Vespers hymn +"Ave maris stella", same responsory text at both hours (unusual for this session's categories — +every other one had distinct Lauds/Vespers responsories), distinct versicles per hour. + +One masked collision this surfaced: the Annunciation (Mar 25, `common: common-of-the-bvm`, +`propers: "annunciation"` — but no `lauds-capitulum-annunciation.yml` authored yet) now +resolves through this Common instead of falling through to Passiontide's seasonal default — +a real improvement, though still interim until Annunciation's own real Proprio content (already +found and queued in the individual-saints list) is imported and takes precedence over it. +Updated the Passiontide-seasonal-office Vespers test off Mar 25 onto the clean Mar 30. + +`npm test` (498 tests), `tsc --noEmit` both pass. This closes the "ferial/other" bucket +entirely. **Still open**: the ~31 individual saints with their own real `ex Proprio Sanctorum` +content, the actual next task. + ## Known, deliberate simplifications (not bugs — working as designed) - `getDayCollects`: each collect in a multi-collect day renders as its own diff --git a/src/data/propers/common/lauds-capitulum-common-of-the-bvm.yml b/src/data/propers/common/lauds-capitulum-common-of-the-bvm.yml new file mode 100644 index 0000000..b71a1ba --- /dev/null +++ b/src/data/propers/common/lauds-capitulum-common-of-the-bvm.yml @@ -0,0 +1,19 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617), Lauds +# `votive=C11` live query, 2026-08 -- read directly from the source +# first (Sancti/02-11.txt, 05-31.txt, 07-16.txt, 09-24.txt, 10-11.txt -- +# the 5 saints/feasts in this category, Apparition of the Immaculate +# BVM, Queenship, Our Lady of Mount Carmel, Our Lady of Ransom, and the +# Maternity), all of whose own `[Rank]`/`[Rule]` say plain "ex C11"/"vide +# C11", settling the votive number with no calendar dependency. Same +# chapter reused for Vespers -- no separate vespers-capitulum- file +# authored, per vespers.ts's vespersCapitulumForOverride fallback. +id: lauds-capitulum-common-of-the-bvm +text: + la: "Ab inítio et ante sǽcula creáta sum, et usque ad futúrum sǽculum non désinam, et in habitatióne sancta coram ipso ministrávi." + en: "From the beginning, and before the world, was I created, and unto the world to come I shall not cease to be, and in the holy dwelling place I have ministered before him." +citation: + la: "Sir 24:14" + en: "Sir 24:14" +status: + la: verified + en: verified diff --git a/src/data/propers/common/lauds-hymn-common-of-the-bvm.yml b/src/data/propers/common/lauds-hymn-common-of-the-bvm.yml new file mode 100644 index 0000000..184691d --- /dev/null +++ b/src/data/propers/common/lauds-hymn-common-of-the-bvm.yml @@ -0,0 +1,81 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617), Lauds +# `votive=C11` live query, 2026-08 -- see lauds-capitulum-common-of-the- +# bvm.yml's header. "O gloriósa Dómina" -- the same pre-Urban VIII hymn +# text already found for the Annunciation's own proper (a separate, +# individually-imported saint, not this Common) -- a real, confirmed +# overlap between the two, not a mix-up. +id: lauds-hymn-common-of-the-bvm +text: + la: >- + O gloriósa Dómina, + + Excélsa super sídera: + + Qui te creávit, próvide + + Lactásti sacro úbere. + + + Quod Heva tristis ábstulit, + + Tu reddis almo gérmine: + + Intrent ut astra flébiles, + + Cæli fenéstra facta es. + + + Tu Regis alti jánua, + + Et porta lucis fúlgida: + + Vitam datam per Vírginem, + + Gentes redémptæ, pláudite. + + + Glória tibi Dómine, + + Qui natus es de Vírgine, + + Cum Patre et Sancto Spíritu, + + In sempitérna sǽcula. Amen. + en: >- + O glorious lady! throned on high + + Above the star-illumined sky; + + Thereto ordained, thy bosom lent + + To thy Creator nourishment. + + + Through thy sweet offspring we receive + + The bliss once lost through hapless Eve; + + And heaven to mortals open lies + + Now thou art portal of the skies. + + + Thou art the door of heaven's high King, + + Light's gateway fair and glistering; + + Life through a Virgin is restored; + + Ye ransomed nations, praise the Lord! + + + All honour, laud, and glory be, + + O Jesu, Virgin-born, to thee; + + All glory, as is ever meet, + + To Father and to Paraclete. Amen. +status: + la: verified + en: verified diff --git a/src/data/propers/common/lauds-responsory-common-of-the-bvm.yml b/src/data/propers/common/lauds-responsory-common-of-the-bvm.yml new file mode 100644 index 0000000..4d377df --- /dev/null +++ b/src/data/propers/common/lauds-responsory-common-of-the-bvm.yml @@ -0,0 +1,24 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617), Lauds +# `votive=C11` live query, 2026-08 -- see lauds-capitulum-common-of-the- +# bvm.yml's header. Same responsory text as Vespers (unusual for this +# app's Common categories so far -- every other one so far had distinct +# Lauds/Vespers responsories). +id: lauds-responsory-common-of-the-bvm +text: + la: | + R.br. Ave María, grátia plena, * Dóminus tecum. + ℟. Ave María, grátia plena, * Dóminus tecum. + ℣. Benedícta tu in muliéribus, et benedíctus fructus ventris tui. + ℟. Dóminus tecum. + ℣. Glória Patri, et Fílio, * et Spirítui Sancto. + ℟. Ave María, grátia plena, * Dóminus tecum. + en: | + R.br. Hail Mary full of grace, * the Lord is with thee. + ℟. Hail Mary full of grace, * the Lord is with thee. + ℣. Blessed art thou among women, and blessed is the fruit of thy womb. + ℟. The Lord is with thee. + ℣. Glory be to the Father, and to the Son, * and to the Holy Ghost. + ℟. Hail Mary full of grace, * the Lord is with thee. +status: + la: verified + en: verified diff --git a/src/data/propers/common/lauds-versicle-common-of-the-bvm.yml b/src/data/propers/common/lauds-versicle-common-of-the-bvm.yml new file mode 100644 index 0000000..382008e --- /dev/null +++ b/src/data/propers/common/lauds-versicle-common-of-the-bvm.yml @@ -0,0 +1,15 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617), Lauds +# `votive=C11` live query, 2026-08 -- see lauds-capitulum-common-of-the- +# bvm.yml's header. Vespers has its own distinct versicle -- see +# vespers-versicle-common-of-the-bvm.yml. +id: lauds-versicle-common-of-the-bvm +text: + la: | + ℣. Diffúsa est grátia in lábiis tuis. + ℟. Proptérea benedíxit te Deus in ætérnum. + en: | + ℣. Grace is poured into thy lips. + ℟. Therefore God hath blessed thee for ever. +status: + la: verified + en: verified diff --git a/src/data/propers/common/vespers-hymn-common-of-the-bvm.yml b/src/data/propers/common/vespers-hymn-common-of-the-bvm.yml new file mode 100644 index 0000000..83fde8f --- /dev/null +++ b/src/data/propers/common/vespers-hymn-common-of-the-bvm.yml @@ -0,0 +1,135 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617), Vespers +# `votive=C11` live query, 2026-08 -- "Ave maris stella," the classic +# Common-of-the-BVM Vespers hymn, genuinely distinct from the Lauds hymn +# (unlike some other categories this session where the two hours shared +# one hymn text) -- see lauds-capitulum-common-of-the-bvm.yml's header +# for the fuller gap/sourcing writeup. +id: vespers-hymn-common-of-the-bvm +text: + la: >- + Ave maris stella, + + Dei Mater alma, + + Atque semper Virgo, + + Felix cæli porta. + + + Sumens illud Ave + + Gabriélis ore, + + Funda nos in pace, + + Mutans Hevæ nomen. + + + Solve vincla reis, + + Profer lumen cæcis, + + Mala nostra pelle, + + Bona cuncta posce. + + + Monstra te esse matrem, + + Sumat per te preces, + + Qui pro nobis natus, + + Tulit esse tuus. + + + Virgo singuláris, + + Inter omnes mitis, + + Nos culpis solútos + + Mites fac et castos. + + + Vitam præsta puram, + + Iter para tutum, + + Ut vidéntes Jesum, + + Semper collætémur. + + + Sit laus Deo Patri, + + Summo Christo decus, + + Spirítui Sancto, + + Tribus honor unus. Amen. + en: >- + Ave, star of ocean, + + Child divine who barest, + + Mother, ever-Virgin, + + Heaven's portal fairest. + + + Taking that sweet Ave + + Erst by Gabriel spoken, + + Eva's name reversing, + + Be of peace the token. + + + Break the sinners' fetters, + + Light to blind restoring, + + All our ills dispelling, + + Every boon imploring. + + + Show thyself a mother + + In thy supplication; + + He will hear who chose thee + + At his incarnation. + + + Maid all maids excelling, + + Passing meek and lowly, + + Win for sinners pardon, + + Make us chaste and holy. + + + As we onward journey + + Aid our weak endeavour, + + Till we gaze on Jesus + + And rejoice forever. + + + Father, Son, and Spirit, + + Three in One confessing, + + Give we equal glory + + Equal praise and blessing. Amen. +status: + la: verified + en: verified diff --git a/src/data/propers/common/vespers-responsory-common-of-the-bvm.yml b/src/data/propers/common/vespers-responsory-common-of-the-bvm.yml new file mode 100644 index 0000000..7872542 --- /dev/null +++ b/src/data/propers/common/vespers-responsory-common-of-the-bvm.yml @@ -0,0 +1,23 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617), Vespers +# `votive=C11` live query, 2026-08 -- see lauds-capitulum-common-of-the- +# bvm.yml's header. Same responsory text as Lauds -- see that file's own +# header note. +id: vespers-responsory-common-of-the-bvm +text: + la: | + R.br. Ave María, grátia plena, * Dóminus tecum. + ℟. Ave María, grátia plena, * Dóminus tecum. + ℣. Benedícta tu in muliéribus, et benedíctus fructus ventris tui. + ℟. Dóminus tecum. + ℣. Glória Patri, et Fílio, * et Spirítui Sancto. + ℟. Ave María, grátia plena, * Dóminus tecum. + en: | + R.br. Hail Mary full of grace, * the Lord is with thee. + ℟. Hail Mary full of grace, * the Lord is with thee. + ℣. Blessed art thou among women, and blessed is the fruit of thy womb. + ℟. The Lord is with thee. + ℣. Glory be to the Father, and to the Son, * and to the Holy Ghost. + ℟. Hail Mary full of grace, * the Lord is with thee. +status: + la: verified + en: verified diff --git a/src/data/propers/common/vespers-versicle-common-of-the-bvm.yml b/src/data/propers/common/vespers-versicle-common-of-the-bvm.yml new file mode 100644 index 0000000..aa0932e --- /dev/null +++ b/src/data/propers/common/vespers-versicle-common-of-the-bvm.yml @@ -0,0 +1,14 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617), Vespers +# `votive=C11` live query, 2026-08 -- distinct from the Lauds versicle +# (see lauds-versicle-common-of-the-bvm.yml). +id: vespers-versicle-common-of-the-bvm +text: + la: | + ℣. Dignáre me laudáre te, Virgo sacráta. + ℟. Da mihi virtútem contra hostes tuos. + en: | + ℣. Holy Virgin, my praise by thee accepted be. + ℟. Give me strength against thine enemies. +status: + la: verified + en: verified diff --git a/tests/hours/lauds.test.ts b/tests/hours/lauds.test.ts index e427949..2a33b79 100644 --- a/tests/hours/lauds.test.ts +++ b/tests/hours/lauds.test.ts @@ -277,6 +277,18 @@ describe('resolveOrdo("lauds", ...)', () => { expect(hymn?.kind === 'hymn' ? hymn.text.text.la : undefined).toContain('Jesu coróna célsior'); }); + it("uses common-of-the-bvm's real office bundle on Our Lady of Mount Carmel's own day", () => { + // Read directly from the source: Sancti/07-16.txt, 02-11.txt, + // 05-31.txt, 09-24.txt, 10-11.txt (the 5 saints/feasts in this + // category) all say plain "ex C11"/"vide C11" -- see lauds- + // capitulum-common-of-the-bvm.yml's header. + const ordo = resolveOrdo('lauds', '2026-07-16'); + const chapter = ordo.parts.find((p) => p.kind === 'chapter'); + expect(chapter?.kind === 'chapter' ? chapter.text.citation?.en : undefined).toBe('Sir 24:14'); + const hymn = ordo.parts.find((p) => p.kind === 'hymn'); + expect(hymn?.kind === 'hymn' ? hymn.text.text.la : undefined).toContain('O gloriósa Dómina'); + }); + it('includes the Kyrie + Our Father lead-in right after the Benedictus, before the day collect (either form)', () => { const ordo = resolveOrdo('lauds', FERIAL_TUESDAY); const litanyIndex = ordo.parts.findIndex((p) => p.kind === 'preces' && p.text.text.la?.includes('Kýrie, eléison')); diff --git a/tests/hours/vespers.test.ts b/tests/hours/vespers.test.ts index 6caf7de..610c8e1 100644 --- a/tests/hours/vespers.test.ts +++ b/tests/hours/vespers.test.ts @@ -334,10 +334,24 @@ describe('resolveOrdo("vespers", ...)', () => { expect(hymn?.kind === 'hymn' ? hymn.text.text.la : undefined).toContain('Fortem viríli péctore'); }); + it("uses common-of-the-bvm's real office bundle for Our Lady of Mount Carmel's First Vespers", () => { + // Live-verified against Divinum Officium (Monastic Tridentinum 1617) + // votive=C11 -- see vespers-hymn-common-of-the-bvm.yml's header. + const ordo = resolveOrdo('vespers', '2026-07-15'); + const chapter = ordo.parts.find((p) => p.kind === 'chapter'); + expect(chapter?.kind === 'chapter' ? chapter.text.citation?.en : undefined).toBe('Sir 24:14'); + const hymn = ordo.parts.find((p) => p.kind === 'hymn'); + expect(hymn?.kind === 'hymn' ? hymn.text.text.la : undefined).toContain('Ave maris stella'); + }); + it("renders Passiontide's seasonal office, with the Gloria Patri omitted from the responsory", () => { - // 2026-03-25 is a Wednesday in Passiontide (Passion Sunday 2026-03-22 - // through Holy Saturday 2026-04-04). - const ordo = resolveOrdo('vespers', '2026-03-25'); + // 2026-03-30 is Holy Monday (Passion Sunday 2026-03-22 through Holy + // Saturday 2026-04-04) -- deliberately not 03-25, the Annunciation's + // own fixed date, whose evening now correctly resolves to real + // Common-of-the-BVM content instead of falling through to this + // seasonal default (the Annunciation's own proper content isn't + // imported yet, so this is still an interim improvement, not final). + const ordo = resolveOrdo('vespers', '2026-03-30'); const chapter = ordo.parts.find((p) => p.kind === 'chapter'); expect(chapter?.kind === 'chapter' ? chapter.text.citation?.en : undefined).toBe('Jer 11:20'); const responsory = ordo.parts.find((p) => p.kind === 'responsory');