From 41263d60432fadd2aef3f04de66b60561f89cbec Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Sat, 22 Aug 2026 13:38:27 +0200 Subject: fix(ef): RG 476(f) -- the Creed is not said at a Requiem Mass colitur said the Creed IS said on All Souls' Day and every other Requiem-shaped day: RG 475(b)'s "in festis I classis" branch fired on rank alone, with nothing checking RG 476(f), "Non dicitur symbolum ... f) in Missis defunctorum". Allow-listed as L1 in expected-divergences-lms.sexp on the argument that [creed] has no notion of a Requiem Mass in its inputs and could not express the rule without a signature change. That argument does not hold. Colour.Black is used by exactly two celebrations in the whole engine, verified by grepping every occurrence in lib/ and data/: commemoration-of-all-souls (data/ef/sanctoral.sexp) and Good Friday (temporal_ef.ml, already false via the earlier RG 23(b) feria exclusion and has no Mass at all in the 1955-restored Holy Week). So on every day this engine can construct, colour = Black if and only if the Mass is a Requiem -- a citable implication (RG 117 assigns black to Masses of the dead) on this data, not a heuristic. Rite_ef.Rubrics_ef.creed now reads observed.colour as RG 476(f)'s own guard, positioned ahead of 475(b)'s rank branch. A new test, test_colour_black_population_is_exactly_two, sweeps both the shipped data and Temporal_ef's own code across a century and fails loudly the day a third Colour.Black celebration is ever introduced, so the proxy cannot silently rot. L1 is closed in expected-divergences-lms.sexp, citation preserved. Blast radius, measured (full 1583-9999 sweep, grouped by observed slug): 8 416 days change from true to false, every one commemoration-of-all-souls (missing from exactly 1 of the 8 417 domain years, a boundary-year transfer effect at 1583/9999). A further 8 416 Colour.Black days are Good Friday, unaffected (already false before this fix). colitur day/readings stay byte-identical to v0.10.1 (checked directly against a v0.10.1 worktree build, 9 domain-spanning years); colitur rubrics changes on exactly the 8 416 days above. colitur emit --format sexp's pretty-printed line count for 2027 moved 9010 -> 9011 as a side effect: Sexplib.Sexp.to_string_hum wraps by column width, and All Souls' Day 2027's record grew one wrapped line because "false" is one character longer than "true". Cosmetic only -- no field's data changed -- and pinned in test/cli.t with the measurement recorded. --- data/ef/expected-divergences-lms.sexp | 131 ++++++++++++++++++++++++---------- 1 file changed, 93 insertions(+), 38 deletions(-) (limited to 'data') diff --git a/data/ef/expected-divergences-lms.sexp b/data/ef/expected-divergences-lms.sexp index 96c9e50..e327419 100644 --- a/data/ef/expected-divergences-lms.sexp +++ b/data/ef/expected-divergences-lms.sexp @@ -15,41 +15,96 @@ ; backs, the SAME convention the missalemeum file's own header states: ; not always "colitur". ; -; L1 -- 2025-11-03 (All Souls' Day, transferred from 2 November, a Sunday -; that year, to the next available day -- RG's own transfer of a -; Commemoration when it falls on a Sunday). colitur (Rite_ef.Rubrics_ef. -; creed) says the Creed IS said (true): observed.rank = Class1, so RG -; 475(b)'s "in festis I classis" branch fires with nothing to stop it. -; The Ordo says it is NOT said (false): "Mon 3 ALL SOULS' DAY I Cl B / No -; Gl Sequence No Cr Pr of the Dead No Blessing" -- confirmed directly -; against the extracted pdftotext text, not merely the fixture row. -; -; The Ordo is right and colitur is not, on the rubric itself: RG 476(f), -; "Non dicitur symbolum ... f) in Missis defunctorum" -- the Creed is -; never said at a Requiem Mass, and All Souls' Day is definitionally one -; (colour black in colitur's own output on this very date). This is NOT a -; new defect this task found and is choosing to leave open -- it is -; rubrics_ef.ml's OWN documented scope limit, stated in that file's header -; comment before this task existed: "476(f) (Requiem Masses, also not -; modelled) ... genuinely inapplicable to this implementation -- a -; documented scope limit, not a defect." [creed] has no notion of "this -; Mass is a Requiem" anywhere in its own inputs (temporal/observed/date), -; so it cannot express 476(f) without a signature change this task's own -; constraints do not authorise (lib/ is read-only here except for this -; allow-list). Recorded here as the SPECIFIC real-world day the scope -; limit is finally witnessed on, rather than left as an abstract note in -; a doc comment nobody's data ever exercised. -; -; Domain-wide count: unmeasured (out of this task's scope -- would need a -; sweep of every I-class Requiem-shaped day 1583-9999, which does not -; exist as a distinct predicate in this codebase to sweep on). The two -; days this WOULD also apply to in principle -- 2 November itself in any -; year it does not fall on a Sunday, and the plain All Souls' Day office -; whenever it is not transferred -- are outside this fixture's own -; window's reach for a second occurrence, so only the one real day above -; is witnessed and adjudicated here. -((id L1) - (citation "RG 476(f): \"Non dicitur symbolum ... f) in Missis defunctorum\" -- the Creed is never said at a Mass of the dead; rubrics_ef.ml's own header already documents this Mass-type as unmodelled") - (verdict lms_ordo) - (note "colitur's [creed] has no notion of a Requiem Mass in its inputs (temporal/observed/date), so RG 475(b)'s I-class branch fires unopposed on All Souls' Day (Class1, black). A pre-existing, self-documented scope limit (rubrics_ef.ml's own header), witnessed here for the first time on a real date rather than left as an abstract note: 2025-11-03, All Souls' Day transferred from Sunday 2 November. The Ordo (\"No Gl Sequence No Cr Pr of the Dead\") is correct on the rubric.") - (expected_rows 1)) +; L1 -- CLOSED, FIXED (whole-branch review finding 1, 2026-08-22): was +; 2025-11-03 (All Souls' Day, transferred from 2 November, a Sunday that +; year). colitur used to say the Creed IS said (true) on rank alone +; (475(b), Class1) where the Ordo, correctly, says it is not: "Mon 3 ALL +; SOULS' DAY I Cl B / No Gl Sequence No Cr Pr of the Dead No Blessing". +; +; This entry's own PREVIOUS text argued the divergence could not be fixed +; without a signature change, because [creed]'s inputs (temporal/observed/ +; date) have no notion of "this Mass is a Requiem". That argument was +; wrong: {!Colour.Black} is used by exactly TWO celebrations in the whole +; engine (verified by grepping every [colour Black]/[Colour.Black] site in +; lib/ and data/) -- [commemoration-of-all-souls] (data/ef/sanctoral.sexp) +; and Good Friday (temporal_ef.ml, already [false] via the RG 23(b) feria +; exclusion regardless of colour, and has no Mass at all in the +; 1955-restored Holy Week) -- so on every day this engine can construct, +; [colour = Black] if and only if the Mass is a Requiem: a citable +; implication (RG 117 assigns black to Masses of the dead) on THIS DATA, +; not a heuristic guess. [Rite_ef.Rubrics_ef.creed] now reads +; [observed.colour] as RG 476(f)'s own guard, positioned ahead of 475(b)'s +; rank branch; see rubrics_ef.ml's own header and the guard's own comment +; for the full account, and test_rubrics_ef.ml's +; [test_colour_black_population_is_exactly_two] for the test that fails +; loudly the day a third [Colour.Black] celebration is ever added, so this +; proxy cannot silently rot. +; +; BLAST RADIUS, measured (full 1583-9999 sweep of {!Colitur_kernel. +; Calendar.year}, grouped by [observed]'s own slug): 8 416 days changed +; from [true] to [false], every one [commemoration-of-all-souls] (missing +; from exactly 1 of the 8 417 domain years -- a boundary-year transfer +; effect at 1583/9999, not a third population member: see the "know what +; each layer cannot see"-style caveats elsewhere in this project for other +; instances of the same edge). A further 8 416 [Colour.Black] days are +; Good Friday ([ef-passiontide-2-friday]), unchanged by this fix (already +; [false] before it, via the earlier feria exclusion) -- confirmed +; [creed_true_among_black = 0] after the fix, over the WHOLE domain, not +; merely the fixture's own 2024-2025 window. +; +; `colitur day`/`colitur readings` are unaffected (neither prints [creed]); +; `colitur rubrics` output changes on exactly the 8 416 days above. + +; L2 -- OPEN, colitur's own gap, found while building L1's fix (whole- +; branch review finding 2, 2026-08-22). NOT an active entry in this +; file's own machine-checked sense (no code loads or cross-checks an +; "L2" id anywhere -- this file's own [allow_entry] machinery is scoped +; to the CREED axis, {!test_lms_ordo.test_creed_matches_or_is_explained} +; alone; a second, unrelated axis reusing the same id-lookup mechanism +; would let one test's "declared but never fired" check spuriously trip +; on the other axis's own entry). Recorded here as prose only, the same +; discipline this file's own closed L1 note above and +; expected-divergences.sexp's own closed C-entries already use for a +; citation worth preserving without a live parser hook -- the REAL +; enforcement is test_lms_ordo.ml's own [test_formulary_override_matches], +; which asserts this population is exactly 3 days directly. +; +; Strengthening test_lms_ordo.ml's formulary-override check from PRESENCE +; to the actual STRING (this same finding 2) surfaced a real, separate +; defect in step 3 of the reading chain ({!Rite_ef.Lectionary_ef. +; readings}), independent of the Creed axis above. Three real days in the +; fixture window -- 2025-05-30 (Friday), 2025-06-02 (Monday), 2025-06-03 +; (Tuesday), all between Ascension Thursday and the following Sunday -- +; have no proper of their own and fall to {!Colitur_kernel. +; Mass_formulary.Preceding_sunday}. colitur resumes the nearest CALENDAR +; Sunday (the "5th"/"6th Sunday after Easter", Paschaltide's own week +; 6/7), but the Missal, and the Ordo, keep saying ASCENSION'S OWN Mass +; through this stretch instead: "Mass of the Ascension" on all three +; days, never a numbered-Sunday title. Step 3 has no notion of "inside +; Ascension's own after-feast period" -- it always resumes the nearest +; preceding Sunday, numbered or not. +; +; STRUCTURAL, not a fixture artefact: the Ascension is a fixed Easter+39 +; (a Thursday inside Paschaltide week 6), so every feria whose own +; Preceding_sunday fallback would otherwise resolve to week 6 or 7 falls +; in this same stretch, every year -- this is not a coincidence of +; 2024-2025 alone, though only this fixture's own window has been checked +; against a real Ordo. +; +; NOT FIXED in this task: fixing it means teaching step 3, or the +; lectionary data, about Ascension's own after-feast period -- the same +; shape as the Christmastide "infra octavam Nativitatis" entries +; data/ef/lectionary.sexp already carries directly rather than resolving +; through this fallback -- a lectionary-data change out of a fix round's +; own scope. test/test_lms_ordo.ml's own +; [expected_preceding_sunday_override] excludes exactly these two +; (season, week) pairs from its general mapping, and +; [test_formulary_override_matches] asserts the excluded population is +; exactly 3 real days, all showing "Mass of the Ascension", so a change +; to this population (a fourth day, a different Ordo string) would be +; caught rather than silently absorbed. +; +; Domain-wide count: unmeasured -- "which feria is inside Ascension's own +; after-feast period" is not a distinct predicate anywhere in this +; codebase to sweep on. Structurally recurs every year, so on the order +; of 3 days/year x domain years, not merely 3 total. -- cgit v1.3