Compare commits
2 Commits
ab8d1d452d
...
374d27858a
| Author | SHA1 | Date | |
|---|---|---|---|
| 374d27858a | |||
| 44dd4bb47a |
@@ -5461,3 +5461,48 @@ Updated 2 `FERIAL_DATE` (2026-12-01, a Tuesday *in Advent*) hymn assertions in
|
|||||||
`tests/hours/matins.test.ts` that had been asserting Tuesday's own ferial text — Advent's own
|
`tests/hours/matins.test.ts` that had been asserting Tuesday's own ferial text — Advent's own
|
||||||
seasonal hymn correctly outranks the weekday cycle now. `npm test` (2025 passed) and `tsc --noEmit`
|
seasonal hymn correctly outranks the weekday cycle now. `npm test` (2025 passed) and `tsc --noEmit`
|
||||||
both pass.
|
both pass.
|
||||||
|
|
||||||
|
### Ascension's own hymnody at Matins/Lauds/Vespers, plus the octave mechanism gap it exposed (2026-09-04)
|
||||||
|
|
||||||
|
User asked to actually close the Ascension-octave gap flagged in the entry just above. Turned out
|
||||||
|
to be a genuine mechanism gap, not just missing content: `ascension` is a *temporal*-feast id
|
||||||
|
(`data/calendar/temporal-feasts/ascension.yml`), not a saint record, so
|
||||||
|
`hours/resolve-common.ts`'s `resolveOfficeWinner` — which already synthesizes a sanctoral-shaped
|
||||||
|
winner from an active octave's own saint record (how Assumption's/St. Lawrence's octave already
|
||||||
|
gives every hour real content on interior days) — never recognized it at all. Ascension Day itself
|
||||||
|
and its whole octave were silently rendering the generic Paschaltide hymn at every hour, live-
|
||||||
|
verified against Divinum Officium (Monastic Tridentinum 1617, 2026-05-14, Ascension Day itself):
|
||||||
|
real content is "Jesu nostra redémptio" (identical at Matins/Lauds/Vespers), Act 1:1-2 (Lauds/
|
||||||
|
Vespers' shared chapter), and two genuinely distinct Lauds/Vespers responsories ("Ascéndit Deus in
|
||||||
|
jubilatióne" / "Ascéndens Christus in altum").
|
||||||
|
|
||||||
|
Fixed the mechanism two ways: (1) added `ascension` to `ALWAYS_OVERRIDE_TEMPORAL_IDS` (covers
|
||||||
|
Ascension Day itself, the same way `christ-the-king`/`circumcision`/etc. already do); (2) taught
|
||||||
|
`resolveOfficeWinner` to also synthesize a `{kind: 'temporal'}` winner from an active octave with no
|
||||||
|
saint record but a real temporal-feast record — covers ordinary-feria octave days (a real saint
|
||||||
|
still correctly keeps priority when one wins, e.g. St. Venantius/St. Peter Celestine within the
|
||||||
|
octave, live-verified unaffected). A third gap surfaced testing this: `octaveGoverningPrivilegedDay`
|
||||||
|
(the *Sunday*-side half of that same synthesis) has its own, separate, correct-by-design rule that a
|
||||||
|
privileged Sunday never accepts even an octave override — but live-verified wrong specifically for
|
||||||
|
"Dominica infra Octavam Ascensionis," which really does keep the octave's own hymn/responsory (just
|
||||||
|
with its own distinct proper chapter, not touched here). Rather than loosen that shared gate (real
|
||||||
|
risk of wrongly re-admitting some other octave's override on some other privileged Sunday, unverified
|
||||||
|
case by case), gave Lauds' and Vespers' own hymn-resolution functions (`resolveLaudsHymn`/
|
||||||
|
`resolveVespersHymn`) a narrow, hymn-only intercept: check `resolveActiveOctave` directly (no
|
||||||
|
privileged-Sunday gate) but only for a saint-less octave, before falling to the season/weekday
|
||||||
|
default — leaves every saint-based octave's existing behavior (and every other hour/part) completely
|
||||||
|
untouched.
|
||||||
|
|
||||||
|
Authored `matins-hymn-ascension.yml`, `lauds-{capitulum,responsory,hymn,versicle}-ascension.yml`,
|
||||||
|
and `vespers-{responsory,hymn,versicle}-ascension.yml` (Vespers' own chapter already falls back to
|
||||||
|
Lauds' via `vespersCapitulumForOverride`'s existing cross-hour fallback, so no separate file needed)
|
||||||
|
— all live-verified. Confirmed the whole octave end-to-end via `resolveOrdo` directly (Ascension Day,
|
||||||
|
two plain ordinary-feria octave days, the Sunday within the octave, and 3 real winning saints within
|
||||||
|
the window, all correct) rather than just the reference engine. `npm test` (2025 passed, no test
|
||||||
|
changes needed) and `tsc --noEmit` both pass.
|
||||||
|
|
||||||
|
Flagged, not fixed: Ascension's own collect is still missing (`getTemporalProper('ascension-collect')`
|
||||||
|
— a pre-existing gap, unrelated to and unaffected by this fix, not scoped to "hymnody"). Also flagged:
|
||||||
|
Pentecost/Corpus Christi/Sacred Heart are the same shape (temporal-feast octaves with no saint
|
||||||
|
record) and likely have the same latent hymn gap this fix closed for Ascension specifically — not
|
||||||
|
checked or fixed here.
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# The Ascension's own Lauds chapter (Acts 1:1-2) — shared with Vespers
|
||||||
|
# via vespersCapitulumForOverride's own cross-hour fallback (see
|
||||||
|
# hours/vespers.ts), not duplicated into a separate vespers-capitulum-
|
||||||
|
# ascension.yml. Live-verified against Divinum Officium (Monastic
|
||||||
|
# Tridentinum 1617), Lauds/Vespers live query, 2026-05-14 (Ascension Day
|
||||||
|
# itself) — see matins-hymn-ascension.yml's own header for the fuller
|
||||||
|
# mechanism story (a temporal-feast octave with no saint record wasn't
|
||||||
|
# being picked up at all before this).
|
||||||
|
id: lauds-capitulum-ascension
|
||||||
|
text:
|
||||||
|
la: "Primum quidem sermónem feci de ómnibus, o Theóphile, quæ cœpit Jesus fácere et docére usque in diem, qua præcípiens Apóstolis per Spíritum Sanctum, quos elégit, assúmptus est."
|
||||||
|
en: "The former treatise I made, O Theophilus, of all things which Jesus began to do and to teach, Until the day on which, giving commandments by the Holy Ghost to the apostles whom he had chosen, he was taken up."
|
||||||
|
citation:
|
||||||
|
la: "Act 1:1-2"
|
||||||
|
en: "Acts 1:1-2"
|
||||||
|
status:
|
||||||
|
la: verified
|
||||||
|
en: verified
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
# The Ascension's own Lauds hymn ("Jesu nostra redémptio") — identical
|
||||||
|
# text to Matins' own (matins-hymn-ascension.yml) and Vespers' own
|
||||||
|
# (vespers-hymn-ascension.yml). Live-verified against Divinum Officium
|
||||||
|
# (Monastic Tridentinum 1617), Lauds live query, 2026-05-14 (Ascension
|
||||||
|
# Day itself). Self-contained — this hour's own resolveOfficeBundle
|
||||||
|
# doesn't run a hymn through the doxology-split/append mechanism at all,
|
||||||
|
# and this hymn's own natural ending has no separate doxology stanza in
|
||||||
|
# the source anyway.
|
||||||
|
id: lauds-hymn-ascension
|
||||||
|
text:
|
||||||
|
la: >-
|
||||||
|
Jesu nostra redémptio,
|
||||||
|
|
||||||
|
Amor et desidérium,
|
||||||
|
|
||||||
|
Deus Creátor ómnium,
|
||||||
|
|
||||||
|
Homo in fine témporum:
|
||||||
|
|
||||||
|
|
||||||
|
Quæ te vicit cleméntia,
|
||||||
|
|
||||||
|
Ut ferres nostra crímina,
|
||||||
|
|
||||||
|
Crudélem mortem pátiens,
|
||||||
|
|
||||||
|
Ut nos a morte tólleres!
|
||||||
|
|
||||||
|
|
||||||
|
Inférni claustra pénetrans,
|
||||||
|
|
||||||
|
Tuos captívos rédimens,
|
||||||
|
|
||||||
|
Victor triúmpho nóbili
|
||||||
|
|
||||||
|
Ad dextram Patris résidens.
|
||||||
|
|
||||||
|
|
||||||
|
Ipsa te cogat píetas,
|
||||||
|
|
||||||
|
Ut mala nostra súperes
|
||||||
|
|
||||||
|
Parcéndo, et voti cómpotes
|
||||||
|
|
||||||
|
Nos tuo vultu sáties.
|
||||||
|
|
||||||
|
|
||||||
|
Tu esto nostrum gáudium,
|
||||||
|
|
||||||
|
Qui es futúrus prǽmium,
|
||||||
|
|
||||||
|
Sit nostra in te glória,
|
||||||
|
|
||||||
|
Per cuncta semper sǽcula. Amen.
|
||||||
|
en: >-
|
||||||
|
Hail, thou who man's Redeemer art,
|
||||||
|
|
||||||
|
Jesu, the joy of every heart;
|
||||||
|
|
||||||
|
Great Maker of the world's wide frame,
|
||||||
|
|
||||||
|
And purest love's delight and flame:
|
||||||
|
|
||||||
|
|
||||||
|
What nameless mercy thee o'ercame,
|
||||||
|
|
||||||
|
To bear our load of sin and shame?
|
||||||
|
|
||||||
|
For guiltless, thou thy life didst give,
|
||||||
|
|
||||||
|
That sinful erring man might live.
|
||||||
|
|
||||||
|
|
||||||
|
The realms of woe are forced by thee,
|
||||||
|
|
||||||
|
Its captives from their chains set free;
|
||||||
|
|
||||||
|
And thou, amid thy ransomed train,
|
||||||
|
|
||||||
|
At God's right hand dost victor reign.
|
||||||
|
|
||||||
|
|
||||||
|
Let mercy sweet with thee prevail,
|
||||||
|
|
||||||
|
To cure the wounds we now bewail;
|
||||||
|
|
||||||
|
Oh, bless us with thy holy sight,
|
||||||
|
|
||||||
|
And fill us with eternal light.
|
||||||
|
|
||||||
|
|
||||||
|
Our guide, our way to heavenly rest,
|
||||||
|
|
||||||
|
Be thou the aim of every breast;
|
||||||
|
|
||||||
|
Be thou the soother of our tears,
|
||||||
|
|
||||||
|
Our sweet reward above the spheres. Amen.
|
||||||
|
status:
|
||||||
|
la: verified
|
||||||
|
en: verified
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# The Ascension's own Lauds responsory ("Ascéndit Deus in jubilatióne")
|
||||||
|
# — distinct from Vespers' own ("Ascéndens Christus in altum", see
|
||||||
|
# vespers-responsory-ascension.yml). Live-verified against Divinum
|
||||||
|
# Officium (Monastic Tridentinum 1617), Lauds live query, 2026-05-14
|
||||||
|
# (Ascension Day itself).
|
||||||
|
id: lauds-responsory-ascension
|
||||||
|
text:
|
||||||
|
la: |
|
||||||
|
R.br. Ascéndit Deus in jubilatióne, * Allelúja, allelúja.
|
||||||
|
R. Ascéndit Deus in jubilatióne, * Allelúja, allelúja.
|
||||||
|
V. Et Dóminus in voce tubæ.
|
||||||
|
R. Allelúja, allelúja.
|
||||||
|
V. Glória Patri, et Fílio, * et Spirítui Sancto.
|
||||||
|
R. Ascéndit Deus in jubilatióne, * Allelúja, allelúja.
|
||||||
|
en: |
|
||||||
|
R.br. God is gone up with jubilation. * Alleluia, alleluia.
|
||||||
|
R. God is gone up with jubilation. * Alleluia, alleluia.
|
||||||
|
V. And the Lord with the sound of trumpet.
|
||||||
|
R. Alleluia, alleluia.
|
||||||
|
V. Glory be to the Father, and to the Son, * and to the Holy Ghost.
|
||||||
|
R. God is gone up with jubilation. * Alleluia, alleluia.
|
||||||
|
status:
|
||||||
|
la: verified
|
||||||
|
en: verified
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# The Ascension's own versicle — identical at both Lauds and Vespers
|
||||||
|
# (see vespers-versicle-ascension.yml). Live-verified against Divinum
|
||||||
|
# Officium (Monastic Tridentinum 1617), Lauds/Vespers live query,
|
||||||
|
# 2026-05-14 (Ascension Day itself).
|
||||||
|
id: lauds-versicle-ascension
|
||||||
|
text:
|
||||||
|
la: "V. Dóminus in cælo, allelúja.\nR. Parávit sedem suam, allelúja."
|
||||||
|
en: "V. The Lord in heaven, alleluia.\nR. Hath prepared his throne, alleluia."
|
||||||
|
status:
|
||||||
|
la: verified
|
||||||
|
en: verified
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
# The Ascension's own Matins hymn ("Jesu nostra redémptio"), shared
|
||||||
|
# identically with its own Lauds and Vespers (see lauds-hymn-ascension.yml/
|
||||||
|
# vespers-hymn-ascension.yml). Live-verified against Divinum Officium
|
||||||
|
# (Monastic Tridentinum 1617), Matins/Lauds/Vespers live query, 2026-05-14
|
||||||
|
# (Ascension Day itself).
|
||||||
|
#
|
||||||
|
# Closes a real gap found while fixing the generic Matins seasonal-hymn
|
||||||
|
# fallback (see matins-hymn-paschaltide.yml's own header): 'ascension' is
|
||||||
|
# a temporal-feast id (calendar/data/calendar/temporal-feasts/
|
||||||
|
# ascension.yml), not a saint record, so it was never picked up by
|
||||||
|
# `resolveOfficeWinner`'s octave-synthesis (which only ever checked
|
||||||
|
# `getSaintRecord`) — Ascension Day itself and its whole octave were both
|
||||||
|
# silently rendering the generic Paschaltide hymn instead of their own
|
||||||
|
# proper one, at every hour. Fixed by (1) adding `ascension` to
|
||||||
|
# `ALWAYS_OVERRIDE_TEMPORAL_IDS` (covers Ascension Day itself) and (2)
|
||||||
|
# teaching `resolveOfficeWinner` to also synthesize a `{kind: 'temporal'}`
|
||||||
|
# winner from a temporal-feast-only active octave when no saint record
|
||||||
|
# exists (covers the interior octave days, e.g. St. Ubald's or St.
|
||||||
|
# Bernardine's own days still correctly win outright and keep their own
|
||||||
|
# hymn — this only ever fires on a day nothing else claims).
|
||||||
|
#
|
||||||
|
# Self-contained — this hymn's own natural ending ("Per cuncta semper
|
||||||
|
# sǽcula. Amen.") has no separate trailing doxology stanza at all in the
|
||||||
|
# source, unlike most other Matins hymns in this store.
|
||||||
|
id: matins-hymn-ascension
|
||||||
|
text:
|
||||||
|
la: >-
|
||||||
|
Jesu nostra redémptio,
|
||||||
|
|
||||||
|
Amor et desidérium,
|
||||||
|
|
||||||
|
Deus Creátor ómnium,
|
||||||
|
|
||||||
|
Homo in fine témporum:
|
||||||
|
|
||||||
|
|
||||||
|
Quæ te vicit cleméntia,
|
||||||
|
|
||||||
|
Ut ferres nostra crímina,
|
||||||
|
|
||||||
|
Crudélem mortem pátiens,
|
||||||
|
|
||||||
|
Ut nos a morte tólleres!
|
||||||
|
|
||||||
|
|
||||||
|
Inférni claustra pénetrans,
|
||||||
|
|
||||||
|
Tuos captívos rédimens,
|
||||||
|
|
||||||
|
Victor triúmpho nóbili
|
||||||
|
|
||||||
|
Ad dextram Patris résidens.
|
||||||
|
|
||||||
|
|
||||||
|
Ipsa te cogat píetas,
|
||||||
|
|
||||||
|
Ut mala nostra súperes
|
||||||
|
|
||||||
|
Parcéndo, et voti cómpotes
|
||||||
|
|
||||||
|
Nos tuo vultu sáties.
|
||||||
|
|
||||||
|
|
||||||
|
Tu esto nostrum gáudium,
|
||||||
|
|
||||||
|
Qui es futúrus prǽmium,
|
||||||
|
|
||||||
|
Sit nostra in te glória,
|
||||||
|
|
||||||
|
Per cuncta semper sǽcula. Amen.
|
||||||
|
en: >-
|
||||||
|
Hail, thou who man's Redeemer art,
|
||||||
|
|
||||||
|
Jesu, the joy of every heart;
|
||||||
|
|
||||||
|
Great Maker of the world's wide frame,
|
||||||
|
|
||||||
|
And purest love's delight and flame:
|
||||||
|
|
||||||
|
|
||||||
|
What nameless mercy thee o'ercame,
|
||||||
|
|
||||||
|
To bear our load of sin and shame?
|
||||||
|
|
||||||
|
For guiltless, thou thy life didst give,
|
||||||
|
|
||||||
|
That sinful erring man might live.
|
||||||
|
|
||||||
|
|
||||||
|
The realms of woe are forced by thee,
|
||||||
|
|
||||||
|
Its captives from their chains set free;
|
||||||
|
|
||||||
|
And thou, amid thy ransomed train,
|
||||||
|
|
||||||
|
At God's right hand dost victor reign.
|
||||||
|
|
||||||
|
|
||||||
|
Let mercy sweet with thee prevail,
|
||||||
|
|
||||||
|
To cure the wounds we now bewail;
|
||||||
|
|
||||||
|
Oh, bless us with thy holy sight,
|
||||||
|
|
||||||
|
And fill us with eternal light.
|
||||||
|
|
||||||
|
|
||||||
|
Our guide, our way to heavenly rest,
|
||||||
|
|
||||||
|
Be thou the aim of every breast;
|
||||||
|
|
||||||
|
Be thou the soother of our tears,
|
||||||
|
|
||||||
|
Our sweet reward above the spheres. Amen.
|
||||||
|
status:
|
||||||
|
la: verified
|
||||||
|
en: verified
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
# The Ascension's own Vespers hymn ("Jesu nostra redémptio") — identical
|
||||||
|
# text to Matins' own (matins-hymn-ascension.yml) and Lauds' own
|
||||||
|
# (lauds-hymn-ascension.yml). Live-verified against Divinum Officium
|
||||||
|
# (Monastic Tridentinum 1617), Vespers live query, 2026-05-14 (Ascension
|
||||||
|
# Day itself).
|
||||||
|
id: vespers-hymn-ascension
|
||||||
|
text:
|
||||||
|
la: >-
|
||||||
|
Jesu nostra redémptio,
|
||||||
|
|
||||||
|
Amor et desidérium,
|
||||||
|
|
||||||
|
Deus Creátor ómnium,
|
||||||
|
|
||||||
|
Homo in fine témporum:
|
||||||
|
|
||||||
|
|
||||||
|
Quæ te vicit cleméntia,
|
||||||
|
|
||||||
|
Ut ferres nostra crímina,
|
||||||
|
|
||||||
|
Crudélem mortem pátiens,
|
||||||
|
|
||||||
|
Ut nos a morte tólleres!
|
||||||
|
|
||||||
|
|
||||||
|
Inférni claustra pénetrans,
|
||||||
|
|
||||||
|
Tuos captívos rédimens,
|
||||||
|
|
||||||
|
Victor triúmpho nóbili
|
||||||
|
|
||||||
|
Ad dextram Patris résidens.
|
||||||
|
|
||||||
|
|
||||||
|
Ipsa te cogat píetas,
|
||||||
|
|
||||||
|
Ut mala nostra súperes
|
||||||
|
|
||||||
|
Parcéndo, et voti cómpotes
|
||||||
|
|
||||||
|
Nos tuo vultu sáties.
|
||||||
|
|
||||||
|
|
||||||
|
Tu esto nostrum gáudium,
|
||||||
|
|
||||||
|
Qui es futúrus prǽmium,
|
||||||
|
|
||||||
|
Sit nostra in te glória,
|
||||||
|
|
||||||
|
Per cuncta semper sǽcula. Amen.
|
||||||
|
en: >-
|
||||||
|
Hail, thou who man's Redeemer art,
|
||||||
|
|
||||||
|
Jesu, the joy of every heart;
|
||||||
|
|
||||||
|
Great Maker of the world's wide frame,
|
||||||
|
|
||||||
|
And purest love's delight and flame:
|
||||||
|
|
||||||
|
|
||||||
|
What nameless mercy thee o'ercame,
|
||||||
|
|
||||||
|
To bear our load of sin and shame?
|
||||||
|
|
||||||
|
For guiltless, thou thy life didst give,
|
||||||
|
|
||||||
|
That sinful erring man might live.
|
||||||
|
|
||||||
|
|
||||||
|
The realms of woe are forced by thee,
|
||||||
|
|
||||||
|
Its captives from their chains set free;
|
||||||
|
|
||||||
|
And thou, amid thy ransomed train,
|
||||||
|
|
||||||
|
At God's right hand dost victor reign.
|
||||||
|
|
||||||
|
|
||||||
|
Let mercy sweet with thee prevail,
|
||||||
|
|
||||||
|
To cure the wounds we now bewail;
|
||||||
|
|
||||||
|
Oh, bless us with thy holy sight,
|
||||||
|
|
||||||
|
And fill us with eternal light.
|
||||||
|
|
||||||
|
|
||||||
|
Our guide, our way to heavenly rest,
|
||||||
|
|
||||||
|
Be thou the aim of every breast;
|
||||||
|
|
||||||
|
Be thou the soother of our tears,
|
||||||
|
|
||||||
|
Our sweet reward above the spheres. Amen.
|
||||||
|
status:
|
||||||
|
la: verified
|
||||||
|
en: verified
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# The Ascension's own Vespers responsory ("Ascéndens Christus in
|
||||||
|
# altum") — distinct from Lauds' own ("Ascéndit Deus in jubilatióne",
|
||||||
|
# see lauds-responsory-ascension.yml). Live-verified against Divinum
|
||||||
|
# Officium (Monastic Tridentinum 1617), Vespers live query, 2026-05-14
|
||||||
|
# (Ascension Day itself).
|
||||||
|
id: vespers-responsory-ascension
|
||||||
|
text:
|
||||||
|
la: |
|
||||||
|
R.br. Ascéndens Christus in altum, * Allelúja, allelúja.
|
||||||
|
R. Ascéndens Christus in altum, * Allelúja, allelúja.
|
||||||
|
V. Captívam duxit captivitátem.
|
||||||
|
R. Allelúja, allelúja.
|
||||||
|
V. Glória Patri, et Fílio, * et Spirítui Sancto.
|
||||||
|
R. Ascéndens Christus in altum, * Allelúja, allelúja.
|
||||||
|
en: |
|
||||||
|
R.br. When Christ ascended up on high. * Alleluia, alleluia.
|
||||||
|
R. When Christ ascended up on high. * Alleluia, alleluia.
|
||||||
|
V. He led captivity captive.
|
||||||
|
R. Alleluia, alleluia.
|
||||||
|
V. Glory be to the Father, and to the Son, * and to the Holy Ghost.
|
||||||
|
R. When Christ ascended up on high. * Alleluia, alleluia.
|
||||||
|
status:
|
||||||
|
la: verified
|
||||||
|
en: verified
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# The Ascension's own versicle — identical at both Vespers and Lauds
|
||||||
|
# (see lauds-versicle-ascension.yml). Live-verified against Divinum
|
||||||
|
# Officium (Monastic Tridentinum 1617), Vespers live query, 2026-05-14
|
||||||
|
# (Ascension Day itself).
|
||||||
|
id: vespers-versicle-ascension
|
||||||
|
text:
|
||||||
|
la: "V. Dóminus in cælo, allelúja.\nR. Parávit sedem suam, allelúja."
|
||||||
|
en: "V. The Lord in heaven, alleluia.\nR. Hath prepared his throne, alleluia."
|
||||||
|
status:
|
||||||
|
la: verified
|
||||||
|
en: verified
|
||||||
+21
-1
@@ -1,6 +1,7 @@
|
|||||||
import type { HourDefinition, HourPart, ResolvedOrdo, ResolvedPart, ResolvedText } from './types';
|
import type { HourDefinition, HourPart, ResolvedOrdo, ResolvedPart, ResolvedText } from './types';
|
||||||
import type { LiturgicalDay, Weekday } from '../calendar/types';
|
import type { LiturgicalDay, Weekday } from '../calendar/types';
|
||||||
import { resolveDay } from '../calendar';
|
import { resolveDay, resolveActiveOctave } from '../calendar';
|
||||||
|
import { getSaintRecord } from '../calendar/feasts';
|
||||||
import { getDayLabel } from '../calendar/day-label';
|
import { getDayLabel } from '../calendar/day-label';
|
||||||
import { getPsalmVerses } from '../psalter';
|
import { getPsalmVerses } from '../psalter';
|
||||||
import { getCanticle, type CanticleVerse } from './lauds-canticles';
|
import { getCanticle, type CanticleVerse } from './lauds-canticles';
|
||||||
@@ -282,6 +283,25 @@ function resolvePsalmody(day: LiturgicalDay): ResolvedPart[] {
|
|||||||
* exact original text.
|
* exact original text.
|
||||||
*/
|
*/
|
||||||
function resolveLaudsHymn(day: LiturgicalDay, key: string): ResolvedText {
|
function resolveLaudsHymn(day: LiturgicalDay, key: string): ResolvedText {
|
||||||
|
// A temporal-feast-only octave (Ascension's own — no saint record, so
|
||||||
|
// resolveOfficeWinner's own octave-synthesis can't help here on a
|
||||||
|
// privileged Sunday, whose `octaveGoverningPrivilegedDay` gate is
|
||||||
|
// correctly closed to a real *saint* overriding it but wrongly also
|
||||||
|
// closes the *octave's own* hymn — live-verified wrong: "Dominica infra
|
||||||
|
// Octavam Ascensionis" still uses Ascension's own hymn/responsory, just
|
||||||
|
// with its own distinct proper chapter) still needs its own hymn
|
||||||
|
// recognized here directly via resolveActiveOctave (no privileged-
|
||||||
|
// Sunday gate) — checked before the plain season/weekday fallback, but
|
||||||
|
// deliberately not touched at the chapter/responsory/versicle level:
|
||||||
|
// this Sunday's own chapter genuinely differs from Ascension Day's own,
|
||||||
|
// so folding the whole bundle through the octave id would be wrong.
|
||||||
|
const octave = resolveActiveOctave(day.date);
|
||||||
|
if (octave && !getSaintRecord(octave.id)) {
|
||||||
|
const octaveHymn = resolveCommon(`lauds-hymn-${octave.id}`);
|
||||||
|
if (octaveHymn.status.la !== 'missing' || octaveHymn.status.en !== 'missing') {
|
||||||
|
return octaveHymn;
|
||||||
|
}
|
||||||
|
}
|
||||||
const body = resolveCommon(`lauds-hymn-${key}`);
|
const body = resolveCommon(`lauds-hymn-${key}`);
|
||||||
const doxology = resolveCommon(getHymnDoxologyId(day, `lauds-hymn-${key}-doxology-per-annum`));
|
const doxology = resolveCommon(getHymnDoxologyId(day, `lauds-hymn-${key}-doxology-per-annum`));
|
||||||
return appendDoxology(body, doxology);
|
return appendDoxology(body, doxology);
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ export const ALWAYS_OVERRIDE_TEMPORAL_IDS = new Set([
|
|||||||
'christ-the-king',
|
'christ-the-king',
|
||||||
'christmas-octave-sunday',
|
'christmas-octave-sunday',
|
||||||
'immaculate-heart-of-mary',
|
'immaculate-heart-of-mary',
|
||||||
|
'ascension',
|
||||||
'circumcision',
|
'circumcision',
|
||||||
'holy-name-of-jesus',
|
'holy-name-of-jesus',
|
||||||
'vigil-of-christmas',
|
'vigil-of-christmas',
|
||||||
@@ -124,6 +125,16 @@ export function resolveOfficeWinner(day: LiturgicalDay): DayWinner {
|
|||||||
if (saint) {
|
if (saint) {
|
||||||
return { kind: 'sanctoral', id: saint.id, name: saint.name, rank: saint.rank };
|
return { kind: 'sanctoral', id: saint.id, name: saint.name, rank: saint.rank };
|
||||||
}
|
}
|
||||||
|
// A temporal-feast-only octave (Ascension's own — no saint record to
|
||||||
|
// synthesize from, unlike Assumption's/St. Lawrence's) still needs its
|
||||||
|
// own content recognized on interior octave days, the same way its own
|
||||||
|
// feast day already is via the `ALWAYS_OVERRIDE_TEMPORAL_IDS` check
|
||||||
|
// above — found 2026-09-04 via the Matins seasonal-hymn fallback
|
||||||
|
// silently rendering the generic Paschaltide text throughout the whole
|
||||||
|
// Ascension octave, not just a missing-content gap on the day itself.
|
||||||
|
if (ALWAYS_OVERRIDE_TEMPORAL_IDS.has(activeOctave.id) && getTemporalFeastRecord(activeOctave.id)) {
|
||||||
|
return { kind: 'temporal', id: activeOctave.id };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return day.winner;
|
return day.winner;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import type { HourDefinition, HourPart, ResolvedOrdo, ResolvedPart, ResolvedText
|
|||||||
import type { LiturgicalDay, Weekday } from '../calendar/types';
|
import type { LiturgicalDay, Weekday } from '../calendar/types';
|
||||||
import { resolveEveningDay } from '../calendar/vespers';
|
import { resolveEveningDay } from '../calendar/vespers';
|
||||||
import { weekdayOf } from '../calendar/weekday';
|
import { weekdayOf } from '../calendar/weekday';
|
||||||
|
import { resolveActiveOctave } from '../calendar';
|
||||||
|
import { getSaintRecord } from '../calendar/feasts';
|
||||||
import { getDayLabel } from '../calendar/day-label';
|
import { getDayLabel } from '../calendar/day-label';
|
||||||
import { getPsalmVerses } from '../psalter';
|
import { getPsalmVerses } from '../psalter';
|
||||||
import { getOpeningVersicleId } from './opening-versicle';
|
import { getOpeningVersicleId } from './opening-versicle';
|
||||||
@@ -190,6 +192,19 @@ function vespersCapitulumForOverride(id: string): ResolvedText {
|
|||||||
* Advent, Lent — the source itself never swaps those) reproduces the
|
* Advent, Lent — the source itself never swaps those) reproduces the
|
||||||
* exact original text. See lauds.ts's identical resolveLaudsHymn. */
|
* exact original text. See lauds.ts's identical resolveLaudsHymn. */
|
||||||
function resolveVespersHymn(day: LiturgicalDay, key: string): ResolvedText {
|
function resolveVespersHymn(day: LiturgicalDay, key: string): ResolvedText {
|
||||||
|
// A temporal-feast-only octave (Ascension's own) still needs its own
|
||||||
|
// hymn recognized directly here, bypassing octaveGoverningPrivilegedDay's
|
||||||
|
// privileged-Sunday gate — see lauds.ts's identical resolveLaudsHymn for
|
||||||
|
// the full story. Guarded to saint-less octaves only: a saint-based
|
||||||
|
// octave (Assumption's, St. Lawrence's) already reaches its own content
|
||||||
|
// through resolveOfficeWinner's existing synthesis without this.
|
||||||
|
const octave = resolveActiveOctave(day.date);
|
||||||
|
if (octave && !getSaintRecord(octave.id)) {
|
||||||
|
const octaveHymn = resolveCommon(`vespers-hymn-${octave.id}`);
|
||||||
|
if (octaveHymn.status.la !== 'missing' || octaveHymn.status.en !== 'missing') {
|
||||||
|
return octaveHymn;
|
||||||
|
}
|
||||||
|
}
|
||||||
const body = resolveCommon(`vespers-hymn-${key}`);
|
const body = resolveCommon(`vespers-hymn-${key}`);
|
||||||
const doxology = resolveCommon(getHymnDoxologyId(day, `vespers-hymn-${key}-doxology-per-annum`));
|
const doxology = resolveCommon(getHymnDoxologyId(day, `vespers-hymn-${key}-doxology-per-annum`));
|
||||||
return appendDoxology(body, doxology);
|
return appendDoxology(body, doxology);
|
||||||
|
|||||||
Reference in New Issue
Block a user