Commit Graph

59 Commits

Author SHA1 Message Date
will 95901ef56a Always list the day's actual winner first in getDayLabel
The anchor-day and plain-temporal-fallback branches were listing any
commemorated saint before the winning identity, so a lower-ranked saint
merely riding along as a commemoration (e.g. St. Andrew on Advent I, or
Ss. Tryphon/Respicius/Nympha on an ordinary Sunday) read as if it were
the day's own winner, with the actual winner's rank label dangling at
the end with no name attached. The winner should always lead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ME8QNPdEmHSbSx1r6VmDRG
2026-08-30 06:10:14 -04:00
will c25505cdc0 Add the Patronage of St. Joseph as a new movable feast with octave
Deploy / deploy (push) Successful in 1m21s
This Duplex I classis feast (instituted by Pius IX, 1847) didn't exist
anywhere in vu's calendar. Dated per the older, pre-1955 reckoning --
Wednesday after the 2nd Sunday after Easter (Easter+17) -- rather than the
1913 Pius X reform's later placement on the 3rd Sunday after Easter
itself, per direct instruction. Mechanism: one new temporal-feast record
plus a new EASTER_OFFSET_STARTS table entry (the only code change --
everything else is the existing generic anchor-driven resolution).

Authored the feast day's own Matins reading and its full 7-day octave
(days 2/3/4/6/7/8; day 5, the Sunday, has no override in the source at
all, correctly left unauthored).

Fixed one real collateral effect: an existing fixed-year calendar test
(St. Pudentiana vs. St. Peter Celestine, 2038-05-19) broke because that
date now falls on this octave's own closing day, tying Celestine's rank
against the octave's threshold -- the app's own documented tie-break
correctly favors the octave that year. Moved the proof date to 2033.
Also bumped the PWA precache file-size cap (6 MiB -> 8 MiB) since this
content pull pushed the main bundle past the previous limit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhysogLP9eCeKS7JEwRi6y
2026-08-28 07:12:08 -04:00
will 4bbd78b1fd Model Ascension, Corpus Christi, and the Sacred Heart as temporal feasts
Deploy / deploy (push) Successful in 1m23s
Adds pre-1955 TemporalFeastRecords (rank duplex-1-classis, real octaves)
for the three "feasts of the Lord" that were previously only referenced
as bare date offsets: Corpus Christi/Sacred Heart's own days already
couldn't lose to a sanctoral candidate, but with no record the day fell
back to the generic Trinity-week feria collect and never displayed its
real name; Ascension had no protection at all against an ordinary saint
winning it outright. Sacred Heart's own record carries the
forbidsSuccessorCommemoration flag added in the prior commit, refusing to
commemorate Most Precious Blood on the rare late-Easter date they fall
adjacent.

octave.wins is set to duplex on all three, matching Pentecost's own
verified threshold, despite a known conflict with a previously
live-verified case (St. Ubald winning First Vespers within Ascension's
own octave) -- kept per direct instruction; the affected tests (Ubald,
St. Margaret of Scotland) were updated to assert the new behavior, and
the tradeoff is documented in ascension.yml and TODO.md. A handful of
unrelated test fixtures that happened to land inside these new octave
windows were moved to nearby clean dates.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
2026-08-26 15:21:26 -04:00
will dde539d2e4 Fix Vespers commemoration: a Simplex successor is commemorated too
Deploy / deploy (push) Successful in 1m18s
User-reported: 2026-08-24 Vespers (St. Bartholomew, Duplex II. classis,
keeps his own evening) should have commemorated 2026-08-25's St. Louis
(Simplex), but didn't. This was the exact untested asymmetry the old
commemorationOf's own doc comment flagged as "inferred by symmetry, not
independently live-verified." Live-verifying now shows the two
directions genuinely differ: a Simplex predecessor losing to tomorrow's
First Vespers is correctly excluded (Aug 7 Donatus case, "nihil de
præcedenti"), but a Simplex successor displaced because today keeps its
own Vespers IS still commemorated (Aug 24->25, "commemoratio de
sequenti").

Split the one shared commemorationOf into
commemorationOfDisplacedPredecessor (keeps the Simplex exclusion) and
commemorationOfDisplacedSuccessor (drops it).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
2026-08-26 08:57:03 -04:00
will 9fb9cb5e24 Add Ember-day mechanism (privileged feria, not a rank contest) + real content
Deploy / deploy (push) Successful in 1m17s
Researched whether September/Advent Ember days belong in the
movable-feasts.ts table alongside Christ the King/Immaculate Heart of
Mary. Live-verified against the reference engine they don't: Ember days
are privileged ferias (a saint can still win outright against them), not
named feasts contesting the day by rank.

Two smaller pieces instead: calendar/temporal.ts's septemberEmberDayOffset
(Sunday nearest Sept 14, same "nearest" arithmetic adventStart already
used, factored into a shared nearestSunday helper) feeds a new
resolveTemporalCategory check giving those 3 dates privileged-feria-minor
(live-verified correct); calendar/ember-days.ts's applyEmberDay relabels
the day's own temporal id to the Ember day's own (so its real content is
found) when the feria itself wins, or adds a commemoration when a saint
does. Advent Ember days needed no precedence change -- Advent's own
season default already covers them.

Found and fixed a real bug along the way: matins.ts's nocturnReadingIds
only ever pulled a commemorated *sanctoral* id's own readings, never a
commemorated *temporal* one's -- so a commemorated Ember day (the common
case) would never have surfaced its own content. Same root cause as the
day.winner.id gap the IHM relocation fixed earlier, just hiding in the
commemorations loop instead.

Authored all 6 days' real collect + 3 Matins readings each, transcribed
directly from the reference engine (September: Tempora/093-{3,5,6}.txt;
Advent: Tempora/Adv3-{3,5,6}.txt, whose lessons are themselves a
cross-reference to the Annunciation's own Common, followed and
transcribed from there). Kept as 3 separate readings per day rather than
the usual combine-into-one default, since each carries its own
genuinely distinct proper responsory.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VZSAgRi4QE4XRTqVto93zA
2026-08-22 07:27:52 -04:00
will 5e79fb4edf Generalize non-Sunday movable feasts into one Easter-offset resolver
Deploy / deploy (push) Successful in 1m21s
The bespoke applyImmaculateHeart function (following the applyMarianSaturday/
applyChristTheKing precedent of one hand-written override function per
feast) doesn't scale: several more feasts are planned that all reduce to
"weekday N days from Easter Sunday" (Ember/Rogation days, more
Sacred-Heart-family Marian devotions, St. Joseph's pre-1955 Eastertide
feast, Lenten Friday Passion devotions), and one-off functions invite
subtle ordering bugs -- applyImmaculateHeart had to be sequenced after
applyMarianSaturday specifically or it would have been silently clobbered.

Replaced with calendar/movable-feasts.ts's generic applyMovableFeasts,
which scans calendar/temporal-feasts.ts's existing per-feast YAML records
for a new optional `easterOffset` field. Adding the next movable feast is
now a new data/calendar/temporal-feasts/<id>.yml file with `rank` and
`easterOffset` set, not a new TypeScript function. Same rank-compared,
commemorate-the-loser semantics as before, just centralized instead of
duplicated per feast.

christ-the-king, marian-saturday, and christmas-octave-sunday stay as
their own functions -- they're structurally different rules (a fixed
month-position search, a date-less fallback default, and a fixed-date-
range Sunday search, respectively), not Easter offsets, so force-fitting
them into this table wouldn't actually simplify anything.

