<feed xmlns='http://www.w3.org/2005/Atom'>
<title>colitur.git/man, branch v1.0.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=v1.0.0</id>
<link rel='self' href='https://git.labunix.xyz/colitur.git/atom?h=v1.0.0'/>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/'/>
<updated>2026-08-22T21:24:12Z</updated>
<entry>
<title>feat(ef): the Mass preface, RG 482-499</title>
<updated>2026-08-22T21:24:12Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-22T21:24:12Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=0806fe65e388a9502035bc9d4f551528ac74b26d'/>
<id>urn:sha1:0806fe65e388a9502035bc9d4f551528ac74b26d</id>
<content type='text'>
Item 2 of Phase 3 (celebrant-rubrics-phase1), the bulk of this phase
and the last EF Mass rubric this project scoped: which preface is
said, deferring to seasonal/proper-title rules for the fourteen named
prefaces, then RG 498's Common residual.

RG 482 gives the resolution chain: the Mass's own proper preface,
failing that the seasonal one, failing that Common. Read literally,
RG 484-497 look like fourteen separate rules, but each numbered
rubric's own propria/de-Tempore pair produces the SAME preface
identity either way, so the whole chain collapses into one priority-
ordered decision: title/mystery triggers (Holy Cross, Sacred Heart,
Christ the King, Trinity, St Joseph, BVM, the Nativity octave, the
Apostles, Epiphany), each independent of season, then six seasonal
windows (Nativity, Epiphany, Lent, Holy Cross/Passiontide, Easter,
Ascension, Holy Spirit, Trinity-for-ordinary-Sundays), then Common.

The "one genuinely unproven piece" the design spec worried about --
per-feast proper prefaces extracted from the Missal's propers at scale
-- turned out not to be a large-scale extraction problem at all: every
one of the fourteen propers is a closed, small, subject/slug-keyed
trigger (mirroring Precedence_ef.band's own RG 91 table), not
thousands of individual saints' pages. The one genuine open question
(RG 488, the Chrism Mass) is N/A: this engine resolves one Mass per
civil day and has no separate Chrism-Mass dimension.

Preface is a new kernel type (lib/kernel/preface.ml[i]), not an
EF-specific one, the same placement as Colour/Subject/Mass_formulary:
Liturgical_day.t is parameterised only over season/rank, so any field
it carries generically must live in the kernel even though only EF
constructs a value of it today. Wired exactly as creed/gloria were
(Rite.t.preface, Calendar.ml, Rite_ef.context), but Preface.t option,
not a bare bool: unlike creed/gloria, a preface is said only at a
Mass, and Good Friday (1955-restored Holy Week) resolves an observed
celebration but has no Mass at all -- None is the honest answer there,
and also the neutral value an unimplemented rite returns.

Two priority-order findings only the oracle settled, not derivable
from the Latin text in isolation, both cross-checked against 358
individually classified entries in the FIUV Ordo's own praef column
(test/fixtures/fiuv-ordo-2025-2026.sexp, already captured, wired up
here as a new comparison axis): RG 484(b)'s own "except Masses with a
proper of the divine mysteries or Persons" is narrower than every
other window's implicit exception (an Apostle inside the Nativity
octave is overridden to Nativity; outside it, keeps his own preface
even inside another window); and RG 495's "et votivis" half is live
for the one office this engine models without a votive-Mass dimension
(the Saturday Office of the BVM), which also proved a vigil is not a
"festum" for this purpose (the Assumption's own vigil takes Common,
not BVM, correcting an initial reuse of Precedence_ef.marian_slugs
that had no reason to make that distinction for its own, different
rubric). A third, RG16(a)-shaped fix landed the same way: RG 494(b)'s
own Trinity grant must read the day's TEMPORAL season, not the
celebration that actually won it, or a Class1 feast with no preference
of its own (All Saints) wrongly falls to Common on a Sunday it merely
commemorates.

