Commit Graph

86 Commits

Author SHA1 Message Date
will 6ecd1485c4 Add jdc (Judges) responsory, composed from Gideon's cry at Jdc 7:17-20
Deploy / deploy (push) Successful in 1m52s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MKC2QQGLYo2UTiDjDyWEkW
2026-09-05 07:14:07 -04:00
will 9e66ad10e4 Add josue (Joshua) responsory, composed from Josue 24:15-16
Deploy / deploy (push) Successful in 1m56s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MKC2QQGLYo2UTiDjDyWEkW
2026-09-05 07:04:25 -04:00
will dcea19015f Add 1esdr (Ezra) responsory, composed from 1 Esdr 8:21-23
Deploy / deploy (push) Successful in 1m56s
No liturgical precedent exists for this book; the verse's antithesis
("the hand of our God is upon all them that seek him in goodness: and
his power and strength, and wrath upon all them that forsake him") is
reordered so the hopeful clause repeats after the V., not the wrath
clause. Closes the per-book pool at 68/72 -- the last 4 have no
sourceable material at all.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ALE7phKTAnmRWvWMU9dZa7
2026-09-05 06:39:18 -04:00
will c98abaebb9 Drop parenthetical gloss from Nehemiah responsory V.
Deploy / deploy (push) Successful in 2m12s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ALE7phKTAnmRWvWMU9dZa7
2026-09-05 06:24:21 -04:00
will 1d566ec6e0 Add 2esdr (Nehemiah), correcting a prior mis-diagnosis
Deploy / deploy (push) Successful in 2m2s
Nehemiah was wrongly bundled in with ezra's "ambiguous, not acted on"
reasoning and left unseeded. It actually has a real, unambiguous
citation in the Missa (Ember Wednesday of September's Lectio/Communio,
Neh 8:1-10) that a prior pass never checked. R. from v.3, V. from v.9,
both from that accented Missa Lectio.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ALE7phKTAnmRWvWMU9dZa7
2026-09-05 06:14:20 -04:00
will c2a15d94dd Add ruth -- composed with no liturgical precedent at all
Deploy / deploy (push) Successful in 1m51s
User-directed: compose Ruth's own responsory from Ruth 1:16-17 ("thy
people shall be my people, and thy God my God") on the verse's own
merit. Unlike deut/rom/bar, this text has no liturgical precedent
anywhere in the reference source (no Nuptial Mass file even exists
there) -- flagged that distinction before proceeding; user confirmed
explicitly.

Since data/scripture/ruth-1.yml (the usual bulk import) carries no
accents, the Latin was hand-accented rather than transcribed, but
cross-checked word-by-word against already-accented occurrences of
the same words elsewhere in the corpus rather than guessed freehand.

66 of 72 bible-plan books now seeded. npm test (2029 passed) and
tsc --noEmit pass; live-verified through getBiblePlanReadings.
Canonical-key audit re-run, clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGjUyhUZJaSjiniEmnLdak
2026-09-04 22:01:15 -04:00
will e52c285f99 Add bar (Baruch), found in the Missa propers, not the Horas
Deploy / deploy (push) Successful in 1m54s
User pointed to missa/Latin/Tempora/Quad6-6.txt -- the Mass propers, a
directory tree this whole responsory search had never once checked
(everything so far searched horas/, the Divine Office proper). The
Easter Vigil Mass's own fourth prophecy ([Proph_Baruch3], Bar 3:9-38,
"Audi, Israel, mandata vitae") is genuine, real, accented liturgical
Latin -- just never part of Matins at all.

Composed bar the same way as deut/rom: built from that prophecy's own
climactic close ("Hic est Deus noster... Post haec in terris visus
est, et cum hominibus conversatus est" -- read at the Vigil because
early exegetes saw "seen upon earth, and conversed with men" as a
prophecy of the Incarnation).

Extended the Missa check to the other 6 already-absent books too --
genuinely zero citations anywhere. Ezra turned up one thin, ambiguous
Missa Introit citation that doesn't match its own cited verse; left
unseeded rather than force it.

