diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-13 10:04:21 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-13 10:04:21 +0200 |
| commit | 59fbda87d565ad9b98c2493e9703390cd988609d (patch) | |
| tree | 71ebfb8e9568cd5003c10dabc8804fba4ca66e76 /lib/rites/rite_ef/temporal_ef.ml | |
| parent | 254cfd7d9111b0f23f9c44e82d3e31d5817dc5a4 (diff) | |
| parent | e30a4be5a2594fb3b6c4b51345d138cd89ba78ad (diff) | |
| download | colitur-59fbda87d565ad9b98c2493e9703390cd988609d.tar.gz colitur-59fbda87d565ad9b98c2493e9703390cd988609d.zip | |
Merge branch 'ef-rg112-rg110': the Holy Family, RG 112(a), observed identity
Builds the Feast of the Holy Family (RG 17(b), first Sunday after
Epiphany, II class), which did not exist in colitur at all -- it emitted
an ordinary Sunday on all 8417 days the feast occurs. Adds RG 112(a)'s
exclusion, on RG 95 paragraph 2's authority ('Si vero duo festa eiusdem
Divinae Personae ... fit de festo, quod in tabella praecedentiae
superiorem obtinet locum, et aliud omittitur'), corroborated by RG
112(a) and by the Holy Family Mass propers' own 13-January rubric.
Three validation layers had missed the missing feast, each for its own
reason: the differential because lectio lacks it too and shares
colitur's data lineage; the golden layer for want of a pin; and the
oracle because it compared the observed day's rank and colour but never
its identity. That last gap is the more important half of this change
and is now closed -- the oracle compares observed identity, with the
unresolvable population counted and pinned rather than silently skipped.
Also rescales RG 91's band table x10. entry_14_movable_band had been a
negative sentinel, chosen to avoid collision with a real table position;
it also inverted ordering, making a movable II-class feast of the Lord
outrank every I-class day. Unreachable on universal data, live the
moment a diocesan overlay places a I-class proper or indult feast in the
7-13 January window. A half-row is now an ordinary position between its
neighbours. The rescale was verified entry-by-entry against a
photographic scan and moves zero days across the domain.
RG 110 is NOT built despite the branch name; it remains open, as do the
Holy Name of Jesus office (missing in 3619 of 8417 years) and RG 98's
transfer-ordering mechanism.
Diffstat (limited to 'lib/rites/rite_ef/temporal_ef.ml')
| -rw-r--r-- | lib/rites/rite_ef/temporal_ef.ml | 116 |
1 files changed, 105 insertions, 11 deletions
diff --git a/lib/rites/rite_ef/temporal_ef.ml b/lib/rites/rite_ef/temporal_ef.ml index 7782876..1ce9de9 100644 --- a/lib/rites/rite_ef/temporal_ef.ml +++ b/lib/rites/rite_ef/temporal_ef.ml @@ -64,6 +64,46 @@ let season d = citation gap. *) let christ_the_king y = sunday_on_or_before (mk y 10 31) +(* RG 17(b) (Caput III, "De Dominicis"), primary text, verified against BOTH + photographic scans (missale-romanum-1962.pdf and "Missale Romanum + 1962_text.pdf" -- the electronic transcription, 1962-06-23,_SS_Ioannes + _XXIII,_Missale_Romanum,_LT.pdf, carries the SAME text here, so this one + paragraph is not itself a transcription-vs-scan divergence): "17. + Dominica excludit, per se, assignationem perpetuam festorum. Excipiuntur: + a) festum Ssmi Nominis Iesu, celebrandum dominica quae occurrit a die 2 + ad 5 ianuarii (secus die 2 ianuarii); b) festum S. Familiae Iesu, Mariae, + Ioseph, celebrandum dominica prima post Epiphaniam; ... Haec festa locum + tenent dominicae occurrentis cum omnibus iuribus et privilegiis: de + dominica, proinde, nulla fit commemoratio" -- a Sunday of itself excludes + the perpetual assignment of feasts to it; EXCEPTED: (a) the Most Holy + Name of Jesus, celebrated on the Sunday falling 2-5 January (otherwise 2 + January); (b) the HOLY FAMILY of Jesus, Mary and Joseph, celebrated on + the FIRST SUNDAY AFTER EPIPHANY; ... these feasts hold the place of the + occurring Sunday with ALL its rights and privileges: of the Sunday, + therefore, NO commemoration is made -- the identical "cum omnibus + iuribus et privilegiis: nulla fit commemoratio" formula RG 16(a) already + uses for a FIXED-date Lord feast impeding a Sunday (register §6.0), + stated here for the Sunday-ASSIGNED feasts RG 17 itself lists by letter. + + UNLIKE (a)'s own narrow 2-5 January window (which CAN be empty of a + Sunday -- the calendarium's own January table carries an explicit "vel ea + deficiente, die 2 ianuarii" fallback for it, scan-verified), (b)'s 7-13 + January window can NEVER be empty: [sunday_on_or_before (mk y 1 6)] is, + by construction, at most 6 days before 6 January, so adding 7 always + lands in [7, 13] regardless of which weekday 6 January falls on (every + one of the 7 possible cases is exercised by test_temporal_ef.ml's own + [test_holy_family]). The calendarium's own text for (b), both in RG 17 + itself and in its January table entry ("Dominica I post Epiphaniam: + S. Familiae, Iesu, Mariae, Ioseph, II classis"), carries no fallback + clause of any kind -- consistent with there being no gap for one to + cover. + + Formula IDENTICAL to [week_origin]'s own [Time_after_epiphany] case below + (the first Sunday after Epiphany) -- not re-derived a second time, just + named here for its own citation and so [temporal] can test a specific + date against it without reaching into [week_origin]'s implementation. *) +let holy_family_sunday y = Date.add_days (sunday_on_or_before (mk y 1 6)) 7 + let same a b = Date.compare a b = 0 (* Named temporal days: the I-class feasts of the Lord (RG 91 entries 1 and 3), @@ -404,15 +444,16 @@ let temporal d = let easter = Computus.gregorian_easter y in let s = season d in let weekday = Date.weekday d in - let build ~season ~slug ~colour ~rank ~week = + let build ?(subject = Colitur_kernel.Subject.Temporal) ?(names = Colitur_kernel.Names.empty) ~season + ~slug ~colour ~rank ~week () = let office = - Colitur_kernel.Celebration.make ~slug:(Slug.of_string_exn slug) ~rank ~colour - ~subject:Colitur_kernel.Subject.Temporal ~layer:"temporal" () + Colitur_kernel.Celebration.make ~slug:(Slug.of_string_exn slug) ~rank ~colour ~subject ~names + ~layer:"temporal" () in { Colitur_kernel.Temporal.season; week; weekday; office } in match named d with - | Some (season, slug, colour, rank) -> build ~season ~slug ~colour ~rank ~week:(week d) + | Some (season, slug, colour, rank) -> build ~season ~slug ~colour ~rank ~week:(week d) () | None -> ( (* Rogations (the Minor Litanies only -- RG 87, Monday and Tuesday before Ascension). The Major Litanies (25 April, RG 80) are a fixed @@ -441,10 +482,10 @@ let temporal d = if rogation = 36 || rogation = 37 then build ~season:s ~slug:(if rogation = 36 then "ef-rogation-monday" else "ef-rogation-tuesday") - ~colour:Colour.Violet ~rank:(ferial_rank d s) ~week:(week d) + ~colour:Colour.Violet ~rank:(ferial_rank d s) ~week:(week d) () else match ember d with - | Some (slug, rank, colour) -> build ~season:s ~slug ~colour ~rank ~week:(week d) + | Some (slug, rank, colour) -> build ~season:s ~slug ~colour ~rank ~week:(week d) () | None -> ( match sunday_slug d with | Some slug -> @@ -456,11 +497,55 @@ let temporal d = reaches this fallback -- leaving II class here except the remaining Advent and Lent Sundays. *) let rank = match s with Advent | Lent -> Class1 | _ -> Class2 in - build ~season:s ~slug ~colour ~rank ~week:(week d) + (* RG 17(b) (this file's own [holy_family_sunday], full + citation there): the ONE Sunday a year this branch must + NOT leave [subject = Temporal] (this function's own + default) -- the Holy Family, whose slug/rank/colour are + otherwise EXACTLY what this branch already computes for + the 7-13 January Sunday (an accident this task's own + oracle-strengthening work exposed: rank/colour alone + could never distinguish "Holy Family" from "an ordinary, + unnamed Sunday", since they happen to coincide). Every + OTHER Sunday this branch ever builds -- including the + narrower Holy Name of Jesus window, RG 17(a), still + unbuilt as its own named day, register §6 -- keeps + [Temporal] and no name, unaffected. + + [names] -- fix round 1 (coordinator finding 3): a LATIN + name, not English. The oracle's own observed-identity + axis (test_oracle.ml) reads only [en], so this is + deliberately invisible to it -- setting an ENGLISH name + here would mean reading missalemeum's own title text + (the oracle this exact axis is compared against) to + decide colitur's own "ground truth" name, precisely the + "expected value promoted from actual output" vacuity + flavour this project's own review process watches for. + Latin has no such circularity: the calendarium's own + January table, both photographic scans, word for word: + "Dominica I post Epiphaniam: S. Familiae, Iesu, Mariae, + Ioseph, II classis" -- and the Mass propers' own heading + (also both scans): "SANCTAE FAMILIAE IESU, MARIAE, + IOSEPH, II classis", the exact string used here, the + same genitive-title convention test_names.ml's own + worked example already uses for Easter ("Dominica + Resurrectionis"). Every other temporal-cycle candidate + still carries no name at all (register §6.2's own open + item on Holy Name of Jesus, RG 17(a)) -- this is a + targeted addition for the one day this task built, not a + claim that the gap is closed generally. *) + let subject, names = + if same d (holy_family_sunday y) then + ( Colitur_kernel.Subject.Lord, + Colitur_kernel.Names.of_list + [ (Colitur_kernel.Lang.of_string_exn "la", "Sanctae Familiae Iesu, Mariae, Ioseph") ] ) + else (Colitur_kernel.Subject.Temporal, Colitur_kernel.Names.empty) + in + build ~subject ~names ~season:s ~slug ~colour ~rank ~week:(week d) () | None -> ( match christmastide_feria_slug d with | Some slug -> - build ~season:s ~slug ~colour:(season_colour s) ~rank:(ferial_rank d s) ~week:(week d) + build ~season:s ~slug ~colour:(season_colour s) ~rank:(ferial_rank d s) + ~week:(week d) () | None -> (* The days between Ash Wednesday and Lent I have proper Masses and belong to no numbered week. *) @@ -468,7 +553,7 @@ let temporal d = if after_ashes >= -45 && after_ashes <= -43 then build ~season:s ~slug:(Printf.sprintf "ef-lent-after-ashes-%s" (weekday_word d)) - ~colour:Colour.Violet ~rank:Class3 ~week:None + ~colour:Colour.Violet ~rank:Class3 ~week:None () else let colour = (* The Pentecost octave weekdays are red, not Paschaltide's white. *) @@ -508,14 +593,22 @@ let temporal d = Printf.sprintf "ef-%s-%d-%s" (season_slug_word s) (Option.value week_n ~default:0) (weekday_word d) in - build ~season:s ~slug ~colour ~rank:(ferial_rank d s) ~week:week_n))) + build ~season:s ~slug ~colour ~rank:(ferial_rank d s) ~week:week_n ()))) (* Independent restatement of [named]'s fixed and Easter-relative dates, paired with the slug each should carry, for civil year [y]. Deliberately NOT derived from [named] itself -- consumed by [Validate]'s anchor- agreement check (design spec §5.7), which exists precisely to catch an accidental single-site drift (e.g. Ascension's [off 39] silently becoming - [off 40]) that both sides moving together would hide. *) + [off 40]) that both sides moving together would hide. + + [holy_family_sunday] is NOT one of [named]'s own outputs (its own + citation above explains why -- [temporal] applies it as a targeted + [subject] override inside [sunday_slug]'s branch, not through [named]'s + 4-tuple), but it is exactly the same kind of independently-computed + anchor this list exists to guard -- an accidental drift in + [holy_family_sunday]'s own [+7] would silently move Holy Family without + this guard catching it, same as any other entry here. *) let anchors y = let easter = Computus.gregorian_easter y in let off n = Date.add_days easter n in @@ -526,6 +619,7 @@ let anchors y = ("ef-nativity-octave-day-7", mk y 12 31); ("ef-circumcision", mk y 1 1); ("ef-epiphany", mk y 1 6); + ("ef-time-after-epiphany-sunday-1", holy_family_sunday y); ("ef-ash-wednesday", off (-46)); ("ef-passion-sunday", off (-14)); ("ef-palm-sunday", off (-7)); |
