summaryrefslogtreecommitdiff
path: root/test/test_differential.ml
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-08-15 03:40:19 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-08-15 03:40:19 +0200
commitb0ff86ae552b90613be21c52433f4180deba7758 (patch)
tree5d3e41886ded15231da10d06659eb24cc106650f /test/test_differential.ml
parent459d2c74711e6a152fb338f88d2327f12180b61f (diff)
downloadcolitur-b0ff86ae552b90613be21c52433f4180deba7758.tar.gz
colitur-b0ff86ae552b90613be21c52433f4180deba7758.zip
test(differential): fix round 1 -- Holy Week, Lent Ember, RG 69
Two Critical findings, both real: Holy Week (including the entire Sacred Triduum) was reading Passion Week's Masses -- the original colitur_keys widened lectio's single, conflated ini section into both weeks instead of Passion week alone. Narrowed to Passion week only; Holy Week's own four cleanest days (Monday, Tuesday, Thursday, Saturday) are hand-authored directly from the Missal, verified twice against both scans (C23); Holy Wednesday and Good Friday are genuinely multi-lesson liturgies with no single Epistle slot and are deliberately left unanswered, not guessed (C24). The Lenten Ember days were still dead keys: Temporal_ef computes ef-lent-ember-{wed,fri,sat}, lectio's ini names the same data ef-lent-1-{wednesday,friday,saturday}, and colitur_keys never translated it -- both engines independently fell through to the same wrong ferial answer, so even the differential stayed green (C22, a genuine lectio bug recorded for upstream). Fixed the instance and the class: colitur_keys gained the rename, and tools/bootstrap_lectionary.ml gained assert_reachable, sweeping Rite_ef.Temporal_ef.temporal at generation time so a translation table entry naming a slug colitur never computes dies loudly instead of shipping silently, plus an informational log of every real slug with no entry at all. C21 ("colitur's step 3 cannot reach a correct answer for the fixed Christmastide slugs") is retired, superseded rather than merely patched: the Nativity-Octave days now have their own direct Missal formulary (Tit. 3,4-7/Luc. 2,15-20, "Diebus infra octavam Nativitatis Domini"), resolved at step 2, not step 3 at all. That surfaced a real RG 69 gap underneath it: a Sunday landing 26-31 December should keep its own Office, not the fixed weekday placeholder, which Temporal_ef does not currently distinguish. C6's verdict is re-opened (open, not colitur) for the 19 of its 138 rows where this applies directly, and a new entry C25 (57 rows) records the same gap propagating one hop further through step 3 into Holy Name week. Both are out of this task's own scope -- a behaviour change to a shared, multi-round-reviewed kernel-adjacent function -- and recorded, not fixed, per the coordinator's own instruction. C6's own note is rewritten in full rather than layered with another correction; C18's stale trailing count is fixed to match its own pin; the Vigil-misapplication risk flagged as a Minor closed itself once the Nativity-Octave fix landed, confirmed by inspection rather than assumed. dune test: 358/358. COLITUR_EXHAUSTIVE_SWEEP=1 dune test --force: 359/359.
Diffstat (limited to 'test/test_differential.ml')
-rw-r--r--test/test_differential.ml178
1 files changed, 127 insertions, 51 deletions
diff --git a/test/test_differential.ml b/test/test_differential.ml
index 74cc54d..bdb3377 100644
--- a/test/test_differential.ml
+++ b/test/test_differential.ml
@@ -717,54 +717,117 @@ let lectio_no_reading_slugs =
[ "vincent-ferrer"; "francis-of-paola"; "isidore-of-seville"; "thomas-aquinas"; "john-of-god";
"sts-felicitas-perpetua"; "frances-rome" ]
-(* C21 (task 8) -- [verdict open], the FIRST entry in this file that is not
- [verdict colitur] (see data/ef/expected-divergences.sexp's own header for
- the file-level rule this departs from, and the note on why). A genuine,
- precisely-diagnosed colitur LOGIC LIMITATION, not a data/bootstrap issue
- and not a rubric dispute: {!Rite_ef.Lectionary_ef.readings}'s step 3 is a
- SINGLE hop to the immediately preceding civil Sunday's own temporal
- identity. For a run of colitur-only FIXED Christmastide slugs
- ([ef-nativity-octave-day-{5,6,7}], 29-31 December; the
- [ef-christmas-{0,1,2}-<weekday>] ferias of the two weeks that follow) that
- ONE Sunday is itself frequently ANOTHER entry-less fixed slug (another
- Nativity-Octave day, or, on the single occasion 24 December itself falls
- on a Sunday, [ef-nativity-vigil]) -- so step 3 finds nothing (95 of these
- 107 rows) or, on the 12 rows where the walk happens to land exactly on
- that one Vigil-is-a-Sunday collision, finds the WRONG thing (the Vigil's
- own Mass, misapplied to a later feria that is not itself Christmas Eve).
- lectio's own resolution reaches further by some mechanism this task did
- not fully reverse-engineer (empirically: it variously finds Christmas
- Day's own Mass or Advent IV's own Mass, depending on the year's
- alignment). Properly fixing this needs either an iterative walk-back in
- [readings] itself or a per-year-verified direct entry for every fixed
- Christmastide slug (task 6's own rigor, applied to a new population) --
- both are logic/behaviour changes to a shared, carefully-reviewed
- kernel-adjacent function (Tasks 4-6's own multi-round review history),
- out of this task's own safe scope. Recorded here, not left silently
- failing, because the orchestrating instruction's own condition for
- "leave it failing" is "if you cannot explain a divergence" -- this one
- IS explained, precisely; what remains unresolved is which SAFE fix to
- build, not what the mechanism is. Gated on the two literal colitur
- slug-family prefixes (never a bare "any citation diff" rule) so an
- unrelated future bug on any OTHER slug still surfaces as unexplained.
- Derived directly from the OCaml comparator's own failure output
- (test_layer_c_counts_match_citations), not hand-counted first and
- cross-checked after: 107. NOTE: an earlier version of this comment (and
- of [colitur_keys] in tools/bootstrap_lectionary.ml) measured 202 here,
- before a regression in the FIRST version of the "ef-christmas-sunday-0"
- translation (replaced instead of widened the key -- caught by
- test_lectionary_ef.ml's own pre-existing test, not by this reasoning)
- was fixed; fixing it also legitimately shrank this population by 95
- rows. data/ef/expected-divergences.sexp's own C21/C6 notes have the full
- before/after account, including the ONE guess this task tried for
- [ef-nativity-octave-day-{5,6,7}] (Holy Name Sunday's own citation,
- uniformly) and reverted once measured -- Missal-confirmed
- (docs/research/scan1.txt, "Dominica infra octavam Nativitatis Domini,
- II classis": Gal. 4,1-7 / Luc. 2,33-40) to be right for the genuine
- Sunday-within-the-Octave case alone, wrong whenever the true preceding
- Sunday is Christmas Day or Advent IV instead. *)
-let christmastide_fixed_slug_family (c : row) =
- starts_with ~prefix:"ef-nativity-octave-day-" c.slug || starts_with ~prefix:"ef-christmas-" c.slug
+(* C21 -- RETIRED, task 8 fix round 1 (coordinator review). Previously a
+ [verdict open] entry (107 rows) for "colitur's step 3 cannot reach a
+ correct answer for the fixed Christmastide slugs". That diagnosis has
+ been SUPERSEDED, not merely fixed around: Important 3(a)'s own direct
+ Missal formulary (tools/bootstrap_lectionary.ml's own
+ [nativity_octave_entries]) gives [ef-nativity-octave-day-{5,6,7}] a
+ real, correct answer via STEP 2, not step 3 at all, so "step 3 cannot
+ reach it" is no longer even true. What C21 used to cover has split
+ cleanly into two DIFFERENT, more precisely diagnosed populations:
+ colitur's own [ef-nativity-octave-day-N] rows now fold into C6 above
+ (widened, [verdict] re-opened -- see its own note); the
+ [ef-christmas-1-<weekday>] rows that resume THAT slug's own (partly
+ wrong, per RG 69) answer one hop later via step 3 are C25 below, a
+ genuinely different id because the mechanism is now precisely RG 69
+ propagating through step 3, not "step 3 has no answer". No predicate
+ or helper of this file's own still names "C21" -- removing the code
+ alongside the id is the same discipline this file's own header already
+ applies to C2-C5/C7/C9-C13 (closed, cited, never left as dead code). *)
+
+(* C22 (task 8, fix round 1, coordinator review, Critical 2): the Lenten
+ Ember days (RG 91 entry 18, colitur's own ef-lent-ember-{wed,fri,sat})
+ are reachable for the first time this fix round -- tools/
+ bootstrap_lectionary.ml's own [colitur_keys] comment has the full
+ account of the dead-key bug this closes. lectio's own SLUG for these
+ three days already matched colitur's (both call it "ef-lent-ember-wed"
+ etc, confirmed by this row's own [c.slug]/[l.slug] agreement -- no
+ [Slug_f] in this entry's own diff set), but lectio's own READING
+ resolution has the IDENTICAL internal mismatch colitur's used to have:
+ its own ini keys this data under "ef-lent-1-<weekday>", and its own
+ [caldata.Readings] never reaches it either, so it still falls back to
+ Lent I Sunday's own Mass (e.g. "2 Cor. 6:1-10"/"Matt 4:1-11") on every
+ one of these dates. That is a genuine LECTIO bug, reported here for
+ upstream, NOT fixed in this task (the brief's own triage rule: record,
+ do not patch the sibling project) -- and it is exactly the "Holy
+ Thursday was violet in both" shape this project's own CLAUDE.md already
+ names: layer 3 was STRUCTURALLY BLIND to this the whole time colitur
+ also had the bug, because both engines independently produced the same
+ wrong answer. Gated on colitur's own slug family (a literal 3-member
+ list, not a pattern) and the diff set staying [First_f; Gospel_f]
+ alone (slug/rank/colour already agree). Derived directly from the OCaml
+ comparator's own failure output, not hand-counted first and cross-
+ checked after: 128 (43 + 43 + 42 -- a few of the 46-year population are
+ impeded by a competing sanctoral feast each year, so the Ember office
+ itself is not always the observed day). *)
+let lent_ember_slugs = [ "ef-lent-ember-wed"; "ef-lent-ember-fri"; "ef-lent-ember-sat" ]
+
+(* C23/C24 (task 8, fix round 1, coordinator review, Critical 1): Holy
+ Week's own citations (tools/bootstrap_lectionary.ml's own
+ [holy_week_entries] comment has the full Missal citations and the two-
+ scan corroboration for each). lectio has no Holy Week propers at all --
+ every "ef-passiontide-0-<weekday>" ini section is Passion week's own
+ Mass (or, for Tuesday specifically, Holy Tuesday's own Passion Gospel
+ riding along on Passion week's own Epistle -- a genuine internal
+ inconsistency in lectio's own source, not this project's to fix), so
+ lectio shows THAT reused/conflated citation on every Holy Week weekday,
+ every year, regardless of what the real Missal prints there.
+
+ C23 covers the four days colitur now answers correctly and completely
+ (Monday, Tuesday, Thursday, Saturday) -- verdict colitur, cited
+ directly. C24 covers the two days colitur deliberately answers with []
+ instead of a guess (Wednesday, Good Friday -- both genuinely
+ multi-lesson liturgies with no single Epistle slot this schema could
+ honestly fill; [holy_week_entries]'s own comment has the full argument
+ for why forcing a pair would be an uncited editorial choice, not a
+ Missal fact). Both entries: gated on colitur's own literal slug list
+ and [diffs] staying exactly [First_f; Gospel_f] (identity already
+ agrees on both). Every occurrence across the whole 2005-2050 fixture
+ falls in all 46 years without exception, on every one of these six
+ slugs -- Holy Week recurs every year by construction, so this is not a
+ coincidental count the way a collision-driven entry's would be.
+ Derived directly from the OCaml comparator's own failure output, not
+ hand-counted first and cross-checked after: C23 184 (46 x 4), C24 92
+ (46 x 2). *)
+let holy_week_answered_slugs =
+ [ "ef-passiontide-2-monday"; "ef-passiontide-2-tuesday"; "ef-passiontide-2-thursday";
+ "ef-passiontide-2-saturday" ]
+
+let holy_week_unanswered_slugs = [ "ef-passiontide-2-wednesday"; "ef-passiontide-2-friday" ]
+
+(* C25 (task 8, fix round 1, coordinator review, Important 3(b)) --
+ [verdict open], the SAME RG 69 gap C6 above re-opened, one hop removed.
+ RG 69 (docs/research/scan1.txt:625-631, word for word: "De dominica
+ infra octavam Nativitatis Domini... semper fit Officium cum
+ commemoratione festi forte occurrentis... nisi dominica incidat in
+ festum I classis") is unconditional: a Sunday landing 26-31 December
+ should keep ITS OWN Office (with the day's feast merely commemorated),
+ not the fixed weekday placeholder -- but colitur's [Temporal_ef] gives
+ both the SAME slug, undifferentiated by weekday (C6's own note, and
+ data/ef/expected-divergences.sexp's own C6 entry, have the full
+ account). Confirmed, not merely inferred,
+ that THIS entry is the direct, one-hop-removed consequence of that same
+ gap: every single one of these rows' colitur-side citation is "Tit. 3,
+ 4-7" (the fixed weekday formulary), because [Lectionary_ef.readings]'
+ step 3 resumes the SAME wrongly-undifferentiated Sunday C6 already
+ names, not a second, independent cause. A genuine, precisely-diagnosed
+ [Temporal_ef] defect -- out of this task's own scope (a behaviour
+ change to a shared, multi-round-reviewed kernel-adjacent function) --
+ recorded here per the coordinator's own instruction ("record it
+ prominently... for a follow-up task"), not fixed and not left silently
+ failing. Gated on the literal 4-slug family (the only members of
+ [ef-christmas-1-<weekday>] this mechanism can ever reach -- Monday and
+ Tuesday of that same week are always claimed first by the Circumcision
+ or Holy Name's own DIRECT entries, so they can never fall through to
+ this specific step-3 chain) and [diffs] staying exactly
+ [First_f; Gospel_f] (identity already agrees -- this is a pure content
+ consequence). Derived directly from the OCaml comparator's own failure
+ output, not hand-counted first and cross-checked after: 57
+ (19 + 19 + 13 + 6, Wednesday/Thursday/Friday/Saturday respectively). *)
+let rg69_one_hop_slugs =
+ [ "ef-christmas-1-wednesday"; "ef-christmas-1-thursday"; "ef-christmas-1-friday";
+ "ef-christmas-1-saturday" ]
(* [layer_c_reason l c diffs] returns the [data/ef/expected-divergences.sexp]
[id] this row-pair's remaining (post Layer A/B) diff set belongs to, or
@@ -789,8 +852,18 @@ let layer_c_reason (l : row) (c : row) diffs =
the reviewer: dropping the RG 91 entry 17 elevation in temporal_ef
(Class2 -> Class4 on octave days 5-7) left BOTH differential tests green
with C6 still reporting 138. The slug guard below already pins identity;
- [Rank] only removed the ability to notice a rank regression. *)
- && diffs = [ Slug_f ]
+ [Rank] only removed the ability to notice a rank regression.
+
+ WIDENED, task 8 fix round 1 (coordinator review, Important 3(a)/(b)):
+ [First_f; Gospel_f] joined the accepted set. Important 3(a)'s own fix
+ (tools/bootstrap_lectionary.ml's [nativity_octave_entries]) gives
+ these dates a real, Missal-verified citation for the first time --
+ and it does NOT converge with lectio's own (differently incomplete)
+ Sunday-walkback answer, so ALL 138 of this entry's rows now carry a
+ citation diff too, not merely the slug one. See data/ef/expected-
+ divergences.sexp's own C6 entry for why this entry's [verdict] is
+ now [open], not [colitur] -- Important 3(b)'s own RG 69 finding. *)
+ && subset diffs [ Slug_f; First_f; Gospel_f ]
&& List.mem c.slug nativity_octave_day_slugs
then Some "C6"
else if
@@ -858,7 +931,10 @@ let layer_c_reason (l : row) (c : row) diffs =
diffs = [ First_f; Gospel_f ] && String.equal l.first "-" && String.equal l.gospel "-"
&& List.mem c.slug lectio_no_reading_slugs
then Some "C20"
- else if christmastide_fixed_slug_family c && subset diffs [ Slug_f; First_f; Gospel_f ] then Some "C21"
+ else if List.mem c.slug rg69_one_hop_slugs && diffs = [ First_f; Gospel_f ] then Some "C25"
+ else if List.mem c.slug lent_ember_slugs && diffs = [ First_f; Gospel_f ] then Some "C22"
+ else if List.mem c.slug holy_week_answered_slugs && diffs = [ First_f; Gospel_f ] then Some "C23"
+ else if List.mem c.slug holy_week_unanswered_slugs && diffs = [ First_f; Gospel_f ] then Some "C24"
else None
(* ---------------------------------------------------------------------- *)