diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-12 15:16:00 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-12 15:16:00 +0200 |
| commit | ea22ad2bde211998e6719fd5fb76233571a48383 (patch) | |
| tree | 43c5a7532d910bf8d8f51fa4965c745bc7d8e300 /lib/kernel/precedence.ml | |
| parent | 81bb608ad60877df977af16f69f1ee0c99aa68f4 (diff) | |
| download | colitur-ea22ad2bde211998e6719fd5fb76233571a48383.tar.gz colitur-ea22ad2bde211998e6719fd5fb76233571a48383.zip | |
fix(kernel,rite-ef): admit orders commemorations by RG 113's table of precedence, not slug
Precedence_ef.admit broke a same-rank tie among commemoration candidates
alphabetically by slug -- a deterministic engineering convention with no
rubrical citation. RG 113's own second sentence, primary-source-verified
against two independent scans and previously uncited in the register
(only "commemoratio de Tempore fit primo loco" was quoted before), gives
the real rule: "in admittendis et ordinandis aliis commemorationibus,
servetur ordo tabellae praecedentiae" -- admitting and ordering
commemorations both run on the rite's own table of precedence (band's
28-entry table), not RG 8's coarse four-class rank.
Precedence.resolve now computes each commemoration candidate's own band
value once, generically, and hands it to rules.admit as a third tuple
element (Precedence.rules.admit's signature changed accordingly, ditto
Precedence_ef.admit; every rule-record stub in the test suite updated to
match). Precedence_ef.admit's own compare_dignity is replaced by
compare_precedence, ordering by band then slug; a residual tie within one
identical band value still falls back to slug, since RG 113 gives no
further instruction there -- documented as a still-uncited engineering
convention, not dressed up as a rubric.
RG 98 ("in paritate autem Officium prius impeditum praecedit") was
considered as a candidate authority for that residual and rejected: it
governs the transfer queue order among several simultaneously-impeded
I-class feasts (Caput XIII), a different operation in a different
chapter from RG 113's commemoration admission (Caput XVI); nothing in the
primary text connects the two.
Blast radius measured against the pre-change binary across the entire
1583-9999 domain (not only 2005-2050): the admitted-commemoration-slug
set is byte-identical, day for day, before and after this change. The
fix corrects the citation and mechanism, not the answer, on this
codebase's current data -- both of the task brief's named examples
(22 Feb Chair-of-Peter/Lent-vs-Paul, 22 Sept Maurice-vs-Thomas-of-
Villanova) are confirmed present and unchanged in both streams. A new
test (RG113: admit picks by precedence order, not slug, when they
disagree) proves admit actually consults the passed-in precedence value
with a synthetic pair whose slug order and precedence order disagree --
teeth a same-band-only regression test could not have caught, since
every real collision found in the domain happens to agree on both axes.
271 -> 272 tests, all green; COLITUR_EXHAUSTIVE_SWEEP=1 unaffected.
Diffstat (limited to 'lib/kernel/precedence.ml')
| -rw-r--r-- | lib/kernel/precedence.ml | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/lib/kernel/precedence.ml b/lib/kernel/precedence.ml index d48203e..2c55817 100644 --- a/lib/kernel/precedence.ml +++ b/lib/kernel/precedence.ml @@ -18,8 +18,13 @@ type ('s, 'r) rules = { admit : observed:'r candidate -> temporal:'r candidate -> - ('r candidate * privilege) list -> + ('r candidate * privilege * int) list -> ('r candidate * privilege) list; + (** the trailing [int] on each input triple is that candidate's own + [band] value, computed once by {!resolve} below (a rite's [admit] + has no [context] of its own to compute it with) -- see [resolve]'s + own comment for why this is a KERNEL-level policy, not a rite- + specific rule threaded in as data. *) } type 'r resolution = { @@ -56,7 +61,19 @@ let resolve rules ctx ~temporal ~sanctoral = ([], [], []) losers in let comms = List.rev comms and deferred = List.rev deferred in - let admitted = rules.admit ~observed ~temporal comms in + (* RG 113 (EF; docs/research/rules-register.md ยง4 "Commemorations"): "in + admittendis et ordinandis aliis commemorationibus, servetur ordo + tabellae praecedentiae" -- admitting AND ordering commemorations both + run on the rite's own table of precedence, the same [band] already + used above to pick [observed]. Computed here, once, generically (a + rite's own [admit] has no [ctx] of its own to call [band] with) rather + than inside every rite's [admit] separately -- a kernel-level POLICY + ("commemorations are ordered by the rite's own band"), not a + rite-specific RULE baked into the kernel: the actual [band] function, + and whether a rite's [admit] even uses the value it is handed, both + stay entirely rite-supplied. *) + let comms_by_precedence = List.map (fun (c, p) -> (c, p, rules.band ctx c)) comms in + let admitted = rules.admit ~observed ~temporal comms_by_precedence in let dropped = List.filter (fun c -> not (List.exists (fun a -> fst a == fst c) admitted)) comms in |
