summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-08-22 13:38:27 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-08-22 13:38:27 +0200
commit41263d60432fadd2aef3f04de66b60561f89cbec (patch)
treec7fcffcdb2650ea8c98b07b75c03f69e632b4b4a
parent3bfa0c459e3c0b5bfa962b7dbb0227db5a8ba09f (diff)
downloadcolitur-41263d60432fadd2aef3f04de66b60561f89cbec.tar.gz
colitur-41263d60432fadd2aef3f04de66b60561f89cbec.zip
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.
-rw-r--r--data/ef/expected-divergences-lms.sexp127
-rw-r--r--lib/rites/rite_ef/rubrics_ef.ml58
-rw-r--r--lib/rites/rite_ef/rubrics_ef.mli5
-rw-r--r--test/cli.t14
-rw-r--r--test/test_rubrics_ef.ml88
5 files changed, 247 insertions, 45 deletions
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.
+; 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".
;
-; 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.
+; 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.
;
-; 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))
+; 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.
diff --git a/lib/rites/rite_ef/rubrics_ef.ml b/lib/rites/rite_ef/rubrics_ef.ml
index 6345399..ab9da32 100644
--- a/lib/rites/rite_ef/rubrics_ef.ml
+++ b/lib/rites/rite_ef/rubrics_ef.ml
@@ -26,12 +26,37 @@
engine resolves ONE observed office and ONE Mass per civil day (see
Rite.t.readings' own doc comment) -- it has no separate "which votive
Mass is said" dimension. So the "vel/et...votivis" halves of 475(a)/(b),
- 476(c) entirely, 476(d)'s "et votivis" half, and 476(f) (Requiem Masses,
- also not modelled) are genuinely inapplicable to this implementation --
- a documented scope limit, not a defect. 476(e) needs no branch at all:
- [creed] below reads only [observed], never a day's admitted
- commemorations, so a commemoration can never change its answer by
- construction. *)
+ 476(c) entirely, and 476(d)'s "et votivis" half are genuinely
+ inapplicable to this implementation -- a documented scope limit, not a
+ defect. 476(e) needs no branch at all: [creed] below reads only
+ [observed], never a day's admitted commemorations, so a commemoration
+ can never change its answer by construction.
+
+ 476(f) ("in Missis defunctorum") is DIFFERENT: this file used to carry
+ it in the same "not modelled" list above, on the reasoning that
+ [creed]'s inputs (temporal/observed/date) have no notion of "this Mass
+ is a Requiem". That reasoning was wrong, found by the LMS Ordo layer
+ (test_lms_ordo.ml, allow-list entry L1, now closed -- see
+ expected-divergences-lms.sexp) on 2025-11-03, All Souls' Day: colitur
+ said the Creed where the Ordo, correctly, does not. [observed] DOES
+ carry a usable signal -- RG 117 assigns black to Masses of the dead,
+ and {!Colour.Black} is used by exactly TWO celebrations in this whole
+ engine, verified by grepping every [colour Black]/[Colour.Black] site
+ in lib/ and data/: [commemoration-of-all-souls] in
+ data/ef/sanctoral.sexp, and Good Friday in temporal_ef.ml (which is a
+ Holy Week FERIA, RG 23(b), already excluded by the [n >= -6 && n <=
+ -1] branch below regardless of colour, and has no Mass at all in the
+ 1955-restored Holy Week). So on every day this engine can actually
+ construct, [colour = Black] if and only if the Mass is a Requiem --
+ a citable implication ON THIS DATA, not a heuristic guess. [creed]
+ below uses it as 476(f)'s own guard. This is a PROXY, not a general
+ "is this a Requiem Mass" field, and it is only as good as that
+ two-member population: {!test_rubrics_ef}'s own
+ [test_colour_black_population_is_exactly_two] fails loudly the day a
+ third [Colour.Black] celebration is added anywhere, so the proxy
+ cannot silently rot into covering (or missing) a non-Requiem black
+ Mass. If that ever happens, this guard needs re-deriving, not merely
+ re-approving. *)
open Colitur_kernel
@@ -223,6 +248,27 @@ let creed ~(temporal : (Vocab_ef.season, Vocab_ef.rank) Temporal.t)
Precedence_ef.is_vigil slug
then false
else if
+ (* RG 476(f): "in Missis defunctorum" -- the Creed is never said at a
+ Requiem Mass, checked here, ahead of 475(b)'s rank branch, the same
+ "category excludes regardless of rank" position as the feria and
+ vigil checks immediately above (All Souls' Day is [Class1], so
+ without this guard 475(b) would grant it [true] unopposed, which is
+ exactly the defect this guard fixes -- see this file's own header
+ for the two-member [Colour.Black] population this proxy rests on,
+ and {!Colour.Black}'s own citation, RG 117, for why colour is the
+ Requiem signal. Placed before, not after, 475(b)/(c)/(e) so a black
+ Class1 or Class2 day can never reach them; nothing above this point
+ (the Nativity/Easter/Pentecost octave override, the Sunday rule, the
+ feria and vigil exclusions) is ever reachable by a Requiem Mass on
+ the shipped data either -- a Requiem is never kept on a Sunday or
+ inside a privileged octave -- so this guard's own position relative
+ to THOSE branches is moot on real data, checked, not merely assumed:
+ {!creed_apostle_slugs} and [marian_slugs] contain no Black-coloured
+ entry, and 2 November can never fall inside any of the three
+ octaves 475(d) names. *)
+ observed.Celebration.colour = Colour.Black
+ then false
+ else if
(* RG 475(b): "in festis I classis". Genuine feasts only, by
construction of the two exclusions immediately above (feria I
classis -- Ash Wednesday and Holy Week, the only feriae that are
diff --git a/lib/rites/rite_ef/rubrics_ef.mli b/lib/rites/rite_ef/rubrics_ef.mli
index 16e7491..7a1284b 100644
--- a/lib/rites/rite_ef/rubrics_ef.mli
+++ b/lib/rites/rite_ef/rubrics_ef.mli
@@ -29,7 +29,10 @@ val creed_apostle_slugs : string list
{!Liturgical_day.t.commemorations}: RG 476(e), "ratione alicuius
commemorationis in Missa occurrentis" [never say the Creed merely
because of a commemoration], holds by construction rather than by a
- checked branch. *)
+ checked branch. RG 476(f) ("in Missis defunctorum") reads
+ [observed]'s [colour]: see the .ml's own header for why [Colour.Black]
+ is a sound proxy for "this Mass is a Requiem" on the shipped data, and
+ what would have to be re-checked if that ever stops being true. *)
val creed :
temporal:(Vocab_ef.season, Vocab_ef.rank) Temporal.t ->
observed:Vocab_ef.rank Celebration.t ->
diff --git a/test/cli.t b/test/cli.t
index ac1351b..e2d2eb5 100644
--- a/test/cli.t
+++ b/test/cli.t
@@ -534,10 +534,20 @@ CSV run rather than one per year:
$ colitur emit --format csv --from 2027 --to 2028 | wc -l
732
-sexp and xml are also available:
+sexp and xml are also available. This line count moved 9010 -> 9011
+(whole-branch review fix round, RG 476(f)): [emit --format sexp] pretty-
+prints with [Sexplib.Sexp.to_string_hum], a column-width wrapping printer,
+not a fixed-shape one -- 2027's All Souls' Day (2 November) record grew a
+single wrapped line when its own [creed] field's value changed from
+[true] to [false] (RG 476(f), the Creed is never said at a Requiem Mass;
+see rubrics_ef.ml), because "false" is one character longer than "true"
+and pushed that one line's rendered width over to_string_hum's own wrap
+threshold. Purely cosmetic -- the record's DATA is unchanged in every
+other field, and this is not a claim that [emit]'s FORMAT changed, only
+that one record's pretty-printed SHAPE did:
$ colitur emit --format sexp --from 2027 --to 2027 | wc -l
- 9010
+ 9011
$ colitur emit --format xml --from 2027 --to 2027 | head -2
<?xml version="1.0" encoding="UTF-8"?>
diff --git a/test/test_rubrics_ef.ml b/test/test_rubrics_ef.ml
index 5109c69..a778a5a 100644
--- a/test/test_rubrics_ef.ml
+++ b/test/test_rubrics_ef.ml
@@ -26,6 +26,7 @@ module Colour = Colitur_kernel.Colour
module Subject = Colitur_kernel.Subject
module Slug = Colitur_kernel.Slug
module Temporal = Colitur_kernel.Temporal
+module Computus = Colitur_kernel.Computus
module V = Rite_ef.Vocab_ef
module RE = Rite_ef.Rubrics_ef
module TE = Rite_ef.Temporal_ef
@@ -175,6 +176,87 @@ let test_holy_saturday_easter_vigil_no_creed () =
by 476(a) ("in Missa Vigiliae paschalis"). *)
check "RG 23(b)/476(a): Holy Saturday (the Easter Vigil Mass)" 2026 4 4 false
+(* ---- RG 476(f): "in Missis defunctorum" -- the Creed is never said at a
+ Requiem Mass. Whole-branch review finding 1: colitur used to say [true]
+ here on rank alone (475(b), Class1) -- the LMS Ordo layer's own former
+ allow-list entry L1, now closed, was this exact day. See rubrics_ef.ml's
+ own header for why {!Colour.Black} is a sound RG 117 proxy for "this Mass
+ is a Requiem" on the shipped data. ---- *)
+
+let test_476f_all_souls_no_creed () =
+ (* 2025-11-03: All Souls' Day (2 November, a Sunday that year, transferred
+ to the next open day, RG's own Class1/black office unchanged by the
+ transfer) -- `colitur day 2025` confirms class-1/black/
+ commemoration-of-all-souls on this date. Before this fix [creed] here
+ was [true] via 475(b); the Ordo's own text ("No Cr") says otherwise. *)
+ check "RG 476(f): All Souls' Day (transferred), a Requiem, says no Creed" 2025 11 3 false
+
+let test_476f_good_friday_no_creed () =
+ (* 2026-04-03: Good Friday, [colour = Black] (temporal_ef.ml's own
+ [days_between easter d = -2] branch) -- already [false] via the RG
+ 23(b) feria-I-classis exclusion checked earlier in [creed], so this is
+ a belt-and-braces witness that the 476(f) guard, were it ever reached
+ first, would agree rather than a case that depends on it: Good Friday
+ has no Mass in the 1955-restored Holy Week to begin with. *)
+ check "RG 476(f)/RG 23(b): Good Friday, black, says no Creed" 2026 4 3 false
+
+(* Whole-branch review finding 1's own instruction: a test that FAILS if a
+ third {!Colour.Black} celebration is ever introduced, so the RG 476(f)
+ guard's colour proxy cannot silently rot into covering the wrong
+ population. Two independent checks, matching the two places a black
+ celebration could be added:
+
+ DATA: every entry the shipped sanctoral layer (sanctoral.sexp, with
+ adjustments.sexp merged on top -- the same [layer] every other test in
+ this file resolves against) carries directly, fixed AND movable alike
+ ({!Colitur_kernel.Layer.entries} holds the raw [Date_spec.t], not a
+ resolved index, so this needs no date walk at all to cover every civil
+ year).
+
+ CODE: {!Rite_ef.Temporal_ef.temporal}'s own colour logic, which
+ sanctoral.sexp cannot see (Good Friday's black is computed, not data) --
+ swept across a century the same span and for the same coverage reason
+ {!test_ferial_origin_never_carries_lord_bvm_or_apostle_slug} above
+ already uses, since a Colour.Black bug introduced into a rare branch
+ (an Ember day, Rogation Wednesday...) would not show up in one year. *)
+let test_colour_black_population_is_exactly_two () =
+ let black_data_entries =
+ List.filter
+ (fun (e : V.rank Colitur_kernel.Layer.entry) -> e.Colitur_kernel.Layer.cel.Cel.colour = Colour.Black)
+ layer.Colitur_kernel.Layer.entries
+ in
+ Alcotest.(check int) "exactly one Colour.Black entry in the shipped data" 1
+ (List.length black_data_entries);
+ (match black_data_entries with
+ | [ e ] ->
+ Alcotest.(check string) "the one Colour.Black data entry is All Souls" "commemoration-of-all-souls"
+ (Slug.to_string e.Colitur_kernel.Layer.cel.Cel.slug)
+ | _ -> ());
+ let code_black = ref [] in
+ for y = 1583 to 1682 do
+ let dec31 = mk y 12 31 in
+ let d = ref (mk y 1 1) in
+ while Date.compare !d dec31 <= 0 do
+ let t = TE.temporal !d in
+ if t.Temporal.office.Cel.colour = Colour.Black then code_black := (y, !d, t) :: !code_black;
+ d := Date.add_days !d 1
+ done
+ done;
+ Alcotest.(check bool) "the century sweep found at least 100 Colour.Black temporal days" true
+ (List.length !code_black >= 100);
+ List.iter
+ (fun (_, d, (t : (V.season, V.rank) Temporal.t)) ->
+ let easter = Computus.gregorian_easter (Date.year d) in
+ Alcotest.(check int)
+ (Printf.sprintf "%s: the only code-side Colour.Black day is Good Friday (Easter-2)"
+ (Date.to_iso8601 d))
+ (-2) (Date.to_rata d - Date.to_rata easter);
+ Alcotest.(check string)
+ (Printf.sprintf "%s: Good Friday's own slug" (Date.to_iso8601 d))
+ "ef-passiontide-2-friday"
+ (Slug.to_string t.Temporal.office.Cel.slug))
+ !code_black
+
(* ---- RG 476(b) negative: a plain II-class saint, not Domini/BVM, not an
Apostle/Evangelist ---- *)
@@ -381,6 +463,12 @@ let suite =
Alcotest.test_case "RG 23/476(a): Holy Thursday" `Quick test_holy_thursday_no_creed;
Alcotest.test_case "RG 23/476(a): Holy Saturday / Easter Vigil" `Quick
test_holy_saturday_easter_vigil_no_creed;
+ Alcotest.test_case "476(f): All Souls' Day (transferred), a Requiem, no Creed" `Quick
+ test_476f_all_souls_no_creed;
+ Alcotest.test_case "476(f)/RG 23(b): Good Friday, black, no Creed" `Quick
+ test_476f_good_friday_no_creed;
+ Alcotest.test_case "Colour.Black population is exactly two (data + code)" `Quick
+ test_colour_black_population_is_exactly_two;
Alcotest.test_case "476(b): plain II-class saint (negative)" `Quick
test_476b_plain_class2_saint;
Alcotest.test_case "vigils excluded even when Class2 and Marian" `Quick