From 7fb37f623774210e744db4a0d112b5d136717a73 Mon Sep 17 00:00:00 2001 From: Will Estes Date: Wed, 26 Aug 2026 06:45:31 -0400 Subject: [PATCH] Fix First Vespers rank threshold: any sanctoral winner qualifies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc --- src/calendar/vespers.ts | 15 ++++++++++----- .../common/st-zephyrinus-magnificat-antiphon.yml | 12 ++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 src/data/propers/common/st-zephyrinus-magnificat-antiphon.yml diff --git a/src/calendar/vespers.ts b/src/calendar/vespers.ts index 941d311..c5126f6 100644 --- a/src/calendar/vespers.ts +++ b/src/calendar/vespers.ts @@ -40,11 +40,16 @@ function hasFirstVespers(day: LiturgicalDay): boolean { } // Live-verified (2026-08): Ss. Cyriacus/Largus/Smaragdus (Aug 8, plain // Semiduplex) claims First Vespers over St. Donatus's Aug 7 — "Vespera - // de sequenti" in the real Monastic 1617 engine — so Semiduplex clears - // this bar, not duplex-majus as originally guessed (unverified at the - // time). Matches keepsOwnSecondVespers's own privileged-feria-minor - // threshold just below, which uses the same cutoff. - return day.winner.kind === 'sanctoral' && isAtLeast(day.winner.rank, 'semiduplex'); + // de sequenti" in the real Monastic 1617 engine. Originally thought + // Semiduplex was the actual cutoff, but re-verified 2026-08-25: St. + // Zephyrinus (Aug 26, plain Simplex) likewise claims First Vespers over + // St. Louis's Aug 25 (also Simplex) — "Vespera de sequenti; nihil de + // præcedenti" — so *any* real sanctoral winner, however low-ranked, + // clears this bar; there's no rank floor at all, only the separate + // keepsOwnSecondVespers question of whether the day *before* it + // outranks the claim. Every FeastClass (including `vigil`, untested + // directly but the same "lowest tier" logic) now qualifies. + return day.winner.kind === 'sanctoral'; } /** Does this day keep its own Second Vespers regardless of what tomorrow is? */ diff --git a/src/data/propers/common/st-zephyrinus-magnificat-antiphon.yml b/src/data/propers/common/st-zephyrinus-magnificat-antiphon.yml new file mode 100644 index 0000000..0abc3e1 --- /dev/null +++ b/src/data/propers/common/st-zephyrinus-magnificat-antiphon.yml @@ -0,0 +1,12 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617), Vespers +# live query, St. Zephyrinus's own First Vespers (anticipated the evening +# of Aug 25, per the corrected `hasFirstVespers` rule — see +# src/calendar/vespers.ts). The "Iste Sanctus" formula, common to a +# Martyr not Pope/Bishop-rank office. +id: st-zephyrinus-magnificat-antiphon +text: + la: "Iste Sanctus pro lege Dei sui certávit usque ad mortem, et a verbis impiórum non tímuit: fundátus enim erat supra firmam petram." + en: "This man is holy for he hath striven for the law of his God even unto death, and hath not feared for the words of the ungodly; for he had his foundation upon a strong rock." +status: + la: verified + en: verified