aboutsummaryrefslogtreecommitdiff
path: root/CLAUDE.md
diff options
context:
space:
mode:
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