Model St. Clare and surface active octaves in the day label
Deploy / deploy (push) Successful in 52s

Today (Aug 12, within St. Lawrence's octave) was resolving as a plain
ferial day: St. Clare wasn't modeled in the calendar at all, and even
once an octave commemoration exists, getDayLabel only ever looked for a
sanctoral commemoration, never an octave one, so the label fell all the
way through to the generic ordinal week label.

Adds St. Clare (Simplex under Monastic 1617, correctly losing to
Lawrence's octave and only commemorated -- live-verified against three
clean years). Extends getDayLabel to show the active octave itself as
the day's primary identity when nothing else has won outright (e.g.
"3rd Day within the Octave of St. Lawrence, Martyr -- St. Clare,
Virgin"), matching what the live reference engine actually titles these
days, rather than falling back to an anonymous ordinal week label.

Also fixes a regression this surfaced: Trinity Sunday is technically
also day 8 of Pentecost's own octave, and the naive octave-first check
was shadowing its own anchor-day name ("8th Day within the Octave of
Pentecost" instead of "Trinity Sunday"). A season's own named anchor day
now always outranks an active octave label.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-12 06:39:48 -04:00
parent ff81a6fe52
commit 5f32a3751c
5 changed files with 111 additions and 13 deletions
+12 -3
View File
@@ -76,13 +76,22 @@ describe('August sanctoral pull (first pass)', () => {
expect(getDayCollect(day).status.en).toBe('verified');
});
it("dates within St. Lawrence and the Assumption's own octaves still exclude the real secondary saint the source names (St. Clare, Aug 12) -- Clare herself isn't modeled yet -- but both octaves themselves (now modeled, see calendar/octaves.ts) correctly keep commemorating through them regardless", () => {
it("St. Lawrence's own octave correctly keeps St. Clare (Simplex) to a commemoration, and the Assumption's octave does the same for its own date", () => {
// St. Clare is now modeled (added directly off this gap) -- Simplex
// under Monastic 1617, below the octave's semiduplex `wins` threshold,
// so she's commemorated rather than winning outright, matching the
// live engine's own "Tertia die infra Octavam S. Laurentii Martiris ~
// Semiduplex" / "Commemoratio: S. Claræ Virginis" for this date.
const clareDay = resolveDay('2025-08-12');
expect(clareDay.winner.kind).toBe('temporal');
expect(clareDay.commemorations).toEqual([{ kind: 'octave', id: 'st-lawrence', name: 'St. Lawrence, Martyr' }]);
expect(clareDay.commemorations).toEqual([
{ kind: 'sanctoral', id: 'st-clare', name: 'St. Clare, Virgin', rank: 'simplex' },
{ kind: 'octave', id: 'st-lawrence', name: 'St. Lawrence, Martyr' },
]);
// Aug 22 is the Assumption's own octave day (In Octava Assumptionis),
// Duplex, blocking Ss. Timothy/Hippolytus/Symphorian the same way --
// it's also day 8 of the Assumption's own octave.
// it's also day 8 of the Assumption's own octave. Those three still
// aren't modeled, so this stays a bare octave commemoration.
const assumptionOctaveDay = resolveDay('2025-08-22');
expect(assumptionOctaveDay.winner.kind).toBe('temporal');
expect(assumptionOctaveDay.commemorations).toEqual([
+20
View File
@@ -44,6 +44,26 @@ describe('getDayLabel — ordinal temporal label', () => {
});
});
describe('getDayLabel — active octave', () => {
it('shows the octave day itself as the primary label, plus a lesser saint commemorated alongside it', () => {
// St. Lawrence's own octave (Aug 10-17); Aug 12 is day 3, and also St.
// Clare's own day -- Simplex, below the octave's semiduplex threshold,
// so she's commemorated rather than winning. Matches the live engine's
// own title for this date directly (see saints/st-clare.yml).
expect(getDayLabel(resolveDay('2026-08-12'))).toBe('3rd Day within the Octave of St. Lawrence, Martyr — St. Clare, Virgin');
});
it('shows the octave day alone when nothing is separately commemorated that day', () => {
// Aug 17 is day 8 (the last day) of St. Lawrence's octave, with no
// sanctoral candidate of its own in this app's calendar.
expect(getDayLabel(resolveDay('2026-08-17'))).toBe('8th Day within the Octave of St. Lawrence, Martyr');
});
it("a season's own named anchor day outranks an active octave, even though Trinity Sunday is technically also day 8 of Pentecost's own octave", () => {
expect(getDayLabel(resolveDay('2026-05-31'))).toBe('Trinity Sunday');
});
});
describe('getDayLabel — feast name combination', () => {
const base: LiturgicalDay = {
date: '2026-06-15',