Add Te decet laus to Matins, drop Ps 129/50 from ferial Preces
Deploy / deploy (push) Successful in 1m24s

Matins now sings "Te decet laus" (Psalterium/Common/Prayers.txt's [Te
decet]) immediately after the Te Deum on every 3-nocturn day, matching
Rule of Benedict ch. 11's close of Vigils. New common text
te-decet-laus.yml, wired into both matins.ts branches that render a Te
Deum; absent on ferial days along with it.

Also drops Psalm 129 (De profundis) from the Lauds ferial Preces and
Psalm 50 (Miserere) from the Vespers ferial Preces, per direct
instruction — both were embedded inline in the live-transcribed text.
Updated the affected fixture tests to key off a versicle that survives
the removal instead of the now-absent psalm text.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EWzE3kaSZCs79fPBrrE1aF
This commit is contained in:
2026-08-23 09:03:04 -04:00
parent 0fb3b4c13e
commit 42dd4dc04b
8 changed files with 70 additions and 98 deletions
+8 -4
View File
@@ -166,11 +166,15 @@ describe('resolveOrdo("lauds", ...)', () => {
expect(collectIndex).toBeGreaterThan(litanyIndex);
});
it('uses the fuller Tridentine 1906/1910 ferial Preces (with Psalm 129) on a plain ferial day, not the short Sunday/feast litany', () => {
it('uses the fuller Tridentine 1906/1910 ferial Preces on a plain ferial day, not the short Sunday/feast litany', () => {
// Psalm 129 (De profundis), present in the live render, is deliberately
// dropped from this app's own text (2026-08) — 'Ego dixi' is the next
// versicle after where the psalm used to sit, still unique to the
// fuller ferial form vs. the short litany.
const ordo = resolveOrdo('lauds', FERIAL_TUESDAY);
const preces = ordo.parts.find((p) => p.kind === 'preces' && p.text.text.la?.includes('Kýrie, eléison'));
expect(preces?.kind === 'preces' ? preces.text.text.la : undefined).toContain('De profúndis clamávi');
expect(preces?.kind === 'preces' ? preces.text.text.en : undefined).toContain('Out of the depths');
expect(preces?.kind === 'preces' ? preces.text.text.la : undefined).toContain('Ego dixi: Dómine, miserére mei');
expect(preces?.kind === 'preces' ? preces.text.text.en : undefined).toContain('I said: Lord, be merciful');
});
it('uses the short Sunday/feast litany, without Psalm 129, on a Sunday and on a real saint\'s own winning day', () => {
@@ -186,7 +190,7 @@ describe('resolveOrdo("lauds", ...)', () => {
it('still uses the fuller ferial Preces on a Vigil, even though a Vigil is a sanctoral winner (unlike isSundayOrFeast elsewhere)', () => {
const ordo = resolveOrdo('lauds', '2028-08-09'); // Vigil of St. Lawrence wins outright this year (not a Sunday)
const preces = ordo.parts.find((p) => p.kind === 'preces' && p.text.text.la?.includes('Kýrie, eléison'));
expect(preces?.kind === 'preces' ? preces.text.text.la : undefined).toContain('Psalmus 129');
expect(preces?.kind === 'preces' ? preces.text.text.la : undefined).toContain('Ego dixi: Dómine, miserére mei');
});
it('resolves just the winners own collect on a plain day with nothing commemorated', () => {
+8 -2
View File
@@ -41,6 +41,9 @@ describe('resolveOrdo("matins", ...) ferial (1-nocturn) branch', () => {
expect(psalms).toEqual([3, 94, 43, 44, 47, 48, 49, 54, 55, 58, 59]);
expect(ordo.parts.some((p) => p.kind === 'te-deum')).toBe(false);
expect(ordo.parts.some((p) => p.kind === 'canticle')).toBe(false);
// "Te decet laus" is sung only right after the Te Deum on a 3-nocturn
// day (2026-08) — absent here along with the Te Deum itself.
expect(ordo.parts.some((p) => p.kind === 'versicle' && p.text.text.la?.includes('Te decet laus'))).toBe(false);
});
it("gives every nocturn psalm its own antiphon and includes Tuesday's own versicle (data/hours/matins-ferial-antiphons.yml)", () => {
@@ -125,12 +128,15 @@ describe('resolveOrdo("matins", ...) Sunday (3-nocturn) branch', () => {
it('renders each nocturn versicle with both its V. and R. lines (real bug: sundayPsalmNocturn/sundayCanticleNocturn used to drop the R. line entirely)', () => {
const versicles = ordo.parts.filter((p) => p.kind === 'versicle') as { text: { text: Record<string, string> } }[];
// Opening Deus-in-adjutorium versicle + one per nocturn (1, 2, 3).
expect(versicles).toHaveLength(4);
// Opening Deus-in-adjutorium versicle + one per nocturn (1, 2, 3) +
// the closing "Te decet laus" versicle after the Te Deum (2026-08).
expect(versicles).toHaveLength(5);
const [, nocturn1, nocturn2, nocturn3] = versicles;
expect(nocturn1?.text.text.la).toBe('V. Memor fui nocte nóminis tui Dómine.\nR. Et custodívi legem tuam.');
expect(nocturn2?.text.text.la).toBe('V. Média nocte surgébam ad confiténdum tibi.\nR. Super justítia justificatiónis tuæ.');
expect(nocturn3?.text.text.la).toBe('V. Exaltáre Dómine in virtúte tua.\nR. Cantábimus et psallémus virtútes tuas.');
// The 5th versicle is "Te decet laus", right after the Te Deum (2026-08).
expect(versicles[4]?.text.text.la).toContain('Te decet laus');
});
it("resolves the user's own bible-plan reading (Tobit/Sirach) for Nocturn 1", () => {
+7 -3
View File
@@ -229,11 +229,15 @@ describe('resolveOrdo("vespers", ...)', () => {
expect(collectIndex).toBeGreaterThan(litanyIndex);
});
it('uses the fuller Tridentine 1906/1910 ferial Preces (with Psalm 50) on a plain ferial day, not the short Sunday/feast litany', () => {
it('uses the fuller Tridentine 1906/1910 ferial Preces on a plain ferial day, not the short Sunday/feast litany', () => {
// Psalm 50 (Miserere), present in the live render, is deliberately
// dropped from this app's own text (2026-08) — 'Ego dixi' is the next
// versicle after where the psalm used to sit, still unique to the
// fuller ferial form vs. the short litany.
const ordo = resolveOrdo('vespers', '2026-06-16');
const preces = ordo.parts.find((p) => p.kind === 'preces' && p.text.text.la?.includes('Kýrie, eléison'));
expect(preces?.kind === 'preces' ? preces.text.text.la : undefined).toContain('Miserére mei, Deus');
expect(preces?.kind === 'preces' ? preces.text.text.en : undefined).toContain('Have mercy on me, O God');
expect(preces?.kind === 'preces' ? preces.text.text.la : undefined).toContain('Ego dixi: Dómine, miserére mei');
expect(preces?.kind === 'preces' ? preces.text.text.en : undefined).toContain('I said: Lord, be merciful');
});
it("uses the short Sunday/feast litany, without Psalm 50, on a Sunday and on a real saint's own winning day", () => {