summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-08-15 01:06:20 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-08-15 01:06:20 +0200
commitfe94cd9c4150fd6285dab49b06e23b6db42d131b (patch)
treee9c80481988635e9925dd19ba3ccc5bb3ddd1e24
parentba0adbaf3176ff753312d7052d0dc2795ac55dc9 (diff)
downloadcolitur-fe94cd9c4150fd6285dab49b06e23b6db42d131b.tar.gz
colitur-fe94cd9c4150fd6285dab49b06e23b6db42d131b.zip
ef(lectionary): fix round 1 -- correct a wrong test, a wrong comment, and ba0adba's own wrong commit body
Three Important findings, all traceable to the task-5 brief rather than the implementation itself; all confirmed against the real data and the real resolver before fixing, not taken on trust. 1. test_step3_uses_temporal_not_observed (2028-12-26) did not exercise step 3 at all: 26 December is always Stephen, a real sanctoral entry with its own citations, so that date resolves entirely at step 1. Its justifying comment was also wrong -- 24 December's TEMPORAL slug is ef-nativity-vigil, IDENTICAL to its observed slug (Temporal_ef.named hard-codes the Vigil for that date ahead of any Sunday computation), so there was never a temporal/observed split on that date to exploit. Replaced with 2025-02-03: 2 February 2025 (Sunday) is observed as the Purification (own citations Mal 3:1-4 / Luke 2:22-32) but its TEMPORAL identity is ef-time-after-epiphany-sunday-4 (Rom 13:8-10 / Matt 8:23-27, a different lectionary entry); 3 February has no proper of its own and reaches step 3, which must return the Sunday's TEMPORAL reading, not the Purification's. Verified against data/ef/sanctoral.sexp and data/ef/lectionary.sexp directly. 2. The termination-argument comment in lectionary_ef.ml (and its echo in lectionary_ef.mli) claimed an unguarded Sunday would loop. It would not: readings is not recursive -- step 3's fallback is one flat Lectionary.find, never a re-entrant call into readings -- so an unguarded Sunday would just repeat step 2's own already-failed lookup once (same pure inputs, same None) and return [] normally. Rewritten to say what is actually true: the guard exists because a Sunday has no PRECEDING Sunday to resume, not because skipping it would be dangerous; the chain terminates because every step consults data or a strictly earlier date, and no step ever calls back into readings. 3. Correcting the record, per instruction, rather than amending ba0adba: that commit's own body said Advent ferias carry 'Advent I's own readings copied onto the following Monday-Thursday'. Both details are wrong, verified directly against data/ef/lectionary.sexp: the duplicated readings are ef-advent-SUNDAY-2's (Rom 15:4-13 / Matt 11:2-10), not Advent I's, and they appear on ef-advent-2-monday, -tuesday, -thursday and -saturday -- four non-contiguous days, not a Monday-to-Thursday span. The in-code comment and the task-5 brief's own commit template both already said 'Advent II' correctly; only ba0adba's commit body had the error. dune test --force: 344 tests, all green (unchanged count -- one test's body changed, none added or removed).
-rw-r--r--lib/rites/rite_ef/lectionary_ef.ml25
-rw-r--r--lib/rites/rite_ef/lectionary_ef.mli7
-rw-r--r--test/test_lectionary_ef.ml39
3 files changed, 52 insertions, 19 deletions
diff --git a/lib/rites/rite_ef/lectionary_ef.ml b/lib/rites/rite_ef/lectionary_ef.ml
index 02c3c64..37ec1d8 100644
--- a/lib/rites/rite_ef/lectionary_ef.ml
+++ b/lib/rites/rite_ef/lectionary_ef.ml
@@ -49,12 +49,25 @@ let readings ~lectionary ~observed ~temporal ~date ~temporal_at =
records the ferial-Mass selection rule itself as unconfirmed
against the primary source.
- Termination: guarded on weekday. A Sunday reaching this branch
- would compute [days_since_sunday Sun = 0] and look up ITSELF,
- looping forever -- every other step in the chain consults data
- (a lectionary lookup), this is the only one that consults
- another date, so this guard is the whole chain's termination
- argument, not merely a special case.
+ Guarded on weekday, but NOT because a Sunday reaching this
+ branch would loop (fix round 1, coordinator review: the
+ original comment here claimed exactly that, and it was wrong).
+ [readings] is not recursive -- step 3's fallback is one flat
+ [Lectionary.find], never a re-entrant call into [readings] --
+ so without the guard, [days_since_sunday Sun = 0] would just
+ repeat the SAME [Lectionary.find] step 2 already ran and
+ already got [None] from (same pure inputs, same date), and
+ return [] once, normally. The chain as a whole terminates
+ because every step either consults data (a lookup) or, here,
+ a strictly EARLIER date via [temporal_at] -- no step ever calls
+ back into [readings] itself, so there is no recursion anywhere
+ in this function for a cycle to form in the first place. The
+ real reason for the guard is simpler: a Sunday has no
+ PRECEDING Sunday to resume -- consulting itself would be
+ meaningless (it would re-ask the question step 2 just
+ answered), not dangerous, so the guard exists to make that
+ intent explicit rather than to prevent a runaway loop that was
+ never actually possible.
The preceding Sunday's TEMPORAL slug, never its observed one:
the rubric is the preceding Sunday's Mass even in a year when a
diff --git a/lib/rites/rite_ef/lectionary_ef.mli b/lib/rites/rite_ef/lectionary_ef.mli
index 159fd57..e54a0b1 100644
--- a/lib/rites/rite_ef/lectionary_ef.mli
+++ b/lib/rites/rite_ef/lectionary_ef.mli
@@ -23,9 +23,10 @@ open Colitur_kernel
Steps 1-3 (Tasks 4-5): the observed celebration's own proper, else the
day's own temporal slug in the lectionary, else -- for a weekday whose
own slug has no entry -- the preceding Sunday's temporal slug (never its
- observed one; a Sunday guards against consulting itself and looping,
- see [readings]'s own implementation comment). A day matching none of the
- three gets [] for now -- the Commons (Task 6) are not built here. *)
+ observed one; a Sunday is guarded out because it has no PRECEDING Sunday
+ to resume, not because consulting itself would loop -- [readings] is not
+ recursive, see its own implementation comment). A day matching none of
+ the three gets [] for now -- the Commons (Task 6) are not built here. *)
val readings :
lectionary:Lectionary.t ->
observed:Vocab_ef.rank Celebration.t ->
diff --git a/test/test_lectionary_ef.ml b/test/test_lectionary_ef.ml
index 6d8f3fe..8af57f6 100644
--- a/test/test_lectionary_ef.ml
+++ b/test/test_lectionary_ef.ml
@@ -128,16 +128,35 @@ let test_step3_christmas_feria_resumes_sunday () =
[ "Gal 4:1-7"; "Luke 2:33-40" ]
(refs (day 2025 12 29))
-(* The distinction that matters: step 3 uses the preceding Sunday's TEMPORAL
- slug, never the observed one. 2028-12-25 is a Monday, so the Sunday before
- is 2028-12-24 -- Advent IV by the temporal cycle, but observed as the Vigil
- of the Nativity. The feria must take Advent IV's Mass, not the Vigil's. *)
+(* Fix round 1 (coordinator review, Important finding 1): the original test
+ here (2028-12-26) did not exercise step 3 at all -- 26 December is always
+ Stephen (Class2, a real sanctoral entry with its own citations, fixed
+ regardless of weekday), so that date resolves entirely at step 1 and never
+ reaches step 2 or 3. Its justifying comment was also factually wrong: 24
+ December's TEMPORAL slug is [ef-nativity-vigil], identical to its OBSERVED
+ slug -- [Temporal_ef.named] hard-codes the Vigil for 24 December ahead of
+ any Sunday computation, so there is no temporal/observed split on that
+ date to exploit in the first place.
+
+ 2025-02-03 genuinely discriminates, verified directly against the real
+ data (data/ef/sanctoral.sexp, data/ef/lectionary.sexp) and the real
+ resolver, not transcribed: 2025-02-02 (a Sunday) is observed as the
+ Purification of the BVM (RG 16(a): a Feast of the Lord takes the Sunday's
+ place outright), with its own citations Mal 3:1-4 / Luke 2:22-32 -- but
+ its TEMPORAL identity is [ef-time-after-epiphany-sunday-4], whose
+ lectionary entry is the different Rom 13:8-10 / Matt 8:23-27. 2025-02-03
+ (Monday) has no sanctoral office of its own and no entry for its own
+ temporal slug ([ef-time-after-epiphany-4-monday], absent from
+ data/ef/lectionary.sexp), so it reaches step 3 and must return the
+ Sunday's TEMPORAL readings (Rom 13:8-10 / Matt 8:23-27). A "step 3 reads
+ the observed office instead of the temporal one" bug would instead return
+ the Purification's (Mal 3:1-4 / Luke 2:22-32) -- different, checkable
+ values, not a bare length check. *)
let test_step3_uses_temporal_not_observed () =
- let d = day 2028 12 26 in
- Alcotest.(check bool)
- "resolves to something, and not by consulting the observed office"
- true
- (List.length (refs d) = 2)
+ Alcotest.(check (list string))
+ "3 February 2025 takes the preceding Sunday's TEMPORAL Mass (Time after Epiphany IV), not the Purification's"
+ [ "Rom 13:8-10"; "Matt 8:23-27" ]
+ (refs (day 2025 2 3))
(* Termination: a Sunday that reaches step 3 would consult itself. It must
not: the guard is weekday <> Sun. *)
@@ -156,7 +175,7 @@ let suite =
test_step3_advent_feria_resumes_sunday);
("step 3: Christmas feria resumes the preceding Sunday", `Quick,
test_step3_christmas_feria_resumes_sunday);
- ("step 3: uses the Sunday's temporal slug, not its observed office", `Quick,
+ ("step 3: 3 Feb 2025 takes the Sunday's temporal Mass, not the Purification's", `Quick,
test_step3_uses_temporal_not_observed);
("step 3: a Sunday does not recurse into itself", `Quick,
test_step3_sunday_does_not_recurse) ]