aboutsummaryrefslogtreecommitdiff
path: root/CLAUDE.md
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-08-13 21:19:12 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-08-13 21:19:12 +0200
commit2af482c7293d821f10c3bbc96b7913d658c5839c (patch)
tree608eaf6bcc46d9dbda0a6dd3a830a5967b201bfa /CLAUDE.md
parenta3afb19dc6390c9e33ed5fa0ecbd6e5895e60e8d (diff)
parent72b19098905cd609d87783f6e68311de4f1b61a0 (diff)
downloadcolitur-2af482c7293d821f10c3bbc96b7913d658c5839c.tar.gz
colitur-2af482c7293d821f10c3bbc96b7913d658c5839c.zip
Merge branch 'ef-major-litanies': the Major Litanies, and a kernel bug
Builds the Major Litanies (RG 80, 81, 109(f)) -- an item deferred three times, each time on a reason that did not survive contact. Two recorded blockers were false (a kernel signature said to be missing already carried what was needed; Easter Monday, said to be unmarkable, occurs exactly 8417 times in 8417 years) and a displacement estimate of ~97.7% of years measured at 4 years in 46. 8611 days change in four shapes, zero unclassified: the commemoration appearing on ordinary 25 Aprils, displacing St Mark's own on the four II-class Sundays RG 111(b) governs, and relocating to the following Tuesday in the 194 years RG 80's transfer clause fires. No day outside 25/26/27 April differs at all, and observed, rank, colour, season, week and transferred_in are byte-identical across all 3074246 days. The entity is a Commemoration_only sanctoral entry, which honours RG 81 structurally rather than by special case: Precedence.resolve partitions such candidates out of the band contest, so 'nihil fit in Officio' holds by construction, and being sanctoral-origin it can never claim RG 113's de-Tempore first place. And it surfaced a latent kernel bug. Calendar.build_day decided whether a transferred candidate had settled by testing only whether it became that day's observed celebration -- correct for every prior use, a losing feast that wins its unblocked target, and wrong for a Commemoration_only candidate, which can never be observed by the same status that lets it transfer. The first fix accepted two settlement channels and the review found a third: a candidate capped out by admit at its target. That third case was already visible inside the task's own mutation proof, as an undiagnosed ninth failure it had set aside. The fix is a provable no-op in isolation: a3afb19 plus the new calendar.ml alone, swept over every day of the domain, is byte-identical to base.
Diffstat (limited to 'CLAUDE.md')
-rw-r--r--CLAUDE.md184
1 files changed, 103 insertions, 81 deletions
diff --git a/CLAUDE.md b/CLAUDE.md
index 7875fbe..6e8289a 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -169,6 +169,20 @@ against missalemeum; layer 5 pins ~30 dates.
`band`'s own `Commemoration_only` guard (below) also turns it red, on the same
date this whole gap was originally found through — both reverted after
confirming.
+- **Major Litanies (RG 80/109(f), `ef-major-litanies` task): layer 3 is
+ entirely BLIND to a commemoration-only entity, confirmed not merely
+ argued** — lectio computes no Major Litanies at all, and its own `row`
+ type carries no commemorations field in the first place (limit 1, same
+ file). `data/ef/expected-divergences.sexp` needed no change; a whole new
+ privileged commemoration, present or absent, present-but-displacing-a-
+ saint, or transferring to a different date entirely, is genuinely
+ invisible to that layer. Layer 4 (missalemeum) sees the entity and the
+ RG 111(b) question (both years in its 2026-2027 window), but is ALSO
+ blind to the transfer specifically, because neither year in that window
+ is a trigger year — confirmed by mutation (disabling the transfer
+ branch produced zero oracle failures), not merely by the calendar
+ coincidence. Only golden pins see the transfer at all. Full account:
+ `.superpowers/sdd/2026-08-12-colitur-rg16a/major-litanies-report.md`.
- **The `admit` same-rank tie-break is RG 113, not an uncited convention** (same
task, fix round 1): RG 113's own second sentence ("in admittendis et ordinandis
aliis commemorationibus, servetur ordo tabellae praecedentiae"), previously
@@ -196,8 +210,13 @@ against missalemeum; layer 5 pins ~30 dates.
## Current state (Plans 1–3 DONE — verify with `git log`)
-**Plans 1 + 2 are on `main` (35 commits). Plan 3 is branch `ef-plan3`, 42 commits,
-259 tests green** (260 with the exhaustive sweep). The kernel, the **complete EF
+**Plans 1 + 2 are on `main` (35 commits). Plan 3 and its follow-on fix/feature
+tasks (RG 16(a), Holy Family/RG 112(a), Holy Name/RG 110, the Sacred Triduum,
+the BVM Saturday Office, the Major Litanies) have landed on a chain of feature
+branches since — test count keeps climbing task by task (325 tests green, 326
+with the exhaustive sweep, as of `ef-major-litanies`; this line is not kept in
+lockstep with every task, `git log`/`dune test` are the actual source of
+truth).** The kernel, the **complete EF
temporal cycle**, the **resolution engine**, the **sanctoral data**, and **all five
validation layers** are built. `colitur day <year>` emits a full resolved year.
@@ -231,12 +250,16 @@ commemorations RG 108–112, transfers RG 96–98) · `rite_ef` (the bundle).
in its provenance header) · `data/ef/adjustments.sexp` (overlay — `Add` as well
as `Suppress`/`Edit`: RG 110's own 30 June companion, `commemoration-of-st-peter`,
is genuinely missing from lectio's own source, not merely from colitur's
-bootstrap, so it is hand-authored here rather than upstream) · two cited
+bootstrap, so it is hand-authored here rather than upstream; `Add major-litanies`,
+`ef-major-litanies` task, RG 80/81, same reasoning) · two cited
allow-lists, `expected-divergences.sexp` (7 active entries, vs lectio — C1, C6,
C8, C14, C15, C16, C17; several more closed and recorded in the register, not
-deleted) and `expected-divergences-missalemeum.sexp` (11 active, vs the oracle —
+deleted — untouched by the Major Litanies, layer 3 is blind to that entity, see
+above) and `expected-divergences-missalemeum.sexp` (12 active, vs the oracle —
M2 closed/M18 widened by the `ef-bvm-saturday` task; M12 closed/M19 opened by an
-earlier one). Fixtures live in `test/fixtures/` with asserted SHA-256s.
+earlier one; M5 corrected (a prior note had 2027's own outcome backwards) and
+M20 added by the `ef-major-litanies` task, M18 394 not 395 accordingly).
+Fixtures live in `test/fixtures/` with asserted SHA-256s.
**CLI**: `colitur easter <year>`, `temporal <year>`, `day <year>`.
@@ -474,24 +497,27 @@ Boniface 14 May, Evaristus, Theodore); and `romanus`, which should not exist on
9 August. lectio's ini is **generated from missalemeum**, so the two are one
lineage, not two independent sources.
-**Unbuilt, recorded**: RG 112(b)/(c)/(d) (only (a) has a live witness this
-codebase's data can construct). Allow-list entries M11 and M13 are `verdict
-open` by design. Holy Name of Jesus (RG 17(a)) and RG 110 (inseparable
-Peter/Paul commemorations) are **RESOLVED — see item 4 above.** The Sacred
-Triduum's own identity is **RESOLVED — see item 5 below.** RG 91 entry 27's
-BVM Saturday Office is **RESOLVED — see item 9 below.**
-Major Litanies (25 April) and the Rogation-Wednesday commemoration are
-**NARROWED, still unbuilt — see item 5 below**: both rules are now
-scan-verified and register-cited, but neither is built, because both need the
-SAME missing machinery (a rite-computed, Easter-relative, non-competing
-commemoration candidate — no channel in `Precedence.resolve`/`calendar.ml`
-constructs one; sanctoral candidates are Fixed-date only, the day's temporal
-candidate is exactly one and already spoken for).
+**Unbuilt, recorded**: RG 112(b)/(c)/(d, non-BVM half) (only (a) and (d)'s
+BVM half have a live witness this codebase's data can construct). Allow-list
+entries M11 and M13 are `verdict open` by design. Holy Name of Jesus (RG
+17(a)) and RG 110 (inseparable Peter/Paul commemorations) are **RESOLVED —
+see item 4 above.** The Sacred Triduum's own identity is **RESOLVED — see
+item 5 below.** RG 91 entry 27's BVM Saturday Office is **RESOLVED — see
+item 9 below.** The Major Litanies (25 April, RG 80/109(f)) are **RESOLVED
+— see item 5 below.**
+Rogation Wednesday's own commemoration (RG 87-89) **remains genuinely
+unbuilt** — see item 5 below: the Major Litanies' own "no third channel"
+blocker turned out to be dissolved by REUSING the existing RG 96 transfer
+machinery rather than by adding the missing channel, but that reuse is not
+available to Rogation Wednesday, whose trigger is not a fixed civil date at
+all (it is the day's own temporal identity, Easter+38, which coincides
+structurally with the Ascension Vigil) — confirmed still blocked for the
+original, distinct architectural reason.
5. **The Sacred Triduum (RG 91 entry 2) — RESOLVED (2026-08-13,
- `ef-triduum-litanies` task); Major Litanies (RG 80) and Rogation
- Wednesday's own commemoration (RG 87-89) — established from a
- photographic scan, deliberately NOT built.** Holy Thursday/Good
+ `ef-triduum-litanies` task); Major Litanies (RG 80/81/109(f)) —
+ RESOLVED (2026-08-13, `ef-major-litanies` task); Rogation Wednesday's
+ own commemoration (RG 87-89) remains genuinely unbuilt.** Holy Thursday/Good
Friday/Holy Saturday kept their existing slugs
(`ef-passiontide-2-{thursday,friday,saturday}` — RG 91 entry 2 is
identified structurally by `Precedence_ef.band`, off rank and Easter
@@ -512,67 +538,63 @@ candidate is exactly one and already spoken for).
unit test see it at all. Mutation-tested: reverting `temporal_ef.ml`
alone reddens 6 tests across those two files.
- Major Litanies (25 April, RG 80) and Rogation Wednesday's own
- commemoration (RG 87-89, Minor Litanies) were both investigated to the
- same depth and **both scan-verified and fully register-cited, but
- deliberately not built**: RG 80's own transfer clause (25 April moving to
- the following Tuesday whenever it coincides with Easter Sunday or Easter
- Monday — **194 of 8,417 domain years, ≈2.3%, measured**, not assumed
- rare) and Rogation Wednesday's own commemoration (RG 88/89, competing
- only when the Ascension Vigil already occupies the day) both need a
- commemoration candidate keyed to a MOVABLE, Easter-relative date that
- is not the day's own temporal office — a kind of thing
- `Precedence.resolve`'s architecture has no channel for: sanctoral
- candidates come exclusively from `Layer.on_date`'s Fixed-`Date_spec`
- lookup (`date_spec.ml`'s own header: Easter-relative forms "arrive with
- the OF sanctoral" — not yet), and the day's temporal candidate is
- exactly one, already spoken for. RG 110's own `rg110_additions`
- mechanism (item 4 above) looks like a precedent but is not one: it only
- ever RE-INCLUDES a candidate that already exists elsewhere in that
- date's own candidate pool (both Peter and Paul are ordinary Fixed-date
- sanctoral entries); neither the Major Litanies' Easter+2 target nor
- Rogation Wednesday's own Mass commemoration has any such pre-existing
- candidate to find.
+ **Major Litanies (25 April, RG 80/81/109(f)) — RESOLVED (2026-08-13,
+ `ef-major-litanies` task).** The "no channel for a movable,
+ Easter-relative commemoration candidate" blocker this entry previously
+ recorded (and the item-5 header used to describe as blocking BOTH the
+ Litanies and Rogation Wednesday) turned out to be dissolved by a
+ DIFFERENT design, not by adding the missing channel: RG 80's own
+ transfer is structurally the SAME operation RG 96 already performs for
+ an impeded I-class feast (a losing candidate relocated to a named later
+ date), so it is built by REUSING `Precedence.disposition`'s existing
+ `Transfer` constructor and `Calendar`'s existing placement machinery,
+ with a fixed target (Easter+2) instead of a searched one — no new
+ `Date_spec` variant, no third candidate stream. Entity:
+ `Commemoration_only`, `Fixed(4,25)`, `data/ef/adjustments.sexp`'s `Add
+ major-litanies`. **The genuine reason to defer, correctly identified by
+ an earlier fix-round review** (25 April is St Mark, II class, so RG
+ 111(b) — not (c), a citation this task corrected — makes a privileged
+ Litanies commemoration DISPLACE Mark's own ordinary one whenever both
+ compete) **is now measured and adjudicated**: full domain blast radius
+ (1583-9999, zero unclassified findings) is 7 394 years the Litanies
+ simply appear, 829 years they displace Mark (4 of them, 2010/2021/
+ 2027/2032, in the 2005-2050 window), 194 origin departures + 194
+ target arrivals for the transfer (the same 194 figure this entry
+ already had, now independently re-derived through the real
+ `Calendar`/`Precedence` pipeline). The Sunday-displacement question
+ itself (RG 111(b): does a privileged commemoration categorically
+ override an ordinary II-class one, or does missalemeum's own
+ divergent data mean otherwise?) is ADJUDICATED colitur, honestly
+ flagged as the first real (non-synthetic) test of that specific admit
+ clause — see the "know what each layer cannot see" section above and
+ the task's own full report for the reasoning and the correction this
+ task made to a PRE-EXISTING allow-list note (M5) that had 2027's own
+ oracle outcome backwards. A genuine kernel bug was found and fixed
+ along the way, kept rite-agnostic: `calendar.ml`'s `build_day` used to
+ decide "did a transfer settle" by checking ONLY whether the candidate
+ became `observed` at its target — impossible by construction for a
+ `Commemoration_only` candidate (RG 81), caught by `prop_invariants`'
+ SAMPLED 200-year property (the default `dune test` run), NOT the
+ committed exhaustive sweep (which walks in order and would have found
+ it deterministically at year 1638, not the later, seed-dependent year
+ the sample happened to draw) — attribution corrected in fix round 1
+ (F4). Fix round 1 also found and closed a THIRD settlement channel
+ `settled_at` still missed (a transferred candidate capped out by
+ admission limits AT its own target, F1) — unreachable on shipped data,
+ caught by the same sampled property while mutation-testing the RG 109(f)
+ privilege. Full account: `.superpowers/sdd/2026-08-12-colitur-rg16a/major-
+ litanies-report.md`.
- **The real reason to defer the Major Litanies, corrected by the
- fix-round review** — the version above was wrong in two load-bearing
- ways and is retracted:
-
- - It said the suppression half needs "a kernel signature extension
- threading Easter-offset into `disposition`/`admit`". It does not.
- `admit` **already** takes `~temporal` (added for exactly this class of
- question during the RG 16(a) task) and `disposition` already takes
- `~winner`; on 25 April in a transfer year both carry the Easter Sunday
- or Easter Monday office. A rite-local slug test suppresses it with
- **zero** kernel surface.
- - It implied Easter Monday is unmarkable. Measured over the whole
- domain: `ef-easter-1-monday` occurs **exactly 8 417 times in 8 417
- years** — once every year, never displaced, since it is an I-class
- octave day — making it precisely as reliable a marker as
- `ef-easter-sunday`. The stated asymmetry between the two trigger
- conditions does not exist.
-
- So the **guarded** build (a `Commemoration_only` `Fixed(4,25)` entry, RG
- 109(f) wired, plus slug-based suppression on the two Easter slugs) is a
- strict improvement, not a regression: 8 223 years newly correct, 194
- unchanged, zero new wrong answers. "Worse than the recorded gap" was
- true only of the *unguarded* build, which is the only option that was
- scored.
-
- Deferring is still right, for a reason nobody had identified: **25 April
- is St Mark, II class**, so under **RG 111(c)** a *privileged* Litanies
- commemoration (RG 109(f)) would **displace** whatever ordinary
- commemoration the day currently carries, in ≈97.7% of years — a live,
- unmeasured blast radius straight through layers 3 and 4. That
- measurement is the prerequisite, and it makes this its own task rather
- than a rider on another. The 194 figure is exact and reproduced twice
- (Easter = 25 April in 67 years, Easter Monday = 25 April in 127).
-
- Full reasoning: the `ef-triduum-litanies` task report and register
- (Rogations/§4, and the two narrowed open items in §6). **Rogation
- Wednesday remains genuinely blocked** — Easter+38 coincides with the
- Ascension Vigil by construction, so there is no `(month, day)` pair a
- `Fixed` spec could anchor to and no partial build exists at all.
+ **Rogation Wednesday remains genuinely blocked**, and for the ORIGINAL
+ architectural reason, now confirmed distinct from the Litanies' own
+ (dissolved) one: its trigger is not a fixed civil date at all, but the
+ day's OWN temporal identity (Easter+38), which coincides structurally
+ with the Ascension Vigil — there is no `(month, day)` pair a `Fixed`
+ spec could ever anchor to, so the Litanies' own "reuse the RG 96
+ transfer machinery" trick does not apply here (nothing is being
+ transferred FROM a civil date; the commemoration would have to be
+ synthesised from the day's own Easter offset, which still has no
+ channel). No partial build exists.
9. **RG 91 entry 27, the votive Office of the BVM on Saturday — RESOLVED
(2026-08-13, `ef-bvm-saturday` task).** `Precedence_ef.band` already