aboutsummaryrefslogtreecommitdiff
path: root/lib/kernel/validate.mli
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-08-12 02:37:03 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-08-12 02:37:03 +0200
commit4235a6aa18b815c5457a7eb97fd97eb4919dfd4b (patch)
tree053625ce1e05c550feaf85a533a67456af8a13c1 /lib/kernel/validate.mli
parent51f8a25da4f0f939e0a77ce89b5c4b769c6bfe48 (diff)
downloadcolitur-4235a6aa18b815c5457a7eb97fd97eb4919dfd4b.tar.gz
colitur-4235a6aa18b815c5457a7eb97fd97eb4919dfd4b.zip
kernel(validate): fold in Plan 2's carried guards
Three carried items from Plan 2's parked rulings, closed: 1. Slug uniqueness moves from a 200-sample QCheck property scoped to one rite (test_temporal_ef.ml) into Validate's own "slugs" check, so every consumer gets it. The resumed-Sunday exemption that property carried is dropped, not weakened elsewhere: Plan 2 verified zero duplicate slugs domain-wide (all 8 416 years), and by construction a resumed Sunday only ever backfills a week number Septuagesima cut short that same liturgical year, so it can never repeat a number that year's own January Sundays already used. The now-redundant property and its is_resumable_sunday_slug helper are removed from test_temporal_ef.ml; test_validate.ml's own domain-wide property covers the same ground for every consumer. 2. The anchors-erosion guard (Plan 2: deleting entries from a rite's anchors list left the whole suite green) is implemented, but not in Validate. Which of a rite's named days are Easter-derived is knowledge only the rite's own `named` function has; Rite.t deliberately exposes only `temporal` and `anchors`, never `named`, so a rite-agnostic Validate has no ground truth to check anchors' completeness against. Hardcoding an Easter offset, or even Easter itself, would smuggle Western/Gregorian-specific knowledge into code meant to also serve a future Julian-reckoning rite; rediscovering "named-ness" structurally from `temporal` alone is unsound for EF, since most ordinary Sunday/feria slugs from Septuagesima onward are also constant-offset-from-Easter by construction. The guard is therefore EF-specific and lives in test_temporal_ef.ml, discovering the Easter-derived slug set mechanically (scanning a window around Easter and keeping whatever `named` answers Some for) rather than hand-copying either named's or anchors' own offset list, then asserting completeness against the real anchors for the domain's Easter extremes (1598, 1666) plus an ordinary year. A negative fixture proves the guard has teeth, matching Plan 2's exact regression (anchors missing "ef-ascension" reports it, and only it, as missing). 3. test_validate.ml's extreme_years comment claimed 1818/2038; verified against Computus.gregorian_easter directly, the domain's actual Easter extremes (1583..2500) are 1598/1666. Corrected. Verification: the full 1583..9999 domain sweep (233 tests via dune test's 200-sample default, plus a manual full sweep) reports exactly one failure -- the known, already-pinned year-9999 season-truncation case -- and zero occurrences of the new "slugs" check anywhere in the domain. Deleting "ef-ascension" from the real anchors list (reproducing Plan 2's regression directly) is caught immediately by the new EF test and, confirmed empirically, invisible to Validate's own full property sweep -- direct evidence for why item 2 cannot live in Validate.
Diffstat (limited to 'lib/kernel/validate.mli')
-rw-r--r--lib/kernel/validate.mli7
1 files changed, 7 insertions, 0 deletions
diff --git a/lib/kernel/validate.mli b/lib/kernel/validate.mli
index 511c78f..5e55fc5 100644
--- a/lib/kernel/validate.mli
+++ b/lib/kernel/validate.mli
@@ -17,6 +17,13 @@ val failure_to_string : failure -> string
straddles two civil years, and checks only the pairs whose date actually
falls within the year walked.
+ ["slugs"]: no two dates within the walked liturgical year may carry the
+ same office slug (Plan 2 carried item 4). Asserted outright, with no
+ exemption for the resumed-Sunday reuse a slug's own name might suggest:
+ a resumed Sunday only ever backfills a week number Septuagesima cut
+ short that same year, so by construction it never repeats a number that
+ year's own January Sundays actually used.
+
The season check compares the run-length-compressed season sequence
against [rite.Rite.season_runs], not [rite.Rite.vocab.seasons]: a rite may
have one season appear in two separate runs (the modern form's Ordinary