65 of 72 bible-plan books now seeded -- this closes the per-book
responsory pool. npm test (2029 passed) and tsc --noEmit pass;
live-verified through getBiblePlanReadings. Canonical-key audit
re-run, clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGjUyhUZJaSjiniEmnLdak
2026-09-04 21:36:48 -04:00
will 2b7495fc91 Close the Matins per-book responsory pool: rom is the last book
Deploy / deploy (push) Successful in 1m53s
Composed rom from Rom 13:11-12 ("the night is past, the day is at
hand... let us cast off the works of darkness, and put on the armour
of light") -- the standing year-round ferial Lauds Capitulum, also
used at Advent I's own Capitulum. Genuine accented Vulgate/
Douay-Rheims text, never historically assembled into its own Matins
responsory, same approach as deut. User-confirmed before adding.

64 of 72 bible-plan books now seeded -- every book actually used in
the bible-plan has a real responsory, whether transcribed (62) or
composed from genuine already-liturgical text (deut, rom). The
remaining 8 have no citation anywhere in the source at all; there's
nothing further to check.

npm test (2029 passed) and tsc --noEmit pass; live-verified through
getBiblePlanReadings. Canonical-key audit re-run, clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGjUyhUZJaSjiniEmnLdak
2026-09-04 21:14:03 -04:00
will afa187032b Add deut, this pool's first genuine original composition
Deploy / deploy (push) Successful in 1m55s
User found a lead reading a patristic homily (English/Sancti/01-02.txt)
that quotes Deut 32:11's eagle image. Deuteronomy has no historical
Matins responsory anywhere in the reference source, so unlike every
other entry in this pool, this one is composed rather than
transcribed: a real R./V. pairing built from the Canticle of Moses'
own genuine verses (Latin/Psalterium/Psalmorum/Psalm226.txt, sung at
Lauds), verified against data/scripture/deut-32.yml to confirm the
citation is standard verse 11 and not the breviary's own internal
chant-verse-numbering (32:15-16) for the same text. Documented plainly
in the data file's own header as vu's composition, not presented as
historically attested.

63 of 72 bible-plan books now seeded. npm test (2029 passed) and
tsc --noEmit pass; live-verified through getBiblePlanReadings.
Canonical-key audit re-run, clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGjUyhUZJaSjiniEmnLdak
2026-09-04 20:06:48 -04:00
will 52052d737e Find Canticles, Leviticus, and Numbers in Sancti, not Tempora
Deploy / deploy (push) Successful in 1m51s
User pushback on Canticles being "confirmed absent" -- right instinct
to check the Commune files, which redirected productively: the same
Lectio-citation survey run against Sancti (individual saint/feast
files) rather than just Tempora found real, genuine content:

- cant: the Visitation (July 2) reads straight through the Song of
  Songs, blending it with the Visitation narrative itself.
- lev: the Purification of the BVM's own Leviticus purification-law
  reading is the feast's actual reason for being.
- num: the Exaltation of the Holy Cross's bronze-serpent/Cross
  typology (Num 21:6-9).

Re-checked the other 9 already-"confirmed absent" books against
Sancti too -- still genuinely absent, no alternate abbreviation
missed.

62 of 72 bible-plan books now seeded -- the real final count. Only
Romans and 9 books with no citation anywhere (Tempora or Sancti)
remain. npm test (2025 passed) and tsc --noEmit pass; live-verified
through getBiblePlanReadings. Canonical-key audit re-run, clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGjUyhUZJaSjiniEmnLdak
2026-09-04 19:03:01 -04:00
will e96d201346 Close out the Matins per-book responsory pool: 59 of 72 books
Deploy / deploy (push) Successful in 1m49s
Asked to translate the 15 remaining "real Latin, no English" books.
None needed translation: the whole post-Epiphany reading season
(Galatians/Ephesians/Philippians/Colossians/1-2 Timothy/Titus/
Philemon/2 Thessalonians) turns out to have no distinct responsory
content of its own -- every feria file references 2 Corinthians' own
week (already bilingual) by weekday position. Same for 2 Peter/2-3
John/Jude, which reference Ascension Day's own responsories (act).

Only Romans genuinely has nothing: every citing file borrows an
unrelated feast's own proper responsory (Circumcision, Christmas Day,
a January saint), never anything Romans-specific. Left unseeded --
using one would repeat the Sacred Heart/Jeremiah mismatch this pool
already avoids elsewhere.

59 of 72 books now seeded -- every book with any usable Latin content
in the source at all. The remaining 13 (Romans plus 12 books with no
citation anywhere) are the real, final gap.

Ran the full canonical-key audit again; confirmed clean. npm test
(2025 passed) and tsc --noEmit pass; live-verified through
getBiblePlanReadings.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGjUyhUZJaSjiniEmnLdak
2026-09-04 18:50:56 -04:00
will ff87aff240 Add 1 Cor, 2 Cor, 1 Peter, 1 John; fix a repeated canonical-key bug
Deploy / deploy (push) Successful in 1m52s
Confirmed Leviticus/Numbers/Deuteronomy genuinely absent from Tempora
(precise awk-based survey, not a loose grep). Added 1cor (Maundy
Thursday's own Institution-narrative Nocturn 3), 2cor (Epiphany II
Sunday), 1pet and 1joan (Paschaltide Sunday sets already partly used
for jac/jas).

Caught a repeat of the same canonical-key mistake from the previous
commit: the jas entry should have been keyed jac (BOOK_ALIASES maps
jas->jac). Fixed, and this time audited every single key in the file
programmatically against BOOK_ALIASES rather than just the keys
touched this pass -- confirmed clean.

45 of 72 books now seeded. npm test (2025 passed) and tsc --noEmit
pass; live-verified through getBiblePlanReadings.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGjUyhUZJaSjiniEmnLdak
2026-09-04 18:31:13 -04:00
will c32fabb54d Add Acts, Apocalypse, James, Hebrews, and the 4 Gospels to responsory pool
Deploy / deploy (push) Successful in 1m48s
Surveyed Tempora precisely with an awk one-liner reading the line after
every [LectioN] tag (two lines deep for Gospel citations) rather than a
loose grep-for-book-prefix, which had already produced one false
positive this session.