colitur rubrics gains a sixth TAB-separated column. Domain-wide
1583-9999 exhaustive sweep confirms every Christmastide day resolves
Nativity/Epiphany/Bvm, every Paschaltide day one of its own three
windows or a season-independent title, every Lent day Lent or a
title, and Passiontide legitimately produces Easter exactly once a
year (the Vigil Mass) -- 8416 of the domain's 8417 years, the one
short year being the domain's own upper boundary (the liturgical year
opening in 9999 cannot construct dates in year 10000, a pre-existing
edge this sweep re-confirms rather than a new one).

day/readings verified byte-identical to the branch's own state before
this phase (commit 9c96e0a) across a 455-year sample spanning the
whole domain -- not literally to the v0.10.1 tag, which 22 earlier
commits on this same branch (Phase 1/2, the bissextile shift, the
Rogation colour fix) had already moved past before this phase began.
</content>
</entry>
<entry>
<title>feat(ef): the Gloria in excelsis, RG 431-432, deferring to Breviary 237-238</title>
<updated>2026-08-22T15:56:42Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-22T15:56:42Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=f4cc032d7e812d716ff6b5df8192f79a2560e8f0'/>
<id>urn:sha1:f4cc032d7e812d716ff6b5df8192f79a2560e8f0</id>
<content type='text'>
Phase 2 of celebrant-rubrics-phase1: colitur rubrics gains a fifth
column, whether the Gloria is said. Follows the Creed's own seam
exactly -- Rite.t.gloria, Liturgical_day.t.gloria, wired through
calendar.ml the same way.

RG 431(a)/432(a) defer the Gloria to the Breviary's own Te Deum rule
(nn. 237-238), so te_deum is implemented as its own named predicate,
cited clause by clause, not collapsed into a colour heuristic. 431(c)
(Holy Thursday, the Easter Vigil Mass) and 432(b)/(d) (violet; a
Requiem) are independent overrides checked ahead of the Te Deum-derived
answer. Every clause this engine has no dimension to model
(votive Mass classes, the wider n.302 "Missa festiva" categories) is
stated as N/A with its own reasoning, not silently dropped.

Validated against the FIUV universal Ordo (Gloria and Te Deum) and all
three LMS editions (Gloria). A first pass over-trusted a clean-looking
15-for-15 FIUV contradiction of 237(b)'s own Septuagesima exception and
replaced it with a blanket "every Sunday" rule; the evidence was itself
corrupted -- the FIUV extractor recognised only one of the source's two
Te Deum negations ("non dicitur", not "sine"), so every "sine Te Deum"
Sunday read wrongly true. Fixed in tools/extract_fiuv_ordo.ml, fixture
re-extracted, and the literal 237(b) reading restored once the
corrected data confirmed it. A second bug surfaced alongside it (Palm/
Passion Sunday wrongly reading true via Temporal_ef.named's own table
membership, then Christ the King wrongly reading false from an
over-broad fix) is closed with an explicit two-slug exclusion.

Domain-wide 1583-9999: every violet or Rose day is gloria=false except
the Easter Vigil (RG 431(c) lex specialis), every Requiem is
gloria=false, both measured exhaustively, zero exceptions. Mutation-
proved: disabling 431(c) reddens 8 tests including all four oracle
comparisons; disabling 238(c)'s feria-I-classis exclusion reddens
exactly the dedicated Ash Wednesday unit test, a genuine blind spot in
both oracle layers, reported rather than hidden.

Two open, cited findings, neither fixed here (out of this task's
"follow creed's exact seam" scope): a privileged Lenten/Passiontide
feria carrying one commemoration reads Gloria=true in the LMS Ordo but
Te-Deum=true/Gloria=false in FIUV -- the two oracles disagree with each
other, not merely with colitur (data/ef/expected-divergences-lms.sexp
L5, expected-divergences-fiuv.sexp F3); and a pre-existing, uncited
Colour.Violet bug on Rogation Monday/Tuesday in Temporal_ef.temporal,
surfaced by this comparison but root-caused as a separate defect (L6).

