aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/test_calendar.ml2
-rw-r--r--test/test_differential.ml23
-rw-r--r--test/test_golden.ml95
-rw-r--r--test/test_precedence.ml2
-rw-r--r--test/test_precedence_ef.ml158
-rw-r--r--test/test_rite_ef.ml45
-rw-r--r--test/test_validate.ml12
7 files changed, 228 insertions, 109 deletions
diff --git a/test/test_calendar.ml b/test/test_calendar.ml
index 505994e..8770017 100644
--- a/test/test_calendar.ml
+++ b/test/test_calendar.ml
@@ -82,7 +82,7 @@ module Fixture = struct
test below a genuine Precedence-native omission (distinct from a
deferred one) to exercise. *)
let rules : (season, rank) P.rules =
- { P.band; disposition; admit = (fun ~observed:_ cs -> List.filteri (fun i _ -> i < 1) cs) }
+ { P.band; disposition; admit = (fun ~observed:_ ~temporal:_ cs -> List.filteri (fun i _ -> i < 1) cs) }
(* RG 96, generic form: search forward from the day after [origin] for the
first day whose occupant is not "blocking" -- in this synthetic
diff --git a/test/test_differential.ml b/test/test_differential.ml
index aa75737..e12cd9a 100644
--- a/test/test_differential.ml
+++ b/test/test_differential.ml
@@ -450,19 +450,16 @@ let layer_c_reason (l : row) (c : row) diffs =
&& subset diffs [ Slug_f; Rank; Colour_f ]
then Some "C10"
else if String.equal c.slug "ef-passiontide-2-thursday" && diffs = [ Colour_f ] then Some "C11"
- (* RG16(a) task (register §6.0 + the sanctoral subject audit, this task's
- own report): 2 February on a Sunday. colitur now observes the Sunday
- (data/ef/adjustments.sexp retags the Purification `Bvm`, so it no
- longer bands at RG 91 entry 14 -- only a Feast of the LORD does); the
- Purification survives as its own commemoration, matching the register's
- ruling, just not as [c]'s OBSERVED slug here. lectio still tags it
- `class = lord` (unretagged upstream) and so still observes it outright.
- Matched on [l.slug] (lectio's side), the only side that can show this
- literal now -- colitur's own [c.slug] is whichever Sunday family the
- date falls in (time-after-epiphany or Septuagesima), not one fixed
- literal, unlike [c7]/[c11]'s single-slug tests above. *)
- else if String.equal l.slug "purification-of-the-blessed-virgin-mary" && subset diffs [ Slug_f; Colour_f ]
- then Some "C12"
+ (* RG16(a) task, fix round 1 (CRITICAL finding): a C12 entry briefly lived
+ here, allow-listing 2 February on a Sunday against lectio, when
+ `data/ef/adjustments.sexp` retagged the Purification `Bvm`. REVERTED --
+ the user has ruled: follow the oracle (register §6.0 has the full
+ account). The Purification is `Lord` again, colitur observes it
+ outright on those six 2-February Sundays, matching lectio's own
+ `class = lord` exactly -- no divergence to allow-list. Left
+ unimplemented here deliberately, not merely absent by oversight: this
+ comment is the record that C12 existed and was removed, should a
+ future reader wonder why the numbering skips it. *)
else None
(* ---------------------------------------------------------------------- *)
diff --git a/test/test_golden.ml b/test/test_golden.ml
index 85a129b..fb3cff4 100644
--- a/test/test_golden.ml
+++ b/test/test_golden.ml
@@ -501,16 +501,38 @@ let test_ii_class_sunday_admits_only_ii_class_commemoration () =
of the bug this pin closes -- before this fix `colitur day` admitted
"+ef-time-after-pentecost-sunday-9" here.
+ CORRECTED, fix round 1 (IMPORTANT finding, item 2): this pin used to
+ expect Pope Sixtus II et al. (6 August's own unrelated Class3 saint,
+ Commemoration_only) admitted as an ordinary commemoration in the freed
+ slot -- promoted from `colitur day`'s own actual output without
+ consulting either the primary text or the oracle first (the exact
+ vacuous-pin flavour the review caught, and this file's own header warns
+ against). Re-derived properly this time:
+ - PRIMARY TEXT: RG 16(a) itself says the winning Feast of the Lord holds
+ the Sunday's place cum omnibus iuribus et privilegiis -- WITH ALL the
+ Sunday's own rights and privileges. RG 111(b) is one of those: in
+ dominicis II classis, una tantum admittitur commemoratio, SCILICET DE
+ FESTO II CLASSIS -- a Sunday's own slot is reserved for a Class2
+ candidate specifically. The day is still a dominica II classis for
+ this purpose even though the Transfiguration, not the Sunday, is
+ [observed] -- so Sixtus (Class3) has no standing for the slot at all,
+ the same as on any other II-class Sunday (contrast
+ [test_ii_class_sunday_admits_only_ii_class_commemoration] above,
+ romanus, Class3, excluded the identical way on an ORDINARY II-class
+ Sunday).
+ - ORACLE, independently fetched (missalemeum's own /api/v5/calendar
+ JSON, not the small-model webpage summary, which proved unreliable for
+ this exact question): 2023-08-06 (a Sunday) -- title Transfiguration of
+ Our Lord, commemorations empty, displaced Pope Sixtus II, Felicissimus
+ and Agapitus, Martyrs -- Sixtus displaced, not commemorated. Control,
+ 2026-08-06 (a Thursday, no Sunday collision) -- Sixtus present in
+ commemorations. Being a Sunday is exactly what excludes him.
+
Deliberately NOT a bare "comms=[]" pin (this project's own catalogued
vacuity flavour: a count/emptiness assertion that would pass even if
nothing had ever been offered): [omitted_has] first proves the Sunday
really WAS a candidate that reached [disposition] and was actively
- excluded, not merely never constructed. And the Sunday is not the day's
- ONLY loser -- Pope Sixtus II, Felicissimus and Agapitus (Martyrs,
- Commemoration_only, III class, also fixed 6 August, unrelated to the
- Sunday) still receive their own ORDINARY commemoration exactly as RG
- 111(c)/(d) require: proof that RG 16(a) suppresses the SUNDAY
- specifically, not "every commemoration due that day". *)
+ excluded, not merely never constructed. *)
let test_rg16a_lord_feast_no_sunday_commemoration_2028 () =
let d = fetch 2028 8 6 in
Alcotest.(check bool)
@@ -518,35 +540,45 @@ let test_rg16a_lord_feast_no_sunday_commemoration_2028 () =
true
(omitted_has d "ef-time-after-pentecost-sunday-9");
Alcotest.(check string)
- "2028-08-06: the Transfiguration observed; the Sunday has NO commemoration (RG16a); an UNRELATED III-class \
- saint the same day still gets its own ordinary one"
+ "2028-08-06: the Transfiguration observed; NO commemoration at all -- RG16(a)'s own \"cum omnibus iuribus \
+ et privilegiis\" keeps the day a dominica II classis for RG111(b), so Sixtus (Class3) has no standing \
+ either, oracle-confirmed"
"2028-08-06 sunday season=time-after-pentecost week=9 slug=transfiguration-of-our-lord rank=class-2 \
- colour=white comms=[pope-sixtus-ii-felicissimus-and-agapitus-martyrs:ordinary] in=- out=[]"
+ colour=white comms=[] in=- out=[]"
(describe d)
-(* 2025-02-02: the other direction, and the change that made this task's
- two halves inseparable (this task's own report). The Purification (2
- Feb, calendarium "IN PURIFICATIONE B. MARIAE VIRG.") is a feast of the
- BLESSED VIRGIN, not of the Lord -- data/ef/adjustments.sexp retags it
- [Bvm] (the sanctoral audit, this task's report), so it no longer bands
- at RG 91 entry 14 and no longer outranks an occurring II-class Sunday
- (entry 16 > entry 15). `date -d 2025-02-02 +%A` = Sunday, independently
- confirmed. Register §6.0's own text: "Applying RG 16(a) to today's
- [pre-fix] data would then also suppress the Sunday's commemoration
- there" -- exactly the wrong outcome the data fix (not RG 16(a) itself)
- prevents: with the Purification correctly Bvm, RG 16(a)'s own winner-side
- [subject = Lord] conjunct never matches here, so the Sunday is simply the
- observed day and the Purification survives as its ordinary commemoration
- (RG 109/RG 111(b): a plain II-class candidate on a II-class Sunday, no
- privileged rival due). *)
+(* 2025-02-02, the other real instance of the SAME pattern -- not a
+ contrasting second direction, per this task's fix round 1 (CRITICAL
+ finding, item 1, reverted; see register §6.0 for the full account).
+
+ The Purification (2 Feb, calendarium "IN PURIFICATIONE B. MARIAE VIRG.")
+ stays [subject = Lord] -- the user has ruled: follow the oracle.
+ missalemeum treats it exactly as RG 16(a)'s own "festum Domini" case
+ (independently fetched, `/api/v5/calendar` JSON): 2020-02-02 (a Sunday)
+ -- `{"title":"Purification of the Blessed Virgin Mary","tags":["IV
+ Sunday after Epiphany"],...,"commemorations":[],"displaced":[]}` -- the
+ Sunday named only as a TAG (the underlying temporal placement), not
+ commemorated at all; matches 2014-02-02 exactly. Contrast, the SAME
+ oracle on an ordinary Marian feast (2019-09-08, the Nativity of the
+ BVM): `{"title":"XIII Sunday after Pentecost",...,"commemorations":
+ [{"title":"Nativity of the Blessed Virgin Mary",...}],...}` -- the
+ Sunday observed, the feast merely commemorated, the OPPOSITE pattern --
+ proving missalemeum does not treat every Marian feast this way, only the
+ Purification specifically. `date -d 2025-02-02 +%A` = Sunday,
+ independently confirmed.
+
+ Unlike 2028-08-06, no second sanctoral candidate exists on 2 February
+ (data/ef/sanctoral.sexp has exactly one 2 February entry) -- a genuinely
+ clean "comms=[]" case, complementing the pair above rather than
+ duplicating it. *)
let test_purification_on_a_sunday_2025 () =
check
~msg:
- "2025-02-02: the Sunday observed (Purification retagged Bvm, no longer a Feast of the Lord); the \
- Purification survives as an ordinary commemoration, not suppressed"
+ "2025-02-02: the Purification observed (subject Lord, unretagged -- the oracle's own treatment); NO \
+ commemoration of the Sunday, oracle-confirmed"
2025 2 2
- "2025-02-02 sunday season=time-after-epiphany week=4 slug=ef-time-after-epiphany-sunday-4 rank=class-2 \
- colour=green comms=[purification-of-the-blessed-virgin-mary:ordinary] in=- out=[]"
+ "2025-02-02 sunday season=time-after-epiphany week=4 slug=purification-of-the-blessed-virgin-mary \
+ rank=class-2 colour=white comms=[] in=- out=[]"
let suite =
( "golden pins (known-tricky years)",
@@ -574,10 +606,11 @@ let suite =
Alcotest.test_case "IV-class ferias never commemorated (2026)" `Quick test_iv_class_ferias_never_commemorated;
Alcotest.test_case "RG111(b): a II-class Sunday admits only a de-festo-II-classis commemoration (2009, 2026)"
`Quick test_ii_class_sunday_admits_only_ii_class_commemoration;
- Alcotest.test_case "RG16(a): a Feast of the Lord leaves the impeded Sunday with no commemoration (2028-08-06)"
+ Alcotest.test_case
+ "RG16(a): a Feast of the Lord leaves the impeded Sunday with NO commemoration at all, not even an \
+ unrelated saint's own (2028-08-06, rubric + oracle)"
`Quick test_rg16a_lord_feast_no_sunday_commemoration_2028;
Alcotest.test_case
- "RG16(a) does not fire for the (corrected) Purification: the Sunday observed, the Purification \
- commemorated (2025-02-02)"
+ "RG16(a), the Purification (oracle-ruled): observed outright, the Sunday not commemorated (2025-02-02)"
`Quick test_purification_on_a_sunday_2025
] )
diff --git a/test/test_precedence.ml b/test/test_precedence.ml
index 369c490..ff75baa 100644
--- a/test/test_precedence.ml
+++ b/test/test_precedence.ml
@@ -26,7 +26,7 @@ let rules =
| Cel.Feast -> (match loser.P.cel.Cel.rank with
| Hi -> P.Transfer
| Lo -> P.Commemorate P.Ordinary));
- admit = (fun ~observed:_ cs -> List.filteri (fun i _ -> i < 2) cs) }
+ admit = (fun ~observed:_ ~temporal:_ cs -> List.filteri (fun i _ -> i < 2) cs) }
let slug_of c = S.to_string c.P.cel.Cel.slug
diff --git a/test/test_precedence_ef.ml b/test/test_precedence_ef.ml
index facf3eb..52de989 100644
--- a/test/test_precedence_ef.ml
+++ b/test/test_precedence_ef.ml
@@ -290,7 +290,7 @@ let test_all_souls_yields_to_sunday () =
let rules =
{ P.band = (fun c cd -> PE.band c cd);
disposition = (fun ~winner:_ ~loser:_ -> P.Omit);
- admit = (fun ~observed:_ cs -> cs) }
+ admit = (fun ~observed:_ ~temporal:_ cs -> cs) }
in
let resolution = P.resolve rules day_ctx ~temporal:sunday ~sanctoral:[ all_souls ] in
Alcotest.(check string) "the Sunday is observed, not All Souls"
@@ -812,31 +812,58 @@ let observed_class3 = cand ~rank:V.Class3 "ef-some-class3-day"
let slugs_of admitted =
List.map (fun (c, _) -> S.to_string c.P.cel.Cel.slug) admitted
+(* Real-data shapes for the fix round's own RG16(a)/[admit] interaction
+ (below): a Feast of the Lord (subject Lord, Class2, sanctoral) as
+ [observed], oracle-confirmed real slugs/ranks rather than hand-typed
+ ones, the same coupling-safety reason [of_temporal] rows elsewhere in
+ this file use real data. *)
+let lord_winner =
+ cand ~origin:P.Sanctoral ~rank:V.Class2 ~subject:Sub.Lord ~layer:PE.universal_layer
+ "transfiguration-of-our-lord"
+
+(* Pope Sixtus II et al. (6 August, real slug/rank/status from
+ data/ef/sanctoral.sexp): Class3, Commemoration_only, tagged [Ordinary]
+ here directly (as every other [admit_cases] row does, isolating
+ [admit]'s own selection logic from [privilege_of], per this table's own
+ header comment). *)
+let sixtus =
+ cand ~origin:P.Sanctoral ~rank:V.Class3 ~status:Cel.Commemoration_only
+ ~layer:PE.universal_layer "pope-sixtus-ii-felicissimus-and-agapitus-martyrs"
+
+(* (description, observed, temporal, comms, expected). [temporal] --
+ {!Precedence.rules.admit}'s own new parameter, fix round 1 (RG16(a)
+ task): the day's temporal-cycle candidate, independent of who is
+ [observed]. Every row below except the last two repeats [observed] as
+ [temporal] -- no RG16(a) displacement occurs in those rows (the pattern
+ [PE.admit]'s pre-fix code implicitly, and wrongly, assumed held
+ UNIVERSALLY), so the two values coinciding is the faithful shape, not a
+ simplification that dodges the new parameter. The last two rows are
+ where they genuinely differ -- see their own comment. *)
let admit_cases =
[ (* RG 111 (§4): "I class: none save one privileged." *)
( "I-class day, only an ordinary commemoration due -> none admitted",
- observed_class1,
+ observed_class1, observed_class1,
[ (ordinary_hi, P.Ordinary) ],
[] );
( "I-class day, ordinary + privileged both due -> only the privileged \
one, regardless of the ordinary one's higher dignity",
- observed_class1,
+ observed_class1, observed_class1,
[ (ordinary_hi, P.Ordinary); (privileged_lo, P.Privileged) ],
[ "ef-privileged-lo" ] );
( "I-class day, two privileged due -> only the higher-dignity one (still \
just \"one\")",
- observed_class1,
+ observed_class1, observed_class1,
[ (privileged_lo, P.Privileged); (privileged_hi, P.Privileged) ],
[ "ef-privileged-hi" ] );
(* RG 111: "II-class Sundays: one (dropped if a privileged one is due)." *)
( "II-class Sunday, only an ordinary commemoration due -> it is admitted",
- observed_class2_sunday,
+ observed_class2_sunday, observed_class2_sunday,
[ (ordinary_hi, P.Ordinary) ],
[ "ef-ordinary-hi" ] );
( "II-class Sunday, ordinary (higher dignity) + privileged (lower \
dignity) both due -> the PRIVILEGED one is admitted, the ordinary \
one dropped despite outranking it",
- observed_class2_sunday,
+ observed_class2_sunday, observed_class2_sunday,
[ (ordinary_hi, P.Ordinary); (privileged_lo, P.Privileged) ],
[ "ef-privileged-lo" ] );
(* RG 111(b)'s own rank floor ("scilicet DE FESTO II CLASSIS"), fix
@@ -848,7 +875,7 @@ let admit_cases =
below, which has no such restriction. *)
( "II-class Sunday, sole candidate is an ORDINARY Class3 (not \
\"de festo II classis\") -> admitted nothing, not the best available",
- observed_class2_sunday,
+ observed_class2_sunday, observed_class2_sunday,
[ (ordinary_class3, P.Ordinary) ],
[] );
(* RG 111: "other II class: one" -- no privilege override, the exact
@@ -857,23 +884,55 @@ let admit_cases =
observed day, OPPOSITE winner. *)
( "other II-class day, only an ordinary commemoration due -> it is \
admitted",
- observed_class2_other,
+ observed_class2_other, observed_class2_other,
[ (ordinary_hi, P.Ordinary) ],
[ "ef-ordinary-hi" ] );
( "other II-class day, same ordinary+privileged pair as the Sunday row \
above -> the ORDINARY one wins on pure dignity this time, the \
privileged one dropped",
- observed_class2_other,
+ observed_class2_other, observed_class2_other,
[ (ordinary_hi, P.Ordinary); (privileged_lo, P.Privileged) ],
[ "ef-ordinary-hi" ] );
(* RG 111: "III-IV class: at most two" -- three candidates due, top two
by dignity admitted, the third (lowest dignity) dropped. *)
( "III-class day, three commemorations due -> the top two by dignity, \
not merely \"two of them\"",
- observed_class3,
+ observed_class3, observed_class3,
[ (ordinary_hi, P.Ordinary); (privileged_lo, P.Privileged);
(ordinary_lowest, P.Ordinary) ],
- [ "ef-ordinary-hi"; "ef-privileged-lo" ] )
+ [ "ef-ordinary-hi"; "ef-privileged-lo" ] );
+ (* Fix round 1, item 2 (RG16(a) task review): the CRITICAL witness for
+ [~temporal]. RG 16(a)'s own text -- the winning Feast of the Lord
+ holds the Sunday's place "cum omnibus iuribus et privilegiis" -- means
+ the day is STILL a "dominica II classis" for RG 111(b)'s own rank
+ floor, even though [observed] is now the FEAST (Transfiguration, real
+ slug/rank/subject), not the Sunday. [temporal] (a real Sunday
+ candidate, {!an_ordinary_sunday}) is what reveals that; nothing in
+ [observed] does, since its own slug carries no Sunday marker at all.
+ Oracle-confirmed (missalemeum, 2023-08-06, a Sunday):
+ "commemorations": [], Sixtus "displaced". Before this fix
+ [observed_is_sunday] read [observed]'s own slug and got [false] here,
+ wrongly taking the "other II class: one" branch below and admitting
+ Sixtus (Class3) despite RG 111(b)'s rank floor. *)
+ ( "RG16(a) interaction: a Feast of the Lord observed on a day whose \
+ TEMPORAL candidate is a II-class Sunday -> the RG111(b) rank floor \
+ still applies, admits nothing (Sixtus, Class3, has no standing)",
+ lord_winner, an_ordinary_sunday,
+ [ (sixtus, P.Ordinary) ],
+ [] );
+ (* The control, same pair as the row above with [observed] = [temporal]
+ (no displacement -- an ordinary WEEKDAY, not a Sunday): "other II
+ class: one", no rank floor, Sixtus IS admitted. Oracle-confirmed
+ (missalemeum, 2026-08-06, a Thursday): Sixtus in "commemorations".
+ Proves the DISCRIMINATING factor is [temporal]'s own Sunday-ness, not
+ merely "was the winner a Feast of the Lord" -- that alone is true of
+ BOTH rows here, and only one of them excludes Sixtus. *)
+ ( "control: the same Feast of the Lord on an ORDINARY weekday (temporal \
+ = observed, not a Sunday) -> \"other II class: one\", Sixtus IS \
+ admitted",
+ lord_winner, lord_winner,
+ [ (sixtus, P.Ordinary) ],
+ [ "pope-sixtus-ii-felicissimus-and-agapitus-martyrs" ] )
]
(* Order independence (brief: "the admitted set must not depend on input
@@ -886,8 +945,10 @@ let test_admit_order_independent () =
let comms =
[ (ordinary_hi, P.Ordinary); (privileged_lo, P.Privileged); (ordinary_lowest, P.Ordinary) ]
in
- let forward = slugs_of (PE.admit ~observed:observed_class3 comms) in
- let reversed = slugs_of (PE.admit ~observed:observed_class3 (List.rev comms)) in
+ let forward = slugs_of (PE.admit ~observed:observed_class3 ~temporal:observed_class3 comms) in
+ let reversed =
+ slugs_of (PE.admit ~observed:observed_class3 ~temporal:observed_class3 (List.rev comms))
+ in
Alcotest.(check (list string)) "reversed input admits the same candidates"
forward reversed
@@ -1023,25 +1084,34 @@ let test_ii_class_sunday_privileged_witness_admitted_end_to_end () =
(List.map (fun (c, reason) -> (S.to_string c.P.cel.Cel.slug, reason)) resolution.P.omitted)
(* RG 16(a) (register §6.0) reached end-to-end through the REAL pipeline
- ([PE.band] AND [PE.disposition] together, not [disposition] in
- isolation as [disposition_cases]'s own rows above test it): a real civil
- date this task's own blast-radius measurement names as a live instance
- of the bug this branch fixes -- 6 August 2028 is a Sunday (independently
- checked with `date -d 2028-08-06 +%A`, the same cross-check discipline
- [test_golden.ml]'s own header requires), Time after Pentecost week 9, and
- the Transfiguration (6 Aug, II class, "IN TRANSFIGURATIONE D. N. I. C.")
- falls on it. Before this fix `colitur day` emitted this Sunday as an
- admitted [+ef-time-after-pentecost-sunday-9] commemoration on that date
- (register §6.0's own reproduction); this proves the full pipeline now
- agrees with the isolated [disposition] rows above: [observed] is the
+ ([PE.band], [PE.disposition] AND [PE.admit] together, not any one of
+ them in isolation as this file's own hand-tagged rows test them
+ separately): a real civil date this task's own blast-radius measurement
+ names as a live instance of the bug this branch fixes -- 6 August 2028
+ is a Sunday (independently checked with `date -d 2028-08-06 +%A`, the
+ same cross-check discipline [test_golden.ml]'s own header requires),
+ Time after Pentecost week 9, and the Transfiguration (6 Aug, II class,
+ "IN TRANSFIGURATIONE D. N. I. C.") falls on it. Before this fix
+ `colitur day` emitted this Sunday as an admitted
+ [+ef-time-after-pentecost-sunday-9] commemoration on that date (register
+ §6.0's own reproduction).
+
+ Fix round 1 (item 2): a THIRD candidate, Pope Sixtus II et al. (real
+ slug/rank/status, 6 August, unrelated to the Sunday), is now also
+ offered, so this test exercises BOTH fixes at once, the same real shape
+ [test_golden.ml]'s own 2028-08-06 pin does: [observed] is the
Transfiguration ({!band} entry 14 already did this correctly before this
- task), [commemorations] is EMPTY (not merely missing the Sunday from
- [admit]'s cut -- RG 16(a) is a [disposition]-level Omit, before [admit]
- ever runs), and the Sunday appears in [omitted] with
- ["omitted: yielded to a higher day"] ({!Precedence.resolve}'s own Omit
- reason), never ["omitted: admission limit reached"] (that reason would
- mean the Sunday was tagged [Commemorate] and then cut by [admit] -- a
- different, wrong mechanism for the same wrong end state). *)
+ task); the Sunday is [disposition]-level [Omit] (RG 16(a)); Sixtus is
+ [disposition]-level [Commemorate], but [admit] then excludes him too --
+ RG 111(b)'s rank floor, reached only because [admit] reads the day's
+ Sunday-ness off [~temporal] (the [sunday] candidate passed to
+ [P.resolve]), not off [observed] (the Transfiguration, whose own slug
+ carries no Sunday marker). [commemorations] is EMPTY, and BOTH losers
+ land in [omitted] with their own distinct reasons -- the Sunday via
+ [disposition]'s own Omit ("omitted: yielded to a higher day"), Sixtus via
+ [admit]'s cut ("omitted: admission limit reached") -- proving the two
+ fixes operate through genuinely different mechanisms, not the same one
+ coincidentally producing the same string. *)
let test_rg16a_lord_feast_suppresses_sunday_end_to_end () =
let date = mk 2028 8 6 in
let day_ctx = ctx date in
@@ -1050,15 +1120,25 @@ let test_rg16a_lord_feast_suppresses_sunday_end_to_end () =
cand ~origin:P.Sanctoral ~rank:V.Class2 ~subject:Sub.Lord ~layer:PE.universal_layer
"transfiguration-of-our-lord"
in
- let resolution = P.resolve real_rules day_ctx ~temporal:sunday ~sanctoral:[ transfiguration ] in
+ let sixtus =
+ cand ~origin:P.Sanctoral ~rank:V.Class3 ~status:Cel.Commemoration_only ~layer:PE.universal_layer
+ "pope-sixtus-ii-felicissimus-and-agapitus-martyrs"
+ in
+ let resolution =
+ P.resolve real_rules day_ctx ~temporal:sunday ~sanctoral:[ transfiguration; sixtus ]
+ in
Alcotest.(check string) "the Transfiguration is observed, not the Sunday"
"transfiguration-of-our-lord" (S.to_string resolution.P.observed.P.cel.Cel.slug);
- Alcotest.(check int) "no commemorations at all -- RG16(a)'s own \"nulla fit commemoratio\""
+ Alcotest.(check int)
+ "no commemorations at all -- RG16(a)'s own \"nulla fit commemoratio\" AND RG111(b)'s rank floor, both live"
0 (List.length resolution.P.commemorations);
Alcotest.(check (list (pair string string)))
- "the Sunday is omitted with RG16(a)'s own disposition-level reason, not admit's cut"
- [ ("ef-time-after-pentecost-sunday-9", "omitted: yielded to a higher day") ]
- (List.map (fun (c, reason) -> (S.to_string c.P.cel.Cel.slug, reason)) resolution.P.omitted)
+ "both losers omitted, via two DIFFERENT mechanisms: the Sunday at disposition-level (RG16a), Sixtus at \
+ admit's own cut (RG111b)"
+ [ ("ef-time-after-pentecost-sunday-9", "omitted: yielded to a higher day");
+ ("pope-sixtus-ii-felicissimus-and-agapitus-martyrs", "omitted: admission limit reached") ]
+ (List.map (fun (c, reason) -> (S.to_string c.P.cel.Cel.slug, reason)) resolution.P.omitted
+ |> List.sort compare)
(* Completes Task 7's carried fix (RG 91 entry 8, §4): on a real Sunday
landing on 2 November, All Souls does not merely lose (that was Task 7's
@@ -1091,7 +1171,7 @@ let test_all_souls_transfers_end_to_end () =
origin = P.Temporal }
in
let all_souls = cand ~origin:P.Sanctoral ~layer:PE.universal_layer "ef-all-souls" in
- let rules = { P.band = PE.band; disposition = PE.disposition; admit = (fun ~observed:_ cs -> cs) } in
+ let rules = { P.band = PE.band; disposition = PE.disposition; admit = (fun ~observed:_ ~temporal:_ cs -> cs) } in
let resolution = P.resolve rules day_ctx ~temporal:sunday ~sanctoral:[ all_souls ] in
Alcotest.(check (list string)) "All Souls is deferred (transferred), not omitted or commemorated"
[ "ef-all-souls" ]
@@ -1281,10 +1361,10 @@ let suite =
Alcotest.test_case "All Souls transfers end-to-end (resolve, real rules)" `Quick
test_all_souls_transfers_end_to_end ]
@ List.map
- (fun (desc, observed, comms, expect) ->
+ (fun (desc, observed, temporal, comms, expect) ->
Alcotest.test_case desc `Quick (fun () ->
Alcotest.(check (list string)) desc expect
- (slugs_of (PE.admit ~observed comms))))
+ (slugs_of (PE.admit ~observed ~temporal comms))))
admit_cases
@ [ Alcotest.test_case "admit is order-independent (III-class, 3 candidates)" `Quick
test_admit_order_independent;
diff --git a/test/test_rite_ef.ml b/test/test_rite_ef.ml
index ad9057b..6fcb25d 100644
--- a/test/test_rite_ef.ml
+++ b/test/test_rite_ef.ml
@@ -88,22 +88,30 @@ let test_vigil_of_christmas_suppressed () =
appears_anywhere
(* RG16(a) task (register §6.0 + the sanctoral subject audit, this task's
- own report): data/ef/sanctoral.sexp is left untouched (still a faithful
- mirror of lectio, subject `Lord` for both entries below -- see
- test_sanctoral_ef.ml's own "explicit class = lord" spot-check, which
- loads that file WITHOUT applying this overlay and still passes); the
- correction lives entirely in data/ef/adjustments.sexp's two [Edit]
- directives, the same mechanism [test_vigil_of_christmas_suppressed]
- above already proves for a sibling bootstrap defect. This is the ONE
- test in the suite that observes the two retags actually take effect
- through the real pipeline -- without it, a typo in either directive's
- slug (silently a no-op diagnostic, not a hard failure -- Overlay.apply's
- own contract) or a reverted adjustments.sexp would leave every other
- test green (2 February isn't a Sunday in any golden-pinned year, and
- [test_sanctoral_ef.ml] deliberately never applies the overlay). Also
- re-verifies the four entries the audit confirmed correct and left
- untouched, so a future accidental retag of one of THEM would be caught
- here too, not just the two that changed. *)
+ own report). data/ef/sanctoral.sexp is left untouched (still a faithful
+ mirror of lectio, subject `Lord` for every entry below except
+ `most-holy-name-of-mary` -- see test_sanctoral_ef.ml's own "explicit
+ class = lord" spot-check, which loads that file WITHOUT applying this
+ overlay and still passes); the one real correction lives entirely in
+ data/ef/adjustments.sexp's single remaining [Edit] directive, the same
+ mechanism [test_vigil_of_christmas_suppressed] above already proves for
+ a sibling bootstrap defect.
+
+ CORRECTED, fix round 1 (CRITICAL finding, item 1): this test used to
+ also assert `purification-of-the-blessed-virgin-mary` was retagged
+ `Bvm`. REVERTED -- the user has ruled: follow the oracle (register §6.0
+ has the full account, both the calendarium argument for `Bvm` and the
+ oracle evidence against it). The Purification is `Lord` again, one of
+ FIVE untouched entries this test now re-verifies, not four.
+
+ This is the ONE test in the suite that observes the one live retag
+ actually takes effect through the real pipeline -- without it, a typo in
+ the directive's slug (silently a no-op diagnostic, not a hard failure --
+ Overlay.apply's own contract) or a reverted adjustments.sexp would leave
+ every other test green ([test_sanctoral_ef.ml] deliberately never
+ applies the overlay). Also re-verifies the five entries the audit
+ confirmed correct and left untouched, so a future accidental retag of
+ one of THEM would be caught here too, not just the one that changed. *)
let test_rg16a_subject_retag_in_effect () =
let layer = real_layer () in
let subject_of slug =
@@ -111,10 +119,11 @@ let test_rg16a_subject_retag_in_effect () =
| Some e -> e.Layer.cel.Cel.subject
| None -> Alcotest.failf "slug %s not found in the overlaid layer" slug
in
- Alcotest.(check bool) "Purification retagged Bvm (calendarium: \"B. MARIAE VIRG.\")" true
- (subject_of "purification-of-the-blessed-virgin-mary" = Subject.Bvm);
Alcotest.(check bool) "Most Holy Name of Mary retagged Bvm (calendarium: \"Nominis Mariae\")" true
(subject_of "most-holy-name-of-mary" = Subject.Bvm);
+ Alcotest.(check bool)
+ "Purification stays Lord (reverted, fix round 1 -- the user's ruling: follow the oracle)" true
+ (subject_of "purification-of-the-blessed-virgin-mary" = Subject.Lord);
Alcotest.(check bool) "Precious Blood stays Lord (calendarium: \"D. N. I. C.\") -- audit, not touched" true
(subject_of "precious-blood-of-our-lord-jesus-christ" = Subject.Lord);
Alcotest.(check bool) "Transfiguration stays Lord (calendarium: \"D. N. I. C.\") -- audit, not touched" true
diff --git a/test/test_validate.ml b/test/test_validate.ml
index 89053c1..42c58f5 100644
--- a/test/test_validate.ml
+++ b/test/test_validate.ml
@@ -225,7 +225,7 @@ module Synthetic = struct
let rules : (season, rank) P.rules =
{ P.band = (fun _ _ -> 0);
disposition = (fun ~winner:_ ~loser:_ -> P.Omit);
- admit = (fun ~observed:_ _ -> []) }
+ admit = (fun ~observed:_ ~temporal:_ _ -> []) }
let year_start y = match D.make ~year:y ~month:1 ~day:1 with Ok d -> d | Error e -> failwith e
@@ -377,7 +377,7 @@ module Synthetic = struct
let dup_rules : (season, rank) P.rules =
{ P.band = (fun _ c -> match c.P.origin with P.Temporal -> 0 | P.Sanctoral -> 10);
disposition = (fun ~winner:_ ~loser:_ -> P.Commemorate P.Ordinary);
- admit = (fun ~observed:_ cs -> List.map (fun (c, p) -> ({ c with P.origin = c.P.origin }, p)) cs) }
+ admit = (fun ~observed:_ ~temporal:_ cs -> List.map (fun (c, p) -> ({ c with P.origin = c.P.origin }, p)) cs) }
(* "unconverged": two entries collide on one date (6 June), both beating
the temporal office and tied with each other, so slug decides:
@@ -416,7 +416,7 @@ module Synthetic = struct
disposition =
(fun ~winner:_ ~loser ->
match loser.P.cel.Cel.rank with R1 -> P.Transfer | R2 -> P.Commemorate P.Ordinary);
- admit = (fun ~observed:_ cs -> cs) }
+ admit = (fun ~observed:_ ~temporal:_ cs -> cs) }
let guard_transfer_target (_ : rank P.candidate) (origin : D.t) (_ : D.t -> rank Cel.t) = origin
@@ -444,7 +444,7 @@ module Synthetic = struct
{ P.band = (fun _ c -> match c.P.origin with P.Temporal -> 0 | P.Sanctoral -> 10);
disposition = (fun ~winner:_ ~loser:_ -> P.Commemorate P.Ordinary);
admit =
- (fun ~observed:_ cs ->
+ (fun ~observed:_ ~temporal:_ cs ->
let sorted = List.stable_sort adm_compare_slug cs in
if List.length sorted mod 2 = 1 then adm_take 2 sorted else adm_take 1 sorted) }
@@ -475,7 +475,7 @@ module Synthetic = struct
disposition =
(fun ~winner:_ ~loser ->
match loser.P.cel.Cel.rank with R1 -> P.Transfer | R2 -> P.Commemorate P.Ordinary);
- admit = (fun ~observed:_ cs -> cs) }
+ admit = (fun ~observed:_ ~temporal:_ cs -> cs) }
let collide_d2 = match D.make ~year:2026 ~month:2 ~day:10 with Ok d -> d | Error e -> failwith e
let collide_transfer_target (_ : rank P.candidate) (_ : D.t) (_ : D.t -> rank Cel.t) = collide_d2
@@ -492,7 +492,7 @@ module Synthetic = struct
let clean_sanctoral_rules : (season, rank) P.rules =
{ P.band = (fun _ c -> match c.P.origin with P.Temporal -> 0 | P.Sanctoral -> 10);
disposition = (fun ~winner:_ ~loser:_ -> P.Commemorate P.Ordinary);
- admit = (fun ~observed:_ cs -> cs) }
+ admit = (fun ~observed:_ ~temporal:_ cs -> cs) }
end
open Synthetic