Give the Matins invitatory antiphon a real weekday cycle
Deploy / deploy (push) Successful in 2m3s

The plain ferial fallback was a single fixed year-round text that was
actually just Monday's own antiphon, mislabeled in its own comment as
live-verified for 2026-09-06 (a Sunday). The real Monastic 1617 source
genuinely varies this antiphon Sunday-Saturday, same shape as the Matins
hymn's own weekday cycle. Adds the six missing weekday variants and
dispatches on weekday in resolveMatinsInvitatoryText.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W8cttEhwbN3f6hiHQHqCae
This commit is contained in:
2026-09-06 08:52:36 -04:00
parent 7482df1777
commit 90f6450b2f
10 changed files with 144 additions and 11 deletions
+25 -4
View File
@@ -11,10 +11,6 @@ content in the same shape, not a design change. The dated log below is that pipe
## Open work, in priority order
1. **Mechanism gaps**
- **2026-09-06 invitatory antiphon questioned** — user flagged today's (2026-09-06)
invitatory antiphon as suspect; needs tracing back to its source (override > octave >
Common > season > ferial chain in `hours/matins.ts`'s invitatory resolution) to find
and fix whatever underlying bug or content problem produced it. Not yet investigated.
- **Gospel+homily pairing shouldn't carry a responsory** — user, 2026-09-06: when a Matins
Gospel pericope is immediately followed by its own patristic homily (the paired
`gospel`/homily rendering — see `hours/matins.ts`'s Gospel+homily-fold-in convention),
@@ -6445,3 +6441,28 @@ Albis", i.e. Low Sunday, not yet itself named beyond a generic ordinal — a sep
still-open gap) carries a name distinct from the plain "Die N" pattern.
`npm test` (2066 passed) and `tsc --noEmit` both pass.
### Matins invitatory antiphon weekday cycle — closed (2026-09-06)
User flagged 2026-09-06's (a plain Sunday, `post-pentecost-15`) invitatory antiphon as suspect.
Traced it to a real content bug, not a resolution-order bug: `matins-invitatory-antiphon.yml` (the
final ferial fallback in `resolveMatinsInvitatoryText`) held a single fixed year-round text
("Veníte, * Exsultémus Dómino") that its own header claimed was "live-verified... 2026-09-06" —
that was wrong. Querying the live reference engine for that exact date returns a different text
("Adorémus Dóminum, * Qui fecit nos"), and querying a full week showed the real source
(`Psalterium/Special/Matutinum Special.txt`'s `[Invit Trid_]` block) genuinely varies the plain
`{Antiphona ex Psalterio secundum tempora}` invitatory antiphon Sunday-Saturday — same shape as the
Matins hymn's own weekday cycle (`matins-hymn-ferial-tuesday.yml` etc., closed 2026-09-04). The
fixed text turned out to be Monday's own real antiphon, silently standing in for every other
weekday including Sunday.
Fixed the same way as the hymn cycle: six new weekday-specific files
(`matins-invitatory-antiphon-{sunday,tuesday,wednesday,thursday,friday,saturday}.yml`, full
Latin+English pulled from the reference engine's own `Invit Trid_`/`Invit Trid` blocks, Latin and
English respectively), `matins-invitatory-antiphon.yml` (no day suffix) still used for Monday.
`hours/matins.ts`'s `resolveMatinsInvitatoryText` now dispatches on `day.weekday` for its final
fallback tier, same pattern as `resolveMatinsHymn`'s `weekdayFerialHymnIds`. Two pre-existing tests
in `tests/hours/matins.test.ts` hardcoded "Veníte" as the generic ferial default — both dates are
actually Tuesdays, updated to expect Tuesday's own real text ("Jubilémus Deo").
`npm test` (2066 passed) and `tsc --noEmit` both pass.
@@ -0,0 +1,16 @@
# Friday's own plain ferial Matins invitatory antiphon (Psalterium/
# Special/Matutinum Special.txt's "Invit Trid_" block, `Feria VI=`). Its
# English happens to be byte-identical to Sunday's own
# (matins-invitatory-antiphon-sunday.yml) — confirmed in the source, not
# a copy-paste slip: both weekdays' Latin renders as "Let us worship the
# Lord, for He is our Maker" in the reference engine's own translation
# despite slightly different Latin wording. See matins-invitatory-
# antiphon-sunday.yml's header for the weekday-cycle mechanism this
# belongs to; live-verified 2026-09-06.
id: matins-invitatory-antiphon-friday
text:
la: "Adorémus Dóminum, * Quóniam ipse fecit nos."
en: "Let us worship the Lord, for * He is our Maker."
status:
la: verified
en: verified
@@ -0,0 +1,14 @@
# Saturday's own plain ferial Matins invitatory antiphon (Psalterium/
# Special/Matutinum Special.txt's "Invit Trid_" block, `Sabbato=`).
# Reached only when Saturday is neither Marian (see calendar/index.ts's
# applyMarianSaturday) nor covered by a season's own seasonal invitatory
# — same real-world rarity as matins-hymn-ferial-saturday.yml's own case.
# See matins-invitatory-antiphon-sunday.yml's header for the weekday-cycle
# mechanism this belongs to; live-verified 2026-09-06.
id: matins-invitatory-antiphon-saturday
text:
la: "Dóminum, Deum nostrum, * Veníte, adorémus."
en: "The Lord our God: * O come, let us worship Him."
status:
la: verified
en: verified
@@ -0,0 +1,16 @@
# Sunday's own plain ferial Matins invitatory antiphon (Psalterium/Special/
# Matutinum Special.txt's "Invit Trid_" block, `Dominica=`) — the plain
# `{Antiphona ex Psalterio secundum tempora}` weekday cycle genuinely
# varies Sunday-Saturday, same shape as the Matins hymn's own weekday
# cycle (see matins-hymn-ferial-tuesday.yml etc.). `matins-invitatory-
# antiphon.yml` (no day suffix) had been standing in for every day
# including Sunday with what's actually Monday's own text — reported by
# the user 2026-09-06 as suspect and live-verified against Monastic
# Tridentinum 1617 directly.
id: matins-invitatory-antiphon-sunday
text:
la: "Adorémus Dóminum, * Qui fecit nos."
en: "Let us worship the Lord, for * He is our Maker."
status:
la: verified
en: verified
@@ -0,0 +1,11 @@
# Thursday's own plain ferial Matins invitatory antiphon (Psalterium/
# Special/Matutinum Special.txt's "Invit Trid_" block, `Feria V=`).
# See matins-invitatory-antiphon-sunday.yml's header for the weekday-cycle
# mechanism this belongs to; live-verified 2026-09-06.
id: matins-invitatory-antiphon-thursday
text:
la: "Dóminum, qui fecit nos, * Veníte, adorémus."
en: "It is the Lord That hath made us: * O come, let us worship Him."
status:
la: verified
en: verified
@@ -0,0 +1,11 @@
# Tuesday's own plain ferial Matins invitatory antiphon (Psalterium/
# Special/Matutinum Special.txt's "Invit Trid_" block, `Feria III=`).
# See matins-invitatory-antiphon-sunday.yml's header for the weekday-cycle
# mechanism this belongs to; live-verified 2026-09-06.
id: matins-invitatory-antiphon-tuesday
text:
la: "Jubilémus Deo, * Salutári nostro."
en: "Let us make a joyful noise to * the God of our salvation."
status:
la: verified
en: verified
@@ -0,0 +1,11 @@
# Wednesday's own plain ferial Matins invitatory antiphon (Psalterium/
# Special/Matutinum Special.txt's "Invit Trid_" block, `Feria IV=`).
# See matins-invitatory-antiphon-sunday.yml's header for the weekday-cycle
# mechanism this belongs to; live-verified 2026-09-06.
id: matins-invitatory-antiphon-wednesday
text:
la: "In manu tua, Dómine, * Omnes fines terræ."
en: "In Thy hand, O Lord, * are the inmost depths of the earth."
status:
la: verified
en: verified
@@ -1,13 +1,25 @@
# Live-verified (Monastic Tridentinum 1617, 2026-09-06 and 2026-12-15).
# This is Monday's own plain ferial Matins invitatory antiphon
# (Psalterium/Special/Matutinum Special.txt's "Invit Trid_" block, `Feria
# II=`). Its original comment claimed this text was "live-verified...
# 2026-09-06" as the year-round default — wrong: that date query actually
# returns Sunday's own distinct text ("Adorémus Dóminum, * Qui fecit
# nos.", matins-invitatory-antiphon-sunday.yml), not this one. The real
# `{Antiphona ex Psalterio secundum tempora}` cycle genuinely varies
# Sunday-Saturday, same shape as the Matins hymn's own weekday cycle (see
# matins-hymn-ferial.yml's own header) — user flagged today's rendering
# as suspect 2026-09-06, traced to this file standing in for every
# weekday including Sunday. `hours/matins.ts`'s
# `resolveMatinsInvitatoryText` now looks up a weekday-specific id
# (matins-invitatory-antiphon-sunday/-tuesday/-wednesday/-thursday/
# -friday/-saturday) for those six days; this file (no day suffix) is
# still used directly for Monday, same convention as matins-hymn-ferial.
#
# Real practice repeats this antiphon as an interspersed refrain between
# verse groups of Psalm 94 (the historical "Venite" invitatory shape) —
# deliberately not modeled that way here, per direct instruction: this app
# frames it like any other psalm antiphon instead, one opening
# (incipit-or-full, same rank rule as everywhere else) and one full
# repeat after, via hours/matins.ts's plain 'psalm' + 'antiphon' parts.
# Fixed year-round for now — real practice does vary this by season/feast
# (`{Antiphona ex Psalterio secundum tempora}` in the source); not yet
# modeled, a deferred follow-on (see TODO.md).
id: matins-invitatory-antiphon
text:
la: "Veníte, * Exsultémus Dómino."
+15 -1
View File
@@ -345,7 +345,21 @@ function resolveMatinsInvitatoryText(day: LiturgicalDay): ResolvedText {
return seasonal;
}
}
return resolveCommon('matins-invitatory-antiphon');
// The plain `{Antiphona ex Psalterio secundum tempora}` weekday cycle
// (Psalterium/Special/Matutinum Special.txt's "Invit Trid_" block) —
// same weekday-varying shape as `resolveMatinsHymn`'s own cycle, found
// missing the same way (user flagged 2026-09-06's Sunday rendering as
// suspect; it was silently reusing Monday's own text). Monday's text
// still lives at the unsuffixed `matins-invitatory-antiphon` id.
const weekdayInvitatoryIds: Partial<Record<Weekday, string>> = {
sunday: 'matins-invitatory-antiphon-sunday',
tuesday: 'matins-invitatory-antiphon-tuesday',
wednesday: 'matins-invitatory-antiphon-wednesday',
thursday: 'matins-invitatory-antiphon-thursday',
friday: 'matins-invitatory-antiphon-friday',
saturday: 'matins-invitatory-antiphon-saturday',
};
return resolveCommon(weekdayInvitatoryIds[day.weekday] ?? 'matins-invitatory-antiphon');
}
/** The Invitatory (Ps 94) — real practice interleaves its antiphon as a
+9 -2
View File
@@ -29,7 +29,11 @@ describe('resolveOrdo("matins", ...) ferial (1-nocturn) branch', () => {
expect(ordo.parts[3]).toMatchObject({ kind: 'section-heading', label: 'Invitatory' });
expect(ordo.parts[4]).toMatchObject({ kind: 'psalm', psalmNumber: 94 });
const invitatoryAntiphon = (ordo.parts[4] as { antiphon?: { text: Record<string, string> } }).antiphon;
expect(invitatoryAntiphon?.text.la).toContain('Veníte');
// FERIAL_DATE is a Tuesday — its own weekday-specific invitatory
// antiphon (see hours/matins.ts's resolveMatinsInvitatoryText), not
// Monday's "Veníte" text every weekday used to share before the
// weekday cycle was built (2026-09-06).
expect(invitatoryAntiphon?.text.la).toContain('Jubilémus Deo');
// Real practice repeats the invitatory antiphon between verse groups —
// deliberately not modeled that way here (see hours/matins.ts's own
// header): confirm there's exactly one standalone repeat, not several.
@@ -1090,7 +1094,10 @@ describe('resolveOrdo("matins", ...) Common-of-an-Apostle hymn + invitatory (202
// 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');
// Advent has no seasonal invitatory antiphon authored, so this falls
// through to Tuesday's own weekday text (see hours/matins.ts's
// resolveMatinsInvitatoryText and its 2026-09-06 weekday-cycle fix).
expect(invitatoryFullLatin(FERIAL_DATE)).toContain('Jubilémus Deo');
expect(invitatoryFullLatin(FERIAL_DATE)).not.toContain('Regem Apostolórum');
});
});