<feed xmlns='http://www.w3.org/2005/Atom'>
<title>colitur.git/lib/rites/rite_of/rite_of.ml, branch main</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=main</id>
<link rel='self' href='https://git.labunix.xyz/colitur.git/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/'/>
<updated>2026-08-26T12:28:50Z</updated>
<entry>
<title>fix(citation): make the well-formed reading-part set rite-supplied</title>
<updated>2026-08-26T12:28:50Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-26T12:28:50Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=e5cbc662227de4f3ab0089fe73f639f4f84601a4'/>
<id>urn:sha1:e5cbc662227de4f3ab0089fe73f639f4f84601a4</id>
<content type='text'>
I7 (final-review.md, 2026-08-25-colitur-of-phases-3-5): OF Sundays and
solemnities shipped without the Second reading, and the lectionary
data header called the First reading an "Epistle" -- EF vocabulary.
The sole blocker was Validate's own kernel-hardcoded assertion that a
well-formed day's sorted citation parts are exactly [First; Gospel];
Citation.part already carried Second.

Rite.t gains citation_shapes : Citation.part list list, the fourth
EF-shaped kernel misfit (after Preface.t, Mass_formulary.source,
transfer_target's strictly-later contract) and the first fixed rather
than only documented. EF supplies its one shape unchanged; OF supplies
two, [First; Gospel] on a feria/feast/memorial and [First; Second;
Gospel] on a Sunday or solemnity (OLM 1981 Praenotanda n. 66.1 vs
n. 69.1, n. 84(b)/(c), page-image verified against olm-1981.pdf).
Validate's "citations" check now matches against the rite's own
declared shapes rather than a single literal pattern, preserving all
three invariants it always enforced: zero or one complete shape, never
partial; no part outside what the rite declares; no part repeated.

bootstrap_lectionary_of.ml's cite now extracts a Second reading from
Sunday-cycle ini sections only, correctly excluding the one stray
`second` field lectio's snapshot carries on a weekday-cycle section (a
content-verified scraping artifact). The hand-authored Christmas Day
entry gains its own Second reading from the same OLM passage already
cited for its First/Gospel. Regenerated data/of/lectionary.sexp: 771
entries unchanged, citation fields 1542 -&gt; 1725 (+183, all Second
readings), SHA-256 re-pinned, header wording fixed and a new coverage
bullet added. Responsorial Psalm is deliberately still not emitted --
OLM 1981 Praenotanda n. 71 itself lists it apart from the readings
proper as a chant with its own refrain, and the finding driving this
change names only the missing Second reading.

EF output verified byte-identical to the branch start (empty
lib/rites/rite_ef + data/ef diff since v1.0.0, plus a direct binary
comparison of `day`/`readings` for 2026, 1583 and 9999 against a
worktree build of the pre-change commit).

Tests: three new fixtures in test_validate.ml prove the generalisation
holds both directions (a multi-shape rite accepts either of its
declared shapes; a rite that never declared a shape still rejects it).
test_citation_coverage_of.ml's pinned residual grows 41 -&gt; 49, all new
entries the same already-understood chapter-crossing shape.
</content>
</entry>
<entry>
<title>feat(of): assemble Rite_of.context and wire --rite of into the CLI</title>
<updated>2026-08-26T07:53:22Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-26T07:53:22Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=8fa9db25f55f4ae92ad6a28115484dd981593a3c'/>
<id>urn:sha1:8fa9db25f55f4ae92ad6a28115484dd981593a3c</id>
<content type='text'>
Task 5 of Phases 3-5 (the payoff task): bundles Tasks 1-4's separately
built pieces (Temporal_of, Precedence_of, Rubrics_of, Lectionary_of)
into a (Vocab_of.season, Vocab_of.rank) Colitur_kernel.Rite.t, and
wires colitur day/readings --rite of &lt;year&gt; into the CLI. Default
stays ef; every pre-existing invocation is byte-identical (asserted
directly in test/cli.t and against a real v1.0.0 build for three
years, plus git diff --stat v1.0.0..HEAD over lib/rites/rite_ef/,
lib/kernel/, data/ef/ is empty).

No kernel change was needed, confirming the spec's central claim.
season_runs needed real thought rather than the brief's own suggested
Vocab_of.seasons: Temporal_of.season's own 'first run'/'second run'
comments confirm Ordinary Time is genuinely interrupted by Lent and
Easter over one liturgical year, so the expected run-length-compressed
sequence names it twice, six runs over five seasons -- exactly the
case Rite.t.season_runs's own doc comment already names as its
illustration for why this field is rite-supplied rather than derived.
easter/fixed_key are as specified, each carrying its own citation
(Gregorian computus; the 2002 Missal's one bissextilis occurrence is a
leap-year table entry, not a kalends-doubling rule, so fixed_key is
identity).

Follows rite_ef.ml's template and its lectionary-parameter lesson
exactly: lectionary is caller-supplied, not closed over.

test/test_rite_of.ml resolves the real assembled rite (calendar-2002
.sexp + all 13 amendment overlays + lectionary.sexp) through Calendar
and Validate.run, the same discipline test_validate.ml/test_rite_ef.ml
already apply to EF. This is the first time rite_of has been checked
this way, and it surfaced two new, real, cited gaps outside this
task's own scope to fix: Temporal_of never reaches Normae n.35(a)'s
30-December Holy Family fallback in a year with no Sunday in 26-31
December (first hit 1583, the domain floor), and Temporal_of.anchors
disagrees with temporal on 24 December when that date is itself a
Sunday (Advent IV outranks the Vigil, first hit 2006). Both pinned as
known-wrong, not fixed, the same treatment the brief's own pre-known
St Joseph/Palm Sunday gap (Normae n.56(f)) gets, pinned on 2062. A
third gap was found in data/of/lectionary.sexp's own coverage (audited
against one civil year only, so the other weekday-cycle letter is
unaudited and at least one pairing is asymmetric on shipped data) --
that file is excluded from this task, so the wide 2005-2050 sweep
checks structural invariants only and leaves the citation-chain checks
to the small, individually-audited landmark-year set.

make check (COLITUR_EXHAUSTIVE_SWEEP=1): exit 0, 867 tests, ~316s.
</content>
</entry>
</feed>
