Omit Lauds suffrages entirely during Advent/Christmastide/Passiontide and any active octave
Deploy / deploy (push) Successful in 54s
Deploy / deploy (push) Successful in 54s
Checked directly against Monastic Tridentinum 1617 (not just the Tridentine 1906/1910 track the suffrage content itself comes from) -- this omission isn't a rubric-track-specific quirk, it holds under this app's own primary source too: - Advent, Christmastide, and Passiontide ferias: suffrages omitted entirely. Confirmed ordinary Lent (weeks 1-4, not Passiontide) is NOT excluded -- only the last two weeks are. - Any day within an active octave: suffrages omitted entirely, however low that octave's own rank is -- confirmed against day 2/3 of St. Lawrence's own Semiduplex octave, well below the existing Duplex+ threshold. Today (within Lawrence's octave) was showing all five suffrages before this fix; the real office has none but the Marian antiphon. Still not modeled, flagged in TODO.md: Paschaltide's own substitution (a single alleluia-form "Suffragium Paschale" replaces the whole set during Eastertide, rather than the ordinary set showing or being omitted) -- a separate, larger feature. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -271,14 +271,20 @@ real `draft` status went through it.
|
|||||||
- `getDayCollects`: each collect in a multi-collect day renders as its own
|
- `getDayCollects`: each collect in a multi-collect day renders as its own
|
||||||
complete "Let us pray ... Amen." block, not the more compressed real form
|
complete "Let us pray ... Amen." block, not the more compressed real form
|
||||||
(one "Let us pray," only the last collect's doxology).
|
(one "Let us pray," only the last collect's doxology).
|
||||||
- Suffrage omission only checks `omitOnDouble` (+ Marian Saturday's own
|
- Suffrage omission (`lauds.ts`'s `suffrages` case) now checks: Double-or-
|
||||||
Cross/BVM filter, + Christ the King's explicit id check, + the Cross-only
|
higher rank, Christ the King, Advent/Christmastide/Passiontide season,
|
||||||
ferial-office check added 2026-08). Real seasonal suppression is still
|
any active octave (however low its own rank), Marian Saturday's own
|
||||||
missing: per the Tridentine 1906/1910 source (`specials.pl`'s
|
Cross/BVM filter, and the Cross-only ferial-office check — all
|
||||||
`checksuffragium`), suffrages are omitted *entirely* during Advent,
|
confirmed directly against **Monastic Tridentinum 1617** itself, not
|
||||||
Christmastide, and Passiontide, and whenever any octave is active — none
|
just the Tridentine 1906/1910 track the suffrage content and the
|
||||||
of that is modeled, so e.g. an Advent feria currently still shows all
|
Joseph/Cross-gating logic were sourced from (checked Advent 2026-12-03,
|
||||||
five suffrages when the real office would have none.
|
Christmastide 2026-12-30, Passiontide 2026-03-23, an active octave via
|
||||||
|
St. Lawrence's own Aug 11-12, and ordinary Lent 2026-02-20 specifically
|
||||||
|
*not* excluded, to confirm it's Passiontide-only, not all of Lent).
|
||||||
|
Still not modeled: the Paschaltide *substitution* (real practice
|
||||||
|
replaces the whole suffrage set with a single alleluia-form "Suffragium
|
||||||
|
Paschale" during Eastertide rather than omitting or showing the
|
||||||
|
ordinary set) — flagged, not built.
|
||||||
- `data/calendar/temporal-categories.yml`'s season→category reconstruction
|
- `data/calendar/temporal-categories.yml`'s season→category reconstruction
|
||||||
is from general knowledge of the pre-1955 tradition, not independently
|
is from general knowledge of the pre-1955 tradition, not independently
|
||||||
verified against a primary source for every entry (flagged inline where
|
verified against a primary source for every entry (flagged inline where
|
||||||
|
|||||||
+14
-2
@@ -1,6 +1,6 @@
|
|||||||
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, isAtLeast, isSundayOrFeast } from '../calendar';
|
import { resolveDay, isAtLeast, isSundayOrFeast, activeOctavesFor } from '../calendar';
|
||||||
import { getDayLabel } from '../calendar/day-label';
|
import { getDayLabel } from '../calendar/day-label';
|
||||||
import { getTemporalFeastRecord } from '../calendar/temporal-feasts';
|
import { getTemporalFeastRecord } from '../calendar/temporal-feasts';
|
||||||
import { getPsalmVerses } from '../psalter';
|
import { getPsalmVerses } from '../psalter';
|
||||||
@@ -244,7 +244,19 @@ function resolvePart(part: HourPart, day: LiturgicalDay): ResolvedPart[] {
|
|||||||
// "Suffragium{omittitur}" — the whole set drops, same as any other
|
// "Suffragium{omittitur}" — the whole set drops, same as any other
|
||||||
// Double-or-higher day.
|
// Double-or-higher day.
|
||||||
const isChristTheKing = day.winner.kind === 'temporal' && day.winner.id === 'christ-the-king';
|
const isChristTheKing = day.winner.kind === 'temporal' && day.winner.id === 'christ-the-king';
|
||||||
if (part.omitOnDouble && (isDoubleOrHigher(day.winner) || isChristTheKing)) {
|
// Confirmed live against Monastic Tridentinum 1617 directly (this
|
||||||
|
// isn't a Tridentine-1906-only quirk -- the same exclusions hold
|
||||||
|
// under the app's own primary rubric track): suffrages are omitted
|
||||||
|
// *entirely* during Advent, Christmastide, and Passiontide (not all
|
||||||
|
// of Lent -- ordinary Lent ferias still get them, checked directly
|
||||||
|
// against 2026-02-20; only the last two weeks), and on any day
|
||||||
|
// within an active octave, however low that octave's own rank is
|
||||||
|
// -- checked directly against day 3 of St. Lawrence's own
|
||||||
|
// (Semiduplex) octave, which still omits them despite being well
|
||||||
|
// below the Duplex+ rank threshold below.
|
||||||
|
const isSeasonallyExcluded = day.season === 'advent' || day.season === 'christmastide' || day.season === 'passiontide';
|
||||||
|
const isWithinAnOctave = activeOctavesFor(day.date).length > 0;
|
||||||
|
if (part.omitOnDouble && (isDoubleOrHigher(day.winner) || isChristTheKing || isSeasonallyExcluded || isWithinAnOctave)) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
// "Of the Holy Cross" is the real *ferial*-office suffrage, sourced
|
// "Of the Holy Cross" is the real *ferial*-office suffrage, sourced
|
||||||
|
|||||||
@@ -219,6 +219,26 @@ describe('resolveOrdo("lauds", ...)', () => {
|
|||||||
expect(crossSuffrage).toBeUndefined();
|
expect(crossSuffrage).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('omits the suffrages entirely during Advent, Christmastide, and Passiontide -- confirmed against Monastic Tridentinum 1617 directly, not just Tridentine 1906/1910', () => {
|
||||||
|
const advent = resolveOrdo('lauds', '2026-12-03'); // plain Advent feria
|
||||||
|
const christmastide = resolveOrdo('lauds', '2026-12-30'); // plain day within the Christmas Octave
|
||||||
|
const passiontide = resolveOrdo('lauds', '2026-03-23'); // Monday of Passion Week
|
||||||
|
for (const ordo of [advent, christmastide, passiontide]) {
|
||||||
|
expect(ordo.parts.some((p) => p.kind === 'preces' && p.label === 'Of the Holy Cross')).toBe(false);
|
||||||
|
expect(ordo.parts.some((p) => p.kind === 'preces' && p.label === 'For Peace')).toBe(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('shows the suffrages on an ordinary Lent feria (not Passiontide) -- only the last two weeks of Lent are excluded, not all of it', () => {
|
||||||
|
const ordo = resolveOrdo('lauds', '2026-02-20'); // Friday after Ash Wednesday, week 1 of Lent
|
||||||
|
expect(ordo.parts.some((p) => p.kind === 'preces' && p.label === 'For Peace')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('omits the suffrages entirely on any day within an active octave, however low the octave\'s own rank is', () => {
|
||||||
|
const ordo = resolveOrdo('lauds', LAWRENCE_OCTAVE_DAY); // day 2 of St. Lawrence's own (Semiduplex) octave
|
||||||
|
expect(ordo.parts.some((p) => p.kind === 'preces' && p.label === 'For Peace')).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
it('closes with the Conclusio, the closing versicle ("may the Lord grant us his peace... and life everlasting"), and the Marian antiphon -- without spelling out the silent Our Father', () => {
|
it('closes with the Conclusio, the closing versicle ("may the Lord grant us his peace... and life everlasting"), and the Marian antiphon -- without spelling out the silent Our Father', () => {
|
||||||
const ordo = resolveOrdo('lauds', FERIAL_TUESDAY);
|
const ordo = resolveOrdo('lauds', FERIAL_TUESDAY);
|
||||||
const closingVersicle = ordo.parts.find(
|
const closingVersicle = ordo.parts.find(
|
||||||
|
|||||||
Reference in New Issue
Block a user