Fix Matins reading-pool ordering/leak bugs and redundant day-label commemoration

- nocturnReadingIds no longer lets a demoted commemoration's temporal id
  (equal to the plain governing-Sunday temporalId) sneak a Sunday's own
  homily into an unrelated weekday's pool via the commemorations loop —
  a second code path than the one a prior fix gated, affecting 18
  days/year.
- Reading pool order now follows id priority (winner first, then every
  temporal commemoration, then every sanctoral commemoration) instead of
  raw nocturn-tag/array order, matching the day label's own
  temporal-then-sanctoral convention.
- gospelReadingPart now falls back to the paired homily's own responsory
  when the Gospel entry has none of its own, instead of silently
  dropping it.
- Patristic source labels now show "(for <occasion>)" so a reader can
  tell which occasion a pooled reading belongs to on a multi-reading day.
- collectCommemorations no longer restates the plain generic temporal
  label (e.g. "Saturday in the 15th week after Trinity") once anything
  else is already being celebrated — general, not Ember-specific.
  Updated 4 day-label tests that encoded the old behavior.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MKC2QQGLYo2UTiDjDyWEkW
This commit is contained in:
2026-09-05 12:13:41 -04:00
parent f8bd7f3140
commit 65a1f359e6
3 changed files with 157 additions and 51 deletions
+17 -4
View File
@@ -78,7 +78,7 @@ const EMBER_DAY_NAMES: Record<string, Bi> = {
'ember-advent-saturday': bi('Ember Saturday in Advent', 'Sabbato Quattuor Temporum in Adventu'),
};
function emberDayLabel(id: string): Bi | undefined {
export function emberDayLabel(id: string): Bi | undefined {
return EMBER_DAY_NAMES[id];
}
@@ -488,9 +488,22 @@ function collectCommemorations(
sanctoral.push(name);
}
} else if (c.kind === 'temporal') {
if (c.id === temporalId) {
temporal.push(anchorDayName(day, false) ?? temporalLabel(day));
} else {
// `c.id === temporalId` (the plain governing weekday, e.g. "Saturday
// in the 15th week after Trinity") is deliberately never shown here:
// this function only ever runs to list *secondary* identities
// alongside an already-displayed primary winner (a plain temporal
// day that wins outright never reaches `day.commemorations` at all —
// its own name is the header itself, via a different branch of
// `getDayLabel`). Once something else is already being celebrated,
// restating "this is also just the Nth ordinary weekday" tells the
// reader nothing they don't already know from the winner+rank shown
// — unlike a *named* temporal identity (an Ember day, a vigil), which
// genuinely adds information. Not Ember-specific (a 2026-09-05 first
// pass wrongly scoped this to "only when an Ember commemoration is
// also present" — user, 2026-09-05: "it has nothing to do with
// ember-ness"); this plain generic label is dropped unconditionally
// whenever it shows up as a mere commemoration, Ember day or not.
if (c.id !== temporalId) {
const emberName = emberDayLabel(c.id);
if (emberName) {
temporal.push(emberName);