From e7e19c530af2c89e9716e1e2b3559e9d0e19db62 Mon Sep 17 00:00:00 2001 From: Will Estes Date: Fri, 4 Sep 2026 10:38:05 -0400 Subject: [PATCH] Author Sunday's own Matins hymn and every season's (Advent-Paschaltide) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "genuinely more complex, not-yet-understood two-hymn mechanism" flagged for Sunday turned out simple: Day0 Hymnus ("Nocte surgéntes") is just Sunday's plain per-annum hymn, and Day0 Hymnus1 ("Primo diérum ómnium") is Septuagesima-tide's own separate seasonal hymn -- the same shape Advent/Lent/Passiontide/Paschaltide each already have. Live-verified these 4 don't vary by weekday within their season (a Lenten Sunday and a Lenten feria render identically). None of the 6 were authored at all before this -- every Sunday and every season day not otherwise overridden by a winning saint/octave silently fell through to Monday's own ferial placeholder text. Authored matins-hymn-{sunday,septuagesima,advent,lent,passiontide, paschaltide}.yml, all live-verified, self-contained with their own real closing doxology baked in. Septuagesima is checked directly by day.season in resolveMatinsHymn itself, deliberately not folded into the shared seasonalOfficeSuffix (Lauds/Vespers have no matching content yet -- resolveOfficeBundle there is all-or-nothing per feast, so adding it would silently blank their chapter/hymn instead of falling through to their current weekday default). Known, flagged simplification: the generic Paschaltide hymn wrongly applies during the Ascension octave, whose own real hymn isn't authored anywhere yet -- a same-shape gap Lauds already has, not a new regression. Updated 2 FERIAL_DATE (a Tuesday in Advent) hymn assertions that had been asserting Tuesday's own ferial text -- Advent's own seasonal hymn correctly outranks the weekday cycle now. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01AGjUyhUZJaSjiniEmnLdak --- .../propers/common/matins-hymn-advent.yml | 100 ++++++++++ .../propers/common/matins-hymn-ferial.yml | 16 +- src/data/propers/common/matins-hymn-lent.yml | 173 ++++++++++++++++ .../common/matins-hymn-paschaltide.yml | 185 ++++++++++++++++++ .../common/matins-hymn-passiontide.yml | 170 ++++++++++++++++ .../common/matins-hymn-septuagesima.yml | 174 ++++++++++++++++ .../propers/common/matins-hymn-sunday.yml | 80 ++++++++ src/hours/matins.ts | 30 ++- tests/hours/matins.test.ts | 17 +- 9 files changed, 926 insertions(+), 19 deletions(-) create mode 100644 src/data/propers/common/matins-hymn-advent.yml create mode 100644 src/data/propers/common/matins-hymn-lent.yml create mode 100644 src/data/propers/common/matins-hymn-paschaltide.yml create mode 100644 src/data/propers/common/matins-hymn-passiontide.yml create mode 100644 src/data/propers/common/matins-hymn-septuagesima.yml create mode 100644 src/data/propers/common/matins-hymn-sunday.yml diff --git a/src/data/propers/common/matins-hymn-advent.yml b/src/data/propers/common/matins-hymn-advent.yml new file mode 100644 index 0000000..0f218d0 --- /dev/null +++ b/src/data/propers/common/matins-hymn-advent.yml @@ -0,0 +1,100 @@ +# Advent's own Matins hymn ("Verbum supérnum, pródiens"). Live-verified +# against both a plain Advent Sunday and a plain Advent feria +# (2026-12-10, a Thursday with no saint of its own) — byte-identical, so +# this season doesn't vary its Matins hymn by weekday the way the plain +# per-annum ferial cycle does. Self-contained with its own closing +# doxology stanza baked in (a fixed, unique ending, "Laus, honor, virtus, +# glória... In sæculórum sǽcula" — not the shared weekday doxology). +id: matins-hymn-advent +text: + la: >- + Verbum supérnum, pródiens + + A Patre olim éxiens, + + Qui natus orbi súbvenis, + + Cursu declívi témporis. + + + Illúmina nunc péctora, + + Tuóque amóre cóncrema; + + Audíto ut præcónio + + Sint pulsa tandem lúbrica. + + + Judéxque cum post áderis + + Rimári facta péctoris, + + Reddens vicem pro ábditis, + + Justísque regnum pro bonis. + + + Non demum arctémur malis + + Pro qualitáte críminis; + + Sed cum beátis cómpotes + + Simus perénnes cælibes. + + + Laus, honor, virtus, glória, + + Deo Patri, et Fílio, + + Sancto simul Paráclito, + + In sæculórum sǽcula. Amen. + en: >- + Celestial Word, to this our earth + + Sent down from God's eternal clime, + + To save mankind by mortal birth + + Into a world of change and time; + + + Enlighten our hearts; vain hopes destroy; + + And in thy love's consuming fire + + Fill all the soul with heavenly joy, + + And melt the dross of low desire. + + + So when the Judge of quick and dead + + Shall bid his awful summons come, + + To whelm the guilty soul with dread, + + And call the blessed to their home. + + + Saved from the whirling, black abyss, + + Forevermore to us be given + + To share the feast of saintly bliss, + + And see the face of God in heaven. + + + To God the Father and the Son + + Our songs with one accord we raise; + + And to the Holy Spirit, One + + With them, be ever equal praise. Amen. +status: + la: verified + en: verified diff --git a/src/data/propers/common/matins-hymn-ferial.yml b/src/data/propers/common/matins-hymn-ferial.yml index 40e256f..05983aa 100644 --- a/src/data/propers/common/matins-hymn-ferial.yml +++ b/src/data/propers/common/matins-hymn-ferial.yml @@ -10,15 +10,13 @@ # `resolveMatinsHymn` now looks up a weekday-specific id # (`matins-hymn-ferial-tuesday`/`-wednesday`/`-thursday`/`-friday`/ # `-saturday`) for those five days; this file (`matins-hymn-ferial`, no -# day suffix) is still used directly for Monday, and — as a deliberate, -# documented placeholder, not yet its own real content — for Sunday too: -# Sunday's own real Matins hymn selection is a genuinely more complex, -# not-yet-modeled two-hymn mechanism (Day0 Hymnus vs Hymnus1, live source -# tags H-MatDom1/H-MatDom4, purpose unconfirmed). Saturday's own gap -# (superseded on nearly every ordinary Saturday by Marian Saturday, not a -# full Little Office — see matins-hymn-ferial-saturday.yml and -# calendar/index.ts's applyMarianSaturday) was closed the same day. See -# TODO.md's 2026-09-04 entries. +# day suffix) is still used directly for Monday. Sunday's own gap (turned +# out simple, not the "genuinely more complex two-hymn mechanism" first +# suspected — see matins-hymn-sunday.yml's own header) and Saturday's own +# gap (superseded on nearly every ordinary Saturday by Marian Saturday, +# not a full Little Office — see matins-hymn-ferial-saturday.yml and +# calendar/index.ts's applyMarianSaturday) were both closed the same +# session. See TODO.md's 2026-09-04 entries. # # The closing doxology stanza is split out into # matins-hymn-doxology-per-annum.yml (see hours/matins.ts) — the source diff --git a/src/data/propers/common/matins-hymn-lent.yml b/src/data/propers/common/matins-hymn-lent.yml new file mode 100644 index 0000000..81dd249 --- /dev/null +++ b/src/data/propers/common/matins-hymn-lent.yml @@ -0,0 +1,173 @@ +# Lent's own Matins hymn ("Ex more docti mýstico"), used throughout Lent +# up to (not including) Passiontide, which has its own separate hymn +# (`matins-hymn-passiontide.yml`). Live-verified against both a plain +# Lenten Sunday (2026-03-01) and a plain Lenten feria (2026-03-03, a +# Tuesday) — byte-identical, so this season doesn't vary its Matins hymn +# by weekday. Self-contained with its own closing doxology stanza baked +# in (a fixed, unique ending, "Præsta, beáta Trínitas..." — not the +# shared weekday doxology). +id: matins-hymn-lent +text: + la: >- + Ex more docti mýstico + + Servémus hoc jejúnium, + + Deno diérum círculo + + Ducto quater notíssimo. + + + Lex et prophétæ prímitus + + Hoc prætulérunt, póstmodum + + Christus sacrávit, ómnium + + Rex atque factor témporum. + + + Utámur ergo párcius + + Verbis, cibis et pótibus, + + Somno, jocis, et árctius + + Perstémus in custódia. + + + Vitémus autem péssima, + + Quæ súbruunt mentes vagas: + + Nullúmque demus cállidi + + Hostis locum tyránnidi. + + + Dicámus omnes cérnui: + + Clamémus atque sínguli, + + Plorémus ante Júdicem, + + Flectámus iram víndicem, + + + Nostris malis offéndimus + + Tuam, Deus, cleméntiam: + + Effúnde nobis désuper, + + Remíssor, indulgéntiam. + + + Meménto quod sumus tui, + + Licet cadúci, plásmatis: + + Ne des honórem nóminis + + Tui, precámur, álteri. + + + Laxa malum, quod fécimus, + + Auge bonum, quod póscimus: + + Placére quo tandem tibi + + Possímus hic, et pérpetim. + + + Præsta, beáta Trínitas, + + Concéde, simplex Únitas, + + Ut fructuósa sint tuis + + Jejuniórum múnera. Amen. + en: >- + The fast, as taught by holy lore, + + We keep in solemn course once more: + + The fast to all men known, and bound + + In forty days of yearly round. + + + The law and seers that were of old + + In diverse ways this Lent foretold, + + Which Christ, all seasons' King and Guide, + + In after ages sanctified. + + + More sparing therefore let us make + + The words we speak, the food we take, + + Our sleep and mirth, and closer barred + + Be every sense in holy guard. + + + Avoid the evil thoughts that roll + + Like waters o'er the heedless soul; + + Nor let the foe occasion find + + Our souls in slavery to bind. + + + In prayer together let us fall, + + And cry for mercy, one and all, + + And weep before the Judge's feet, + + And his avenging wrath entreat. + + + Thy grace have we offended sore, + + By sins, O God, which we deplore; + + But pour upon us from on high, + + O pardoning One, thy clemency. + + + Remember thou, though frail we be, + + That yet thine handiwork are we; + + Nor let the honour of thy name + + Be by another put to shame. + + + Forgive the sin that we have wrought; + + Increase the good that we have sought: + + That we at length, our wanderings o'er, + + May please thee here and evermore. + + + Grant O thou Blessed Trinity, + + Grant, O Essential Unity, + + That this our fast of forty days + + May work our profit and thy praise. Amen. +status: + la: verified + en: verified diff --git a/src/data/propers/common/matins-hymn-paschaltide.yml b/src/data/propers/common/matins-hymn-paschaltide.yml new file mode 100644 index 0000000..8969958 --- /dev/null +++ b/src/data/propers/common/matins-hymn-paschaltide.yml @@ -0,0 +1,185 @@ +# Paschaltide's own Matins hymn ("Rex sempitérne Dómine"), live-verified +# against a plain post-Easter-Octave feria (2026-04-20, a Monday, "Feria +# Secunda infra Hebdomadam II post Octavam Paschæ"). Covers vu's whole +# `PASCHALTIDE_SEASONS` cluster (eastertide/ascensiontide/pentecost) per +# `seasonalOfficeSuffix`'s existing collapse — but the Ascension octave +# itself is live-verified to actually use a real, different, not-yet- +# authored proper hymn of its own ("...Qui scandis super sídera", +# 2026-05-15) that this app doesn't model yet; this generic Paschaltide +# text will incorrectly apply there for now — a known simplification +# matching a same-shape, pre-existing gap in Lauds' own +# `lauds-hymn-paschaltide.yml`, not a new regression. Flagged in TODO.md. +# +# Self-contained with its own closing doxology stanza baked in ("Glória +# tibi Dómine, Qui surrexísti a mórtuis..." — byte-identical to the +# already-existing `hymn-doxology-pasch.yml` used by Lauds/Vespers, but +# baked directly into the body here rather than split out/reattached, +# since this hour doesn't need the seasonal doxology-override mechanism +# for its own sub-season variants (Ascension/Pentecost/etc.) to matter — +# those days don't reach this file's own generic content at all until the +# proper-hymn gap above is closed). +id: matins-hymn-paschaltide +text: + la: >- + Rex sempitérne Dómine, + + Rerum Creátor ómnium, + + Qui eras ante sǽcula + + Semper cum Patre Fílius: + + + Qui mundi in primórdio + + Adam plásmasti hóminem: + + Cui tuæ imágini + + Vultum dedísti símilem. + + + Quem diábolus decéperat, + + Hostis humáni géneris, + + Cujus tu formam córporis + + Assúmere dignátus es: + + + Ut hóminem redímeres, + + Quem ante jam plasmáveras: + + Et nos Deo conjúngeres, + + Per carnis contubérnium. + + + Quem éditum ex Vírgine + + Pavéscit omnis ánima: + + Per quem et nos resúrgere + + Devóta mente crédimus. + + + Qui nobis in Baptísmate + + Donásti indulgéntiam, + + Qui tenebámur vínculis + + Ligáti consciéntiæ. + + + Qui Crucem propter hóminem + + Suscípere dignátus es: + + Dedísti tuum sánguinem + + Nostræ salútis prétium. + + + Quǽsumus Auctor ómnium, + + In hoc Pascháli gáudio, + + Ab omni mortis ímpetu + + Tuum defénde pópulum. + + + Glória tibi Dómine, + + Qui surrexísti a mórtuis, + + Cum Patre et Sancto Spíritu, + + In sempitérna sǽcula. Amen. + en: >- + O thou, the heavens' eternal King, + + Creator, unto thee we sing, + + With God the Father ever One, + + Co-equal, co-eternal Son. + + + Thy hand, when first the world began, + + Made in thine own pure image man, + + And linked to Adam, sprung from earth, + + A living soul of heavenly birth. + + + And when by craft the envious foe + + Had marred thy noblest work below, + + Clothed in our flesh, thou didst restore + + The image thou hadst made before. + + + So that thou might redeem man + + Whom thou hadst made + + And us to God might thou wouldst unite + + Through thy union with the flesh. + + + Once wast thou born of Mary's womb; + + And now, new-born from out the tomb, + + O Christ, thou bidd'st us rise with thee + + From death to immortality. + + + Eternal Shepherd, thou dost lave + + Thy flock in pure baptismal wave, + + That mystic bath, that grave of sin, + + Where ransomed souls new life begin. + + + Redeemer, thou for us didst deign + + To hang upon the Cross of pain, + + And give for us the lavish price + + Of thine own blood in sacrifice. + + + Grant, Lord, in thee each faithful mind + + Unceasing paschal joy may find; + + And from the death of sin set free + + Souls newly born to life by thee. + + + To Thee Who, dead, again dost live, + + All glory, Lord, Thy people give; + + All glory, as is ever meet, + + To Father and to Paraclete. Amen. +status: + la: verified + en: verified diff --git a/src/data/propers/common/matins-hymn-passiontide.yml b/src/data/propers/common/matins-hymn-passiontide.yml new file mode 100644 index 0000000..7527f65 --- /dev/null +++ b/src/data/propers/common/matins-hymn-passiontide.yml @@ -0,0 +1,170 @@ +# Passiontide's own Matins hymn ("Pange, lingua, gloriósi prœ́lium +# certáminis" — the Passiontide recension of Venantius Fortunatus' hymn, +# distinct from Lent's own "Ex more docti mýstico" used up to this point). +# Live-verified against both Passion Sunday itself (2026-03-22) and a +# plain Passiontide feria (2026-03-24, a Tuesday) — byte-identical, so +# this season doesn't vary its Matins hymn by weekday. This particular +# breviary recension is 5 stanzas, ending after the Incarnation/manger +# stanza — it does not continue into the "Lustra sex qui iam peracta..." +# stanzas some other uses of this hymn carry. Self-contained with its own +# closing doxology stanza baked in (a fixed, unique ending, "Glória, et +# honor Deo..." — not the shared weekday doxology). +id: matins-hymn-passiontide +text: + la: >- + Pange, lingua, gloriósi + + Prœlium certáminis, + + Et super Crucis trophǽo + + Dic triúmphum nóbilem, + + Quáliter Redémptor orbis + + Immolátus vícerit. + + + De paréntis protoplásti + + Fraude Factor cóndolens, + + Quando pomi noxiális + + Morsu in mortem córruit, + + Ipse lignum tunc notávit, + + Damna ligni ut sólveret. + + + Hoc opus nostræ salútis + + Ordo depopóscerat, + + Multifórmis proditóris + + Ars ut artem fálleret, + + Et medélam ferret inde, + + Hostis unde lǽserat. + + + Quando venit ergo sacri + + Plenitúdo témporis, + + Missus est ab arce Patris + + Natus, orbis Cónditor, + + Atque ventre virgináli + + Carne amíctus pródiit. + + + Vagit infans inter arcta + + Cónditus præsépia: + + Membra pannis involúta + + Virgo Mater álligat: + + Et manus, pedésque, et crura + + Stricta cingit fáscia. + + + Glória, et honor Deo + + Usqueqáque Altíssimo, + + Una Patri, Filióque; + + Inclyto Paráclito: + + Cui laus est et potéstas, + + Per ætérna sǽcula. Amen. + en: >- + Sing, my tongue, the glorious battle + + Sing the last, the dread affray; + + O'er the cross, the victor's trophy, + + Sound the high triumphal lay: + + Tell how Christ, the world's Redeemer, + + As a victim won the day. + + + God, his Maker, sorely grieving + + That the first-made Adam fell, + + When he ate the fruit of sorrow, + + Whose reward was death and hell, + + Noted then this wood, the ruin + + Of the ancient wood to quell. + + + For the work of our salvation + + Needs would have his order so, + + And the multiform deceiver's + + Art by art would overthrow, + + And from thence would bring the med'cine + + Whence the insult of the foe. + + + Wherefore, when the sacred fullness + + Of the appointed time was come, + + This world's Maker left his Father, + + Sent the heav'nly mansion from, + + And proceeded, God Incarnate, + + Of the Virgin's holy womb. + + + Weeps the infant in the manger + + That in Bethlehem's stable stands; + + And his limbs the Virgin Mother + + Doth compose in swaddling bands, + + Meetly thus in linen folding + + Of her God the feet and hands. + + + To the Trinity be glory + + Everlasting, as is meet; + + Equal to the Father, equal + + To the Son, and Paraclete: + + Trinal Unity, whose praises + + All created things repeat. Amen. +status: + la: verified + en: verified diff --git a/src/data/propers/common/matins-hymn-septuagesima.yml b/src/data/propers/common/matins-hymn-septuagesima.yml new file mode 100644 index 0000000..b278b19 --- /dev/null +++ b/src/data/propers/common/matins-hymn-septuagesima.yml @@ -0,0 +1,174 @@ +# Septuagesima-tide's own Matins hymn ("Primo diérum ómnium" — +# Psalterium/Special/Matutinum Special.txt's "Day0 Hymnus1M", a genuinely +# separate full text from the secular "Day0 Hymnus1", not a word-swap). +# Live-verified 2026-02-01 (Septuagesima Sunday itself). Checked before +# `matins-hymn-sunday.yml` in `resolveMatinsHymn` — this only ever +# applies during Septuagesima/Sexagesima/Quinquagesima, a real, narrow +# season vu's calendar already tracks (`day.season === 'septuagesima'`) +# but that the shared `seasonalOfficeSuffix` (Lauds/Vespers' own) doesn't +# cover — checked directly here rather than added there, since Lauds/ +# Vespers have no matching Septuagesima content authored yet and adding +# it to that shared function would silently blank their own chapter/ +# hymn instead of falling through to their current (imperfect but real) +# weekday default. See TODO.md. +# +# Self-contained, own closing doxology baked in — happens to be +# byte-identical to the shared "Praesta, Pater piíssime..." weekday +# doxology, but this hour doesn't use the split/append mechanism at all +# for this seasonal tier (see matins-hymn-sunday.yml's own header). +id: matins-hymn-septuagesima +text: + la: >- + Primo diérum ómnium, + + Quo mundus extat cónditus, + + Vel quo resúrgens Cónditor + + Nos morte victa líberat. + + + Pulsis procul torpóribus + + Surgámus omnes ócius, + + Et nocte quærámus pium + + Sicut prophétam nóvimus. + + + Nostras preces ut áudiat, + + Suámque dextram pórrigat: + + Et expiátos sórdibus + + Reddat polórum sédibus. + + + Ut quique sacratíssimo + + Hujus diéi témpore + + Horis quiétis psállimus, + + Donis beátis múneret. + + + Jam nunc patérna cláritas + + Te postulámus áffatim: + + Absit libído sórdidans + + Et omnis actus nóxius. + + + Ne fœda sit, vel lúbrica + + Compágo nostri córporis, + + Per quem Avérni ígnibus + + Ipsi cremémur ácrius. + + + Ob hoc Redémptor, quǽsumus, + + Ut probra nostra díluas, + + Vitæ perénnis cómmoda + + Nobis benígne cónferas. + + + Quo carnis actu éxsules + + Effécti ipsi cælibes, + + Ut præstolámur cérnui, + + Melos canámus glóriæ. + + + Præsta, Pater piíssime, + + Patríque compar Únice, + + Cum Spíritu Paráclito + + Regnans per omne sǽculum. Amen. + en: >- + Hail day! whereon the One in Three + + First formed the earth by sure decree, + + The day its Maker rose again, + + And vanquished death, and burst our chain. + + + Away with sleep and slothful ease + + We raise our hearts and bend our knees, + + And early seek the Lord of all, + + Obedient to the Prophet's call. + + + That He may hearken to our prayer, + + Stretch forth His strong right arm to spare, + + And ev'ry past offense forgiven, + + Restore us to our home in heaven. + + + Assembled here this holy day, + + This holiest hour we raise the lay, + + And O that He to whom we sing, + + May now reward our offering! + + + O Father of unclouded light! + + Keep us this day as in thy sight, + + In word and deed that we may be + + From ev'ry touch of evil free. + + + That this our body's mortal frame + + May know no sin, and fear no shame, + + Nor fire hereafter be the end + + Of passions which our bosom rend. + + + Redeemer of the world, we pray + + That thou wouldst wash our sins away, + + And give us, of Thy boundless grace, + + The blessings of the heavenly place. + + + Most Holy Father, hear our cry, + + Through Jesus Christ our Lord most High + + Who, with the Holy Ghost and thee + + Shall live and reign eternally. Amen. +status: + la: verified + en: verified diff --git a/src/data/propers/common/matins-hymn-sunday.yml b/src/data/propers/common/matins-hymn-sunday.yml new file mode 100644 index 0000000..92bbfe9 --- /dev/null +++ b/src/data/propers/common/matins-hymn-sunday.yml @@ -0,0 +1,80 @@ +# Sunday's own plain Matins hymn ("Nocte surgéntes vigilémus omnes" — +# Psalterium/Special/Matutinum Special.txt's "Day0 Hymnus", Monastic +# 1617's own "Day0 HymnusM" swap applied: "Víribus totis"/"beátam"/ +# "réboat" replacing the secular "Voce concórdi"/"perénnem"/"résonat"). +# Live-verified against 3 clean ordinary-time (Trinitytide) Sundays with +# no season/octave/winning-saint override (2026-07-05, 2026-08-02, +# 2026-09-06), all byte-identical. +# +# Self-contained with its own closing doxology stanza baked in (a fixed, +# unique Sapphic-meter ending, "Præstet hoc nobis Déitas beáta..." — not +# the shared iambic-dimeter "Praesta, Pater piíssime..." every weekday +# ferial hymn uses) — same convention as every other self-contained +# Matins hymn (see e.g. matins-hymn-common-of-an-apostle.yml). +# +# Septuagesima-tide has its own separate, genuinely different Sunday +# hymn ("Primo diérum ómnium", `matins-hymn-septuagesima.yml`) — checked +# before this one in `resolveMatinsHymn`'s precedence, same as Advent/ +# Lent/Passiontide/Paschaltide's own seasonal hymns. Advent/Lent/ +# Passiontide/Paschaltide's own Sunday hymns turned out identical to +# their own ferial-weekday hymns (live-verified: a Lenten Tuesday and a +# Lenten Sunday both render "Ex more docti mýstico"), unlike the plain +# per-annum case here, where Sunday genuinely differs from the weekday +# cycle (`matins-hymn-ferial*.yml`). +id: matins-hymn-sunday +text: + la: >- + Nocte surgéntes vigilémus omnes, + + Semper in psalmis meditémur, atque + + Víribus totis Dómino canámus + + Dúlciter hymnos. + + + Ut pio Regi páriter canéntes, + + Cum suis Sanctis mereámur aulam + + Íngredi cæli, simul et beátam + + Dúcere vitam. + + + Præstet hoc nobis Déitas beáta + + Patris, ac Nati, paritérque Sancti + + Spíritus, cujus réboat per omnem + + Glória mundum. Amen. + en: >- + Now, from the slumbers of the night arising, + + Chant we the holy psalmody of David, + + Hymns to our Master, with a voice concordant, + + Sweetly intoning. + + + So may our Monarch pitifully hear us, + + That we may merit with his saints to enter + + Mansions eternal, therewithal possessing + + Joy beatific. + + + This be our portion, God forever blessed, + + Father eternal, Son, and Holy Spirit, + + Whose is the glory, which through all creation + + Ever resoundeth. Amen. +status: + la: verified + en: verified diff --git a/src/hours/matins.ts b/src/hours/matins.ts index 340bafe..e17faf8 100644 --- a/src/hours/matins.ts +++ b/src/hours/matins.ts @@ -450,6 +450,21 @@ function resolveMatinsHymn(day: LiturgicalDay): ResolvedText { return commonHymn; } } + // Septuagesima-tide checked directly by `day.season`, not folded into + // `seasonalOfficeSuffix` — that function is shared with Lauds/Vespers, + // which have no matching Septuagesima content authored yet; adding it + // there would silently blank their own chapter/hymn (resolveOfficeBundle + // requires all-or-nothing) instead of falling through to their current + // weekday default. Scoped to Matins alone until Lauds/Vespers' own + // Septuagesima content exists too (see TODO.md). Its own hymn ("Primo + // diérum ómnium") is a genuinely separate seasonal text from the plain + // Sunday/ferial one below, live-verified 2026-02-01. + if (day.season === 'septuagesima') { + const septuagesima = resolveCommon('matins-hymn-septuagesima'); + if (septuagesima.status.la !== 'missing' || septuagesima.status.en !== 'missing') { + return septuagesima; + } + } const seasonSuffix = seasonalOfficeSuffix(day.season); if (seasonSuffix) { const seasonal = resolveCommon(`matins-hymn-${seasonSuffix}`); @@ -457,6 +472,16 @@ function resolveMatinsHymn(day: LiturgicalDay): ResolvedText { return seasonal; } } + // Sunday's own plain hymn ("Nocte surgéntes"), self-contained (own + // doxology baked in, unlike the shared weekday one below) — checked + // here, after every season/octave/Common tier above but before the + // Monday-Saturday ferial cycle, live-verified 2026-09-04. + if (day.weekday === 'sunday') { + const sunday = resolveCommon('matins-hymn-sunday'); + if (sunday.status.la !== 'missing' || sunday.status.en !== 'missing') { + return sunday; + } + } // The plain ferial hymn's own Monastic source (Day1-6 Hymnus, Psalterium/ // Special/Matutinum Special.txt) carries a real seasonal-doxology // substitution marker (live-checked 2026-09-03) — unlike the Advent/ @@ -470,8 +495,9 @@ function resolveMatinsHymn(day: LiturgicalDay): ResolvedText { // text — a real gap uncovered when the user noticed Friday showing // Monday's own hymn, and Saturday's own gap found the same day by // asking what actually renders on a real Ember Saturday (see - // matins-hymn-ferial.yml's header for why Sunday alone still falls to - // the plain `matins-hymn-ferial` id as a documented placeholder). + // matins-hymn-ferial.yml's header for why Monday alone still falls to + // the plain `matins-hymn-ferial` id, since Monday's own text simply + // lives there unsuffixed). const weekdayFerialHymnIds: Partial> = { tuesday: 'matins-hymn-ferial-tuesday', wednesday: 'matins-hymn-ferial-wednesday', diff --git a/tests/hours/matins.test.ts b/tests/hours/matins.test.ts index 1698db2..64913b0 100644 --- a/tests/hours/matins.test.ts +++ b/tests/hours/matins.test.ts @@ -774,9 +774,9 @@ describe('resolveOrdo("matins", ...) Assumption-octave hymn fallback (2026-08-22 }); it("a plain ferial day outside the octave still gets the plain ferial hymn, unaffected", () => { - // FERIAL_DATE (2026-12-01) is a Tuesday -- see the identical note on - // the other FERIAL_DATE hymn assertion below. - expect(hymnLatin(FERIAL_DATE)).toContain('Consors patérni lúminis'); + // FERIAL_DATE (2026-12-01) is a Tuesday in Advent -- see the identical + // note on the other FERIAL_DATE hymn assertion below. + expect(hymnLatin(FERIAL_DATE)).toContain('Verbum supérnum, pródiens'); }); }); @@ -1074,11 +1074,12 @@ describe('resolveOrdo("matins", ...) Common-of-an-Apostle hymn + invitatory (202 }); it('a plain ferial day is unaffected -- still falls through to the plain ferial hymn and invitatory antiphon', () => { - // FERIAL_DATE (2026-12-01) is a Tuesday, so this is Tuesday's own - // ferial hymn ("Consors patérni lúminis") since 2026-09-04's weekday- - // specific hymn fix -- previously every weekday fell through to the - // same (mislabeled) Monday text ("Somno reféctis ártubus"). - expect(hymnLatin(FERIAL_DATE)).toContain('Consors patérni lúminis'); + // FERIAL_DATE (2026-12-01) is a Tuesday in Advent, so since Advent's + // own Matins hymn was authored (2026-09-04), this is Advent's own + // seasonal hymn ("Verbum supérnum, pródiens"), not Tuesday's own + // ferial one -- season outranks weekday in resolveMatinsHymn's own + // precedence, same as everywhere else. + expect(hymnLatin(FERIAL_DATE)).toContain('Verbum supérnum, pródiens'); expect(invitatoryFullLatin(FERIAL_DATE)).toContain('Veníte'); expect(invitatoryFullLatin(FERIAL_DATE)).not.toContain('Regem Apostolórum'); });