day/readings verified byte-identical against a build from the branch
tip before this task (v0.10.1's own tag predates an already-landed
bissextile fix that legitimately changed both, so it is not the right
baseline).

671 tests green (dune test); 678 with the exhaustive sweep
(COLITUR_EXHAUSTIVE_SWEEP=1 dune test --force, ~104s).
</content>
</entry>
<entry>
<title>docs: six validation layers, not five -- the LMS Ordo is wired in</title>
<updated>2026-08-22T11:55:15Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-22T11:55:15Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=1ee397c5a09bb5c999e1681f0a6a5d884f2f9ff4'/>
<id>urn:sha1:1ee397c5a09bb5c999e1681f0a6a5d884f2f9ff4</id>
<content type='text'>
Task 6 (celebrant-rubrics-phase1) added test_lms_ordo.ml as a sixth
validation layer, comparing 400 days against a printed Latin Mass
Society Ordo -- a genuinely independent fourth lineage, never passed
through Divinum Officium/missalemeum/lectio. README.md's own table
still said "Five validation layers"; man/colitur.1 still said "two
published-calendar oracles"; CLAUDE.md still said "5 layers" in two
places and, worse, stated as fact that "the published Ordo... Not
wired in as a layer" in the file every future session is instructed
to read first.

Updated all three, describing what the new layer covers (the Creed,
the BVM Saturday votive Mass's own seasonal selection, the reading
formulary override) and what it cannot see (one civil year, only
three of the formulary axis's five sources, England &amp; Wales diocesan
propers excluded from every comparison) -- consistent with
docs/research/ordo/PROVENANCE-lms.md, not overstating it.

CLAUDE.md's own stale claim is corrected in place, not silently
rewritten, matching the file's own established convention: the
paragraph it lived in was about a DIFFERENT, earlier Ordo (unreliable
PDF column extraction, still genuinely unwired for that reason), and
its own closing prediction -- "a structured Ordo would be the only
way to add a fourth lineage" -- is exactly what the LMS Ordo's
structured extractor (tools/extract_lms_ordo.ml) has since done.
Historical "five layers" mentions elsewhere in CLAUDE.md, describing
completed state as of earlier branches, are left alone -- they were
true then, and rewriting them would misrepresent the record the same
way overstating layer 6's own coverage would.

Left README's pre-existing v0.9.0/569-tests staleness untouched, as
instructed -- it predates this branch and is a separate matter.
</content>
</entry>
<entry>
<title>feat(ef): the Creed, RG 475-476</title>
<updated>2026-08-22T10:02:01Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-22T10:01:48Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=d4682c13161b62bc83eaae37790493f670d39c01'/>
<id>urn:sha1:d4682c13161b62bc83eaae37790493f670d39c01</id>
<content type='text'>
Whether the Creed is said at Mass. New Rubrics_ef.creed, reached through
a new Rite.t.creed field and a new Liturgical_day.t.creed bool (false,
not an option, for a rite that has not implemented the rule); colitur
rubrics gains a fourth TAB-separated column.

