Non-Sunday Dec 24 previously just inherited Advent 4's ferial collect and
antiphons with nothing of its own. Import the Vigil's real proper content
from the reference engine (Duplex I classis): its own collect, all 5 Lauds
antiphons, the Benedictus antiphon, and Matins' Gospel (Matt 1:18-21) +
St. Jerome homily, wired via a new `vigil-of-christmas` temporal id scoped
to non-Sunday Dec 24 only. Advent IV landing on Dec 24 itself is untouched,
left as its own separate design question.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ME8QNPdEmHSbSx1r6VmDRG
Every temporal id had its Lauds (Benedictus) antiphon authored, but only
3 of 57 had the Vespers (Magnificat) counterpart -- a whole-calendar
gap exposed by 2026-08-29's Vespers rendering with no Magnificat
antiphon at all. Sourced from the reference engine's static Tempora/
Sancti files, same convention and per-id reference dates already
established for the Benedictus antiphons.
advent-4 and marian-saturday are the only two ids still missing one
(neither resolves from the static files alone) -- follow-up commit.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ME8QNPdEmHSbSx1r6VmDRG
She was rendering as a bare collect (propers: null had no
sanctoral-commemoration fallback), and even that collect used
collect-c6's Virgin-and-Martyr text -- she was a matron, not a virgin.
Live-verified against Divino Afflatu: added collect-c7 (the Common's
own non-Virgin-Martyr template) and a full antiphon/versicle/collect
commemoration bundle.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018sPkfGLiq58pmmDoBWH5UX
nativity-of-st-john-the-baptist.yml's `common` field (common-of-an-apostle)
was the same mistaken placeholder as the Beheading's, but this feast
needed a different fix: the reference engine assigns it no Commune at
all -- every [Rule] line in Sancti/06-24.txt and SanctiM/06-24.txt points
to proper text, never a Commune category -- so there's no better-fitting
id to swap in either.
Authored the real proper content that was still falling through to the
apostle Common, live-verified against the local Divinum Officium CGI
instance (Monastic Tridentinum 1617):
- Matins invitatory antiphon ("Regem Præcursóris Dóminum")
- Matins hymn ("Antra desérti téneris," with the Monastic doxology
substitution already used by this feast's own Lauds/Vespers hymns)
- Full Matins Nocturn 1-3 psalmody + nocturn versicles (Nocturn 1/2 reuse
St. Lawrence's own shared psalm-number pool per "Psalmi Dominica";
Nocturn 3 reuses St. Lawrence's own canticle scripture files verbatim,
since the citations are identical)
- Vespers psalmody (only 4 psalm slots at this Monastic rank, not 5 as a
naive reading of the raw Ant Vespera list would suggest)
- Nocturn 2/3 responsories on the existing nocturn-readings file
`common: common-of-an-apostle` is left in place as a fully inert
placeholder (a non-optional field with no better id available) with an
updated comment explaining why.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WvnBMq7HGfXRyMsVLu2v4D
decollation-of-st-john-baptist.yml's `common` field was set to
common-of-an-apostle -- a mistaken placeholder (he isn't an apostle) that
leaked into the Aug 29 Matins invitatory and the Lauds/Vespers office
bundle. Corrected to common-of-a-martyr, matching the file's own already-
correct `minorHoursCommon` field.
Also corrected a stale comment in the feast's own nocturn-readings file
claiming neither Nocturn 2 nor 3 has a proper responsory: Nocturn 2's own
closing responsory is genuine proper text (not a Commune reference like
Nocturn 3's), and is now authored.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WvnBMq7HGfXRyMsVLu2v4D
This Duplex I classis feast (instituted by Pius IX, 1847) didn't exist
anywhere in vu's calendar. Dated per the older, pre-1955 reckoning --
Wednesday after the 2nd Sunday after Easter (Easter+17) -- rather than the
1913 Pius X reform's later placement on the 3rd Sunday after Easter
itself, per direct instruction. Mechanism: one new temporal-feast record
plus a new EASTER_OFFSET_STARTS table entry (the only code change --
everything else is the existing generic anchor-driven resolution).
Authored the feast day's own Matins reading and its full 7-day octave
(days 2/3/4/6/7/8; day 5, the Sunday, has no override in the source at
all, correctly left unauthored).
Fixed one real collateral effect: an existing fixed-year calendar test
(St. Pudentiana vs. St. Peter Celestine, 2038-05-19) broke because that
date now falls on this octave's own closing day, tying Celestine's rank
against the octave's threshold -- the app's own documented tie-break
correctly favors the octave that year. Moved the proof date to 2033.
Also bumped the PWA precache file-size cap (6 MiB -> 8 MiB) since this
content pull pushed the main bundle past the previous limit.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhysogLP9eCeKS7JEwRi6y
St. Stephen, St. John the Apostle, and Holy Innocents each have an 8-day
octave overlapping Christmas week, but their intervening days (2-7) carry
no distinct Lectio content in the source -- every suffix file checked at
Dec 27-31 is a bare @Sancti/MM-DD alias, correctly left unauthored, same
pattern as the fixed-date octaves. Only each octave's own closing "In
Octava" day (Jan 2/3/4 respectively) carries real content: St. Augustine's
sermon on Stephen + St. Jerome on Matt 23:34-35; St. Augustine's Tractate
36 on John + St. John Chrysostom on John 21:20-24; St. Augustine's first
sermon for Childermas + St. John Chrysostom on Matt 2:13-18.
This closes the octave-readings backlog entirely -- every fixed-date,
movable-feast, and Christmas-week saint octave has now been audited by
calendar date against the source.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhysogLP9eCeKS7JEwRi6y
Ascension, Corpus Christi, and Sacred Heart octave content lives in the
reference engine's Tempora/ directory, keyed by liturgical offset from
Easter rather than calendar date. All three octaves' 7 non-feast days
(day 2 through the closing day) turned out to have genuine, distinct
patristic content -- unlike the fixed-date octaves, none were bare
vide-only days. 21 files authored across the three octaves.
Found and fixed one duplication along the way: each octave's own Sunday
day turned out to duplicate content already authored under a different id
in the earlier post-Pentecost temporal-cycle sweep, since a numbered
post-Pentecost Sunday and the Sunday within Corpus Christi's or Sacred
Heart's octave are structurally the same calendar day every year. Both
duplicate files (corpus-christi-octave-day-4, sacred-heart-octave-day-3)
were dropped after confirming the reading still surfaces via the existing
temporal id.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhysogLP9eCeKS7JEwRi6y
Re-auditing the two prior sanctoral bulk passes (pre-1955 Tridentine track
and SanctiM Monastic-1617 track) turned up one saint missed by both:
St. Felix I (May 30), authored the same single-lesson shape as
st-pontian.yml. This closes the saint-level side of the Matins
patristic/hagiographic reading backlog.
Separately, auditing octave-day content by calendar date (the reference
engine keys it that way, not by octave-day-number) found two real gaps in
already-partially-authored fixed-date octaves: Immaculate Conception's own
closing day (Dec 15, Pius IX bull + St. Epiphanius homily) and Nativity of
the BVM's day 3 (Sep 10, St. Jerome on Matthew's genealogy -- no usable
reference English, own translation used, draft). Every other apparent gap
in these octaves was confirmed a correctly-empty vide-only day, not a
further gap.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhysogLP9eCeKS7JEwRi6y
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
Commune/C7's own invitatory antiphon ("Laudémus Deum nostrum * In
confessióne beátæ N..") needs a per-saint genitive-singular name, unlike
every other Common invitatory antiphon currently authored. Exports
resolve-common.ts's existing substituteName helper (previously only used
by getDayCollect for collectCommon/collectName) and wires it into
resolveMatinsInvitatoryText via a new SaintRecord.invitatoryName field
-- kept separate from collectName since the two templates' {N}
placeholders don't always need the same grammatical case. Fills in real
declined names for the 3 saints using common-of-a-holy-woman (Anne,
Martha, Mary Magdalene).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012AVXS5iTrk3c2anSYVGwxS
resolveMatinsInvitatoryText's Common-category tier existed but only had
Common-of-an-Apostle authored, so every other Common category fell all
the way through to the plain ferial invitatory antiphon regardless of
rank (e.g. St. Joseph Calasanctius, 2026-08-27, Confessor). Adds the
Confessor family (5 duplicated ids, matching the hymn's own precedent),
Martyr family (2 ids + Several Martyrs), Virgin family (2 ids), and
Dedication — all read directly from the reference engine's own
Commune/C-number [Invit] lines. Holy Women (C7) needs a name-template
mechanism this project doesn't have yet for invitatory antiphons, and
General/All Saints (C9) turned out to be a mislabeled backlog item (C9 is
actually the Office of the Dead) — both logged in TODO.md instead.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012AVXS5iTrk3c2anSYVGwxS
common-of-an-abbot's own P/T/S/N antiphon files already claimed to cover
common-of-a-confessor and common-of-a-confessor-not-bishop too ("an Abbot
is himself a Confessor"), but the matching duplicate files were never
authored — so the ~36 saints using either of those two ids (bare
common-of-a-confessor is the more common of the two) got no minor-hour
antiphon at all. Adds the 8 missing files, copying the abbot file's
already-verified text, matching this category's existing duplicate-not-
alias convention (see matins-hymn-common-of-a-confessor.yml vs.
matins-hymn-common-of-a-confessor-not-bishop.yml).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012AVXS5iTrk3c2anSYVGwxS
Closes the last content gap flagged when Circumcision was added: its
rubric borrows Christmas Day's propers wholesale, but Christmas Day
itself has no hymn authored anywhere in vu yet. Lauds reuses the
already-verified Christmas Octave Sunday text (byte-identical in the
source); Vespers/Matins use the Monastic "Christe Redemptor omnium",
a genuinely separate hymn from the secular "Jesu, Redemptor omnium",
with a fresh draft English translation since none exists in the
reference engine for that variant.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
Historically a floating Sunday (Jan 2-5, fixed to Jan 2 when no Sunday
falls there); per direct instruction this is instead fixed to Jan 2
every year for simplicity. Adds the feast's collect, Magnificat/
Benedictus antiphons, full Lauds psalmody, capitulum, the three-part
"Jesu dulcis memoria" hymn cycle (Vespers/Matins/Lauds), the Invitatory
antiphon, versicles, and two Matins nocturn readings (both St. Bernard
of Clairvaux), sourced from Tempora/Nat2-0.txt. Reuses the `fixed-date`
anchor kind added in the prior commit.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
Jan 1 previously fell through to generic Christmastide-feria content with
no identity of its own, despite being Christmas's own Octave Day. Adds a
`fixed-date` anchor kind to calendar/movable-feasts.ts's MovableAnchor
(the existing easter/nth-sunday kinds can't express "always Jan 1"),
plus the feast's collect, Magnificat/Benedictus antiphons, full Lauds
psalmody, capitulum, versicle, and two Matins nocturn readings (Leo the
Great, Ambrose), sourced from Sancti/01-01.txt.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
resolveMatinsHymn (hours/matins.ts) is a separate mechanism from
resolveOfficeBundle, with its own fallback chain (proper -> active
octave -> Common via SaintRecord.common -> season -> ferial). Only the
Confessor family and Apostle had a matins-hymn-<id>.yml before this
pass; everything else fell through to season/ferial at Matins
specifically, even after the Lauds/Vespers fixes.
Live-verified and authored: common-of-several-martyrs ("Ætérna Christi
múnera, Et Mártyrum victórias"), common-of-an-abbot and
common-of-several-confessors (= Confessor-Not-Bishop's hymn, same label
finding as Lauds/Vespers), common-of-a-virgin-martyr/-virgin ("Vírginis
Proles"), common-of-a-holy-woman/-widow (a genuinely shorter closing-two-
stanzas form, "Hujus obténtu, Deus alme"), Guardian Angels/St.
Michael/St. Gabriel/St. Raphael (reused from St. Michael's Apparition,
confirmed via SanctiM/05-08.txt's own cross-reference), common-of-the-
bvm ("Quem terra, pontus, ǽthera"), Finding/Exaltation of the Holy Cross
("Pange, lingua, gloriósi," the Nativity-themed other half of the same
poem as Lauds' own hymn), and the Transfiguration (byte-identical to its
own Vespers hymn).
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
Next-largest remaining Common category (22 real users) with no Lauds/
Vespers bundle authored, same fix pattern as Confessor-Not-Bishop and
Martyr(-Bishop). Live-verified against Divinum Officium (Monastic
Tridentinum 1617) votive=C3: chapter Sap 3:1-3, Lauds hymn "Rex glorióse
Mártyrum," Vespers hymn "Sanctórum méritis ínclyta gáudia," shared
versicle "Exsultábunt Sancti in glória." Cross-checked votive=C3/C3a/C3b
byte-identical, confirming the Missal-collect split (plain-martyrs vs.
Pope-martyrs) doesn't carry through to this Office bundle. Proof tested
on Ss. Placid and Companions (Duplex II. classis, real un-outranked
Second Vespers).
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
hasFirstVespers() required Semiduplex-or-higher, so a bare Simplex
feast could never anticipate the evening before it. Live-verified
this was too strict: St. Zephyrinus (Aug 26, plain Simplex) claims
First Vespers over St. Louis (Aug 25, also Simplex) in the reference
engine -- "Vespera de sequenti; nihil de præcedenti." A Simplex feast
has no Second Vespers of its own, but it does still get First Vespers;
there's no rank floor at all, only keepsOwnSecondVespers' separate
question of whether the preceding day outranks the claim.
This also surfaces St. Zephyrinus's Magnificat antiphon, which now
actually gets used (St. Louis, previously shown by the old bug, is
permanently boxed out of ever governing real Vespers in this merged
calendar -- Bartholomew outranks him the evening before, Zephyrinus
the evening after, every year -- so his own Magnificat antiphon was
never authored). Added st-zephyrinus-magnificat-antiphon.yml, live-
verified bilingual text ("Iste Sanctus...").
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
Real Monastic 1617 has no Preces at the Little Hours, and that was
previously documented as intentional. Per this project's "not a
reconstruction" design, Prime was recently given Preces in the secular
Tridentine form as a deliberate deviation from Monastic — do the same
here: the reference engine's ferial minor-hour Preces (Kyrie, Pater
Noster, then "Domine Deus virtutum, converte nos..." V/R pairs) is
authored as a single shared common id and wired into all three hours
after the chapter. By explicit choice this is said every day regardless
of rank, mirroring Prime's own "every ferial day" simplification, rather
than importing the reference engine's Sunday/feast form, whose sourcing
(a V/R block reused from Compline) looks like a data quirk rather than
genuine minor-hour content.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PXySSbbUh1EhdN1RnAoCaP
Every capitulum-*.yml under the three Little Hours combined the chapter,
"R. Deo grátias"/"Thanks be to God", and the trailing V./R. pair into one
flat single-line string. The .lang-column CSS already renders on
white-space: pre-line (as little-hour-conclusio.yml's block-scalar text
already demonstrated), so the run-together rendering was purely a missing
line-break bug in the source YAML, not a CSS or resolver issue.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PXySSbbUh1EhdN1RnAoCaP
Monastic Prime's own Dominicales Preces drop the "Et ego ad te, Domine,
clamavi..." versicle block and shorten the closing "Miserere nostri,
Domine... Fiat misericordia tua..." set. Prefer the secular Tridentine
form instead (live-verified against Divinum Officium's "Tridentine -
1906" version), keeping "beato Patri nostro Benedicto" in the Confiteor
by explicit choice even though the real secular Confiteor omits it.
The Sunday/ferial by-day-kind split stays as-is; the ferial form
(prime-preces-feriales.yml) is unchanged and continues to show on every
ferial day by deliberate choice, more generously than the historical
rubric.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HWN869GrMFHqrer9fdCBbF
Proof content for the new Common-fallback mechanism, live-verified
against Divinum Officium (Monastic Tridentinum 1617): Lauds chapter/
responsory/hymn/versicle ("Jesu coróna célsior"), cross-checked
byte-identical between St. Louis's and St. Nicholas of Tolentino's own
days. Vespers bundle (hymn "Iste Conféssor Dómini sacrátus", reusing
the already-authored Matins hymn translation) sourced via the
reference engine's votive=C5 view instead of a real saint's own Second
Vespers, since every saint in this Common category has their own
Second Vespers permanently outranked by an adjacent fixed feast.
TODO.md records the fuller sourcing detail and the remaining open
Common categories.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HWN869GrMFHqrer9fdCBbF
Fixes the ferial-hymn fallback for St. Louis and 82 other confessor
saints across all 5 confessor common ids, using the pre-Urban VIII
(Monastic-track "sacrátus") textual variant with a fresh English
translation rather than the reference engine's mismatched reused one.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019jHSimu99UDKh1pRRd11uV
resolveMatinsHymn gained a Common-category tier (override -> octave ->
Common category -> season -> ferial), reusing matins-psalmody-
overrides.ts's own getSaintRecord(id)?.common lookup pattern. The
invitatory antiphon (invitatoryParts), previously one hardcoded fixed
text for every day of the year with only full-vs-incipit doubling
varying by rank, now goes through a real resolveMatinsInvitatoryText
(override -> Common category -> season -> ferial, no octave tier) before
the doubling step.
Content authored this pass: Common-of-an-Apostle only, both hymn
(matins-hymn-common-of-an-apostle.yml, "Aeterna Christi munera") and
invitatory antiphon (matins-invitatory-common-of-an-apostle.yml, "Regem
Apostolorum Dominum"), both read directly from the reference engine's
Commune/C1.txt. Live-verified: St. Bartholomew (2026-08-24) and St.
Andrew (2026-11-30) both now resolve to this Common's text.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F25189JqjXddUhU9hM9nUS
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
All 53 nocturn-readings files with a responsory field started straight
into the text with no leading R., unlike octave-readings' own R./V.
convention. Fixed in content per direct instruction (not injected at
render time), matching each file's own existing plain V./R. style rather
than switching to octave-readings' R./V. glyphs.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EWzE3kaSZCs79fPBrrE1aF
The later post-Pentecost Sundays' real Nocturn 2 patristic content isn't
keyed by Pentecost offset in the reference engine — it's keyed by civil
calendar month/week (the old "Scriptura occurrens" cycle), which shifts
relative to post-pentecost-NN every year depending on Easter's date. Port
Date.pm's monthday() algorithm (pre-1955/Tridentine rubrics) as a new,
date-driven id, author all 20 August-November month-week files from the
reference engine's Tempora/0MN-0.txt sources, and pool them in
hours/matins.ts as a third, independent reading source alongside the
existing temporalId lookup.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EWzE3kaSZCs79fPBrrE1aF
Closes the gap the user found on 2026-08-23 (post-pentecost-13's Matins had
no patristic reading): nocturn-readings/ had content for only one temporal
id (post-pentecost-15, the original mechanism proof date). Since
resolveTemporalId maps every day in a liturgical week to the same id, one
file per id covers the whole week — authored all 23 remaining
post-pentecost-NN ids (01-14, 16-24) from the reference engine's own
Tempora/PentNN-0.txt files. Trinity Sunday (01) keeps its own full proper
office including a displaced-Sunday commemoration; 02-11 have real Nocturn
2+3 content; 12 onward are Nocturn-3-only (homily, Gospel incipit skipped
per convention), reusing the same two responsories the source itself
cross-references week to week.
Rest of the temporal cycle (Advent/Christmas/Epiphany/Septuagesima/Lent/
Easter) is a separate follow-up pass, tracked in TODO.md.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EWzE3kaSZCs79fPBrrE1aF
Researched whether September/Advent Ember days belong in the
movable-feasts.ts table alongside Christ the King/Immaculate Heart of
Mary. Live-verified against the reference engine they don't: Ember days
are privileged ferias (a saint can still win outright against them), not
named feasts contesting the day by rank.
Two smaller pieces instead: calendar/temporal.ts's septemberEmberDayOffset
(Sunday nearest Sept 14, same "nearest" arithmetic adventStart already
used, factored into a shared nearestSunday helper) feeds a new
resolveTemporalCategory check giving those 3 dates privileged-feria-minor
(live-verified correct); calendar/ember-days.ts's applyEmberDay relabels
the day's own temporal id to the Ember day's own (so its real content is
found) when the feria itself wins, or adds a commemoration when a saint
does. Advent Ember days needed no precedence change -- Advent's own
season default already covers them.
Found and fixed a real bug along the way: matins.ts's nocturnReadingIds
only ever pulled a commemorated *sanctoral* id's own readings, never a
commemorated *temporal* one's -- so a commemorated Ember day (the common
case) would never have surfaced its own content. Same root cause as the
day.winner.id gap the IHM relocation fixed earlier, just hiding in the
commemorations loop instead.
Authored all 6 days' real collect + 3 Matins readings each, transcribed
directly from the reference engine (September: Tempora/093-{3,5,6}.txt;
Advent: Tempora/Adv3-{3,5,6}.txt, whose lessons are themselves a
cross-reference to the Annunciation's own Common, followed and
transcribed from there). Kept as 3 separate readings per day rather than
the usual combine-into-one default, since each carries its own
genuinely distinct proper responsory.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VZSAgRi4QE4XRTqVto93zA