From e26d7da141f7985fadc53d8399a69dbaa1153c94 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Thu, 27 Aug 2026 00:38:40 +0200 Subject: fix(of): correct the Annunciation's transfer_target slug, dead Rule 1 precedence_of.ml's transfer_target Rule 1 (Normae n. 60's fixed Easter+8 destination for the Annunciation falling in Holy Week) keyed off "of-annunciation", a placeholder that never matched the real shipped entry's own slug ("annunciation-of-the-lord", data/of/calendar-2002.sexp). Rule 1 was therefore dead code: it could only ever fire against test_precedence_of.ml's own synthetic candidate, which happened to carry the identical placeholder. Output was nonetheless correct on shipped data (latent, not live): Rule 3's general forward search structurally converges on the same Easter+8 target, because the Easter Octave occupies exactly Easter+1..+7 at band 20 and the 3-9 April window carries only memorials on the universal calendar. The exposure is an overlay placing a proper solemnity (band 40) or proper feast (band 80) anywhere in 3-9 April, where Rule 3 would diverge from Rule 1's fixed destination and Rule 1 would silently fail to override it. Fixed the slug, and updated the existing Rule-1 tests' own synthetic candidate to the real slug so they keep exercising Rule 1 rather than Rule 3's coincidental agreement. Added a test that tells the two rules apart rather than only checking the output they happen to agree on: it rigs the occupant callback to occupy Easter+8 with a synthetic Tabula-entry-3 candidate, confirms (via a control case using a different solemnity) that the rig genuinely forces Rule 3's search past that date, then shows the real shipped Annunciation still lands on Easter+8 despite the block -- only explicable by Rule 1 firing, not by Rule 3 happening to agree. --- lib/rites/rite_of/precedence_of.ml | 41 +++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 14 deletions(-) (limited to 'lib/rites/rite_of/precedence_of.ml') diff --git a/lib/rites/rite_of/precedence_of.ml b/lib/rites/rite_of/precedence_of.ml index 0e2c246..30fe48e 100644 --- a/lib/rites/rite_of/precedence_of.ml +++ b/lib/rites/rite_of/precedence_of.ml @@ -465,20 +465,33 @@ let max_search_days = 400 let domain_max_date = match Date.make ~year:9999 ~month:12 ~day:31 with Ok d -> d | Error e -> failwith e -(* NOTE, found while adding [st_joseph_slug] below, NOT fixed here -- - out of scope for the W1 task this touches: [annunciation_slug] does not - match the real shipped entry's own slug (data/of/calendar-2002.sexp has - "annunciation-of-the-lord", not "of-annunciation"), so Rule 1 below - never actually fires against real sanctoral data -- only against the - synthetic candidate test_precedence_of.ml's own [annunciation] builds - with the same placeholder slug. Whether this is output-visible on real - data was not established either way here; Rule 3's general forward - search is a plausible fallback that could reach the identical Easter+8 - target by coincidence in the one case tested - ([test_annunciation_in_easter_octave]'s own comment says as much for a - collision NOT in Holy Week), but that is not the same claim as "the two - rules always agree", and this was not checked for Holy Week itself. *) -let annunciation_slug = "of-annunciation" +(* W6 (of-known-wrongs, 2026-08-26; found by W1, fixed here). This used to + read "of-annunciation", a placeholder that never matched the real + shipped entry's own slug (data/of/calendar-2002.sexp has + "annunciation-of-the-lord") -- so Rule 1 below was DEAD CODE: it could + only ever fire against test_precedence_of.ml's own synthetic candidate, + which happened to carry the identical placeholder, never against real + sanctoral data. + + LATENT, NOT LIVE, on shipped data: Rule 3's general forward search + structurally converges on the identical Easter+8 target whenever the + Annunciation falls in Holy Week, because the Easter Octave occupies + exactly Easter+1..+7 at band 20 and 3-9 April (where Easter+8 lands) + carries only memorials on the shipped universal calendar -- confirmed, + not merely argued, by test_precedence_of.ml's own + [test_annunciation_rule1_actually_fires], which rigs a synthetic + Tabula-entry-3 occupant AT Easter+8 and shows Rule 3 alone would have + had to step past it to Easter+9, while the REAL slug (fixed here) makes + Rule 1 land on Easter+8 regardless -- the one test in this file that + tells "Rule 1 fired" apart from "Rule 3 happened to agree", which no + test here did before it. + + LIVE the moment an overlay places a proper solemnity (band 40) or + proper feast (band 80) anywhere in 3-9 April: Rule 3 would then diverge + from n. 60's own fixed Easter+8 destination, and with the placeholder + slug Rule 1 would silently fail to override it. Fixed at the source + instead of documented around. *) +let annunciation_slug = "annunciation-of-the-lord" (* The real shipped slug (data/of/calendar-2002.sexp) -- St Joseph's own Rule 0 below is matched against the actual sanctoral entry, not a -- cgit v1.3