475(a) reads the TEMPORAL cycle's own weekday, not the observed day: a
Sunday impeded by a Feast of the Lord (RG 16a) still says the Creed.
475(d)'s three octaves (Nativity, Easter, Pentecost) are pure date/
Easter-offset windows, checked first, since a saint's feast winning the
day inside one of them still says the Creed ("etiam in festis
occurrentibus") -- St Stephen, 26 December, is the live witness.

RG 23 classifies Ash Wednesday and every feria of Holy Week (including
the Sacred Triduum) as feriae, not festa, however high their rank, so
475(b)/(c)'s "in festis" never reaches them; this single check subsumes
476(a)'s own naming of the Chrism/Lord's-Supper Mass and the Easter
Vigil. RG 28-34 vigils are a third liturgical-day category, also
excluded from "in festis" regardless of rank -- reuses the already-
exported Precedence_ef.is_vigil rather than a new list.

475(e)'s Apostle/Evangelist natalicia list (creed_apostle_slugs) was
derived by grepping data/ef/sanctoral.sexp directly and checking each
candidate's own date against whether it is that saint's dies natalis --
not copied from any list supplied with the task. The Conversion of St
Paul and the 30 June Commemoration of St Paul are excluded (neither is
a natalicium); the Chair of St Peter and St Barnabas are included only
because the clause names them explicitly, which is exactly why it has
to: neither is a natalicium either.

475(c)'s BVM half reuses Precedence_ef.marian_slugs (newly exported)
rather than the subject field alone: checked against the shipped data,
almost every Marian sanctoral entry ships subject=Saint, not Bvm.

man/colitur.1's rubrics section is updated to match the new column;
test/cli.t repinned via dune promote for the same reason. Verified
day/readings output byte-identical to v0.10.1 across the whole
1583-9999 domain (both binaries' concatenated day+readings output,
6,148,492 lines each, zero diff). Domain-wide: 882,996 days say the
Creed, 2,191,250 do not; every one of the domain's 439,178 Sundays says
it, zero exceptions.
</content>
</entry>
<entry>
<title>feat(cli): colitur rubrics prints the day's Mass formulary</title>
<updated>2026-08-22T09:21:14Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-22T09:21:14Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=fd8a4f115d3c62450368cf9b3fed5705ce78e805'/>
<id>urn:sha1:fd8a4f115d3c62450368cf9b3fed5705ce78e805</id>
<content type='text'>
Separate from day for the reason readings is: a formulary name contains
spaces and day's row is space-separated with a variable-length tail.

Modelled on readings' own structure (year parsing, --overlay plumbing,
error handling): --overlay is accepted, since an overlay can change
which celebration is observed and hence which Mass is said. --lang,
--raw and --sigla-* are refused rather than silently ignored -- this
row resolves no display name and no citation for any of them to
affect.

Output is TAB-separated (date, formulary slug, source), not space or
" | " like the two existing reports: a resolved formulary NAME is a
column a later task may add, and it can carry both spaces and
punctuation a citation never does, ruling out either separator already
in use.

day and readings verified byte-identical (sha256) against a v0.10.1
build across 1583/1900/2026/2038/9999. Man page documents rubrics
beside readings and renders through groff with no errors.
</content>
</entry>
<entry>
<title>docs(config): document the flavour key</title>
<updated>2026-08-21T10:33:30Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-21T10:33:30Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=0eae32f67145065b0e4960650ae06c293fd9f272'/>
<id>urn:sha1:0eae32f67145065b0e4960650ae06c293fd9f272</id>
<content type='text'>
colitur.1 documented the flag and colitur-config(5) documented every
[defaults] key except this one, which the previous commit added.

