From f579ba2d2e15479f0520e297496c4b8dda0f15b8 Mon Sep 17 00:00:00 2001 From: Will Estes Date: Sun, 6 Sep 2026 06:28:46 -0400 Subject: [PATCH] Fix nocturn reading occasion labels leaking rank and commemorations occasionName() fell back to getDayLabel() (the full day-heading builder) when the temporal day itself won, baking the feast rank and every commemoration/transfer note into the "(for ...)" annotation. Use temporalLabel()'s bare ordinal name instead, matching the sanctoral-winner branch, so the label names only the single occasion that pooled the reading. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01PNMRYZiEbU2NuSfRQUi4uP --- src/hours/matins.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hours/matins.ts b/src/hours/matins.ts index 10935e0..f9b6769 100644 --- a/src/hours/matins.ts +++ b/src/hours/matins.ts @@ -815,8 +815,9 @@ function fallbackHagiographicLabel(id: string): string | undefined { * comment), or — the most common case in the whole pool — a plain governing * Sunday's own temporal-cycle id (`post-pentecost-15`) or its * `month-week-` half (see `nocturnReadingIds`'s `temporalKept` block), - * which falls back to the same `getDayLabel` the day's own heading uses - * (e.g. "The 14th Sunday after Trinity"). Used to annotate an authored + * which falls back to `temporalLabel`'s bare ordinal name (e.g. "The 14th + * Sunday after Trinity" — no rank, no commemorations; that's the day + * heading's job, not this annotation's). Used to annotate an authored * patristic `source` with *why* it's here, since a single day can pool * several ids' worth of readings (e.g. a commemorated Ember day's own * Gospel homily alongside the winning saint's own) and a bare "Pope St. @@ -827,12 +828,11 @@ function occasionName(id: string, day: LiturgicalDay): string | undefined { if (named) return named; const monthWeek = monthWeekId(day.date); if (id === resolveTemporalId(day.date) || (monthWeek && id === `month-week-${monthWeek}`)) { - // When a saint (not the temporal day itself) won the day, name the - // plain Sunday/feria only — `getDayLabel`'s own text is winner-centric - // (the winning saint's full name + rank), which would otherwise get - // pointlessly repeated back into its own "(for ...)" annotation, since - // the winner's name is already shown elsewhere as the day's heading. - return day.winner.kind === 'sanctoral' ? temporalLabel(day).en : getDayLabel(day).en; + // Always the bare Sunday/feria name — never `getDayLabel`, which bakes + // in the day's rank and every commemoration/transfer note. This + // annotation names the single occasion that pooled this one reading, + // not the whole day's heading. + return temporalLabel(day).en; } return undefined; }