Model Ascension, Corpus Christi, and the Sacred Heart as temporal feasts
Deploy / deploy (push) Successful in 1m23s

Adds pre-1955 TemporalFeastRecords (rank duplex-1-classis, real octaves)
for the three "feasts of the Lord" that were previously only referenced
as bare date offsets: Corpus Christi/Sacred Heart's own days already
couldn't lose to a sanctoral candidate, but with no record the day fell
back to the generic Trinity-week feria collect and never displayed its
real name; Ascension had no protection at all against an ordinary saint
winning it outright. Sacred Heart's own record carries the
forbidsSuccessorCommemoration flag added in the prior commit, refusing to
commemorate Most Precious Blood on the rare late-Easter date they fall
adjacent.

octave.wins is set to duplex on all three, matching Pentecost's own
verified threshold, despite a known conflict with a previously
live-verified case (St. Ubald winning First Vespers within Ascension's
own octave) -- kept per direct instruction; the affected tests (Ubald,
St. Margaret of Scotland) were updated to assert the new behavior, and
the tradeoff is documented in ascension.yml and TODO.md. A handful of
unrelated test fixtures that happened to land inside these new octave
windows were moved to nearby clean dates.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014axryJBrRswYh2niA7WCUc
This commit is contained in:
2026-08-26 15:21:26 -04:00
parent 2f7b421558
commit 4bbd78b1fd
9 changed files with 219 additions and 36 deletions
@@ -0,0 +1,38 @@
# Read from the reference engine: web/www/horas/Latin/Tempora/Pasc5-4.txt,
# untagged/default [Rank] block — "Duplex I classis cum Octava Privilegiata
# III classis;;7" (the "(rubrica 196)" variant strips the octave entirely,
# 1955/1960-reform text this project deliberately doesn't follow — see
# CLAUDE.md's pre-1955 calendar/rubrics note). Previously not modeled as
# its own record at all: `resolveSeason` already carves Easter+39 into its
# own `ascensiontide` season, but nothing gave that Thursday itself a real
# identity — `temporal-categories.yml`'s `ascensiontide` entry maps every
# feria in the season (including Ascension Thursday itself) to plain
# `ordinary-feria`, so before this record existed the day would have shown
# generic "Thursday in Ascensiontide" content, with no recognition it's
# the feast at all. Duplex I classis outranks any real sanctoral
# candidate regardless, so this record's `rank` alone is enough to make
# `calendar/movable-feasts.ts`'s `applyMovableFeasts` win the day outright
# — the `ordinary-feria` category was never actually load-bearing here.
id: ascension
name: "The Ascension of Our Lord"
rank: duplex-1-classis
anchor:
kind: easter
offset: 39
octave:
enabled: true
# Deliberately `duplex`, matching pentecost-sunday.yml's own verified
# threshold as the closest analogue — despite a real, pre-existing
# counter-example already in this codebase:
# tests/hours/vespers.test.ts's St. Ubald test ("Live-verified against
# Divinum Officium (Monastic Tridentinum 1617) votive=C4") has him
# (Semiduplex) winning First Vespers on May 15, *within* this octave's
# own window, which a strict `duplex` threshold contradicts — real
# octaves come in three privilege "orders", and Ascension/Sacred Heart
# are the weakest (Order III), historically permissive enough that an
# ordinary Semiduplex saint can still occur inside them, unlike
# Pentecost's own (Order I) octave this threshold is borrowed from.
# Kept at `duplex` anyway per direct instruction (2026-08-26) despite
# this known conflict — the Ubald test itself was updated to match, see
# its own comment. Revisit if this turns out to misfire elsewhere.
wins: duplex
@@ -0,0 +1,27 @@
# Read from the reference engine: web/www/horas/Latin/Tempora/Pent01-4.txt,
# untagged/default [Rank] block — "Duplex I classis cum Octava privilegiata
# II ordinis;;7" (the "(rubrica 1960)" variant strips the octave — 1960-
# reform text this project deliberately doesn't follow, see CLAUDE.md's
# pre-1955 calendar/rubrics note). `temporal-categories.yml` already
# forces this single day to `privileged-feria-major` (no sanctoral
# candidate can win it), so this record doesn't change *occurrence* on
# the feast day itself — what it fixes is identity: without it,
# `calendar/temporal-id.ts`'s `resolveTemporalId` falls back to
# `post-pentecost-01` (Trinity Sunday's own governing collect) for this
# date, so the day would display as generic Trinity-week feria content,
# not "Corpus Christi" by name. `rank` here is enough for
# `calendar/movable-feasts.ts`'s `applyMovableFeasts` to make this id the
# day's real winner.
id: corpus-christi
name: "The Most Holy Body of Christ"
rank: duplex-1-classis
anchor:
kind: easter
offset: 60
octave:
enabled: true
# See ascension.yml's own note (same `duplex` choice, same known
# conflict with a live-verified counter-example elsewhere in this
# codebase — St. Margaret of Scotland's own First Vespers test, updated
# to match) — kept at `duplex` per direct instruction (2026-08-26).
wins: duplex
@@ -0,0 +1,23 @@
# Read from the reference engine: web/www/horas/Latin/Tempora/Pent02-5.txt,
# untagged/default [Rank] block — "Duplex I classis cum Octava
# privilegiata III ordinis;;6.51" (the "(rubrica 196)" variant strips the
# octave — 1955/1960-reform text this project deliberately doesn't
# follow, see CLAUDE.md's pre-1955 calendar/rubrics note).
# `temporal-categories.yml` already forces this single day to
# `privileged-feria-major`; this record's job is identity (a real name
# and rank instead of falling back to whatever Sunday governs that week's
# collect) and giving `forbidsSuccessorCommemoration` (see
# temporal-feasts.ts's own doc comment) a record to live on.
id: sacred-heart
name: "The Most Sacred Heart of Our Lord Jesus Christ"
rank: duplex-1-classis
anchor:
kind: easter
offset: 68
octave:
enabled: true
# See ascension.yml's own note (same `duplex` choice, same known
# conflict with a live-verified counter-example, kept per direct
# instruction 2026-08-26).
wins: duplex
forbidsSuccessorCommemoration: true