Records the explicit choice to keep the pre-existing Sep 29 mapping as a
deliberate simplification rather than removing it, per user decision.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
6 collects, 1 antiphon -- including backfilling the pre-existing Nativity
of the BVM entry now that the pulling methodology exists.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
14 saints (12 real winners + 2 stubs), plus a propers-slug update for the
pre-existing Nativity of the BVM entry. Two monastic-calendar-specific
finds: St. Nicholas of Tolentino (Sep 10) overrides what the base
Tridentine table treats as a plain Nativity-octave continuation, and St.
Januarius (Sep 19) is a monastic-only addition absent from the base table
entirely. Also flags (not yet acted on) that the pre-existing Sep 29 St.
Michael mapping doesn't appear to hold in this pull's actual target
track -- see the sanctoral-calendar.yml comment for detail.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
11 collects, 4 antiphons -- including backfilling the three pre-existing
August entries (Lawrence, Assumption, Augustine) now that the pulling
methodology exists. Also updates three pre-existing tests whose dates
collided with this month's new real content: the vigil-of-St.-Lawrence
backward-transfer case now runs into a real feast at its landing day
instead of an empty one (confirmed correct against the live reference
engine, including the surviving commemoration on the impeded Sunday
itself), and two other tests moved off Aug 9/10 to dates unaffected by
the new data.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
18 saints (14 real winners + 4 stubs), plus propers-slug updates for the
4 pre-existing August entries. Notable this month: several dates have a
real named secondary saint permanently subordinate to an unmodeled fixed
octave (Lawrence's own, the Assumption's) or the fixed Transfiguration --
excluded entirely rather than guessed at, since this app can't yet
represent the actual blocking primary (a known, deferred octave gap).
Most notable casualty: St. Clare (Aug 12).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Real collect text for all 9 July saints that have one, plus St. Mary
Magdalene's own antiphon — same extraction method as prior months.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
23 saints for July (18 real + 5 stubs). Caught and corrected a real
mistake in this pull's own methodology: an earlier live-query pass
recorded St. Apollinaris under July 24 based on a year where he'd
actually transferred there (his true date, the 23rd, was a Sunday that
year) — cross-checking against the raw calendar text file
(1570.txt) caught it before it went in. His real date is the 23rd, with
St. Liborius as his (permanently unwinnable) secondary; July 24 is
instead the Vigil of St. James with St. Christina as its own secondary.
Five stubs this month are all genuinely unwinnable (fixed-date
competitors) — the most of any month so far.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Real collect text for all 16 June saints that have one, plus a real
antiphon for 4 of them and a fifth (Ss. Peter and Paul) that deliberately
reuses the Chair-of-Peter-at-Antioch antiphon text, matching the source's
own cross-reference — same extraction method as prior months.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
18 saints for June, all winning outright on a clean per-annum date — no
stubs this month, including two normally blocked by the generic
"Sanctae Mariae Sabbato" Saturday votive, which just needed a
non-Saturday year instead.
Three distinct Pauline feasts now exist in this pull (Conversion of St.
Paul, Jan 25; Ss. Peter and Paul, June 29; Commemoration of St. Paul,
June 30) plus a second St. Leo (Leo II, June 28, distinct from Leo I in
April). The Nativity of St. John the Baptist (Duplex I. classis, the
highest rank pulled so far) is kept in the sanctoral store despite the
very high rank, same as the Conversion of St. Paul/Chair-of-Peter
feasts — it's about the saint himself, not a feast of the Lord/BVM.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Real collect text for all 13 May saints that have one, plus a real
antiphon for the 3 that have one of their own (Ss. Philip and James, St.
John Before the Latin Gate, the Apparition of St. Michael) — same
extraction method as prior months. Two saints (St. Peter Celestine, St.
Urban I) have an [Ant 1] in the source that turned out to just be a
cross-reference to the generic Common template, not real unique text, so
no antiphon file was authored for them.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
18 saints for May (16 real + 2 stubs). Both stubs this month are
genuinely unwinnable in the real historical calendar in any year (their
competing observances are fixed-date, not movable) — flagged explicitly
in their own files as distinct from the usual "just an artifact of the
year checked" caveat.
A second, distinct feast of St. Michael (his Apparition, May 8) is kept
as its own record separate from st-michael.yml's Sept 29 dedication
feast, same precedent as the two Chair-of-Peter feasts.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Real collect text for all 8 April saints that have one — same extraction
method as prior months. One correction to St. Robert's own English
translation in the source, which left his name in Latin genitive form
("blessed Robérti") rather than translating it — fixed, flagged in the
file as a transcription artifact, not a deliberate style choice.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
12 saints for April (11 real + St. Catherine of Siena as a stub), all
winning outright on a clean per-annum date.
Two real methodological findings this month:
- St. Mark (Apr 25, Duplex II. classis) directly confirms the
privileged-feria-major behavior from the previous fix: he only ever
gets commemorated within the Easter Octave, never wins there.
- St. Robert/St. Catherine of Siena (Apr 29) is a genuine, year-stable
monastic-calendar reassignment — this app's own base Latin source data
files that date's Roman-calendar content under a different saint (Peter
Martyr) entirely, which a naive raw-file lookup by MM-DD would have
missed; the live per-date query resolved it correctly regardless, and
is what these records are actually built from. Worth remembering for
future months.
New common category: common-of-an-evangelist (St. Mark, an Evangelist
but not an Apostle).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
A plain Duplex saint was losing to any privileged feria (Ember days
included) since the occurrence engine only let duplex-1-classis+ get
even a commemoration there. Verified this was wrong: St. Gregory the
Great, plain Duplex, outright wins against a Lenten Ember Saturday in
the real Monastic 1617 engine.
Splits TemporalCategory's single privileged-feria into privileged-feria
(the lesser tier — Lent's Ember days, verified — now behaves like an
ordinary Sunday: Duplex+ wins outright) and privileged-feria-major (Ash
Wednesday, Holy Week, the Easter Octave, verified via St. Mark only ever
being commemorated there, never winning — behaves like privileged-
Sunday). Everywhere else the old single category was ambiguous
(Pentecost's own Ember days/Vigil/Octave, the Vigil of Christmas)
defaults to the stricter major tier pending verification.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Real collect text for all 6 March saints that have one, plus St. Joseph's
own antiphon — same extraction method as January/February.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
7 saints for March, all winning outright on a clean per-annum date. Notably
St. Benedict himself (Mar 21, Duplex I. classis, the founder — "S. P. N."
in the source) turns out to have no unique Oratio/Antiphon at all in this
date's source file, only Common-of-an-Abbot cross-references — flagged in
his own file to check his second (July) feast when that month comes up.
Two Benedictine-oblate saints (Frances of Rome, Gregory the Great) are
marked "O. N." (Ordinis Nostri) in the source — real significance for a
monastic calendar. St. Frances also needed a new common category,
common-of-a-widow (she's neither virgin nor martyr).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Real collect text for the 6 February saints that have one, plus a real
antiphon for the 2 that have one of their own — same extraction method
as January (fully-rendered live-engine output, not the raw source files'
own shorthand endings).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
13 saints for February (12 real + the Vigil of St. Matthias), all
verified winning outright on a clean per-annum date — no secondary/
commemorated stubs needed this month, unlike January.
Two new scope exclusions found this month, beyond the usual octave/
temporal-continuation and fixed Lord/BVM feast ones: the generic
"Sanctae Mariae Sabbato" Saturday votive (not a real saint) and Feb 29's
leap-year redirect of the Vigil of St. Matthias (a real but not-yet-
modeled leap-day date shift).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Real collect text for the 9 January saints that have one, plus a real
antiphon for the 3 that have one of their own (as opposed to falling back
to a generic Common-of-Saints text) — read directly from the reference
engine's fully-rendered output, not reconstructed from the raw source
files' own shorthand endings ($Per Dominum, $Qui vivis, etc.).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
20 saints for January, verified per-day against Divinum Officium (Monastic
Tridentinum 1617): 13 that actually win their day outright (rank pulled
from a live per-date query, since the static 1570/M1617 calendar text
files turned out unreliable once monastic-specific overrides apply) and
7 stubs for saints that only ever get commemorated, with an explicitly
flagged, unverified simplex rank guess pending correction.
Deliberately out of scope: pure octave-continuation days (In Octava S.
Stephani, the Epiphany-octave ferias) and fixed-date feasts of the
Lord/BMV (Circumcision, Epiphany) — sanctoral only, not temporal.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Three separate resolver files (terce.ts/sext.ts/none.ts), not a shared
little-hour module — they're structurally identical but kept independent
by choice. Ordo verified against Divinum Officium (Monastic Tridentinum
1617): opening versicle, self-contained hymn, one antiphon framing three
psalms (no closing repeat, unlike Prime), a capitulum with its own
embedded short versicle/response, the day's own collect, and a closing
identical across all three hours.
Also fills in psalter-distribution.yml's previously-missing Sunday/
Monday/Tuesday psalm entries (Ps 118 sections for Sunday/Monday; Tuesday
turns out to share Wednesday/Thursday's native gradual-psalm set, not a
distinct one). Friday/Saturday's antiphons are derived from each day's
first psalm rather than reusing the native gradual antiphons, since
those two days already use a redistributed, non-native psalm set.
hours/types.ts gains a 'day-collect' part kind — the first ordo to use
the day's own Proper collect rather than a fixed text.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Fixed, self-contained text (including each hymn's own final doxology
stanza) — unlike Prime's/Compline's hymns, these don't change by season,
so there's no appendDoxology split. Verified against Divinum Officium
(Monastic Tridentinum 1617).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Text for every psalm src/data/psalter-distribution.yml's terce/sext/none
tables reference but hadn't been authored yet — the native Gradual set
(119-127) plus the psalms used by the Friday/Saturday redistribution.
Verified Latin/English against Divinum Officium (Monastic Tridentinum
1617).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Corrects and completes the occurrence rules, based on a design discussion
plus one concrete data point: St. Anthony Abbot (plain Duplex) was found
outright winning against an ordinary Sunday in the real Monastic 1617
engine, which the old duplex-1-classis-only threshold got wrong.
- FeastClass gains `vigil`, inserted between `simplex` and `semiduplex` —
one ordering that correctly serves both "does this win against a Sunday"
(vigil behaves like simplex there) and "which of two saints wins a
landing-day collision" (vigil beats simplex, loses to semiduplex).
- LiturgicalDay.occurring (a flat OccurringFeast[] that could only ever
express a losing *sanctoral* candidate) is replaced by `winner:
DayWinner` + `commemorations: Commemoration[]` — a discriminated list
that can hold the temporal day itself, one or more sanctoral entries, or
(not built yet, but the shape already accommodates it) a future octave
kind.
- commemorations.ts: ordinary Sundays let Duplex+ win outright (Sunday
commemorated in return), Semiduplex/Vigil transfer elsewhere (too
substantial a feast to cheapen with a bare commemoration), Simplex stays
and is commemorated. Privileged Sundays never displace; Duplex-majus+
commemorated, everything else transfers.
- collision.ts (new): resolves two sanctoral candidates wanting the same
day (a transfer landing on an already-occupied day, or two native
saints sharing a date) — duplex > semiduplex > vigil > simplex, loser
always commemorated, ties favor the native occupant.
- temporal-id.ts (new): maps any date to one of the 52 real Sunday-collect
ids from the previous commit, so a temporal winner/commemoration can
actually be looked up, not just labeled "temporal" in the abstract.
- index.ts's resolveDay orchestrates all of it, including the actual
Monday/Saturday transfer mechanism. Landing on a privileged feria (the
concrete case: Holy Week, right after Palm Sunday) is explicitly
deferred rather than guessed at — it needs its own Easter-keyed lookup
table, the same way the reference engine handles it.
Added the Vigil of St. Lawrence (Aug 9) as real content specifically to
exercise the backward-transfer rule end-to-end: Aug 9, 2026 is a Sunday,
so the vigil transfers cleanly back to Saturday, verified by a new
integration test alongside the unit-level rule and collision tests.
New data/propers/temporal/*.yml and propers/index.ts's getTemporalProper,
mirroring the existing common-propers store. Populated with all 52
distinct Sunday collects for the full liturgical year (Advent 1-4, the
Christmas-octave Sunday, Epiphany 1-6, Septuagesima-tide, Lent 1-4 +
Passion + Palm Sunday, the 8 Paschal-time Sundays through Pentecost, and
post-Pentecost 1-24), each verified against the real Monastic Tridentinum
1617 engine.
Keyed Pentecost/offset-based ("post-pentecost-N-collect"), not
Trinity-counted — that's a display choice for calendar/day-label.ts, kept
independent of this content's storage identity. 8 of the 52 needed to be
read directly from the reference engine's source files plus its standard
closing-formula macros, since a real saint outranks those particular
Sundays on every candidate year checked and a live date query would only
ever return the saint's own collect.
Non-Sunday Monastic Matins is 12 psalms/day; ferial Terce/Sext/None always
repeats the same 9 (119-127) regardless of weekday. Worked out an editorial
redistribution in conversation: cut non-Sunday Matins to 9/day, and hand
the freed capacity to Friday's and Saturday's Terce/Sext/None instead of
discarding it, keeping Wednesday/Thursday's 119-127 as-is and leaving
Sunday/Monday/Tuesday untouched entirely.
No code reads `matins`/`terce`/`sext`/`none` from this table yet — those
hours don't exist until milestone 3 (T/S/N) and milestone 5 (Matins).
Recording the decision now, with the method spelled out in the comment,
so it survives until then rather than needing to be re-derived. Verified
against a real Monastic Tridentinum 1617 run throughout, not reconstructed
from memory.
Replaces the FeastRank placeholder with a real ordered FeastClass (the old
pre-1955 six-level scale) and a new TemporalCategory (privileged/ordinary
Sunday/feria). calendar/commemorations.ts's decideOccurrence encodes the
actual precedence rules as explicit, commented branches per category
rather than the reference engine's own opaque numeric weights — this app
targets one ruleset, so the readability trade-off is worth it. Category
membership (data/calendar/temporal-categories.yml) is a best-effort
reconstruction of the pre-1955 tradition, not sourced from a primary text;
expect corrections.
calendar/feasts.ts resolves real sanctoral candidates, and resolveDay()
wires it all together — occurring/temporalCategory are no longer stubs.
isDoubleOrHigher (hours/antiphon.ts) is now a real comparison instead of
a hardcoded false.
Seeded 7 real saints/feasts, each verified directly against Divinum
Officium's own rank data (not reconstructed from memory) as a small,
growable start: St. Lawrence, the Assumption, St. Augustine, the Nativity
of the BVM, St. Michael, All Saints, the Immaculate Conception.
Ordo is Monastic 1617 as a base, with deliberate Tridentine 1906
additions: the "In manus tuas" short responsory, the Nunc Dimittis
with its "Salva nos" antiphon, the fuller Preces (Monastic's own is
shorter), and Lent's "Christe, qui lux es et dies" hymn replacement
(English translation marked draft, pending a real historical one).
Psalms 4, 90, 133 are fixed daily with real verified text, unlike
Prime's weekday-rotated psalms.
The closing Marian antiphon now picks Alma Redemptoris Mater / Ave
Regina Caelorum / Regina Caeli / Salve Regina by real season, using
the calendar work from the previous commit — except Ave Regina
Caelorum's own window (Candlemas through the day before Maundy
Thursday) doesn't align to any single season value, so that one case
checks the real date directly instead of going through the by-season
table.
resolve-common.ts extracts the resolve/status/doxology/antiphon
helpers Prime already had into something Compline can share; a few
propers files lose their "prime-" prefix now that both hours use them.
resolveDay() no longer hardcodes season: 'trinitytide'. Easter is
computed via the Anonymous Gregorian algorithm (verified against 16
known reference dates spanning 1583-2100); Advent/Christmastide/
Epiphanytide follow the Christmas-anchored rules (including Advent's
"Sunday nearest Nov 30"); Septuagesima through Trinitytide come from
easter-offsets.yml, reshaped from single named anchor points into real
ranges plus single-day overrides for Corpus Christi and Sacred Heart.
occurring feasts (calendar/feasts.ts) are still a stub — the sanctoral
calendar and Double-vs-not ranking are a separate, larger project.
Pulls in verified content from Divinum Officium rather than placeholders:
17 psalms (2, 6, 7-19, 118, 129), 365 days of the Martyrology, and the full
121-reading Regula cycle, plus the Athanasian Creed.
Ordo corrections driven by review against the real engine output:
- Capitulum and Preces now pick a Sunday/feast vs. ferial form
(calendar/isSundayOrFeast); ferial Preces said every ferial day by choice.
- Chapter responsory, hymn doxology, and the opening versicle's
Alleluia/Laus tibi all vary by season via a shared resolver
(hours/seasonal-propers.ts).
- Real Roman Kalends/Nones/Ides Latin dating (calendar/roman-date.ts,
verified against 363/365 real Martyrology headings) plus the historical
"bis sextus" Feb 29 handling, and the Martyrology's Luna (moon-day)
heading (a ported Golden-Number calculation).
- Fixed responsory structure (was missing its initial full repeat),
weekday psalm antiphons (opening as incipit-or-full by rank, full
repeat after the psalms/Creed as its own part, "*" chant mark kept),
scripture citations on the capitulum/lectio brevis, and V./R. markers
switched from Unicode symbols to plain text for reliable font rendering.
- Dropped Pretiosa and the dead-commemoration psalm (129) for time;
trimmed section headings down to the ones that are actually named
things (Preces, Chapter Office, etc. no longer relabel connective text).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Client-side-first PWA (Vite/TS, no backend) per the approved plan: day-
navigable shell listing all 8 hours, Prime fully resolves via the
calendar -> psalter -> ordo pipeline, the other 7 hours are registered
but flagged not-implemented. Sanctoral/temporal calendar data uses a
day -> id indirection layer (saints, easter-offsets, fixed-date-calendar)
so reassigning a feast to a different day is a data edit, not a code
change. Docker (Caddy-serving-static) + Gitea CI workflow scaffolded to
match the eec/drip/bookshop operational pattern.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>