diff options
| -rw-r--r-- | lib/rites/rite_ef/precedence_ef.ml | 21 | ||||
| -rw-r--r-- | test/test_precedence_ef.ml | 45 |
2 files changed, 61 insertions, 5 deletions
diff --git a/lib/rites/rite_ef/precedence_ef.ml b/lib/rites/rite_ef/precedence_ef.ml index cd0c53b..5a2d307 100644 --- a/lib/rites/rite_ef/precedence_ef.ml +++ b/lib/rites/rite_ef/precedence_ef.ml @@ -514,7 +514,18 @@ let privilege_of (c : Vocab_ef.rank Precedence.candidate) : Precedence.privilege let is_temporal = c.Precedence.origin = Precedence.Temporal in let open Vocab_ef in (* (a) RG 109(a) (§4): "of a Sunday" -- the same slug marker RG 33's - [impedes_vigil] already reads to answer "is this candidate a Sunday". *) + [impedes_vigil] already reads to answer "is this candidate a Sunday". + + FRAGILITY, named here because this is the decision point (fix-round + re-review, F5): [is_sunday_slug] is a SUBSTRING match, so the Holy Name + of Jesus obtains this privilege on its Sunday shape only because its + slug happens to read "ef-holy-name-sunday". That is a naming accident, + not a cited rule. The real warrant is RG 17's own closing paragraph + (quoted in full at temporal_ef.ml's [holy_name_sunday]): "Haec festa + locum tenent dominicae occurrentis cum omnibus iuribus et privilegiis" + -- these feasts hold the occurring Sunday's place WITH ALL ITS RIGHTS + AND PRIVILEGES, of which RG 109(a)'s privilege is one. A slug rename + would silently drop it while every test stayed green. *) if is_sunday_slug slug then Precedence.Privileged (* (b) RG 109(b) (§4): "of a I-class day" -- the candidate's own rank. In this codebase's current disposition rules the ONLY way a @@ -1185,9 +1196,11 @@ let rg110_find_companion comms companion_slug = compares commemoration ORDER at all -- the lectio differential does not compare commemorations (its own "limit 1"); the oracle's own [identity_diff] sorts both sides into a multiset before comparing; - {!Colitur_kernel.Record}/`describe` (test_golden.ml) both sort their own - comms field too, for the same reason presence/identity checks should not - be order-sensitive by accident. This function's own [admit_cases] unit + and [describe] (test_golden.ml) sorts its own comms field too, for the + same reason presence/identity checks should not be order-sensitive by + accident. (CORRECTED, fix-round re-review: this previously also named + {!Colitur_kernel.Record}. Record.t has NO commemorations field at all -- + see record.mli -- so it neither sorts nor carries them.) This function's own [admit_cases] unit test (test_precedence_ef.ml) is therefore the ONLY place in this codebase's test suite where commemoration order is asserted at all -- flagged here, and in CLAUDE.md's own "know what each layer cannot see" diff --git a/test/test_precedence_ef.ml b/test/test_precedence_ef.ml index 639f64c..ed9a933 100644 --- a/test/test_precedence_ef.ml +++ b/test/test_precedence_ef.ml @@ -1031,6 +1031,16 @@ let sixtus = let chair_of_st_peter_synth = cand ~rank:V.Class2 "chair-of-st-peter" let paul_companion_synth = cand ~rank:V.Class3 ~status:Cel.Commemoration_only "paul" +(* An unrelated third commemoration, sorting AFTER both members of the RG110 + pair, so that "spliced immediately after its trigger" and "appended at the + end" give different answers. Added by the fix-round re-review (G1): with + only the pair present the two are indistinguishable, and the re-review + proved an append-at-end variant passed the whole suite green. Class3 + Commemoration_only so it cannot win the day; its slug is deliberately not + one {!PE.rg110_companion_slug} recognises. *) +let unrelated_comm_synth = + cand ~rank:V.Class3 ~status:Cel.Commemoration_only "zzz-unrelated-commemoration" + (* Any real Lent/Ember feria's own shape (a Class3, PRIVILEGED, temporal- origin candidate) -- {!PE.rg110_companion_slug} does not match this slug, so it is a neutral bystander in [admit]'s own normal (pre-RG110) contest, @@ -1184,7 +1194,40 @@ let admit_cases = (loses the day to an ordinary II-class Sunday), Paul rides along \ AFTER it (RG110(c): \"huic orationi additur altera\")", cand ~rank:V.Class2 "ef-some-other-sunday", cand ~rank:V.Class2 "ef-some-other-sunday", - [ po chair_of_st_peter_synth P.Ordinary; (paul_companion_synth, P.Ordinary, 999) ], + (* A third, unrelated candidate is OFFERED here deliberately, and is + correctly NOT admitted -- which is itself the point. + + The fix-round re-review asked for a third commemoration so that + "spliced IMMEDIATELY after its own trigger" (RG110(c)'s own word) + could be told apart from "appended at the end of the list": with a + single-member result the two coincide, and it proved an + append-at-end variant passed the whole suite green. + + Attempting it establishes something better than the test it asked + for: on this day-shape a third commemoration is RUBRICALLY + IMPOSSIBLE, so the distinction is unobservable BY CONSTRUCTION, not + merely unobserved. Shape (c) requires the trigger to LOSE the day + while still being admitted -- and a Class2 trigger can only lose to + a I-class day (RG 111(a): one privileged commemoration) or a + II-class Sunday (RG 111(b): one, and "scilicet de festo II + classis"). Both caps are ONE. Anything a third candidate could be + is either outranked by the trigger or excluded by the rank floor; + here [zzz-unrelated-commemoration] is Class3 and RG 111(b) drops + it, leaving the pair alone. + That is why the re-review's own domain sweep found shape (c) never + co-occurring with a third commemoration in 8 417 years: not an + accident of the data, a consequence of the rubric. + + So RG110(c)'s "ante omnes alias commemorationes" half has no + reachable witness in the EF's real rubrical space, and the + adjacency this row asserts is exercised only against the pair + itself. The append-at-end variant therefore remains + indistinguishable from the splice on any input the engine can + actually construct -- recorded in the register rather than papered + over with a synthetic row that proves a shape no rubric permits. *) + [ po chair_of_st_peter_synth P.Ordinary; + (paul_companion_synth, P.Ordinary, 999); + po unrelated_comm_synth P.Ordinary ], [ "chair-of-st-peter"; "paul" ] ); (* Defensive: a trigger slug is [observed], but its companion is simply not present among [comms] at all (a data gap, or -- as this exact |
