aboutsummaryrefslogtreecommitdiff
path: root/test/test_oracle.ml
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_oracle.ml')
-rw-r--r--test/test_oracle.ml74
1 files changed, 67 insertions, 7 deletions
diff --git a/test/test_oracle.ml b/test/test_oracle.ml
index 1ad4b1f..1e724b8 100644
--- a/test/test_oracle.ml
+++ b/test/test_oracle.ml
@@ -802,6 +802,50 @@ let m20_commemoration_matches (c : colitur_row) =
colitur. *)
let m8_dates = [ "2026-11-01"; "2027-08-15" ]
+(* M28 -- the 1962 Missal's own two Judith citations, primary-source-verified
+ against the photographic scans this task (branch ef-lectionary) read
+ directly, after a live-missalemeum full-year sweep surfaced them:
+
+ Assumption (15 Aug) scan1:35357, under "IN ASSUMPTIONE BEATAE
+ MARIAE VIRGINIS" -- "Iudith 13, 22-25; 15, 10"
+ Seven Sorrows (15 Sep) scan1:36938, corroborated independently at
+ scan1:28468 -- "Iudith 13, 22 et 23-25"
+
+ Both engines used to carry a chapter-carry-over defect here: lectio's own
+ generator emitted "Judith 13:22-25; 13:15; 13:10" for the Assumption
+ (inventing two verses out of the second citation's own "15, 10" by
+ re-applying chapter 13) and "Judith 13:22; 13:25" for the Seven Sorrows
+ (dropping the "et 23-" range). colitur inherited both through its own
+ bootstrap -- the "Holy Thursday was violet in both" shared-lineage shape
+ this project's own CLAUDE.md names, and the reason layer 3 could never
+ have found this: lectio IS the other side of that comparison. Fixed
+ upstream in lectio (v0.46.1+) and re-bootstrapped here; missalemeum
+ still serves the defective form, so the divergence is now visible on
+ layer 4 and adjudicated colitur.
+
+ The predicate pins BOTH sides literally, not merely the diff shape -- the
+ C6/C14 failure mode this file's own header documents (a date-and-shape
+ gate that would silently swallow a DIFFERENT citation divergence landing
+ on the same date). It is also the first reader of [layer_m_reason]'s own
+ oracle-row parameter since M2 closed; that parameter was deliberately
+ kept named and typed for exactly this ("so a FUTURE oracle-title
+ predicate has somewhere to plug back in without a signature change"). *)
+let judith_divergence (c : colitur_row) (o : oracle_row) =
+ match (c.c_first, o.o_first) with
+ (* Assumption *)
+ | Some "Judith 13:22-25; 15:10", Some "Judith 13:22-25; 13:15; 13:10" -> true
+ (* Seven Sorrows *)
+ | Some "Judith 13:22; 13:23-25", Some "Judith 13:22; 13:25" -> true
+ | _ -> false
+
+(* 2027-08-15 is deliberately ABSENT here: it carries this divergence AND
+ M8's own, independently-caused one (the Assumption falls on a Sunday that
+ year), and the classifier admits one entry per day. It is accounted under
+ M8, whose own gate names this predicate explicitly rather than widening
+ to [First_mismatch] blindly -- neither cause is silently absorbed into
+ the other, the same discipline C15's own split from C1 already set. *)
+let m28_dates = [ "2026-08-15"; "2026-09-15"; "2027-09-15" ]
+
(* M9 -- REMOVED, ef-rebootstrap (2026-08-12): see data/ef/expected-
divergences-missalemeum.sexp's own "FIVE MORE REMOVED" note. St
Theodore (9 Nov) is now present in data/ef/sanctoral.sexp (theodore),
@@ -1277,12 +1321,14 @@ let m26_dates =
citation fields are not, discovered by this task). *)
let m27_dates = [ "2026-12-25"; "2027-12-25" ]
-(* [_o] (the oracle's own row) is unused now that M2 -- its one reader, via
- [o.o_title] -- is closed/removed (see the comment above [m1_dates]):
- every remaining predicate below reads only [c]/[diffs]. Kept as a named,
- typed parameter (not dropped from the signature) so a FUTURE oracle-title
- predicate has somewhere to plug back in without a signature change. *)
-let layer_m_reason (c : colitur_row) (_o : oracle_row) diffs =
+(* The oracle's own row went unused when M2 -- its one reader, via
+ [o.o_title] -- was closed/removed (see the comment above [m1_dates]), and
+ was kept as a named, typed parameter rather than dropped from the
+ signature "so a FUTURE oracle-title predicate has somewhere to plug back
+ in without a signature change". Task 9 (branch ef-lectionary) is that
+ future: {!judith_divergence} pins the ORACLE's own citation as well as
+ colitur's, so the parameter is live again and no longer underscored. *)
+let layer_m_reason (c : colitur_row) (o : oracle_row) diffs =
if diffs = [] then None
(* M1's own subset widened (this task): colitur's observed day on both
dates is TEMPORAL-origin (the Sunday itself, RG33's own point -- the
@@ -1312,7 +1358,21 @@ let layer_m_reason (c : colitur_row) (_o : oracle_row) diffs =
Some "M3"
else if List.mem c.c_date m5_dates && diffs = [ Comm_identity_mismatch ] && m5_commemoration_matches c then
Some "M5"
- else if List.mem c.c_date m8_dates && diffs = [ Comm_presence ] then Some "M8"
+ (* M8's own gate widened, Task 9 fix (branch ef-lectionary): 2027-08-15 is
+ BOTH an impeded-Sunday day (M8's own cause) and a Judith-citation day
+ (M28's), and the classifier admits one entry per day. [Comm_presence]
+ stays REQUIRED -- M8's own divergence must actually be present, so this
+ can never degrade into a bare citation gate -- and [First_mismatch] is
+ admitted only when it is exactly the M28 shape, both sides pinned. A
+ citation divergence of any OTHER shape, on either M8 date, still
+ escapes to unexplained. *)
+ else if
+ List.mem c.c_date m8_dates
+ && subset diffs [ Comm_presence; First_mismatch ]
+ && List.mem Comm_presence diffs
+ && ((not (List.mem First_mismatch diffs)) || judith_divergence c o)
+ then Some "M8"
+ else if List.mem c.c_date m28_dates && diffs = [ First_mismatch ] && judith_divergence c o then Some "M28"
else if List.mem c.c_date m10_dates && diffs = [ Comm_presence ] then Some "M10"
else if List.mem c.c_date m11_dates && diffs = [ Comm_presence ] then Some "M11"
(* M13's own subset widened AGAIN (this task, following the SAME pattern