summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-08-12 04:12:41 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-08-12 04:12:41 +0200
commit079e332e0a797105588787f7e5fdabd95ba1fa12 (patch)
tree1cf2881355296a5e8ee43583e52185247977ece1 /test
parentefc1b303417388c75f27403952b506dc4d4e03d7 (diff)
downloadcolitur-079e332e0a797105588787f7e5fdabd95ba1fa12.tar.gz
colitur-079e332e0a797105588787f7e5fdabd95ba1fa12.zip
kernel(precedence): three RG-verified EF precedence bugs, found via oracle
Task 16's missalemeum oracle comparison (2026-2027) surfaced three distinct precedence-engine bugs, each confirmed against the primary 1962 Missale Romanum text and cross-checked against the oracle: 1. RG 33 (vigil omission) was transcribed backwards. The primary text reads "Vigilia II AUT III classis penitus omittitur" (a II OR III class vigil is entirely omitted on any Sunday or I-class feast) -- not "I aut II" as the register and this module's own rank check (Class1 || Class2) previously had it. I-class vigils (Nativity, Pentecost) can never actually lose in this engine (band always ranks them above anything that could coincide with their dates), so the Class1 half was dead code; the real bug was that Class3 (St Lawrence's vigil, the sole III-class vigil) was MISSING, so it fell through to an ordinary commemoration instead of RG 33's mandatory omission whenever 9 August landed on a Sunday. 2. RG 93/95/109/113 read together: an ordinary, non-privileged TEMPORAL-cycle office (a bog-standard green-season feria, a plain Advent/Lent Ember day, a Minor Rogation day) has no standing to be commemorated at all when impeded -- RG 109's six-item list is a CLOSED set of the only temporal circumstances that generate a commemoration, not a floor under which anything ordinary still gets one. The engine previously commemorated the losing feria itself in this situation; confirmed wrong against ~190 independent missalemeum days (2026-2027) showing zero commemorations for the exact shape. Vigils are explicitly excluded from this new rule -- RG 31/32 give them their own "if impeded, commemorated" mandate, independent of RG 109's list. 3. RG 111(b)'s Sunday admission slot is restricted to "de festo II classis" -- a rank restriction, not merely the best available ordinary candidate. A III/IV-class ordinary saint competing for a II-class Sunday's single commemoration slot had no such restriction applied before; confirmed wrong via St Hyginus (11 Jan, Class3) losing to Holy Family, which missalemeum shows entirely displaced, never commemorated. All three fixes are pure disposition/admission changes -- they never touch band, so the observed day (season/slug/rank/colour) is unaffected in every case; the lectio differential (which never compares commemorations) stays green untouched. test_precedence_ef.ml updated throughout: two previously-wrong test expectations corrected (the RG33 III-class-vigil boundary row, the IV-class-feria totality row), three privilege boundary rows sharpened from "commemorated but unprivileged" to "omitted entirely" now that temporal+ordinary means omission, and a new contrast row added to keep the SANCTORAL side of rule 2 covered separately from the TEMPORAL side.
Diffstat (limited to 'test')
-rw-r--r--test/test_precedence_ef.ml93
1 files changed, 76 insertions, 17 deletions
diff --git a/test/test_precedence_ef.ml b/test/test_precedence_ef.ml
index aa98686..2f08864 100644
--- a/test/test_precedence_ef.ml
+++ b/test/test_precedence_ef.ml
@@ -375,17 +375,34 @@ let disposition_cases =
of_temporal (off 38),
"Omit" );
(* RG 33's own boundary, proved from both sides so the rule is shown to
- gate on the WINNER too, not "any vigil is always omitted": *)
+ gate on the WINNER too, not "any vigil is always omitted": winner is
+ neither a Sunday nor I class, so RG 33's omission does not fire; the
+ vigil is temporal-origin ({!of_temporal}, the real Ascension Vigil)
+ and would otherwise land in Task 16's new "ordinary temporal loser ->
+ Omit" branch too (see the IV-class-feria row further down) -- this
+ row is what proves that branch's own [not (is_vigil ...)] guard: a
+ vigil, per RG 31's own text ("si impediuntur, commemorantur"), is
+ ALWAYS commemorated once RG 33 does not omit it outright, regardless
+ of RG 109's closed list. *)
( "RG33 boundary: vigil loses to an ordinary (non-Sunday, non-I-class) \
- II-class day -> Commemorate, NOT Omit",
+ II-class day -> Commemorate, NOT Omit (RG31's own vigil mandate)",
cand ~origin:P.Sanctoral ~rank:V.Class2 ~layer:PE.universal_layer "ef-some-other-feast",
of_temporal (off 38),
"Commemorate(Ordinary)" );
- ( "RG33 boundary: a III-class vigil (outside RG33's I/II-class scope) \
- loses to a Sunday -> Commemorate, NOT Omit",
+ (* CORRECTED 2026-08-12 (Task 16, primary-source-verified): the register
+ previously (mis-)transcribed RG 33 as covering only I/II-class
+ vigils, so this row's own title used to read "outside RG33's
+ I/II-class scope" and expect Commemorate. The primary text ("Vigilia
+ II AUT III classis penitus omittitur...") covers II OR III class --
+ St Lawrence's vigil (III class, RG 32) falling on ANY Sunday ("in
+ dominica quavis") is entirely omitted, exactly like a II-class vigil.
+ See {!PE.is_omissible_vigil}'s own comment for the full primary text
+ and the register correction. *)
+ ( "RG33 (corrected): a III-class vigil loses to a Sunday -> Omit, not \
+ Commemorate",
an_ordinary_sunday,
cand ~origin:P.Sanctoral ~rank:V.Class3 ~layer:PE.universal_layer "ef-lawrence-vigil",
- "Commemorate(Ordinary)" );
+ "Omit" );
(* Task 11, issue (a): [disposition]'s own [is_vigil] check (the RG 33
omission test) is a SEPARATE call site from [band]'s -- both read the
same private [is_vigil], but each needed its own witness, since a fix
@@ -424,16 +441,45 @@ let disposition_cases =
cand ~origin:P.Sanctoral ~status:Cel.Commemoration_only ~layer:PE.universal_layer
"ef-suppressed-vigil",
"Commemorate(Privileged)" );
- (* Totality: the lower ranks the RG 33/RG 95 branches never touch still
- reach the RG 95 "commemorated or omitted" branch, not an
- unhandled/exceptional case. *)
+ (* Totality (SANCTORAL side): the lower ranks the RG 33/RG 95/Task-16
+ branches never touch still reach the RG 95 "commemorated or omitted"
+ branch's [Commemorate] side, not an unhandled/exceptional case -- RG
+ 111(c)/(d) admit an "ordinary" SAINT commemoration freely, with none
+ of RG 109's closed-list restriction the temporal branch below has. *)
( "III-class feast loses to a I-class day -> Commemorate",
cand "ef-nativity",
cand ~origin:P.Sanctoral ~rank:V.Class3 ~layer:PE.universal_layer "ef-some-saint-3",
"Commemorate(Ordinary)" );
- ( "IV-class feria loses to a II-class Sunday -> Commemorate",
+ (* Task 16 (primary-source-verified: RG 95 + RG 109's closed list + RG
+ 113 -- see this branch's own comment in precedence_ef.ml for the full
+ three-text argument): an ORDINARY, non-privileged TEMPORAL-cycle
+ loser -- a bog-standard green-season feria of Time after Pentecost,
+ none of RG 109(a)-(f) -- has NO standing to be commemorated at all
+ when impeded; it is entirely omitted, not the "ordinary"
+ commemoration a losing SAINT would get (contrast the SANCTORAL row
+ immediately above, same rank, same kind of winner, opposite
+ [Commemorate]/[Omit] outcome -- the discriminating factor is
+ [origin], nothing else). Before this fix the engine wrongly
+ commemorated the losing feria itself here; confirmed wrong against
+ the missalemeum oracle (Task 16 report): every one of ~190
+ structurally identical days (an ordinary sanctoral feast impeding an
+ ordinary temporal feria, 2026-2027) shows zero commemorations in an
+ independent published EF calendar. *)
+ ( "TASK16: an ORDINARY temporal feria loses to a II-class Sunday -> \
+ Omit, not Commemorate (RG109's closed list; contrast the sanctoral \
+ row above)",
an_ordinary_sunday,
cand ~rank:V.Class4 "ef-time-after-pentecost-1-sat",
+ "Omit" );
+ (* Totality's other half: a SANCTORAL loser of the exact same rank as
+ the row above still reaches [Commemorate], proving the branch above
+ is gated on [origin] and not merely on rank -- without this row nothing
+ here would distinguish "temporal losers are omitted" from "IV-class
+ losers are omitted", which would be a much bigger (and wrong) claim. *)
+ ( "TASK16 contrast: a SANCTORAL IV-class loser still reaches \
+ Commemorate(Ordinary)",
+ an_ordinary_sunday,
+ cand ~origin:P.Sanctoral ~rank:V.Class4 ~layer:PE.universal_layer "ef-some-minor-saint",
"Commemorate(Ordinary)" )
]
@@ -506,29 +552,42 @@ let privilege_cases =
already used by the entry-18 [band] row above. Both sourced from
[Temporal_ef.temporal]. If [privilege_of] relied on the season prefix
alone without excluding Ember slugs, both would wrongly come back
- [Privileged] -- the exact trap this pair of rows guards against. *)
+ [Privileged] -- the exact trap this pair of rows guards against.
+
+ CHANGED, Task 16: these used to expect [Commemorate(Ordinary)] --
+ "not privileged" originally meant "commemorated, but without RG 109's
+ higher liturgical honours". Now that a TEMPORAL-origin [Ordinary]
+ loser is Task 16's own [Omit] branch (see precedence_ef.ml), "not
+ privileged" for a temporal candidate means "not commemorable at all"
+ -- a sharper, more direct assertion of the same underlying
+ [privilege_of] classification, via the one vantage point available
+ on that private function. *)
( "boundary: an Advent Ember day is NOT privileged (only September is, \
- RG109(d))",
+ RG109(d)) -- and being temporal+ordinary, TASK16 omits it entirely",
cand "ef-nativity",
of_temporal (mk 2026 12 16),
- "Commemorate(Ordinary)" );
+ "Omit" );
( "boundary: a Lent Ember day is NOT privileged (only September is, \
- RG109(d))",
+ RG109(d)) -- and being temporal+ordinary, TASK16 omits it entirely",
cand "ef-nativity",
of_temporal (off (-39)),
- "Commemorate(Ordinary)" );
+ "Omit" );
(* Negative, RG 109(f)'s own boundary: the Minor Litanies/Rogations
(Monday/Tuesday before Ascension, RG 87 -- [Temporal_ef.temporal]
DOES compute these, unlike the Major Litanies RG 109(f) actually
names, see [privilege_of]'s own comment) must NOT be mistaken for the
Major Rogations RG 109(f) privileges: RG 88 says the Minor Rogations
change nothing in the Office at all, so nothing about them is
- privileged either. *)
+ privileged either -- and (Task 16) being temporal+ordinary, a Minor
+ Rogation day impeded by a saint is now omitted outright, matching the
+ missalemeum oracle exactly (Task 16 report: 11 May 2026 and 12 May
+ 2026, both Minor Rogation days impeded by a saint, show zero
+ commemoration of the Rogation in the independent oracle). *)
( "boundary: a Minor Rogation day is NOT privileged (RG109(f) names \
- the Major Litanies, not these)",
+ the Major Litanies, not these) -- TASK16 omits it entirely",
cand "ef-nativity",
of_temporal (off 36),
- "Commemorate(Ordinary)" )
+ "Omit" )
]
(* Task 9: [PE.admit] -- RG 111's admission counts (register line 378),