aboutsummaryrefslogtreecommitdiff
path: root/internal/calendar/precedence_ef.go
Commit message (Collapse)AuthorAgeFilesLines
* calendar, precedence_ef: two more RG 91 gaps exposed by defect 4Lukasz Kasprzak2026-08-121-1/+36
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Found during the mandated 2005-2050 before/after verification (not one of the seven, but caused by defect 4's own fix, so fixed in the same pass rather than left as a self-introduced regression). Neither is a hypothetical: both are live in the fixed calendar and both were individually confirmed via cmd/lectio-ef-dump before being written up as tests. 1. RG 91 entry 4 (Immaculate Conception, Assumption BVM) sits ABOVE entry 6 (Sundays of Advent/Lent/Passiontide) -- unlike an ORDINARY I-class feast (entry 11, e.g. St Joseph), the Immaculate Conception (8 December) is not impeded by an Advent Sunday at all. Before defect 4, Advent Sundays were wrongly II class, so this was accidentally right (I beats II outright, no tie reached); once Sundays became I class the tie-break mattered for the first time, and precedenceEF had no branch for it -- the Sunday wrongly won. 2. RG 91 entry 5 (Vigil & Octave day of the Nativity) sits above entry 6 the same way, and its own gap was worse than a wrong winner: the Vigil of Christmas (24 December) falling on Advent IV, once defect 4 made that a genuine I-class tie, sent the Vigil into transferIfImpededEF's forward walk -- which has no way to re-place a transfer crossing the Dec 31/Jan 1 boundary (celebrationDate re-resolves a fixed date using the YEAR OF THE DAY BEING QUERIED, so a walk landing in the following January can never match the query that produced it). The Vigil did not move to the wrong day; it vanished for the whole year, for every year 24 December is a Sunday (2006, 2017, 2023, 2028, 2034, 2045). Both fixed the same way as the existing II-class-feast-of-the-Lord bonus in precedenceEF (a one-line precedence adjustment keyed on slug), generalised into a single beatsClass1Sunday helper covering both RG 91 entries. A separate, unrelated bug surfaced by the SAME verification pass and fixed alongside it: transferIfImpededEF's destination check reused precedenceEF's tie-break BAND to decide "is this day I or II class", but band encodes a different question (which of two EQUAL-class candidates wins a tie) -- an ordinary, non-Sunday II-class temporal candidate YIELDS under defect 2's own fix (band 5), even though it is genuinely II class. A day within the Octave of the Nativity (26-31 Dec, RG 67) is exactly such a day, so band<=3 alone let a transfer wrongly land inside it (a real reproduction: "vigil-of-christmas" would have landed on 29 December 2006 instead of vanishing outright, caught while tracing the entry-5 bug above). Replaced with a direct class test (isHighClass), which is both correct and simpler -- it no longer needs the Sunday flag at all for this particular check. Witnesses (precedence_ef_repro_test.go): TestImmaculateConceptionBeatsAdventSunday, TestVigilOfChristmasSurvivesAdventSunday. Fail before this commit with: 2013-12-08 observed = "ef-advent-sunday-2" want immaculate-conception-of-the-blessed-virgin-mary (RG 91 entry 4 beats entry 6) 2006-12-24 observed = "ef-advent-sunday-4" want vigil-of-christmas (RG 91 entry 5 beats entry 6; must not vanish) (full set: 2013/2019/2024 for the first, 2006/2017/2023/2028 for the second)
* precedence_ef: a II-class privileged feria yields to a feast (defect 2)Lukasz Kasprzak2026-08-121-13/+36
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | precedenceEF's equal-class tie-break only distinguished "ordinary III/IV-class feria yields" from "everything else wins" -- Sundays, named feasts, Lent/Passiontide ferias, AND II-class privileged ferias (the Ember days, the late-Advent 17-23 Dec ferias) were all bucketed into the same "wins its tie" branch. RG 91 disagrees at class 2: entry 15 (Sundays) sits ABOVE entry 16 (II-class feasts of the universal Church), so a Sunday wins -- but entry 16 sits ABOVE entry 18 (II-class ferias, including the Ember days), so those FERIAS yield instead, the opposite direction from a Sunday. St Matthew (21 September, II class) was losing to the September Ember Wednesday every time the two coincided; St Thomas (21 December, II class) was losing to an ordinary late-Advent feria the same way once the previous commit correctly promoted those ferias to II class. The fix distinguishes a II-class Sunday from a II-class feria using a Sunday flag that already existed on `candidate` (used by the OF path) but was never wired up for EF: temporal_ef.go's efCel always set Sunday: false, even on an actual Sunday. A new efSunday helper (efCel plus the flag) replaces the three efCel calls inside temporalEF's Sunday branch, and computeEF now propagates td.Sunday into the day's temporal candidate. precedence_ef_test.go's own pre-existing witness ("at equal class, the temporal office wins") encoded exactly the bug: a bare class-2 temporal candidate with no Sunday/season information, standing in for "the temporal office" in general. It is rewritten into two explicit cases (Sunday wins its tie; a privileged feria yields) plus the existing Lent/Passiontide-vs-ordinary III/IV-class case restated explicitly rather than left implicit. Witness (precedence_ef_repro_test.go): TestMatthewBeatsSeptemberEmberWednesday. Fails before this commit with: 2016-09-21 observed = "ef-september-ember-wed" want matthew (RG 91 entry 16 beats entry 18) 2022-09-21 observed = "ef-september-ember-wed" want matthew (RG 91 entry 16 beats entry 18) With this commit, all seven named defects are fixed: LECTIO_EF_ORACLE_STRICT=1 go test ./internal/calendar/... -run TestOracleEF passes (0 unallow-listed rank/colour mismatches over 730 days). The gate stays in place for this commit; a following commit removes it.
* fix(ef): 1962 occurrence precedence for the full sanctoralLukasz Kasprzak2026-07-281-5/+22
| | | | | | | | | | | | | | | - Septuagesima ferias are IV class (per annum), not III class, so a III class saint (e.g. Conversion of St Paul, Jan 25) displaces them. - Holy Week ferias and the privileged octaves of Easter and Pentecost are I class: no saint's feast is admitted (temporal office wins). - Occurrence tie-break is asymmetric by season: an ordinary feria (Advent, per annum) yields to an equal-class feast; Lent/Passiontide ferias keep their privilege and win the tie. - A II class feast of the Lord (Purification, Exaltation of the Cross, Dedication of the Lateran) displaces a II class Sunday it falls on. Validated against missalemeum across 2025-2027: ~97.5% of days observe the liturgically-correct celebration, 100% rank agreement on saint-days.
* feat(calendar): precedenceEF (1960 occurrence by class + ↵Lukasz Kasprzak2026-07-271-0/+49
temporal-before-sanctoral)