<feed xmlns='http://www.w3.org/2005/Atom'>
<title>lectio.git/internal/bible, 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-07-29T11:20:56Z</updated>
<entry>
<title>bible(wuj): strip leaked verse numbers from the deuterocanon text</title>
<updated>2026-07-29T11:20:56Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-07-29T11:20:56Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/lectio.git/commit/?id=8c15fac1c65806f97e1bfec2fd8af3e17d8d7b22'/>
<id>urn:sha1:8c15fac1c65806f97e1bfec2fd8af3e17d8d7b22</id>
<content type='text'>
~3,800 verses carried their own verse number at the start of the text (a
biblia.info.pl harvest artifact concentrated in the deuterocanonical books --
Sirach, 1-2 Maccabees, Wisdom, Judith, Baruch, at 90-98% of each, plus 3 strays
in Ezra/Proverbs). E.g. Sirach 4:4 read "4 Nie odrzucaj..." instead of "Nie
odrzucaj...". It passed every check: verse counts are unaffected, and the
verses aren't short.

Strip a leading token only where it exactly equals the verse number (so a
genuine "40 dni" in a non-matching verse is untouched), and only when text
follows. 3797 verses fixed; 35,810-row parity preserved, no verse emptied, no
new warnings; --corpus-check wuj still clean; make test green.
</content>
</entry>
<entry>
<title>bible(corpus-check): warn on a verse present but stubbed vs the Vulgate</title>
<updated>2026-07-29T10:09:57Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-07-29T10:09:57Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/lectio.git/commit/?id=806503cc3da3be227855910b222de8b72be549bc'/>
<id>urn:sha1:806503cc3da3be227855910b222de8b72be549bc</id>
<content type='text'>
The count-based checks (gap, duplicate, missing chapter) only see a verse's
presence, so a verse that IS there but truncated -- a lost opening line, a merge
artifact, the exact class that lost 44 psalm openings and Acts 6:5 from the old
Wujek scrape -- passes silently.

Add a warning for it, compared CROSS-CORPUS to the aligned Vulgate verse (never
within the chapter). That is deliberate: a genuinely terse verse ("Non occides",
"Jesus wept") is short in the Vulgate too, so it is not flagged; only a corpus
stub against a substantial Vulgate verse fires (corpus &lt;12 chars, &lt;1/4 of a
Vulgate verse &gt;=40). Rune-counted (script-agnostic) and skipped on the Psalms
when the corpus renumbers them (psalm_system != vulgate), where per-verse
alignment with the Vulgate would not hold.

Warning only, never an error. Zero false positives across vul/wuj/drb/grb;
a `stub` testdata fixture (Genesis 1:1 = "x") exercises a real hit.
</content>
</entry>
<entry>
<title>test(bible): skip corpus-dependent tests when optional corpora aren't embedded</title>
<updated>2026-07-29T09:46:17Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-07-29T09:46:17Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/lectio.git/commit/?id=8ddd910dd545c45a7227da87ca125758b4a0e2cb'/>
<id>urn:sha1:8ddd910dd545c45a7227da87ca125758b4a0e2cb</id>
<content type='text'>
Since 51c0f4e split the corpora (only vul embedded by default; wuj/drb/grb
behind -tags fullbible), `go test ./...` on the default build was red across six
packages -- every failure was a test assuming an optional corpus is present.

Guard those assertions with a skip keyed on bible.Meta(code), so they run under
-tags fullbible and skip -- not fail -- on the default vul-only build. Mixed
tests are split into subtests so the always-embedded vul assertions and pure
logic (pl-&gt;vul fallback, explicit passthrough, bt-rejection, i18n labels) keep
running on both builds. Test-only change; no product code or corpora touched.

- internal/bible: TestVerses, TestLookup, TestCorpusBooks, TestChapters,
  TestGrbNoApparatusMarkers, TestCrossChapterRange* (requireCorpus helper).
- internal/cli, config, render, tui, web: the same pattern for their
  corpus-dependent tests.
- Fixes an index-out-of-range panic in internal/tui's reader tests that was
  aborting the package binary and masking 3 further corpus-absence failures
  (TestReaderBookmarkFlow, TestReaderChapterJump, TestReaderRemembersPlace).

