30b3971190be545b403241e44356764ffe907262
134 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
1a1b296c5f |
Model the Paschaltide alleluia suffix on Common-category antiphons
Deploy / deploy (push) Successful in 56s
Live-querying settled the "sometimes 1, sometimes 2 allelúja" question: categories without their own dedicated Paschaltide source-text chain (Confessor-Bishop/Doctor, Abbot, Virgin, ...) get a mechanical single suffix appended at render time, not a rank/octave-dependent count. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
75b731221e |
Close out P/T/S/N: St. Benedict's/All Saints Benedictine's own content, St. Michael redirect bug
Deploy / deploy (push) Successful in 57s
The last 2 duplex-majus+ saints held back from the original 29-saint P/T/S/N pass (for lacking a collect at the time) get the same individual live-query treatment as their peers: real, unique proper text for both (St. Benedict's own Prime antiphon is the opening line of St. Gregory the Great's Life of St. Benedict; All Saints of the Benedictine Order draws on Matt 13:43, Luke 6:22-23, and a well-known All Saints antiphon) -- 14 new files, English translated throughout since the source rendered none for either. A final calendar-wide sweep (every saint's resolveMinorHourAntiphon/ resolveMinorHourChapter) turned up one more real gap, in the mechanism itself rather than missing data: St. Michael's propers field points at Apparition of St. Michael's own id (the two feasts are word-for-word identical), and getDayCollect/getBenedictusAntiphon both explicitly follow propers when resolving content -- but getMinorHourOverrideId doesn't; it keys off the day's own winner id directly, so resolveMinorHourAntiphon was looking for a file that could never exist. Fixed the same way as Finding of St. Stephen: minorHoursCommon points directly at his delegate's already-authored proper files. Every real saint on this app's calendar now has real P/T/S/N content. The only remaining absence is Ss. Ursula and Companions (no way to verify a category of one) and the example-confessor test placeholder, which was never meant to have any. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
37dac8b476 |
Sweep minorHoursCommon (P/T/S/N) across the whole calendar, not just the 94-saint batch
Deploy / deploy (push) Successful in 56s
The original 29-saint P/T/S/N pass only ever covered duplex-majus+ saints; every below-majus saint from the *original*, pre-94-batch 109-saint pass had never had Prime/Terce/Sext/None attempted at all -- same gap already found and fixed for the 94-batch's own below-majus saints, now closed for the rest of the calendar too. Reused the Kalendaria-table-validated fileref approach rather than a blind Sancti/MM-DD.txt read -- a real near-miss caught this early: St. Apollonia's Sancti/02-09.txt is currently St. Cyril of Alexandria's (a 19th-century addition to that filename slot); blind reading would have silently attributed his Doctor-of-the-Church Common to her. Also fixed a regex bug the same pass turned up: the "vide"/"ex CXX" pattern matched the bare word "Commune" (no number) and reading-specific sub-references like "ex C4 in 2 loco" -- found via St. Clement, whose Monastic-specific [Rule] override has neither a clean "vide CXX" nor a number after "Commune." 90 below-majus saints swept, ~82 wired directly into the categories already established in the previous commits -- no new content needed, every C-number variant found already falls inside an already-verified family. A real bug this pass caught and fixed in its own output: Ss. Ursula and Companions (deliberately left minorHoursCommon-unwired) got swept up and wrongly wired, since she has collectCommon set despite propers: null and being a genuine commemoration-only stub -- the Kalendaria lookup silently defaulted to St. Hilarion's own primary slot at her shared date. Caught by cross-checking every swept saint's propers field for this exact pattern; reverted. A real new category found: Doctors of the Church are not one thing. 6 of the 7 saints whose own [Rule] says "vide C4a" (Athanasius, Augustine, Basil the Great, Hilary of Poitiers, John Chrysostom, Leo I) render P/T/S/N byte-identical to the already-verified common-of-a-confessor-bishop -- wired directly. St. Gregory the Great is the one genuine exception: his own live-rendered P/T/S/N is real, unique proper text (his own election, his Liber Regulae Pastoralis, the dove-and-quill legend, the "non Angli sed Angeli" episode) -- 7 new files, English translated throughout since the source rendered none. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
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> |
||
|
|
ea15e909df |
Resolve 15 "unwinnable" stubs' Benedictus antiphons from source directly
Deploy / deploy (push) Successful in 55s
Direct feedback on the previous commit's framing: "unwinnable" was describing an artifact of Divinum Officium's own single-winner precedence model, not a real content gap -- this app already renders commemorated saints on their own terms and doesn't need a saint to win a live query to have real content. Fixed by reading each of the 15 saints' own already-validated fileref directly (the exact same fileref their collect was already sourced from during the Kalendaria-table pull) for its [Ant 1] section, falling back to whatever Common its own [Rule]/[Rank] "vide"/"ex CXX" reference names when there isn't one -- the same proper-then-Common shape getDayCollect/collectCommon already uses, just applied to the Benedictus antiphon too. 14 of the 15 had no [Ant 1] of their own at all -- clean Common fallback, and every one of their C-numbers falls inside a family already live-query-verified in the previous commit, so minorHoursCommon/benedictusCommon were wired directly with full confidence: St. Marcus, St. Felix (Presbyter), St. Hermes, St. Saturninus, St. Prisca, St. Thecla, St. Catherine of Siena, Ss. Machabees, Ss. Marius/Martha/Audifax/Abachum, Ss. Twelve Brothers, Ss. Alexander/Eventius/Theodulus/Juvenal, Ss. Felix/Simplicius/ Faustinus/Beatrix, Ss. Nabor and Felix. St. Felicitas needed one new category (C7), but it turned out to be a cross-reference resolving to text byte-identical to the already-verified common-of-a-virgin. The 1 remaining (Ss. Euphemia, Lucy, and Geminian) does have her own real [Ant 1] -- but marked draft, not verified, on principle: St. Alexius's own file also has a genuine [Ant 1] that his actual live-rendered Benedictus antiphon doesn't use (common-of-an-abbot's text instead), so a raw [Ant 1] read alone isn't sufficient proof, and for a saint that can never be live-checked at all that uncertainty can't be resolved either way -- used the text anyway, honestly flagged rather than claimed as confirmed. St. Frances of Rome and St. Bibiana (the older, pre-Kalendaria-table 109-saint pass) are good candidates for this same fix but weren't touched here, since their own fileref was never derived by this session's work. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
9faa7168bc |
Author Benedictus antiphons for the remaining 26 propers:null saints
Deploy / deploy (push) Successful in 57s
Completes the 94-saint batch's Benedictus-antiphon coverage. A saint with a genuine proper collect doesn't imply a genuine proper antiphon, same finding as St. Martin of Tours's mixed proper/shared split from the original 29-saint pass: of the 26, 15 are genuinely unwinnable stubs (already documented from the collects pass -- always commemorated, never the day's own title, so nothing to live-query) and left honestly missing, matching St. Frances of Rome/St. Bibiana's precedent from the original 109-saint pass; 7 of the remaining 11 turned out to render byte-identical to an already-authored Common category (benedictusCommon wired directly, no new content) -- including Ss. Dionysius and Companions, whose own `common` field says common-of-a-martyr-bishop but whose live-verified minor-hour text actually matches common-of-several-martyrs, another case (like Chair of St. Peter earlier) where the two fields genuinely diverge. The other 4 have real unique text of their own: All Saints of the Benedictine Order, St. Agnes (secunda), St. Benedict (no English in the source, translated and marked draft, same gap as St. Scholastica's), and the Vigil of St. John the Baptist (deliberately echoing the Benedictus canticle's own opening words). P/T/S/N for these 26 not attempted here -- a further layer on top, same as how the original 109 got Benedictus antiphons long before their own later, separate P/T/S/N pass. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
ffaa797940 |
Author Benedictus antiphon + P/T/S/N Commons for 66 propers:null saints
Deploy / deploy (push) Successful in 56s
Continues the 94-saint batch this collects pass unblocked. Raw Commune/*.txt fields don't reliably match what the engine actually renders per hour -- same lesson as the collects pass, confirmed again: no CommuneM/*.txt file defines explicit per-hour antiphon fields for any category this batch needed, and the already-authored common-of-a-confessor-bishop content (from the original 29-saint pass) doesn't match Commune/C4.txt's own raw [Ant 1] either, since it was live-query-sourced rather than read from the file directly. Fixed by querying web/cgi-bin/horas/officium.pl directly (local Perl, not a network fetch) for one representative saint per Common category, with every representative's title verified against an accent-insensitive name-stem match before its content is trusted -- caught a stale-date bug this way: St. Emerentiana's stored clean-year comment actually rendered St. Hilary of Poitiers's office that year. Cross-querying multiple saints per nominal SaintRecord.common category found the real liturgical groupings are coarser (Martyr-Bishop and Martyr; Abbot, Confessor-not-Bishop, and Confessor; Virgin-Martyr, Virgin, and Holy Woman all render identical minor-hour text) but not uniformly so (Pope-Martyrs render distinct allelúja-toned text from plain Several-Martyrs; the Dedication of the Basilicas of Ss. Peter and Paul draws from the Dedication Common, not its nominal common-of-an-apostle at all). Net: 7 new shared Common categories plus the pre-existing common-of-a-confessor-bishop (which also needed a new Benedictus-antiphon file of its own) cover 66 of the 94 saints. New mechanism: SaintRecord.benedictusCommon, with getBenedictusAntiphon falling back to it the same way getDayCollect already falls back to collectCommon -- no name-substitution needed here, since every Common category in current use renders name-free Benedictus-antiphon text. Also fixes a real bug this surfaced: getMinorHourOverrideId gated all Prime/Terce/Sext/None lookup behind the same duplex-majus+ threshold Lauds' own psalmody override uses, on the assumption that only a strong feast carries its own minor-hour content -- live-querying proved that wrong (a winning Semiduplex saint still renders its own antiphons, not the ferial default). Lauds' psalmody override itself stays majus+-gated correctly, since it's a much bigger per-saint commitment this batch doesn't add a Common fallback for. Ss. Ursula and Companions deliberately left without a minor-hour Common: her collect template has no other calendar member to verify a shared text against, and she can never be queried directly (a genuinely unwinnable stub) -- left honestly unauthored rather than guessed. The other 26 of the 94 (own proper collect, from the collects batch) still need their own individually-authored Benedictus antiphon, same shape as the original 109-saint pass -- not done in this pass. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
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>
|
||
|
|
2658a2b94e |
Fix splitNamedAntiphon silently upgrading draft text to verified
Deploy / deploy (push) Successful in 53s
Every antiphon that goes through the incipit/full split -- which is every antiphon across every hour -- lost its real status the moment it passed through here: splitNamedAntiphon hardcoded `verified` on its output via verifiedText(), regardless of what the source's actual status was. Concretely, this meant St. Scholastica's antiphon (I translated it myself, no English existed in the source), Matthias's and several other apostles' reworded English, and Gregory the Great's translated antiphon all silently rendered as if fully verified -- losing the "unverified draft text" UI marker (src/ui/styles.css's .text-draft, a dashed underline + tooltip) that's supposed to distinguish "copied straight from the source" from "Claude's own rendering." Fixed by having splitNamedAntiphon accept a real ResolvedText and carry its per-language status through unchanged to both outputs, instead of silently upgrading everything to verified. Callers whose antiphon never had a status field to begin with (plain weekday-default antiphons and Lauds psalmody overrides -- neither type tracks status at all, always implicitly verified by the source file's own live-checked convention) now wrap with verifiedText() explicitly at the call site, rather than that assumption being buried inside splitNamedAntiphon itself. resolveMinorHourAntiphon (Prime/Terce/Sext/None's override lookup) now returns a full ResolvedText for the same reason. Verified end-to-end with St. Scholastica's real draft-English antiphon, both via a direct unit test and visually in the browser (the dashed underline now shows correctly under her Benedictus antiphon). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
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> |
||
|
|
5f4cf33776 |
Add per-feast overrides to Prime/Terce/Sext/None; fill Lauds' own Lawrence office bundle
Deploy / deploy (push) Successful in 51s
Prime/Terce/Sext/None had no per-feast override mechanism at all before this -- their psalm antiphon always fell back to the plain weekday default and their chapter was always a single fixed per-annum/per-weekday text, regardless of what was actually being celebrated, even on a saint's own actual feast day (not just during an octave). Confirmed live (Monastic Tridentinum 1617) that St. Lawrence has his own real antiphon and chapter at every one of these hours, both on his own day and throughout his octave. New shared mechanism in hours/resolve-common.ts: getMinorHourOverrideId (duplex-majus+ threshold, kept in sync with Lauds' own so it's one shared backlog), resolveMinorHourAntiphon, resolveMinorHourChapter -- all resolveOfficeWinner-aware, so an octave day gets the same override as the feast's own actual day. Prime additionally needed isSundayOrFeastOffice (its capitulum/Preces Sunday-vs-ferial choice) made octave-aware -- live-verified Prime's capitulum stays the Sunday/feast form throughout the octave too, so no new file was needed there, just reaching the existing one correctly. Also fills in Lauds' own still-missing Lawrence office bundle (capitulum/responsory/hymn/versicle) -- flagged in TODO.md as worth fixing "even before tackling the other 32" and still not done until now. Authored real content for St. Lawrence across all five hours from live queries. The same ~31-saint backlog (TODO.md) now applies uniformly across Lauds and the four hours fixed here. Also documents a real, found-not-fixed gap: when two octaves overlap with no temporal standing to yield to (St. Lawrence's and the Assumption's genuinely overlap every Aug 16-17), this app currently picks whichever started first, which happens to match the live engine on Aug 17 (Lawrence's own elevated final "Octave Day" outranks the Assumption's ordinary octave-day strength) but only by coincidence, not a real rank comparison -- proposed design written up in TODO.md pending a decision on scope. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
143244203d |
Fix octave-day office content: use the octave's own feast, not the plain ferial
Deploy / deploy (push) Successful in 52s
Real, multi-part bug found by looking closely at today's rendering (day 3
of St. Lawrence's octave, St. Clare commemorated): the psalmody
antiphons, hymn, chapter/responsory/versicle, Benedictus antiphon, and
day collect were all keyed off `day.winner` directly, which stays the
plain temporal identity (post-pentecost-11) throughout an octave --
St. Lawrence's own already-authored psalmody override and collect never
engaged on any day but his actual feast day. Live-verified (Tridentine
1910, 2026-08-12) that the whole office on an ordinary octave day
actually comes from the octave's own feast ("{ex Commune aut Festo}" /
"{ex Proprio Sanctorum}"), with a *weaker* commemorated saint (Clare)
getting a separate Ant+V/R+collect block of her own alongside it.
Fixed with a new resolveOfficeWinner(day) in hours/resolve-common.ts,
used everywhere getDayCollect/getDayCollects/getBenedictusAntiphon/
getPsalmodyOverrideFor used to read day.winner directly. Deliberately
gated on temporalCategory === 'ordinary-feria' (the day has no standing
of its own) rather than "any active octave" -- the Christmas Octave's
own stacked octaves are the live-verified counterexample where the
*temporal* day keeps the office instead, each octave becoming its own
separate commemoration block (not yet modeled, flagged in TODO.md).
Also fixes the ferial Preces gate (added in the previous commit) to
exclude active octaves the same way the suffrages already do --
live-verified "Preces Feriales{omittitur}" on the same date.
getDayCollects now renders a sanctoral commemoration as a real
Ant+V/R+collect bundle when authored (${propers}-commemoration.yml),
not just a bare, unlabeled collect -- the old rendering was indeed the
confusing "PRAYER / (translation pending)" block spotted today, which
was St. Clare's placeholder with no indication whose it was or why.
Authored her real commemoration bundle and standalone collect from the
same live query rather than leaving it pending.
One correction to a guess floated mid-session: the Benedictus antiphon
does NOT go to the commemorated saint (Clare) -- live-verified it stays
with the octave's own feast (Lawrence's "In cratícula"), same as
everything else in the primary office; only the separate commemoration
block is Clare's.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
||
|
|
9c9811a9ed |
Add Lauds' ferial Preces (Tridentine 1906/1910), shown on ferial/vigil days
Deploy / deploy (push) Successful in 53s
Monastic 1617 has no Preces feriales at Lauds at all -- content sourced from Tridentine 1906/1910 per direct instruction, same track as the Cross suffrage and St. Joseph's suffrage. New lauds-preces-feriales.yml (Kyrie, Pater noster, the full versicle litany, Psalm 129, closing versicles) transcribed from a live query against a clean Advent feria, matching what actually rendered rather than the underlying template's own conditional markup (the Pope/Bishop and benefactors' versicles are both dropped live despite being present in the template; the King/nation versicle pair is kept despite the template's own rubric note suggesting otherwise). New `lauds-preces` part kind (hours/types.ts) picks between this and the existing short Sunday/feast litany (lauds-short-litany.yml, unchanged content) on a ferial-or-vigil day. Deliberately not the shared `isSundayOrFeast` predicate, which treats a Vigil as a "feast" -- here a Vigil needs to land on the ferial side instead, per direct instruction. Also deliberately wider than the real 1906/1910 rubric itself, which restricts the fuller form to Advent/Lent/Ember days specifically -- shown on *every* ferial or vigil day instead, mirroring the identical explicit choice already made for Prime's own ferial Preces. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
2f8f744cd1 |
Omit Lauds suffrages entirely during Advent/Christmastide/Passiontide and any active octave
Deploy / deploy (push) Successful in 54s
Checked directly against Monastic Tridentinum 1617 (not just the Tridentine 1906/1910 track the suffrage content itself comes from) -- this omission isn't a rubric-track-specific quirk, it holds under this app's own primary source too: - Advent, Christmastide, and Passiontide ferias: suffrages omitted entirely. Confirmed ordinary Lent (weeks 1-4, not Passiontide) is NOT excluded -- only the last two weeks are. - Any day within an active octave: suffrages omitted entirely, however low that octave's own rank is -- confirmed against day 2/3 of St. Lawrence's own Semiduplex octave, well below the existing Duplex+ threshold. Today (within Lawrence's octave) was showing all five suffrages before this fix; the real office has none but the Marian antiphon. Still not modeled, flagged in TODO.md: Paschaltide's own substitution (a single alleluia-form "Suffragium Paschale" replaces the whole set during Eastertide, rather than the ordinary set showing or being omitted) -- a separate, larger feature. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
fb66f60770 |
Add St. Joseph's suffrage; fix Cross/BVM suffrage gating
Deploy / deploy (push) Successful in 51s
Three things prompted by today's date resolving wrong: 1. St. Joseph's own Lauds suffrage was never modeled at all. Added lauds-suffrage-joseph.yml, sourced from Tridentine 1906/1910 (the reference engine's "Tridentine - 1906" version) per direct instruction -- Monastic 1617's own suffrage set has no Joseph suffrage at Lauds, so this one genuinely comes from a different track than the other four. 2. The Cross suffrage's actual gating rule, live-verified against a plain ferial win, a plain Sunday win, a low-rank saint's own win (even bare Simplex), and Marian Saturday: it shows only when the bare temporal feria itself is what's being prayed -- the opposite of "Sunday or a feast of the Lord." Expressed as `!isSundayOrFeast(day)` (the same ferial/festive split Prime's capitulum already uses) plus one more exclusion for a named temporal identity like Marian Saturday, which isn't Sunday or a sanctoral win either but still isn't a bare ferial office. 3. The BVM suffrage is correctly dropped on Marian Saturday (unchanged behavior, just now understood and commented correctly): it's specific to a day whose own office is already Marian, confirmed via the same live source, not a guess. Also models St. Clare (Aug 12, Simplex under Monastic 1617) and surfaces active octaves in getDayLabel, since today's date was resolving as a plain ferial day instead of showing St. Lawrence's octave with St. Clare commemorated. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
73672853ef |
Author christmas-octave-sunday's own Benedictus antiphon
Deploy / deploy (push) Successful in 52s
Corrects the previous conclusion (that this id had no clean sourceable date at all). The reference engine has a dedicated proper for this Sunday, Tempora/Nat1-0, distinct from the individual octave-day saints' own pages -- most years the Sunday loses outright to a Duplex-II-classis octave saint (St. Stephen/St. John/Holy Innocents) and only earns a bare commemoration, which is what the earlier search kept finding, but 2029-12-30 is a year where the Sunday wins outright with no commemoration at all, so that's the date pulled from. All 52 temporal ids (54 counting marian-saturday/christ-the-king) now have an authored Benedictus antiphon, closing out the temporal half of the "every sanctoral and temporal entry needs its antiphons" task for real. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
5a76f2198c |
Author Benedictus antiphons for all 51 remaining temporal ids
Deploy / deploy (push) Successful in 50s
Pulls the Lauds Benedictus antiphon (Latin + English) for every temporal-id proper except christmas-octave-sunday, completing the "every sanctoral and temporal entry needs its antiphons" task (sanctoral side finished in prior commits this session). Dates were found programmatically: a Node script iterated resolveDay() over full years to find, for each temporal id, the first date this app's own calendar logic resolves to it, then each candidate date was cross-checked against a live Divinum Officium (Monastic Tridentinum 1617) query to confirm the title has no saint collision before pulling content. Four ids (easter-5, easter-6, post-pentecost-11, post-pentecost-14) needed a second, alternate date after the first candidate turned out to collide with a saint modeled in the live reference engine but not in this app (St. Mark, St. Athanasius, Our Lady of the Snows). christmas-octave-sunday is deliberately left unauthored: every date it can resolve to collides with a specific named octave-day feast in the real calendar, so there's no clean generic content to source -- see TODO.md. Also updates tests/hours/lauds.test.ts: the old "falls back to missing on a plain temporal day" test used a date that now has real content (post-pentecost-11), so it's replaced with a test confirming that content resolves correctly plus a new test specifically covering the christmas-octave-sunday exception. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
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> |
||
|
|
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> |
||
|
|
4548042b65 |
hours: split Saturday's Deuteronomy canticle back into its own two parts
Deploy / deploy (push) Successful in 48s
Per direct instruction: RB 13 says this canticle "in duas glorias" -- two pieces, each closing with its own Gloria Patri, framed by one shared antiphon (opening before the first, full only after the second) -- not joined into one continuous block the way this was first built. canticleText() now takes an optional verse slice so Saturday can ask for two. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
73f9c1aebe |
hours: use the Marian Sabbato hymn as Saturday's own Lauds default
Deploy / deploy (push) Successful in 47s
By explicit choice, not the honest-missing placeholder from before: a
genuinely per-annum, unprivileged Saturday isn't achievable (every one
is either Marian-Sabbato-overridden or in a privileged season with its
own swapped hymn), so Sanctae Mariae Sabbato's own hymn ("O gloriosa
Domina") becomes Saturday's default rather than leaving a gap.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
||
|
|
5830e4cfd2 |
hours: build Lauds
Deploy / deploy (push) Successful in 48s
Opening versicle; Ps 66 (fixed, no antiphon at all); the weekday- variable psalm groups (Ps 50 plus 1-2 more, framed by their own antiphon each, wholesale-substituted by Sunday's Ps 50+117-share-one- antiphon shape); the weekday OT canticle; the Laudate psalms (148-150) under one more shared antiphon; the weekday chapter/responsory/hymn/ versicle bundle; the Benedictus (framed by a day-resolved antiphon, same incipit-or-full/full-repeat shape as Compline's Nunc Dimittis); the Kyrie/Pater-noster short litany; the day's collect(s) — winner plus one per commemoration, via the new getDayCollects; the four Tridentine suffrages (omitted on a Double-or-higher feast); the conclusio; the closing versicle (the silent Our Father that precedes it isn't re-rendered, its text having already appeared once at the short litany); and the closing Marian antiphon, reusing Compline's own mechanism exactly. Known, deliberate gap, not yet fixed: the psalmody doesn't model the Commune/feast override real practice applies on a Semiduplex-or-higher day (substituting an entirely different psalm+canticle set) — every day currently gets the plain ferial weekday distribution regardless of who wins. That's a separate, larger propers-authoring task (a full Common-of-Saints psalm set per Common). Also a simplification in getDayCollects: each collect in a multi- collect day renders as its own complete "Let us pray ... Amen." block, rather than the more compressed real form (one "Let us pray," only the last collect's doxology). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
3cd6faafe6 |
hours: move Prime's test MONDAY off a date the June pull now owns
June's sanctoral pull assigned Ss. Vitus, Modestus, and Crescentia to 2026-06-15 — the same date prime.test.ts's MONDAY constant used, which correctly flips Prime's capitulum/Preces from ferial to feast form now that isSundayOrFeast sees a real sanctoral winner there. Moved to an still-unpulled October Monday instead; also fixed a stale comment that had drifted from the constant's actual value. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
813d173f5c |
hours: build Terce, Sext, and None
Deploy / deploy (push) Successful in 39s
Three separate resolver files (terce.ts/sext.ts/none.ts), not a shared little-hour module — they're structurally identical but kept independent by choice. Ordo verified against Divinum Officium (Monastic Tridentinum 1617): opening versicle, self-contained hymn, one antiphon framing three psalms (no closing repeat, unlike Prime), a capitulum with its own embedded short versicle/response, the day's own collect, and a closing identical across all three hours. Also fills in psalter-distribution.yml's previously-missing Sunday/ Monday/Tuesday psalm entries (Ps 118 sections for Sunday/Monday; Tuesday turns out to share Wednesday/Thursday's native gradual-psalm set, not a distinct one). Friday/Saturday's antiphons are derived from each day's first psalm rather than reusing the native gradual antiphons, since those two days already use a redistributed, non-native psalm set. hours/types.ts gains a 'day-collect' part kind — the first ordo to use the day's own Proper collect rather than a fixed text. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
81440de832 |
hours: add the day's-collect resolver
Terce/Sext/None's Oratio is the day's own Proper-of-season/-saints collect, not a fixed text — getDayCollect() resolves it from the LiturgicalDay's winner (temporal id or sanctoral saint's propers), falling through to an honest "missing" status for saints that don't have authored propers yet. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
226fff2ce6 |
ui: show the "day being celebrated" label
Deploy / deploy (push) Successful in 38s
Adds a real label under each hour's heading — "Monday in the 10th week after Trinity", "The 1st Sunday of Advent" — computed from whichever LiturgicalDay the hour actually resolved against, which can differ from the nav date for Compline's evening anticipation. calendar/day-label.ts combines two things: an ordinal week-within-season label (pure date arithmetic on the season anchors from calendar/temporal.ts and calendar/easter.ts — Trinity-counted, not Divinum Officium's own Pentecost-counted convention; meant to become configurable later via the same day->id indirection already used for the sanctoral calendar, not hardcoded forever), and a feast name from calendar/commemorations.ts's occurrence decision — shown alone if the feast displaces the day outright, prefixed onto the temporal label if merely commemorated, or omitted entirely if nothing's occurring. |
||
|
|
eaaca05ad8 |
calendar: First/Second Vespers anticipation for Compline
Compline (and eventually Vespers) now resolves off whichever day's identity actually governs tonight's office, not always today's — real practice anticipates a higher-ranking tomorrow (Alma Redemptoris Mater starting the Saturday evening before Advent I, Ave Regina Caelorum starting the eve of Candlemas, Regina Caeli starting at the Easter Vigil), which the previous date-only resolution missed entirely. calendar/vespers.ts's resolveEveningDay compares today's and tomorrow's precedence (reusing commemorations.ts's FeastClass machinery) to decide. One deliberate absolute exception, caught by a failing test: a short, explicit list of supreme fixed/movable feasts (Easter, Christmas, Epiphany, Candlemas, Ascension, Corpus Christi, Sacred Heart) always wins tomorrow's Vespers before checking whether today would otherwise keep its own — without it, Holy Saturday's privileged-feria status incorrectly blocked Easter's anticipation, the textbook case this whole thing exists to get right. hours/compline.ts now resolves its whole ordo through resolveEveningDay instead of resolveDay. |
||
|
|
2ea21f2c89 |
calendar: real occurrence/precedence resolution (feast ranks, sanctoral content)
Replaces the FeastRank placeholder with a real ordered FeastClass (the old pre-1955 six-level scale) and a new TemporalCategory (privileged/ordinary Sunday/feria). calendar/commemorations.ts's decideOccurrence encodes the actual precedence rules as explicit, commented branches per category rather than the reference engine's own opaque numeric weights — this app targets one ruleset, so the readability trade-off is worth it. Category membership (data/calendar/temporal-categories.yml) is a best-effort reconstruction of the pre-1955 tradition, not sourced from a primary text; expect corrections. calendar/feasts.ts resolves real sanctoral candidates, and resolveDay() wires it all together — occurring/temporalCategory are no longer stubs. isDoubleOrHigher (hours/antiphon.ts) is now a real comparison instead of a hardcoded false. Seeded 7 real saints/feasts, each verified directly against Divinum Officium's own rank data (not reconstructed from memory) as a small, growable start: St. Lawrence, the Assumption, St. Augustine, the Nativity of the BVM, St. Michael, All Saints, the Immaculate Conception. |
||
|
|
ec448bc35b |
compline: build the full hour, sharing Prime's resolver helpers
Deploy / deploy (push) Successful in 38s
Ordo is Monastic 1617 as a base, with deliberate Tridentine 1906 additions: the "In manus tuas" short responsory, the Nunc Dimittis with its "Salva nos" antiphon, the fuller Preces (Monastic's own is shorter), and Lent's "Christe, qui lux es et dies" hymn replacement (English translation marked draft, pending a real historical one). Psalms 4, 90, 133 are fixed daily with real verified text, unlike Prime's weekday-rotated psalms. The closing Marian antiphon now picks Alma Redemptoris Mater / Ave Regina Caelorum / Regina Caeli / Salve Regina by real season, using the calendar work from the previous commit — except Ave Regina Caelorum's own window (Candlemas through the day before Maundy Thursday) doesn't align to any single season value, so that one case checks the real date directly instead of going through the by-season table. resolve-common.ts extracts the resolve/status/doxology/antiphon helpers Prime already had into something Compline can share; a few propers files lose their "prime-" prefix now that both hours use them. |
||
|
|
58958aa847 |
Prime: real content (psalms, Martyrology, Regula) and ordo corrections
Deploy / deploy (push) Failing after 21s
Pulls in verified content from Divinum Officium rather than placeholders: 17 psalms (2, 6, 7-19, 118, 129), 365 days of the Martyrology, and the full 121-reading Regula cycle, plus the Athanasian Creed. Ordo corrections driven by review against the real engine output: - Capitulum and Preces now pick a Sunday/feast vs. ferial form (calendar/isSundayOrFeast); ferial Preces said every ferial day by choice. - Chapter responsory, hymn doxology, and the opening versicle's Alleluia/Laus tibi all vary by season via a shared resolver (hours/seasonal-propers.ts). - Real Roman Kalends/Nones/Ides Latin dating (calendar/roman-date.ts, verified against 363/365 real Martyrology headings) plus the historical "bis sextus" Feb 29 handling, and the Martyrology's Luna (moon-day) heading (a ported Golden-Number calculation). - Fixed responsory structure (was missing its initial full repeat), weekday psalm antiphons (opening as incipit-or-full by rank, full repeat after the psalms/Creed as its own part, "*" chant mark kept), scripture citations on the capitulum/lectio brevis, and V./R. markers switched from Unicode symbols to plain text for reliable font rendering. - Dropped Pretiosa and the dead-commemoration psalm (129) for time; trimmed section headings down to the ones that are actually named things (Preces, Chapter Office, etc. no longer relabel connective text). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
a5dc6502d7 |
Milestone 0/1: shell, calendar/psalter/hours scaffold, Prime
Deploy / deploy (push) Failing after 1m8s
Client-side-first PWA (Vite/TS, no backend) per the approved plan: day- navigable shell listing all 8 hours, Prime fully resolves via the calendar -> psalter -> ordo pipeline, the other 7 hours are registered but flagged not-implemented. Sanctoral/temporal calendar data uses a day -> id indirection layer (saints, easter-offsets, fixed-date-calendar) so reassigning a feast to a different day is a data edit, not a code change. Docker (Caddy-serving-static) + Gitea CI workflow scaffolded to match the eec/drip/bookshop operational pattern. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |