lauds-capitulum-st-gabriel-archangel.yml carried Apparition of St.
Michael's own capitulum ("Significávit Deus...") under Gabriel's id --
found in passing while authoring his Matins psalmody. His real
capitulum, read directly from the reference engine's Sancti/03-24.txt
([Capitulum Laudes]), is Daniel's own account of the angel's visitation
(Dan 9:21-22), genuinely proper to Gabriel, not shared with Apparition
despite sharing the same hymn. No separate vespers-capitulum file exists
for this id, so the fix covers both hours via vespersCapitulumForOverride.
Updated tests/hours/lauds.test.ts: removed Gabriel from the shared-
chapter assertion loop (Guardian Angels/Raphael still legitimately share
Apparition's chapter, confirmed via their own saint files' explicit
source cross-references) and added a dedicated test for his own chapter.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhysogLP9eCeKS7JEwRi6y
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
Last of the 12-saint individual-Proprio list this session. Live-verified
against Divinum Officium (Monastic Tridentinum 1617), 2025-11-13 (clean
year): own chapter (Isa 8:18, "Ecce ego et púeri mei") and own hymn
("Salvéte, cedri Líbani," same text both hours); responsory and versicle
byte-identical to Common-of-Several-Martyrs's own already-authored
content.
This closes the individual-saint Proprio pass: 10 real saints/feasts
imported, 2 flagged stubs (Ss. Alexander etc., Ss. Machabees) confirmed
to need no new content. Combined with the 10 Common categories and the
Guardian-Angels/Archangels fix earlier this session, resolveOfficeBundle
now has real, live-verified Lauds/Vespers content for every gap the
original audit found.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
Live-verified against Divinum Officium (Monastic Tridentinum 1617),
2026-08-06 (fixed date). Fully proper feast: own chapter (Phil 3:20-21),
own distinct responsory/hymn/versicle at each hour ("Amor Jesu
dulcíssime" Lauds, "Quicúmque Christum quǽritis" Vespers), with real
Alleluias baked into the responsories.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
Fully proper feast, live-verified against Divinum Officium (Monastic
Tridentinum 1617), 2027-05-03 for the Finding (its own 2026 date
collides with a privileged Sunday) and 2026-09-14 for the Exaltation.
Own chapter (Phil 2:5-7), own distinct responsory/hymn/versicle at each
hour -- Lauds hymn "Lustris sex qui jam peráctis," Vespers hymn "Vexílla
Regis pródeunt," both with real Alleluias baked into their own text
(confirmed permanent via the Vespers hymn's own "In hoc Pascháli gáudio"
line, not seasonal contamination).
Authored under two ids (finding-of-the-holy-cross and proper-to-the-
finding-of-the-holy-cross): Exaltation's own saint file sets common:
proper-to-the-finding-of-the-holy-cross, a different id than its propers
field (a separate day-collect/antiphon lookup) -- without the second
copy, resolveOfficeBundle fell through to the ferial default for her.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
Live-verified against Divinum Officium (Monastic Tridentinum 1617),
2026-02-02 (fixed date, always winnable): only the chapter is genuinely
her own (Mal 3:1, "Ecce ego mitto Angelum meum"). Responsory, both
hymns, and both versicles are all byte-identical to Common-of-the-BVM's
own already-authored content -- duplicated under her own id.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
Live-verified against Divinum Officium (Monastic Tridentinum 1617),
2026-03-25 (fixed date, always winnable). Own chapter (Isa 7:14-15,
"Ecce virgo concípiet") and own versicle ("Ave, María, grátia plena")
at both hours, own Vespers responsory ("Ángelus Dómini * Nuntiávit
Maríæ," the opening of the Angelus). Lauds responsory and both hours'
hymns turn out byte-identical to Common-of-the-BVM's own already-
authored content -- reused verbatim.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
Live-verified against Divinum Officium (Monastic Tridentinum 1617),
2029-01-21: byte-identical to St. Agatha's own override (Sir 51:1-3).
Confirmed a real, saint-specific shared override between these two
ancient Roman virgin martyrs specifically, not a general Virgin-Martyr
rank-tier variant -- St. Lucy (also a Canon-of-the-Mass virgin martyr)
uses the plain Common chapter on her own clean day. Responsory, hymn,
and versicle reuse Common-of-a-Virgin-Martyr's own content.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
Live-verified against Divinum Officium (Monastic Tridentinum 1617),
2026-02-05: only the chapter is genuinely her own (Sir 51:1-3,
"Confitébor tibi, Dómine, Rex"). Responsory, hymn, and versicle are all
byte-identical to Common-of-a-Virgin-Martyr's own already-authored
content -- duplicated under her own id.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
Live-verified against Divinum Officium (Monastic Tridentinum 1617),
2035-06-30 (clean year): only the chapter is genuinely his own (2 Tim
4:7-8, "Bonum certámen certávi" -- Paul's own "I have fought the good
fight"). Responsory, hymn, and versicle are all byte-identical to
Common-of-an-Apostle's own already-authored content at Lauds -- reused
under his own id, since resolveOfficeBundle resolves a whole bundle per
id, not per part. Vespers content inferred by the same pattern (his real
Vespers is permanently masked by the Octave of St. John the Baptist's
Nativity closing the same day every year checked, 2026-2030 -- not
modeled in this app), not independently verified.
Updates one existing test whose date (2026-06-30) now correctly shows
his own proper chapter winning over the plain Common fallback.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
Live-verified against Divinum Officium (Monastic Tridentinum 1617),
2033-03-21 (clean year), cross-checked directly against the source's own
Monastic-specific file (SanctiM/03-21.txt), which carries a full proper
office for his Transitus despite the plain secular Sancti file having
none.
Own chapter (Eccli 50:6-7, "Ecce Confessor magnus") and own hymns at
both hours ("Inter ætérnas súperum corónas" Lauds, "Láudibus cives
résonent canóris" Vespers, recounting Subiaco and the founding of Monte
Cassino). Lauds responsory/versicle and Vespers versicle turn out
byte-identical to Common-of-a-Confessor-Bishop's own -- authored
explicitly under his own id rather than left to fall through, since his
actual common (common-of-an-abbot) resolves to a different Confessor-
Not-Bishop responsory that would be wrong here. Vespers has its own
proper responsory invoking him by name ("Sancte Pater Benedícte").
Neither hymn (nor the chapter) has an English rendering in the reference
engine -- own translations, marked draft.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
Live-verified against Divinum Officium (Monastic Tridentinum 1617),
2033-03-12 (clean year, per his own saint file's comment). Own chapter
(Eccli 50:1, "Ecce sacérdos magnus... suffúlsit domum") and own hymns at
both hours ("Mella cor obdulcántia" Lauds, "Anglórum jam Apóstolus"
Vespers, the latter recounting his sending Augustine of Canterbury and
the "non Angli sed Angeli" legend); responsory and versicle turn out
byte-identical to Common-of-a-Confessor-Bishop's own, reused verbatim.
Neither hymn has an English rendering in the reference engine at all --
own original translations, marked draft.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
Finished the "ferial/other" audit bucket via each saint's own source
file. Vigils (9 saints) are not a gap at all: every vigil's own [Rule]
explicitly says "Responsory Feria"/"Versum Feria" -- deliberate rubric,
matching this app's existing isFerialOrVigil convention. Even the "ex
C1v" tag on the 6 apostle vigils resolves to the same plain ferial text
when live-queried, confirming no override applies to the Lauds/Vespers
bundle for any vigil.
Common-of-the-BVM (5 feasts) is a real category: each source file says
plain "ex C11"/"vide C11". Live-verified votive=C11: chapter Sir 24:14,
Lauds hymn "O gloriósa Dómina" (the same pre-Urban-VIII text as the
Annunciation's own separate proper), Vespers hymn "Ave maris stella,"
same responsory at both hours, distinct versicles per hour.
Surfaced one masked collision: the Annunciation now resolves through
this Common instead of the ferial default (real improvement, still
interim until its own proper content is imported). Moved the
Passiontide-seasonal-office Vespers test off its date (Mar 25) onto the
clean Mar 30.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
Read straight from the source (Sancti/02-12.txt, Ss. Seven Holy Founders
of the Servite Order -- the only saint in this category): its own [Rule]
says plain "vide C5," no votive number of its own. Duplicated the same 7
files under common-of-several-confessors.
This closes every Common category this session's audit found with real
users -- resolveOfficeBundle now has real Lauds/Vespers content for
every category, not just the two it started with.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
Methodology upgrade this session: read each saint's own Sancti/MM-DD.txt
[Rank]/[Rule] field directly instead of hunting for a per-saint clean
year to live-query -- it states the real Common assignment (or a direct
proper-content inheritance) with zero calendar dependency.
Guardian Angels/St. Gabriel/St. Raphael the Archangels' own files say
"vide C4," but that's a Missal/Mass-propers designation -- their real
Monastic-breviary file (SanctiM/10-02.txt) cross-references St. Michael's
Apparition (Sancti/05-08, already fully authored in this app) directly
for the chapter/responsory at every hour. No common-of-an-angel category
exists in the source at all. Duplicated St. Michael's Apparition's 7
Lauds/Vespers files under each of the three saints' own ids (proper
content, not a Common fallback), live-verified on their own real 2026
days.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
Both genuinely distinct from Virgin(-Martyr) -- different chapter
Prov 31:10-11 "Mulíerem fortem," different hymn "Fortem viríli péctore"
-- but share that category's exact responsory pattern and versicle
byte-for-byte in both hours. Live-verified via St. Anne's own real day
(Jul 26). St. Monica's real day (May 4) confirms common-of-a-widow
shares the identical content with common-of-a-holy-woman, so the same 7
files were duplicated under that id too -- first content authored for
either category at all.
Proof: St. Anne's and St. Monica's own days for Lauds, St. Margaret of
Scotland's real First-Vespers anticipation (Jun 9 -> 10) for Vespers.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
common-of-a-confessor-doctor (4 saints) is another "same content,
different id" case: live-verified votive=C4a byte-identical to plain
votive=C4 (Common-of-a-Confessor-Bishop), so duplicated verbatim rather
than authored fresh, matching the already-existing matins-hymn-common-
of-a-confessor-doctor.yml precedent.
common-of-an-apostle (3 saints/feasts) is genuinely distinct: chapter
Eph 2:19-20, hymn "Exsúltet cælum láudibus" (byte-identical Lauds/
Vespers), shared versicle "Annuntiavérunt ópera Dei." Also duplicated
under the separate common-of-apostles (plural) id used by the Octave of
Ss. Peter and Paul.
Proofs: St. John Damascene (own day) + St. Robert Bellarmine (First
Vespers) for Confessor-Doctor; Commemoration of St. Paul (own day) + the
Beheading of St. John the Baptist (First Vespers) for Apostle.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
Live-verified against Divinum Officium (Monastic Tridentinum 1617)
votive=C6: chapter 2 Cor 10:17-18, hymn "Jesu, coróna Vírginum" (byte-
identical Lauds/Vespers), shared versicle "Diffúsa est grátia in lábiis
tuis" -- only the two responsories differ between the hours. Cross-
checked plain common-of-a-virgin (St. Praxedes) renders the same real
content, matching the already-existing benedictus-antiphon-common-of-a-
virgin.yml precedent -- duplicated the same 7 files under that id too.
Proof: St. Apollonia's own clean year (2029-02-09, her 2026 date collides
with St. John of Matha) for Lauds, St. Praxedes's real First-Vespers
anticipation for Vespers.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
Same finding as common-of-a-confessor: live-verified (St. Maurus, Jan 15;
St. Odo, Feb 7) that Common-of-an-Abbot's real Lauds/Vespers content is
identical to Common-of-a-Confessor-Not-Bishop's -- an Abbot isn't
necessarily a bishop, so the traditional rite reuses the plain Confessor
common for them. Duplicated the same 7 files under this id, matching the
existing benedictus-antiphon-common-of-an-abbot.yml precedent. Proof
tests on St. Maurus (Duplex II. classis, own Lauds + real First-Vespers
anticipation Jan 14 -> 15).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
Fixed a real audit-methodology bug first: the bulk gap-audit was sampling
each saint's own date via prayVespera, which reflects whatever saint
claims First Vespers that evening (often a neighboring day's), not the
sampled saint's own category. Redid it via prayLaudes (no anticipation).
That surfaced the real finding: common-of-a-confessor (37 saints, this
app's largest remaining gap) isn't a distinct liturgical Common -- it's
common-of-a-confessor-not-bishop under a different label. St. Joseph's
and St. Thomas Aquinas's chapter is byte-identical to the already-
authored Sir 31:8-9 text, and several of the 37 saints' own file comments
already say "vide C5" (Confessor Not a Bishop) directly. Not relabeled
across the 37 saint files, since matins-hymn-common-of-a-confessor.yml
and benedictus-antiphon-common-of-a-confessor.yml already establish this
plain id as the real, working one for those saints' Matins/Benedictus
content -- duplicated the Lauds/Vespers bundle under this id too, to
match that existing convention.
Updates two existing tests whose dates collided with this fix: the
FERIAL_MONDAY constant (moved off St. Raymond Nonnatus's own day) and a
new Vespers proof on St. Joseph's First Vespers.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
Third Common category (17 real users) with no Lauds/Vespers bundle
authored. Live-verified against Divinum Officium (Monastic Tridentinum
1617) votive=C4: chapter Sir 44:16-17 "Ecce sacérdos magnus," Lauds hymn
"Jesu Redémptor ómnium," shared versicle "Justum dedúxit Dóminus per vias
rectas." Found the Vespers hymn is byte-identical to Common-of-a-
Confessor-Not-Bishop's own ("Iste Conféssor Dómini sacrátus") even though
the chapter, both responsories, and the Lauds hymn all genuinely differ
between the two categories -- reused that already-authored text verbatim
rather than re-deriving it.
No real Duplex-II-classis+ saint exists in this category, so the Vespers
proof uses St. Ubald's real First-Vespers anticipation instead of a
votive-only proof. Updates one existing test (2026-04-20, Paschaltide
seasonal office) whose date turned out to also anticipate St. Anselm's
First Vespers, previously masked by this same gap.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
St. Zephyrinus (Aug 26, common-of-a-martyr-bishop, Simplex) claims First
Vespers over St. Louis's Aug 25, but that evening was showing the plain
ferial hymn instead of a real Common-of-a-Martyr hymn: no content had
been authored yet for this Common category's Lauds/Vespers bundle, so
resolveOfficeBundle's chapter lookup came back missing and the whole
bundle fell through to the ferial default.
Live-verified against Divinum Officium (Monastic Tridentinum 1617)
votive=C2b: chapter Jac 1:12, Lauds hymn "Martyr Dei, qui unicum," Vespers
hymn "Deus tuorum militum," shared versicle "Justus ut palma florebit."
Used the votive-office view rather than a real saint's own day for the
same structural reason as the earlier Confessor-Not-Bishop fix: every
real Common-of-a-Martyr-Bishop saint either has proper content of his own
(St. Lawrence, St. Stephen) or never reaches the rank needed to keep his
own Vespers (St. Zephyrinus, St. Callistus). Cross-checked votive=C2/C2a/
C2b/C2-1 all render identical text, so the same 7 files were duplicated
under the plain common-of-a-martyr id too (St. Hadrian, St. Hermes, St.
Fidelis of Sigmaringen).
Updates one existing Vespers test whose date (2026-03-03) turned out to
also anticipate St. Lucius I's First Vespers, previously masked by this
same content gap; adds two new proof tests and a TODO.md entry.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
Matins now sings "Te decet laus" (Psalterium/Common/Prayers.txt's [Te
decet]) immediately after the Te Deum on every 3-nocturn day, matching
Rule of Benedict ch. 11's close of Vigils. New common text
te-decet-laus.yml, wired into both matins.ts branches that render a Te
Deum; absent on ferial days along with it.
Also drops Psalm 129 (De profundis) from the Lauds ferial Preces and
Psalm 50 (Miserere) from the Vespers ferial Preces, per direct
instruction — both were embedded inline in the live-transcribed text.
Updated the affected fixture tests to key off a versicle that survives
the removal instead of the now-absent psalm text.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EWzE3kaSZCs79fPBrrE1aF
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.
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).
Lauds had the identical issue Vespers started with: resolveOffice only
ever rendered the plain weekday chapter/responsory/hymn/versicle,
year-round, with no Advent/Lent/Passiontide/Paschaltide override —
same source file (Major Special.txt) as Vespers', just never wired up.
Ports the same seasonalOfficeSuffix-based precedence (per-feast/octave
override -> season -> weekday default) and the matching seasonal
content, transcribed the same way as Vespers' own (Monastic hymn
variants applied from the source's substitution notation against each
base Roman text). Paschaltide's chapter is byte-identical to Vespers'
own — the source aliases "[Pasch Vespera] = @:Pasch Laudes" — so both
hours' data files intentionally carry the same text rather than one
importing the other's id.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>