aboutsummaryrefslogtreecommitdiff
path: root/CLAUDE.md
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-08-13 10:04:21 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-08-13 10:04:21 +0200
commit59fbda87d565ad9b98c2493e9703390cd988609d (patch)
tree71ebfb8e9568cd5003c10dabc8804fba4ca66e76 /CLAUDE.md
parent254cfd7d9111b0f23f9c44e82d3e31d5817dc5a4 (diff)
parente30a4be5a2594fb3b6c4b51345d138cd89ba78ad (diff)
downloadcolitur-59fbda87d565ad9b98c2493e9703390cd988609d.tar.gz
colitur-59fbda87d565ad9b98c2493e9703390cd988609d.zip
Merge branch 'ef-rg112-rg110': the Holy Family, RG 112(a), observed identity
Builds the Feast of the Holy Family (RG 17(b), first Sunday after Epiphany, II class), which did not exist in colitur at all -- it emitted an ordinary Sunday on all 8417 days the feast occurs. Adds RG 112(a)'s exclusion, on RG 95 paragraph 2's authority ('Si vero duo festa eiusdem Divinae Personae ... fit de festo, quod in tabella praecedentiae superiorem obtinet locum, et aliud omittitur'), corroborated by RG 112(a) and by the Holy Family Mass propers' own 13-January rubric. Three validation layers had missed the missing feast, each for its own reason: the differential because lectio lacks it too and shares colitur's data lineage; the golden layer for want of a pin; and the oracle because it compared the observed day's rank and colour but never its identity. That last gap is the more important half of this change and is now closed -- the oracle compares observed identity, with the unresolvable population counted and pinned rather than silently skipped. Also rescales RG 91's band table x10. entry_14_movable_band had been a negative sentinel, chosen to avoid collision with a real table position; it also inverted ordering, making a movable II-class feast of the Lord outrank every I-class day. Unreachable on universal data, live the moment a diocesan overlay places a I-class proper or indult feast in the 7-13 January window. A half-row is now an ordinary position between its neighbours. The rescale was verified entry-by-entry against a photographic scan and moves zero days across the domain. RG 110 is NOT built despite the branch name; it remains open, as do the Holy Name of Jesus office (missing in 3619 of 8417 years) and RG 98's transfer-ordering mechanism.
Diffstat (limited to 'CLAUDE.md')
-rw-r--r--CLAUDE.md141
1 files changed, 120 insertions, 21 deletions
diff --git a/CLAUDE.md b/CLAUDE.md
index 4fb93f9..54ae709 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -113,6 +113,28 @@ against missalemeum; layer 5 pins ~30 dates.
the week column. It also **shares colitur's own lineage**: colitur's data was
bootstrapped from lectio, so an error both inherited is invisible here. Proven:
Holy Thursday was violet in both because both were wrong.
+- **Layer 4's OBSERVED-identity gap is CLOSED** (2026-08-13, branch
+ `ef-rg112-rg110`, register §6.2): it used to compare the observed day's rank
+ and colour and stop there — never whether it is actually the RIGHT day. Holy
+ Family (RG 17(b), missing from colitur entirely until this task) was rank
+ 2/white on both sides purely by coincidence (an ordinary, unnamed Sunday
+ and Holy Family share both), so this layer stayed silently green through
+ the whole gap's lifetime. Now compares `Celebration.t.names` against
+ missalemeum's own title, same mapping/limits as the commemoration-identity
+ fix below: resolvable only for a SANCTORAL-origin observed day; a
+ TEMPORAL-origin one (an ordinary Sunday, a feria, a movable named feast —
+ 373 of 730 days in the 2026–2027 window) is `Observed_identity_unresolved`,
+ counted and allow-listed (`M18`), never silently skipped. Full breakdown:
+ 331 of 730 days resolved (330 matching, 1 mismatched — Joseph vs the Seven
+ Sorrows, `M13`), 399 unresolved (373 in `M18`, 26 absorbed inside four
+ other entries' own widened subsets). The blind spot, precisely: a
+ TEMPORAL-origin observed day silently replaced by a DIFFERENT
+ temporal-origin observed day of the SAME rank and colour — exactly Holy
+ Family's own shape. Teeth proved and
+ reverted: corrupting one sanctoral saint's own English name on an OBSERVED
+ day (rank/colour untouched) reddened the suite immediately with an
+ `observed-identity-mismatch` and nothing else — the exact shape the
+ pre-strengthening comparator would have slept through completely.
- **Layer 4's commemoration-identity gap is CLOSED** (2026-08-12, Task B, branch
`ef-rg16a`, two fix rounds): it used to compare presence/count only, never
*which* commemoration won — reversing `admit`'s dignity sort (the engine
@@ -189,16 +211,18 @@ validation layers** are built. `colitur day <year>` emits a full resolved year.
transfers need whole-year knowledge, so per-date resolution cannot be correct).
**EF rite module** (`lib/rites/rite_ef`): `vocab_ef` (8 RG-cited seasons, 4
-classes) · `temporal_ef` (season boundaries RG 71–77, named feasts, Sunday slugs,
-week numbering, the resumed-Sunday tail, ferias, four Ember sets, Rogations,
-`anchors`) · `precedence_ef` (the full RG 91 28-entry table, occurrence RG 92–95,
-commemorations RG 108–111, transfers RG 96–98) · `rite_ef` (the bundle).
+classes) · `temporal_ef` (season boundaries RG 71–77, named feasts including
+Holy Family (RG 17(b)), Sunday slugs, week numbering, the resumed-Sunday tail,
+ferias, four Ember sets, Rogations, `anchors`) · `precedence_ef` (the full RG 91
+28-entry table including entry 14's movable/fixed split, occurrence RG 92–95,
+commemorations RG 108–112, transfers RG 96–98) · `rite_ef` (the bundle).
**Data**: `data/ef/sanctoral.sexp` (322 entries, bootstrapped from lectio, SHA-256
in its provenance header) · `data/ef/adjustments.sexp` (overlay) · two cited
-allow-lists, `expected-divergences.sexp` (11 entries, vs lectio) and
-`expected-divergences-missalemeum.sexp` (14, vs the oracle). Fixtures live in
-`test/fixtures/` with asserted SHA-256s.
+allow-lists, `expected-divergences.sexp` (5 active entries, vs lectio — C1, C6,
+C8, C14, C15; several more closed and recorded in the register, not deleted) and
+`expected-divergences-missalemeum.sexp` (12 active, vs the oracle). Fixtures
+live in `test/fixtures/` with asserted SHA-256s.
**CLI**: `colitur easter <year>`, `temporal <year>`, `day <year>`.
@@ -229,10 +253,11 @@ dune exec colitur -- day 2026 | head
- **Plan 4 — OF rite module** (proves `RITE` generalizes) → the lectionary
bootstrap and citations → full output/rendering → hardening and a first tag.
- **Both behaviour items below are now RESOLVED** (RG 16(a) and commemoration
- identity, closed on branch `ef-rg16a`) — kept here as the record of what the
- five layers, taken together, used to sleep through, and as the shape a
- future gap of the same kind would need to be caught by.
+ **All three behaviour items below are now RESOLVED** (RG 16(a) and
+ commemoration identity, closed on branch `ef-rg16a`; Holy Family/RG 112(a)
+ and observed identity, closed on branch `ef-rg112-rg110`) — kept here as
+ the record of what the five layers, taken together, used to sleep through,
+ and as the shape a future gap of the same kind would need to be caught by.
### Carried into Plan 4 (read before starting)
@@ -242,7 +267,7 @@ triage, and the whole-branch review — is in
workspace is deliberately kept, because it and the register corrections exist
nowhere in git (`docs/` is gitignored).
-**The two behaviour items, in order:**
+**The three behaviour items, in order:**
1. **RG 16(a) — RESOLVED (RG16(a) task, branch `ef-rg16a`, 2026-08-12; ONE
FIX ROUND of review after the first pass — see register §6.0 for the full,
@@ -271,11 +296,12 @@ nowhere in git (`docs/` is gitignored).
of the Dedication of a Church's own classification (*"Festum
Dedicationis Ecclesiae est festum Domini"*) means St Michael's Dedication
(29 Sep) may also be `Lord`, not `Saint` — measured, not applied (1 200
- days domain-wide if it were). Two further open items recorded, not fixed:
- 13 January (Baptism of the Lord, mistagged `Saint`, and separately, RG 112
- — a feast/mystery of one Divine Person excludes a commemoration of
- another of the SAME Person — entirely unimplemented, confirmed live on 7
- real years).
+ days domain-wide if it were). Two further open items were recorded here,
+ not fixed at the time: 13 January (Baptism of the Lord, mistagged
+ `Saint`) and RG 112, unimplemented. **Both are now RESOLVED — see item 3
+ below.** (The `Saint` mistag turned out to be independently fixed by the
+ `ef-rebootstrap` re-bootstrap, upstream of item 3's own task; RG 112 is
+ item 3's own work.)
2. **Commemoration identity — RESOLVED (Task B, branch `ef-rg16a`, 2026-08-12;
ONE FIX ROUND of review after the first pass — see register §6.1 for the
full, corrected account).** Was unasserted outside ~3 test rows — **the
@@ -297,21 +323,86 @@ nowhere in git (`docs/` is gitignored).
figure: 599 is the tie POPULATION, 65 (or 67) the real ADMITTED-SET
decisions within it, 149 order-only — all now independently reproduced
(register §6.1), not merely asserted.
+3. **Holy Family (RG 17(b)) + RG 112(a) + layer 4's observed-identity gap —
+ RESOLVED (2026-08-13, branch `ef-rg112-rg110`; see register §6.2 for the
+ full account).** Holy Family did not exist anywhere in colitur — a `grep`
+ found no trace in `lib/` or `data/`, and the day it should have observed
+ emitted an ordinary Sunday instead, undetected because **layer 4 compared
+ the observed day's rank and colour, never its identity** (Holy Family is
+ rank 2/white on both sides purely by coincidence — see the "know what
+ each layer cannot see" section above, closed first, as the regression
+ net, before any production code changed). Built: `Temporal_ef.temporal`'s
+ existing Sunday-fallback branch already computed the right slug/rank/
+ colour for 7-13 January by coincidence; the only silently-wrong field was
+ `subject` (always `Temporal`), now `Lord` on `holy_family_sunday y`
+ (`RG 91 entry 14`, "primum mobilia, deinde fixa") alone. RG 17(b)'s own
+ window can never be empty of a Sunday (unlike RG 17(a)'s Holy Name,
+ which carries an explicit calendarium fallback for its own narrower
+ window) — checked, not assumed; no fallback built. `Precedence_ef.band`
+ gained a movable-half priority for entry 14 — without it, Holy Family
+ would tie with the fixed Commemoration of the Baptism of the Lord
+ (13 January) and lose the kernel's alphabetical tie-break, backwards
+ from RG 91's own stated order. **The whole table is now scaled ×10**
+ (entry *n* → 10*n*), so a half-row is expressed as an ordinary position
+ between its neighbours. *(CORRECTED: this paragraph previously described
+ `entry_14_movable_band` as "negative so it can never collide with a real
+ table position". That was the bug, not the design — a negative sentinel
+ avoids **collision** but also inverts **ordering**, making a movable
+ II-class feast of the Lord outrank every I-class day. Unreachable on
+ universal data; live the moment a diocesan overlay puts a I-class proper
+ or indult feast, RG 91 entries 12–13, in the 7–13 January window. Do not
+ re-derive the sentinel approach.)*
+ `disposition` gained RG 112(a) (a mystery of one Divine Person excludes a
+ commemoration of another mystery of the SAME Divine Person). The primary
+ authority is **RG 95 ¶2** — *"Si vero duo festa eiusdem Divinæ Personæ…
+ fit de festo, quod in tabella præcedentiæ superiorem obtinet locum, et
+ aliud omittitur"* — an occurrence-level rule present in all three
+ documents; RG 112(a) and the Holy Family Mass propers' own 13-January
+ rubric corroborate it. *(CORRECTED: this previously called the propers'
+ rubric a further instance of the transcription defect. It is not. The
+ transcription carries RG 112 in full; RG 112 has no worked example in
+ either scan; and the propers' note is absent because that document is a
+ partial 2006 web capture containing almost no propers text — one
+ `Introitus` in 26 322 lines against 52 in a scan. Diagnose the cause of a
+ silence before invoking the rule.)*
+ **Blast radius, measured (`git archive` pre-change binary vs HEAD, full
+ 1583–9999 sweep, diffed): 1 220 days, every single one the identical
+ shape, cross-verified against `date -d` independently (exactly 1 220
+ years have 13 January on a Sunday) — no anomaly, nothing outside what
+ was expected.** The differential's own C1 (the 6-13 January blanket) lost
+ exactly those 7 (of the 1 220) rows within its 2005–2050 window and they
+ were split into their own new cited entry (C15), not silently
+ re-absorbed — the same discipline the task brief demanded. Not built:
+ RG 110 (inseparable Peter/Paul, still open, M12) — out of this task's own
+ dispatched scope despite the branch name. Holy Name of Jesus (RG 17(a))
+ has the identical "generic-Sunday-slug masking a real named feast" shape
+ Holy Family had — flagged as a new open item, not fixed here (no live
+ collision exists for it in today's data, so nothing is currently WRONG
+ about it the way Holy Family's own Baptism collision was). **A SECOND,
+ more severe Holy Name gap, found in review (fix round 1, coordinator
+ finding 9): unlike RG 17(b)'s own 7–13 January window (never empty),
+ RG 17(a)'s narrower 2–5 January window CAN be empty of a Sunday, and the
+ calendarium carries an explicit fallback ("vel, ea deficiente, die 2
+ ianuarii") colitur does not implement at all — 3 619 of 8 417 years in
+ the domain (independently computed, matched exactly) have NO Holy Name
+ office whatsoever, a genuine missing II-class feast on 43% of years, not
+ merely an unnamed one. Recorded, not fixed — out of this task's own
+ dispatched scope.
**Structural items, cheapest to fix before OF exists:**
-3. **`Record` and `Liturgical_day` both claim to be "the single stable output
+4. **`Record` and `Liturgical_day` both claim to be "the single stable output
schema".** `Record` cannot express what the engine now computes (no observed
celebration, no commemorations, no transfers), has **no test file**, and is
used only by the legacy `colitur temporal` path — `day` hand-formats instead.
Plan 2's carried item (add a `cycle` field for OF's Sunday A/B/C and weekday
I/II) is still open and now costlier: it must pass through `Temporal.t`, which
is embedded in the sexp-derived `Liturgical_day.t`.
-4. **`Temporal.RITE` and `Rite.t` are two competing abstractions.** The module
+5. **`Temporal.RITE` and `Rite.t` are two competing abstractions.** The module
type still exists and `temporal_ef` still satisfies it, but it carries none of
`rules`, `anchors`, `season_runs`, `transfer_target` — satisfying it now proves
almost nothing. `Rite.t` is the load-bearing one.
-5. **EF-shaped things still in "rite-agnostic" kernel code**: `validate.ml`
+6. **EF-shaped things still in "rite-agnostic" kernel code**: `validate.ml`
hardcodes Sunday as the week start; `Liturgical_day.transferred_in` is an
`option` justified by RG 96; `Precedence.privilege` is defined by RG 111;
`Repose` is EF vocabulary emitted by nothing. Each is one field short of the
@@ -328,7 +419,15 @@ lineage, not two independent sources.
**Unbuilt, recorded**: the Sacred Triduum has no proper office (it uses ordinary
Passiontide ferial slugs); RG 91 entry 27's BVM Saturday Office; RG 110's
inseparable commemorations; Major Litanies (25 April); the Rogation-Wednesday
-commemoration. Allow-list entries M11 and M13 are `verdict open` by design.
+commemoration; Holy Name of Jesus (RG 17(a)) still carries `subject = Temporal`
+like an ordinary Sunday, the same identity gap Holy Family had until this task,
+found while closing it (register §6.2) but not itself fixed — no live collision
+exists for it in today's data; **Holy Name of Jesus also has no RG 17(a) fallback
+for its own 2–5 January window when it is empty of a Sunday (unlike RG 17(b)'s
+7–13 January, never empty) — 3 619 of 8 417 domain years have no Holy Name office
+at all, found in review (fix round 1, finding 9), a genuine missing II-class
+feast, not merely an unnamed one.** Allow-list entries M11 and M13 are `verdict
+open` by design.
## How to work here