aboutsummaryrefslogtreecommitdiff
path: root/test/test_validate.ml
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-08-12 13:32:13 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-08-12 13:32:13 +0200
commit7d3b5ec831a60e8b63466251d63b2bd564acba2b (patch)
treef9e5015704ff74f42b777d7aac207ffda0d55673 /test/test_validate.ml
parent5c9f2cdbffdff67ec8a1939ed6958767acf406fd (diff)
downloadcolitur-7d3b5ec831a60e8b63466251d63b2bd564acba2b.tar.gz
colitur-7d3b5ec831a60e8b63466251d63b2bd564acba2b.zip
fix(rite-ef,kernel): follow the oracle on the Purification; admit reads the day's own Sunday-ness, not observed
Fix round 1 review, two findings landed together because each golden pin's correctness depends on both. CRITICAL (item 1): reverts this branch's own first-pass retag of the Purification (2 February) from Lord back to Bvm -> Lord. The calendarium titles it 'B. Mariae Virg.', but missalemeum -- this project's designated EF oracle -- treats it as taking an occurring II-class Sunday's place outright, commemorations empty, exactly RG16(a)'s own festum Domini treatment (2020-02-02, 2014-02-02, independently fetched). Control, 2019-09-08 (the Nativity of the BVM, an ordinary Marian feast, on a Sunday): the Sunday observed, the feast merely commemorated -- the opposite pattern, proving the Purification's own oracle treatment is deliberate, not a gap. RG16(a) alone, on the untouched data, would have matched the oracle character for character; retagging Bvm is what moved colitur away from it on 1200 domain-wide days. The user has ruled: follow the oracle. Genuine primary-text counter-evidence (RG120(b), the colour rule grouping 2 February under 'B. Mariae Virg.', a category separate from 'Domini') is recorded in the register, not discarded -- a different project could reasonably rule the other way on the same evidence. most-holy-name-of-mary stays retagged Bvm; that one was never disputed. Removes the now-unneeded C12 lectio allow-list entry (data/ef/ expected-divergences.sexp, test_differential.ml): with the Purification Lord again, colitur matches lectio's own class = lord on every affected date, no divergence to allow-list. IMPORTANT (item 2): Precedence.rules.admit gains a ~temporal parameter -- a genuine kernel signature change, unlike RG16(a) itself. RG111(b)'s own Sunday rank floor ('one commemoration, namely of a II-class feast') used to be detected by reading observed's own slug for a Sunday marker, which silently assumed observed IS the day's temporal-cycle office. RG16(a) breaks that assumption on purpose: a Feast of the Lord standing in for an impeded Sunday 'cum omnibus iuribus et privilegiis' keeps the day a dominica II classis for RG111(b) too, even though the FEAST, not the Sunday, is observed. Before this fix an unrelated saint (Pope Sixtus II et al., 6 August, Class3) was wrongly admitted into the freed slot on every one of 1178 domain-wide days. Oracle-confirmed directly: 2023-08-06 (a Sunday) shows him displaced, commemorations empty; 2026-08-06 (an ordinary Thursday) shows him admitted -- being a Sunday is exactly what excludes him. admit now reads Sunday-ness off ~temporal (the day's own temporal-cycle candidate, passed through from Precedence.resolve unchanged) instead of observed. Validate's own admission fixed-point invariant updated to pass the same real temporal candidate through. Both golden pins in test_golden.ml were promoted from actual colitur day output without independently consulting the rubric or the oracle first -- a real defect the review caught. Re-derived from both before re-pinning: 2028-08-06 and 2025-02-02 now pin comms=[], no commemoration at all, matching missalemeum exactly in both cases.
Diffstat (limited to 'test/test_validate.ml')
-rw-r--r--test/test_validate.ml12
1 files changed, 6 insertions, 6 deletions
diff --git a/test/test_validate.ml b/test/test_validate.ml
index 89053c1..42c58f5 100644
--- a/test/test_validate.ml
+++ b/test/test_validate.ml
@@ -225,7 +225,7 @@ module Synthetic = struct
let rules : (season, rank) P.rules =
{ P.band = (fun _ _ -> 0);
disposition = (fun ~winner:_ ~loser:_ -> P.Omit);
- admit = (fun ~observed:_ _ -> []) }
+ admit = (fun ~observed:_ ~temporal:_ _ -> []) }
let year_start y = match D.make ~year:y ~month:1 ~day:1 with Ok d -> d | Error e -> failwith e
@@ -377,7 +377,7 @@ module Synthetic = struct
let dup_rules : (season, rank) P.rules =
{ P.band = (fun _ c -> match c.P.origin with P.Temporal -> 0 | P.Sanctoral -> 10);
disposition = (fun ~winner:_ ~loser:_ -> P.Commemorate P.Ordinary);
- admit = (fun ~observed:_ cs -> List.map (fun (c, p) -> ({ c with P.origin = c.P.origin }, p)) cs) }
+ admit = (fun ~observed:_ ~temporal:_ cs -> List.map (fun (c, p) -> ({ c with P.origin = c.P.origin }, p)) cs) }
(* "unconverged": two entries collide on one date (6 June), both beating
the temporal office and tied with each other, so slug decides:
@@ -416,7 +416,7 @@ module Synthetic = struct
disposition =
(fun ~winner:_ ~loser ->
match loser.P.cel.Cel.rank with R1 -> P.Transfer | R2 -> P.Commemorate P.Ordinary);
- admit = (fun ~observed:_ cs -> cs) }
+ admit = (fun ~observed:_ ~temporal:_ cs -> cs) }
let guard_transfer_target (_ : rank P.candidate) (origin : D.t) (_ : D.t -> rank Cel.t) = origin
@@ -444,7 +444,7 @@ module Synthetic = struct
{ P.band = (fun _ c -> match c.P.origin with P.Temporal -> 0 | P.Sanctoral -> 10);
disposition = (fun ~winner:_ ~loser:_ -> P.Commemorate P.Ordinary);
admit =
- (fun ~observed:_ cs ->
+ (fun ~observed:_ ~temporal:_ cs ->
let sorted = List.stable_sort adm_compare_slug cs in
if List.length sorted mod 2 = 1 then adm_take 2 sorted else adm_take 1 sorted) }
@@ -475,7 +475,7 @@ module Synthetic = struct
disposition =
(fun ~winner:_ ~loser ->
match loser.P.cel.Cel.rank with R1 -> P.Transfer | R2 -> P.Commemorate P.Ordinary);
- admit = (fun ~observed:_ cs -> cs) }
+ admit = (fun ~observed:_ ~temporal:_ cs -> cs) }
let collide_d2 = match D.make ~year:2026 ~month:2 ~day:10 with Ok d -> d | Error e -> failwith e
let collide_transfer_target (_ : rank P.candidate) (_ : D.t) (_ : D.t -> rank Cel.t) = collide_d2
@@ -492,7 +492,7 @@ module Synthetic = struct
let clean_sanctoral_rules : (season, rank) P.rules =
{ P.band = (fun _ c -> match c.P.origin with P.Temporal -> 0 | P.Sanctoral -> 10);
disposition = (fun ~winner:_ ~loser:_ -> P.Commemorate P.Ordinary);
- admit = (fun ~observed:_ cs -> cs) }
+ admit = (fun ~observed:_ ~temporal:_ cs -> cs) }
end
open Synthetic