aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/ef/commons.sexp43
-rw-r--r--data/ef/expected-divergences-missalemeum.sexp9
-rw-r--r--data/ef/expected-divergences.sexp13
-rw-r--r--data/ef/sanctoral.sexp4
-rw-r--r--lib/rites/rite_ef/precedence_ef.ml41
-rw-r--r--test/test_differential.ml18
-rw-r--r--test/test_lectionary_ef.ml10
-rw-r--r--test/test_oracle.ml37
-rw-r--r--test/test_precedence_ef.ml28
-rw-r--r--test/test_sanctoral_ef.ml8
10 files changed, 199 insertions, 12 deletions
diff --git a/data/ef/commons.sexp b/data/ef/commons.sexp
index c488fa2..1bf7dfd 100644
--- a/data/ef/commons.sexp
+++ b/data/ef/commons.sexp
@@ -155,6 +155,26 @@
(((part First) (reference "Ecclus 31:8-11"))
((part Gospel) (reference "Luke 12:35-40"))))
+ ; --- Commune Confessoris non Pontificis, SECOND Mass ("Altera Missa",
+ ; headed "II / Pro Confessore non Pontifice"), Missa "Iustus ut palma
+ ; florebit". scan1 [25]-[26], lines 42057-42128; scan2 (26), lines
+ ; 46967-46993. The bracketed page differs between printings exactly as
+ ; this file's header warns -- scan1 prints [25], scan2 (26) -- so this
+ ; entry keys on the Mass's IDENTITY (heading + "Iustus" incipit), never
+ ; the number. Added by the ef-sanctoral-status task for `didacus`.
+ ; Epistle heading: "Lectio Epistolae beati Pauli Apostoli ad Corinthios.
+ ; 1 Cor. 4, 9-14" (scan1:42058-42059, item 4359).
+ ; Gospel heading: "Sequentia sancti Evangelii secundum Lucam.
+ ; Luc. 12, 32-34" (scan1:42113-42115, item 4364).
+ ; scan2 prints BOTH citations on one line, 46993: "1 Cor. 4, 9-14" and
+ ; "Luc. 12, 32-34" -- the two OCR layers agree exactly, so the page-image
+ ; third reading this file's METHOD requires on disagreement was not
+ ; triggered. Distinct from the FIRST Mass above (Ecclus 31:8-11 /
+ ; Luke 12:35-40), which is a different formulary on the same pages.
+ (common-of-a-confessor-not-a-bishop-2
+ (((part First) (reference "1 Cor 4:9-14"))
+ ((part Gospel) (reference "Luke 12:32-34"))))
+
; --- Commune Abbatum, Missa "Os iusti"
; scan1 [27]-[28], lines 42134-42202; scan2 (28)-(29), lines 47057-47114.
; Epistle: "Lectio libri Sapientiae. Eccli. 45, 1-6"
@@ -254,4 +274,25 @@
; 5 April: "S. Vincentii Ferrerii Conf. / III classis / Missa Os iusti,
; de Communi Confessoris non Pontificis I loco [24], praeter orationem
; sequentem." scan1:28627-28632, scan2:31682-31689.
- (vincent-ferrer common-of-a-confessor-not-a-bishop-1))))
+ (vincent-ferrer common-of-a-confessor-not-a-bishop-1)
+
+ ; 16 May: "Die 16 maii / S. Ubaldi Ep. et Conf. / III classis / Missa
+ ; Statuit, de Communi Confessoris Pontificis I loco [19], praeter
+ ; orationem sequentem." scan1:30196-30200; scan2:33448-33457 (which
+ ; prints the same instruction with its own pagination, "(20)", and the
+ ; same proper Oratio "Auxilium tuum nobis, Domine"). Only the Oratio is
+ ; proper; the readings are the Common's. SAME Common as `patrick`.
+ ; Promoted from Commemoration_only by the ef-sanctoral-status task: the
+ ; Missal's own universal calendarium ranks 16 May "S. Ubaldi Ep. et
+ ; Conf., III classis" outright, with no commemoration rubric.
+ (ubaldus common-of-a-confessor-bishop-1)
+
+ ; 13 November: "Die 13 novembris / S. Didaci Conf. / III classis / Missa
+ ; Iustus, de Communi Confessoris non Pontificis II loco [25], praeter
+ ; orationem sequentem." scan1:40276-40284; scan2 prints the identical
+ ; instruction as "2* loco (26)" -- the pagination offset again, the Mass
+ ; identity stable. Only the Oratio is proper. Promoted from
+ ; Commemoration_only by the same task, on the same calendarium evidence
+ ; ("S. Didaci Conf., Ill classis", scan1; "S. Didaci Conf., III cl.",
+ ; scan2).
+ (didacus common-of-a-confessor-not-a-bishop-2))))
diff --git a/data/ef/expected-divergences-missalemeum.sexp b/data/ef/expected-divergences-missalemeum.sexp
index 84b4f25..dfee36c 100644
--- a/data/ef/expected-divergences-missalemeum.sexp
+++ b/data/ef/expected-divergences-missalemeum.sexp
@@ -257,8 +257,8 @@ REVISED, ef-bvm-saturday task: 395 of the 730 days in this window used to carry
REVISED AGAIN, Task 9 (branch ef-lectionary, layer-4 oracle): 352, down by 42 from 394. NOT a change to this entry's own guard (still, and only, [diffs = [ Observed_identity_unresolved ]] exactly) -- this task compared reading citations for the first time, and 42 of the former 394 rows now ALSO carry a real [First_mismatch]/[Gospel_mismatch] alongside the pre-existing observed-identity gap, so they escape this entry's own EXACT-match guard and move to the FIVE new entries below (M23 2, M24 4, M25 4, M26 30, M27 2 -- 2+4+4+30+2=42, exactly accounting for the drop, verified against the comparator's own failure output, not assumed from the arithmetic alone -- CORRECTED, fix round 1, coordinator review: this note previously miscounted them as \"six\").
-CORRECTED, fix round 1 (coordinator review): the remaining 352 were previously described as every day whose citation \"ALREADY agreed with missalemeum before this task and still does\" -- imprecise for 18 of them. Before this task the citation axis did not exist at all, so NO row's citation was ever actually checked; \"already agreed\" wrongly implies the pre-task VALUE was correct on all 352, when for 18 it was not -- it only became correct, and therefore only started agreeing, because of this task's own three fixes (Holy Name Sunday's own two dates, 2026-01-04/2027-01-03; 12 more January-window ferias across the three RG-17(a)/Holy-Family-propers-rubric families that now resolve at step 2 instead of the walkback, one full list: 2026-01-02/05/07/08/09/12, 2027-01-04/05/07/08/11/12; and Corpus Christi/Sacred Heart in both years, 2026-06-04/06-12, 2027-05-27/06-04 -- 2+12+4=18, independently re-derived against the real resolver, not merely arithmetic). The other 334 were genuinely unaffected by this task, matching both before and after (or, more precisely, would have matched on the day this axis existed either way). WIDENED 352 -> 355 (movable-date-specs follow-up, 2026-08-17): the three Trinity-week ferias that M26 shape 2(a) used to cover now agree with the oracle on their citations and differ only on observed-identity, which is this entry own generic shape -- a temporal-origin day for which colitur sets no English name. Not a new divergence: the same three days, one of their two causes removed. WIDENED 355 -> 376 (BVM Saturday Mass, 2026-08-17): the BVM Saturday days M26 shape 1 used to cover now agree with the oracle on their citations and differ only on observed identity, which is this entry's own generic shape -- the office is temporal-origin and deliberately carries no English name. Not new divergences: the same days, their citation cause removed.")
- (expected_rows 376))
+CORRECTED, fix round 1 (coordinator review): the remaining 352 were previously described as every day whose citation \"ALREADY agreed with missalemeum before this task and still does\" -- imprecise for 18 of them. Before this task the citation axis did not exist at all, so NO row's citation was ever actually checked; \"already agreed\" wrongly implies the pre-task VALUE was correct on all 352, when for 18 it was not -- it only became correct, and therefore only started agreeing, because of this task's own three fixes (Holy Name Sunday's own two dates, 2026-01-04/2027-01-03; 12 more January-window ferias across the three RG-17(a)/Holy-Family-propers-rubric families that now resolve at step 2 instead of the walkback, one full list: 2026-01-02/05/07/08/09/12, 2027-01-04/05/07/08/11/12; and Corpus Christi/Sacred Heart in both years, 2026-06-04/06-12, 2027-05-27/06-04 -- 2+12+4=18, independently re-derived against the real resolver, not merely arithmetic). The other 334 were genuinely unaffected by this task, matching both before and after (or, more precisely, would have matched on the day this axis existed either way). WIDENED 352 -> 355 (movable-date-specs follow-up, 2026-08-17): the three Trinity-week ferias that M26 shape 2(a) used to cover now agree with the oracle on their citations and differ only on observed-identity, which is this entry own generic shape -- a temporal-origin day for which colitur sets no English name. Not a new divergence: the same three days, one of their two causes removed. WIDENED 355 -> 376 (BVM Saturday Mass, 2026-08-17): the BVM Saturday days M26 shape 1 used to cover now agree with the oracle on their citations and differ only on observed identity, which is this entry's own generic shape -- the office is temporal-origin and deliberately carries no English name. Not new divergences: the same days, their citation cause removed. CORRECTED, ef-sanctoral-status: 376 -> 373. Three rows left this entry for M30 when `ubaldus` and `didacus` were promoted to Feast on the Missal's own calendarium. They were unresolved here precisely because the observed office was TEMPORAL-origin (a feria) and carries no English name; now the observed office is the SAINT, which is sanctoral-origin and does resolve, so the comparator can state a real identity mismatch instead of declining to compare. The entry shrinks because its shape stopped occurring on those days, not because the days stopped diverging.")
+ (expected_rows 373))
((id M19)
(citation "RG 110's OTHER direction: \"In Officio et Missa S. Petri semper fit commemoratio S. Pauli, ET VICISSIM\" -- the SAME rule M12 used to cite, applied here to Paul's own office commemorating Peter, not Peter's own office commemorating Paul; confirmed a third time by the calendarium's own June table, both photographic scans, word for word: \"In Commemoratione S. Pauli Ap., III classis. / Commemoratio S. Petri Ap.\"")
(verdict colitur)
@@ -303,3 +303,8 @@ CORRECTED, fix round 1 (coordinator review): the remaining 352 were previously d
(verdict colitur)
(note "ef-oconnell-rubrics branch. Unlike every other entry in this file, the oracle here is not an independent witness against colitur: it is colitur's own discarded ancestor. colitur was bootstrapped from lectio, lectio's ini is generated from missalemeum, and missalemeum uses Divinum Officium's data files, so all three carried the same two wrong colours and no layer sharing that lineage could see it (CLAUDE.md's own lineage note, register 6.20). The defect surfaced only against the Missal's own RG 128 -- transcribed in the register since 2026-08-11 and disagreeing with the shipped data all along -- plus O'Connell and a published 1962 Ordo. Same fix as C37 in the lectio differential, seen from the oracle side. 3 rows in this window: 2026-08-14, 2027-08-09, 2027-08-14. 2026-08-09 is absent because it is a Sunday that year and the vigil never occurs, checked with date -d. Gated on the exact dates and Colour_f alone, so any other divergence on these days would still surface unexplained.")
(expected_rows 3))
+ ((id M30)
+ (citation "The 1962 Missal's own universal CALENDARIUM. 16 May: 'S. Ubaldi Ep. et Conf., III classis' (docs/research/scan1.txt:2801, corroborated scan2.txt:3197). 13 November: 'S. Didaci Conf., III classis' (scan1.txt:3091, corroborated scan2.txt:3532). Neither carries a Commemoratio rubric, and each has its own Mass entry in the Proprium Sanctorum taking its readings from a Common with only its Oratio proper -- which a bare commemoration never has. The calendarium carries no 'pro aliquibus locis' marker anywhere, so an entry in it is universal by construction. The published 1962 Ordo (register 6.21) independently lists both as the day's III-class office. Full account and method in C38, data/ef/expected-divergences.sexp")
+ (verdict colitur)
+ (note "ef-sanctoral-status branch. As with M29, the oracle here is not an independent witness against colitur but colitur's own discarded ancestor: colitur was bootstrapped from lectio, lectio's ini is generated from missalemeum, and missalemeum uses Divinum Officium's data files, so all three carried the same wrong status. Found by auditing ALL 290 fixed-date sanctoral entries against the calendarium; these two were the only status defects in the file. 3 rows in this window: 2026-05-16, 2026-11-13, 2027-11-13. Where colitur now observes the saint the oracle still observes the feria, so rank, observed identity and both citations differ together and the commemoration colitur used to emit is gone. Colour differs only on 13 November, the ferial green giving way to the confessor's white; 16 May is in Paschaltide and already white. Gated on the exact dates and on a subset of that named field list, so a divergence of any other shape on these days would still surface unexplained. Three rows also leave M18 (376 to 373): they were unresolved there only because the observed office was a temporal-origin feria with no English name, and the observed office is now sanctoral and resolves.")
+ (expected_rows 3))
diff --git a/data/ef/expected-divergences.sexp b/data/ef/expected-divergences.sexp
index a863604..9934ff6 100644
--- a/data/ef/expected-divergences.sexp
+++ b/data/ef/expected-divergences.sexp
@@ -90,8 +90,8 @@ Gated on the literal date window (month=12, day in {29,30,31}) AND colitur's own
((id C8)
(citation "RG 87 (Minor Litanies/Rogations, Mon/Tue before Ascension); register §3c item 3")
(verdict colitur)
- (note "Rogation Monday and Tuesday exist as colitur's own ef-rogation-{monday,tuesday} slugs (violet) whenever no higher-ranked saint intervenes. lectio computes no Rogation days at all and shows the plain paschaltide-week-6 feria instead. REFRESHED (ef-rebootstrap fixture refresh, 2026-08-12): expected_rows UNCHANGED at 31 -- lectio's fix wave did not touch Rogation computation at all (not named in any of its seven defects), independently confirmed by re-deriving the count against the refreshed fixture (same Python cross-check as C1/C6, matched the OCaml comparator's own failure output before being set here).")
- (expected_rows 31))
+ (note "Rogation Monday and Tuesday exist as colitur's own ef-rogation-{monday,tuesday} slugs (violet) whenever no higher-ranked saint intervenes. lectio computes no Rogation days at all and shows the plain paschaltide-week-6 feria instead. REFRESHED (ef-rebootstrap fixture refresh, 2026-08-12): expected_rows UNCHANGED at 31 -- lectio's fix wave did not touch Rogation computation at all (not named in any of its seven defects), independently confirmed by re-deriving the count against the refreshed fixture (same Python cross-check as C1/C6, matched the OCaml comparator's own failure output before being set here). CORRECTED, ef-sanctoral-status: 31 -> 26. Five rows left this entry for C38 when `ubaldus` (16 May) was promoted to Feast on the Missal's own calendarium: 16 May can itself be a Rogation Monday or Tuesday, and a III-class feast outranks the Rogation feria, so on those five days colitur's observed office is now the saint and the divergence is C38's, not this entry's. The rows did not stop diverging; their CAUSE changed, and they are filed where the cause is cited.")
+ (expected_rows 26))
((id C14)
(citation "RG 95 (translation is a right of I-class feasts) + RG 96 (the general forward walk, \"the next following day that is not I or II class\") + RG 96's own Attamen (a) (\"festum Annuntiationis ... quando est transferendum post Pascha, transfertur, tamquam in sedem propriam, in feriam II post dominicam in albis\" -- the Annunciation's transferred target is its OWN PROPER SEAT, not a provisional landing spot subject to further re-ordering)")
(verdict colitur)
@@ -114,8 +114,8 @@ CORRECTED, Task 9 (branch ef-lectionary, layer-4 oracle): the 13-vs-7 coincident
(verdict colitur)
(note "ef-bvm-saturday task: colitur now builds RG 91 entry 27's votive Office of the BVM on every otherwise-unoccupied IV-class Saturday (Rite_ef.Temporal_ef's own [bvm_saturday_names] citation has the full argument) -- white (RG 431(e) -> RG 121(a) -> RG 120(b); RG 120(b) alone reads \"de festis\" and this Office is not a festum), unconditionally, overriding the season's own colour (violet in Septuagesima, green in Time after Epiphany/Time after Pentecost; Christmastide and ordinary Paschaltide already happened to be white). lectio builds no equivalent office at all -- checked directly against its own tridentine-calendar.ini/generator, no comparable rule exists there, the same genuine upstream gap C15/C16 above document for their own gaps, not a colitur bootstrap miss -- so it keeps showing the plain season colour on every one of these Saturdays. Season, slug and rank all still agree: temporal_ef.ml's own [bvm_saturday_names] citation (\"Slug\" paragraph) deliberately REUSES the ordinary <season>-<week>-saturday ferial slug rather than minting a new one (partly BECAUSE a bespoke uniform slug would itself have broken Colitur_kernel.Validate's own slug-uniqueness invariant, sighted on every otherwise-unoccupied Saturday in a year), so [Colour_f] alone is the complete diff set every one of these rows carries -- never [Slug_f] too. Gated on colitur's own [rank]=class-4, [weekday]=saturday and [colour]=white (test_differential.ml's own [is_bvm_saturday_row]) rather than a date list, unlike C14/C15/C16 above: RG 78's own condition (\"otherwise unoccupied IV-class Saturday\") reduces exactly to this triple, and the population is large (a substantial fraction of all Saturdays in the 2005-2050 window) and entirely formulaic, not a short, individually-interesting list. Derived directly from the OCaml comparator's own failure output (test_layer_c_counts_match_citations), not hand-counted first and cross-checked after.
-NARROWED, task 8: expected_rows moved 416 -> 406. Not a regression -- 10 of the former 416 rows now ALSO carry [First_f]/[Gospel_f] (C19's own Time-after-Epiphany week-numbering-shift years, 2008/2013/2019/2030/2036/2041/2047, on the specific Saturdays where the BVM office and the week-shift coincide) and so no longer satisfy this entry's own EXACT [diffs = [ Colour_f ]] guard -- they move to C19 instead, which explains the SAME colour divergence plus the week-shift's own citation divergence together. This entry's own guard is intentionally NOT widened to `subset`: doing so would risk silently absorbing a future, unrelated citation bug on an otherwise-ordinary BVM Saturday. Re-derived directly from the OCaml comparator's own failure output: 406. NARROWED (movable-date-specs follow-up, 2026-08-17): 406 -> 397. Nine of these Saturdays are ALSO the Saturday of the week after Trinity Sunday, where colitur now resolves the printed Mass the Missal assigns that week (RG 299 escape clause -- see C35) while lectio still walks back to Trinity. Those rows carry a citation difference as well as this entry own colour one, so they belong to C35 now; split out to a cited entry rather than silently re-absorbed here, the same discipline C15 own split from C1 set. The colour cause is unchanged on all 397 that remain. WIDENED (BVM Saturday Mass, 2026-08-17): 397 -> 445, the entry's scope growing with its cause. colitur has built RG 78's OFFICE since the ef-bvm-saturday task, white where lectio (having no such office) is green. It now also says the MASS that office calls for, RG 309(a)'s iuxta temporum diversitatem selection among the five Missae de sancta Maria in sabbato, where lectio says the feria's. So these days differ on citations as well as colour. One cause, one entry: the predicate admits Colour/First/Gospel together, requires at least one, and keeps its subject=bvm guard, still the only field pinning WHICH celebration is observed since the office deliberately reuses the ferial slug. Rows absorbed from C1, C19 and C25 are those entries' own Saturdays, refiled here rather than left split across two ids for one divergence.")
- (expected_rows 445))
+NARROWED, task 8: expected_rows moved 416 -> 406. Not a regression -- 10 of the former 416 rows now ALSO carry [First_f]/[Gospel_f] (C19's own Time-after-Epiphany week-numbering-shift years, 2008/2013/2019/2030/2036/2041/2047, on the specific Saturdays where the BVM office and the week-shift coincide) and so no longer satisfy this entry's own EXACT [diffs = [ Colour_f ]] guard -- they move to C19 instead, which explains the SAME colour divergence plus the week-shift's own citation divergence together. This entry's own guard is intentionally NOT widened to `subset`: doing so would risk silently absorbing a future, unrelated citation bug on an otherwise-ordinary BVM Saturday. Re-derived directly from the OCaml comparator's own failure output: 406. NARROWED (movable-date-specs follow-up, 2026-08-17): 406 -> 397. Nine of these Saturdays are ALSO the Saturday of the week after Trinity Sunday, where colitur now resolves the printed Mass the Missal assigns that week (RG 299 escape clause -- see C35) while lectio still walks back to Trinity. Those rows carry a citation difference as well as this entry own colour one, so they belong to C35 now; split out to a cited entry rather than silently re-absorbed here, the same discipline C15 own split from C1 set. The colour cause is unchanged on all 397 that remain. WIDENED (BVM Saturday Mass, 2026-08-17): 397 -> 445, the entry's scope growing with its cause. colitur has built RG 78's OFFICE since the ef-bvm-saturday task, white where lectio (having no such office) is green. It now also says the MASS that office calls for, RG 309(a)'s iuxta temporum diversitatem selection among the five Missae de sancta Maria in sabbato, where lectio says the feria's. So these days differ on citations as well as colour. One cause, one entry: the predicate admits Colour/First/Gospel together, requires at least one, and keeps its subject=bvm guard, still the only field pinning WHICH celebration is observed since the office deliberately reuses the ferial slug. Rows absorbed from C1, C19 and C25 are those entries' own Saturdays, refiled here rather than left split across two ids for one divergence. CORRECTED, ef-sanctoral-status: 445 -> 439. Six rows left this entry for C38 when `ubaldus` (16 May) and `didacus` (13 November) were promoted to Feast. RG 78's protasis is an UNOCCUPIED IV-class Saturday; a III-class feast occupies it, so on the six Saturdays those two dates fall on within 2005-2050 the BVM Office is no longer kept at all and the divergence is C38's. Same discipline as C8 above and as C25's own closure: an entry shrinks when its shape stops occurring, rather than silently absorbing rows whose cause has changed.")
+ (expected_rows 439))
((id C18)
(citation "RG 124 (\"XVIII - De coloribus paramentorum\", \"C) De colore rubro\"), both photographic scans word for word: 124(b) \"adhibetur color ruber in Officio et Missa de festis: ... Sanctorum Apostolorum et Evangelistarum, in eorum die natalicio, excepto festo S. Ioannis (27 decembris)\"; 124(e) \"Sanctorum Martyrum, quorum colitur aut martyrium\"; register's own audit rewrite, ef-sanctoral-audit task")
(verdict colitur)
@@ -252,3 +252,8 @@ CORRECTED, fix round 1 (coordinator review, Important 1): this note previously d
(verdict colitur)
(note "ef-oconnell-rubrics branch. The sharpest demonstration in the project of the lineage problem recorded in CLAUDE.md and register 6.20: lectio, missalemeum and colitur all carried the same two wrong colours, because colitur was bootstrapped from lectio, lectio's ini is generated from missalemeum, and missalemeum uses Divinum Officium's data files. Three sources agreeing is one source counted three times. The defect became visible only against witnesses outside that tree -- the Missal's own RG 128 (already transcribed in the register since 2026-08-11, and disagreeing with the shipped data all along), O'Connell, and a published 1962 Ordo. The Ordo is what first flagged the Assumption vigil; O'Connell is what found St Lawrence's, which the Ordo could not give because that source omits the vigil entirely. Gated on the two literal slugs and diffs = [Colour_f] exactly, so a future identity or rank divergence on either day would NOT be absorbed here. 77, not 92: over the fixture's 2005-2050 span each vigil has 46 possible occurrences, and 15 are impeded outright (the vigil yields when its own date falls on a Sunday), so those rows never reach this entry -- both engines agree on the Sunday. Derived from the OCaml comparator's own output, not hand-counted.")
(expected_rows 77))
+ ((id C38)
+ (citation "The 1962 Missal's own universal CALENDARIUM, which is the universal calendar of the Roman rite -- it carries no 'pro aliquibus locis' marker anywhere in its 573 lines, while the wider Missal carries 79 of them elsewhere, so an entry appearing in it is universal by construction. 16 May: 'S. Ubaldi Ep. et Conf., III classis' (docs/research/scan1.txt:2801), corroborated scan2.txt:3197 ('16 S. Ubaldi Ep. et Conf., III cl.'). 13 November: 'S. Didaci Conf., III classis' (scan1.txt:3091), corroborated scan2.txt:3532 ('S. Didaci Conf., III cl.'). Neither carries a Commemoratio rubric; both are bare III-class feasts. Each also has its own Mass entry in the Proprium Sanctorum -- 'Die 16 maii / S. Ubaldi Ep. et Conf. / III classis / Missa Statuit, de Communi Confessoris Pontificis I loco [19], praeter orationem sequentem' (scan1.txt:30196, scan2.txt:33448) and 'Die 13 novembris / S. Didaci Conf. / III classis / Missa Iustus, de Communi Confessoris non Pontificis II loco [25], praeter orationem sequentem' (scan1.txt:40276, scan2 printing the same with its own pagination, '2 loco (26)') -- which a mere commemoration never has, a commemoration carrying only an oration. The published 1962 Ordo (register 6.21) independently lists both as the day's III-class office")
+ (verdict colitur)
+ (note "ef-sanctoral-status branch. Both entries carried rank Class3 with status Commemoration_only, bootstrapped from lectio, which inherits it from missalemeum, which is generated from Divinum Officium -- the same single lineage C37 documents. Found by auditing ALL 290 fixed-date sanctoral entries against the Missal's own calendarium, day by day, anchored on the Roman calends column rather than the OCR-mangled arabic day numbers; ubaldus and didacus were the ONLY two status defects in the whole file, and the 10 days the automated pass could not cover were checked by hand and all agree. That result also narrows a standing register claim: the recorded 'wrongly Commemoration_only' defect was described as a cluster in 6 March - 5 April, and neither of these falls in it, so the cluster was an artefact of where someone looked rather than the defect's extent. Neither saint needed a proper authored: each takes its Mass from a Common with only its own Oratio proper, so this is an assignment in data/ef/commons.sexp, one of them to a Common newly transcribed for it (common-of-a-confessor-not-a-bishop-2, 1 Cor 4:9-14 / Luke 12:32-34, read independently in both scans). 70 rows over 2005-2050, in TWO exact diff shapes the predicate spells out separately rather than collapsing: 32 for ubaldus, where 16 May falls in Paschaltide and the ferial colour is ALREADY white so no colour difference arises, and 38 for didacus, where 13 November is green Time after Pentecost and the white confessor changes it. Not 46 each: the rest of the occurrences are impeded, or the saint loses to a competing office, and both engines then agree. Derived from the OCaml comparator's own output, not hand-counted.")
+ (expected_rows 70))
diff --git a/data/ef/sanctoral.sexp b/data/ef/sanctoral.sexp
index dca4a9b..b460a9e 100644
--- a/data/ef/sanctoral.sexp
+++ b/data/ef/sanctoral.sexp
@@ -740,7 +740,7 @@
(cel
((slug didacus)
(names ((en "St. Didacus") (pl "\197\155w. Dydaka, Wyznawcy")))
- (rank Class3) (status Commemoration_only) (colour White)
+ (rank Class3) (status Feast) (colour White)
(subject Saint) (citations ()) (layer ef-universal))))
((date (Fixed (month 10) (day 9)))
(cel
@@ -3116,7 +3116,7 @@
(names
((en "St. Ubaldus")
(pl "\197\155w. Ubalda, Biskupa i Wyznawcy")))
- (rank Class3) (status Commemoration_only) (colour White)
+ (rank Class3) (status Feast) (colour White)
(subject Saint) (citations ()) (layer ef-universal))))
((date (Fixed (month 5) (day 25)))
(cel
diff --git a/lib/rites/rite_ef/precedence_ef.ml b/lib/rites/rite_ef/precedence_ef.ml
index dd75765..b69ee52 100644
--- a/lib/rites/rite_ef/precedence_ef.ml
+++ b/lib/rites/rite_ef/precedence_ef.ml
@@ -1532,6 +1532,45 @@ let rg110_find_companion comms companion_slug =
codebase's test suite where commemoration order is asserted at all --
flagged here, and in CLAUDE.md's own "know what each layer cannot see"
section, as a genuine, permanent limit, not merely this fix's own gap. *)
+(* RG 113, sentence ONE -- "Commemoratio de Tempore fit primo loco" (the
+ commemoration of the Season is made in the first place), verified in the
+ electronic transcription docs/research/LT.txt and in both photographic
+ scans; register §6.26.
+
+ §4 of the register and this file's own {!admit} already implement RG 113's
+ SECOND sentence ("In admittendis et ordinandis ALIIS commemorationibus,
+ servetur ordo tabellae praecedentiae") as the admission/ordering criterion,
+ adopted on the ef-rg16a branch. The first sentence was never implemented:
+ ordering was by {!band} alone, for every commemoration including the
+ seasonal one.
+
+ RECONCILED WITH RG 110(c), which says the inseparable Peter/Paul pair is
+ added "ante omnes alias commemorationes". The two rubrics share a technical
+ term: RG 113's own sentence fixes the sense of *aliae commemorationes* as
+ "the ones other than the de Tempore commemoration it has just placed primo
+ loco", and RG 110(c) sits three paragraphs earlier in the same code. Read
+ consistently, RG 110(c) puts the pair at the head of the OTHERS, not ahead
+ of the season. Hence this runs AFTER {!rg110_additions}, not before:
+ RG 110(c)'s own "immediate" adjacency (trigger then companion, fix round 1,
+ register §6.3) is preserved by {!List.partition}'s stability, and the
+ seasonal commemoration then steps in front of the pair rather than
+ splitting it.
+
+ [origin] is the exact discriminator the kernel already carries -- a
+ candidate is {!Precedence.Temporal} iff it came from the rite's temporal
+ cycle, which is what "de Tempore" means. Measured over 1583-9999, no day
+ ever carries more than one such commemoration (RG 112(c), "an Office, Mass
+ or commemoration of the season excludes another seasonal commemoration",
+ holding empirically), so this promotes at most one entry; [partition] is
+ used rather than a find-and-move so the zero case and the never-observed
+ many case are both total without a special branch. *)
+let rg113_season_first
+ (comms : (Vocab_ef.rank Precedence.candidate * Precedence.privilege) list) :
+ (Vocab_ef.rank Precedence.candidate * Precedence.privilege) list =
+ let de_tempore (c, _) = c.Precedence.origin = Precedence.Temporal in
+ let seasonal, others = List.partition de_tempore comms in
+ seasonal @ others
+
let rg110_additions (comms : (Vocab_ef.rank Precedence.candidate * Precedence.privilege * int) list)
~(observed : Vocab_ef.rank Precedence.candidate)
(normal : (Vocab_ef.rank Precedence.candidate * Precedence.privilege) list) :
@@ -1702,7 +1741,7 @@ let admit ~(observed : Vocab_ef.rank Precedence.candidate)
as the non-Sunday II-class case, just with room for two. *)
List.map drop_band (take 2 sorted)
in
- rg110_additions comms ~observed normal
+ rg113_season_first (rg110_additions comms ~observed normal)
(* Task 11: RG 96 -- where an impeded I-class feast lands (docs/research/
rules-register.md §4, "Transfer/translation"). [band] decides who is
diff --git a/test/test_differential.ml b/test/test_differential.ml
index 849bde4..25a690d 100644
--- a/test/test_differential.ml
+++ b/test/test_differential.ml
@@ -912,6 +912,19 @@ let good_friday_slug = "ef-passiontide-2-friday"
Paschaltide and is correctly white already. *)
let violet_vigil_slugs = [ "vigil-of-st-lawrence"; "vigil-of-the-assumption" ]
+(* C38 (ef-sanctoral-status): `ubaldus` (16 May) and `didacus` (13 November)
+ were promoted from Commemoration_only to Feast on the Missal's own
+ universal calendarium, which ranks both "III classis" outright. lectio
+ inherits the Commemoration_only status from missalemeum, so where colitur
+ now observes the saint, lectio still observes the feria -- hence the slug,
+ rank and both citations differ together. Two exact shapes, not one:
+ 16 May falls in Paschaltide, whose ferial colour is ALREADY white, so no
+ colour difference arises there; 13 November is Time after Pentecost, green,
+ so the white confessor changes it. Both shapes are spelled out rather than
+ collapsed into a subset check, so a colour difference appearing on 16 May
+ (or vanishing on 13 November) would surface as unexplained. *)
+let promoted_feast_slugs = [ "ubaldus"; "didacus" ]
+
(* C26 (task 8, fix round 2, coordinator review, Important): Passion
week's own real Tuesday Mass (tools/bootstrap_lectionary.ml's own
[passion_tuesday_entry] comment has the full Missal citation and both
@@ -1294,6 +1307,11 @@ let layer_c_reason (l : row) (c : row) diffs =
else if String.equal c.slug good_friday_slug && diffs = [ First_f; Gospel_f; Colour_f ] then
Some "C36"
else if List.mem c.slug violet_vigil_slugs && diffs = [ Colour_f ] then Some "C37"
+ else if
+ List.mem c.slug promoted_feast_slugs
+ && (diffs = [ Slug_f; Rank; First_f; Gospel_f ]
+ || diffs = [ Slug_f; Rank; First_f; Gospel_f; Colour_f ])
+ then Some "C38"
else if List.mem c.slug holy_week_slugs && diffs = [ First_f; Gospel_f ] then Some "C23"
else if String.equal c.slug passion_tuesday_slug && diffs = [ First_f; Gospel_f ] then Some "C26"
else if String.equal c.slug advent_ember_sat_slug && diffs = [ First_f; Gospel_f ] then Some "C27"
diff --git a/test/test_lectionary_ef.ml b/test/test_lectionary_ef.ml
index a5a0f6e..d56d187 100644
--- a/test/test_lectionary_ef.ml
+++ b/test/test_lectionary_ef.ml
@@ -442,11 +442,21 @@ let test_step4_assignment_table () =
Alcotest.(check (list (pair string string)))
"the Commons assignment table, exactly"
[ ("benedict", "common-of-abbots");
+ ("didacus", "common-of-a-confessor-not-a-bishop-2");
("frances-rome", "common-of-non-virgins-2");
("gregory-the-great", "common-of-supreme-pontiffs");
("isidore-of-seville", "common-of-doctors");
("patrick", "common-of-a-confessor-bishop-1");
+ (* ef-sanctoral-status: ubaldus and didacus were promoted from
+ Commemoration_only to Feast on the Missal's own universal
+ calendarium, which ranks both "III classis" outright with no
+ commemoration rubric. Each takes its Mass from a Common with only
+ its own Oratio proper, per its own rubric at its own date, so
+ neither needed a proper authored -- only an assignment. ubaldus
+ shares patrick's Common exactly ("Missa Statuit, de Communi
+ Confessoris Pontificis I loco"). *)
("sts-felicitas-perpetua", "common-of-non-virgins-1");
+ ("ubaldus", "common-of-a-confessor-bishop-1");
("vincent-ferrer", "common-of-a-confessor-not-a-bishop-1") ]
assigned
diff --git a/test/test_oracle.ml b/test/test_oracle.ml
index 129c43b..7ee3848 100644
--- a/test/test_oracle.ml
+++ b/test/test_oracle.ml
@@ -1334,6 +1334,20 @@ let m25_dates = [ "2026-03-09"; "2026-03-24"; "2027-03-01"; "2027-03-16" ]
fix seen from the lectio side, and register 6.20 on the shared lineage.
Spans all three oracle windows. 2026-08-09 is absent because it is a
Sunday that year and the vigil never occurs; checked with `date -d`. *)
+(* M30 (ef-sanctoral-status) -- `ubaldus` (16 May) and `didacus` (13 Nov),
+ promoted from Commemoration_only to Feast on the Missal's own universal
+ calendarium ("III classis" outright, no commemoration rubric, and a Mass
+ entry of their own in the Proprium). missalemeum keeps them as
+ commemorations, so on these days colitur observes the SAINT where the
+ oracle observes the feria: rank, observed identity and both citations
+ differ together, and the commemoration colitur used to emit is gone.
+ Colour differs only on 13 November, where the ferial green gives way to
+ the confessor's white; 16 May is in Paschaltide, already white. The same
+ population as C38 in the lectio differential -- and, as there, the oracle
+ here is colitur's own discarded ancestor rather than an independent
+ witness (register 6.20). *)
+let m30_dates = [ "2026-05-16"; "2026-11-13"; "2027-11-13" ]
+
let m29_dates =
[ "2026-08-14"; "2027-08-09"; "2027-08-14"; "2035-08-09"; "2035-08-14"; "2038-08-09";
"2038-08-14" ]
@@ -1493,6 +1507,11 @@ let layer_m_reason (c : colitur_row) (o : oracle_row) diffs =
&& subset diffs [ Observed_identity_unresolved; First_mismatch; Gospel_mismatch ]
then Some "M27"
else if List.mem c.c_date m29_dates && subset diffs [ Colour_f ] then Some "M29"
+ else if List.mem c.c_date m30_dates
+ && subset diffs
+ [ Rank; Colour_f; Comm_presence; Comm_count; Observed_identity_mismatch;
+ Comm_identity_unresolved; First_mismatch; Gospel_mismatch ]
+ then Some "M30"
else None
(* ---------------------------------------------------------------------- *)
@@ -1844,7 +1863,19 @@ let classify_2038 (c : colitur_row) (o : oracle_row) diffs =
nh = 0 || at 0
in
let first_is s = match c.c_first with Some f -> contains f s | None -> false in
- if contains title "Mass of the B. V. M." then Some "BVM-SATURDAY-MASS (M26 shape 1)"
+ (* ef-sanctoral-status: `didacus`, promoted to Feast on the Missal's own
+ calendarium. 13 November 2038 is a SATURDAY, so before the promotion the
+ day kept RG 78's votive Office of the BVM (nothing else occupied it) and
+ after it the III-class feast does. Classified here explicitly, ahead of
+ every other branch, because without it the day falls through to the
+ BVM-Saturday branch and is labelled as the very office the promotion
+ REMOVED -- a label that would read as "still a BVM Saturday" and hide the
+ real cause. Same population as M30 in the 2026-2027 window and C38 in the
+ lectio differential. 16 May 2038 is a Sunday, so `ubaldus` is impeded and
+ never reaches this window at all. *)
+ if c.c_date = "2038-11-13" then
+ Some "PROMOTED-FEAST-RG-CALENDARIUM (M30, colitur; see C38)"
+ else if contains title "Mass of the B. V. M." then Some "BVM-SATURDAY-MASS (M26 shape 1)"
else if first_is "Col 1:12-20" then Some "CHRIST-THE-KING-WEEK (M26 shape 2b)"
else if diffs = [ Colour_f ] && List.mem c.c_observed_slug m21_2038_slugs then Some "COLOUR (M21)"
else if first_is "Judith" then Some "JUDITH (M28, register 6.6)"
@@ -2069,6 +2100,10 @@ let test_2038_class_counts () =
Paschaltide. 2 of 2 possible -- neither 9 nor 14 August 2038 is a
Sunday, so both vigils are actually observed that year. *)
("VIGIL-COLOUR-RG128 (M29, colitur; see C37)", 2);
+ (* ef-sanctoral-status: 13 November 2038 is a Saturday, so the
+ promoted `didacus` displaces RG 78's BVM Office there. 1 of 2
+ possible: 16 May 2038 is a Sunday and `ubaldus` is impeded. *)
+ ("PROMOTED-FEAST-RG-CALENDARIUM (M30, colitur; see C38)", 1);
("COMM-NAME-FORM (same entity, different English name)", 2);
("COMM-ONLY-TIE-BREAK (RG-under-determined convention -- register 6.16)", 1);
("JOSEPH-ANNUNCIATION-TRANSFER-ORDER (C14's own collision)", 2);
diff --git a/test/test_precedence_ef.ml b/test/test_precedence_ef.ml
index 790dab6..3f3e070 100644
--- a/test/test_precedence_ef.ml
+++ b/test/test_precedence_ef.ml
@@ -1170,12 +1170,40 @@ let unrelated_comm_synth =
contest; it adds Paul regardless. *)
let lent_feria_synth = (cand ~origin:P.Temporal ~rank:V.Class3 "ef-lent-2-monday-synth", P.Privileged, 180)
+(* RG 113 sentence ONE (docs/research/rules-register.md §6.26):
+ "Commemoratio de Tempore fit primo loco." The commemoration OF THE SEASON
+ is made in the first place; the second sentence's table order governs the
+ OTHERS. Every other candidate in this table is [origin = P.Temporal] by
+ [cand]'s own default, so the rule is an identity on them and no existing
+ row's expectation moves; these two candidates exist to make a MIXED-origin
+ row possible, which is the only shape that can witness it.
+
+ This file's [admit_cases] is the ONLY place in the whole suite that
+ asserts commemoration ORDER -- the differential never compares
+ commemorations, the oracle sorts both sides into a multiset, and
+ test_golden.ml's own [describe] deliberately sorts its comms field. So a
+ row here is the only thing standing between this rule and a silent
+ regression. *)
+let sanctoral_hi =
+ { (cand ~rank:V.Class2 "ef-sanctoral-hi") with P.origin = P.Sanctoral }
+
+let seasonal_lo = cand ~rank:V.Class3 "ef-seasonal-lo"
+
let admit_cases =
[ (* RG 111 (§4): "I class: none save one privileged." *)
( "I-class day, only an ordinary commemoration due -> none admitted",
observed_class1, observed_class1,
[ po ordinary_hi P.Ordinary ],
[] );
+ (* RG 113 s1: the de Tempore commemoration leads, even though the
+ sanctoral one outranks it on RG 91's table (Class2 beats Class3) and
+ would therefore come first under sentence TWO alone. Both slots of a
+ III-class day are filled, so this row tests ORDER, not selection. *)
+ ( "III-class day, seasonal + sanctoral both admitted -> the SEASONAL one \
+ first (RG 113 s1), despite the sanctoral one's higher table position",
+ observed_class3, observed_class3,
+ [ po sanctoral_hi P.Ordinary; po seasonal_lo P.Ordinary ],
+ [ "ef-seasonal-lo"; "ef-sanctoral-hi" ] );
( "I-class day, ordinary + privileged both due -> only the privileged \
one, regardless of the ordinary one's higher dignity",
observed_class1, observed_class1,
diff --git a/test/test_sanctoral_ef.ml b/test/test_sanctoral_ef.ml
index ebf96dc..5c46edf 100644
--- a/test/test_sanctoral_ef.ml
+++ b/test/test_sanctoral_ef.ml
@@ -47,7 +47,13 @@ let test_load_and_counts () =
let commemoration_only =
List.filter (fun e -> e.L.cel.Cel.status = Cel.Commemoration_only) l.L.entries
in
- Alcotest.(check int) "104 Commemoration_only" 104 (List.length commemoration_only);
+ (* 102, not 104: ef-sanctoral-status promoted `ubaldus` (16 May) and
+ `didacus` (13 November) to Feast. Both are ranked "III classis" outright
+ in the Missal's own universal calendarium, with no commemoration rubric,
+ and both have their own Mass entry in the Proprium taking its readings
+ from a Common. They were the ONLY two defects found by auditing all 290
+ fixed-date entries against that calendarium -- see the register. *)
+ Alcotest.(check int) "102 Commemoration_only" 102 (List.length commemoration_only);
let class1 = List.filter (fun e -> e.L.cel.Cel.rank = V.Class1) l.L.entries in
Alcotest.(check int) "12 Class1" 12 (List.length class1);
let temporal_subjects = List.filter (fun e -> e.L.cel.Cel.subject = Sub.Temporal) l.L.entries in