summaryrefslogtreecommitdiff
path: root/test/test_lectionary.ml
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-08-17 12:28:03 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-08-17 12:28:03 +0200
commit8d1eb25a311e16ddb7bf89d2b21fb1ca0aa058a7 (patch)
tree9c72d1c30f0f37ef7138325abb3ca26ebe68ff14 /test/test_lectionary.ml
parent9947a28f3a40bd8ac36892dcf5aad59d9e6f847c (diff)
downloadcolitur-8d1eb25a311e16ddb7bf89d2b21fb1ca0aa058a7.tar.gz
colitur-8d1eb25a311e16ddb7bf89d2b21fb1ca0aa058a7.zip
test(oracle): compare reading citations against missalemeum
Layer 4 (test_oracle.ml) now extracts and compares the Epistle/Gospel citation for every one of the 730 days in the 2026-2027 fixture, the same axis Task 8 already added to layer 3. tools/ extract_missalemeum_oracle.py gained a structural citation-span detector (the first "*...*"-wrapped span under 40 chars containing a chapter:verse-shaped digit pair), verified exhaustively over all 1 458 Lectio/Evangelium sections. 728 of 730 days are comparable; the 2 that are not (Good Friday, both years) have no such section in missalemeum's own JSON at all -- a structural limit on the oracle's own side (M23), not a colitur gap. 451 of 730 days differ and are all explained across 19 cited entries; 0 unexplained. Chain step 4 (the Commons) has no layer-4 witness: confirmed empirically (a scratch sweep, not merely re-asserted from Task 6's own report) that none of the 15 Commons/proper saints is ever the observed office in this window. The comparison surfaced three genuine colitur bugs in data/ef/lectionary.sexp, all fixed at the source in tools/bootstrap_lectionary.ml: 1. Holy Name of Jesus (ef-holy-name-sunday/ef-holy-name) carried a mis-derived citation, borrowed by analogy from an unrelated ini section ("ef-christmas-sunday-0", the Sunday-within-the-Octave's own Mass) on the wrong assumption the two share a Mass. Disproved by missalemeum's own extraction for both real Holy Name Sundays in its window, confirmed against the Missal itself, twice, both scans (Acts 4:8-12/Luke 2:21, not Gal 4:1-7/Luke 2:33-40). 2. RG 17(a)'s own "diebus ferialibus" rubric (immediately following the Holy Name heading, both scans) was never implemented: 2-5 January ferias repeat 1 January's Mass, 7-12 January ferias before Holy Family Sunday repeat Epiphany's, and Holy Family's own week has a named formula ("Missa Dominicae Primae post Epiphaniam"). All three fell to step 3's undifferentiated Sunday walkback instead. Fixed for three 5-weekday families, deliberately excluding Saturday from all three -- RG 78's BVM Saturday Office wins there unconditionally, confirmed against missalemeum's own title on this window's own such Saturdays. 3. Corpus Christi and Sacred Heart (both real, never-impeded I-class movable feasts) had no lectionary entry at all. Both engines independently fell back to Trinity Sunday's own citation and silently agreed on the wrong answer -- the "Holy Thursday violet in both" shape CLAUDE.md names for exactly this reason. Because lectionary.sexp is shared with layer 3 (the lectio differential, 2005-2050), these fixes changed colitur's output for the whole domain, not only 2026-2027. data/ef/expected-divergences.sexp and test_differential.ml needed matching updates: C1 narrowed 361->173 and C25 narrowed 57->13 (rows that now resolve correctly moved to new entries), C16's note corrected (count unchanged), and six new entries added (C29-C34, 397 rows total, all verdict colitur). test_lectionary.ml and test_lectionary_ef.ml's own pins were updated to match (entry count 131->148; one step-3 regression test re-pointed to a date that still genuinely exercises that step). One entry, M26 (30 rows, verdict open), is a genuine unfixed gap: colitur's step-3 "resume the preceding Sunday" fallback is its only ferial-Mass mechanism, and missalemeum's own selection is more granular in three confirmed ways (a rotating votive Mass of the BVM, a named weekly formula for at least one week, and later Time-after-Pentecost weeks this task's own investigation did not narrow to a single rule) -- the same "needs a season-keyed selection mechanism, new behaviour not new data" shape data/ef/expected-divergences.sexp's own C6/C25 and Task 6's own residual concern already name, out of this task's own scope to build. dune test: 358 tests green. COLITUR_EXHAUSTIVE_SWEEP=1 dune test --force: 359 tests green, 89.5s.
Diffstat (limited to 'test/test_lectionary.ml')
-rw-r--r--test/test_lectionary.ml93
1 files changed, 69 insertions, 24 deletions
diff --git a/test/test_lectionary.ml b/test/test_lectionary.ml
index 3fbf8c5..a6ca334 100644
--- a/test/test_lectionary.ml
+++ b/test/test_lectionary.ml
@@ -85,30 +85,38 @@ let test_ef_data_file_loads () =
own Temporal_ef vocabulary, PLUS hand-authored/derived entries
(tools/bootstrap_lectionary.ml's own [colitur_keys]/
[vigil_entries]/[holy_week_entries]/[passion_tuesday_entry]/
- [nativity_octave_entries]/[derived_entries] comments have the full
- account, task 8, branch ef-lectionary, fix rounds 1-2):
- "ef-christmas-sunday-0" widens into itself PLUS "ef-holy-name-
- sunday" (+1); the three Lent Ember sections rename 1:1 (no count
- change); "ef-passiontide-0-tuesday" is EXCLUDED (fix round 2,
+ [nativity_octave_entries]/[holy_name_entries]/
+ [epiphanytide_opening_entries]/[movable_feast_entries] comments
+ have the full account, task 8 (branch ef-lectionary, fix rounds
+ 1-2) then Task 9 (same branch, layer-4 oracle) below):
+ "ef-passiontide-0-tuesday" is EXCLUDED (task 8 fix round 2,
Important -- it is Holy Tuesday's data, not Passion Tuesday's,
-1); the other five Passiontide sections rename 1:1 (no count
- change); one hand-authored entry sourced from lectio's SANCTORAL
- calendar, not this lectionary ini ([ef-nativity-vigil], +1); SIX
- hand-authored directly from the Missal, all of Holy Week (+6,
- fix round 2 -- Wednesday and Friday added, the first pass's
- Critical bug); ONE hand-authored directly from the Missal,
- Passion Tuesday's own real citation (+1, fix round 2); three
- hand-authored directly from the Missal, the fixed Nativity-Octave
- days (+3); one entry derived from an already-translated one
- rather than re-typed ([ef-holy-name], +1); two ini sections
- EXCLUDED, fix round 3 -- "ef-advent-ember-sat"/
- "ef-september-ember-sat" carried a saint's Mass verbatim (Thomas
- the Apostle's/Matthew's, the C26 shape), not the real Ember
- Saturday (-2); two hand-authored directly from the Missal
- replacing them, [ember_saturday_corrections] (+2, net 0 against
- the -2 immediately above).
- 119 + 1 - 1 + 1 + 6 + 1 + 3 + 1 - 2 + 2 = 131. *)
- Alcotest.(check int) "entry count" 131
+ change); the three Lent Ember sections rename 1:1 (no count
+ change); "ef-advent-ember-sat"/"ef-september-ember-sat" are
+ EXCLUDED, task 8 fix round 3 (Important -- Thomas the Apostle's/
+ Matthew's Mass verbatim, not the real Ember Saturday, -2);
+ 119 - 1 - 2 = 116 real ini-translated entries. PLUS: one
+ hand-authored entry sourced from lectio's SANCTORAL calendar, not
+ this lectionary ini ([ef-nativity-vigil], +1); SIX hand-authored
+ directly from the Missal, all of Holy Week ([holy_week_entries],
+ +6); ONE hand-authored directly from the Missal, Passion
+ Tuesday's own real citation ([passion_tuesday_entry], +1); TWO
+ hand-authored directly from the Missal, replacing the two
+ excluded Ember Saturdays above ([ember_saturday_corrections],
+ +2); three hand-authored directly from the Missal, the fixed
+ Nativity-Octave days ([nativity_octave_entries], +3).
+ Task 9 (branch ef-lectionary, layer-4 oracle -- CORRECTED,
+ [ef-holy-name-sunday]/[ef-holy-name] no longer widened/derived
+ from "ef-christmas-sunday-0", see [colitur_keys]'s own
+ CORRECTED note): TWO hand-authored directly from the Missal
+ ([holy_name_entries], +2); FIFTEEN hand-authored directly from
+ the Missal, three 5-weekday families
+ ([epiphanytide_opening_entries], +15); TWO hand-authored
+ directly from the Missal, two major movable feasts with
+ previously no entry at all ([movable_feast_entries], +2).
+ 116 + 1 + 6 + 1 + 2 + 3 + 2 + 15 + 2 = 148. *)
+ Alcotest.(check int) "entry count" 148
(List.length (Lectionary.entries l));
(match Lectionary.find l (slug "ef-lent-1-monday") with
| Some [ a; b ] ->
@@ -128,9 +136,46 @@ let test_ef_data_file_loads () =
| Some _ -> Alcotest.fail (name ^ ": expected exactly two citations")
| None -> Alcotest.fail (name ^ ": missing")
in
- check_entry "ef-holy-name-sunday" "Gal 4:1-7" "Luke 2:33-40";
+ (* Task 9 (branch ef-lectionary, layer-4 oracle): CORRECTED --
+ [ef-holy-name-sunday]/[ef-holy-name] used to be pinned here at
+ "Gal 4:1-7"/"Luke 2:33-40", the Sunday-within-the-Octave's own
+ citation this generator used to (wrongly) borrow by analogy.
+ missalemeum's own independent extraction (2026-01-04/2027-01-03,
+ real Holy Name Sundays) disproved it; the Missal itself confirms
+ the real value, both scans (scan1.txt:6579-6608,
+ scan2.txt:7225-7297, "SANCTISSIMI NOMINIS IESU... Act. 4, 8-12...
+ Luc. 2, 21") -- see [colitur_keys]'s own CORRECTED note in
+ bootstrap_lectionary.ml for the full account. *)
+ check_entry "ef-holy-name-sunday" "Acts 4:8-12" "Luke 2:21";
check_entry "ef-christmas-sunday-0" "Gal 4:1-7" "Luke 2:33-40";
- check_entry "ef-holy-name" "Gal 4:1-7" "Luke 2:33-40";
+ check_entry "ef-holy-name" "Acts 4:8-12" "Luke 2:21";
+ (* Task 9: RG 17(a)'s own "diebus ferialibus" rubric (2-13 January,
+ three 5-weekday families -- bootstrap_lectionary.ml's own
+ [epiphanytide_opening_entries] comment has the full citations and
+ the RG 78/BVM-Saturday reasoning for why Saturday is excluded from
+ all three). One weekday pinned per family (a regression net, not
+ an exhaustive per-weekday audit -- the generator's own
+ [assert_reachable] already guards every emitted key is a real
+ Temporal_ef slug). *)
+ check_entry "ef-christmas-1-monday" "Titus 2:11-15" "Luke 2:21";
+ check_entry "ef-christmas-1-friday" "Titus 2:11-15" "Luke 2:21";
+ check_entry "ef-christmas-2-tuesday" "Isa 60:1-6" "Matt 2:1-12";
+ check_entry "ef-christmas-2-monday" "Isa 60:1-6" "Matt 2:1-12";
+ check_entry "ef-time-after-epiphany-1-wednesday" "Rom 12:1-5" "Luke 2:42-52";
+ let must_stay_absent name =
+ match Lectionary.find l (slug name) with
+ | None -> ()
+ | Some _ -> Alcotest.fail (name ^ ": must stay absent -- RG 78's BVM Saturday Office")
+ in
+ must_stay_absent "ef-christmas-1-saturday";
+ must_stay_absent "ef-christmas-2-saturday";
+ must_stay_absent "ef-time-after-epiphany-1-saturday";
+ (* Task 9: two major, permanently-named I-class movable feasts with
+ no entry at all before this task (bootstrap_lectionary.ml's own
+ [movable_feast_entries] comment has the full citations, both
+ scans). *)
+ check_entry "ef-corpus-christi" "1 Cor 11:23-29" "John 6:56-59";
+ check_entry "ef-sacred-heart" "Eph 3:8-12, 14-19" "John 19:31-37";
check_entry "ef-nativity-vigil" "Rom 1:1-6" "Matt 1:18-21";
check_entry "ef-pentecost-ember-wed" "Acts 5:12-16" "John 6:44-52.";
check_entry "ef-pentecost-ember-fri" "Joel 2:23-24; 26-27" "Luke 5:17-26";