<feed xmlns='http://www.w3.org/2005/Atom'>
<title>colitur.git/lib/kernel/date_spec.ml, branch v0.1.0</title>
<subtitle>deterministic OCaml engine to compute and validate liturgical calendars for multiple rites, template-driven output to year 9999</subtitle>
<id>https://git.labunix.xyz/colitur.git/atom?h=v0.1.0</id>
<link rel='self' href='https://git.labunix.xyz/colitur.git/atom?h=v0.1.0'/>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/'/>
<updated>2026-08-11T14:21:46Z</updated>
<entry>
<title>kernel: loaders never escape as an exception, date-spec validates on load</title>
<updated>2026-08-11T14:21:46Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-11T14:21:46Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=745ec8f8edb32ee7ef0a8c12ab84833216296f73'/>
<id>urn:sha1:745ec8f8edb32ee7ef0a8c12ab84833216296f73</id>
<content type='text'>
Layer.load narrowed its catch to Sexplib0.Sexp_conv_error.Of_sexp_error,
but rank_of_sexp is caller-supplied and may raise anything -- e.g. a
hand-written rank parser that calls invalid_arg. Overlay.load already
catches every exception from the equivalent call; mirror that here so
layer.mli's "never as an exception" promise actually holds.

Date_spec.t derived its sexp converters with plain ppx_sexp_conv, unlike
Slug and Lang, which hand-write validating parsers specifically so
malformed data is rejected at load. (Fixed (month 13) (day 40)) used to
deserialise cleanly into a spec that simply never resolves -- a saint
quietly vanishing with no diagnostic. t_of_sexp now re-runs the value
through the existing fixed validator, the same shape Slug and Lang
already use.

Covering tests: a Layer.load case where rank_of_sexp raises
Invalid_argument instead of Of_sexp_error (would have escaped
uncaught before this fix); two Date_spec.t_of_sexp cases (month 13,
31 April) that must raise Of_sexp_error rather than silently
constructing an unresolvable spec.
</content>
</entry>
<entry>
<title>kernel: fix sexp deriving, add missing tests, canonicalize remove</title>
<updated>2026-08-11T09:54:16Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-11T09:54:16Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=8b6c0036cb6c7f0e48a9370f53be25fd2bb243f4'/>
<id>urn:sha1:8b6c0036cb6c7f0e48a9370f53be25fd2bb243f4</id>
<content type='text'>
Use [@@deriving sexp] with open Sexplib0.Sexp_conv instead of hand-rolling
converters (fixes non-standard Citation shape and missing field validation).
Names.t_of_sexp wraps derived version to enforce canonical sort on load.

Add tests:
- Names of_list duplicate handling
- Names sexp canonical sort guarantee (identical serialization)
- Names and Date_spec sexp roundtrips

Fix Names.remove to canonicalize output (defensive against non-canonical input).
</content>
</entry>
<entry>
<title>kernel: Names, Citation and Date_spec</title>
<updated>2026-08-11T09:37:32Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-11T09:37:32Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=57322e766a0ece579dafcddcfe2572676a98fca8'/>
<id>urn:sha1:57322e766a0ece579dafcddcfe2572676a98fca8</id>
<content type='text'>
Names is an open language-keyed assoc kept in canonical order so equal name
sets serialise identically. Citation carries references only, never text.
Date_spec ships the one form the EF sanctoral needs; 29 February is
constructible and resolves to None in common years.
</content>
</entry>
</feed>
