Commit Graph

354 Commits

Author SHA1 Message Date
will b52b202909 Make octave-reading source attribution bilingual
The heading above each Matins octave reading was a bare Latin string
(e.g. "Sermo sancti Bernárdi Abbátis") rendered as-is in both the
Latin and English columns, since the app shows both languages side
by side rather than toggling. Widen OctaveReadingText.source and the
lesson part's label to carry per-language text, and render it as its
own lang-columns row like the body text beneath it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L3wxvz3mPXiHxkPB5JpnmD
2026-08-21 08:04:03 -04:00
will a7da8b0211 Add Assumption's proper Matins hymn
Deploy / deploy (push) Successful in 1m13s
"Surge! Jam terris fera bruma cessit" / "Arise! the cold blasts from
earth have receded", read from the reference engine's Sancti/08-15.txt,
used throughout the Assumption's octave via that override mechanism.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L3wxvz3mPXiHxkPB5JpnmD
2026-08-21 07:56:11 -04:00
will 62c74539f8 Add Matins hymn override mechanism
Matins always rendered the plain ferial hymn, unlike Lauds/Vespers which
already check a duplex-majus+ override then a seasonal default first.
Surfaced by the Assumption's octave, which keeps the feast's own proper
hymn all week rather than falling back to ferial.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L3wxvz3mPXiHxkPB5JpnmD
2026-08-21 07:56:06 -04:00
will 4835b35fc1 Add Assumption octave commemoration content
Deploy / deploy (push) Successful in 1m13s
Assembled from already-verified Assumption pieces (Benedictus
antiphon, Vespers V/R, post-1950-dogma collect) since the octave
commemoration block this app's own generous-commemorations design
calls for has no direct reference-engine source to copy.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L3wxvz3mPXiHxkPB5JpnmD
2026-08-21 07:38:55 -04:00
will 1ed15f15c0 Fix getDayCollects skipping octave commemorations on outright-win days
The substitutedOctaveId gate only checked temporalCategory, not who
actually won the day, so a saint winning outright within an active
octave (e.g. St. Bernard vs. the Assumption octave, Aug 20) silently
lost that octave's own commemoration block at Lauds/Vespers. Now
mirrors resolveOfficeWinner's real gate (day.winner.kind and
ALWAYS_OVERRIDE_TEMPORAL_IDS).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L3wxvz3mPXiHxkPB5JpnmD
2026-08-21 07:38:49 -04:00
will 833983c875 Switch Assumption collect to the post-1950-dogma text
Deploy / deploy (push) Successful in 1m14s
Monastic 1617 itself is inconsistent: the feast/closing octave day
render the old pre-dogma "Famulórum tuórum..." collect, but the
interior octave days (16/18/19/21) render the newer "Omnípotens
sempitérne Deus, qui Immaculátam..." collect from the 1954 Divino
Afflatu revision -- a data cross-reference slip in the reference
engine, not a deliberate rubric. vu already used one collect uniformly
across the whole octave rather than replicating the split; switch that
shared collect to the newer text per user preference.
2026-08-21 07:26:44 -04:00
will 927f031d6b Add full Ant+V/R+collect commemoration for St. Jane Frances de Chantal
Deploy / deploy (push) Successful in 1m15s
Lauds/Vespers were falling back to a bare collect for her commemoration
since only the collect had been authored. Live-verified the antiphon
and versicle against the reference engine (Divino Afflatu - 1954,
1955-08-21, the nearest year her feast actually fell on a Sunday and
was commemorated rather than won).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L3wxvz3mPXiHxkPB5JpnmD
2026-08-21 07:11:01 -04:00
will 212067a823 Add date picker and audio interface to TODO
Deploy / deploy (push) Successful in 1m13s
Two new mechanism-gap items: an arbitrary-date calendar picker (day-nav
currently only steps one day at a time) and a "read it to me" audio
interface via the Web Speech API for long texts.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L3wxvz3mPXiHxkPB5JpnmD
2026-08-21 06:58:42 -04:00
will 945c5ef109 Default the initial hour to local time of day instead of always Prime
Deploy / deploy (push) Successful in 1m18s
Visiting the app with no hour in the URL previously always showed
Prime for today, since selectedHour was hardcoded in AppState. Now it
picks the hour whose band contains the visitor's local clock time.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L3wxvz3mPXiHxkPB5JpnmD
2026-08-21 06:50:42 -04:00
will 9e6b36bed9 Lower St. Jane Frances de Chantal to semiduplex
Deviates from the reference engine's plain Duplex per the user's own
calendar.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L3wxvz3mPXiHxkPB5JpnmD
2026-08-21 06:50:36 -04:00
will 784e0fb5ba Order hour nav by the day, not by build/declaration order
Deploy / deploy (push) Successful in 1m9s
HOUR_IDS drove the nav's render order but was declared arbitrarily;
reorder to Matins, Lauds, Prime, Terce, Sext, None, Vespers, Compline
so the nav reads left-to-right the way the office actually unfolds.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-19 09:33:58 -04:00
will 4373b60f07 Lay out hour nav horizontally and use real links
Deploy / deploy (push) Successful in 1m7s
Matches the reference app's row layout instead of a vertical sidebar
list, and switches from buttons to anchors since hours are real
routes — plain click still SPA-navigates, modifier/middle clicks
fall through to native browser behavior (open in new tab, etc.).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-19 09:31:46 -04:00
will 15929a6e50 Add Matins' missing closing (Benedicamus Domino / Fidelium animae)
Deploy / deploy (push) Successful in 1m7s
Matins is hand-assembled in TS rather than driven by a data/hours/*.yml
parts list, so it never got the closing wired in that every other hour
has. Live-verified against the reference engine's Monastic Tridentinum
1617 Matutinum "Conclusio" block that Matins' closing text is
byte-identical to lauds-conclusio — reusing it the same way
Vespers already does.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-19 09:24:54 -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 9364185f70 Omit responsories' own closing Gloria Patri throughout Passiontide
A different, wider rule than the psalm/canticle Gloria (Triduum-only):
responsories drop their Gloria for the whole of Passiontide (Passion
Sunday through Holy Saturday), except on a Sancti feast's own day —
live-verified (St. Joseph, Duplex I, 2027-03-19, landing in Passiontide
that year, keeps it; an ordinary ferial day in the same window omits it,
at both Compline and Prime).

Every responsory's stored text differs, Gloria-bearing vs Gloria-free,
by exactly one fixed-wording line, so resolve-common.ts's new
resolveResponsory filters that line out rather than requiring separate
per-season files or a data migration — mechanism first, per the
project's own stated content-authoring order. Wired into the four hours
that have a real responsory (Compline, Prime, Lauds, Vespers); Lauds/
Vespers' existing hand-authored Passiontide-proper responsories were
already Gloria-free and are unaffected.
2026-08-19 06:38:21 -04:00
will e93fc4032a Drop Matins' opening (versicle, Ps 3, Invitatory, hymn) during the Sacred Triduum
Tenebrae's rubric replaces Matins' usual opening with a silently-said
Pater/Ave/Credo, live-verified against both Monastic Tridentinum 1617
and Divino Afflatu 1954 (Holy Thursday: Invitatorium and Hymnus both
"omittitur", no Ps 3 or versicle either). Since this app already never
renders that silent block on ordinary days either (data/hours/prime.yml),
the fix is a pure omission straight into Nocturn 1, using the same
isInTriduum window added for the Gloria Patri work.
2026-08-19 06:18:07 -04:00
will 7ffb9afea2 Extend closing Gloria Patri to canticles, centralize instead of baking it in
Benedictus, Magnificat, and Nunc Dimittis had the Gloria Patri baked
verbatim into their propers YAML with no Triduum suppression; Matins'
Nocturn 3 OT canticles had none at all. Give the 'canticle' ResolvedPart
the same centrally-attached gloriaPatri field psalms already got, strip
the baked-in text, and drop Lauds' now-redundant local append/Triduum
check — live-verified that canticles follow the exact same Triduum-only
omission as psalms (e.g. Benedictus at Lauds of Holy Thursday).
2026-08-19 06:06:07 -04:00
will b230f3f1e8 Add closing Gloria Patri after psalms, omitted during the Sacred Triduum
Psalms across every hour rendered with no closing Gloria Patri at all.
Add it centrally (hours/index.ts) rather than per-hour, using a new
calendar/temporal.ts isInTriduum helper so it's correctly dropped from
Maundy Thursday through Holy Saturday and nowhere else — live-verified
against both of this app's actual source tracks (Divino Afflatu 1954
and Tridentine 1906), not just the modern Rubrics 1960 default. Also
fixes Lauds' existing but Triduum-blind canticle Gloria Patri append.
2026-08-19 06:03:51 -04:00
will a9f673fef9 Label Matins nocturns and the Invitatory in the rendered ordo
Deploy / deploy (push) Successful in 1m17s
Adds a section-heading ResolvedPart kind and emits "Invitatory" and
"Nocturn I/II/III" headings in matins.ts, so the hour's structural
boundaries are visible instead of rendering as one undifferentiated
stream of parts. Ferial (1-nocturn) days get no Nocturn heading, matching
their existing single-unnumbered-nocturn design.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-19 05:28:44 -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 ef71d9c5bc Distribute Matins readings front-light across nocturns, not evenly
Deploy / deploy (push) Successful in 1m7s
Nocturn 1 and 2 each get exactly one reading; Nocturn 3 absorbs the
rest of the pool, however large. A pool of only one reading goes to
Nocturn 3 rather than Nocturn 1.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 13:06:57 -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 79372fb274 Don't commemorate a Vigil alongside the very feast it anticipates
At Vespers/Compline, a day's own Vigil losing tonight to tomorrow's First
Vespers was showing up as a redundant extra commemoration alongside that
same feast (e.g. Nov 29's Compline showing both "St. Andrew" and "Vigil
of St. Andrew" for Advent I's anticipated evening).

Added an explicit `vigilOf` field to each Vigil's own saint record
(several Vigil ids don't map cleanly to their feast's id by stripping a
`vigil-of-` prefix — `vigil-of-the-assumption` vs `assumption`,
`vigil-of-st-james` vs `st-james-the-greater` — so this needs to be
explicit rather than guessed from the id or date adjacency).
calendar/vespers.ts's evening-anticipation merge now skips adding the
Vigil commemoration when tomorrow's winner or its own commemorations
already include that same feast.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 11:00:09 -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 a68ab716b7 Add rank data to named temporal feast records
TemporalFeastRecord had no rank field at all, so Christmas/Pentecost/
Christ the King/Marian Saturday had nothing for the day label to show.
Christmas, Pentecost, and Christ the King are Duplex I Class (the
latter's own file comment already said so); Marian Saturday is a
Simplex-strength votive commemoration.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 07:41:50 -04:00
will 25669dfdae Record the Confessor Matins psalmody categories in TODO.md
Deploy / deploy (push) Successful in 1m4s
Documents the Francis of Paola / Basil the Great live-verification,
the identical-apart-from-versicles finding, the Duplex+ saints checked
for proper-antiphon eligibility, and the M1617-kalendar wrinkle found
along the way (a SanctiM file existing doesn't mean the saint is
actually on the Monastic Tridentinum 1617 calendar).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 07:09:55 -04:00
will e9134b2117 Add Matins test proofs for the new Confessor category tiers
Two new Common-tier proofs (Francis of Paola, Basil the Great) confirm
the resolver picks up both new categories with verified antiphon text.
The old ferial-fallback proof (St. John Bosco, Common of a Confessor)
is now superseded since that category is authored -- swapped for Ss.
Fabian and Sebastian (Common of Several Martyrs, still unauthored).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 07:09:48 -04:00
will b944f18433 Author Common-of-a-Confessor(-Bishop) Matins psalmody overrides
Live-verified against Divinum Officium's Monastic Tridentinum 1617 CGI
instance: St. Francis of Paola (2030-04-02, "vide C5") for the plain
Confessor scheme, St. Basil the Great (2035-06-14) for the Bishop
scheme. The two turned out word-for-word identical in psalm numbers
and antiphon text across all three nocturns, differing only in their
three nocturn-closing versicles -- kept as separate full files since
the mechanism has no partial-override support.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 07:09:43 -04:00
will 0a8bcef859 Wire the Matins psalmody-override category tier into real resolution
Deploy / deploy (push) Successful in 1m5s
getMatinsPsalmodyOverride is now a genuine 3-tier lookup: proper
(saints/) -> Common (categories/, joined via the winner's own
SaintRecord.common) -> the plain ferial fallback, reversing the earlier
"category files are documentation-only" decision now that two
categories are trusted. Category files gain an `aliases` field;
common-of-a-martyr.yml lists common-of-a-martyr-bishop, since the
reference engine's own Matins psalmody redirects that Common outright
to plain Martyr — so its three Duplex+ saints (Ignatius, Callistus,
Boniface, none with proper text of his own) get real Common-tier
content with no new authoring.

tests/hours/matins.test.ts's old ferial-fallback proof (St. Ignatius)
is rewritten as a Common-tier proof; a fresh ferial-fallback proof
(St. John Bosco, an unauthored Confessor category) replaces it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 06:52:08 -04:00
will 9ba09964ea Author Common-of-a-Martyr/Apostle categories and St. Andrew's proper Matins psalmody
Deploy / deploy (push) Successful in 1m6s
Two categories live-verified: common-of-a-martyr (from St. Ignatius of
Antioch, whose own office is entirely Common — also confirms
Common-of-a-Martyr-Bishop redirects to this same scheme, and that none
of its 3 Duplex+ saints has a proper antiphon of his own) and
common-of-an-apostle (from St. Bartholomew). St. Andrew authored as the
second saint-level proof, sharing the apostle category's psalm numbers
in every slot with his own proper antiphon text.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 06:43:00 -04:00
will f9a28ec001 Add Isaiah 61 and Wisdom 3/10 scripture chapters
Sparse transcriptions (only the cited verses) for St. Andrew's Matins
Nocturn III canticles, live-verified against the reference engine.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 06:42:54 -04:00
will 2bac28d36c Refactor Matins psalmody overrides to category-keyed data
Split the store into categories/*.yml (generic Common-category psalm-
number/versicle/canticle scheme) and saints/*.yml (per-saint proper
antiphon overrides, unchanged shape) per the mechanism's own flagged
next step. St. Lawrence's file moves into saints/ with a category
cross-reference; resolution behavior (per-saint lookup, ferial
fallback when unauthored) is unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 06:42:48 -04:00
will f550412c61 Record the octave-precedence and Matins-psalmody fixes in TODO.md
Deploy / deploy (push) Successful in 1m7s
2026-08-18 06:11:57 -04:00
will 3e58f2258d Add Matins psalmody overrides for a Duplex+ weekday feast
matins.ts's three-nocturn gate correctly governed nocturn count
(Sunday, or Duplex+) but wrongly reused the literal Sunday psalmody as
content for every three-nocturn day, including a weekday feast. Live-
verified (Monastic Tridentinum 1617) that a Duplex+ weekday feast has
its own genuinely different psalmody -- confirmed per-Common-category,
not per-saint, by cross-checking St. Lawrence against St. Ignatius of
Antioch (a different Martyr sub-category, nearly identical psalm
numbers, different antiphons).

New mechanism (matins-psalmody-overrides.ts, mirroring the Lauds one
but keyed per-category) with St. Lawrence authored as the live-verified
proof; falls back to the plain ferial weekday table, redistributed into
3 nocturns, for every other Duplex+ id until its own category's content
is authored. Also generalizes the canticle shape to support a citation
spanning multiple scripture chapters under one heading (Lawrence's own
Nocturn 3), and adds the new Sirach/Jeremiah chapters his canticles cite.
2026-08-18 06:11:52 -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 ee3e155bfa Close out the octave-content TODO item
Deploy / deploy (push) Successful in 1m7s
Christmas Octave's own commemoration blocks are now modeled -- see the
prior two commits. Updates the top-of-file priority summary and the
dated build-log entry to reflect this.
2026-08-17 21:32:11 -04:00
will 6f1e152d7f Render octave commemorations in getDayCollects on stacking days
getDayCollects previously dropped kind: 'octave' commemorations
entirely, so on days where the temporal office keeps its own standing
(the Christmas Octave's own Nativity/Stephen/John/Holy-Innocents stack,
e.g. Dec 30) those octaves contributed nothing but a name in the day
label. Add an octave branch, gated on temporalCategory !== 'ordinary-
feria' -- the same condition resolveOfficeWinner uses -- so an ordinary
octave day's already-substituted primary content never gets a redundant
repeat.
2026-08-17 21:32:05 -04:00
will f60a142bb4 Add Christmas Octave's own commemoration collect content
Ant+V/R+collect "Commemoratio Octavæ" blocks for Christmas, St. Stephen,
St. John, and Holy Innocents, sourced from the reference engine's Sancti/
12-25..28.txt Octava 3 sections -- content for the mechanism change in
the next commit.
2026-08-17 21:31:55 -04:00
will 825328eae6 Add St. Francis Xavier (Dec 3) sanctoral content
Deploy / deploy (push) Successful in 1m7s
Own real Oratio and Nocturn 2-3 content (Duplex majus). This was the
only real gap left in December -- the rest of the month was already
complete from the earlier pre-1955 sanctoral pull. No test collisions:
Dec 3 was genuinely open.

This closes out the full-year sanctoral sweep (January-December).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 17:53:22 -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 253a6ce516 Add 6 more April saints previously never added
Deploy / deploy (push) Successful in 1m5s
St. Isidore of Seville, St. Vincent Ferrer, St. Hermenegild, St. Anselm,
St. Fidelis of Sigmaringen, St. Peter Canisius -- April complete.
St. Peter Canisius is the second common-of-a-confessor-doctor saint
(after St. John Damascene in March), same benedictusCommon reuse
pattern. St. Hugh, Abbot (Apr 1) checked and correctly skipped: his own
file is Commemoratio-rank with only a collect, no Lectio content at
all to source.

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

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 15:51:01 -04:00