diff options
| -rw-r--r-- | CLAUDE.md | 55 | ||||
| -rw-r--r-- | lib/rites/rite_ef/temporal_ef.ml | 32 | ||||
| -rw-r--r-- | test/test_golden.ml | 6 | ||||
| -rw-r--r-- | test/test_temporal_ef.ml | 6 |
4 files changed, 78 insertions, 21 deletions
@@ -531,20 +531,47 @@ candidate is exactly one and already spoken for). date's own candidate pool (both Peter and Paul are ordinary Fixed-date sanctoral entries); neither the Major Litanies' Easter+2 target nor Rogation Wednesday's own Mass commemoration has any such pre-existing - candidate to find. Major Litanies' ORDINARY case (the ≈97.7% of years - RG 80's transfer clause does not trigger) is independently buildable - today with zero new machinery — a `Commemoration_only` `Fixed(4,25)` - sanctoral entry, `Precedence_ef.privilege_of`'s already-present, dead RG - 109(f) branch wired to it — but building only that would leave the - transfer years with a NEW wrong answer (a phantom commemoration on - Easter Sunday/Monday itself, which RG 80 explicitly forbids), not merely - the old, understood gap, so it was not built either. Full reasoning, - including the paths considered and rejected (a kernel signature - extension threading Easter-offset into `disposition`/`admit` closes half - of the Major Litanies problem — suppression — but not the relocation - half, and Rogation Wednesday has no equivalent half-solution at all): the - `ef-triduum-litanies` task report and register (Rogations/§4, and the two - narrowed open items in §6). + candidate to find. + + **The real reason to defer the Major Litanies, corrected by the + fix-round review** — the version above was wrong in two load-bearing + ways and is retracted: + + - It said the suppression half needs "a kernel signature extension + threading Easter-offset into `disposition`/`admit`". It does not. + `admit` **already** takes `~temporal` (added for exactly this class of + question during the RG 16(a) task) and `disposition` already takes + `~winner`; on 25 April in a transfer year both carry the Easter Sunday + or Easter Monday office. A rite-local slug test suppresses it with + **zero** kernel surface. + - It implied Easter Monday is unmarkable. Measured over the whole + domain: `ef-easter-1-monday` occurs **exactly 8 417 times in 8 417 + years** — once every year, never displaced, since it is an I-class + octave day — making it precisely as reliable a marker as + `ef-easter-sunday`. The stated asymmetry between the two trigger + conditions does not exist. + + So the **guarded** build (a `Commemoration_only` `Fixed(4,25)` entry, RG + 109(f) wired, plus slug-based suppression on the two Easter slugs) is a + strict improvement, not a regression: 8 223 years newly correct, 194 + unchanged, zero new wrong answers. "Worse than the recorded gap" was + true only of the *unguarded* build, which is the only option that was + scored. + + Deferring is still right, for a reason nobody had identified: **25 April + is St Mark, II class**, so under **RG 111(c)** a *privileged* Litanies + commemoration (RG 109(f)) would **displace** whatever ordinary + commemoration the day currently carries, in ≈97.7% of years — a live, + unmeasured blast radius straight through layers 3 and 4. That + measurement is the prerequisite, and it makes this its own task rather + than a rider on another. The 194 figure is exact and reproduced twice + (Easter = 25 April in 67 years, Easter Monday = 25 April in 127). + + Full reasoning: the `ef-triduum-litanies` task report and register + (Rogations/§4, and the two narrowed open items in §6). **Rogation + Wednesday remains genuinely blocked** — Easter+38 coincides with the + Ascension Vigil by construction, so there is no `(month, day)` pair a + `Fixed` spec could anchor to and no partial build exists at all. ## How to work here diff --git a/lib/rites/rite_ef/temporal_ef.ml b/lib/rites/rite_ef/temporal_ef.ml index 4aa8aea..4b59ff4 100644 --- a/lib/rites/rite_ef/temporal_ef.ml +++ b/lib/rites/rite_ef/temporal_ef.ml @@ -199,7 +199,9 @@ let holy_name_names = [Lord]-subject entry in data/ef/sanctoral.sexp has a fixed civil date inside Holy Week's own movable range (earliest 19 March, latest 24 April; the register's own subject audit lists exactly six [Lord]-tagged - entries, all fixed in January, February, August, September or November) + entries, all fixed in January, February, JULY, August, September or + November -- the Precious Blood, 1 July, was omitted from this list until + the fix-round review counted six entries against five months) -- and any [Class1] sanctoral entry that DOES land there (e.g. a transferred Annunciation) reaches Precedence_ef.disposition's EARLIER, subject-blind "I class, not a Sunday -> Transfer" branch first @@ -208,13 +210,39 @@ let holy_name_names = sweep (git archive, pre- vs post-change) shows zero [observed]/[commemorations]/[transferred_*] difference traceable to this tag anywhere in the domain -- see the task report. *) +(* SOURCE NOTE on the three literals below (corrected, fix-round review): + each is the Missal's own RUNNING HEADER for that Office, which is the + convention every other Latin name in this file already follows + ([holy_family_sunday], [holy_name_sunday]). Counted across both + photographic scans: + "Feria V in Cena Domini" heading FERIA QUINTA IN CENA + DOMINI; running header 1:1 + "Feria VI in Passione et Morte Domini" heading FERIA SEXTA / IN + PASSIONE ET MORTE DOMINI; + running header 1:1. NOT + "Feria VI Parasceve", which + occurs ZERO times as a title in + either scan -- every occurrence + of Parasceve is inside the + Johannine Passion text. RG + 132(a) writes "feriae VI in + Passione et Morte Domini". + "Sabbato sancto" heading SABBATO SANCTO (1x); + running header "Sabbato sancto" + 28x / 30x. + The last was previously shipped as "Sabbato Sancto", a third casing + attested in NEITHER scan -- it appears only in the electronic + transcription's own table of contents, i.e. the source this project's + methodology rule deprecates -- while the comment called it "both + photographic scans, word for word". Recased to the running-header form + the other names use. *) let triduum_names = function | -3 -> Some (Colitur_kernel.Names.of_list [ (Colitur_kernel.Lang.of_string_exn "la", "Feria V in Cena Domini") ]) | -2 -> Some (Colitur_kernel.Names.of_list [ (Colitur_kernel.Lang.of_string_exn "la", "Feria VI in Passione et Morte Domini") ]) - | -1 -> Some (Colitur_kernel.Names.of_list [ (Colitur_kernel.Lang.of_string_exn "la", "Sabbato Sancto") ]) + | -1 -> Some (Colitur_kernel.Names.of_list [ (Colitur_kernel.Lang.of_string_exn "la", "Sabbato sancto") ]) | _ -> None let same a b = Date.compare a b = 0 diff --git a/test/test_golden.ml b/test/test_golden.ml index 68478ec..594ea6b 100644 --- a/test/test_golden.ml +++ b/test/test_golden.ml @@ -165,7 +165,7 @@ let omitted_has (day : (V.season, V.rank) LD.t) slug = let test_easter_extreme_1598 () = check ~msg:"1598-03-21 Holy Saturday: still Passiontide, violet (RG 128)" 1598 3 21 "1598-03-21 saturday season=passiontide week=2 slug=ef-passiontide-2-saturday rank=class-1 colour=violet subject=lord \ - name_la=Sabbato Sancto comms=[] in=- out=[]"; + name_la=Sabbato sancto comms=[] in=- out=[]"; check ~msg:"1598-03-22 earliest possible Easter (Gauss-verified): Paschaltide begins, white, class-1" 1598 3 22 "1598-03-22 sunday season=paschaltide week=1 slug=ef-easter-sunday rank=class-1 colour=white subject=temporal name_la=- comms=[] in=- \ @@ -177,7 +177,7 @@ let test_easter_extreme_1598 () = let test_easter_extreme_1666 () = check ~msg:"1666-04-24 Holy Saturday: still Passiontide, violet (RG 128)" 1666 4 24 "1666-04-24 saturday season=passiontide week=2 slug=ef-passiontide-2-saturday rank=class-1 colour=violet subject=lord \ - name_la=Sabbato Sancto comms=[] in=- out=[]"; + name_la=Sabbato sancto comms=[] in=- out=[]"; check ~msg:"1666-04-25 latest possible Easter (Gauss-verified): Paschaltide begins, white, class-1" 1666 4 25 "1666-04-25 sunday season=paschaltide week=1 slug=ef-easter-sunday rank=class-1 colour=white subject=temporal name_la=- comms=[] in=- \ @@ -206,7 +206,7 @@ let test_easter_extreme_1666 () = let test_easter_extreme_2038_late_modern () = check ~msg:"2038-04-24 Holy Saturday: still Passiontide, violet (RG 128)" 2038 4 24 "2038-04-24 saturday season=passiontide week=2 slug=ef-passiontide-2-saturday rank=class-1 colour=violet subject=lord \ - name_la=Sabbato Sancto comms=[] in=- out=[]"; + name_la=Sabbato sancto comms=[] in=- out=[]"; check ~msg:"2038-04-25 late-modern instance of the latest possible Easter (Gauss-verified)" 2038 4 25 "2038-04-25 sunday season=paschaltide week=1 slug=ef-easter-sunday rank=class-1 colour=white subject=temporal name_la=- comms=[] in=- \ out=[]" diff --git a/test/test_temporal_ef.ml b/test/test_temporal_ef.ml index a979700..5394173 100644 --- a/test/test_temporal_ef.ml +++ b/test/test_temporal_ef.ml @@ -764,7 +764,9 @@ let test_holy_name_fallback_anchor_present_and_erosion_is_caught () = sanctoral entry anywhere in data/ef/sanctoral.sexp has a FIXED civil date inside Holy Week's own movable range (earliest 19 March, latest 24 April -- the register's own subject audit lists exactly six [Lord]-tagged - entries, all fixed in January, February, August, September or November); + entries, all fixed in January, February, JULY, August, September or + November -- the Precious Blood, 1 July, was omitted from this list until + the fix-round review counted six entries against five months); any [Class1] sanctoral entry that DOES land there (e.g. a transferred Annunciation) reaches {!Rite_ef.Precedence_ef.disposition}'s EARLIER, subject-blind "I class, not a Sunday -> Transfer" branch first, so RG @@ -792,7 +794,7 @@ let test_sacred_triduum_identity () = Alcotest.(check bool) "2026-04-04 Holy Saturday: subject Lord" true (subject_of (d 2026 4 4) = Sub.Lord); Alcotest.(check (option string)) "2026-04-04 Holy Saturday: Latin name, both photographic scans verbatim" - (Some "Sabbato Sancto") (name_la_of (d 2026 4 4)); + (Some "Sabbato sancto") (name_la_of (d 2026 4 4)); (* Neighbouring days carry no name/subject override -- the tag is exactly three days wide, not the whole Passiontide-2 week. *) Alcotest.(check (option string)) "2026-04-01 (Wednesday of Holy Week): no Latin name" |
