aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-08-11 23:46:51 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-08-11 23:46:51 +0200
commit21dab521d6bfe8e4e7d04f761c11754059339ba2 (patch)
tree0efa49c48175bb4840a87b5a39ae0c297777cb5a
parent3583448631c1f1cf0767728d605a858fcb810cfc (diff)
downloadcolitur-21dab521d6bfe8e4e7d04f761c11754059339ba2.tar.gz
colitur-21dab521d6bfe8e4e7d04f761c11754059339ba2.zip
test(ef): prove the II-class-Sunday privilege override end-to-end
Adds test_ii_class_sunday_privileged_witness_admitted_end_to_end, proving RG 111's "II-class Sundays: one, dropped if a privileged one is due" clause through the real pipeline (band, disposition, privilege_of, admit together), not only at the isolated admit level. RG 109(b) is the one privileged category that is sanctoral and rank-based rather than temporal-origin: a Commemoration_only, Class1 sanctoral candidate (the same shape disposition_cases already uses as (b)'s witness) is held out of the band contest entirely by Precedence.resolve, so it always loses regardless of what wins the day. Paired with an ordinary sanctoral saint, both losing to an ordinary Class2 Sunday, gives observed_is_sunday = true with one privileged and one ordinary loser due at once, with no new fixture. Documents, and mutation-confirms, what this fixture does and does not prove: RG 109(b)'s only reachable witness is Class1 (the highest dignity), so the privileged loser here is unavoidably also the higher-dignity one, and the admission outcome alone cannot distinguish "privilege overrides dignity" from "dignity alone picked the same winner" -- that distinction remains admit_cases's job. What this test does prove, and what a category-(b) regression in privilege_of breaks, is the privilege tag itself surviving the real pipeline end-to-end.
-rw-r--r--test/test_precedence_ef.ml68
1 files changed, 67 insertions, 1 deletions
diff --git a/test/test_precedence_ef.ml b/test/test_precedence_ef.ml
index 09c41fd..a95b321 100644
--- a/test/test_precedence_ef.ml
+++ b/test/test_precedence_ef.ml
@@ -676,6 +676,69 @@ let test_privileged_lent_feria_admitted_end_to_end () =
resolution.P.commemorations);
Alcotest.(check int) "nothing omitted" 0 (List.length resolution.P.omitted)
+(* Fix round 1 (post-Task-9 review): the II-class-Sunday override (RG 111
+ "one, dropped if a privileged one is due") reached through the REAL
+ pipeline, with both a privileged AND an ordinary commemoration due on the
+ same day -- previously only proven at the isolated [admit] level
+ ([admit_cases]'s hand-tagged rows above). RG 109(a)-(f)'s five reachable
+ categories are all properties of a TEMPORAL-origin office, and only one
+ temporal candidate exists per date, so a privileged AND an ordinary
+ commemoration cannot both be due from the temporal side alone -- but
+ category (b) is the exception: it is sanctoral and rank-based (a
+ [Commemoration_only] entry carrying [Class1], the exact shape
+ [disposition_cases]'s own (b) witness row uses), and a [Commemoration_only]
+ entry is held out of the band contest entirely ({!Precedence.resolve}),
+ so it is a loser regardless of what [observed] turns out to be. Paired
+ with an ordinary sanctoral saint, both lose to an ordinary Class2 Sunday,
+ giving [observed_is_sunday = true] with one [Privileged] and one
+ [Ordinary] loser due at once -- no synthetic fixture needed.
+
+ NOTE on what this test does and does not prove: the only reachable
+ witness for RG 109(b) is [Class1] (the highest dignity), and any
+ sanctoral loser that could ALSO beat this same Sunday by pure dignity
+ would win the day outright instead of losing to it (any [Feast]-status
+ [Class1] sanctoral candidate bands at entry 11-13, ahead of an ordinary
+ Sunday's entry 15) -- so within this specific pipeline shape the
+ privileged loser is unavoidably also the higher-dignity one, and this
+ test cannot by itself distinguish "privilege overrides dignity" from
+ "dignity alone happened to pick the same winner". That distinction is
+ what [admit_cases]'s hand-tagged rows above prove (a LOWER-dignity
+ privileged candidate still beats a HIGHER-dignity ordinary one on a
+ II-class Sunday, the opposite of "other II class"'s own row). This test's
+ job is narrower and complementary: proving the real pipeline
+ ([PE.band], [PE.disposition], [PE.privilege_of] via [disposition],
+ [PE.admit] together) actually reaches and exercises the override branch
+ end-to-end, not merely in isolation. *)
+let test_ii_class_sunday_privileged_witness_admitted_end_to_end () =
+ let date = mk 2026 7 5 (* an ordinary Time-after-Pentecost Sunday. *) in
+ let day_ctx = ctx date in
+ let sunday = of_temporal date in
+ let privileged_witness =
+ cand ~origin:P.Sanctoral ~status:Cel.Commemoration_only ~layer:PE.universal_layer
+ "ef-commemoration-only-b-witness"
+ (* Class1 by [cand]'s own default -- RG 109(b). *)
+ in
+ let ordinary_saint = cand ~origin:P.Sanctoral ~rank:V.Class2 ~layer:PE.universal_layer "ef-some-saint" in
+ let resolution =
+ P.resolve real_rules day_ctx ~temporal:sunday ~sanctoral:[ privileged_witness; ordinary_saint ]
+ in
+ (* Checked against [sunday]'s own slug, not a hand-typed/guessed literal
+ (its exact week number is not worth independently re-deriving here):
+ this asserts identity with the real [Temporal_ef.temporal] candidate,
+ proving the SUNDAY -- not either sanctoral loser -- is what wins the
+ day, which the privilege assertions below presuppose. *)
+ Alcotest.(check string) "the Sunday wins the day, not either sanctoral loser"
+ (S.to_string sunday.P.cel.Cel.slug) (S.to_string resolution.P.observed.P.cel.Cel.slug);
+ Alcotest.(check (list (pair string string)))
+ "only the privileged (Commemoration_only, Class1) witness is admitted"
+ [ ("ef-commemoration-only-b-witness", "Privileged") ]
+ (List.map
+ (fun (c, p) -> (S.to_string c.P.cel.Cel.slug, match p with P.Privileged -> "Privileged" | P.Ordinary -> "Ordinary"))
+ resolution.P.commemorations);
+ Alcotest.(check (list (pair string string))) "the ordinary saint is dropped into omitted, not vanished"
+ [ ("ef-some-saint", "omitted: admission limit reached") ]
+ (List.map (fun (c, reason) -> (S.to_string c.P.cel.Cel.slug, reason)) resolution.P.omitted)
+
(* Completes Task 7's carried fix (register line 334): on a real Sunday
landing on 2 November, All Souls does not merely lose (that was Task 7's
[band] fix, proved by [test_all_souls_yields_to_sunday] above) -- it must
@@ -753,4 +816,7 @@ let suite =
Alcotest.test_case "II-class Sunday: second loser dropped into omitted" `Quick
test_ii_class_sunday_drops_second_loser_into_omitted;
Alcotest.test_case "RG109(e) Lent feria privileged end-to-end" `Quick
- test_privileged_lent_feria_admitted_end_to_end ] )
+ test_privileged_lent_feria_admitted_end_to_end;
+ Alcotest.test_case
+ "II-class Sunday override: RG109(b) witness admitted over an ordinary saint, end-to-end"
+ `Quick test_ii_class_sunday_privileged_witness_admitted_end_to_end ] )