diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-22 20:55:18 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-22 20:55:18 +0200 |
| commit | 9c96e0afc19925b651e0dfee3bc9182dee72acf0 (patch) | |
| tree | 5f1fe05d495ddea61f585311f3dbca8bb1062cd8 /test/test_lms_ordo.ml | |
| parent | cd3e03bf3e5b040786838fc3c5639d7c29e9b3b8 (diff) | |
| download | colitur-9c96e0afc19925b651e0dfee3bc9182dee72acf0.tar.gz colitur-9c96e0afc19925b651e0dfee3bc9182dee72acf0.zip | |
fix(ef): ferias after the Ascension repeat its own Mass, not a Sunday's
Ascension has no octave under the 1960 rubrics -- confirmed structurally:
the Proprium de Tempore's own table of contents runs straight from "In
Ascensione Domini" to "Dominica post Ascensionem" with no per-feria
headings in between. Step 3 of the reading chain therefore fell through
to Preceding_sunday on every unoccupied weekday in that stretch, walking
each one back to the 5th or 6th Sunday after Easter's own citation.
The Missal's own Proprium de Tempore carries an explicit marginal rubric
immediately after the Ascension's Mass propers, before "Dominica post
Ascensionem" begins: "Diebus a feria VI post Ascensionem usque ad feriam
VI ante vigiliam Pentecostes inclusive, dicitur Missa de festo
Ascensionis, cum Gloria et praefatione de Ascensione, sine Credo et
Communicantes proprio" -- every feria without its own proper, from the
Friday after the Ascension through the Friday before the Vigil of
Pentecost, repeats the Ascension's own Mass. RG 490(b) corroborates
independently: it assigns the Ascension preface "tamquam de Tempore"
across that identical window, which only makes sense if the Mass
actually repeated there is the Ascension's, not a numbered Sunday's
(whose own Mass would carry no need for a preface override at all).
Witnessed directly, not only inferred from the rubric: the LMS Ordo
prints "Mass of the Ascension" literally on every affected day across
all three of its fixture windows, in BOTH the tail of Ascension's own
week and the following week -- ruling out the alternative reading (that
the second week instead resumes "Dominica post Ascensionem"'s own Mass,
which a first pass over the FIUV Ordo's own week-labelled titles could
suggest at a glance; its own [praef] field for the same two dates
independently reads "Ascensionis", resolving the apparent conflict).
Implemented as data, not logic, matching this codebase's own established
precedent for the identical RG 299 shape (the week after Trinity Sunday,
data/ef/lectionary.sexp's [trinity_week_entries]): six new hand-authored
entries, [ascension_week_entries] in tools/bootstrap_lectionary.ml,
regenerated against a git-pinned copy of lectio's own source ini (SHA-256
verified unchanged) so the regeneration carries no unrelated drift. The
window's two Saturdays are deliberately excluded -- RG 78's votive Office
of Our Lady on Saturday always wins an otherwise-unoccupied Class4
Saturday first, before step 2 (this fix's own entry point) is ever
reached, so an entry for either slug would be dead data.
Blast radius measured in-process across the full 1583-9999 domain
(throwaway probe, not committed): 16 350 days total across the six
slugs, every one resolved via step 2 (Own_slug), zero anomalies, and the
window's two Saturdays confirmed to contribute zero hits via this cause
across the whole domain, corroborating the RG78-interception reasoning
by direct sweep.
Closed L2 in data/ef/expected-divergences-lms.sexp. New cited entries:
C41 in data/ef/expected-divergences.sexp (95 of 16801 rows, 2005-2050 --
lectio has no equivalent rubric and still walks these ferias back);
M31 in data/ef/expected-divergences-missalemeum.sexp (3 rows in the
2026-2027 window, plus the same shape independently reconfirmed in the
2035 and 2038 live-capture windows) -- missalemeum, Divinum Officium's
lineage, still gives the same wrong answer colitur itself used to give,
which is why these rows used to agree with M18's shape and now escape it
(M18 373 -> 370, the same mechanism M23-M27 established when the
citation axis was first built).
Golden pin: 2031-05-23, the exact date the bug report was filed against.
Mutation-tested: reverting data/ef/lectionary.sexp alone (a git-diff
capture/restore, not a source-code revert, since the fix is data) reddens
19 tests across the differential, both oracle fixtures, all three LMS
Ordo windows, the golden pin, the lectionary unit test and every Render
golden template; restored and reconfirmed green (681 tests; 683 under
COLITUR_EXHAUSTIVE_SWEEP=1, ~175s).
Diffstat (limited to 'test/test_lms_ordo.ml')
| -rw-r--r-- | test/test_lms_ordo.ml | 91 |
1 files changed, 83 insertions, 8 deletions
diff --git a/test/test_lms_ordo.ml b/test/test_lms_ordo.ml index ed1c871..32ecfbc 100644 --- a/test/test_lms_ordo.ml +++ b/test/test_lms_ordo.ml @@ -333,7 +333,8 @@ let expected_named_sunday_override slug ~year = else None (* See Task 6's own [ascension_week_override] citation (test_lms_ordo.ml - history, expected-divergences-lms.sexp L2): STRUCTURAL, not a fixture + history, data/ef/expected-divergences-lms.sexp's own now-CLOSED L2, + celebrant-rubrics-phase1 Bug 2, 2026-08-22): STRUCTURAL, not a fixture artefact -- the Ascension is a fixed Easter+39, so every feria whose own [Preceding_sunday] fallback would otherwise resolve to a week-6/7 Sunday falls, in SOME years, between Ascension Thursday and the following @@ -341,11 +342,39 @@ let expected_named_sunday_override slug ~year = the finding: it is specifically the days AFTER Ascension (not merely "any week-6/7 Preceding_sunday day") that get this treatment -- see [expected_preceding_sunday_override]'s own citation for the Rogation - Monday counter-example that exposed the difference. [is_ascension_week] + Monday counter-example that exposed the difference. [is_after_ascension] below is the corrected predicate: the day's own DATE compared against - {!Computus.ascension} for its own year, not [n]. *) + {!Computus.ascension} for its own year, not [n]. + + FIXED (celebrant-rubrics-phase1, Bug 2): data/ef/lectionary.sexp's new + [ascension_week_entries] now answers these six ferial slugs directly at + step 2 (Own_slug), so [check_formulary_overrides]'s own [Preceding_sunday] + branch below never reaches them any more -- moved to a dedicated + [Own_slug] branch in that same function, which still asserts the Ordo's + override reads exactly [ascension_week_override], now as a genuine + confirmation that colitur's OWN citation matches (previously this + predicate only served to EXCLUDE the population from the general + Preceding_sunday mapping, because colitur had no correct answer to + compare). This constant and [is_after_ascension] itself are still load- + bearing for that confirmation -- kept, not deleted, the same "the + regression net survives its own fix" discipline + data/ef/expected-divergences-lms.sexp's own L6 note states for + [is_l6_rogation_colour]. *) let ascension_week_override = "Mass of the Ascension" +(* The exact six slugs data/ef/lectionary.sexp's own [ascension_week_entries] + (tools/bootstrap_lectionary.ml) now answers at step 2 -- gated on SLUG + IDENTITY, not merely [is_after_ascension date], because that date range + also covers "Dominica post Ascensionem" and the Vigil of Pentecost, both + genuinely [Own_slug] and both carrying their OWN, different citation, not + the Ascension's (caught live: an earlier, date-only version of this gate + wrongly flagged both as missing an Ordo override before this list was + added). *) +let ascension_week_slugs = + [ "ef-easter-6-friday"; "ef-easter-7-monday"; "ef-easter-7-tuesday"; "ef-easter-7-wednesday"; + "ef-easter-7-thursday"; "ef-easter-7-friday" + ] + (* Bounded ABOVE by Pentecost, not merely "later than Ascension" -- a bare lower bound is wrong for any date past Ascension in the SAME civil year (every date from June to December satisfies "> Ascension", which a @@ -431,7 +460,34 @@ let check_formulary_overrides ordo colitur = :: !bad | None -> bad := Printf.sprintf "%s: unmapped (colitur resumed %S) and Ordo shows no override" o.date slug :: !bad)) - | Some { MF.via = MF.Votive; _ } | Some { MF.via = MF.Own_slug; _ } | None -> ()) + | Some { MF.via = MF.Own_slug; said } -> ( + (* celebrant-rubrics-phase1, Bug 2 fix: the six Ascension-week + ferias moved from [Preceding_sunday] (the branch above, which + used to special-case them via [is_after_ascension]) to + [Own_slug] -- data/ef/lectionary.sexp's own + [ascension_week_entries] now answers at step 2, before step 3 + is ever reached. Checked HERE, not merely left to fall through + silently the way every OTHER [Own_slug] day already does + (RG 299's ordinary case, a real proper Mass, needs no Ordo + cross-check because nothing about it is adjudicated): this is + the one [Own_slug] population this suite has an OUTSIDE + witness for, and losing that check when the fix landed would + have been a silent regression net, not merely dead code -- the + Ordo's own override text must still read "Mass of the + Ascension" on exactly these days. *) + let slug = match said with Some s -> Colitur_kernel.Slug.to_string s | None -> "" in + if List.mem slug ascension_week_slugs then + match o.formulary_override with + | Some got when String.equal got ascension_week_override -> incr ascension_week + | Some got -> + bad := + Printf.sprintf "%s: colitur resolved %S via Own_slug (after Ascension), Ordo shows %S, not %S" + o.date slug got ascension_week_override + :: !bad + | None -> + bad := Printf.sprintf "%s: colitur resolved %S via Own_slug (after Ascension), Ordo shows no override" + o.date slug :: !bad) + | Some { MF.via = MF.Votive; _ } | None -> ()) pairs; { fc_bad = List.rev !bad; fc_proper = !proper; fc_common = !common; fc_preceding_sunday = !preceding_sunday; fc_ascension_week = !ascension_week } @@ -733,7 +789,7 @@ let make_suite ~label ~fixture_path ~fixture_sha256 ~window_first ~window_last ~ Alcotest.(check int) (Printf.sprintf "%d Preceding_sunday days in the window" expected_preceding_sunday) expected_preceding_sunday r.fc_preceding_sunday; Alcotest.(check int) - (Printf.sprintf "%d Preceding_sunday days fall in the Ascension-week exclusion, no more, no fewer" + (Printf.sprintf "%d Ascension-week days resolve via Own_slug and match the Ordo's own override, no more, no fewer" expected_ascension_week) expected_ascension_week r.fc_ascension_week in @@ -797,19 +853,38 @@ let suite_2023_2024 = Own_slug is excluded). Matthias himself moves to 25 February, an I-class Sunday that admits him not even as a commemoration (RG16(a)), so his own Mass is not said anywhere in this window any more. *) - ~expected_bvm_votive:12 ~expected_proper:181 ~expected_common:2 ~expected_preceding_sunday:61 + (* expected_preceding_sunday 61 -> 60 (celebrant-rubrics-phase1, Bug 2 + fix, 2026-08-22): the window's own single Ascension-week day + (2024-05-06 was BEFORE Ascension that year and never counted here in + the first place -- see [ascension_week_override]'s own citation; the + real Ascension-week day this window carries is elsewhere in May) + now resolves via Own_slug (step 2, data/ef/lectionary.sexp's new + [ascension_week_entries]), not Preceding_sunday -- it leaves this + bucket's population the same way a Proper day already does, while + expected_ascension_week itself is UNCHANGED (1): the same day is + still counted, just via check_formulary_overrides' own new + Own_slug branch instead of its Preceding_sunday one. *) + ~expected_bvm_votive:12 ~expected_proper:181 ~expected_common:2 ~expected_preceding_sunday:60 ~expected_ascension_week:1 ~expected_gloria_l5:5 ~expected_gloria_l6:0 let suite_2024_2025 = make_suite ~label:"lms-ordo-2024-2025" ~fixture_path:"fixtures/lms-ordo-2024-2025.sexp" ~fixture_sha256:"da817b75c5bf40ed3be1d5f6890b199705e02ce4d42111253ab8547bccabc3f7" ~window_first:"2024-11-27" ~window_last:"2025-12-31" ~year_lo:2023 ~year_hi:2026 ~allow_list_path ~expected_rows:400 - ~expected_bvm_votive:14 ~expected_proper:179 ~expected_common:2 ~expected_preceding_sunday:66 + (* expected_preceding_sunday 66 -> 63 (celebrant-rubrics-phase1, Bug 2 + fix): this window's own three Ascension-week days move from + Preceding_sunday to Own_slug, the same reasoning as the 2023-2024 + window's own note above; expected_ascension_week stays 3. *) + ~expected_bvm_votive:14 ~expected_proper:179 ~expected_common:2 ~expected_preceding_sunday:63 ~expected_ascension_week:3 ~expected_gloria_l5:5 ~expected_gloria_l6:0 let suite_2025_2026 = make_suite ~label:"lms-ordo-2025-2026" ~fixture_path:"fixtures/lms-ordo-2025-2026.sexp" ~fixture_sha256:"8839a61e0c7d1e6c8326114f4f45a5c183551287a88f4ed01127154add6ae5a5" ~window_first:"2025-11-28" ~window_last:"2026-12-31" ~year_lo:2024 ~year_hi:2027 ~allow_list_path ~expected_rows:399 - ~expected_bvm_votive:13 ~expected_proper:174 ~expected_common:2 ~expected_preceding_sunday:68 + (* expected_preceding_sunday 68 -> 66 (celebrant-rubrics-phase1, Bug 2 + fix): this window's own two Ascension-week days move from + Preceding_sunday to Own_slug, the same reasoning as the 2023-2024 + window's own note above; expected_ascension_week stays 2. *) + ~expected_bvm_votive:13 ~expected_proper:174 ~expected_common:2 ~expected_preceding_sunday:66 ~expected_ascension_week:2 ~expected_gloria_l5:6 ~expected_gloria_l6:0 |
