diff --git a/TODO.md b/TODO.md index bf642e6..05b33d0 100644 --- a/TODO.md +++ b/TODO.md @@ -5192,3 +5192,43 @@ the old, incomplete assertion. Full suite re-run after this follow-up: `npm test` (2021 passed, 47 files) and `npm run build` (`tsc --noEmit` + `vite build`) both pass. + +### Ember days' own Benedictus/Magnificat antiphons authored (2026-09-03) + +Follow-on from the 2026-08-22 Ember-day mechanism entry, whose "not authored, logged instead" +note called the gap "the Ember-day-specific `[Ant 2]`/`[Ant 3]` Lauds antiphons" — imprecise, and +worth correcting here. Live-verified (Monastic Tridentinum 1617) against a clean year for each +Ember weekday (Wed 2023-09-20, Fri 2024-09-20, Sat 2025-09-20 for September; Dec 16/18/19 2026 +for Advent, all winning outright): the day's own Lauds *psalmody* (Ps 50/63/64 + canticle + +Laudate, all 5 antiphon slots) stays entirely on the plain ferial weekday default, unchanged — +only the **Benedictus antiphon** (and, Wed/Fri only, the **Magnificat antiphon**) is genuinely +proper to the Ember day, each labeled "Antiphona ex Proprio de Tempore" live. `hours/resolve- +common.ts`'s `getBenedictusAntiphon`/`getMagnificatAntiphon` already look up `${winner.id}- +benedictus-antiphon`/`-magnificat-antiphon` unconditionally for any temporal winner (rank- +agnostic by design, same as the chapter/hymn bundle) — so this needed no mechanism change at +all, just the missing content files, which is why it silently rendered blank rather than +tripping any test. + +**Authored**: 6 Benedictus antiphon files (one per Ember weekday × quarter) and 4 Magnificat +antiphon files (Wed + Fri only, both quarters). September Wednesday/Friday reuse the identical +text for both (`[Ant 3]` is a bare `@:Ant 2` cross-reference in the source, not independently +authored — a real fact about the source, not a shortcut taken here); Advent Wednesday's two +differ (`Missus est Gábriel` / `Ecce ancílla Dómini`); September Saturday uses the Monastic +track's own `TemporaM/093-6.txt` override (`Illumináre... Deus Israël`) per this project's +Monastic-1617-first preference, matching the choice already made for this day's Matins +responsories. + +**Not authored, correctly**: Magnificat antiphons for either quarter's Ember Saturday — Second +Vespers on both is always ceded outright to the following Sunday ("Vespera de sequenti; nihil de +præcedenti," live-verified), and the source file itself has no `[Ant 3]` for either Saturday, +confirming the omission is real, not a gap. Advent Ember Friday's own Magnificat antiphon *was* +still authored despite being currently unreachable — Dec 18 always falls inside the O Antiphons' +own unconditional Dec 17-23 window, which wins the Vespers Magnificat outright — per this +project's standing "import available real content even if it may not survive the current +calendar" default. + +New assertions added to `tests/calendar/ember-days.test.ts` (Benedictus antiphon text/status on +all 6 winning-outright dates; Magnificat status on Advent Ember Wednesday, the one case with no +overriding mechanism to complicate the assertion). `npm test` (2023 passed, 47 files) and +`tsc --noEmit` both pass. + diff --git a/src/data/propers/temporal/ember-advent-friday-benedictus-antiphon.yml b/src/data/propers/temporal/ember-advent-friday-benedictus-antiphon.yml new file mode 100644 index 0000000..5acb780 --- /dev/null +++ b/src/data/propers/temporal/ember-advent-friday-benedictus-antiphon.yml @@ -0,0 +1,10 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617), Lauds +# live query, 2026-12-18 -- Advent Ember Friday, labeled "Antiphona ex +# Proprio de Tempore". Same text as Tempora/Adv3-5.txt's own [Ant 2]. +id: ember-advent-friday-benedictus-antiphon +text: + la: "Ex quo facta est * vox salutatiónis tuæ in áuribus meis, exsultávit in gáudio infans in útero meo, allelúja." + en: "As soon as the voice of thy salutation * sounded in mine ears, the babe leaped in my womb for joy. Alleluia." +status: + la: verified + en: verified diff --git a/src/data/propers/temporal/ember-advent-friday-magnificat-antiphon.yml b/src/data/propers/temporal/ember-advent-friday-magnificat-antiphon.yml new file mode 100644 index 0000000..5e1dcf9 --- /dev/null +++ b/src/data/propers/temporal/ember-advent-friday-magnificat-antiphon.yml @@ -0,0 +1,17 @@ +# Real content from Tempora/Adv3-5.txt's own [Ant 3], authored per this +# project's "import available content even if it may not survive the +# current calendar" default -- but currently unreachable in practice: +# Advent Ember Friday always falls on Dec 18 (the Wednesday after the 3rd +# Sunday of Advent is always Dec 17-23's own week), which the O Antiphons +# mechanism (calendar/index.ts, unconditional date-keyed override, see +# TODO.md 2026-08-30) always wins for the Vespers Magnificat antiphon +# instead -- live-verified 2026-12-18 renders "O Adonái," not this text. +# Kept for completeness/correctness of the id space, same as any other +# real proper text this store authors ahead of its own reachability. +id: ember-advent-friday-magnificat-antiphon +text: + la: "Hoc est testimónium, * quod perhíbuit Joánnes: Qui post me venit, ante me factus est." + en: "John bare witness of Him, * saying He That cometh after me is preferred before me." +status: + la: verified + en: verified diff --git a/src/data/propers/temporal/ember-advent-saturday-benedictus-antiphon.yml b/src/data/propers/temporal/ember-advent-saturday-benedictus-antiphon.yml new file mode 100644 index 0000000..71cba1b --- /dev/null +++ b/src/data/propers/temporal/ember-advent-saturday-benedictus-antiphon.yml @@ -0,0 +1,18 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617), Lauds +# live query, 2026-12-19 -- Advent Ember Saturday, labeled "Antiphona ex +# Proprio de Tempore". Same text as Tempora/Adv3-6.txt's own plain [Ant +# 2] (not the "(rubrica cisterciensis)" alternate below it -- no +# Cistercian-specific track modeled in this app). +# +# No Magnificat antiphon file for this id: Ember Saturday's own Second +# Vespers is always ceded to the 4th Sunday of Advent (live-verified +# 2026-12-19: "Dominica IV Adventus"), same "Vespera de sequenti" pattern +# already confirmed for September's own Ember Saturday -- the source file +# itself has no [Ant 3] for this day either. +id: ember-advent-saturday-benedictus-antiphon +text: + la: "Quómodo fiet istud, * Angele Dei, quóniam virum non cognósco? Audi, María Virgo: Spíritus Sanctus supervéniet in te, et virtus Altíssimi obumbrábit tibi." + en: "O thou Angel of God, * how shall this be, seeing I know not a man? Hear, O Virgin Mary! the Holy Ghost shall come upon thee, and the power of the Highest shall overshadow thee!" +status: + la: verified + en: verified diff --git a/src/data/propers/temporal/ember-advent-wednesday-benedictus-antiphon.yml b/src/data/propers/temporal/ember-advent-wednesday-benedictus-antiphon.yml new file mode 100644 index 0000000..60b242e --- /dev/null +++ b/src/data/propers/temporal/ember-advent-wednesday-benedictus-antiphon.yml @@ -0,0 +1,12 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617), Lauds +# live query, 2026-12-16 -- Advent Ember Wednesday, labeled "Antiphona ex +# Proprio de Tempore". Same text as Tempora/Adv3-3.txt's own [Ant 2]. +# Lauds psalmody itself stays on the plain ferial Wednesday antiphons +# throughout (confirmed live), same as September's own Ember Wednesday. +id: ember-advent-wednesday-benedictus-antiphon +text: + la: "Missus est Gábriel * Angelus ad Maríam Vírginem desponsátam Joseph." + en: "The angel Gabriel * was sent to Mary, a virgin espoused to Joseph." +status: + la: verified + en: verified diff --git a/src/data/propers/temporal/ember-advent-wednesday-magnificat-antiphon.yml b/src/data/propers/temporal/ember-advent-wednesday-magnificat-antiphon.yml new file mode 100644 index 0000000..1a07a45 --- /dev/null +++ b/src/data/propers/temporal/ember-advent-wednesday-magnificat-antiphon.yml @@ -0,0 +1,14 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617), Vespers +# live query, 2026-12-16 -- Advent Ember Wednesday's own Second Vespers, +# labeled "Antiphona ex Proprio de Tempore" (Dec 16 falls just before the +# O Antiphons' own Dec 17-23 window, so this really is what's said, unlike +# Friday's own sibling file below). Distinct text from the Benedictus +# antiphon this time (Tempora/Adv3-3.txt's own separate [Ant 3]), not a +# reused cross-reference like September's Wednesday/Friday. +id: ember-advent-wednesday-magnificat-antiphon +text: + la: "Ecce ancílla Dómini: * fiat mihi secúndum verbum tuum." + en: "Behold the handmaid * of the Lord; be it unto me according to thy word." +status: + la: verified + en: verified diff --git a/src/data/propers/temporal/ember-september-friday-benedictus-antiphon.yml b/src/data/propers/temporal/ember-september-friday-benedictus-antiphon.yml new file mode 100644 index 0000000..8638ef5 --- /dev/null +++ b/src/data/propers/temporal/ember-september-friday-benedictus-antiphon.yml @@ -0,0 +1,15 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617), Lauds +# live query, 2024-09-20 -- the clean year in range where September Ember +# Friday itself wins outright, labeled "Antiphona ex Proprio de Tempore". +# Same text as Tempora/093-5.txt's own [Ant 2] (the plain secular +# recension, not the "(rubrica cisterciensis)" alternate below it -- no +# Cistercian-specific track modeled in this app). Lauds psalmody itself +# stays on the plain ferial Friday antiphons throughout, same as +# Wednesday's own sibling file. +id: ember-september-friday-benedictus-antiphon +text: + la: "Múlier, * quæ erat in civitáte peccátrix, stans retro secus pedes Dómini, lácrimis cœpit rigáre pedes ejus et capíllis cápitis sui tergébat, et deosculabátur pedes ejus et unguénto ungébat." + en: "A woman in the city which was a sinner stood at the Lord's Feet behind Him, * and began to wash His Feet with tears, and did wipe them with the hairs of her head, and kissed His Feet, and anointed them with the ointment." +status: + la: verified + en: verified diff --git a/src/data/propers/temporal/ember-september-friday-magnificat-antiphon.yml b/src/data/propers/temporal/ember-september-friday-magnificat-antiphon.yml new file mode 100644 index 0000000..f9b6c71 --- /dev/null +++ b/src/data/propers/temporal/ember-september-friday-magnificat-antiphon.yml @@ -0,0 +1,10 @@ +# Tempora/093-5.txt's [Ant 3] "(rubrica 196)" is a bare "@:Ant 2" +# cross-reference, same identical text reused for Vespers as the sibling +# -benedictus-antiphon.yml -- see that file's own comment. +id: ember-september-friday-magnificat-antiphon +text: + la: "Múlier, * quæ erat in civitáte peccátrix, stans retro secus pedes Dómini, lácrimis cœpit rigáre pedes ejus et capíllis cápitis sui tergébat, et deosculabátur pedes ejus et unguénto ungébat." + en: "A woman in the city which was a sinner stood at the Lord's Feet behind Him, * and began to wash His Feet with tears, and did wipe them with the hairs of her head, and kissed His Feet, and anointed them with the ointment." +status: + la: verified + en: verified diff --git a/src/data/propers/temporal/ember-september-saturday-benedictus-antiphon.yml b/src/data/propers/temporal/ember-september-saturday-benedictus-antiphon.yml new file mode 100644 index 0000000..6470fc6 --- /dev/null +++ b/src/data/propers/temporal/ember-september-saturday-benedictus-antiphon.yml @@ -0,0 +1,24 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617), Lauds +# live query, 2025-09-20 -- the clean year in range where September Ember +# Saturday itself wins outright, labeled "Antiphona ex Proprio de +# Tempore". Uses the Monastic track's own override text +# (Latin/TemporaM/093-6.txt's [Ant 2], "Illumináre... Deus Israël") in +# place of the secular Tempora/093-6.txt's plain "Illúmina... in viam +# pacis" (no "Deus Israël"), per this project's Monastic-1617-first +# structure preference -- same choice already made for this day's Matins +# responsories. The English/Tempora/093-6.txt translation already carries +# "O Thou the God of Israel," confirming it was translated from the +# Monastic Latin, not the secular. +# +# No Magnificat antiphon file for this id: Ember Saturday's own Second +# Vespers is always ceded outright to the following Sunday ("Vespera de +# sequenti; nihil de præcedenti," live-verified 2025-09-20) -- the source +# file itself has no [Ant 3] for this day, correctly reflecting that the +# text would never be said. +id: ember-september-saturday-benedictus-antiphon +text: + la: "Illumináre, Dómine, * his, qui in ténebris sedent: et dírige pedes nostros in viam pacis, Deus Israël." + en: "Give light, O Lord, * to them that sit in darkness, and guide our feet into the way of peace, O Thou the God of Israel." +status: + la: verified + en: verified diff --git a/src/data/propers/temporal/ember-september-wednesday-benedictus-antiphon.yml b/src/data/propers/temporal/ember-september-wednesday-benedictus-antiphon.yml new file mode 100644 index 0000000..b134880 --- /dev/null +++ b/src/data/propers/temporal/ember-september-wednesday-benedictus-antiphon.yml @@ -0,0 +1,17 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617), Lauds +# live query, 2023-09-20 -- the one clean year in range where September +# Ember Wednesday itself wins outright (no competing saint), labeled +# "Antiphona ex Proprio de Tempore". Same text as Tempora/093-3.txt's own +# [Ant 2] ("Hoc genus...", echoing Lectio3's Gospel line): the app's +# Lauds psalmody itself stays entirely on the plain ferial Wednesday +# antiphons (Ps 50/63/64 + canticle + Laudate all confirmed unchanged +# live) -- only the Benedictus antiphon is genuinely proper to the Ember +# day, not the whole psalm-antiphon block TODO.md's 2026-08-22 entry +# loosely called "Lauds antiphons." +id: ember-september-wednesday-benedictus-antiphon +text: + la: "Hoc genus * dæmoniórum in nullo potest exíre, nisi in oratióne et jejúnio." + en: "This kind of devils * can come forth by nothing but by prayer and fasting." +status: + la: verified + en: verified diff --git a/src/data/propers/temporal/ember-september-wednesday-magnificat-antiphon.yml b/src/data/propers/temporal/ember-september-wednesday-magnificat-antiphon.yml new file mode 100644 index 0000000..f41c2ae --- /dev/null +++ b/src/data/propers/temporal/ember-september-wednesday-magnificat-antiphon.yml @@ -0,0 +1,12 @@ +# Same source as the sibling -benedictus-antiphon.yml: Tempora/093-3.txt's +# [Ant 3] is a bare "@:Ant 2" cross-reference, i.e. the identical text +# reused for both Lauds and Vespers on this day -- not independently +# authored content, but the reference engine's own real choice, not a +# simplification on this app's part. +id: ember-september-wednesday-magnificat-antiphon +text: + la: "Hoc genus * dæmoniórum in nullo potest exíre, nisi in oratióne et jejúnio." + en: "This kind of devils * can come forth by nothing but by prayer and fasting." +status: + la: verified + en: verified diff --git a/tests/calendar/ember-days.test.ts b/tests/calendar/ember-days.test.ts index 8e37199..b642af8 100644 --- a/tests/calendar/ember-days.test.ts +++ b/tests/calendar/ember-days.test.ts @@ -53,6 +53,42 @@ describe('Ember days', () => { } }); + it("Lauds' Benedictus antiphon is the Ember day's own proper text on all 6 winning-outright days (2026-08-22 added the mechanism/collect/Matins, but not this -- fixed here)", () => { + // Wed/Fri/Sat winning outright for the September quarter, one per + // weekday (2026's own dates are all saint-outranked, see above) -- + // found by scanning forward from 2023, all live-verified against the + // reference engine. + const cases: [string, string][] = [ + ['2023-09-20', 'Hoc genus'], + ['2024-09-20', 'Múlier'], + ['2025-09-20', 'Illumináre, Dómine'], + ['2026-12-16', 'Missus est Gábriel'], + ['2026-12-18', 'Ex quo facta est'], + ['2026-12-19', 'Quómodo fiet istud'], + ]; + for (const [date, expectedStart] of cases) { + const ordo = resolveOrdo('lauds', date); + const idx = ordo.parts.findIndex((p) => p.kind === 'canticle' && p.canticleId === 'benedictus'); + const antiphon = ordo.parts[idx + 1] as { text: { text: { la?: string }; status: { la?: string; en?: string } } }; + expect(antiphon.text.status.la).toBe('verified'); + expect(antiphon.text.status.en).toBe('verified'); + expect(antiphon.text.text.la).toContain(expectedStart); + } + }); + + it("Vespers' Magnificat antiphon is proper on Ember Wednesday (Sept and Advent) where the reference engine actually renders it, not overridden by a Sunday/O-Antiphon", () => { + // September Ember Friday/Saturday and Advent Ember Friday/Saturday + // are excluded here: Saturday's Second Vespers is always ceded to the + // following Sunday (live-verified), and Advent Ember Friday/Saturday + // (always Dec 18/19) are always inside the O Antiphons' own + // unconditional Dec 17-23 window -- both real, not gaps. + const ordo = resolveOrdo('vespers', '2026-12-16'); + const idx = ordo.parts.findIndex((p) => p.kind === 'canticle' && p.canticleId === 'magnificat'); + const antiphon = ordo.parts[idx + 1] as { text: { status: { la?: string; en?: string } } }; + expect(antiphon.text.status.la).toBe('verified'); + expect(antiphon.text.status.en).toBe('verified'); + }); + it('Matins renders 3 real, distinct, verified lessons+responsories for each of the 6 Ember days', () => { const dates = ['2026-09-16', '2026-09-18', '2026-09-19', '2026-12-16', '2026-12-18', '2026-12-19']; for (const date of dates) {