Compare commits

...

3 Commits

Author SHA1 Message Date
will e7c5fc0c24 Give a Vigil's own First Vespers Magnificat its real weekday fallback
Deploy / deploy (push) Successful in 1m31s
A Vigil never has a fixed proper Magnificat antiphon in the real rubric
-- its Rule block ("ex C1v; ... Laudes 2") always borrows whatever the
current ferial weekday's own antiphon is, live-verified across 4
different years (2025-2028) at the Vigil of St. Andrew's own First
Vespers. getMagnificatAntiphon now special-cases saint.rank === 'vigil'
to fall through to the same weekday-default table the plain temporal
branch already used, rather than trying (and missing) a fixed Common
lookup.

Closes the 11th and last Common-category Magnificat antiphon gap; see
TODO.md for the full writeup, including how the first pass wrongly
closed this one as "not a gap" before being asked to double check.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QEe9oTbn1UjQVAYcCoW1a
2026-08-31 22:27:27 -04:00
will ccc406003c Author 10 sanctoral Common-category Magnificat antiphons
getMagnificatAntiphon's Common-category fallback
(magnificat-antiphon-${benedictusCommon}) had never been authored for
any of the 11 real Common categories saints fall back to -- only the
temporal-cycle side of this gap had been closed previously. Sourced
each from its Commune file's own [Ant 3] (Second Vespers), live-verified
against Ss. Placid and Companions, St. Blaise, and St. John Gualbert's
real evenings.