Added act (Ascension Day's own Matins), marc (Easter Sunday's own),
heb (Good Friday's own Tenebrae), apoc (Easter III Sunday), jas
(Easter IV Sunday), and luc/matt/joan (Advent I/II/III Sundays, one
entry each). 41 of 72 bible-plan books now seeded.

Confirmed no English exists anywhere in the reference engine for
Galatians/Ephesians/Philippians/Colossians/Titus/Philemon or Romans --
real Latin exists, no bilingual source; left unseeded.

npm test (2025 passed) and tsc --noEmit pass; live-verified through
the real getBiblePlanReadings call chain (not a direct
getResponsoryForBook call, per the previous commit's lesson).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGjUyhUZJaSjiniEmnLdak
2026-09-04 18:20:44 -04:00
will f0b771a02a Fix real correctness bug: pool keys must match canonical book form
Deploy / deploy (push) Successful in 1m50s
bible-plan.ts normalizes a reading's book through canonicalBook()
(scripture/index.ts's BOOK_ALIASES map) before calling
getResponsoryForBook -- so the pool must be keyed by the canonical
form, not the bible-plan YAML's own raw book code. 12 of the 33 keys
seeded earlier today used the raw form and would have silently
resolved to undefined in the real app despite passing an initial
"live verification" that called getResponsoryForBook directly
(bypassing the normalization the real call site always applies).

Renamed: 1macc->1mach, 2macc->2mach, 1sam->1reg, 2sam->2reg,
1kgs->3reg, 2kgs->4reg, jdt->jdth, zeph->soph, obad->abd, jonah->jon,
hos->osee, mic->mich.

Re-verified through the actual getBiblePlanReadings call chain this
time (2026-06-04, post-pentecost-01/Thursday, "1sam 9-10" now
resolves a real responsory). npm test (2025 passed) and
tsc --noEmit pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGjUyhUZJaSjiniEmnLdak
2026-09-04 18:11:36 -04:00
will 3b46a18d63 Add 14 more books to Matins responsory pool, fix 2 dropped entries
Deploy / deploy (push) Successful in 1m52s
User caught jdt (Judith) listed as unseeded despite having real
responsory content directly visible in the reference source -- and
already flagged present in this same session's own citation dump,
never followed up on. Self-audit after that catch found job had also
been extracted earlier this session but never committed to the file.

Added jdt, esth, job, eccl, hab, joel, zeph, obad, jonah, mal, hos, mic,
nah, and lam (Maundy Thursday's own Tenebrae responsories). 33 of 72
bible-plan books now seeded, up from 19.

npm test (2025 passed) and tsc --noEmit pass; live-verified via
getResponsoryForBook resolving real text for every new key.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGjUyhUZJaSjiniEmnLdak
2026-09-04 17:43:43 -04:00
will 816dcadf0d Fix wrong book-count estimate in Matins responsory pool notes (66 -> 72)
Deploy / deploy (push) Successful in 1m52s
"~66" was an eyeballed guess from a sort|uniq -c list, never actually
counted -- and coincidentally echoes the 66-book Protestant canon count,
a bad number to leave uncorrected in a Catholic office project's own
docs. The real count (grep -c distinct `book:` values across
data/hours/bible-plan/*.yml) is 72.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGjUyhUZJaSjiniEmnLdak
2026-09-04 17:28:22 -04:00
will 7cee7a1e8a Fix Matins responsory extraction bug, unblock 8 more books
Deploy / deploy (push) Successful in 1m50s
The per-book pool extraction script only matched a bare [ResponsoryN]
tag, missing the reference engine's underscore-suffixed [ResponsoryN_]
template convention that holds the real text (a bare tag often just
@:-references it, alongside a Cistercian-rubric variant). This wrongly
made 1sam/2sam/1kgs/2kgs/2macc look untranslated in English.

Fixed the script and hand-followed @Tempora/X:ResponsoryN cross-file
references to add 1sam, 2sam, 1kgs, 2kgs, 2macc, zach, amos, and agg --
19 of ~66 bible-plan books now seeded (up from 11).

npm test (2025 passed) and tsc --noEmit pass; live-verified via
getResponsoryForBook resolving real text for every new key at every
pool index.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGjUyhUZJaSjiniEmnLdak
2026-09-04 17:13:13 -04:00
will 91dcc2c972 Seed 8 more books in the Matins per-book responsory pool
Deploy / deploy (push) Successful in 1m59s
Added exod, prov, sir, sap, tob, ezek, dan, 1macc (11 of ~66 total now
seeded), each sourced from a genuine, non-overridden reference-engine
Tempora file with real bilingual Responsory text. sir/sap and dan reuse
prov's/ezek's own entries respectively, confirmed by the reference
engine's own week files @-referencing that same pool -- real evidence
this app's loose book-level responsory match is historically authentic,
not invented.

Skipped 1sam (macro-only responsory text, not worth resolving for one
book) and 2sam/1kgs/2kgs/2macc/zach/amos/agg (real Latin but no
reference-engine English translation at all).

npm test (2025 passed) and tsc --noEmit pass; live-verified via
getResponsoryForBook resolving real text for every new key.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGjUyhUZJaSjiniEmnLdak
2026-09-04 16:59:50 -04:00
will a570266028 Add per-Common-category Matins responsory pool, expand per-book pool
Deploy / deploy (push) Successful in 1m52s
The per-book responsory pool (Nocturn 1 scripture readings) only had `isa`
seeded; the much bigger, previously untracked gap was that 272 of 355
nocturn-readings/*.yml files (Nocturn 2/3 patristic readings) had no
responsory at all. Added a sibling per-Common-category pool, sourced from
the reference engine's static Commune text files, covering all 19 of vu's
real `common:` category ids (several confirmed aliases of the same
underlying file). Wired into matins.ts's reading assembly as a fallback
when a reading has no proper responsory of its own. Also expanded the
per-book pool with `gen` and `jer`.

Live-verified end-to-end (St. Francis de Sales, Ss. Cornelius/Cyprian, Ss.
Euphemia/Lucy/Geminianus). npm test (2025 passed) and tsc --noEmit pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGjUyhUZJaSjiniEmnLdak
2026-09-04 16:47:17 -04:00
will 0b6a0ad1cc Complete Marian Saturday: proper Matins/Lauds hymns, ferial antiphons
Design (direct instruction): Marian Saturday is its own rank tier,
between simplex and vigil in vu's FeastClass scale -- beats a plain
Simplex saint (commemorated in return), loses cleanly with zero trace
to anything Vigil-or-higher. Deliberately not the full historical
Officium Sabbatorum B.M.V. ("no little office"): ferial psalmody is
kept everywhere, only the antiphons swap to Marian text; Matins and
Lauds each get a real proper Marian hymn; the Marian collect applies
whenever the day wins.

The calendar-side mechanism (calendar/index.ts's applyMarianSaturday)
and a collect/Benedictus antiphon already existed from an earlier
session -- authored what was still missing: matins-hymn-marian-
saturday.yml (Matins had nothing at all) and lauds-{capitulum,
responsory,hymn,versicle}-marian-saturday.yml.

Also found and fixed 3 real bugs from that earlier, unverified pass:
Lauds' own hymn ("O gloriósa Dómina") was sitting under the plain
ferial lauds-hymn-saturday id instead of its own marian-saturday id;
that id's capitulum/responsory/versicle siblings were live-verified
from a different, privileged Lenten Ember Saturday, not a genuine
per-annum ferial Saturday -- corrected to the real content ("Auróra
jam spargit polum" / Rom 13:12-13 / "Sana ánimam meam" / "Repléti
sumus mane misericórdia tua", live-verified against a clean September
Ember Saturday); and the Lauds psalmody override used the real
historical proper psalm set (92/99/62) instead of the ferial one,
rolled back per direct instruction to plain ferial psalms (50, 142,
the split Canticle of Moses) with only the antiphons swapped.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGjUyhUZJaSjiniEmnLdak
2026-09-04 09:32:25 -04:00
will 44feb8c6b1 Widen seasonal hymn-doxology to cover Marian Saturday and the Assumption octave
getHymnDoxologyId now takes the whole LiturgicalDay (needed for a date-window
check) and checks a feast override for a temporal winner's id too, not just
sanctoral — matching Divinum Officium's own Common-of-the-BVM `Doxology=Nat`
rule, which is why Marian Saturdays get the Nativity doxology regardless of
season. Also ports the source's Aug 16-22 (Assumption octave) hardcoded
Nativity-doxology window, confirmed live not excluded for the Monastic/
Tridentine 1617 track.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AGjUyhUZJaSjiniEmnLdak
2026-09-03 14:59:32 -04:00
will 3794903c68 Alias common-of-a-confessor-pope to common-of-a-confessor-bishop
Deploy / deploy (push) Successful in 1m51s
While auditing the Lauds/Vespers Common-category psalmody note for
staleness, found 3 saints (St. Pius X, St. Leo II, St. Pius V) use
common: common-of-a-confessor-pope, which had no alias in either
category file -- unlike common-of-a-confessor-doctor, which already
does. Live-verified (votive=C4 vs C4b, both Vespers and Lauds,
Monastic Tridentinum 1617): psalms/antiphons are byte-identical to
Confessor-Bishop's, only the Magnificat antiphon and collect differ
(both already handled per-saint, not through this table).

Note: this doesn't change any currently-visible content -- all 3
saints are ranked duplex/semiduplex, below the duplex-majus+ threshold
this psalmody-override tier is gated at, so they correctly fall to the
plain ferial default regardless. It closes a real data-completeness
gap for whenever a duplex-majus+ Confessor Pope is added.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Je2mXNHoXmi1DS3xEL67rH
2026-09-03 07:26:19 -04:00
will 63f48d26d2 Fix Matins bible-plan readings stuck on stale "translation pending"
resolveReading() in bible-plan.ts preferred each YAML row's hardcoded
status: { la: missing, en: missing } over computing status from the
actually-resolved text. That field was accurate before the Vulgate/
Douay-Rheims bulk import but was never cleared once real text landed,
so every Matins bible-plan reading kept showing as untranslated
regardless. Strip the stale field from all 368 files so status falls
through to the real compute-from-resolved-text path.

Also alias book abbreviations in scripture/index.ts's lookup: the
bulk-imported store uses Vulgate-numbering codes (sap, jac, joan,
1reg..4reg, 1par/2par, 1esdr/2esdr, ...) matching octave-readings.ts's
existing convention, while bible-plan.ts's TSV import used common
English abbreviations (kgs, sam, chr, john, jas, luke, mark, ...) for
the ~30 books where the two conventions diverge. Alias at the lookup
layer so citations keep their familiar English display form.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Je2mXNHoXmi1DS3xEL67rH
2026-09-03 05:43:07 -04:00
will 90665429ae Author Easter Octave Wednesday-Saturday's shared Matins antiphons
Deploy / deploy (push) Successful in 1m28s
All 4 weekdays share the exact same 2 antiphons verbatim ("Jesum qui
crucifíxus est quǽritis, allelúja..." / "Veníte et vidéte locum ubi
pósitus erat Dóminus, allelúja, allelúja."), live-verified against
Pofficium.pl (Monastic Tridentinum 1617, prayMatutinum) across
2026-04-08/09/10/11 — despite each day drawing on a different Gospel
reading in the nocturn-readings pool, the antiphon layer doesn't vary
by day.

Layered onto vu's own already-fixed per-weekday ferial psalm numbers
rather than the reference engine's own differently-sized (Rule of
Benedict summer-contracted) psalm set for these days, consistent with
this project's deliberate rejection of that contraction.

This closes "Easter's own octave" fully: calendar precedence
(2026-09-01), Sunday/Monday/Tuesday's shared proper psalmody, and now
Wednesday-Saturday's antiphons (both 2026-09-02).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X26BkFT3ARbtUGXuBmzUmD
2026-09-02 07:51:34 -04:00
will 57acbeefe9 Author Easter Sunday/Monday/Tuesday's shared proper Matins
Deploy / deploy (push) Successful in 1m29s
Easter Sunday, Monday, and Tuesday of the Octave share winner {kind:
temporal, id: easter-sunday}, and now share one live-verified proper
Matins psalmody: Nocturn 1 (Ps 1,2,8,15,23,27 under one antiphon),
Nocturn 2 (Ps 29,63,65,75,87,107 under one antiphon), Nocturn 3 (the
same 3 canticles already authored for the ordinary-Paschaltide
seasonal override, under its own antiphon) — sourced from
Pofficium.pl (Monastic Tridentinum 1617, prayMatutinum) against
2026-04-05/06/07. All 3 nocturn-closing versicles are byte-identical
to the ones already authored for the Paschaltide override, confirming
those are shared season-wide rather than coincidentally reused. The
12 patristic lessons were already authored in an earlier sweep
(nocturn-readings/easter-sunday.yml) and needed no new work.

Restricted to just these 3 days via the new weekdays field: the
Octave's other 4 weekdays (Wed-Sat) share the same winner id but have
their own different, not-yet-authored antiphons, tracked as a
separate open item in TODO.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X26BkFT3ARbtUGXuBmzUmD
2026-09-02 07:42:39 -04:00
will 9da5a74301 Remove spurious mid-nocturn versicle from ferial Matins
The 1-nocturn ferial branch was rendering a V./R. versicle stuck
mid-list, as if marking a nocturn boundary that doesn't exist in a
single continuous nocturn. Live-verified against the reference engine
(Pofficium.pl, Monastic Tridentinum 1617) for Wednesday and Thursday:
the real office runs straight from the last psalm to the Capitulum,
with no versicle anywhere in the psalmody. The embedded mid-list V./R.
line in the source Psalmi matutinum.txt is inert there and was never
actually emitted by the engine — matins-ferial-antiphons.yml's
versicle field was a documented-but-unverified assumption, not real
content.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X26BkFT3ARbtUGXuBmzUmD
2026-09-02 07:06:21 -04:00
will 6b66999908 Fix Ascensiontide Sunday precedence and give it its own Matins proper
Deploy / deploy (push) Successful in 1m27s
The Sunday within the Octave of Ascension was letting a Duplex saint win
outright (ascensiontide's Sunday was miscategorized ordinary-sunday
instead of privileged-sunday, the only "great octave" season not already
so classed). Live-verified the reference engine keeps the Sunday primary
and transfers the saint instead. Fixed the category, then authored the
Sunday's own wholly proper Matins (a different psalm scheme entirely, not
a seasonal overlay) via a new per-temporalId override layer.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017XMSokiTD2Qc5vPP2YQu3Q
2026-09-01 09:58:40 -04:00
will 05f82a3556 Give ordinary Paschaltide Sundays their own Matins Nocturn I-III content
Deploy / deploy (push) Successful in 1m26s
Same seasonal-overlay shape as Advent, live-verified against the reference
engine across 5 Paschaltide Sundays. Generalized sundayNocturnFor to a
season-keyed lookup covering both Advent and Paschaltide.

Confirmed two related non-gaps while investigating: Christmastide/post-
Epiphany Sundays have no seasonal block in the source, and a Duplex+ saint
winning outright on a Sunday deliberately still uses the fixed Sunday
psalmody per this app's own documented design (readings still surface the
saint via the separate pool) — neither needs a fix.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017XMSokiTD2Qc5vPP2YQu3Q
2026-09-01 09:31:22 -04:00
will c3e540f6c2 Give Advent Sundays their own Matins Nocturn I-III content
Deploy / deploy (push) Successful in 1m27s
Nocturns I-II had no seasonal override mechanism at all, and Nocturn III's
own Septuagesima-Palm override didn't cover Advent — live-verified against
the reference engine that Advent has its own seasonal antiphons/versicles
across all three nocturns, identical on all 4 Advent Sundays.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017XMSokiTD2Qc5vPP2YQu3Q
2026-09-01 09:07:46 -04:00
will 3d221c2a45 Give Sunday Matins Nocturn III its own antiphon Septuagesima-Palm Sunday
It was hardcoded to "Allelúja, allelúja, allelúja" year-round. Each of
the 9 Sundays from Septuagesima through Palm Sunday has its own
Gospel-tied antiphon instead, live-verified against Monastic Tridentinum
1617; Lent 1-4 also swap in their own canticles, and Lent 1-4 plus
Passion/Palm Sunday swap in their own versicle. New
matins-sunday-nocturn3-overrides.yml, keyed by temporalId and merged
over the base nocturn3 group by hours/matins.ts's new
sundayNocturn3For — only the real-Sunday branch uses it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017XMSokiTD2Qc5vPP2YQu3Q
2026-09-01 08:17:14 -04:00
will afff77f75a Split ferial Matins nocturn antiphons to one per psalm
Every cross-psalm pair previously shared one antiphon under just the
first psalm, which read inconsistently once psalter-distribution.yml's
reslice left some pairs intact and split others. Each pair is now two
single-psalm groups: the psalm whose own words the shared antiphon
actually quoted keeps it, and its former partner gets a real antiphon
borrowed from elsewhere in the reference corpus where one exists, else
one composed fresh from its own opening verse.
2026-09-01 07:30:35 -04:00
will b050e523ec Split Terce/Sext/None Preces into always-shown Kyrie/Pater + ferial-only versicles
Kyrie eleison and Pater Noster now render every day regardless of rank
(minor-hour-kyrie-pater); the further Preces V/R versicle pairs are
ferial-only, dropped on Sunday and any sanctoral winner.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017XMSokiTD2Qc5vPP2YQu3Q
2026-09-01 06:39:10 -04:00
will 04a8686551 Finish the last 5 vigils: weekday-keyed commemoration antiphons
Deploy / deploy (push) Successful in 1m32s
Corrected an earlier "no source exists" claim by live-querying real
commemorated instances of the Vigils of St. Lawrence and the Assumption
across six different weekdays. Their source files' own [Rule] block
("Versum Feria") turns out to be a real, sourced mechanism, not an
absence: a mere commemoration doesn't reuse the vigil's own antiphon at
all -- it borrows the plain ferial day's antiphon/versicle instead, and
that antiphon quotes the Benedictus canticle in weekday sequence (same
shape vespers-magnificat-antiphons.yml already uses for the Magnificat).
The versicle is a single fixed text. Sunday has no entry: a Vigil
transfers off an ordinary Sunday rather than ever reaching a
commemoration there, confirmed live as well as already true in this
app's own precedence rules.

sanctoralCommemorationPart now takes weekday and resolves this
dynamically for common-of-a-vigil saints, rather than needing a static
per-saint file. All 218 saints with an authored collect now have a real
commemoration antiphon.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ME8QNPdEmHSbSx1r6VmDRG
2026-08-30 18:12:12 -04:00
will 654ec868cb Give the Vigil of Christmas (Dec 24) its own proper content
Deploy / deploy (push) Successful in 1m28s
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
2026-08-30 07:45:44 -04:00
will b3a7176cb8 Add the O Antiphons (Dec 17-23) as an unconditional Vespers Magnificat override
Deploy / deploy (push) Successful in 1m27s
advent-4's own remaining Magnificat-antiphon gap turned out to be a
mechanism problem, not missing content: Dec 17-23 always carries one of
the seven "O Antiphons" at Vespers, keyed to the calendar date itself,
not to whichever Advent week (advent-3 or advent-4, varies by year)
happens to govern that date -- a single per-week file was structurally
the wrong shape.

Added vespers-o-antiphons.yml (MM-DD keyed) and a new lookup tier in
getMagnificatAntiphon, checked unconditionally ahead of both the
per-week temporal file and a real sanctoral winner's own antiphon --
direct instruction: the O Antiphon wins this one text slot on these
seven dates regardless of who otherwise wins the day (e.g. St. Thomas,
Dec 21, still keeps every other part of his own office). Two of the
seven (O Clavis David/O Oriens, Dec 20-21) couldn't be live-verified --
every reference-engine track routes those two dates through St.
Thomas's Vigil/feast instead, which this app's own vigil-of-st-thomas.yml
already documents diverging from -- so they're marked draft rather than
verified.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ME8QNPdEmHSbSx1r6VmDRG
2026-08-30 07:04:30 -04:00
will 7393b3e2be Drop the redundant (Exodus)/(Deuteronomy) parenthetical from canticle names
Deploy / deploy (push) Successful in 1m27s
Both Canticle of Moses entries carried a book-name parenthetical in
their display name, redundant with (and now, since the last commit,
duplicated verbatim by) the citation shown right underneath. Only one
canticle is ever displayed per day, so there's nothing to disambiguate
in the UI -- trim to plain "Canticle of Moses" for both.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018sPkfGLiq58pmmDoBWH5UX
2026-08-29 10:40:13 -04:00
will 7153a846c2 Strip the editorializing parenthetical out of the Canticle of Moses's citation
Deploy / deploy (push) Successful in 1m26s
The user-facing citation field carried an explanatory aside
("liturgical division; split across two Lauds slots") instead of a
plain reference. Move that explanation into the file's own header
comment (which already existed) and leave citation as just "Deut
32:1-65".

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018sPkfGLiq58pmmDoBWH5UX
2026-08-29 10:32:39 -04:00
will 949196b847 Author proper Lauds/Vespers antiphons for the Beheading of St. John Baptist
Deploy / deploy (push) Successful in 1m32s
Live-verified against Divinum Officium (Tridentine 1906/1910 and
Divino Afflatu 1954, Sancti/08-29.txt) — the feast's own 5-antiphon
set ([Ant Vespera], reused verbatim at Lauds as [Ant Laudes]), now
wired through both the newly rank-agnostic Lauds/Vespers proper tier
and the new minor-hour derivation mechanism. Vespers gets only the
first four (mapped onto vu's Monastic-1617-structured four-psalm
Vespers, matching common-of-a-martyr.yml's own 109/111/112/115
baseline) — the reference's own fifth antiphon is a secular five-
psalm-Vespers detail that doesn't apply here, and is used only at
Lauds' Laudate psalm instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VFGHb4XMe6Wya4pGpPhEEi
2026-08-29 07:35:33 -04:00
will a6e4bb15b1 Author real proper Matins/Vespers content for the Nativity of St. John the Baptist
Deploy / deploy (push) Successful in 1m30s
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
2026-08-29 06:24:33 -04:00
will a2d082e608 Keep a short litany + Our Father at Compline on a Double, don't omit
Deploy / deploy (push) Successful in 1m28s
compline-preces.yml was already the secular Tridentine 1906/1910 text
word-for-word (verified live against both tracks), so no text change
was needed there. The actual gap: both Monastic and secular tracks drop
Compline's Preces to nothing on a Double-or-higher, unlike Vespers/Lauds
which fall back to a short form. Per explicit request, this is now a
deliberate vu-specific deviation from both tracks: on a Double, Compline
substitutes the same short Kyrie/Pater-Noster litany Vespers already
falls back to on Sundays/feasts, instead of showing nothing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AHXJAWVAabCKX1JgmDh4Rn
2026-08-29 05:29:56 -04:00
will fbb3a2cfc7 Alias common-of-an-evangelist and -several-women-martyrs, not new schemes
St. Mark's and St. Luke's own reference-engine rule files say "ex C1a",
byte-identical to plain C1 (Apostles) -- an Evangelist-not-Apostle
reuses the Apostles' own scheme, not a separate one.

Ss. Perpetua and Felicity's own file says "vide C7b"; C7b returns the
same four psalm numbers and group/canticle/Laudate antiphons as plain
C7 (Holy Woman) -- its only real difference is the Magnificat/Benedictus
antiphon, handled by a separate, already-existing mechanism, not this
psalmody table. (First-draft duplicate category files for this id were
written and then deleted once this was caught by diffing line-by-line
against the live output.)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AHXJAWVAabCKX1JgmDh4Rn
2026-08-28 21:33:05 -04:00
will e7fc70bf77 Add Common-of-a-Dedication Vespers psalmody category
Genuinely its own scheme (votive=C8) -- unlike every other Common,
Vespers' numbers (109/110/111/147) don't match any other category's
pattern. Lauds' own version is left unauthored: its OT canticle
("Canticum Ieremiae") has never been transcribed anywhere in this app,
so that file isn't written rather than guessed at (see TODO.md).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AHXJAWVAabCKX1JgmDh4Rn
2026-08-28 21:32:54 -04:00
will 15cc76dacf Add Common-of-an-Angel Lauds/Vespers psalmody category
No dedicated numbered Common exists for Angels in the reference engine;
St. Michael's own rule says plain "Psalmi Dominica" with his own proper
antiphons, which Guardian Angels (no proper of her own) reuses
byte-for-byte at both hours. Authored as a reusable category so any
future proper-less Angel addition benefits automatically.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AHXJAWVAabCKX1JgmDh4Rn
2026-08-28 21:32:46 -04:00
will 33c9b2415b Fix Vespers ferial psalmody weekday bug, add duplex-majus+ Common psalmody override
Deploy / deploy (push) Successful in 1m33s
Vespers psalms on Mon-Sat were silently following the anticipated
First-Vespers day's weekday instead of the actual calendar date's, since
resolvePsalmody reused resolveEveningDay's result (correct for
propers/office, which legitimately borrow tomorrow's identity, but wrong
for the ferial psalm cycle, which has no per-feast override of its own).

Also adds a duplex-majus+ Common-category psalmody override to both
Lauds and Vespers, mirroring Matins' existing saint/category mechanism.
Lauds already had a per-feast-only override; Vespers had none. 8 of 24
Common categories authored for both hours, live-verified against the
reference engine.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AHXJAWVAabCKX1JgmDh4Rn
2026-08-28 20:51:06 -04:00
will b19f88696f Rotate Terce/Sext/None psalm assignments for Wed/Thu/Fri/Sat
Deploy / deploy (push) Successful in 1m24s
Wednesday and Friday now carry their own distinct psalm sets (formerly
Friday's and Saturday's, respectively); Tuesday, Thursday, and Saturday
share the gradual psalm set.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVigobgkuEayoGdEiubBdt
2026-08-28 12:41:41 -04:00
will 908f7c320d Author Matins Common-of-a-Widow psalmody (secular-sourced), alias Several-Women-Martyrs
Closes the last 2 of 20 Matins psalmody-override Common categories. The
Monastic-1617 track alone was a genuine dead end here -- no real saint
in the Monastic corpus ever invokes this Common, so there was no live
Monastic rendering to verify a hand-resolution against. Resolved per
explicit user authorization to source secular-track content directly,
consistent with this project's existing blended-source design: combined
a direct read of CommuneM/C7.txt's own psalm-substitution rule with one
live secular query (version=Tridentine - 1906) against St. Bridget of
Sweden to supply the actual antiphon text.

Nocturn 1/2 end up near-identical to common-of-a-virgin-martyr.yml (one
antiphon substituted, since Virgin-Martyr's own text literally calls her
a Virgin) -- too close to alias, not close enough to merge, same
reasoning as common-of-a-confessor vs. common-of-a-confessor-bishop.
Nocturn 3 is genuinely Widow-specific (Parable of the Pearl of Great
Price); its English has no source counterpart and is self-translated,
marked draft-quality.

common-of-several-women-martyrs aliased here: its own Monastic template
whole-file-inherits the same base with no genuine Matins-nocturn
override anywhere in the traced redirect chain.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhysogLP9eCeKS7JEwRi6y
2026-08-28 05:40:43 -04:00
will 09cf0c1aa0 Alias Virgin/Confessor-Doctor/Confessor-Pope to existing Matins Common schemes
Read the reference engine's CommuneM/*.txt templates directly (C6a,
C4a, C4b), rather than trial-and-error live queries, to confirm each
whole-file-inherits its parent Common's Matins nocturn psalmody with no
override. Live-verified byte-identical against St. Scholastica (Virgin
-> Virgin-Martyr) and St. Ambrose (Confessor-Doctor -> Confessor-Bishop);
Confessor-Pope -> Confessor-Bishop aliased on the source redirect chain
alone, since none of vu's three Pope-Confessor saints exist on the
Monastic-1617 calendar at all (matching the convention their own files
already use for every other hour).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhysogLP9eCeKS7JEwRi6y
2026-08-28 05:20:13 -04:00
will 9e0c1b3eb1 Author St. Scholastica's proper Matins psalmody
Her psalm numbers and all three nocturn versicles match Common-of-a-
Virgin(-Martyr) exactly, but her page is headed "ex Proprio Sanctorum"
and her antiphons genuinely narrate her own rainstorm-miracle episode --
real proper content, not Common text, so she gets her own saint-level
file rather than being left to the Common fallback.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhysogLP9eCeKS7JEwRi6y
2026-08-28 05:20:06 -04:00
will fd5ab0781e Author proper Matins psalmody for the 5 angel feasts
Common-of-an-Angel doesn't exist in the reference engine -- every angel
feast has genuine proper Matins content of its own, so these are
saint-level overrides, not a Common category. Transcribed directly from
the reference engine's source files (Sancti/05-08 etc.) after a live-CGI
attempt mis-extracted a mid-nocturn antiphon change.

St. Michael needed his own file: the psalmody-override lookup keys off
the day's resolved winner id, not the `propers` field, and his own
Matins antiphons/lessons turn out to genuinely differ from Apparition's
despite his calendar file's "word-for-word identical" claim (true only
of the collect).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhysogLP9eCeKS7JEwRi6y
2026-08-27 22:23:24 -04:00
will b7c722078d Alias Several-Confessors/Evangelist to existing Matins Common schemes
Live-verified byte-identical against Ss. John of God and Camillus de
Lellis (Several Confessors -> Common-of-a-Confessor) and St. Luke
(Evangelist -> Common-of-an-Apostle) -- genuine full redirects, matching
the reference engine's own votive-index adjacency (C1/C1a, C5/C5c).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhysogLP9eCeKS7JEwRi6y
2026-08-27 22:09:13 -04:00