<feed xmlns='http://www.w3.org/2005/Atom'>
<title>colitur.git/man/colitur-overlay.5, branch v0.7.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.7.0</id>
<link rel='self' href='https://git.labunix.xyz/colitur.git/atom?h=v0.7.0'/>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/'/>
<updated>2026-08-18T12:14:09Z</updated>
<entry>
<title>feat(examples): ship two real local calendars, with their limits stated</title>
<updated>2026-08-18T12:14:09Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-18T12:14:09Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=c47d59cbc5f73a4a695757b93e6d8c7709e0b5e8'/>
<id>urn:sha1:c47d59cbc5f73a4a695757b93e6d8c7709e0b5e8</id>
<content type='text'>
Poland and the Benedictines, in the flat INI form, installed beside the
invented diocesan example.

poland.ini -- 17 entries from the Calendarium Perpetuum pro Dioecesium
Poloniae (1964), promulgated under Rubricarum instructum and applying to the
1962 Missal. Transcribed from a published Polish EF ordo that names that same
calendar, cross-checked against missalemeum's supplement page for the two
formularies 1964 added (13 and 15 July). Date, Latin name and class were read
from the source for every entry; three classes could not be recovered from
the PDF's column layout and are marked INFERRED where they appear, with the
reasoning. The header carries an edition warning that is a real trap here:
the Proprium Poloniae of 1921 and 1934 is still bound into many missals and
carries an outdated arrangement of dioceses and ranks. It is not this
calendar, and it is exactly the kind of plausible wrong-edition source that
has cost this project time before.

benedictine.ini -- two entries, and the comment explaining why is the point of
shipping it. Counted across the Norcia ordo: 86 "I cl.", 43 "II cl.", ZERO
"III cl." and ZERO "IV cl.", against 103 "Semidup." and ~96 "Dup.". The
monastic rite uses the Roman classes at the top and the older Duplex /
Semiduplex grades below, exactly where the Roman calendar has III and IV
class. colitur's rank vocabulary cannot express those, so most Benedictine
propers cannot be written here at all -- a mismatch of vocabularies between
related rites, not a gap in the data. Rather than invent a Duplex -&gt; Class3
mapping the source never states, that file ships only what its ordo gives in
Roman terms and lists roughly two dozen excluded feasts BY NAME, so the
omission is visible instead of silent.

Both headers say plainly that they are examples and not authorities: they are
transcriptions from published ordines, none of the five test layers can vouch
for either, and both should be checked against the reader's own ordo. The
cram test asserts only what we control -- that they parse, convert and apply
-- and says so.

They also demonstrate the precedence engine on real data: the Benedictine
Transitus is I class and takes 21 March with the Lenten feria commemorated,
and Maurus is II class and takes 15 January with Paul the First Hermit
commemorated.
</content>
</entry>
<entry>
<title>docs(man): explain how an overlay is actually applied</title>
<updated>2026-08-18T12:02:35Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-18T12:02:35Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=c403d6e3408bba63b1351e80a7afa4150641f78f'/>
<id>urn:sha1:c403d6e3408bba63b1351e80a7afa4150641f78f</id>
<content type='text'>
The format was documented; the pipeline was not. The commonest surprise when
writing a local calendar is 'my feast does not appear', and it is almost never
a loading failure -- which means the existing docs answered a question nobody
was asking.

Four stages, named: load, merge, resolve, emit. The one that matters is
resolve, and the point it makes explicit is that overlay entries take part in
precedence on EQUAL TERMS. A local feast is not privileged for being local; it
competes under RG 91's table exactly as a universal one does.

Three concrete causes of a missing feast, each of which came up while testing
this branch: outranked by the day it lands on, a date structurally occupied
(an easter+60 feast can never appear, because Corpus Christi is Easter+60 and
is I class), or a commemoration past RG 111's limit for the day's class. And
the diagnostic rule -- if check says the file loaded and every directive found
its target, the answer is stage 3, so raise the class or move the date.