Verified: `go test ./...` and `go test -tags fullbible ./...` both green (0 FAIL);
guards active only on the default build (29 skips vs 1 unrelated pre-existing);
gofmt and go vet clean.
</content>
</entry>
<entry>
<title>bible(grb): restrict to the Vulgate canon; restore Hosea and Zechariah</title>
<updated>2026-07-29T09:13:03Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-07-29T09:13:03Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/lectio.git/commit/?id=ab9a02b34d88e6c85e4d494077bb474dc19adbce'/>
<id>urn:sha1:ab9a02b34d88e6c85e4d494077bb474dc19adbce</id>
<content type='text'>
grb failed corpus-check outright: 15 errors, and two whole books absent from
lectio at runtime with no error and no warning.

Upstream grb is a standalone Septuagint reader carrying 87 books. lectio needs
one uniform canon, so scripts/gen-grb-lectio.py derives the 73 books vul has
rather than forking -- upstream stays intact and keeps everything.

Eleven books have no Vulgate counterpart and are dropped, including 2 Esdras,
which upstream's README explains IS Ezra + Nehemiah under the Septuagint's
name; verified byte-identical, so nothing is lost. Five books ARE canonical
under other names and are remapped, and the verse counts show which witness
the Vulgate follows -- Jerome translated Theodotion, not the Old Greek:

    Bel and the Dragon (Theodotion)  42 = vul Daniel 14 (42)   exact
    Bel and the Dragon (LXX)         37                        no
    Sussana (Theodotion)             64 = vul Daniel 13 (65)
    Sussana (LXX)                    37                        no
    Letter of Jeremiah               73 = vul Baruch 6  (72)
    Wisdom of Solomon               435 = vul Wisdom   (439)

Upstream's plain "Daniel" is the Old Greek and is missing chapter 4 outright,
so Theodotion supplies Daniel throughout: complete, and the tradition the
lectionary actually cites. lectio thereby GAINS Wisdom, Daniel 4, Daniel 13-14
and Baruch 6 in Greek rather than losing them.

Three upstream defects are repaired in transit:

  * 408 rows carried 5 fields, not 6 -- a lost tab fused the book number and
    chapter ("281" = book 28, chapter 1). Every one was in Hosea or Zechariah,
    and neither book had a single well-formed row, so bible.go skipped both
    entirely. Hosea (197 verses) and Zechariah (211) are back.
  * 5 merged verse labels ("27-28") that strconv.Atoi turns into verse 0.
  * A UTF-8 BOM welded to the first book name, making "Genesis" a phantom
    74th book matching nothing.

The SBLGNT apparatus sigla are stripped, as TestGrbNoApparatusMarkers
requires; regenerating from raw upstream reintroduces ~8700 of them.

