Track a transferred saint's origin date on DayWinner and Commemoration

Adds transferredFrom to both DayWinner's sanctoral variant and
Commemoration's sanctoral variant, set in calendar/index.ts's
applyIncomingTransfer whenever a transferred-in candidate actually lands
(wins outright) or ends up merely commemorated (lost a collision, or fell
below the landing day's own threshold) — previously this signal was
discarded after resolveDay used it once to decide the winner, so nothing
downstream could tell a transferred feast apart from a native one.

Also adds transferredAway to LiturgicalDay, set from a date's own native
occurrence when its candidate couldn't be kept there at all, so a UI can
note "this office moved elsewhere" without asserting a specific landing
date (which a later, unmodeled multi-hop chain — e.g. into Holy Week —
could get wrong).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013g7AsSvMD9oazR17f3BxLz
This commit is contained in:
2026-08-31 08:53:02 -04:00
parent cb60039ab2
commit db9c844caf
6 changed files with 74 additions and 11 deletions
+8 -1
View File
@@ -45,7 +45,14 @@ describe('April sanctoral pull (first pass)', () => {
]);
const monday = resolveDay('2029-04-30');
expect(monday.winner).toEqual({ kind: 'sanctoral', id: 'st-robert', name: 'St. Robert, Abbot', nameLa: 'Sanctus Robertus, Abbas', rank: 'duplex' });
expect(monday.winner).toEqual({
kind: 'sanctoral',
id: 'st-robert',
name: 'St. Robert, Abbot',
nameLa: 'Sanctus Robertus, Abbas',
rank: 'duplex',
transferredFrom: '2029-04-29',
});
expect(monday.commemorations).toEqual([
{ kind: 'sanctoral', id: 'st-peter-martyr', name: 'St. Peter Martyr, Martyr', nameLa: 'Sanctus Petrus Martyr, Martyr', rank: 'semiduplex' },
]);