<feed xmlns='http://www.w3.org/2005/Atom'>
<title>lectio.git/internal/caldata, branch perf/hoist-date-independent-work</title>
<subtitle>offline Catholic daily readings and liturgical calendar in Go, with CLI, TUI and web clients</subtitle>
<id>https://git.labunix.xyz/lectio.git/atom?h=perf%2Fhoist-date-independent-work</id>
<link rel='self' href='https://git.labunix.xyz/lectio.git/atom?h=perf%2Fhoist-date-independent-work'/>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/lectio.git/'/>
<updated>2026-08-18T15:15:27Z</updated>
<entry>
<title>fix(ef): the ferias between Epiphany and the Sunday after it</title>
<updated>2026-08-18T15:15:27Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-18T15:15:27Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/lectio.git/commit/?id=d27336dc65c7348dcda639b7e43e8948e7bb1caa'/>
<id>urn:sha1:d27336dc65c7348dcda639b7e43e8948e7bb1caa</id>
<content type='text'>
They repeat Epiphany's own Mass, Isa 60:1-6 / Matt 2:1-12. lectio gave them
the Mass of the first Sunday AFTER Epiphany (Rom 12:1-5 / Luke 2:42-52), which
belongs to the ferias that follow that Sunday, not to the ones before it.

The two groups cannot be told apart by slug: both are
ef-time-after-epiphany-1-&lt;weekday&gt;, because the week numbering starts at the
Sunday and the days before it fall in the same numbered week. So the split is
made on the date, against the same anchor efWeek uses.

Saturdays need no exclusion here -- an unoccupied Saturday in the window
carries Our Lady's office and her Mass, and that check runs first. colitur
reaches the same result by listing only the five non-Saturday weekdays.

7, 9 and 12 January 2026 now all match colitur, the 12th being the boundary
case: it follows the Sunday of the 11th and correctly keeps Rom 12:1-5.
</content>
</entry>
<entry>
<title>fix(ef): three saints with proper Masses had no readings at all</title>
<updated>2026-08-18T15:11:04Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-18T15:11:04Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/lectio.git/commit/?id=c4bface0c72283cef55f548feb2a4a3d9eff1e6c'/>
<id>urn:sha1:c4bface0c72283cef55f548feb2a4a3d9eff1e6c</id>
<content type='text'>
Francis of Paola (2 April), Thomas Aquinas (7 March) and John of God (8
March). Unlike the nine added in the previous commit these are NOT Common-
routed -- the Missal prints a proper Mass for each -- they simply had no
reading in this repository and resolved nothing.

John of God is the one worth a note: his Epistle, Ecclus 31:8-11, is also the
Common of a Confessor not a Bishop I, which makes him look Common-routed. He
is not; the Gospel differs and the Missal prints the Mass at his own date.

With these, every day of 2005-2050 resolves a reading. Nothing in that range
comes back empty any more, where before there were four such days.
</content>
</entry>
<entry>
<title>feat(ef): the Masses of saints that come from a Common</title>
<updated>2026-08-18T15:06:28Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-18T15:06:28Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/lectio.git/commit/?id=09f30b32bd5ad0895b23a13b63c1eb5a19184b1c'/>
<id>urn:sha1:09f30b32bd5ad0895b23a13b63c1eb5a19184b1c</id>
<content type='text'>
Nine saints have no proper Mass in the Missal. Its rubric at each one's own
date names a Common -- "Missa Statuit, de Communi Confessoris Pontificis I
loco", "Missa Iustus ... II loco", and so on -- and only the Oratio is proper.
lectio has no Commons concept, so those days resolved no reading at all.

Benedict, Frances of Rome, Gregory the Great, Isidore of Seville, Patrick,
Perpetua &amp; Felicity, Vincent Ferrer, Ubaldus and Didacus.

The readings are written per saint rather than by adding a Commons abstraction.
Each Common resolves to exactly one first/gospel pair for the saint that names
it, so a table plus an assignment layer would buy indirection and nothing else
here; if a future saint needs a Common's OTHER formulary, that is when the
abstraction earns its place.

They go into the generator's missalOverrides table like the rank and colour
corrections, because missalemeum supplies these days with whatever it supplies
them and a regeneration would otherwise leave nine saints mute. The table
learned two new field names to carry them. Four are pinned in
TestTridentineMissalOverrides.

