summaryrefslogtreecommitdiff
path: root/lib/rites/rite_ef/precedence_ef.mli
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-08-11 23:25:39 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-08-11 23:25:39 +0200
commit2ad350e0f97a99f76ac1d2d95cfa210f7393c777 (patch)
tree5ff5c9463c4316a974b7559dafe7c650ba4ae37c /lib/rites/rite_ef/precedence_ef.mli
parent8c6788053dce2a365e3ddf22eccc9c68e641f32e (diff)
downloadcolitur-2ad350e0f97a99f76ac1d2d95cfa210f7393c777.tar.gz
colitur-2ad350e0f97a99f76ac1d2d95cfa210f7393c777.zip
rite(ef): commemoration privilege and admission (RG 108-111)
Precedence_ef.privilege_of classifies a commemoration candidate against RG 109's closed list of privileged commemorations (a Sunday; a I-class day; a day within the Octave of the Nativity; a September Ember day; a feria of Advent, Lent or Passiontide; the Major Rogations in Mass), read entirely off the candidate's own rank/slug/origin, no context needed. Major Rogations (f) is left unimplemented rather than guessed: no producer for the Major Litanies exists anywhere in this codebase yet. disposition's two Commemorate sites now call privilege_of instead of Task 8's interim_privilege placeholder, which is removed entirely (binding and .mli export both gone). Precedence_ef.admit applies RG 111's four admission counts, keyed on the observed day's own class and Sunday-ness: a I-class day admits none except one privileged commemoration; a II-class Sunday admits one, but a privileged commemoration due displaces any ordinary one regardless of dignity; any other II-class day admits one by dignity alone, with no such override; III/IV-class days admit at most two by dignity. Ties break on slug, matching Precedence.compare_by, so the admitted set never depends on input order. Every admitted candidate is a value taken unchanged from the input list, never rebuilt, so Precedence.resolve's physical-equality-based dropped/omitted accounting keeps working -- closing a note left open since Task 2. Tests: RG 109 category rows (one per reachable category, plus boundary rows proving Advent/Lent Ember days and Minor Rogations are correctly excluded), RG 111 admission rows checked on slug identity rather than count, an order-independence check, and three end-to-end integration tests proving the admission limit's drop lands in resolution.omitted rather than vanishing.
Diffstat (limited to 'lib/rites/rite_ef/precedence_ef.mli')
-rw-r--r--lib/rites/rite_ef/precedence_ef.mli62
1 files changed, 53 insertions, 9 deletions
diff --git a/lib/rites/rite_ef/precedence_ef.mli b/lib/rites/rite_ef/precedence_ef.mli
index 9fe8789..9c3af95 100644
--- a/lib/rites/rite_ef/precedence_ef.mli
+++ b/lib/rites/rite_ef/precedence_ef.mli
@@ -65,13 +65,6 @@ val band : Vocab_ef.season Precedence.context -> Vocab_ef.rank Precedence.candid
somewhere to be caught other than a silently-wrong RG 33 disposition. *)
val sunday_marker : string
-(** The placeholder {!Precedence.privilege} every [Commemorate] disposition
- below carries until Task 9 implements RG 109's closed list of privileged
- commemorations and RG 108-111's admission counts. Exposed so Task 9 (and
- any test wanting to assert on it explicitly) does not have to duplicate
- the literal [Precedence.Ordinary]. *)
-val interim_privilege : Precedence.privilege
-
(** [disposition ~winner ~loser]: RG 92-95, 33, 94 (docs/research/
rules-register.md §4, "Occurrence" and "Vigils"). What becomes of a
losing candidate, decided by the LOSER's own rank and status (RG 95),
@@ -89,8 +82,8 @@ val interim_privilege : Precedence.privilege
right of translation; this is also what moves All Souls, register
line 334, once it loses to an occurring Sunday -- WHERE it lands is
{!Rite.t.transfer_target}'s job, not this function's);
- - everything else is [Commemorate], carrying {!interim_privilege} until
- Task 9 replaces it with RG 109's real per-day computation.
+ - everything else is [Commemorate], carrying its real RG 109 privilege
+ (see {!admit} below).
Total over every winner/loser pair {!Precedence.resolve} or {!Calendar}
can construct: [Vocab_ef.rank] (RG 8) and {!Celebration.status} are both
@@ -102,3 +95,54 @@ val disposition :
winner:Vocab_ef.rank Precedence.candidate ->
loser:Vocab_ef.rank Precedence.candidate ->
Precedence.disposition
+
+(** Slug prefix marking a celebration as one of RG 91 entry 17's days within
+ the Octave of the Nativity (29-31 Dec -- 26-28 Dec are Stephen, John, the
+ Innocents, sanctoral, never this prefix). Also colitur's own convention
+ mirroring rite_ef/temporal_ef.ml's own "ef-nativity-octave-day-%d" slug
+ format, not an RG citation -- see {!universal_layer} -- exposed for the
+ same reason as {!vigil_suffix}: a rename of that format has somewhere to
+ be caught other than a silently-wrong RG 109(c) privilege. *)
+val nativity_octave_prefix : string
+
+(** The September set of {!ember_prefixes}, broken out on its own because RG
+ 109(d) privileges September Ember days specifically while leaving the
+ Advent and Lent sets (also {!ember_prefixes}) ordinary -- register lines
+ 375-376. {!ember_prefixes} is built from this constant, not a duplicated
+ literal, so the two cannot silently drift apart. *)
+val september_ember_prefix : string
+
+(** [admit ~observed comms]: RG 108-111 (docs/research/rules-register.md §4,
+ "Commemorations", register lines 371-379). How many of [comms] -- each
+ already tagged with its real RG 109 privilege by {!disposition} -- RG
+ 111 admits, and which, given the day actually observed:
+ - [observed] a [Class1] day: none, except at most one privileged
+ commemoration (the highest-dignity one, if several are due) -- an
+ ordinary one is never admitted here, no matter how many are due;
+ - [observed] a [Class2] Sunday (its slug carries {!sunday_marker}): one
+ -- a privileged commemoration takes the day's one slot over any
+ ordinary one whenever one is due, not by comparing dignity, so an
+ ordinary commemoration that would otherwise win on dignity is still
+ dropped;
+ - [observed] any other [Class2] day: one, by dignity alone -- no
+ privilege override, unlike the Sunday case immediately above;
+ - [observed] a [Class3] or [Class4] day: at most two, by dignity alone.
+
+ "Dignity" here is [Vocab_ef.rank] (RG 8's four classes), NOT {!band}'s
+ finer RG 91 entry number -- {!band} needs a [context] (date/season/
+ weekday) this function does not receive (see {!Precedence.rules.admit}).
+ Ties break on slug, matching {!Precedence.compare_by}, so the result
+ never depends on the order [comms] arrives in.
+
+ Every candidate this returns is a value taken unchanged from [comms],
+ never rebuilt: {!Precedence.resolve}'s own [dropped]/[omitted]
+ accounting tells an admitted candidate from a dropped one by physical
+ equality on the candidate value, so anything this function admitted
+ stays admitted, and anything it did not is reported in
+ {!Precedence.resolution.omitted}, never silently lost. Total: every
+ [Vocab_ef.rank] is one of the four cases above, and every branch is
+ itself total over an empty or arbitrarily long [comms]. *)
+val admit :
+ observed:Vocab_ef.rank Precedence.candidate ->
+ (Vocab_ef.rank Precedence.candidate * Precedence.privilege) list ->
+ (Vocab_ef.rank Precedence.candidate * Precedence.privilege) list