Fix Christmas Octave Sunday's occurrence precedence (was backwards)
Deploy / deploy (push) Successful in 51s
Deploy / deploy (push) Successful in 51s
christmastide's Sunday was coded privileged-sunday (Advent's own tier), which live-checking against the reference engine shows is wrong: on every one of the three real collision dates (St. Stephen/John/Holy Innocents, all Duplex-II-classis, falling on the Sunday within the Octave) the saint wins outright and the Sunday is merely commemorated -- the reverse of what privileged-sunday would produce (Sunday stays primary, saint just gets a nod). St. Silvester (plain Duplex, Dec 31) confirms the same live. Reclassified to ordinary-sunday, which matches all four checked cases: Duplex+ wins outright (Stephen/John/Innocents/ Silvester), Semiduplex still transfers off the Sunday rather than winning (St. Thomas Becket, unaffected by the fix either way), and a day with no saint at all resolves to the Sunday cleanly. Found while pulling christmas-octave-sunday's own Benedictus antiphon from the reference engine's dedicated Tempora/Nat1-0 proper and noticing this app's own occurrence resolution didn't match what the live engine showed for the Sunday's real collision dates. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -213,11 +213,28 @@ Urban I/Eleutherius/John I do have content -- they just needed a very
|
|||||||
late test year). Every pre-existing antiphon file that predated this
|
late test year). Every pre-existing antiphon file that predated this
|
||||||
pass has now been checked against a live Monastic query; most needed
|
pass has now been checked against a live Monastic query; most needed
|
||||||
correction (confirmed Roman-rite sourced), a handful already matched.
|
correction (confirmed Roman-rite sourced), a handful already matched.
|
||||||
- **All ~52 temporal entries: done** (see the section above for method and
|
- **All ~52 temporal entries: done, including `christmas-octave-sunday`**
|
||||||
the one deliberate exception, `christmas-octave-sunday`).
|
(see the section above for method and its own correction).
|
||||||
- **94 `propers: null` saints: not started** — need a collect authored (a
|
- **94 `propers: null` saints: not started** — need a collect authored (a
|
||||||
bigger, separate task) before an antiphon id even has anywhere to attach.
|
bigger, separate task) before an antiphon id even has anywhere to attach.
|
||||||
|
|
||||||
|
### Bug found and fixed while pulling christmas-octave-sunday's antiphon
|
||||||
|
|
||||||
|
`data/calendar/temporal-categories.yml` had christmastide's own Sunday
|
||||||
|
coded `privileged-sunday` (Advent's tier — never displaced short of
|
||||||
|
Duplex-majus+, and even then only commemorated in return). Live-checking
|
||||||
|
all three Duplex-II-classis "Comites Christi" collision dates (St.
|
||||||
|
Stephen/John/Holy Innocents falling on the Sunday, plus St. Silvester,
|
||||||
|
plain Duplex) showed the exact reverse: the saint wins outright every
|
||||||
|
time, the Sunday only commemorated — `ordinary-sunday`'s rule, not
|
||||||
|
`privileged-sunday`'s. Fixed by reclassifying christmastide's `sunday` to
|
||||||
|
`ordinary-sunday` (the `feria` side, `privileged-feria-minor`, was
|
||||||
|
already correct and untouched). New tests in
|
||||||
|
`tests/calendar/december-sanctoral.test.ts` cover both directions: the
|
||||||
|
saint winning on the three verified collision dates, and St. Thomas
|
||||||
|
Becket (Semiduplex) still transferring off the Sunday rather than
|
||||||
|
winning, unchanged by the fix.
|
||||||
|
|
||||||
### Bug found while checking February's results, not yet fixed
|
### Bug found while checking February's results, not yet fixed
|
||||||
|
|
||||||
`hours/resolve-common.ts`'s `splitNamedAntiphon` always marks its output
|
`hours/resolve-common.ts`'s `splitNamedAntiphon` always marks its output
|
||||||
|
|||||||
@@ -52,7 +52,21 @@ bySeason:
|
|||||||
# Canterbury, Semiduplex, wins outright within the Octave (Dec 29) in the
|
# Canterbury, Semiduplex, wins outright within the Octave (Dec 29) in the
|
||||||
# real Monastic 1617 engine, which `privileged-feria`'s Duplex+ threshold
|
# real Monastic 1617 engine, which `privileged-feria`'s Duplex+ threshold
|
||||||
# would wrongly forbid.
|
# would wrongly forbid.
|
||||||
christmastide: { sunday: privileged-sunday, feria: privileged-feria-minor }
|
#
|
||||||
|
# The Sunday itself is `ordinary-sunday`, NOT `privileged-sunday` —
|
||||||
|
# originally miscoded as privileged-sunday (Advent's own Sundays' tier),
|
||||||
|
# which was backwards: live-verified against all six possible collision
|
||||||
|
# dates (Dec 26 St. Stephen, 27 St. John, 28 Holy Innocents — all
|
||||||
|
# Duplex-II-classis — plus 31 St. Silvester, plain Duplex), every one of
|
||||||
|
# them wins outright over the Sunday, which is merely commemorated in
|
||||||
|
# return — exactly ordinary-sunday's Duplex+ rule, and the reverse of
|
||||||
|
# privileged-sunday's (which would keep the Sunday primary and only nod
|
||||||
|
# to the saint). Dec 29 (St. Thomas Becket, Semiduplex) still transfers
|
||||||
|
# off the Sunday rather than winning, and a day with no saint at all
|
||||||
|
# (e.g. Dec 30) still resolves to the Sunday cleanly — both of those
|
||||||
|
# match ordinary-sunday too, so nothing here actually depended on the
|
||||||
|
# stronger tier.
|
||||||
|
christmastide: { sunday: ordinary-sunday, feria: privileged-feria-minor }
|
||||||
epiphanytide: { sunday: ordinary-sunday, feria: ordinary-feria }
|
epiphanytide: { sunday: ordinary-sunday, feria: ordinary-feria }
|
||||||
septuagesima: { sunday: privileged-sunday, feria: ordinary-feria }
|
septuagesima: { sunday: privileged-sunday, feria: ordinary-feria }
|
||||||
lent: { sunday: privileged-sunday, feria: ordinary-feria }
|
lent: { sunday: privileged-sunday, feria: ordinary-feria }
|
||||||
|
|||||||
@@ -108,6 +108,62 @@ describe('December sanctoral pull (first pass, 12/12)', () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('the Christmas Octave Sunday loses outright to a Duplex+ Comites Christi feast when the two collide -- ordinary-sunday, not privileged-sunday', () => {
|
||||||
|
// Corrects a real bug: christmastide's Sunday was originally coded
|
||||||
|
// privileged-sunday (Advent's own tier), which would have kept the
|
||||||
|
// Sunday primary here with the saint merely commemorated -- backwards
|
||||||
|
// from the live Monastic 1617 engine, which was checked directly
|
||||||
|
// against all three Duplex-II-classis collision dates and shows the
|
||||||
|
// saint winning outright every time, the Sunday only commemorated.
|
||||||
|
const stephenSunday = resolveDay('2021-12-26');
|
||||||
|
expect(stephenSunday.winner).toEqual({
|
||||||
|
kind: 'sanctoral',
|
||||||
|
id: 'st-stephen-protomartyr',
|
||||||
|
name: 'St. Stephen, Protomartyr',
|
||||||
|
rank: 'duplex-2-classis',
|
||||||
|
});
|
||||||
|
expect(stephenSunday.commemorations).toContainEqual({ kind: 'temporal', id: 'christmas-octave-sunday' });
|
||||||
|
|
||||||
|
const innocentsSunday = resolveDay('2025-12-28');
|
||||||
|
expect(innocentsSunday.winner).toEqual({
|
||||||
|
kind: 'sanctoral',
|
||||||
|
id: 'holy-innocents',
|
||||||
|
name: 'The Holy Innocents, Martyrs',
|
||||||
|
rank: 'duplex-2-classis',
|
||||||
|
});
|
||||||
|
expect(innocentsSunday.commemorations).toContainEqual({ kind: 'temporal', id: 'christmas-octave-sunday' });
|
||||||
|
|
||||||
|
// A plain Duplex (not just Duplex-II-classis) is still enough: St.
|
||||||
|
// Silvester (Dec 31) wins outright the same way when it falls on the
|
||||||
|
// Sunday, also live-verified.
|
||||||
|
const silvesterSunday = resolveDay('2023-12-31');
|
||||||
|
expect(silvesterSunday.winner).toEqual({
|
||||||
|
kind: 'sanctoral',
|
||||||
|
id: 'st-silvester-i',
|
||||||
|
name: 'St. Silvester I, Pope and Confessor',
|
||||||
|
rank: 'duplex',
|
||||||
|
});
|
||||||
|
expect(silvesterSunday.commemorations).toContainEqual({ kind: 'temporal', id: 'christmas-octave-sunday' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('the Christmas Octave Sunday still keeps a lesser feast from winning, same as before the ordinary-sunday fix', () => {
|
||||||
|
// St. Thomas Becket (Semiduplex, Dec 29) transfers off the Sunday
|
||||||
|
// rather than winning it -- unaffected by the privileged->ordinary
|
||||||
|
// change, since both tiers transfer a Semiduplex here; this test
|
||||||
|
// guards against a regression the other direction.
|
||||||
|
const beckettSunday = resolveDay('2024-12-29');
|
||||||
|
expect(beckettSunday.winner.kind).toBe('temporal');
|
||||||
|
expect(beckettSunday.commemorations.some((c) => c.kind === 'sanctoral')).toBe(false);
|
||||||
|
// St. Thomas still gets his day -- pushed to the next open one.
|
||||||
|
const transferred = resolveDay('2024-12-30');
|
||||||
|
expect(transferred.winner).toEqual({
|
||||||
|
kind: 'sanctoral',
|
||||||
|
id: 'st-thomas-becket',
|
||||||
|
name: 'St. Thomas of Canterbury, Bishop and Martyr',
|
||||||
|
rank: 'semiduplex',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('the Christmas Octave commemorations build up day by day as each Comites Christi feast starts its own octave', () => {
|
it('the Christmas Octave commemorations build up day by day as each Comites Christi feast starts its own octave', () => {
|
||||||
// Same clean year (2033) as above, walking the whole week to show the
|
// Same clean year (2033) as above, walking the whole week to show the
|
||||||
// accumulation directly -- this is the concrete shape of "commemorations
|
// accumulation directly -- this is the concrete shape of "commemorations
|
||||||
|
|||||||
Reference in New Issue
Block a user