Author Ember days' own Benedictus/Magnificat antiphons

Live-verified (Monastic Tridentinum 1617) that an Ember day's Lauds
psalmody stays on the plain ferial default throughout -- only the
Benedictus antiphon (and, Wednesday/Friday only, the Magnificat
antiphon) is genuinely proper to the day. Adds the 6 Benedictus +
4 Magnificat antiphon files (Ember Saturday's Second Vespers is
always ceded to the following Sunday on both quarters, so no
Magnificat content exists to author there).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGjUyhUZJaSjiniEmnLdak
This commit is contained in:
2026-09-04 07:12:01 -04:00
parent bcbc93732f
commit 03d39dc911
12 changed files with 225 additions and 0 deletions
+40
View File
@@ -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` Full suite re-run after this follow-up: `npm test` (2021 passed, 47 files) and `npm run build`
(`tsc --noEmit` + `vite build`) both pass. (`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.
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
+36
View File
@@ -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', () => { 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']; 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) { for (const date of dates) {