Citations are colitur's, verified there against both photographic scans and
the rendered page images; its data/ef/commons.sexp header records the
three-source method and the per-value evidence.
</content>
</entry>
<entry>
<title>feat(ef): the Most Holy Name of Jesus, and the ferias of 2-5 January</title>
<updated>2026-08-18T15:02:47Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-18T15:02:47Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/lectio.git/commit/?id=9572942a0db4a89aaddd42cd33182d44a6e1fefb'/>
<id>urn:sha1:9572942a0db4a89aaddd42cd33182d44a6e1fefb</id>
<content type='text'>
RG 17(a): "festum Ss.mi Nominis Iesu, celebrandum dominica quae occurrit a die
2 ad 5 ianuarii, secus die 2 ianuarii." The Most Holy Name is kept on the
Sunday falling 2-5 January and, when no Sunday falls in that window, on 2
January instead. lectio built neither shape, so the day was an ordinary Sunday
within the octave and read Gal 4:1-7.

The FALLBACK matters more than it looks. The window is four days wide, so in
about three years in seven no Sunday lands in it -- in those years there was no
Holy Name office at all, a missing II-class feast rather than a misnamed one.
The test pins both shapes, checks the fallback does NOT also fire in a year
where the Sunday carries the feast, and asserts across 2005-2050 that every
year gets it exactly once by one shape or the other.

Separately, the ferial days of that window get their own Mass. The Missal's
rubric at the feast says it directly: "Diebus ferialibus a 2 ad 5 ianuarii
Missa dicitur ut die 1 ianuarii" -- the Circumcision's Mass, Titus 2:11-15 /
Luke 2:21. They had been falling through to the Sunday within the octave.

Ferial only, and the exclusions are the interesting part: the Sunday carries
the Holy Name and its own Mass, and an unoccupied Saturday carries Our Lady's
office and hers. 3 January 2026 is such a Saturday and correctly reads
Titus 3:4-7, not 2:11-15 -- which works because the BVM check runs first.

All four days of 2-5 January 2026 now match colitur.
</content>
</entry>
<entry>
<title>fix(ef): Passion week and Holy Week are two weeks, not one</title>
<updated>2026-08-18T14:49:03Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-18T14:49:03Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/lectio.git/commit/?id=74d557580e747cf309b8217d34ab6b9336939fca'/>
<id>urn:sha1:74d557580e747cf309b8217d34ab6b9336939fca</id>
<content type='text'>
efWeek had no Passiontide case, so both weeks fell through to 0 and every day
of Holy Week took the slug of its Passion-week namesake: ef-passiontide-0-
monday served both Passion Monday and Holy Monday. The two weeks therefore
shared one set of readings and Holy Week could not have its own -- Good Friday
was reading Passion Friday's Mass.

Numbered from Passion Sunday now, so the weeks are 1 and 2 and the slugs
distinguish them.

The six ef-passiontide-0-* sections are replaced by colitur's twelve rather
than renamed, and the reason is worth recording: they were not simply Passion
week's Masses. The Tuesday section carried HOLY Tuesday's (Jer 11:18-20 with
the Passion according to Mark), which was Passion Tuesday's only by the same
collision -- colitur documents that specific mix-up and its own correction of
it. Renaming 0 to 1 would have kept the wrong Mass on Passion Tuesday while
looking like a clean migration.

All twelve are colitur's, verified there against both photographic scans. All
six days of Holy Week now match colitur, and so does Passion Tuesday.
</content>
</entry>
<entry>
<title>fix(ef): twelve days were serving the preceding Sunday's Mass</title>
<updated>2026-08-18T14:46:47Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-18T14:46:47Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/lectio.git/commit/?id=a974243ff2a309dc9b4fe1632ddd5fbde6a526b0'/>
<id>urn:sha1:a974243ff2a309dc9b4fe1632ddd5fbde6a526b0</id>
<content type='text'>
Corpus Christi, the Sacred Heart, and the ferias of the first week after
Epiphany and the first week after Pentecost had no lectionary entry, so each
fell through the walk-back and read the Mass of the Sunday before it. Corpus
Christi -- a I-class feast with one of the best-known formularies in the
Missal -- was reading Trinity Sunday's.

