diff --git a/src/data/propers/common/matins-hymn-ferial-friday.yml b/src/data/propers/common/matins-hymn-ferial-friday.yml new file mode 100644 index 0000000..124a931 --- /dev/null +++ b/src/data/propers/common/matins-hymn-ferial-friday.yml @@ -0,0 +1,107 @@ +# Friday's own plain ferial Matins hymn (Psalterium/Special/Matutinum +# Special.txt's "Day5 Hymnus" — Day0=Sunday .. Day6=Saturday). Live- +# verified 2026-09-04 (today, a plain post-Pentecost Friday) against +# Monastic Tridentinum 1617 directly via the CGI instance — Monastic's own +# "Day5 HymnusM" swaps stanza 2's "ómnium"/"vúlnerum" word order and +# stanza 4's "astet" -> "adsit"; the live page confirms both swaps. +# +# Reported by the user: the plain ferial Matins hymn was silently using +# Monday's own text (`matins-hymn-ferial`, mislabeled in its own comment +# as a generic "ferial" hymn) for every weekday, including Friday, where +# the real Monastic 1617 source is this genuinely different hymn. +# +# Closing doxology stanza intentionally omitted — shared across every +# weekday via matins-hymn-doxology-per-annum.yml (see hours/matins.ts). +id: matins-hymn-ferial-friday +text: + la: >- + Tu, Trinitátis Únitas, + + Orbem poténter quæ regis, + + Atténde laudis cánticum, + + Quod excubántes psállimus. + + + Nam léctulo consúrgimus + + Noctis quiéto témpore, + + Ut flagitémus vúlnerum + + A te medélam ómnium. + + + Quo fraude quidquid dǽmonum + + In nóctibus delíquimus, + + Abstérgat illud cǽlitus + + Tuæ potéstas glóriæ. + + + Ne corpus adsit sórdidum, + + Nec torpor instet córdium, + + Ne críminis contágio + + Tepéscat ardor spíritus. + + + Ob hoc, Redémptor, quǽsumus, + + Reple tuo nos lúmine, + + Per quod diérum círculis + + Nullis ruámus áctibus. + en: >- + O Three in One, and One in Three, + + Who rulest all things mightily: + + Bow down to hear the songs of praise + + Which, freed from bonds of sleep, we raise. + + + While lingers yet the peace of night, + + We rouse us from our slumbers light: + + That might of instant prayer may win + + The healing balm for wounds of sin. + + + If, by the wiles of Satan caught, + + This night-time we have sinned in aught, + + That sin Thy glorious power to-day, + + From heaven descending, cleanse away. + + + Let naught impure our bodies stain, + + No laggard sloth our souls detain, + + No taint of sin our spirits know, + + To chill the fervor of their glow. + + + Wherefore, Redeemer grant that we + + Fulfilled with thine own light may be: + + That, in our course, from day to day, + + By no misdeed we fall away. +status: + la: verified + en: verified diff --git a/src/data/propers/common/matins-hymn-ferial-saturday.yml b/src/data/propers/common/matins-hymn-ferial-saturday.yml new file mode 100644 index 0000000..dd0979a --- /dev/null +++ b/src/data/propers/common/matins-hymn-ferial-saturday.yml @@ -0,0 +1,101 @@ +# Saturday's own plain ferial Matins hymn ("Summæ Deus cleméntiæ" — +# Monastic 1617's own "Day6 HymnusM", genuinely distinct text from the +# secular "Day6 Hymnus"/"Summæ Parens cleméntiæ", not just a word-swap — +# Psalterium/Special/Matutinum Special.txt, Day0=Sunday..Day6=Saturday). +# Live-verified 2025-09-20 (a September Ember Saturday winning outright +# with nothing else in play, `{ex Psalterio secundum tempora}` in the +# source, i.e. genuinely the plain per-weekday text). +# +# Reached whenever a Saturday is neither Marian (see calendar/index.ts's +# applyMarianSaturday — an active octave, a real winning saint, or any +# other non-`ordinary-feria` category all suppress it) nor covered by a +# season's own seasonSuffix hymn (Lent/Advent/Paschaltide's own Saturday +# already use their season's hymn first) — chiefly September/Pentecost's +# own Ember Saturday when nothing else wins, same real gap already fixed +# for Tuesday-Friday (see matins-hymn-ferial.yml's own header) but missed +# for Saturday at the time: reported by the user 2026-09-04 by asking +# what actually renders on Ember Saturday and a Saturday where a real +# saint outranks a merely-commemorated Vigil (Aug 8 2026) -- the second +# case turned out fine (the winning saint's own Common hymn already +# applies correctly), but this one was still silently falling to Monday's +# text via the `matins-hymn-ferial` placeholder. +# +# Closing doxology stanza intentionally omitted — shared across every +# weekday via matins-hymn-doxology-per-annum.yml (see hours/matins.ts), +# same convention as the Tuesday-Friday siblings; the live source's own +# closing stanza here is byte-identical to that shared text anyway. +id: matins-hymn-ferial-saturday +text: + la: >- + Summæ Deus cleméntiæ, + + Mundíque Factor máchinæ, + + Unus potentiáliter, + + Trinúsque personáliter: + + + Nostros pius cum cánticis + + Fletus benígne súscipe: + + Quo corde puro sórdibus + + Te perfruámur lárgius. + + + Lumbos, jecúrque mórbidum + + Adúre igni cóngruo, + + Accíncti ut sint pérpetim, + + Luxu remóto péssimo. + + + Ut quique horas nóctium + + Nunc concinéndo rúmpimus, + + Donis beátæ pátriæ + + Ditémur omnes áffatim. + en: >- + Great God of boundless mercy hear; + + Thou Ruler of this earthly sphere; + + In substance one, in persons three, + + Dread Trinity in Unity! + + + Do thou in love accept our lays + + Of mingled penitence and praise; + + And set our hearts from error free, + + More fully to rejoice in thee. + + + Our reins and hearts in pity heal, + + And with thy chastening fires anneal; + + Gird Thou our loins, each passion quell, + + And every harmful lust expel. + + + Now as our anthems, upward borne, + + Awake the silence of the morn, + + Enrich us with thy gifts of grace, + + From heaven, thy blissful dwelling-place! +status: + la: verified + en: verified diff --git a/src/data/propers/common/matins-hymn-ferial-thursday.yml b/src/data/propers/common/matins-hymn-ferial-thursday.yml new file mode 100644 index 0000000..bb4a586 --- /dev/null +++ b/src/data/propers/common/matins-hymn-ferial-thursday.yml @@ -0,0 +1,83 @@ +# Thursday's own plain ferial Matins hymn (Psalterium/Special/Matutinum +# Special.txt's "Day4 Hymnus" — Day0=Sunday .. Day6=Saturday, live-checked +# 2026-09-04, 2026-09-03). Monastic 1617's own "Day4 HymnusM" is a bare +# `@:Day4 Hymnus` cross-reference with no substitution — identical to the +# secular text below. +# +# Closing doxology stanza intentionally omitted — shared across every +# weekday via matins-hymn-doxology-per-annum.yml (see hours/matins.ts). +id: matins-hymn-ferial-thursday +text: + la: >- + Nox atra rerum cóntegit + + Terræ colóres ómnium: + + Nos confiténtes póscimus + + Te, juste judex córdium. + + + Ut áuferas piácula, + + Sordésque mentis ábluas: + + Donésque, Christe, grátiam, + + Ut arceántur crímina. + + + Mens ecce torpet ímpia, + + Quam culpa mordet nóxia: + + Obscúra gestit tóllere, + + Et te, Redémptor, quǽrere. + + + Repélle tu calíginem + + Intrínsecus quam máxime, + + Ut in beáto gáudeat + + Se collocári lúmine. + en: >- + The dusky veil of night hath laid + + The varied hues of earth in shade; + + Before Thee, righteous Judge of all, + + We contrite in confession fall. + + + Take far away our load of sin, + + Our soiled minds make clean within: + + Thy sov'reign grace, O Christ, impart, + + From all offence to guard our heart. + + + For lo! our mind is dull and cold, + + Envenomed by sin's baneful hold: + + Fain would it now the darkness flee, + + And seek, Redeemer, unto Thee. + + + Far from it drive the shades of night, + + Its inmost darkness put to flight; + + Till in the daylight of the blest + + It joys to find itself at rest. +status: + la: verified + en: verified diff --git a/src/data/propers/common/matins-hymn-ferial-tuesday.yml b/src/data/propers/common/matins-hymn-ferial-tuesday.yml new file mode 100644 index 0000000..9c5c746 --- /dev/null +++ b/src/data/propers/common/matins-hymn-ferial-tuesday.yml @@ -0,0 +1,65 @@ +# Tuesday's own plain ferial Matins hymn (Psalterium/Special/Matutinum +# Special.txt's "Day2 Hymnus" — Day0=Sunday .. Day6=Saturday, live-checked +# 2026-09-04). Monastic 1617's own "Day2 HymnusM" is a bare `@:Day2 +# Hymnus` cross-reference with no substitution — identical to the secular +# text below, unlike Wednesday/Friday's own genuine word-swaps. +# +# Closing doxology stanza intentionally omitted — shared across every +# weekday via matins-hymn-doxology-per-annum.yml (see hours/matins.ts). +id: matins-hymn-ferial-tuesday +text: + la: >- + Consors patérni lúminis, + + Lux ipse lucis, et dies, + + Noctem canéndo rúmpimus: + + Assíste postulántibus. + + + Aufer ténebras méntium, + + Fuga catérvas dǽmonum, + + Expélle somnoléntiam, + + Ne pigritántes óbruat. + + + Sic, Christe, nobis ómnibus + + Indúlgeas credéntibus, + + Ut prosit exorántibus, + + Quod præcinéntes psállimus. + en: >- + O Light of Light, O Day-spring bright, + + Co-equal in thy Father's light: + + Assist us, as with prayer and psalm + + Thy servants break the twilight calm. + + + All darkness from our minds dispel, + + And turn to flight the hosts of hell: + + Bid sleepfulness our eyelids fly, + + Lest overwhelmed in sloth we lie. + + + Jesu, thy pardon, kind and free, + + Bestow on us who trust in thee: + + And as thy praises we declare, + + O with acceptance hear our prayer. +status: + la: verified + en: verified diff --git a/src/data/propers/common/matins-hymn-ferial-wednesday.yml b/src/data/propers/common/matins-hymn-ferial-wednesday.yml new file mode 100644 index 0000000..3eb7bbd --- /dev/null +++ b/src/data/propers/common/matins-hymn-ferial-wednesday.yml @@ -0,0 +1,86 @@ +# Wednesday's own plain ferial Matins hymn (Psalterium/Special/Matutinum +# Special.txt's "Day3 Hymnus" — Day0=Sunday .. Day6=Saturday, live-checked +# 2026-09-04, 2026-09-02). Monastic 1617's own "Day3 HymnusM" swaps +# "culpis ómnibus" -> "tu criminibus" in stanza 2 (both mean "forgive our +# sins/crimes" — a stylistic variant, not a change of imagery, so the +# existing secular English translation is reused unchanged, same +# convention already used elsewhere in this store for minor M-track +# word-swaps). +# +# Closing doxology stanza intentionally omitted — shared across every +# weekday via matins-hymn-doxology-per-annum.yml (see hours/matins.ts). +id: matins-hymn-ferial-wednesday +text: + la: >- + Rerum Creátor óptime, + + Rectórque noster, áspice: + + Nos a quiéte nóxia + + Mersos sopóre líbera. + + + Te, sancte Christe, póscimus, + + Ignósce tu criminibus: + + Ad confiténdum súrgimus, + + Morásque noctis rúmpimus. + + + Mentes manúsque tóllimus, + + Prophéta sicut nóctibus + + Nobis geréndum prǽcipit, + + Paulúsque gestis cénsuit. + + + Vides malum, quod fécimus: + + Occúlta nostra pándimus: + + Preces geméntes fúndimus, + + Dimítte quod peccávimus. + en: >- + Who madest all and dost control, + + Lord, with thy touch divine, + + Cast out the slumbers of the soul, + + The rest that is not thine. + + + Look down, Eternal Holiness, + + And wash the sins away, + + Of those, who, rising to confess, + + Outstrip the lingering day. + + + Our hearts and hands by night, O Lord, + + We lift them in our need; + + As holy Psalmists give the word, + + And holy Paul the deed. + + + Each sin to thee of years gone by, + + Each hidden stain lies bare; + + We shrink not from thine awful eye, + + But pray that thou wouldst spare. +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 758913e..40e256f 100644 --- a/src/data/propers/common/matins-hymn-ferial.yml +++ b/src/data/propers/common/matins-hymn-ferial.yml @@ -1,9 +1,24 @@ -# Live-verified (Monastic Tridentinum 1617, 2026-12-15, a plain ferial -# Tuesday) — "{ex Psalterio secundum tempora}" in the source, meaning this -# is itself one of several season-variable hymns rather than a true fixed -# year-round text; only this one (evidently the ordinary-time/per-annum -# form) is authored so far. Seasonal variants deferred (see TODO.md), -# same incremental-content pattern as everywhere else in this project. +# This is Monday's own plain ferial Matins hymn (Psalterium/Special/ +# Matutinum Special.txt's "Day1 Hymnus" — Day0=Sunday .. Day6=Saturday). +# The file's original comment mislabeled it as a single fixed +# "ferial" text and misattributed its live-verification date (2026-12-15) +# to "a plain ferial Tuesday" — that date is in fact a Tuesday, but the +# text itself is Monday's (Monastic 1617's own "Day1 HymnusM" swaps +# "omni témpore" -> "in perpetuum" in the closing line, matching what's +# below). Fixed 2026-09-04 after the user reported Friday showing this +# same text instead of Friday's own hymn: `hours/matins.ts`'s +# `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. # # The closing doxology stanza is split out into # matins-hymn-doxology-per-annum.yml (see hours/matins.ts) — the source diff --git a/src/hours/matins.ts b/src/hours/matins.ts index 2641eb4..340bafe 100644 --- a/src/hours/matins.ts +++ b/src/hours/matins.ts @@ -462,7 +462,24 @@ function resolveMatinsHymn(day: LiturgicalDay): ResolvedText { // substitution marker (live-checked 2026-09-03) — unlike the Advent/ // Paschaltide seasonal hymns above, whose Monastic forms are each fixed, // non-swapping text, so only this final fallback needs the swap. - const body = resolveCommon('matins-hymn-ferial'); + // + // Weekday-specific (2026-09-04): the source's plain Matins hymn genuinely + // varies Monday-Saturday (the classic "week of hymns" — Somno reféctis + // ártubus, Consors patérni lúminis, Rerum Creátor óptime, Nox atra rerum, + // Tu Trinitátis Únitas, Summæ Deus cleméntiæ), not one fixed year-round + // 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). + const weekdayFerialHymnIds: Partial> = { + tuesday: 'matins-hymn-ferial-tuesday', + wednesday: 'matins-hymn-ferial-wednesday', + thursday: 'matins-hymn-ferial-thursday', + friday: 'matins-hymn-ferial-friday', + saturday: 'matins-hymn-ferial-saturday', + }; + const body = resolveCommon(weekdayFerialHymnIds[day.weekday] ?? 'matins-hymn-ferial'); const doxology = resolveCommon(getHymnDoxologyId(day, 'matins-hymn-doxology-per-annum')); return appendDoxology(body, doxology); } diff --git a/tests/hours/matins.test.ts b/tests/hours/matins.test.ts index 34e1d88..1698db2 100644 --- a/tests/hours/matins.test.ts +++ b/tests/hours/matins.test.ts @@ -774,7 +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", () => { - expect(hymnLatin(FERIAL_DATE)).toContain('Somno'); + // 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'); }); }); @@ -1072,7 +1074,11 @@ 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', () => { - expect(hymnLatin(FERIAL_DATE)).toContain('Somno'); + // 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'); expect(invitatoryFullLatin(FERIAL_DATE)).toContain('Veníte'); expect(invitatoryFullLatin(FERIAL_DATE)).not.toContain('Regem Apostolórum'); });