propers: add August's collect and antiphon text
Deploy / deploy (push) Successful in 44s

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>
This commit is contained in:
2026-08-10 21:11:56 -04:00
parent 5230e661c0
commit a492be961b
20 changed files with 387 additions and 11 deletions
+101
View File
@@ -0,0 +1,101 @@
import { describe, expect, it } from 'vitest';
import { resolveDay } from '../../src/calendar';
import { getDayCollect } from '../../src/hours/resolve-common';
// Clean per-annum years for these dates (no Sunday collision) — see
// data/calendar/saints/*.yml for per-saint source detail.
describe('August sanctoral pull (first pass)', () => {
it('St. Peter\'s Chains wins outright at Duplex majus with a real proper collect and antiphon, over a genuinely unwinnable stub', () => {
const day = resolveDay('2026-08-01');
expect(day.winner).toEqual({
kind: 'sanctoral',
id: 'st-peter-ad-vincula',
name: "St. Peter's Chains",
rank: 'duplex-majus',
});
expect(day.commemorations).toEqual([
{ kind: 'sanctoral', id: 'ss-machabees', name: 'Ss. Machabees, Martyrs', rank: 'simplex' },
]);
expect(getDayCollect(day).status.en).toBe('verified');
});
it('a saint normally blocked by the generic Saturday-of-Mary votive wins independently once the date falls on another weekday', () => {
const day = resolveDay('2027-08-02'); // a Monday
expect(day.winner).toEqual({
kind: 'sanctoral',
id: 'st-stephen-i',
name: 'St. Stephen I, Pope and Martyr',
rank: 'simplex',
});
expect(day.commemorations).toEqual([]);
});
it('St. Donatus wins outright every year in this app, unlike the real reference engine where he is occasionally displaced by a multi-day forward transfer this app does not model', () => {
// In the real Monastic 1617 engine, when Aug 3 (the Finding of St.
// Stephen) falls on a Sunday, it transfers forward past several
// higher-rank fixed feasts (Dominic, Our Lady of the Snows, the
// Transfiguration) and lands on Aug 7, displacing Donatus for that
// year (confirmed live for 2025 and 2031, both Aug-3-Sunday years).
// This app's transfer machinery doesn't chase a multi-day skip search
// like that -- see st-donatus.yml -- so Donatus wins here in every
// year, including ones where the real engine would displace him; a
// known, documented simplification rather than a guess.
const ordinary = resolveDay('2026-08-07');
const wouldHaveTransferredInReality = resolveDay('2031-08-07');
for (const day of [ordinary, wouldHaveTransferredInReality]) {
expect(day.winner).toEqual({
kind: 'sanctoral',
id: 'st-donatus',
name: 'St. Donatus, Bishop and Martyr',
rank: 'simplex',
});
}
});
it("the Vigil of St. Lawrence's own vigil rank forces primacy over a real, otherwise-unranked secondary saint", () => {
const day = resolveDay('2025-08-09');
expect(day.winner).toEqual({
kind: 'sanctoral',
id: 'vigil-of-st-lawrence',
name: 'Vigil of St. Lawrence',
rank: 'vigil',
});
expect(day.commemorations).toEqual([
{ kind: 'sanctoral', id: 'st-romanus', name: 'St. Romanus, Martyr', rank: 'simplex' },
]);
});
it('St. Lawrence wins outright at Duplex II. classis, distinct from his own Vigil the day before', () => {
const day = resolveDay('2026-08-10');
expect(day.winner).toEqual({
kind: 'sanctoral',
id: 'st-lawrence',
name: 'St. Lawrence, Martyr',
rank: 'duplex-2-classis',
});
expect(getDayCollect(day).status.en).toBe('verified');
});
it('dates within St. Lawrence and the Assumption\'s own octaves are excluded entirely, even where the source names a real secondary saint (St. Clare, Aug 12), pending octave support', () => {
const clareDay = resolveDay('2025-08-12');
expect(clareDay.winner.kind).toBe('temporal');
expect(clareDay.commemorations).toEqual([]);
const assumptionOctaveDay = resolveDay('2025-08-22');
expect(assumptionOctaveDay.winner.kind).toBe('temporal');
expect(assumptionOctaveDay.commemorations).toEqual([]);
});
it('the Beheading of St. John the Baptist wins outright at Duplex with a real proper collect and antiphon, over a genuinely unwinnable stub', () => {
const day = resolveDay('2025-08-29');
expect(day.winner).toEqual({
kind: 'sanctoral',
id: 'decollation-of-st-john-baptist',
name: 'The Beheading of St. John the Baptist',
rank: 'duplex',
});
expect(day.commemorations).toEqual([
{ kind: 'sanctoral', id: 'st-sabina', name: 'St. Sabina, Martyr', rank: 'simplex' },
]);
expect(getDayCollect(day).status.en).toBe('verified');
});
});
+25 -7
View File
@@ -6,22 +6,40 @@ describe('transfer mechanism (resolveDay integration)', () => {
// added to exercise this — Aug 9, 2026 is a Sunday, so the vigil (rank
// 'vigil') can't win or be commemorated there (see
// commemorations.ts's ordinary-sunday rule) and must transfer backward.
it('a vigil impeded by an ordinary Sunday transfers backward to Saturday, leaving the Sunday untouched', () => {
// Since the August pull, Aug 8 is no longer an empty landing day — Ss.
// Cyriacus, Largus, and Smaragdus (Semiduplex, a fixed, non-movable
// date) natively occupy it every year, so the backward-transferred
// vigil runs into collision.ts's sanctoral-vs-sanctoral rules instead of
// landing untouched: Semiduplex outranks 'vigil' on the shared
// FeastClass scale, so Cyriacus wins and the vigil is commemorated
// rather than displacing him — real transfer+collision interaction, not
// a data error, same class of finding as July's Apollinaris/Vigil-of-
// St.-James case.
it('a vigil impeded by an ordinary Sunday transfers backward to Saturday and collides with the real feast already there', () => {
const saturday = resolveDay('2026-08-08');
const sunday = resolveDay('2026-08-09');
const monday = resolveDay('2026-08-10');
expect(saturday.winner).toEqual({
kind: 'sanctoral',
id: 'vigil-of-st-lawrence',
name: 'Vigil of St. Lawrence',
rank: 'vigil',
id: 'ss-cyriacus-largus-and-smaragdus',
name: 'Ss. Cyriacus, Largus, and Smaragdus, Martyrs',
rank: 'semiduplex',
});
expect(saturday.commemorations).toEqual([]);
expect(saturday.commemorations).toEqual([
{ kind: 'sanctoral', id: 'vigil-of-st-lawrence', name: 'Vigil of St. Lawrence', rank: 'vigil' },
]);
// The Sunday's own resolution is exactly as if the vigil didn't exist.
// The Sunday's own winner is unaffected by the vigil, but St. Romanus
// (the vigil's own stub secondary, see st-romanus.yml) still surfaces
// as a commemoration here: he lost his own local clash against the
// vigil before the vigil transferred away, and that loss stands
// independently of the transfer -- confirmed against the live
// reference engine, which shows the same commemoration on this date.
expect(sunday.winner).toEqual({ kind: 'temporal', id: 'post-pentecost-11' });
expect(sunday.commemorations).toEqual([]);
expect(sunday.commemorations).toEqual([
{ kind: 'sanctoral', id: 'st-romanus', name: 'St. Romanus, Martyr', rank: 'simplex' },
]);
// St. Lawrence's own day (Monday) is unaffected by the backward transfer.
expect(monday.winner).toEqual({
+9 -3
View File
@@ -32,10 +32,16 @@ describe('weekdayOf', () => {
describe('resolveDay', () => {
it('resolves a plain Sunday with no occurring feast', () => {
const day = resolveDay('2026-08-09');
expect(day.date).toBe('2026-08-09');
// Not 2026-08-09 (also a Sunday): since the August sanctoral pull, that
// date does carry a real commemoration (St. Romanus, impeded from
// winning by the Vigil of St. Lawrence, itself impeded by the Sunday
// and transferred away — see tests/calendar/transfer.test.ts, and
// confirmed against the live reference engine, which shows the same
// commemoration despite the vigil's own absence that day).
const day = resolveDay('2026-10-04');
expect(day.date).toBe('2026-10-04');
expect(day.weekday).toBe('sunday');
expect(day.winner).toEqual({ kind: 'temporal', id: 'post-pentecost-11' });
expect(day.winner.kind).toBe('temporal');
expect(day.commemorations).toEqual([]);
});
});