RG 299 is why the first weeks need naming where the others do not: "Item
propriam Missam habent omnes feriae..." -- those ferias have proper Masses,
and the walk-back that serves the rest of the year correctly is wrong for
them.

Citations are colitur's, verified there against both photographic scans. They
were added rather than derived: a comparison of the two lectionaries found the
110 shared slugs agree on EVERY citation, so the divergence was entirely
entries lectio lacked, not entries it had wrong.

Twelve of the 43 colitur has and lectio lacked. The other 31 name days lectio
calls something else, so adding them verbatim would be dead data; those need
the slug question answered first and are deliberately not touched here.
</content>
</entry>
<entry>
<title>fix(ef): the weekdays within the Octave of the Nativity have their own Mass</title>
<updated>2026-08-18T14:32:52Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-18T14:32:52Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/lectio.git/commit/?id=5ee75098e1c86fdce195df2e37784c18a2b081a5'/>
<id>urn:sha1:5ee75098e1c86fdce195df2e37784c18a2b081a5</id>
<content type='text'>
29, 30 and 31 December are named days in the Missal's calendarium -- "De V die
infra octavam Nativitatis Domini, II classis" and so on -- with a direct
formulary, "Diebus infra octavam Nativitatis Domini": Titus 3:4-7 /
Luke 2:15-20, and each date's own rubric pointing at it ("Die 29 decembris ...
Missa Puer natus est nobis, ut supra").

lectio treated them as ordinary Christmas ferias, so they fell back to the
preceding Sunday and served "Dominica infra octavam Nativitatis Domini"
(Gal 4:1-7 / Luke 2:33-40) -- a different heading, for the Sunday
specifically.

Worth recording because it is not a guess: colitur made the IDENTICAL mistake,
gave these three days the Sunday's citation, measured it against real years
and reverted it. Its bootstrap_lectionary.ml keeps the rejection on record
with the scan references for both headings, which is how this one was
diagnosed rather than re-derived.

Only the weekdays. When 29-31 December falls on a Sunday the day really IS
Dominica infra octavam and keeps the Sunday's Mass -- 2030-12-29 is the case,
and it is asserted, because a fix applied by date alone would pass on the
weekdays and silently swallow the Sunday. Mutation-tested: dropping the Sunday
exclusion reddens exactly that assertion and nothing else.
</content>
</entry>
<entry>
<title>feat(ef): the Mass of Our Lady on Saturday (RG 309(a))</title>
<updated>2026-08-18T14:27:05Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-18T14:27:05Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/lectio.git/commit/?id=2dc44fbbc581430e2038e2ff6d67265fe716791c'/>
<id>urn:sha1:2dc44fbbc581430e2038e2ff6d67265fe716791c</id>
<content type='text'>
RG 78 gave the day Our Lady's office and its white colour; this gives it her
Mass. RG 309(a): "Missae de sancta Maria in sabbato ... iuxta temporum
diversitatem" -- the Missal prints five formularies and the season selects
among them.

Without it the day was kept as Our Lady's and then read the FERIA's Mass, so a
Saturday in Septuagesima announced Our Lady and read the parable of the
labourers. colitur hit and fixed the identical bug in its own v0.3.0.

The five, with the two seams that are easy to get wrong:
  Advent            Isa 7:10-15      / Luke 1:26-38
  Christmas Time    Titus 3:4-7      / Luke 2:15-20
  ...and on until the Purification (2 February), not merely to the end of
     Christmas Time
  thereafter        Ecclus 24:14-16  / Luke 11:27-28
  Paschaltide       Ecclus 24:14-16  / John 19:25-27  -- same first reading,
     different gospel, which is why the test asserts the gospel separately

Citations are colitur's, verified there against both photographic scans.

The Advent formulary is unreachable as the Saturday office -- Advent has no
IV-class ferias -- and is kept anyway, because RG 309's subject is the Masses
themselves and a missing branch would fall through silently if the rank rules
ever changed.