common-of-a-vigil (the 11th category) is handled separately, in code --
see the next commit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QEe9oTbn1UjQVAYcCoW1a
2026-08-31 22:27:17 -04:00
will 8702955a5f Fix wrong Ant-tag sourced for two Common-category Benedictus antiphons
benedictus-antiphon-common-of-a-confessor.yml and -the-bvm.yml were each
reading their Commune source file's [Ant 1] (the Common's First Vespers
antiphon), not [Ant 2] (the real Lauds antiphon) -- discovered while
sourcing the sibling Magnificat antiphon set. Live-verified wrong via St.
Alexius's real Lauds query (renders "Euge, serve bone", not "Similabo
eum").

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QEe9oTbn1UjQVAYcCoW1a
2026-08-31 22:27:08 -04:00
14 changed files with 246 additions and 18 deletions
+38
View File
@@ -4446,3 +4446,41 @@ undefined` despite having real authored data. Also found and fixed one stale tes
name yet" as the expected behavior — now asserts the real Latin. `npm test` (807 passed) and
`tsc --noEmit` pass throughout. **Closes this backlog item** — moved out of the "Open work"
priority list.
### Vespers Magnificat antiphon — sanctoral Common-category fallback, 11/11 (2026-08-31)
User flagged today's (Aug 31, St. Raymond Nonnatus) Vespers was missing its Magnificat antiphon.
Root cause was systemic, not date-specific — the earlier 2026-08-30 pass (see above) had closed
the *temporal*-cycle gap in `getMagnificatAntiphon`, but the *sanctoral* Common-category
fallback (`magnificat-antiphon-${saint.benedictusCommon}`) had never been authored at all: only
11 saints ever need it (the ones with `propers: null` or no own antiphon, falling back to
`benedictusCommon`'s 11 distinct category values), and every single one was `missing`.
Sourcing method: each Commune source file (`Latin/Commune/C*.txt`) lays out
Vespers1(`[Ant 1]`) -> Matins -> Lauds(`[Ant 2]`) -> minor hours -> Vespers2(`[Ant 3]`), confirmed
directly by live query (Ss. Placid and Companions, 10-05-2026: the evening before renders
`[Ant 1]` under "Vespera de sequenti", the feast's own evening renders `[Ant 3]`) and
cross-checked against 3 more saints (St. Blaise, St. John Gualbert). Authored 10 of 11 categories'
`magnificat-antiphon-common-of-*.yml` from each Common's own `[Ant 3]`
(`common-of-a-confessor`/`common-of-an-abbot` share one file, C5, so their Magnificat text is
identical by design, same as their existing Benedictus text).
Found and fixed two pre-existing bugs in sibling `benedictus-antiphon-common-of-*.yml` files
while cross-checking `[Ant 2]` against them: `common-of-a-confessor` and `common-of-the-bvm` had
both been sourced from `[Ant 1]` (First Vespers) instead of `[Ant 2]` (Lauds) — live-verified
wrong via St. Alexius's real Lauds query (07-17-2026, renders "Euge, serve bone", not the
file's old "Similabo eum"). Corrected both.
**The 11th category, `common-of-a-vigil`, needed a code fix instead of a content file.**
Initially assumed unreachable (a Vigil's own *Second* Vespers always loses to the following
feast's First Vespers — true, and confirmed via `compareFeastClass('vigil', ...)` always losing
in `resolveEveningDay`). But a Vigil's own *First* Vespers (anticipated the evening before, since
`hasFirstVespers` has no rank floor) absolutely does reach this code path — caught by re-checking
after the user asked "what about 11 of 11?". Live-verified across 4 different years
(2025-2028) that the real office never gives a Vigil a fixed proper Magnificat text at all — its
`[Rule]` block ("ex C1v; ... Laudes 2") always borrows whatever the current ferial weekday's own
antiphon is (`{Antiphona ex Proprio de Tempore}` every single year tried). So `common-of-a-vigil`
correctly has no content file; instead `getMagnificatAntiphon` (`hours/resolve-common.ts`) now
special-cases `saint.rank === 'vigil'` to fall through to the same `vespersMagnificatAntiphons`
weekday-default table the plain temporal branch already used, before ever trying a Common
lookup. `npm test` (810 passed) and `tsc --noEmit` pass.
@@ -1,15 +1,18 @@
# Read directly from the reference engine's own source data files:
# web/www/horas/Latin/Commune/C5.txt ("Commune Confessoris non
# pontificis") and its English counterpart — matches this project's own
# `common-of-a-confessor` category label (see collect-c5.yml's own
# header). First saint to need this Common's own Benedictus antiphon
# (st-alexius.yml, the only prior `common-of-a-confessor` saint, used a
# Cistercian-specific alternate for his minor hours instead and had no
# Benedictus antiphon recorded at all).
# Corrected 2026-08-31: originally read from C5.txt's [Ant 1] ("Similabo
# eum"), but that's this Common's *First Vespers* antiphon, not the Lauds
# Benedictus one -- discovered while sourcing
# magnificat-antiphon-common-of-a-confessor.yml, whose own Second-Vespers
# text made it obvious this file's C5.txt layout is Vespers1(Ant1) ->
# Matins -> Lauds(Ant2) -> minor hours -> Vespers2(Ant3), not a flat
# "[Ant 1] = Benedictus" read. Live-verified directly: St. Alexius's own
# Lauds (07-17-2026) renders "Euge, serve bone" (C5's own [Ant 2]), not
# "Similabo eum" -- matches the already-correct
# benedictus-antiphon-common-of-an-abbot.yml exactly, which resolves to
# this same C5 file via its own C5-1/C5b sub-variants (no Ant override).
id: benedictus-antiphon-common-of-a-confessor
text:
la: "Similábo eum * viro sapiénti, qui ædificávit domum suam supra petram."
en: "I will liken him unto a wise man, * which built his house upon a rock."
la: "Euge, serve bone * et fidélis, quia in pauca fuísti fidélis, supra multa te constítuam, intra in gáudium Dómini tui."
en: "Well done, thou good and faithful servant; * thou hast been faithful over a few things, I will make thee ruler over many things; enter thou into the joy of thy Lord."
status:
la: verified
en: verified
@@ -1,13 +1,19 @@
# Verified against the reference engine's own source data files:
# web/www/horas/Latin/Commune/C11.txt's own [Ant 1] ("In Festis Beatae
# Mariae Virginis" -- Common of Feasts of the BVM) and its English
# counterpart. Reusable by any BVM feast keyed to `common: common-of-
# the-bvm` (SaintRecord.benedictusCommon) that has no proper Benedictus
# antiphon of its own -- e.g. our-lady-of-the-snows.yml.
# Corrected 2026-08-31: originally read from C11.txt's [Ant 1] ("Sancta
# Maria succurre miseris"), but that's this Common's *First Vespers*
# antiphon, not the Lauds Benedictus one -- discovered while sourcing
# magnificat-antiphon-common-of-the-bvm.yml, which made clear this file's
# layout is Vespers1(Ant1) -> Matins -> Lauds(Ant2) -> minor hours ->
# Vespers2(Ant3), the same pattern confirmed live for several sibling
# Commons (see e.g. magnificat-antiphon-common-of-several-martyrs.yml's
# own header). The real Lauds text is C11's own [Ant 2]. Not
# independently live-queried for this specific Common. Reusable by any
# BVM feast keyed to `common: common-of-the-bvm`
# (SaintRecord.benedictusCommon) that has no proper Benedictus antiphon
# of its own -- e.g. our-lady-of-the-snows.yml.
id: benedictus-antiphon-common-of-the-bvm
text:
la: "Sancta María, * succúrre míseris, juva pusillánimes, réfove flébiles, ora pro pópulo, intérveni pro clero, intercéde pro devóto femíneo sexu: séntiant omnes tuum juvámen, quicúmque célebrant tuam sanctam festivitátem."
en: "O Holy Mary, * be thou an help to the helpless, a strength to the fearful, a comfort to the sorrowful; pray for the people, plead for the clergy, make intercession for all women vowed to God: may all that are keeping this thine holy Feast-day feel the might of thine assistance."
la: "Beáta es, * María, quæ credidísti: perficiéntur in te, quæ dicta sunt tibi a Dómino, allelúja."
en: "O Mary * blessed art thou that didst believe! for there shall be a performance of those things which were told thee from the Lord. Alleluia."
status:
la: verified
en: verified
@@ -0,0 +1,16 @@
# Second Vespers Magnificat antiphon for `common-of-a-confessor-bishop`
# (Commune Confessoris Pontificis, Latin/Commune/C4.txt's own [Ant 3] --
# same Vespers1(Ant1)/Lauds(Ant2)/Vespers2(Ant3) file layout confirmed
# for this Common; Ant 2 here matches the already-authored
# benedictus-antiphon-common-of-a-confessor-bishop.yml exactly, so Ant 3
# is trustworthy by the same read. Not independently live-queried for
# this specific Common (both live-query attempts landed on a date this
# saint lost the evening to a higher feast) -- read directly from source
# instead, same as several of this Common-category set's siblings.
id: magnificat-antiphon-common-of-a-confessor-bishop
text:
la: "Amávit eum Dóminus, * et ornávit eum: stolam glóriæ índuit eum, et ad portas paradísi coronávit eum."
en: "The Lord loved him * and beautified him. He clothed him with a robe of glory, and crowned him at the gates of Paradise."
status:
la: verified
en: verified
@@ -0,0 +1,17 @@
# Second Vespers Magnificat antiphon for `common-of-a-confessor`
# (Commune Confessoris non Pontificis, Latin/Commune/C5.txt's own [Ant 3]
# -- confirmed by position/label against the file's Vespers1(Ant1) ->
# Matins -> Lauds(Ant2) -> minor hours -> Vespers2(Ant3) layout, and
# live-verified directly: St. John Gualbert (07-12-2026) and St. Odo's
# Common-of-an-Abbot fallback (which resolves to this same C5 file, no
# override -- see benedictus-antiphon-common-of-an-abbot.yml's own
# comment) both render this exact text at their own Second Vespers.
# Same underlying text as `magnificat-antiphon-common-of-an-abbot.yml`
# by design -- both vu categories share this one Commune file.
id: magnificat-antiphon-common-of-a-confessor
text:
la: "Hic vir despíciens mundum * et terréna, triúmphans, divítias cælo cóndidit ore, manu."
en: "Lo, a servant of God * who esteemed but little things earthly. And by word and work laid him up treasure in heaven."
status:
la: verified
en: verified
@@ -0,0 +1,17 @@
# Second Vespers Magnificat antiphon for `common-of-a-dedication`
# (Commune Dedicationis Ecclesiae, Latin/Commune/C8.txt's own [Ant 3] --
# the "O quam metuendus est locus iste" Jacob's-ladder text, Genesis
# 28:17). Ant 2 in this same file matches the already-authored
# benedictus-antiphon-common-of-a-dedication.yml's "Zacchæe" text
# exactly, confirming the Vespers1(Ant1)/Lauds(Ant2)/Vespers2(Ant3) read
# for this Common. Read directly from source, not independently
# live-queried (this Common's only current user, Ss. Peter and Paul's
# basilicas, sits in a crowded November stretch where every date tried
# lost the evening to a neighboring feast).
id: magnificat-antiphon-common-of-a-dedication
text:
la: "O quam metuéndus est * locus iste: vere non est hic áliud, nisi domus Dei, et porta cæli."
en: "How dreadful is this place. * Surely this is none other but the house of God, and this is the gate of heaven."
status:
la: verified
en: verified
@@ -0,0 +1,14 @@
# Second Vespers Magnificat antiphon for `common-of-a-martyr` (Commune
# Unius Martyris, Latin/Commune/C2.txt's own [Ant 3] -- confirmed by
# file position and live-verified directly: St. Blaise's own Second
# Vespers (02-03-2026, no "Vespera de sequenti") renders this exact
# text. Ant 2 in the same file matches the already-authored
# benedictus-antiphon-common-of-a-martyr.yml's "Qui odit" text exactly.
# Covers `common-of-a-martyr-bishop` too, same as the Benedictus file.
id: magnificat-antiphon-common-of-a-martyr
text:
la: "Qui vult veníre post me, * ábneget semetípsum, et tollat crucem suam, et sequátur me."
en: "If any man will come after me, * let him deny himself and take up his cross daily and follow me."
status:
la: verified
en: verified
@@ -0,0 +1,16 @@
# Second Vespers Magnificat antiphon for `common-of-a-virgin` (Commune
# Unius Virginis, Latin/Commune/C6.txt) -- its own [Ant 3] is a bare
# `@:Ant 1` cross-reference, i.e. this Common reuses its First Vespers
# antiphon at Second Vespers too (same pattern as
# common-of-several-women-martyrs, below). Ant 2 in this same file
# matches the already-authored benedictus-antiphon-common-of-a-virgin.yml
# exactly, confirming the read. Covers `common-of-a-virgin-martyr` and
# `common-of-a-holy-woman` too, same as the Benedictus file. Not
# independently live-queried.
id: magnificat-antiphon-common-of-a-virgin
text:
la: "Veni, Sponsa Christi, * áccipe corónam, quam tibi Dóminus præparávit in ætérnum."
en: "Come, Bride of Christ, and take the everlasting crown * which the Lord hath prepared for thee."
status:
la: verified
en: verified
@@ -0,0 +1,13 @@
# Second Vespers Magnificat antiphon for `common-of-an-abbot` -- same
# underlying Commune file as `common-of-a-confessor` (Latin/Commune/C5.txt,
# via the C5-1/C5b sub-variants which don't override the Ant tags -- see
# benedictus-antiphon-common-of-an-abbot.yml's own header). Its own
# [Ant 3], live-verified directly against St. John Gualbert's real Second
# Vespers (07-12-2026, no "Vespera de sequenti").
id: magnificat-antiphon-common-of-an-abbot
text:
la: "Hic vir despíciens mundum * et terréna, triúmphans, divítias cælo cóndidit ore, manu."
en: "Lo, a servant of God * who esteemed but little things earthly. And by word and work laid him up treasure in heaven."
status:
la: verified
en: verified
@@ -0,0 +1,23 @@
# Second Vespers Magnificat antiphon for `common-of-pope-martyrs`
# (Commune Plurimorum Martyrum Pontificum, Latin/Commune/C3b.txt) -- C3b
# has no [Ant] tags of its own, it's a pure `@Commune/C3` include for
# these (only Oratio/Lectio/Mass propers differ from plain
# common-of-several-martyrs), so this Common's real Second Vespers
# antiphon is C3's own [Ant 3] -- same underlying text as
# magnificat-antiphon-common-of-several-martyrs.yml. (The already-
# authored benedictus-antiphon-common-of-pope-martyrs.yml's distinct
# alleluia-toned "Filiae Jerusalem" text comes from a *different* file,
# Latin/Commune/C1p.txt, the Paschaltide-specific variant of this Common
# -- its live-query source date, 04-22-2042, happened to fall in
# Paschaltide. Not modeled separately here: getMagnificatAntiphon already
# wraps this Common-category fallback in withPaschaltideAlleluia, which
# appends an alleluia to this ordinary-time text during Paschaltide
# rather than swapping in a wholly different one -- the same simplification
# already accepted elsewhere for this fallback tier.)
id: magnificat-antiphon-common-of-pope-martyrs
text:
la: "Gaudent in cælis * ánimæ Sanctórum, qui Christi vestígia sunt secúti: et quia pro ejus amóre sánguinem suum fudérunt, ídeo cum Christo exsúltant sine fine."
en: "In heaven do rejoice the souls of the Saints * who have followed the steps of Christ; and because they shed their blood for the love of Christ, therefore shall they be made glad for ever with Christ."
status:
la: verified
en: verified
@@ -0,0 +1,17 @@
# Second Vespers Magnificat antiphon for `common-of-several-martyrs`
# (Commune Plurimorum Martyrum, Latin/Commune/C3.txt's own [Ant 3] --
# confirmed by file position and live-verified directly: Ss. Placid and
# Companions' own Second Vespers (10-05-2026, no "Vespera de sequenti")
# renders this exact text, while the evening before (10-04-2026, "Vespera
# de sequenti") renders C3's own [Ant 1] instead -- pins down Ant1 =
# First Vespers, Ant3 = Second Vespers for this file layout. Ant 2 in
# the same file matches the already-authored
# benedictus-antiphon-common-of-several-martyrs.yml's "Vestri capilli
# capitis" text exactly.
id: magnificat-antiphon-common-of-several-martyrs
text:
la: "Gaudent in cælis * ánimæ Sanctórum, qui Christi vestígia sunt secúti: et quia pro ejus amóre sánguinem suum fudérunt, ídeo cum Christo exsúltant sine fine."
en: "In heaven do rejoice the souls of the Saints * who have followed the steps of Christ; and because they shed their blood for the love of Christ, therefore shall they be made glad for ever with Christ."
status:
la: verified
en: verified
@@ -0,0 +1,14 @@
# Second Vespers Magnificat antiphon for `common-of-several-women-martyrs`
# (Commune plurimarum non Virginum Martyrum, Latin/Commune/C7b.txt) --
# its own [Ant 2] and [Ant 3] are both bare `@:Ant 1` cross-references,
# i.e. this small Common reuses one single antiphon at Lauds and both
# Vespers alike. Same text as the already-authored
# benedictus-antiphon-common-of-several-women-martyrs.yml (itself read
# from this file's [Ant 1]), by design, not by coincidence.
id: magnificat-antiphon-common-of-several-women-martyrs
text:
la: "Istárum est enim * regnum cælórum, quæ contempsérunt vitam mundi, et pervenérunt ad prǽmia regni, et lavérunt stolas suas in sánguine Agni."
en: "For theirs is * the Kingdom of heaven who love not their lives in this world, and have attained unto the reward of the Kingdom, and have washed their robes in the blood of the Lamb."
status:
la: verified
en: verified
@@ -0,0 +1,16 @@
# Second Vespers Magnificat antiphon for `common-of-the-bvm` (In Festis
# Beatae Mariae Virginis, Latin/Commune/C11.txt's own [Ant 3]) --
# fittingly the Magnificat's own opening line ("Beatam me dicent omnes
# generationes"). Discovered while sourcing this file that
# benedictus-antiphon-common-of-the-bvm.yml had been reading the wrong
# tag ([Ant 1], this Common's First Vespers antiphon, "Sancta Maria
# succurre miseris") instead of [Ant 2] (the real Lauds Benedictus
# antiphon, "Beata es Maria quae credidisti") -- corrected there in the
# same pass; see this file's own header note.
id: magnificat-antiphon-common-of-the-bvm
text:
la: "Beátam me dicent * omnes generatiónes, quia ancíllam húmilem respéxit Deus."
en: "All generations shall call me blessed, * for God hath regarded the lowliness of His hand-maiden."
status:
la: verified
en: verified
+18
View File
@@ -934,6 +934,24 @@ export function getMagnificatAntiphon(day: LiturgicalDay): ResolvedText {
return proper;
}
}
// A Vigil has no proper Magnificat antiphon of its own in the real rubric
// -- its `[Rule]` block ("ex C1v; ... Laudes 2") always borrows whatever
// the current ferial weekday's own antiphon is, live-verified across 4
// different years (2025-2028) at the Vigil of St. Andrew's own First
// Vespers: every one rendered "{Antiphona ex Proprio de Tempore}", never
// a fixed Common text. So a Vigil takes the same weekday-default fallback
// the plain temporal branch above uses, rather than falling through to
// `magnificat-antiphon-common-of-a-vigil` (deliberately never authored --
// there's no single fixed text to put there).
if (saint?.rank === 'vigil') {
const weekdayDefault = vespersMagnificatAntiphons[day.weekday];
if (weekdayDefault) {
const resolved = weekdayDefault.status
? { text: weekdayDefault.antiphon, status: weekdayDefault.status }
: verifiedText(weekdayDefault.antiphon);
return withPaschaltideAlleluia(resolved, day);
}
}
if (saint?.benedictusCommon) {
return withPaschaltideAlleluia(resolveCommon(`magnificat-antiphon-${saint.benedictusCommon}`), day);
}