No behavior change -- the existing Immaculate Heart of Mary test suite
passes unchanged through the new generic path.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VZSAgRi4QE4XRTqVto93zA
2026-08-22 06:33:15 -04:00
will 224f34908c Relocate Immaculate Heart of Mary off Aug 22 to Easter+69
Fixed Aug 22 collided outright with the Assumption's own octave-closing
day (both this project's blended calendar tracks are kept deliberately,
so one shouldn't permanently suppress the other). Moved IHM to the
Saturday after the Feast of the Sacred Heart -- its real diocesan date
from 1914 until Pius XII's 1944 fixed-date decree, and also the date the
1969 reform returned to.

Required real new mechanism, not just a data move: a new bespoke
calendar/index.ts override (applyImmaculateHeart, following the existing
applyMarianSaturday/applyChristTheKing precedent), a move from the
sanctoral saints store to the temporal-feasts store (different propers
lookup entirely), and a real bug fix in matins.ts's nocturnReadingIds,
which only ever picked up a *sanctoral* winner's own reading file.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VZSAgRi4QE4XRTqVto93zA
2026-08-22 05:59:33 -04:00
will 3e1fd3b9c4 Strengthen the Immaculate Conception's and Nativity BVM's octaves too
Deploy / deploy (push) Successful in 1m8s
Same `wins: duplex` override as the Assumption's and Pentecost's
octaves, applied to two more common-class octaves. Accepted side
effect: St. Damasus (Dec 11) and St. Nicholas of Tolentino (Sep 10),
both Semiduplex, no longer tie-and-win an ordinary octave day here --
they're now commemorated instead of winning outright.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-19 07:40:39 -04:00
will 6f8f6618b9 Strengthen the Assumption's octave against a demoted St. John Eudes
Demote St. John Eudes (Aug 19) from Duplex to Semiduplex -- too minor
a confessor to keep outranking the Assumption's octave. To make that
demotion actually cede the day, raise the Assumption's octave to
`wins: duplex` (same pattern already used by Pentecost's octave), so an
ordinary-day tie no longer automatically favors the occurring saint.

Promote St. Thomas of Canterbury (Dec 29) to Duplex so he keeps
winning against the Christmas octave stack now that ordinary-day ties
are no longer a given.

Also add a closing-day tie-break to octave-vs-octave precedence
(pickWinningOctave): when two active octaves tie in rank, the one on
its own closing day now wins the label contest, ahead of the existing
"more recently started" tie-break. Needed because Assumption's day 3
and St. Lawrence's own closing day (Aug 17) now tie at Duplex, and the
closing day should still govern that date's label.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-19 07:39:58 -04:00
will e7bbc7c9f5 Add bilingual day-label headers with Latin weekday/season/ordinal vocabulary
Builds every day label as a {en, la} pair (weekdays, ranks, season/ordinal
phrasing authored in Latin; proper names without an authored Latin form
fall back to their English string) and merges the date+day-label into one
header in the day-nav bar.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-19 05:27:44 -04:00
will 01667e7926 Revert ordinary-Sunday Semiduplex to transferring, per direct instruction
Deploy / deploy (push) Successful in 1m9s
Keeps Simplex commemorating in place, but a Semiduplex feast on an
ordinary Sunday goes back to transferring off to the next open day —
this app's own design choice, not a correction against a reference
engine. The transfer mechanism is already generic: this file's `decideOccurrence`
only signals "couldn't hold onto this candidate" for the day itself;
calendar/index.ts's resolveDay is what independently checks each
neighboring day's own native occurrence for an incoming transfer and
claims it — no separate lookback logic needed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 11:56:15 -04:00
will f43f030a6a Fix ordinary-Sunday precedence and unify getDayLabel's commemoration rendering
Two related fixes surfaced while chasing why St. Gregory Thaumaturgus
appeared to be misdated on Nov 18:

- calendar/commemorations.ts's `ordinary-sunday` case was transferring a
  Semiduplex (or lower) saint off the Sunday instead of commemorating it
  in place — an earlier, unverified guess. Live-verified against both
  Tridentine 1906 and Divino Afflatu 1954 (St. Gregory Thaumaturgus, St.
  Clement, St. Apollinaris, St. Thomas Becket, all real cases): the saint
  stays and is commemorated on the Sunday itself, same as Simplex, never
  pushed to the next open day. This is what was actually moving Gregory
  onto Nov 18 — not a data error. `applyChristmasOctaveSunday`'s own
  Dec 26-29 special case needed a matching adjustment (per its own
  documented intent, the displaced saint there is deliberately *not*
  commemorated in place, since he reappears in full on Dec 30 instead).

- getDayLabel had five branches, each hand-assembling its own
  filter/format logic for which commemorations to show — which is why
  the octave phrasing, the closing-day title, and a missing Sunday
  commemoration turned into three separate bugs earlier instead of one.
  Replaced with a single shared `collectCommemorations` used by every
  branch. This also exposed that the sanctoral-winner branch never
  showed any commemorated saint at all, and every other branch only
  showed the *first* one (`.find()`), silently dropping real collisions
  — both now show every commemorated saint, matching this app's own
  generous-commemoration design.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 10:59:50 -04:00
will 3f07d6e8d3 Fix octave day labels: correct commemoration phrasing, closing-day title, and privileged-season precedence
Deploy / deploy (push) Successful in 1m4s
Three related day-label bugs, all found via Aug 19's mislabeled Assumption
octave commemoration:

- A sanctoral winner that displaces the only active octave now shows the
  octave's real "Nth Day within the Octave of X" phrasing (no rank, since
  it's riding along under the winning feast), not a bare feast name.
- An octave's own closing day now titles itself "Octave of X", matching
  the real DO's "in octava" vs. "infra octavam" distinction, instead of
  "8th Day within the Octave of X".
- A sufficiently-ranked octave can now outrank a privileged temporal
  season (e.g. the Immaculate Conception's octave outright winning several
  of its days against Advent, live-verified against Divino Afflatu 1954),
  via a new shared octaveGoverningPrivilegedDay helper used by both the
  day label and the actual office-content resolver. Deliberately excludes
  Christmastide, whose own stacked octaves are structurally already that
  season's temporal content rather than a foreign add-on.

Updates a Matins test fixture that had unknowingly relied on the
Dec 15 bug (Advent ferial + a lone commemorated saint) and splits it into
a clean ferial case plus a dedicated commemorated-saint case.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 08:49:51 -04:00
will 427ba6756a Show rank in the day label for every winner kind, not just sanctoral
Deploy / deploy (push) Successful in 1m3s
Rank display (added in 1fc4bd7) only fired for a plain sanctoral
winner. Every other case -- an active octave day, a named temporal
feast, a season anchor day (Easter, Trinity Sunday, Epiphany), or the
plain ordinal Sunday/feria fallback -- showed no rank at all, which is
what made today's octave day (Aug 18, day 4 of the Assumption's
octave) show no rank. Octave days use the octave's own already-computed
effective rank; anchor days get a fixed Duplex I Class (Ash Wednesday
excepted -- a privileged feria has no duplex-scale rank); the plain
fallback derives a Semiduplex/Feria label from the day's own
temporalCategory, since Sundays/ferias aren't on the duplex scale at
all.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 07:41:57 -04:00
will 1fc4bd7160 Fix octave-tie precedence, day-label commemorations, and rank display
A tie between an occurring saint's rank and an active octave now favors
the octave only on its own elevated closing day (live-verified: St.
Hyacinth vs. St. Lawrence's own Aug 17 closing day), not on an ordinary
octave day, where a tied saint still wins as before -- confirmed against
two already-tested counterexamples (St. Thomas of Canterbury, St.
Nicholas of Tolentino) that a blanket tie-flip would have broken.

getDayLabel previously dropped every commemoration whenever the day's
winner was a plain saint, and dropped every non-headline active octave
even when an octave itself won -- both fixed. Rank is now shown after
the day's own winner's name (previously not shown anywhere in the UI).

Also authored assumption-octave-day-3.yml, a real content gap (Aug 17,
day 3 of her octave) surfaced while fixing the above.
2026-08-18 06:11:37 -04:00
will f7af1e7cbf Add November sanctoral content (5 saints/feasts)
Deploy / deploy (push) Successful in 1m6s
St. Charles Borromeo (11-04), the Octave Day of All Saints (11-08,
own real Cyprian/Augustine Nocturn 2-3 content, collect reused from
All Saints via cross-id propers), St. Albert the Great (11-15),
St. Gertrude (11-16), St. Felix of Valois (11-20). All Souls' Day
(11-02) deliberately skipped -- a Requiem office, not a normal
saint's office, a genuine mechanism gap.

Several new fixed-date Duplex+ saints displaced existing test
fixtures that had assumed particular dates were clean/ferial/
plain-Sunday: prime.test.ts's MONDAY constant, weekday.test.ts's
clean-Sunday case, and day-label.test.ts's post-Epiphany-overflow
and open-octave-day cases. Fixed by finding genuinely clean
alternate dates/years, never by weakening assertions.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 17:49:06 -04:00
will 0955f7cbd1 Add October sanctoral content: 12 saints/feasts
Deploy / deploy (push) Successful in 1m9s
Continues the full-year sanctoral import: the Guardian Angels (Duplex
majus, full proper content), St. Thérèse of Lisieux, St. Bruno, St.
Bridget of Sweden, St. Francis Borgia, the Maternity of the BVM (Duplex
II Classis, instituted 1931 for the 1500th anniversary of the Council
of Ephesus, full proper content), St. Edward the Confessor, St. Teresa
of Avila (distinct from St. Thérèse of Lisieux -- two different
Carmelite saints sharing a name), St. Margaret Mary Alacoque, St. Peter
of Alcantara, St. John Cantius, and St. Raphael the Archangel (own
full proper content, matching st-gabriel-archangel.yml's established
pattern for a Sancti file that redirects wholesale to another date's
file but still carries its own real content).

St. Raphael's new fixed day (Oct 24, Duplex majus) collided with the
"clean, empty Saturday" fixture used by three tests for Marian
Saturday/Lauds-psalmody-override behavior; moved all three to 2026-07-04,
verified genuinely free of any sanctoral entry (not even a commemorated
Simplex).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 17:30:49 -04:00
will 2cf5e9cd39 Add September sanctoral content: 10 saints/feasts
Deploy / deploy (push) Successful in 1m7s
Continues the full-year sanctoral import: St. Stephen of Hungary, St.
Pius X, St. Lawrence Justinian, Ss. Protus and Hyacinth, the Holy Name
of Mary, the Seven Sorrows of the BVM (Duplex II Classis, own full
proper content except Nocturn 2, a real cross-reference to Passion
Friday's own temporal content), the Impression of the Stigmata of St.
Francis, St. Joseph of Cupertino, Our Lady of Ransom, and St.
Wenceslaus.

Ss. Protus and Hyacinth (Sep 11) were previously excluded under a
stale "real secondary saint blocked by the Nativity's own octave, same
as St. Clare in August" note -- wrong, same class of error already
corrected for St. Tiburtius/Susanna in August: the octave-window
exclusion was never a real rule. Sep 15 (day 8 of the Nativity's own
octave) is now also the Seven Sorrows' own fixed day (Duplex II
Classis), which wins outright with the octave still commemorated
alongside her -- updated september-sanctoral.test.ts's own "excluded
secondary saints" case accordingly, splitting it into the still-valid
Sep 9 (Gorgonius) half and a new Sep 15 case reflecting the real
winner.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 17:13:04 -04:00
will c4726c2953 Add August sanctoral content: 10 saints/feasts
Deploy / deploy (push) Successful in 1m9s
Continues the full-year sanctoral import: Ss. Tiburtius and Susanna, Ss.
Hippolytus and Cassian, the Vigil of the Assumption, St. Joachim (Duplex
II Classis, own full proper content), St. Hyacinth, St. John Eudes, St.
Jane Frances de Chantal, the Immaculate Heart of the BVM (Duplex II
Classis, instituted 1942, full proper content), St. Joseph Calasanctius,
and St. Raymond Nonnatus.

Several of the new fixed dates (Aug 16, 17, 21, 22) fall within or
adjacent to St. Lawrence's and the Assumption's overlapping octave
windows and now win outright there under the ordinary-feria/ordinary-
sunday precedence rules, displacing what several existing tests
expected to be bare octave commemorations or ferial fallbacks. Updated:

- august-sanctoral.test.ts: Aug 22 now correctly shows the Immaculate
  Heart of Mary as the winner, with the Assumption's octave still
  commemorated alongside her.
- day-label.test.ts: the two octave-priority tests pinned to Aug 17
  (now St. Hyacinth's own day) moved their "day 8 alone" case to All
  Saints' own octave (Nov 8, still open); the two-octaves-overlap
  comparison can no longer be demonstrated via any real date in this
  app since every day where St. Lawrence's and the Assumption's octaves
  genuinely overlap is now real sanctoral content -- the underlying
  `pickWinningOctave` mechanism itself stays covered by
  tests/calendar/octaves.test.ts's own synthetic-data unit test.
- vespers.test.ts: the Thursday Ps 138 split test moved off Aug 20,
  whose own first Vespers is now claimed by St. Jane Frances de
  Chantal's fixed day (Aug 21).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 16:59:17 -04:00
will 22917c0068 Add July sanctoral content: 11 saints/feasts, fix St. Leo II's wrong date
Deploy / deploy (push) Successful in 1m6s
Continues the full-year sanctoral import: the Most Precious Blood of Our
Lord (Duplex I Classis, full proper office, elevated by Pius XI for the
1933 Redemption jubilee), the Visitation of the BVM (Duplex II Classis,
full proper office), St. Leo II, St. Anthony Mary Zaccaria, the Octave
Day of Ss. Peter and Paul (own real content, not a bare continuation),
Ss. Cyril and Methodius, St. Elizabeth of Portugal, St. Henry, Our Lady
of Mount Carmel, St. Vincent de Paul, and St. Ignatius of Loyola.

Also fixes a real pre-existing bug surfaced while authoring St. Leo II:
an earlier June sanctoral pull had mapped him to "06-28" (his own vita
text mentions his burial "upon the 28th day of June," but his actual
liturgical feast, per the reference engine's Sancti/07-03.txt, is July
3) with no saints/st-leo-ii.yml ever authored for it -- a wrong-date
stub, same class of artifact as the pre-existing St. Apollinaris
wrong-date bug already documented in july-sanctoral.test.ts. Removed
the stale June 28 entry now that he's correctly authored on July 3.

Two day-label tests pinned to Trinity-Sunday-relative dates that now
collide with new fixed feasts (Jul 6: Octave Day of Ss. Peter and Paul)
were moved to collision-free years/dates, and the July stub test
covering "pure octave-continuation days" was updated to a date (July 4)
that's still genuinely unmapped, since most of that range turned out to
have real content after all.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 16:43:28 -04:00
will 0b8529e04b Add June sanctoral content: 6 saints
Deploy / deploy (push) Successful in 1m4s
Continues the full-year sanctoral import: St. Angela Merici, St. Francis
Caracciolo, St. Boniface of Mainz (Bishop and Martyr, Apostle of Germany --
distinct from the earlier, unrelated St. Boniface Martyr already on May 14),
St. Norbert, St. Margaret of Scotland, and St. Aloysius Gonzaga.

Two of the new fixed dates (June 1, June 4) fall on dates used by two
day-label tests pinned to specific Trinity Sunday years; moved those to
years/dates free of the new entries, with explanatory comments.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 16:23:05 -04:00
will b4e6ed6aa0 Add May sanctoral content: 10 saints plus the Queenship of the BVM
Deploy / deploy (push) Successful in 1m6s
Continues the full-year sanctoral import (see TODO.md/memory for Jan-Apr):
St. Pius V, St. Antoninus, St. Robert Bellarmine, St. John Baptist de la
Salle, St. Paschal Baylon, St. Venantius, St. Bernardine of Siena, St. John
Baptist de Rossi, St. Augustine of Canterbury, St. Mary Magdalene de Pazzi,
and the Queenship of the BVM (May 31, Duplex II Classis, instituted by Pius
XII's 1954 "Ad cæli Reginam" — full proper content, not a Common fallback).

Adding the Queenship to May 31 surfaces a real collision with Trinity
Sunday in years where Trinity falls on May 31 (2026): since this app
models Trinitytide Sundays as plain ordinary-sunday with no special
first-class standing, a Duplex+ sanctoral feast wins outright there per
the existing precedence rule. Updated the two tests pinned to that date
accordingly, with a third moved to a Trinity Sunday date (2023-06-04)
free of any sanctoral entry to keep testing the octave-vs-anchor-day
interaction in isolation.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 16:13:19 -04:00
will ce778d51e3 Add 6 more February saints/feasts previously never added
Deploy / deploy (push) Successful in 1m6s
Purification of the BVM (Feb 2), St. Andrew Corsini (Feb 4), St. John
of Matha (Feb 8), Apparition of the Immaculate BVM at Lourdes (Feb 11),
Ss. Seven Founders of the Servite Order (Feb 12), St. Gabriel of Our
Lady of Sorrows (Feb 27) -- all had real, complete Matins content in
the reference engine and no exclusion comment; simply never reached
during the earlier month-by-month sanctoral pulls. Continuing the same
sweep as January's St. Francis de Sales/St. Martina/St. John Bosco.

Test update (not a regression): St. Andrew Corsini transfers onto Feb 5
in years where Sexagesima falls on his own Feb 4, outranking St. Agatha
when it does -- february-sanctoral.test.ts's proof year for Agatha
moved from 2029 (now a collision year) to 2025 (clean).

npm test (365 tests) and tsc --noEmit both pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 15:26:00 -04:00
will 80f4f935be Add 4 more fixed Lord's/BVM feasts, and fix Our Lady of the Snows' Nocturn 3
Deploy / deploy (push) Successful in 1m6s
Finding of the Holy Cross (May 3), the Transfiguration (Aug 6), the
Exaltation of the Holy Cross (Sep 14), and Dedication of the Basilica of
the Most Holy Savior (Nov 9, the Lateran) were all excluded under the
same stale "fixed feast of the Lord, not modeled" note that turned out
wrong for Our Lady of the Snows. All four have real, complete content in
the reference engine. Presentation of the BVM (Nov 21) was excluded
under the equivalent "fixed BVM feast" note and is added the same way.

- finding-of-the-holy-cross: fully proprium, own collect/antiphon/Matins
  throughout; now correctly outranks
  ss-alexander-eventius-theodulus-and-juvenal, matching what that
  saint's own file already documented as the live reality.
- transfiguration: same proprium shape. Its subordinate saints (Ss.
  Xystus/Felicissimus/Agapitus) stay excluded -- blocked by the real,
  separate octave/subordination-rendering gap, not by an unmodeled
  Transfiguration.
- exaltation-of-the-holy-cross: reuses the Finding of the Holy Cross's
  content wholesale (ex Sancti/05-03) -- collect/antiphon via a cross-id
  `propers` pointer, Matins nocturn-readings duplicated (no cross-id
  lookup exists for that mechanism).
- dedication-of-the-basilica-of-the-most-holy-savior: reuses the
  existing Common-of-a-Dedication (collect-c8, benedictus-antiphon-
  common-of-a-dedication), real unique Nocturn 2 vita of her own. Her
  secondary, St. Theodore, stays excluded for the same
  octave/subordination reason as above.
- presentation-of-the-bvm: real unique collect of her own; her
  Benedictus antiphon is a substituted Common reference
  (truncate-and-add-alleluia edit specific to this feast), authored as
  her own file.

Also: our-lady-of-the-snows.yml was missing its own Nocturn 3 (she
defers to Commune/C11's own Gospel-incipit-plus-Bede-homily, same as
Presentation of the BVM) -- added.

Test updates (not regressions): three tests had fixed proof dates
colliding with the newly-added feasts, updated to reflect the new,
correct behavior. npm test (365 tests) and tsc --noEmit both pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 14:48:50 -04:00
will a7901b3c61 Implement the resumed-post-Epiphany-Sunday temporal-id algorithm
Deploy / deploy (push) Successful in 1m6s
Post-Pentecost overflow years (early Easter, fewer than 6 Sundays after
Epiphany fit before Septuagesima) previously clamped every excess Sunday
to post-pentecost-24 instead of resuming the skipped post-Epiphany
Sundays' own content, per the traditional rubric. Ported directly from
the reference engine's own DivinumOfficium/Date.pm getweek().

Also adds the Epiphany VI Saturday-before-Septuagesima commemoration
(only when Epiphany V was the last Sunday to actually occur), and fixes
day-label.ts's on-screen display to track the same resumed-Sunday
content instead of a raw elapsed-week count — including a correction so
the fixed final Sunday of the year always reads "23rd Sunday after
Trinity", not a per-year-varying number.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-16 20:07:04 -04:00
will 979bbe6aa4 Model cross-day Vespers commemorations, fix First Vespers threshold
Deploy / deploy (push) Successful in 1m1s
Whichever of today/tomorrow doesn't govern a given evening's Vespers
can still be commemorated there, unless it's Simplex (or a bare
temporal winner with no standing of its own) — live-verified in both
directions against the real Monastic 1617 engine: Ss. Cyriacus/Largus/
Smaragdus (Semiduplex) commemorated when Sunday claims First Vespers
over them; St. Anne commemorated even though St. James (Duplex II.
classis) keeps his own Second Vespers outright; St. Donatus (Simplex)
gets nothing ("nihil de præcedenti") in the same situation Cyriacus/
etc. did get a commemoration. The isMajorFixedFeastOfTheLord override
(Christmas/Epiphany/Candlemas/Easter/Ascension/Corpus Christi/Sacred
Heart) deliberately doesn't inherit this yet — no live data on whether
those suppress it the way privileged-sunday/privileged-feria-major do
during the day.

Also fixes hasFirstVespers's threshold, found wrong while gathering
the above evidence: it required duplex-majus+, but Ss. Cyriacus/etc.
(plain Semiduplex) actually claims First Vespers over St. Donatus in
the live engine. Lowered to semiduplex, matching the sibling
privileged-feria-minor threshold already used just below it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13 18:59:16 -04:00
will 130b0f983d Extend the source-file fallback to Frances of Rome/Bibiana, fix a real Agatha/Lucy gap
Deploy / deploy (push) Successful in 56s
Follow-up to the previous commit: applies the same "read the fileref
directly, no live query required" fix to St. Frances of Rome and St.
Bibiana, whose own filerefs simply hadn't been derived yet (they predate
the Kalendaria-table work this session built). Both resolve to
common-of-a-virgin, same as several of the 15 fixed previously.

Also swept every saint on the calendar (not just this batch's own
lineage) for any other still-missing collect or Benedictus antiphon,
which turned up a real, older gap: St. Agatha and St. Lucy's own file
comments already documented "resolves honestly missing... despite
propers being set" -- written before collectCommon existed as a
mechanism at all. Agatha's own [Oratio] is a name-substituted reference
confirmed identical to the already-existing collect-c6.yml template, so
collectCommon was simply wired in. Lucy's own [Oratio] references a
different Common formula unedited, with her own [Name] section supplying
the whole descriptive phrase a plain name field would otherwise need the
template for -- written as her own st-lucy-collect.yml rather than a new
single-use template, since she's the only current user of that unedited
form.

St. Clare showed up in the same sweep but is a false positive: her real
content lives in a separate commemoration-bundle file, used via a
different code path the sweep's synthetic-winner methodology doesn't
exercise -- already fully authored, no gap.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13 10:56:10 -04:00
will 6bb4c6a80f Author day collects for all 94 propers:null saints via Kalendaria tables
Deploy / deploy (push) Successful in 59s
Blind per-date source-file reading (Sancti/SanctiM MM-DD.txt) turned out
unreliable for collect authorship: those files are era-merged, carrying
centuries of accumulated saints behind rubric-conditional gating, so a
naive read often returned a saint canonized long after 1617 instead of
the Monastic-Tridentine-era one actually on this calendar (St. Didacus
instead of All Saints of the Benedictine Order, St. Rose of Lima instead
of Ss. Felix and Adauctus, etc).

Fixed by pulling from web/www/Tabulae/Kalendaria/'s own era-specific
calendar tables (1570.txt Tridentine base + M1617.txt's Monastic diffs)
instead, cross-validated against the pre-1955/Divino Afflatu chain
(1888->1906->1939->1954) as a corroborating signal. Cross-referencing all
205 existing saint records against this table confirmed 204/205 were
already correctly placed -- the earlier live-query verification work was
sound, only blind file-reading was flawed -- so no sanctoral-calendar.yml
corrections were needed, just the collect content itself.

Two collect shapes came out of the 94: 34 proper collects (own YAML file,
Latin verified against source, English translated+draft where the source
lacked it) and 60 resolved via a new Common-collect templating mechanism
-- SaintRecord.collectCommon/collectName plus substituteName() in
resolve-common.ts, filling a template's {N} placeholders positionally
from the saint's own declined name, across 21 new common/collect-c*.yml
templates named after the source's own C-numbering.

St. Michael's Sep 29 propers resolved via its whole-file @Sancti/05-08
inheritance (Apparition of St. Michael, May 8). St. Martha's plural-
template default was overridden to the singular collect-c6a since she's
one person, not a pair.

Also fixes a latent bug this surfaced: getDayCollect looked up
`${collectCommon}-collect`, but collect-c*.yml files are id'd as
`collect-c2` etc with no such suffix -- caught by a smoke test where
every one of the 93 non-Michael saints resolved as missing.

4 pre-existing tests updated: they asserted specific saints (St.
Benedict, St. Romanus Abbot, St. Anthony Abbot) had no authored collect,
which is no longer true; resolve-common.test.ts's generic "missing" case
now uses a synthetic day/winner since no real unauthored saint remains
as an example.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13 08:19:28 -04:00
will ea29e5ee45 Add Dec 26-30's own Sunday rule -- a deliberate remix, not a live-verified fix
Deploy / deploy (push) Successful in 54s
Per direct instruction, and explicitly framed as this project's own
departure from Monastic 1617 itself: within Dec 26-30 inclusive (exactly
one real Sunday falls somewhere in that window every year), whichever
date is the actual Sunday always wins as Nat1-0 outright, with no rank
check at all -- even Stephen/John/Holy Innocents (Duplex II. classis)
get fully displaced, not just commemorated. The displaced saint isn't
commemorated in place either; he reappears in full as Dec 30's own
winner instead (the block's one date with no fixed saint of its own).
Rank never matters for this rule -- confirmed with Becket (Semiduplex)
transferring the same way as the Duplex-II-classis saints.

This deliberately diverges both from what Monastic 1617 itself does on
Dec 26-29 (live-verified two commits ago: the saint wins there, Sunday
merely commemorated) and from the general privileged-sunday transfer
rule elsewhere (which only transfers ranks below duplex-majus and
commemorates everything else in place) -- this window transfers every
rank and commemorates nothing in place, a genuinely new, third
behavior specific to this 5-day block.

Implemented as calendar/index.ts's applyChristmasOctaveSunday, a
narrowly-scoped layer in the same spirit as applyMarianSaturday/
applyChristTheKing, rather than by changing the shared
decideOccurrence/transfer machinery every other Sunday relies on. Dec 31
and everything outside Dec 26-30 is untouched -- St. Silvester still
beats the Sunday there via the plain, unchanged ordinary-sunday rule.

Verified against all five possible Sunday positions within the window
(Dec 26/27/28/29/30) plus the "nothing displaces anything" control case,
each with its own dedicated test in the new
tests/calendar/christmas-octave-sunday.test.ts. Updates two existing
tests whose assertions were correct under the old rule and are now
superseded specifically within this window (Stephen/Innocents no longer
win their own Sunday-collision dates there) while confirming the
underlying ordinary-sunday rule is still live and real outside it (Dec
31/St. Silvester).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-12 10:59:34 -04:00
will 397f31f4fc Implement octave-vs-octave precedence, and fix a real day-label bug it surfaced
Deploy / deploy (push) Successful in 52s
When more than one octave is active on a day with no temporal standing of
its own (St. Lawrence's and the Assumption's genuinely overlap every Aug
16-17), which one governs the day's content/label is now decided by rank
comparison instead of "whichever started first" (an accident of
insertion order). Per direct instruction:

- Highest effective rank wins outright; every other active octave still
  gets commemorated, same as a single octave already outranking a weak
  rival saint.
- A rank tie goes to whichever octave started more recently -- day 1 of
  a new octave needs to be fully present, the whole point of it
  starting. No real tied-rank case exists yet to verify this
  empirically, unlike everything else here -- documented in TODO.md as
  a stated decision, not a live finding.

New OctaveConfig.closingDayRank (default duplex): an octave's own final
day ("in Octava") is elevated above its ordinary in-between rank --
live-verified as a real, general pattern (both St. Lawrence's Aug 17 and
the Assumption's Aug 22 show as Duplex, above their otherwise-Semiduplex
ordinary days), not a one-off. This elevation is *why* Lawrence's octave
beats the Assumption's on their one real overlap day despite the
Assumption being the far higher-ranked feast overall. Feeds both the
existing rival-saint threshold and the new octave-vs-octave comparison.

calendar/octaves.ts gains resolveActiveOctave (+ pickWinningOctave, the
comparison itself factored out for direct unit testing against synthetic
data, since no real tied-rank overlap exists to test against yet).
hours/resolve-common.ts's resolveOfficeWinner and calendar/day-label.ts
both now call it instead of each keeping their own "activeOctavesFor(...)
[0]" logic.

That consolidation surfaced a real, independent bug: getDayLabel never
checked temporalCategory at all before choosing an octave name, unlike
resolveOfficeWinner -- found while testing the real Aug 16 overlap (a
Sunday that year, where the temporal Sunday has standing and should win
outright). Live-verified counterexample: the Christmas Octave's own
stack (Dec 30) was wrongly labeled "3rd Day within the Octave of The Holy
Innocents" instead of the correct plain temporal label -- the real title
never names any of the four stacked octaves there. Fixed by sharing the
exact same ordinary-feria gate resolveOfficeWinner already had, so the
two can no longer disagree.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-12 09:38:06 -04:00
will 5f32a3751c 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>
2026-08-12 06:39:48 -04:00
will ff81a6fe52 Fix Christmas Octave Sunday's occurrence precedence (was backwards)
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>
2026-08-12 06:30:46 -04:00
will 2247e8c27f calendar: exempt Vigils from Our Lady's Saturday's demotion
Deploy / deploy (push) Successful in 49s
Refined per direct correction: Our Lady's Saturday is really only a
Simplex-strength standing, not a privileged-feria-minor-shaped one --
a Vigil keeps forcing its own primacy on a Saturday the same way it
already does any other day (see calendar/commemorations.ts's own
transferDirectionOf special-casing for Vigils elsewhere). Only a
Simplex saint alone now loses to it; a Vigil, along with anything
Semiduplex-or-higher, wins outright and Marian Saturday doesn't apply.

Un-does the two test-date moves this same regression prompted last
time (Vigil of St. Lawrence, Vigil of St. John Baptist) -- both dates'
original years work again now that the fix is right.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 14:20:13 -04:00
will 0404642614 calendar: add Christ the King, last Sunday of October
Deploy / deploy (push) Successful in 51s
A 1925 addition, so nowhere in the Monastic Tridentinum 1617 base this
project otherwise targets -- content sourced from "Monastic Divino
1930" instead, the Monastic-lineage version of the era that actually
carries it. Always wins outright (Duplex I. classis, confirmed live),
commemorating whichever Sunday after Pentecost it displaces -- same
additive-layering shape as applyOctaves/applyMarianSaturday, run last
so nested commemorations (e.g. a Simplex saint already commemorated
under that Sunday) survive underneath it.

Extended the Lauds psalmody-override mechanism (both the psalm groups
and, newly, the chapter/responsory/hymn/versicle bundle) to recognize
named temporal winners as unconditionally override-eligible, not just
duplex-majus+ sanctoral ones -- generalizing what had been a Marian-
Saturday-only special case. Suffrages needed their own explicit check
too: isDoubleOrHigher only ever looks at a sanctoral rank, and a named
temporal winner has no FeastClass to check at all.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 14:13:22 -04:00
will 747a078580 calendar: model Our Lady's Saturday as a real occurrence outcome
Deploy / deploy (push) Successful in 49s
On a free Saturday (nothing privileged already claims it, no active
octave), the day's own identity is now "Our Lady's Saturday" rather
than an anonymous ordinary-feria -- mirrors privileged-feria-minor
exactly, per direct instruction: Semiduplex-or-higher still wins
outright (Marian Saturday doesn't apply at all); below that (Simplex,
and Vigil, both under semiduplex on the FeastClass scale) loses and is
commemorated instead. Layered additively after decideOccurrence, same
shape as applyOctaves -- never touches decideOccurrence's own rules.

Needed a real winner identity (not just the plain temporal feria id)
so day-label/antiphon/collect sourcing can recognize it -- added a
temporal-feasts record purely for that, and taught getDayLabel to
check it for any named temporal winner (a small, free improvement for
Christmas/Pentecost's own labels too, previously unhandled).

hours: build the duplex-majus+ Lauds psalmody override (per-feast)

lauds-psalmody no longer unconditionally uses the plain weekday
default: a duplex-majus-or-higher sanctoral winner, or Our Lady's
Saturday (unconditional, no rank threshold -- it isn't competing with
the weekday default the way a saint is), now substitutes its own
proper psalm groups/antiphons/canticle. Per-feast, not per-Common, per
direct instruction, even though most duplex-majus+ saints across the
year don't have one authored yet and fall back to the plain weekday
default until they do.

Content for the worked example (St. Lawrence's own day) surfaced a
real bug while sourcing it: st-lawrence-antiphon.yml had been read
from the Roman/secular rite's own [Ant 1], not Monastic 1617's actual
Benedictus antiphon for that day -- corrected from a fresh live query.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 14:02:55 -04:00
will eec76a1e4e calendar: enable the four remaining real octaves
Deploy / deploy (push) Successful in 44s
Assumption (Aug 15-22), Nativity of the BVM (Sep 8-15), Immaculate
Conception (Dec 8-15), and All Saints (Nov 1-8) now declare octave:
{ enabled: true }, same generic mechanism as St. Lawrence and the
Christmas trio. Every octave this pull has identified is now modeled;
Matins reading content is a separate, larger follow-up (see conversation)
-- these still just commemorate at L/V-equivalent level for now.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 08:20:47 -04:00
will da3b6e893e calendar: model octaves as a generic, data-driven mechanism
Deploy / deploy (push) Successful in 46s
Adds calendar/octaves.ts: a lookback over the past week collecting every
octave (sanctoral or temporal) still active on a date, stacking multiple
at once (Christmas + St. Stephen + St. John + Holy Innocents all
commemorated together within the Christmas Octave). Declared via an
optional `octave` field on a saint's own record or a new small
TemporalFeastRecord (calendar/temporal-feasts.ts) for temporal ids like
Christmas/Pentecost that didn't have a metadata record before -- data-
driven per user design discussion, with `{ enabled: true }` alone using
sensible defaults (8 days, semiduplex threshold) so a minimal declaration
works without authored content.

Wired into resolveDay as a post-processing layer: doesn't change how a
single day's own precedence contest is decided, just adds commemorations
for active octaves and occasionally overrides the winner when the
occurring saint doesn't clear the strictest active octave's threshold.

Populated so far: St. Lawrence's own octave (the one that repeatedly cost
real saints their spot in August), the three Comites Christi octaves
(Stephen/John/Innocents -- Thomas of Canterbury deliberately excluded,
per discussion), and Pentecost's (duplex threshold, user-specified).
Pentecost's octave offsets are also removed from temporal-categories.yml's
privileged-feria-major classification, letting a real candidate reach the
new octave layer instead of being transferred away first -- with the
side effect that Pentecost's own Ember Saturday no longer forces a
transfer (a sub-threshold saint is now commemorated in place instead, see
tests/calendar/transfer.test.ts's updated case). Assumption, Nativity
BVM, Immaculate Conception, and All Saints' own octaves are not yet
populated with octave data -- deliberately deferred to a follow-up pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 07:23:43 -04:00
will c0413a44dc propers: add December's collect and antiphon text
Deploy / deploy (push) Successful in 45s
10 collects, 5 antiphons -- including backfilling the pre-existing
Immaculate Conception entry. St. Damasus's collect is Latin-only (no
English translation exists in the reference source at all); a few
others (All Saints, Bibiana, Immaculate Conception) needed their English
read directly from the raw source file after the live query's English
side either omitted the Oratio translation or rendered the wrong Marian
feast's text -- caught by cross-checking, not assumed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 06:34:45 -04:00
will 08f94823f7 calendar: give Advent's ordinary ferias their own precedence tier
Deploy / deploy (push) Successful in 44s
Found while starting the December sanctoral pull: Advent's plain
(non-Ember) weekday ferias have real standing in the live Monastic 1617
engine that the existing ordinary-feria category couldn't represent --
a Simplex saint (St. Bibiana, Dec 2) is merely commemorated there rather
than winning outright, while a Semiduplex+ saint (St. Nicholas, Dec 6)
wins with the feria itself commemorated back. Adds a third, weaker
privileged-feria-minor tier (Semiduplex+ threshold, vs. privileged-
feria's Duplex+) rather than reusing either existing tier, mirroring how
privileged-feria/privileged-feria-major were split in March. Lent's own
ordinary ferias likely share this property but are left as-is, unverified
this session.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 06:23:35 -04:00
will 7cc6adfb55 propers: add November's collect and antiphon text
Deploy / deploy (push) Successful in 44s
9 collects, 3 antiphons -- including backfilling the pre-existing All
Saints entry. Also updates two pre-existing tests whose shared date
(2025-11-30, Advent I Sunday) now correctly shows St. Andrew commemorated
alongside it, confirmed against the live reference engine.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 06:18:12 -04:00
will 14227c7afe propers: add October's collect text
Deploy / deploy (push) Successful in 46s
7 collects. Also moves two pre-existing tests' dates off Oct 4-5, which
now carry real sanctoral content (St. Francis, Ss. Placid and
Companions) that changes their governing behavior -- same class of
collision as previous months.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 06:07:51 -04:00
will 3376036779 propers: add September's collect and antiphon text
Deploy / deploy (push) Successful in 43s
6 collects, 1 antiphon -- including backfilling the pre-existing Nativity
of the BVM entry now that the pulling methodology exists.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 21:20:44 -04:00
will a492be961b propers: add August's collect and antiphon text
Deploy / deploy (push) Successful in 44s
11 collects, 4 antiphons -- including backfilling the three pre-existing
August entries (Lawrence, Assumption, Augustine) now that the pulling
methodology exists. Also updates three pre-existing tests whose dates
collided with this month's new real content: the vigil-of-St.-Lawrence
backward-transfer case now runs into a real feast at its landing day
instead of an empty one (confirmed correct against the live reference
engine, including the surviving commemoration on the impeded Sunday
itself), and two other tests moved off Aug 9/10 to dates unaffected by
the new data.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 21:11:56 -04:00
will c03d6a227d propers: add July's collect and antiphon text
Deploy / deploy (push) Successful in 42s
Real collect text for all 9 July saints that have one, plus St. Mary
Magdalene's own antiphon — same extraction method as prior months.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 18:38:50 -04:00
will 9b8dc200a1 propers: add June's collect and antiphon text
Deploy / deploy (push) Successful in 42s
Real collect text for all 16 June saints that have one, plus a real
antiphon for 4 of them and a fifth (Ss. Peter and Paul) that deliberately
reuses the Chair-of-Peter-at-Antioch antiphon text, matching the source's
own cross-reference — same extraction method as prior months.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 17:37:27 -04:00
will a6a72f277d propers: add May's collect and antiphon text
Deploy / deploy (push) Successful in 42s
Real collect text for all 13 May saints that have one, plus a real
antiphon for the 3 that have one of their own (Ss. Philip and James, St.
John Before the Latin Gate, the Apparition of St. Michael) — same
extraction method as prior months. Two saints (St. Peter Celestine, St.
Urban I) have an [Ant 1] in the source that turned out to just be a
cross-reference to the generic Common template, not real unique text, so
no antiphon file was authored for them.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 17:25:56 -04:00
will f0e32ae0c1 calendar: fix transferred candidates blindly winning outright
Found via real data (the May sanctoral pull): a transfer landing on a day
whose own native winner was temporal blindly took over as winner,
regardless of that day's own precedence category — so a transferred-in
Simplex saint (St. Felix I, impeded by Pentecost's Ember Saturday) was
overwriting Trinity Sunday itself instead of being merely commemorated,
the way a native Simplex candidate on an ordinary Sunday already
correctly is.

Fixes applyIncomingTransfer to run the arriving candidate through
decideOccurrence using the receiving day's own temporalCategory, the same
rules a native occurrence there would use, instead of assuming an empty
temporal slot means automatic victory.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 17:25:27 -04:00
will 88074cdfe6 propers: add April's collect text
Deploy / deploy (push) Successful in 41s
Real collect text for all 8 April saints that have one — same extraction
method as prior months. One correction to St. Robert's own English
translation in the source, which left his name in Latin genitive form
("blessed Robérti") rather than translating it — fixed, flagged in the
file as a transcription artifact, not a deliberate style choice.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 17:14:12 -04:00
will effe2b1333 calendar: split privileged-feria into two real precedence tiers
Deploy / deploy (push) Successful in 41s
A plain Duplex saint was losing to any privileged feria (Ember days
included) since the occurrence engine only let duplex-1-classis+ get
even a commemoration there. Verified this was wrong: St. Gregory the
Great, plain Duplex, outright wins against a Lenten Ember Saturday in
the real Monastic 1617 engine.

Splits TemporalCategory's single privileged-feria into privileged-feria
(the lesser tier — Lent's Ember days, verified — now behaves like an
ordinary Sunday: Duplex+ wins outright) and privileged-feria-major (Ash
Wednesday, Holy Week, the Easter Octave, verified via St. Mark only ever
being commemorated there, never winning — behaves like privileged-
Sunday). Everywhere else the old single category was ambiguous
(Pentecost's own Ember days/Vigil/Octave, the Vigil of Christmas)
defaults to the stricter major tier pending verification.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 15:51:09 -04:00
will a2d86a4879 propers: add March's collect and antiphon text
Deploy / deploy (push) Successful in 40s
Real collect text for all 6 March saints that have one, plus St. Joseph's
own antiphon — same extraction method as January/February.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 15:38:11 -04:00