Guarded on the office rather than the day: a sanctoral feast that outranks the
Saturday keeps its own readings, so the observed slug must still be the
temporal one. All twelve BVM Saturdays of 2026 now agree with colitur on
readings, where none did before.
</content>
</entry>
<entry>
<title>fix(ef): twelve RG 124 colours -- missalemeum has the rule inverted</title>
<updated>2026-08-18T13:39:48Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-18T13:39:48Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/lectio.git/commit/?id=967e911728eefb85dc53065c73c5c5d4cdce6a59'/>
<id>urn:sha1:967e911728eefb85dc53065c73c5c5d4cdce6a59</id>
<content type='text'>
RG 124, "De coloribus paramentorum", section C, both photographic scans word
for word: 124(b) gives red to "Sanctorum Apostolorum et Evangelistarum, in
eorum die natalicio, excepto festo S. Ioannis (27 decembris)", and 124(e) to
"Sanctorum Martyrum, quorum colitur aut martyrium". Red is for Apostles,
Evangelists and Martyrs. A Confessor, Doctor or non-martyr Virgin is white.

missalemeum has twelve of these INVERTED IN BOTH DIRECTIONS: ten confessors,
doctors and virgins in red (Ephrem, Julia of Falconieri, John Gualbert,
Camillus de Lellis, Jerome Emiliani, Martha, Alphonsus Liguori, Augustine,
Rose of Lima, John of San Fecundo), and two actual martyrs in white
(Apollinaris and Josaphat, both Bishop and Martyr). Both directions failing is
why this reads as one rule applied backwards rather than twelve separate
slips, and why they are corrected as a block.

Adjudicated by colitur against the scans -- its C18 carries the per-slug
reasoning and its M21 the oracle side, verdict colitur. Two of its fourteen,
conversion-of-st-paul and chair-of-st-peter, already agreed here.

Found by a full-year sweep comparing clectio's output against colitur day by
day, not by the patch tool that produced the earlier corrections. That tool
reads colitur's sanctoral.sexp directly and so misses everything in
adjustments.sexp, the overlay where all twenty of colitur's colour edits
actually live -- its SECOND structural blind spot, after temporal days.

All twelve go into the generator's missalOverrides table, so regeneration
preserves them, and into TestTridentineMissalOverrides, now sixteen pinned
fields. Mutation-tested in BOTH directions: reverting a martyr to white and a
confessor to red each redden the test with the rubric named. Pinning only one
direction would have let a careless "make them all white" fix pass ten of
twelve.

The oracle allow-list gains one entry covering the twelve dates in both years.
</content>
</entry>
<entry>
<title>feat(gen): teach the EF generator to preserve the Missal corrections</title>
<updated>2026-08-18T12:58:20Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-08-18T12:58:20Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/lectio.git/commit/?id=46653b24b0afff60be35c3e876830eb522fd2acc'/>
<id>urn:sha1:46653b24b0afff60be35c3e876830eb522fd2acc</id>
<content type='text'>
The four calendar corrections adopted from colitur are not in missalemeum, so
re-running gen-sanctoral-ef.go silently reverted them. Warning about that in
three places was the stopgap; this fixes it.

The generator now carries a missalOverrides table -- slug, field, required
value, and the authority for it -- applied after every harvest and collision
fix-up has settled, so the Missal's value is the last word. Regenerating is
now safe; hand-editing the generated file is not, and both the file's header
and the generator's comment now say which way round that is.

An explicit table rather than "preserve whatever the existing file had",
which is how the name.&lt;lang&gt; preservation beside it works and would have been
less code. Preserving from the file cannot distinguish a deliberate
correction from staleness: if missalemeum ever fixes one of these, a
preserve-from-file rule would keep overriding it forever with nobody the
wiser. Naming each override with its rubric makes an obsolete one findable by
reading four lines. The apply step reports "already correct upstream" when it
finds one, which is the signal to retire it.

It FAILS rather than warns when an override names a slug the run did not
harvest. A rename upstream would otherwise drop a correction silently, which
is the precise accident the table exists to prevent.

TestTridentineMissalOverrides pins all four values from the other side, so a
regeneration that stopped applying them fails the suite rather than only
failing quietly. Mutation-tested: reverting the Assumption vigil to
missalemeum's white reddens it with a message naming the cause. It also
asserts the Ascension's vigil is NOT violet -- RG 128's rule is "outside
Paschaltide" and that one is inside it -- so a careless "make every vigil
violet" fix fails too.
</content>
</entry>
</feed>