Also records why the shipped adjustments are applied first and why that is not
configurable: replacing rather than layering would silently drop the
inseparable Peter/Paul commemoration, the Major Litanies, St Barbara and
Rogation Wednesday. Overriding one deliberately by naming its slug is a
different thing from losing it by accident.
</content>
</entry>
<entry>
<title>feat(overlay): a flat INI front end, which verifies its own output</title>
<updated>2026-08-18T11:55:18Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-18T11:55:18Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=36daf47dde9b0c16dacef31163ea74effdd5e7f3'/>
<id>urn:sha1:36daf47dde9b0c16dacef31163ea74effdd5e7f3</id>
<content type='text'>
A convenience format for calendars that add a few local feasts and drop one
or two universal entries. Section names are slugs, a [overlay] section carries
the id, and status/subject/layer default so the common case -- an ordinary
local saint's feast -- says only what distinguishes it.

It is a FRONT DOOR, not a second data model. It parses to exactly the
Overlay.t the S-expression form parses to, and everything downstream is the
same code on the same values; a test asserts an INI overlay and its
hand-written sexp equivalent produce identical Overlay.t values. It is also
deliberately less expressive -- Add, Suppress and single-field Edit only --
and refuses Replace, multi-field edits and citation edits BY NAME rather than
dropping them silently. Anything it cannot say is a reason to write sexp.

Little of this is new machinery: tools/bootstrap_sanctoral.ml has parsed INI
and mapped it to celebrations since the sanctoral was bootstrapped from
lectio. The dates needed extending, since that mapping handled only MM-DD;
the flat forms are easter+N/easter-N and mon/day/nth, with nth negative to
count from the end.

`colitur convert` is a separate step rather than --overlay sniffing the
extension, so the author can read what their INI became. When a date form was
mistyped, "what did the engine actually get" is the question, and an invisible
transpile cannot answer it.

The conversion verifies its own output: the emitted text is parsed back with
the same function that loads an overlay and must equal what the INI denoted,
or nothing is written. That is the point of the module. A transpiler emitting
valid-but-wrong sexp is the failure a convenience format invites, and `colitur
check` could never catch it -- the output would parse cleanly and mean
something else.

That check was WRONG on the first attempt, in exactly the way it exists to
prevent. It re-serialised the parsed value instead of parsing the text being
returned, so it verified t -&gt; sexp -&gt; t, which is true by construction and
proves nothing. Found by mutation: corrupting the renderer to emit a different
overlay id sailed through and exited 0. It now parses the returned text, the
mutation is caught with exit 2, and two tests fail under it where none did
before.
</content>
</entry>
<entry>
<title>docs(man): colitur-overlay(5), the overlay format in full</title>
<updated>2026-08-18T11:33:41Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-18T11:33:41Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=150f8c550d2f9ebbac61d195eb342eb2b2ec6b95'/>
<id>urn:sha1:150f8c550d2f9ebbac61d195eb342eb2b2ec6b95</id>
<content type='text'>
The overlay format was documented in three partial places -- a paragraph in
colitur(1), a block in --help, and the comments inside the shipped example --
none of which was a reference. Someone writing a diocesan calendar had to
read all three and infer the rest.

Section 5 because an overlay is a thing a user AUTHORS rather than a command
they run: it belongs beside fstab(5), not in man1.

Covers every directive and every field edit, the six required fields and the
two optional ones, all three date specifications including the signed
Easter_offset and the negative nth, three worked examples, and the caveats.
The subject field gets a note explaining that it is not decoration -- it
decides whether a feast displaces an occurring Sunday under RG 16(a).

Two things it says that the code says and the old prose did not. There is no
Set_status and no Set_date among the field edits, deliberately: changing an
entry's status or its date makes it a different celebration rather than an
edited one, so Replace is the right directive and the change stays visible in
`colitur check` output. And a local feast missing from output has usually
LOST its day under the general rubrics rather than failed to load -- the
engine applies precedence to overlay entries exactly as to universal ones,
which is the first thing an author hits and was written down nowhere.

Writing it caught a documentation bug before it shipped: a first draft listed
a Set_status edit that does not exist and omitted Remove_name that does. Every
documented edit is now cross-checked against overlay.mli.

Linked from colitur(1)'s SEE ALSO and its OVERLAYS section, and from --help.
The Makefile installs it into man5, removes it on uninstall, and the man and
doc targets lint both pages.
</content>
</entry>
</feed>