grb now passes. The remaining warnings are the Septuagint being itself --
Jeremiah is LXX-numbered (grb 33:2 is the Vulgate's 26:2), Esther integrates
its additions into chapters 1-10, LXX Malachi has three chapters, and 3
Kingdoms carries supplements like 10:22a that upstream stores as a duplicate
verse 22. Silencing those would mean deleting real Greek text.
</content>
</entry>
<entry>
<title>bible(drb): renumber three chapters, fill eight absent verses</title>
<updated>2026-07-29T09:12:41Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-07-29T09:12:41Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/lectio.git/commit/?id=fe2a08daf55daa74810cf6e17ab49b9d8b53c89e'/>
<id>urn:sha1:fe2a08daf55daa74810cf6e17ab49b9d8b53c89e</id>
<content type='text'>
Eight corpus-check warnings, of two kinds.

Three chapters (Exodus 40, Genesis 49, Song of Solomon 1) held exactly as many
verses as the Vulgate but numbered with a gap. The count pins the mapping, so
renumbering 1..N is safe and changes no text.

Five chapters were genuinely short. The missing verses came from get.bible's
douayrheims -- the same public-domain source and API scripts/gen-deutero.py
already uses for this corpus, so no new provenance is introduced.

Scope was deliberately narrowed to the flagged chapters. A first pass over
every chapter shorter than the Vulgate pulled in 938 verses, 820 of them in
Psalms -- but drb.ini declares psalm_system = drb, a different numbering, so
matching by Vulgate verse number there would have inserted the wrong text
under the wrong numbers across the Psalter.

One warning remains and is not a defect: Baruch 6 runs 1-72 with verse 37
absent in drb and in get.bible alike, a genuine Douay/Vulgate versification
difference faithfully represented.
</content>
</entry>
<entry>
<title>bible(wuj): rebuild from source, repair to exact Vulgate parity</title>
<updated>2026-07-29T09:12:24Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-07-29T09:12:24Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/lectio.git/commit/?id=390535ff00d61df63a15de6fba23761a2c57cead'/>
<id>urn:sha1:390535ff00d61df63a15de6fba23761a2c57cead</id>
<content type='text'>
The Wujek corpus was missing text and mis-numbering what it had: 453
corpus-check warnings, 8 absent chapters, 84 duplicate rows, and 357 chapters
holding fewer verses than the Vulgate.

Most of it was never a sourcing problem. The original harvest of
biblia.info.pl assumed one verse is one &lt;p&gt;, but many psalms print the
superscription in the anchored paragraph and the psalm's opening line in an
unanchored one behind a drop cap -- so 44 psalms lost their first line, and
Acts 6:5 and others went the same way. Re-harvested with the anchor treated as
a verse START rather than a whole verse (scripts/scrape-wujek.py), which also
had to cope with four anchor shapes across books, hidden page markers opening
paragraphs mid-verse, chapter ids that are simply wrong (Mark labels 87
anchors "15:*" across chapters 14-16), and Psalms heading its divisions
"Psalm CXVII" where every other book says "Rozdzial N".

Structure was then repaired against the Clementine Vulgate, by hand where a
rule would have guessed:

  * The Acts 5 interleaved three streams -- Acts 4:27-37 duplicated, the real
    5:1-37, and 5:38-39 mislabelled 28-29. Verified against the Latin, the
    duplicates dropped, the two renumbered. Acts 4:27 kept the site's own
    wording in place of a 1962 reading, removing a seam.
  * The site heads psalms by Hebrew division; its "Psalm 114" is two psalms.
    Split into Vulgate 113:9-26 and 114:1-9, confirmed at all four boundaries.
  * A corrupt anchor for 1 Chronicles 9:11 pushed 34 paragraphs of genealogy
    into chapter 10. Counts corroborate: 10 + 34 = 44 verses, remainder 14,
    both exactly the Vulgate's.
  * 16 chapters looked short at the end; only two verses were truly absent.
    The rest were merges, split at anchors read off the Latin -- including one
    across a chapter boundary (Colossians 4:1 sat inside 3:25) and four
    numbering offsets where a mid-chapter merge shifted everything after it.

wuj now carries exactly the Vulgate's verse set: 35810 rows, every one of the
1334 chapters matching, no duplicates, no gaps. corpus-check: 0 warnings.

The ~300 verses that could not come from biblia.info.pl are recorded in
NOTICE; they are not public domain.
</content>
</entry>
<entry>
<title>bible: add Douay book aliases Osee-&gt;Hosea, 2 Esdras-&gt;Nehemiah; clectio-gen hermetic</title>
<updated>2026-07-28T20:49:54Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-07-28T20:49:54Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/lectio.git/commit/?id=4bb88c667edc90a5563791dff62ae52ea070b2ee'/>
<id>urn:sha1:4bb88c667edc90a5563791dff62ae52ea070b2ee</id>
<content type='text'>
Two EF Ember-day lessons ("Osee 14:2-10", "2 Esd. 8:1-10") rendered as
"(not in vul)" because the lookup path (ResolveBook, English dialect) lacked
these Douay-Rheims book forms -- they existed only in the Latin dialect, which
ResolveBook does not consult. Add them to the [en] dialect so both lectio and
clectio resolve them (the text is present in vul: Hosea 14, Nehemiah 8).

Also make clectio-gen hermetic: it now points LECTIO_CONFIG at a nonexistent
path so it always uses the EMBEDDED calendar/lectionary/book table, never the
running user's ~/.config/lectio (whose stale books.ini was silently dropping
~30 EF readings from the generated data). It warns on any reading it cannot
resolve. Full range 2025-2054 now generates with 0 dropped readings.
</content>
</entry>
<entry>
<title>cmd/clectio-gen: generator for the tiny C build; bible.LookupKeyed</title>
<updated>2026-07-28T20:08:06Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-07-28T20:08:06Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/lectio.git/commit/?id=723f223690ce6a01124ea5fbd12e1a90ee0ab3f4'/>
<id>urn:sha1:723f223690ce6a01124ea5fbd12e1a90ee0ab3f4</id>
<content type='text'>
clectio (~/git/projects/clectio) is a tiny suckless-C daily-readings build
that compiles the calendar, citations and scripture text in. clectio-gen is
its data compiler: it reuses this engine to compute, for a year range, each
day's name/colour/readings and emits corpus-independent C tables plus the
verse KEYS, so the C side is a dumb lookup and the hard liturgical logic
stays here (oracle-validated).

