diff --git a/TODO.md b/TODO.md index 450619e..dcd8823 100644 --- a/TODO.md +++ b/TODO.md @@ -386,6 +386,45 @@ the original 109-saint pass (own `[Ant 1]`/live-rendered text, not a shared Common), since a saint with a genuine proper collect usually has a genuine proper antiphon too. Not yet started. +### The other 26 propers-set saints' Benedictus antiphons — done (2026-08) + +Turned out **most of these don't have unique antiphon text either** — +a genuine proper collect doesn't imply a genuine proper antiphon, same +finding as St. Martin of Tours's mixed proper-antiphon/shared-chapter +split from the original 29-saint pass. Live-queried Lauds +(`prayLaudes`) for each of the 26, same title-verified method as the +Common-category batch above. + +**15 of the 26 are genuinely unwinnable stubs** (already documented as +such from the collects pass — always commemorated, never the day's own +title, so nothing to query) — same "honestly missing" treatment as St. +Frances of Rome/St. Bibiana in the original 109-saint pass, not +guessed at. + +**Of the 11 that do win outright**, 7 turned out to share existing +Common-category text — `benedictusCommon` wired directly to the already- +authored files from the section above, no new content needed: Ss. +Dionysius and Companions, Ss. Felix and Adauctus, Ss. Maurice and +Companions, Ss. Tryphon and Companions (`common-of-several-martyrs`, +despite Dionysius's own `common` field saying `common-of-a-martyr- +bishop` — another case, like Chair of St. Peter earlier, where the two +fields genuinely diverge), St. Chrysogonus and St. Donatus +(`common-of-a-martyr`), the Vigil of St. Lawrence (`common-of-a-vigil`). + +The remaining 4 have real, unique proper text — new +`{id}-antiphon.yml` files: All Saints of the Benedictine Order ("Vos +qui reliquístis ómnia..."), St. Agnes (secunda) ("Ecce, quod +concupívi..."), St. Benedict ("Sanctíssime Conféssor Dómini..." — no +English in the source, same gap as St. Scholastica's, translated and +marked `draft`), and the Vigil of St. John the Baptist ("Eréxit nobis +* Dóminus cornu salútis..." — deliberately echoing the Benedictus +canticle's own opening words, fitting for the Vigil of the saint whose +father, Zechariah, first spoke that canticle). + +P/T/S/N for these 26 not attempted in this pass — a further layer on +top, same as how the original 109 got Benedictus antiphons long before +their own later, separate P/T/S/N pass (duplex-majus+ subset only). + ### Christmas-Octave Sunday content — done (2026-08) Was: only the Benedictus antiphon existed for `christmas-octave-sunday` @@ -720,12 +759,15 @@ pass has now been checked against a live Monastic query; most needed correction (confirmed Roman-rite sourced), a handful already matched. - **All ~52 temporal entries: done, including `christmas-octave-sunday`** (see the section above for method and its own correction). -- **94 `propers: null` saints: done (2026-08)** — see the dedicated section - below for the collect-authoring pass and the era-specific-calendar - discovery it took to do reliably. Benedictus antiphon + P/T/S/N: done - for the 66 that draw from a shared Common (own dedicated section - below); the other 26 (own proper collect, from the same batch) still - need their own individually-authored Benedictus antiphon, not started. +- **94 `propers: null` saints: done (2026-08)** — see the dedicated + section below for the collect-authoring pass and the era-specific- + calendar discovery it took to do reliably. Benedictus antiphon: done + for all 94 (own dedicated sections below) — 66 via a shared Common; of + the other 26 (own proper collect), 15 are genuinely unwinnable stubs + left honestly missing, 7 share an existing Common, and 4 have real + unique text. P/T/S/N: done for the 66-saint batch; the 26 propers-set + saints' own P/T/S/N not yet attempted, a further layer on top (see + that section's own note). ### Bug found and fixed while pulling christmas-octave-sunday's antiphon diff --git a/src/data/calendar/saints/ss-dionysius-and-companions.yml b/src/data/calendar/saints/ss-dionysius-and-companions.yml index fa42f9c..2f814e0 100644 --- a/src/data/calendar/saints/ss-dionysius-and-companions.yml +++ b/src/data/calendar/saints/ss-dionysius-and-companions.yml @@ -10,3 +10,10 @@ name: "St. Dionysius, Bishop, and Companions, Martyrs" rank: semiduplex common: common-of-a-martyr-bishop propers: "ss-dionysius-and-companions" +# Benedictus antiphon live-verified (2026-08, Lauds query, 2025-10-09, +# winner outright) as byte-identical to common-of-several-martyrs's own +# ("Vestri capílli cápitis...") -- despite `common` above saying +# martyr-*bishop*, not several-martyrs; the two fields aren't always the +# same category (see calendar/feasts.ts's SaintRecord.benedictusCommon +# doc comment). +benedictusCommon: common-of-several-martyrs diff --git a/src/data/calendar/saints/ss-felix-and-adauctus.yml b/src/data/calendar/saints/ss-felix-and-adauctus.yml index 9d195ed..f2a9cbe 100644 --- a/src/data/calendar/saints/ss-felix-and-adauctus.yml +++ b/src/data/calendar/saints/ss-felix-and-adauctus.yml @@ -14,3 +14,6 @@ name: "Ss. Felix and Adauctus, Martyrs" rank: simplex common: common-of-several-martyrs propers: "ss-felix-and-adauctus" +# Benedictus antiphon live-verified (2026-08, Lauds query, 2025-08-30, winner +# outright) as byte-identical to common-of-several-martyrs.yml's own. +benedictusCommon: common-of-several-martyrs diff --git a/src/data/calendar/saints/ss-maurice-and-companions.yml b/src/data/calendar/saints/ss-maurice-and-companions.yml index 1a31868..b422294 100644 --- a/src/data/calendar/saints/ss-maurice-and-companions.yml +++ b/src/data/calendar/saints/ss-maurice-and-companions.yml @@ -11,3 +11,6 @@ name: "Ss. Maurice and Companions, Martyrs" rank: simplex common: common-of-several-martyrs propers: "ss-maurice-and-companions" +# Benedictus antiphon live-verified (2026-08, Lauds query, 2025-09-22, winner +# outright) as byte-identical to common-of-several-martyrs.yml's own. +benedictusCommon: common-of-several-martyrs diff --git a/src/data/calendar/saints/ss-tryphon-and-companions.yml b/src/data/calendar/saints/ss-tryphon-and-companions.yml index 56d60ed..7f749ce 100644 --- a/src/data/calendar/saints/ss-tryphon-and-companions.yml +++ b/src/data/calendar/saints/ss-tryphon-and-companions.yml @@ -9,3 +9,6 @@ name: "Ss. Tryphon, Respicius, and Nympha, Martyrs" rank: simplex common: common-of-several-martyrs propers: "ss-tryphon-and-companions" +# Benedictus antiphon live-verified (2026-08, Lauds query, 2025-11-10, winner +# outright) as byte-identical to common-of-several-martyrs.yml's own. +benedictusCommon: common-of-several-martyrs diff --git a/src/data/calendar/saints/st-chrysogonus.yml b/src/data/calendar/saints/st-chrysogonus.yml index 184f411..47fffce 100644 --- a/src/data/calendar/saints/st-chrysogonus.yml +++ b/src/data/calendar/saints/st-chrysogonus.yml @@ -14,3 +14,6 @@ name: "St. Chrysogonus, Martyr" rank: simplex common: common-of-a-martyr propers: "st-chrysogonus" +# Benedictus antiphon live-verified (2026-08, Lauds query, 2027-11-24, winner +# outright) as byte-identical to common-of-a-martyr.yml's own. +benedictusCommon: common-of-a-martyr diff --git a/src/data/calendar/saints/st-donatus.yml b/src/data/calendar/saints/st-donatus.yml index 942f5e8..06ea6c6 100644 --- a/src/data/calendar/saints/st-donatus.yml +++ b/src/data/calendar/saints/st-donatus.yml @@ -20,3 +20,6 @@ name: "St. Donatus, Bishop and Martyr" rank: simplex common: common-of-a-martyr-bishop propers: "st-donatus" +# Benedictus antiphon live-verified (2026-08, Lauds query, 2026-08-07, winner +# outright) as byte-identical to common-of-a-martyr.yml's own. +benedictusCommon: common-of-a-martyr diff --git a/src/data/calendar/saints/vigil-of-st-lawrence.yml b/src/data/calendar/saints/vigil-of-st-lawrence.yml index 8cb308c..898a900 100644 --- a/src/data/calendar/saints/vigil-of-st-lawrence.yml +++ b/src/data/calendar/saints/vigil-of-st-lawrence.yml @@ -8,3 +8,6 @@ name: "Vigil of St. Lawrence" rank: vigil common: common-of-a-vigil propers: "vigil-of-st-lawrence" +# Benedictus antiphon live-verified (2026-08, Lauds query, 2025-08-09, winner +# outright) as byte-identical to common-of-a-vigil.yml's own. +benedictusCommon: common-of-a-vigil diff --git a/src/data/propers/common/all-saints-of-the-benedictine-order-antiphon.yml b/src/data/propers/common/all-saints-of-the-benedictine-order-antiphon.yml new file mode 100644 index 0000000..e2b33dd --- /dev/null +++ b/src/data/propers/common/all-saints-of-the-benedictine-order-antiphon.yml @@ -0,0 +1,15 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617), Lauds +# live query (2025-11-13, winner outright) -- the Benedictus antiphon. +# Own proper text, not shared with any other saint on this app's +# calendar. No embedded "*": this feast is Duplex II. classis (double- +# or-higher), so its own query shows the antiphon in full at both open +# and close with no separate incipit marker, and there's no lower-rank +# saint sharing this text to reconstruct the split from (same situation +# as benedictus-antiphon-common-of-a-dedication.yml). +id: all-saints-of-the-benedictine-order-antiphon +text: + la: "Vos qui reliquístis ómnia, et secúti estis me, céntuplum accipiétis, et vitam ætérnam possidébitis." + en: "You who left all and follow me, you will receive hundredfolds, and you will have eternal life." +status: + la: verified + en: verified diff --git a/src/data/propers/common/st-agnes-secunda-antiphon.yml b/src/data/propers/common/st-agnes-secunda-antiphon.yml new file mode 100644 index 0000000..8c14d4c --- /dev/null +++ b/src/data/propers/common/st-agnes-secunda-antiphon.yml @@ -0,0 +1,11 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617), Lauds +# live query (2026-01-28, winner outright) -- the Benedictus antiphon. +# Own proper text (her second, "secundo" commemoration, distinct from +# St. Agnes's own Jan 21 feast). +id: st-agnes-secunda-antiphon +text: + la: "Ecce, quod concupívi, * jam vídeo: quod sperávi, jam téneo: ipsi sum juncta in cælis, quem in terris pósita, tota devotióne diléxi." + en: "Behold, now I see that * which I have desired; now I possess that for which I have hoped; now am I united in heaven to Him Whom I loved with my whole heart upon earth." +status: + la: verified + en: verified diff --git a/src/data/propers/common/st-benedict-antiphon.yml b/src/data/propers/common/st-benedict-antiphon.yml new file mode 100644 index 0000000..65156a5 --- /dev/null +++ b/src/data/propers/common/st-benedict-antiphon.yml @@ -0,0 +1,17 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617), Lauds +# live query (2025-03-21, winner outright) -- the Benedictus antiphon. +# The source's own English page didn't render a translation (silently +# duplicated the Latin, same gap as st-scholastica-antiphon.yml); +# translated here in the same register as the rest of this project's +# antiphons, so marked `draft` rather than `verified`. No embedded "*": +# this feast is Duplex I. classis (double-or-higher), so its own query +# shows the antiphon in full at both open and close with no separate +# incipit marker, and there's no lower-rank saint sharing this text to +# reconstruct the split from. +id: st-benedict-antiphon +text: + la: "Sanctíssime Conféssor Dómini, Monachórum pater et dux, Benedícte, intercéde pro nostra omniúmque salúte." + en: "Most holy Confessor of the Lord, father and leader of monks, Benedict, intercede for our salvation and that of all." +status: + la: verified + en: draft diff --git a/src/data/propers/common/vigil-of-st-john-the-baptist-antiphon.yml b/src/data/propers/common/vigil-of-st-john-the-baptist-antiphon.yml new file mode 100644 index 0000000..1381503 --- /dev/null +++ b/src/data/propers/common/vigil-of-st-john-the-baptist-antiphon.yml @@ -0,0 +1,14 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617), Lauds +# live query (2026-06-23, winner outright) -- the Benedictus antiphon. +# Own proper text, deliberately echoing the Benedictus canticle's own +# opening words ("Erexit cornu salutis nobis in domo David pueri sui") — +# a fitting antiphon for the Vigil of the saint whose own father, St. +# Zechariah, first spoke that canticle (Luke 1:69) — not shared with +# common-of-a-vigil.yml's other vigils. +id: vigil-of-st-john-the-baptist-antiphon +text: + la: "Eréxit nobis * Dóminus cornu salútis in domo David púeri sui." + en: "The Lord has raised up * a horn of salvation for us in the house of David his servant." +status: + la: verified + en: verified diff --git a/tests/hours/resolve-common.test.ts b/tests/hours/resolve-common.test.ts index 77e9e99..6e2ace6 100644 --- a/tests/hours/resolve-common.test.ts +++ b/tests/hours/resolve-common.test.ts @@ -71,6 +71,31 @@ describe('minorHoursCommon/benedictusCommon fallback (2026-08, the 94 propers:nu }); }); +describe('the 26 propers-set saints from the 94-saint batch (2026-08)', () => { + it('a saint with a genuine proper collect can still share its Benedictus antiphon with a Common category (benedictusCommon)', () => { + // Ss. Dionysius and Companions -- own proper collect (propers is + // set), but live-verified byte-identical to common-of-several- + // martyrs's Benedictus antiphon, so getBenedictusAntiphon falls + // through to benedictusCommon rather than a nonexistent + // ss-dionysius-and-companions-antiphon.yml. + const day = resolveDay('2025-10-09'); + expect(day.winner).toMatchObject({ kind: 'sanctoral', id: 'ss-dionysius-and-companions' }); + expect(getBenedictusAntiphon(day).status).toEqual({ la: 'verified', en: 'verified' }); + }); + + it("a saint with genuinely unique Benedictus antiphon text resolves its own proper file, not a Common", () => { + // St. Benedict -- own proper text ("Sanctíssime Conféssor Dómini...", + // st-benedict-antiphon.yml), sourced from the source's Latin-only + // page (no English rendering, same gap as St. Scholastica's), so + // English is a translation and stays `draft`. + const day = resolveDay('2025-03-21'); + expect(day.winner).toMatchObject({ kind: 'sanctoral', id: 'st-benedict' }); + const ben = getBenedictusAntiphon(day); + expect(ben.status).toEqual({ la: 'verified', en: 'draft' }); + expect(ben.text.la).toContain('Benedícte'); + }); +}); + describe('splitNamedAntiphon', () => { it('carries a verified status through to both the incipit and full forms', () => { const { incipit, full } = splitNamedAntiphon({