summaryrefslogtreecommitdiff
path: root/lib/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel')
-rw-r--r--lib/kernel/validate.ml33
-rw-r--r--lib/kernel/validate.mli26
2 files changed, 49 insertions, 10 deletions
diff --git a/lib/kernel/validate.ml b/lib/kernel/validate.ml
index 433dc99..24adcd8 100644
--- a/lib/kernel/validate.ml
+++ b/lib/kernel/validate.ml
@@ -330,12 +330,41 @@ let run (rite : ('s, 'r) Rite.t) (layer : 'r Layer.t) ~year =
season = d.Liturgical_day.temporal.Temporal.season;
weekday = d.Liturgical_day.temporal.Temporal.weekday }
in
+ (* CORRECTED (Task B fix round 1, coordinator finding 5): [origin]
+ used to be reconstructed as [Sanctoral] UNCONDITIONALLY, which
+ was harmless while nothing here called [band] on the result
+ (the comment this replaces was correct about [PE.admit] itself:
+ it never reads [origin]) -- but this function ALSO now calls
+ [rite.rules.Precedence.band day_ctx cand] on every one of these
+ reconstructed candidates (the line just below), and [band] DOES
+ read [origin] (its own [is_temporal] test) to choose between its
+ temporal- and sanctoral-keyed branches. A genuinely
+ TEMPORAL-origin commemoration (a privileged Advent/Lent/
+ Passiontide feria, an Ember day, an impeded Sunday) mislabelled
+ [Sanctoral] would score the WRONG band entry (e.g. a Lent feria
+ scoring entry 23, "III-class feasts in particular calendars",
+ instead of its real entry 22) -- inert today only because
+ nothing currently asserts on the SCORE [band] returns here, only
+ on whether re-offering [admit] the same values round-trips
+ (which happens not to depend on getting [origin] right for any
+ case this codebase's data reaches -- unverified in general).
+ [Liturgical_day.t] itself still does not retain a
+ commemoration's original origin, so it is recovered the only
+ way available: a commemoration whose SLUG matches the day's own
+ temporal office is temporal-origin; every other commemoration
+ is sanctoral-origin. This is exact whenever slugs cannot
+ collide across the two streams (Task 12's own "observed" check
+ already assumes this for a different purpose), which is the
+ same assumption the rest of this codebase already leans on. *)
+ let temporal_office_slug = d.Liturgical_day.temporal.Temporal.office.Celebration.slug in
let as_candidates comms =
List.map
(fun (c, p) ->
- let cand : 'r Precedence.candidate =
- { Precedence.cel = c; origin = Precedence.Sanctoral }
+ let origin =
+ if Slug.equal c.Celebration.slug temporal_office_slug then Precedence.Temporal
+ else Precedence.Sanctoral
in
+ let cand : 'r Precedence.candidate = { Precedence.cel = c; origin } in
(cand, p, rite.Rite.rules.Precedence.band day_ctx cand))
comms
in
diff --git a/lib/kernel/validate.mli b/lib/kernel/validate.mli
index 5e55fc5..b46ca30 100644
--- a/lib/kernel/validate.mli
+++ b/lib/kernel/validate.mli
@@ -59,14 +59,24 @@ val failure_to_string : failure -> string
fixed point.
- ["admission"]: the rite's own [rules.admit] is a fixed point on what it
already admitted -- re-offering a day's [commemorations] back to
- [admit] (reconstructed with {!Precedence.Sanctoral} origin; the real EF
- admit reads only rank and slug, never origin, so this reconstruction is
- exact for it) must return exactly that same set. A cap-enforcing
- selector that is not idempotent on its own output has, by definition,
- admitted something its own rule would not admit if asked again -- the
- rite-agnostic form of "the admission limit was not exceeded" available
- without embedding a rite's specific numeric caps (RG 111's, for EF)
- into kernel code.
+ [admit] (with [observed]'s own origin reconstructed as
+ {!Precedence.Sanctoral}; the real EF admit reads only rank and slug
+ from [observed], never origin, so this reconstruction is exact for
+ it) must return exactly that same set. Each offered commemoration's
+ own origin -- CORRECTED, Task B fix round 1 -- is recovered by
+ comparing its slug against the day's own temporal office, not
+ reconstructed as [Sanctoral] uniformly: {!Precedence.rules.admit}
+ (since Task B) is handed each candidate's own {!Precedence.rules.band}
+ value, computed here exactly as {!Precedence.resolve} computes it, and
+ [band] DOES read a candidate's origin (temporal- vs sanctoral-keyed
+ branches) even though EF's own [admit] itself still does not -- a
+ mislabelled origin would silently score the wrong table entry for a
+ genuinely temporal-origin commemoration (e.g. a Lent feria) before
+ this fix. A cap-enforcing selector that is not idempotent on its own
+ output has, by definition, admitted something its own rule would not
+ admit if asked again -- the rite-agnostic form of "the admission limit
+ was not exceeded" available without embedding a rite's specific
+ numeric caps (RG 111's, for EF) into kernel code.
Total over the whole 1583..9999 domain, including [year] = 9999: the
liturgical year opening there continues into out-of-domain civil year