- bible.LookupKeyed(version, ref) returns each resolved verse's
  (book, chapter, verse) key, mirroring Lookup's splitting/versification.
  clectio-gen uses it to record the exact pericopes a lectionary cites.
- Verified: clectio's output is byte-identical to lectio's readings, day
  names 157/157 over a 3-year sample.
</content>
</entry>
<entry>
<title>bible: embed only the Vulgate by default; other corpora opt-in</title>
<updated>2026-07-28T16:01:33Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-07-28T16:01:33Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/lectio.git/commit/?id=5e1664b8008675177a551aff1de371f54d4e20e4'/>
<id>urn:sha1:5e1664b8008675177a551aff1de371f54d4e20e4</id>
<content type='text'>
Split the bundled corpora so the default binary carries only the
public-domain Latin Vulgate. wuj/drb/grb move to corpora_optional/ and are
compiled in only with `-tags fullbible`, or dropped into the user corpora
dir at runtime. This keeps the distributed AGPL binary free of third-party
scripture text -- bible corpora are not covered by lectio's licence.

- bible: read corpus files/metadata from core + optional embed FS
  (embReadCorpus/embCorpusFiles); optionalFS is set only under the tag.
- config: default `versions` now reflects corpora actually available in the
  build (Vulgate first), so a vul-only binary offers no absent versions.
- Makefile: `make build` = vul only; `make build-full` embeds the rest;
  `make test` runs with -tags fullbible; check-corpora validates both dirs.
- tests: corpusmeta asserts on vul (the always-embedded corpus); the
  versions-default expectation follows availableVersions().
</content>
</entry>
<entry>
<title>fix(calendar): OF precedence/transfer + readings resolution; EF Pentecost octave</title>
<updated>2026-07-28T12:35:24Z</updated>
<author>
<name>Lukasz Kasprzak</name>
<email>lukas@labunix.xyz</email>
</author>
<published>2026-07-28T12:35:24Z</published>
<link rel='alternate' type='text/html' href='https://git.labunix.xyz/lectio.git/commit/?id=a80e61963756a28a3963a0442a8ccc1572518373'/>
<id>urn:sha1:a80e61963756a28a3963a0442a8ccc1572518373</id>
<content type='text'>
Fixes found by validating the offline engine per-day vs the LiturgicalCalendar
API (OF) and missalemeum (EF) across 2005-2050. OF calendar is now 0 real
errors in the forward window (season/cycle already perfect).

OF precedence/transfer (calendar):
- Ash Wednesday and Holy Week Mon-Wed are band-2 privileged, so a coinciding
  feast (Chair of St Peter on Ash Wednesday) is suppressed, not observed.
- Solemnities transfer out of Holy Week / the Easter octave: the Annunciation
  defers to the Monday after the 2nd Sunday of Easter; St Joseph is anticipated
  to the Saturday before Palm Sunday; the Nativity of St John the Baptist moves
  to Jun 23 when a Lord's solemnity (Sacred Heart / Corpus Christi) falls Jun 24.
- Within a precedence band, a solemnity of the Lord/BVM outranks a saint's
  (dignity tiebreak) rather than losing an alphabetical slug tie.
- Perpetua &amp; Felicity corrected optional -&gt; obligatory memorial.

OF readings resolution (bible.OFRef + lectionary data):
- Verse-accurate Hebrew-&gt;Vulgate psalm mapping incl. the split psalms
  (9/10, 114/115, 116, 147); "+" verse joins and abbreviated ranges ("127-28")
  normalized; single-chapter books (2/3 John, Jude) get chapter 1.
- Cleaned harvest artifacts from of-lectionary.ini (descriptive-suffix gospels,
  "or Year A" alternates, "*"/"[Vulg.]"/bracket markers, slash abbreviations);
  Joel/Malachi/Zechariah/Esther book-versification citations fixed to Vulgate.
- Split a merged Ps 15:10/11 row in vul.tsv. Result: 0 unresolvable OF readings
  over 2557 rendered days (cycles A/B/C, varied Easters).

EF: the Octave of Pentecost (Whit Monday-Saturday) is red, not white.
</content>
</entry>
</feed>