Says what a flavour IS rather than only listing the values: the set of
characters that must be neutered so a value cannot corrupt its target.
A semicolon is ordinary text in LaTeX and a field separator in
iCalendar; an unescaped &amp; or _ does not look wrong in LaTeX, it aborts
the build. Also why unset means INFER rather than 'no escaping', and why
there is no silent fallback.
</content>
</entry>
<entry>
<title>fix(render): a month answers to both spellings of its own name</title>
<updated>2026-08-20T20:33:07Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-20T20:33:07Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=671c4264707ec8c81845059746632b00f2481d88'/>
<id>urn:sha1:671c4264707ec8c81845059746632b00f2481d88</id>
<content type='text'>
A week object carries month_name/month_num/month_abbr, because at that
level a bare `name` would be ambiguous. An author who learned those names
inside {{#weeks}} reaches for them one level up inside {{#months}} too --
where they resolved to nothing, and an unknown key renders as the empty
string by design, so the result was a silently blank month heading rather
than any error.

Found by writing a template from scratch rather than copying a shipped
one; every shipped template sidesteps it, which is why nothing caught it.

The aliases are additive, so no existing template or golden changes.
colitur-templates(5) now documents both spellings and says why they
exist.
</content>
</entry>
<entry>
<title>fix(citation): close the final review's blocking findings</title>
<updated>2026-08-20T17:03:02Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-20T17:03:02Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=1da70dc7ac03fe33fb92b172a0e26932764170d6'/>
<id>urn:sha1:1da70dc7ac03fe33fb92b172a0e26932764170d6</id>
<content type='text'>
The branch was RED and reported green. `dune test` exited 1: test/cli.t
pinned the pre-fix output `kings_1 19:3-8`, which the previous commit had
already fixed to `1 Reg 19:3-8`. The gate command piped dune through
`tail`, so it reported tail's exit status, and cram prints its diff
BEFORE the alcotest summary, so the two lines shown were the passing
ones. Verify with `dune test; echo $?`, never through a pipe.

A style file's own `book` key was unreachable. sigla_book resolved
against a hardcoded "abbr" and the result was applied unconditionally,
so the documented `[sigla] book = full` could never win. Render gains
book_string, and the style's own value is now the default that a flag or
config overrides. The unit test pinned style_of_fields correctly while
the wiring defeated it.

`lang --check` filtered the reference set to the celebration prefix, so
a file with no [bible] section at all reported a clean bill of health --
contradicting both the reason the keys change was made and lang.ml's own
comment. It now reports missing book names too.

The token test missed a FOURTH citation-bearing file: adjustments.sexp
writes citations as `Set_citation`, not `(reference ...)`. Its 16
citations all parse, so nothing was broken, but nothing was checking.
The first attempt at this fix read the file and extracted NOTHING -- the
marker stopped before the opening quote, so every payload was the part
label -- which is recorded in the code rather than left as a trap.

Also: colitur-config(5) claimed a trailing period the data does not
carry, and two la.ini scan quotes silently corrected OCR damage
("Ionae 3, I - I O", "Epistolse") while presenting themselves as
verbatim. Both are now marked as corrections.
</content>
</entry>
<entry>
<title>fix(lang): stop internal book ids reaching output, and finish the docs</title>
<updated>2026-08-20T15:33:26Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-20T15:33:26Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=46ffa91fd4fcc2249cd097b3b3a639d37a7d592e'/>
<id>urn:sha1:46ffa91fd4fcc2249cd097b3b3a639d37a7d592e</id>
<content type='text'>
Three defects, all found by running the documented examples rather than
by reading code.

All seven modern-numbering targets carried their own internal id as
their Latin name (kings_1.full = kings_1), so --sigla-tradition modern
printed "kings_1 19:3-8" -- leaking a key book.mli states is never shown
to a reader. They now carry Vulgate-derived Latin names marked
CONSTRUCTED: the 1962 Missal uses Vulgate numbering throughout, so it
can contain no incipit for a book that exists only under a later
convention. In Latin the modern tradition therefore only moves Kings and
Esdras; Osee, Ionas, Ecclesiasticus and the Apocalypse keep their names
either way, since modern numbering is a vernacular convention.

The coverage test could not catch this. It compares a name against its
KEY ("kings_1.full"), and "kings_1" differs from that, so the row
passed. A second check now asserts no name IS its own id. The two are
complementary: one catches a missing row, the other a row present but
filled with the wrong thing. Mutation-proved.

--help still claimed sigla settings were resolved "but not yet
rendered", stale since the render wiring landed. colitur-config.5
documented none of the three settings even though config --show prints
them.
</content>
</entry>
<entry>
<title>docs(citation): sigla flags, book naming and traditions</title>
<updated>2026-08-20T15:29:44Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-20T15:29:44Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/colitur.git/commit/?id=152bba4c94060ea2ac7430dfdf826450ee4f2bd8'/>
<id>urn:sha1:152bba4c94060ea2ac7430dfdf826450ee4f2bd8</id>
<content type='text'>
Includes that --raw emits citations verbatim, which is the behaviour
someone diffing against lectio depends on.
</content>
</entry>
</feed>
