aboutsummaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* docs(ef): fix round 1 citation corrections in temporal_ef.ml (F5b, F6)Lukasz Kasprzak2026-08-131-24/+53
| | | | | | | | | | | | | | | | bvm_saturday_names's own comment: the "Missae de S. Maria in sabbato" heading quote corrected from an overclaimed "both scans, word for word" to showing both scans' own raw OCR (noisy, and genuinely differing in abbreviation from each other) side by side, with the substance-only corroboration stated plainly. Colour citation tightened: RG 431(e) (the Missal's own classification of this Mass as a "Missa votiva IV classis... de B. Maria Virg.") -> RG 121(a) (votive Masses take the colour of the feast-type they correspond to) -> RG 120(b) (BVM feasts are white), replacing RG 120(b) alone as the primary citation -- this Office is not itself a festum, so RG 120(b)'s own "in Officio et Missa de festis" was a stretch as the sole basis. Conclusion (white) unchanged.
* docs: fix round 1 ride-along findings (F2-F7)Lukasz Kasprzak2026-08-131-5/+36
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | F2: test_christmastide_feria_slugs's 26 December assertions removed -- St Stephen/John/the Holy Innocents (RG 67-70) always outrank a Class4 Saturday candidate there, in every year, so the office can never actually be observed on any day in the 26-28 December stretch. 3 January (no competing sanctoral entry, any year) used for the "-1-" stretch demonstration instead, alongside the pre-existing 10 January one. F3: test_differential.ml's shared row type gains a subject field (populated for colitur's own rows only; lectio's fixture has no such column). C17's own predicate now also requires subject = "bvm" -- defence in depth against a future bug producing a white Class4 Saturday candidate some other way, particularly in Christmastide/ Paschaltide where colour alone could not catch it. F4: Precedence_ef.band's entry-27 comment gains its RG 78 citation, replacing "per the historical default that fills it". F5: two report inaccuracies corrected -- band was already receiving a real candidate 312,966 times pre-change (what was missing was its identity, not its reality); the "Missae de S. Maria in sabbato" heading quote was presented as "both scans, word for word" when both scans are OCR-noisy there AND genuinely differ in abbreviation from each other -- corrected in temporal_ef.ml's own comment and the register alongside the report. F6: the colour rule gains a tighter citation chain -- RG 431(e) (the Missal's own classification of this Mass as a "Missa votiva IV classis... de B. Maria Virg.") -> RG 121(a) (votive Masses take the colour of the feast-type they correspond to) -> RG 120(b) (BVM feasts are white) -- reaching the same conclusion through the category (votive) the Missal's own text actually places this Mass in, not by treating it as a festum RG 91's own table structure says it is not. F7: the oracle's real seasonal coverage recorded precisely in CLAUDE.md and the register -- of 26 BVM-Saturday-office days in the 2026-2027 fixture only 17 are colour-discriminating; Time after Epiphany (5,015 observed days domain-wide) has zero oracle witnesses. Full account in .superpowers/sdd/2026-08-12-colitur-rg16a/ bvm-saturday-report.md (local, gitignored).
* fix(ef): RG 112(d) excludes a same-BVM commemoration (fix round 1, F1)Lukasz Kasprzak2026-08-135-27/+324
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The BVM Saturday Office is itself "de B. Maria Virg."; RG 112(d) (Caput XVI, "De Commemorationibus") excludes another commemoration whose own oration invokes the SAME BVM's intercession. our-lady-of-mt-carmel (16 July, Commemoration_only) was wrongly admitted as an ordinary commemoration alongside the Office on every 16-July-Saturday -- its own collect explicitly invokes "her" (eius) patronage, and both photographic scans print a rubric anticipating exactly this collision (an either/or of Mass texts, not a joint commemoration). Precedence_ef gains marian_slugs (a closed, hand-verified list of sanctoral slugs that are themselves feasts of the BVM) and is_bvm_office (true for subject = Bvm OR a marian_slugs member -- the disjunction is load-bearing: the Office is identified only by subject, since its own slug is deliberately reused from the ordinary ferial fallback; Mt Carmel is identified only by the list, since its own subject tag is Saint, not Bvm). disposition gains a new branch, checked before the pre-existing Commemoration_only catch-all, since the one live witness is Commemoration_only and that branch's own "always Commemorate" had no exception for this shape. Checked exhaustively against every Marian-named sanctoral entry: only Commemoration_only-status entries can ever reach this branch live (a Feast-status one always wins outright instead of losing). Of the two such entries in the data, only Mt Carmel is reachable -- our-lady-of-ransom (24 September) is provably unreachable: 24 September falling on a Saturday forces 1 September to a Thursday, which by construction makes 24 September the September Ember Saturday, Class2, every time, not a sampled coincidence. Re-measured against the full pre-change binary: the original 75,853-day blast radius is unchanged in total, splitting into 74,633 colour-only + 1,220 colour+comms (16-July Saturdays). Mutation-tested: exactly 3 new tests redden, nothing else.
* docs: RG 91 entry 27 (BVM Saturday) resolvedLukasz Kasprzak2026-08-131-10/+73
| | | | | | | | | | | | | CLAUDE.md's "Unbuilt, recorded" list and Data section move to reflect the closed gap: a new item 9 records the office's own build, citations and measured blast radius; the allow-list counts move to 7 active lectio entries (C17 new) and 11 active missalemeum entries (M2 closed). docs/research/rules-register.md (gitignored, not tracked) gets the matching update: §4's entry marked RESOLVED with a cross-reference, the §6 open-item checkbox closed, and a new §6.4 with the full primary-source account -- every scan reading quoted, the blast-radius reconciliation, and the mutation-test record.
* data(ef): close and derive the RG 91 entry 27 allow-list rowsLukasz Kasprzak2026-08-134-49/+108
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | The BVM Saturday office is now genuinely correct, so both comparators' allow-lists move -- every count derived from the harnesses' own failure output, never transcribed or guessed. lectio differential (data/ef/expected-divergences.sexp, C17, new, colitur): lectio builds no equivalent office at all, so it keeps showing the plain season colour on every otherwise-unoccupied Class4 Saturday where colitur now shows white. Season, slug and rank all still agree (the office deliberately reuses the ordinary ferial slug), so Colour_f alone is the complete diff set -- gated on colitur's own rank/weekday/colour rather than a date list, the same shape M2 used, at 416 rows over 2005-2050. missalemeum oracle (data/ef/expected-divergences-missalemeum.sexp): M2 is CLOSED, REMOVED, the same shape as this file's own M4/M6/M7/M9/M12/ M14/M17 precedents -- not re-adjudicated to a different verdict, gone because the colour divergence it named no longer occurs on any of its former 22 dates. What is left on all 22 is Observed_identity_unresolved alone (colitur's BVM-Saturday candidate is temporal-origin and deliberately carries no English name) -- exactly M18's own shape, not a distinct citation any more. Keeping M2 as a separate id would have kept silently absorbing these rows under a stale "colour differs" citation whose own reason had stopped firing (subset's own diff-set test admits a SMALLER set than the one named) -- the same "count proving cardinality where identity was required" trap this project's review process watches for. M18's own expected_rows moves 373 -> 395 accordingly.
* test(ef): reach RG 91 entry 27 through the real pipeline, end-to-endLukasz Kasprzak2026-08-132-6/+179
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Entry 27's band branch has been unreachable for the right reason since it was written: precedence_ef.ml's own comment on it acknowledged the row existed, but the one test exercising it built a hand-typed candidate, never a real Temporal_ef.temporal output, and nothing built the office itself. Closes that gap on both sides: - The band-table row now sources its candidate from Temporal_ef.temporal directly (of_temporal), the same review-finding-3 discipline the Ember/vigil rows already use, so a future regression in the office's own construction fails this row too, not only the unit-level test. - Two new resolve-level end-to-end tests, using the real band/ disposition/admit triple (not stubs): the office winning a real otherwise-unoccupied Saturday and admitting an ordinary commemoration alongside it (1 August 2026, Holy Machabees -- the task brief's own worked oracle example), and the office genuinely losing to a real competing feast and being omitted under RG 26, with no confusion from the one live data witness that also carries subject Bvm (12 September, Most Holy Name of Mary) -- proving RG 26's rank-keyed omission fires before any subject-keyed rule ever could. - Two golden pins mirroring the same two dates, checked by hand against `colitur day 2026` before being typed in, following this file's own "a golden test blesses whatever it is given, verified independently" discipline. The existing 2038-03-06 pin (RG 91 entry 24 outranking a Class4 candidate) is corrected in passing: that date is itself a Saturday, so the displaced candidate the pin's own omitted-list check names is now precisely entry 27's own shape, not entry 28's bare catch-all -- the win/lose outcome the pin proves is unchanged, only its own more precise citation. Mutation-tested (recorded in the task report): reverting is_bvm_saturday to a constant false reddens the dedicated unit test, the new end-to-end resolve test, and the 2026-08-01 golden pin, while leaving the 2026-09-12 "loses to a real feast" pin untouched, exactly as expected since that date's outcome never depended on the fix.
* temporal(ef): the votive Office of the BVM on Saturday, RG 91 entry 27Lukasz Kasprzak2026-08-132-10/+301
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | RG 91 entry 27, "Officium sanctae Mariae in sabbato", sits in the Table of Precedence between entry 26 (III-class vigils) and entry 28 (IV-class ferias). Precedence_ef.band already routed a plain IV-class Saturday feria to entry 27's own band value, but nothing in Temporal_ef.temporal ever constructed the office itself, so an otherwise-unoccupied Saturday still surfaced with a bare ferial slug and its season's ordinary colour. Established from Caput IX of the Rubricae Generales, both photographic scans and the electronic transcription, word for word (no scan-vs-transcription conflict: RG 78/79 are General Rubrics prose, not the Mass-propers body text the transcription is documented elsewhere as missing almost all of): "78. In sabbatis, in quibus occurrit Officium de feria IV classis, fit de sancta Maria in sabbato. 79. Officium sanctae Mariae in sabbato incipit a Matutino et explicit post Nonam." RG 78's own protasis IS "otherwise unoccupied IV-class Saturday" -- every Saturday whose temporal candidate would otherwise be Class4, across every season that rank reaches (Christmastide, Septuagesima, Time after Epiphany, Time after Pentecost, ordinary Paschaltide). Nothing else was needed to decide "otherwise unoccupied": band's own entry-27 branch already reads rank/weekday on the temporal candidate unconditionally and only wins the day when nothing outranks it -- RG 78's own condition, decided by the existing occurrence machinery. Colour is white, unconditionally, per RG 120(b) ("Adhibetur color albus in Officio et Missa de festis: ... b) B. Mariae Virg."), not RG 119/127/ 128's seasonal rules -- this office is never "de Tempore" for colour purposes, so it overrides the season's own violet/green. The slug is deliberately left UNCHANGED (reused from whatever the generic <season>-<week>-<weekday> ferial fallback would already have produced), for two independent reasons: it matches the Sacred Triduum's own precedent (identified structurally, off rank/weekday, never off the slug), and a bespoke uniform slug would have broken Colitur_kernel.Validate's own slug-uniqueness-per-liturgical-year invariant, sighted zero times before this task -- confirmed directly by writing it that way first and watching the landmark-years test fail. Subject is tagged Bvm (currently inert for precedence -- only Lord is ever read by band/disposition/admit) and the name is the Latin "Officium sanctae Mariae in sabbato" (RG 91 entry 27's own table title and RG 79's own heading), deliberately not English, the same zero-circularity discipline Holy Family/Holy Name/the Sacred Triduum already established. The I-V numbered "Missae de sancta Maria in sabbato" (both scans) are a Mass-propers selection detail (RG 309(a): "iuxta temporum diversitatem") governing which readings/texts are said, not which office is kept -- colitur computes no citations yet (Plan 4), so this is deliberately not modelled here. Two pre-existing tests needed correction, not because they were wrong before, but because RG 78 genuinely changes their dates' own facts: a Saturday inside the Holy Name of Jesus window (3 January) and two Saturdays inside christmastide_feria_slug's own "-0-"/"-2-" stretches (26 December, 10 January) are all otherwise-unoccupied Class4 Saturdays, so they now legitimately carry the BVM office instead of staying a bare Temporal-subject feria.
* Merge branch 'ef-triduum-litanies': the Sacred Triduum's Latin identityLukasz Kasprzak2026-08-134-65/+354
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Gives Holy Thursday, Good Friday and Holy Saturday the names the Missal prints for them, taken from each Office's own running header: 'Feria V in Cena Domini', 'Feria VI in Passione et Morte Domini', 'Sabbato sancto'. Rank and colour were already correct; only the identity was missing, the same shape the Holy Family had. The slug is deliberately unchanged -- it is the lectionary key -- and the names are Latin, which avoids promoting an English value from the oracle the engine is checked against. Not 'Feria VI Parasceve': that phrase occurs zero times as a title in either photographic scan, appearing only inside the Johannine Passion text, and RG 132(a) writes 'feriae VI in Passione et Morte Domini'. Output is byte-identical across all 8417 years -- colitur day prints no name column -- but layer 5 does see it: describe gained name_la, and reverting the change reddens six pins. The Major Litanies (RG 80) and the Rogation Wednesday commemoration were investigated to the same depth, scan-verified, cited, and deliberately not built. Rogation Wednesday is genuinely blocked: Easter+38 coincides with the Ascension Vigil, so no Fixed date-spec can anchor it. The Major Litanies are tractable in the rite module -- the two blockers first recorded for them were false, and are retracted here -- but 25 April is St Mark, II class, so under RG 111(c) a privileged Litanies commemoration would displace the day's existing ordinary commemoration in ~97.7% of years. That blast radius is unmeasured, and measuring it is the prerequisite for its own task.
| * docs: a name that matched no scan, and a blocker that was not realLukasz Kasprzak2026-08-134-21/+78
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Two corrections from the fix-round review, both to the record. "Sabbato Sancto" is attested zero times in either photographic scan. The scans print SABBATO SANCTO as the heading (once) and "Sabbato sancto" as the running header (28x and 30x); the shipped casing appears only in the electronic transcription's table of contents -- the source this project's own methodology rule deprecates -- while the comment beside it called the value "both photographic scans, word for word". Recased to the running-header form, which is the convention the other three Latin names in the file already follow, with a source note recording the count. Third source-fidelity slip this week, and the first where the wrong value came from the deprecated source itself. The Major Litanies deferral was recorded with two false blockers. It claimed a kernel signature extension was needed to suppress the feast in transfer years: admit already takes ~temporal and disposition already takes ~winner, both carrying the Easter office on 25 April, so a rite-local slug test does it with zero kernel surface. And it implied Easter Monday is unmarkable: ef-easter-1-monday occurs exactly 8417 times in 8417 years, as reliable as ef-easter-sunday. So the guarded build -- never scored -- is a strict improvement, 8223 years newly correct against 194 unchanged, and "worse than the gap" was true only of the unguarded one. Deferring is still right, for a reason nobody had found: 25 April is St Mark, II class, so under RG 111(c) a privileged Litanies commemoration would displace the day's existing ordinary commemoration in ~97.7% of years -- an unmeasured blast radius through layers 3 and 4. That measurement is the prerequisite. The 194 figure is exact and reproduces. Also corrects a subject-audit list that named five months for six entries, omitting the Precious Blood on 1 July.
| * docs: close/narrow the Triduum and Litanies open items in CLAUDE.mdLukasz Kasprzak2026-08-131-9/+74
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Item 5: the Sacred Triduum's own identity is RESOLVED (RG 91 entry 2), full 1583-9999 blast radius measured at zero differing CLI lines -- the change is invisible to layers 2-4, visible only to the two golden/ unit tests built for it. Major Litanies (RG 80) and Rogation Wednesday's own commemoration (RG 87-89) are established from a photographic scan and fully cited, but deliberately not built: both need a rite-computed, Easter-relative, non-competing commemoration candidate -- a kind of thing Precedence.resolve's architecture has no channel for. Measured, not assumed: RG 80's own transfer clause triggers in 194 of 8417 domain years (~2.3%), so building only the ordinary case would trade a known, understood gap for a new wrong answer in those years. Renumbers the trailing three architectural-debt items (5-7 -> 6-8) to make room.
| * temporal(ef): the Sacred Triduum's own Latin identity, RG 91 entry 2Lukasz Kasprzak2026-08-133-56/+223
|/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Holy Thursday, Good Friday and Holy Saturday resolved to the generic Passiontide ferial slugs with no distinct identity of their own -- rank and colour were already correct (RG 91 entry 2; Holy Thursday's white per RG 128(b)/RG 122), only Celebration.names/subject were missing. Keeps the slug (RG 91 entry 2 is identified structurally, off rank and Easter offset, by Precedence_ef.band -- never off the slug -- so renaming it would touch precedence for no reason and break the lectio differential's own slug mapping for these three lectionary keys, the same reasoning already given for Holy Family/Holy Name). Carries the identity in Celebration.names instead, the same treatment those two established: Latin, not English, to avoid reading the oracle this axis is compared against. Names sourced from both photographic scans, word for word, corroborated by the electronic transcription's own table-of-contents-style listing at the identical three headings (three-way agreement, nothing to adjudicate): "Feria V in Cena Domini" (Holy Thursday), "Feria VI in Passione et Morte Domini" (Good Friday -- not the transcription's own informal "Feria VI Parasceve" used in passing elsewhere), "Sabbato Sancto" (Holy Saturday). Also tags subject = Lord, going further than Holy Family/Holy Name strictly required (they needed it only because band's entry 14 reads subject to outrank a colliding fixed feast; entry 2 here needs no such thing). Safe: disposition's RG 112(a) branch only fires when both sides of an occurrence are tagged Lord, and no Lord-subject sanctoral entry has a fixed civil date inside Holy Week's own movable range; any Class1 sanctoral entry landing there (e.g. a transferred Annunciation) reaches disposition's earlier, subject-blind Transfer branch first regardless. Verified against the full 1583-9999 domain: zero observed/commemorations/transferred_* difference traceable to the tag. test_golden.ml's describe gains a name_la field alongside subject, for the same reason subject was added: a names-only change is otherwise invisible to every pin whose rank/colour/slug are already correct (this task's own catalogued vacuity flavour #1). Six existing pins move from subject=temporal to subject=lord (the three Easter-extreme Holy Saturday pins, 2016's Good Friday, and the 2026 Holy Thursday/Good Friday pair); the rest gain name_la=- by construction (no other temporal-cycle candidate carries a name yet). Mutation-tested: reverting temporal_ef.ml alone (keeping the tests) reddens the new Rite_ef unit test plus five golden pins across two independent layers.
* Merge branch 'ef-holyname-rg110': the Holy Name of Jesus, RG 110Lukasz Kasprzak2026-08-1313-87/+1188
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Builds the Most Holy Name of Jesus with the fallback RG 17(a) and the calendarium both specify -- 'secus die 2 ianuarii', 'vel, ea deficiente, die 2 ianuarii' -- which was unimplemented, so in 3619 of the domain's 8417 years a II-class feast did not exist at all. Also retags it as a feast of the Lord per RG 91 entry 14. Builds RG 110's inseparable Peter/Paul commemoration ('in numero orationum computando, pro unica habeantur') across the three calendarium pairs, and adds the 30 June companion, which was missing from lectio's source and from missalemeum's output alike -- corroborated in both photographic scans plus RG 124(c), and added through adjustments.sexp so the bootstrap's provenance stands. 14627 days change, in four shapes, none unclassified. The register's earlier 852-day estimate for RG 110 reconciles exactly as the Lent Ember subset of one shape: 288 + 284 + 280. RG 110(c)'s ordering was implemented backwards at first and corrected: 'huic orationi additur altera' attaches the companion to the trigger's own oration, so it follows it, where (a) and (b) attach to the day's and so precede everything. The 'ante omnes alias commemorationes' half remains unimplemented and is unreachable by construction -- shape (c) needs the trigger to lose while still being admitted, which only a I-class day or a II-class Sunday allows, and both RG 111 caps are one. Records a fifth way the validation layers can be green while wrong: nothing anywhere compares commemoration order.
| * test,docs: RG110(c)'s adjacency is unobservable by constructionLukasz Kasprzak2026-08-132-5/+61
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The re-review asked for a third commemoration in the shape-(c) row, so that "spliced immediately after its trigger" could be told apart from "appended at the end" -- it had proved an append-at-end variant passed the whole suite green, the pair alone being too short to distinguish them. Attempting it establishes something better than the test requested. On this day-shape a third commemoration is rubrically impossible. Shape (c) requires the trigger to lose the day while still being admitted, and a Class2 trigger can only lose to a I-class day (RG 111(a): one privileged commemoration) or a II-class Sunday (RG 111(b): one, "scilicet de festo II classis"). Both caps are one. The third candidate is now offered and correctly refused, which is the assertion worth having. So RG 110(c)'s "ante omnes alias commemorationes" half has no reachable witness in the EF's rubrical space, and the re-review's own finding that shape (c) never co-occurs with a third commemoration across 8417 years is a consequence of the rubric rather than an accident of the data. The append-at-end variant stays indistinguishable from the splice on every input the engine can construct. Recorded rather than papered over with a synthetic row proving a shape no rubric permits. Also drops Record from the "nothing compares commemoration order" note -- Record.t has no commemorations field at all -- and names, at privilege_of's own (a) branch, that the Holy Name's Sunday privilege currently rests on a substring match rather than on RG 17's closing paragraph, which is its real warrant.
| * fix round 1: RG 110(c)'s ordering was inverted; M19 lacked an identity gateLukasz Kasprzak2026-08-137-61/+262
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | RG 110(c), word for word: "quoties vero oratio unius Apostoli addenda est ad modum commemorationis, huic orationi additur altera immediate, ante omnes alias commemorationes." "Huic orationi" (dative, "to this oration") refers to the trigger's own oration; "additur altera" means the companion is added to it, i.e. follows it. "Ante omnes alias commemorationes" governs the pair's position relative to other, unrelated commemorations, not the pair's own internal order. The previous build prepended the companion uniformly in both RG 110 shapes, citing this same clause for both -- correct for (a)/(b) (the day's own oration, not a list member, has nothing to order against), backwards for (c), where the trigger is itself a list member and the companion belongs after it. Fixed in rg110_additions: shape (a)/(b) still prepends; shape (c) now splices the companion in immediately after its own trigger. Re-pinned the unit test that had asserted the wrong order, and corrected both rows' comments to cite the clause that actually governs each shape. No layer in this codebase compares commemoration order: the lectio differential never compares commemorations, the oracle sorts both sides into a multiset, and the golden tests' own describe function sorts its commemorations field too. Recorded as a new, permanent blind spot in CLAUDE.md and the register, not merely fixed around -- the admit_cases unit table is the only place order is asserted at all. Re-measured the full blast radius against the same pre-change binary: same 14,627 differing days, same four shapes and counts, confirming the fix changed only the content of the 593 shape-(c) rows and nothing else. Mutation-tested: reverting the splice back to a uniform prepend reddens exactly the shape-(c) unit test; a new golden pin for a real shape-(c) day (2004-02-22) stays green under the same mutation, living proof that golden pins cannot see this axis, not merely a claim. Separately, M19's own predicate checked a date and a diff shape but not which candidate -- proved insufficient by fabricating a second, bogus companion on 30 June and confirming the whole suite stayed green. Fixed by requiring the admitted commemoration to be exactly commemoration-of-st-peter, mirroring C16's own identity guard. Added a golden pin for 30 June, the only assertion of that entry's identity outside the allow-list. Also: corrected a false claim in the task report that the electronic transcription carries no corroboration of the Holy Name fallback -- its own table of contents does, at a line not checked on the first pass. Added two further citations, both re-verified against the scan: RG 17's own closing paragraph, settling the Sunday shape's Sunday- exclusion at the rubric level rather than only in the propers; RG 124(c), which assigns red to 30 June by paragraph number rather than by the generic apostle/martyr default. Noted the fragility of deriving the Sunday shape's RG 109(a) privilege from a slug-substring match rather than from a citation. Cosmetic: a stray blank line and an indentation inconsistency.
| * docs: close the Holy Name / RG 110 open items in CLAUDE.mdLukasz Kasprzak2026-08-131-38/+68
| | | | | | | | | | | | | | | | | | | | | | Both items this file tracked as open since branch ef-rg112-rg110 (Holy Name of Jesus's subject tag and missing RG 17(a) fallback; RG 110's inseparable Peter/Paul commemoration) are resolved. Adds item 4 to the behaviour-items list with the account and measured blast radius, renumbers the structural items 5-7, and removes both from the "Unbuilt, recorded" paragraph. Updates the two allow-list active-entry counts (differential 5 -> 6 for C16; oracle stays 12, M12 closed and M19 opened).
| * precedence(ef): RG 110, the inseparable Peter/Paul commemorationLukasz Kasprzak2026-08-137-42/+387
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | RG 110 (Caput XIV): "In Officio et Missa S. Petri semper fit commemoratio S. Pauli, et vicissim... pro unica habeantur" -- in the Office and Mass of either Peter or Paul, a commemoration of the other is always made, uncapped by RG 111's own admission count. Both photographic scans, full text including sub-clause (c) (a separate trigger this register previously had not transcribed: the same rule also fires when one Apostle's oration is admitted merely as an ordinary/privileged commemoration, not only when it is the day's own office). Three real pairs in the 1962 calendar, all confirmed on both scans: 25 January (conversion-of-st-paul + peter), 22 February (chair-of-st-peter + paul), 30 June (in-commemoratione-sancti-pauli-apostoli + a new commemoration-of-st-peter). The first two already existed as ordinary sanctoral candidates but were wired into RG 111's ordinary, capped admission contest instead of this rule's own uncapped one -- the defect this closes. 30 June had no companion at all: a genuine gap in lectio's own source data (confirmed directly against tridentine-calendar.ini) and in missalemeum's own oracle output for both fixture years, not only a colitur bootstrap miss, so colitur is now uniquely correct on this date among the three engines compared. Added via data/ef/adjustments.sexp's own Add directive, the architecture's existing extension point for exactly this shape of gap, since data/ef/sanctoral.sexp is generated and lectio must not be touched. Precedence_ef.admit gained rg110_additions/rg110_companion_slug, layered on after admit's own four ordinarily-capped branches decide their normal result: checks both the observed candidate and every already-admitted candidate against the three-pair lookup and prepends any companion found, uncapped and additional, never competing for RG 111's own slot. Measured full blast radius (1583-9999, pre-change binary from git archive at 59fbda8 vs the fixed binary, 3,074,246 days each side, 14,627 differing days, all four predicted shapes, zero unclassified): 3,619 Holy Name fallback days (previous commit), 3,533 days Paul was wrongly excluded from Chair of St Peter's own day by a competing privileged feria, 593 days Chair of St Peter itself was admitted only as an ordinary commemoration with Paul entirely absent, and 6,882 days the new 30 June companion is added. The 3,533+593 figure supersedes an earlier, narrower 852-day estimate that measured only the delta between two older code commits, not the rule's full scope. The lectio differential needed no change: it does not compare commemorations at all, and this fix never touches season, slug, rank, or colour. The missalemeum oracle allow-list needed three changes: M12 removed (22 February 2027 no longer diverges in commemoration count), M15's date list gained 2027-02-22 (now reaching identity comparison for the first time, where it lands on that entry's own pre-existing, unrelated limit -- one of the two commemorations is temporal-origin and unnamed), and a new M19 for the 30 June gap. Mutation-tested, both halves separately: disabling the admit-level addition reddens the two new unit tests, the oracle's own M12-shaped checks, and an existing golden pin (updated to expect the Paul companion); removing only the 30 June data entry reddens solely the oracle's new M19 count, confirming the code and data halves are independently load-bearing.
| * temporal(ef): Holy Name of Jesus, RG 17(a) -- fallback + Lord subjectLukasz Kasprzak2026-08-137-2/+471
|/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | RG 17(a): "festum Ss.mi Nominis Iesu, celebrandum dominica quae occurrit a die 2 ad 5 ianuarii (secus die 2 ianuarii)" -- both photographic scans, confirmed on the calendarium's own January table and the Mass propers' own heading. Two defects closed together, since they interact through RG 91 entry 14/RG 16(a): 1. The Sunday shape (2-5 January) now tags subject = Lord, matching RG 91 entry 14 ("Festa Domini II classis") -- previously subject = Temporal, the same defect shape Holy Family had before it. 2. The fallback (RG 17(a)'s own "secus die 2 ianuarii", the calendarium's "vel, ea deficiente, die 2 ianuarii") is now built: 2 January carries the feast whenever no Sunday falls 2-5 January that year. Before this fix colitur emitted no Holy Name office at all in such a year -- a real II-class feast simply missing, on 3,619 of 8,417 years in the domain (43%; 20 of the 46 years 2005-2050, independently re-derived against `date -d`). Both shapes band identically at RG 91 entry 14's MOVABLE half (Precedence_ef.entry_14_movable_band) -- one feast, not two differently classified ones, per the Mass propers' own single heading covering both dates. No live collision exists in the current sanctoral data (nothing fixed-date falls 2-5 January besides a Commemoration_only entry on 5 Jan), so the RG 16(a)/RG 112(a) interaction is proved with synthetic precedence-level fixtures mirroring Holy Family's own precedent, not a live-data regression. One asymmetry the synthetic tests found and kept honest rather than forced: a losing Holy-Name-Sunday is privileged (RG 109(a), "of a Sunday") and survives RG 111(a)'s cap; a losing Holy-Name-fallback is not (2 January is not a Sunday, and no other RG 109(a)-(f) category applies to it), so it gets no commemoration at all if ever outranked -- both individually correct readings of RG 109/111's closed lists. Golden pins follow the brief's own vacuity warning: the Sunday shape already emitted the right slug/rank/colour before this fix (an ordinary Sunday and Holy Name coincide on those fields), so its pin asserts subject explicitly rather than pinning the whole line uncritically; the fallback pin (2029-01-02) is the one with teeth against the larger defect, reddening on slug/rank/subject together if reverted. Mutation-tested: each half of the fix reverted separately reddens exactly its own tests (Sunday subject: the dedicated unit test, the golden pin's subject field, one precedence end-to-end test; fallback: the fallback unit/anchor/golden tests, the new C16 differential count, and both shapes of the precedence end-to-end tests) and nothing else. Adds data/ef/expected-divergences.sexp's C16 (lectio has no fallback for this window at all) -- the lectio differential's own count, independently re-derived against `date -d` for the fixture's 2005-2050 span, not transcribed from the domain-wide figure. The missalemeum oracle window (2026-2027) exercises only the Sunday shape and needed no new entry: subject is not one of its compared fields, and both years' rows already corroborate the Sunday-shape ranking (missalemeum's own 2026-01-04 and 2027-01-03 rows: rank 2, white, title "Holy Name of Jesus").
* Merge branch 'ef-rg112-rg110': the Holy Family, RG 112(a), observed identityLukasz Kasprzak2026-08-1312-206/+1282
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
| * docs: two retracted claims that outlived their retractionLukasz Kasprzak2026-08-133-17/+44
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Both are the defect class this fix round existed to close, which is why they are worth recording rather than quietly overwriting. CLAUDE.md still carried F1's retracted design rationale -- describing entry_14_movable_band as "negative so it can never collide with a real table position" -- and F2's retracted transcription-defect attribution, verbatim, in the one tracked file the project's own workflow tells a fresh session to read first. The fix round struck both everywhere else and missed this file. A session following it as instructed could have re-derived the negative sentinel for entry 20's or entry 23's movable half and re-introduced the inversion in a new branch. precedence_ef.ml's replacement justification for the x10 rescale then introduced a fresh misstatement of the same primary text it was correcting: it attributed "primum mobilia, deinde fixa" to "entry 12's own ninth sub-item" and counted three such rows. Both photographic scans, and the register's own section 4 table, put that clause at entry 13; entry 12 has eight sub-items and no such clause. The split occurs at five rows -- 13, 14, 20, 23's third sub-item, and 24. Entry 24 is the most-evaluated band in the whole domain and is unsplit in the code, which is precisely the sub-rank the new headroom exists to hold. Corrected in the .mli and the register too. No behaviour change; 290 tests green.
| * docs: fix round 1 (F9) -- Holy Name of Jesus is missing a real office, not ↵Lukasz Kasprzak2026-08-131-3/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | just a name A second, more severe gap than the identity-shaped one already recorded: RG 17(a)'s own 2-5 January window, unlike Holy Family's 7-13 January (never empty, register section 6.2), CAN be empty of a Sunday -- the calendarium carries an explicit fallback for it ("vel, ea deficiente, die 2 ianuarii") that colitur does not implement at all. Independently computed (matched the reviewer's own figure exactly): 3,619 of 8,417 domain years have no Sunday in 2-5 January, and colitur emits no Holy Name office whatsoever in any of them -- a genuine missing II-class feast on 43% of years, not merely an unnamed generic Sunday the way Holy Family's own pre-task gap was. Recorded in the register (gitignored, not part of this commit) and CLAUDE.md's carried-item list; out of this task's own dispatched scope (Holy Family and RG 112 only), not fixed here.
| * test(oracle): fix round 1 (F8) -- correct the M18 headline, name the blind ↵Lukasz Kasprzak2026-08-133-22/+40
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | spot precisely The full breakdown, precisely: of 730 days, 331 are resolved (330 matching, 1 mismatched -- M13, Joseph vs the Seven Sorrows), 399 unresolved -- 373 in M18's own bucket, 26 absorbed inside M1/M2/M3/ M16's own widened subsets where the axis fires alongside their pre-existing citation. M18's own note previously stated only its own 373 without this fuller context. Also names the blind spot the axis exists to close in exact terms, not just "the observed day's identity": 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, and the reason every prior layer stayed green through the whole gap. States explicitly what the count pin does and does not prove: it guards against the 373/399 population moving silently in either direction, but cannot say which specific day moved or why.
| * data(ef): fix round 1 (F6) -- restore C1's provenance record for 361Lukasz Kasprzak2026-08-131-1/+1
| | | | | | | | | | | | | | | | | | | | | | The previous refresh's own note recorded HOW 368 was derived (a Python cross-check against the comparator's own failure output, not hand-counted and not copied from a green run); this task's rewrite explained WHY 361 replaces it (C15's own split) but dropped the provenance sentence, stating 368 -> 361 with no record of how the new number was checked. Restored: 361 read directly from the OCaml comparator's own failure output, with the 368-minus-7 arithmetic noted as corroboration, not the derivation.
| * test(temporal_ef): fix round 1 (F5) -- the anchor erosion test proved nothingLukasz Kasprzak2026-08-131-12/+35
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | test_holy_family_anchor_present_and_erosion_is_caught built its "eroded" list by filtering the exact pair it then asserted was absent -- removing an element and checking it is gone proves List.filter works, not that any detector caught anything. Borrowed the name of test_anchors_erosion_is_caught, which uses a genuine one: missing_from_anchors, called with an "expected" set sourced independently of T.anchors (named_slugs_for_year, via T.named). Reworked to match that shape: the expected slug is now sourced from T.sunday_slug (season/weekday logic, a different function entirely from T.anchors's own hand-typed string), and both the presence and erosion checks reuse the real missing_from_anchors detector instead of a bespoke, self-referential one.
| * test(golden): fix round 1 (F4) -- describe pins subject, the field ↵Lukasz Kasprzak2026-08-131-46/+62
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | RG16(a)/RG112(a) key on Two of the three original Holy Family pins (2026-01-11, ordinary year; 2024-01-07, earliest possible date) were byte-identical before and after temporal_ef.ml's own fix. Reverting the feature failed only the 2030-01-13 collision pin -- describe omitted subject, the ONE field the change actually touches on an ordinary (non-collision) year, so those two pins asserted an ordinary Sunday's identity and called it Holy Family. Vacuity flavour #1 (an assertion already true before the code under test ran), not #8 (promoted from actual output) -- the other nine fields' values were independently sourced and remain so. subject added to describe's own formatted line. Every existing golden pin's expected string updated to match -- each value independently sourced (grep data/ef/sanctoral.sexp for the sanctoral-origin pins; Temporal for every ef-* temporal slug) before running the suite to verify, not copied from actual output and rationalised afterward. All matched on the first attempt.
| * temporal(ef): fix round 1 (F3) -- give Holy Family a primary-sourced Latin nameLukasz Kasprzak2026-08-132-7/+50
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | On 7,197 of the 8,417 days Holy Family occurs (every year that isn't the 13-January collision), every emitted byte was identical to the pre-change binary -- subject appeared in no output path the CLI or any test read. Celebration.make already takes ?names, defaulting to empty, and Temporal_ef.build never passed it. build now takes an optional ?names, set only on Holy Family's own branch: a LATIN name, not English. The oracle's own observed-identity axis (test_oracle.ml) reads only `en`, so this is deliberately invisible to it -- an English name here would mean reading missalemeum's own title text, the oracle this exact axis is compared against, to decide colitur's "ground truth" name: the "expected value promoted from actual output" vacuity flavour this project's review process watches for. Latin has no such circularity: the calendarium's own January table and the Mass propers' own heading, both photographic scans, word for word, "Sanctae Familiae Iesu, Mariae, Ioseph" -- the same genitive-title convention test_names.ml's own worked example already uses for Easter ("Dominica Resurrectionis"). Every other temporal-cycle candidate, including the neighbouring Sundays, still carries no name of any kind -- a targeted addition for the one day this task built, not a claim that the general gap (register's own open item on Holy Name of Jesus, RG 17(a)) is closed.
| * precedence(ef): fix round 1 (F2, F7) -- correct a false transcription claim, ↵Lukasz Kasprzak2026-08-133-59/+111
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | cite RG95's real primary authority F2: the disposition comment for RG112(a) claimed the electronic transcription "carries NEITHER this paragraph's own worked example NOR its own more specific Mass-proper rubric... exactly the transcription's documented defect" -- wrong on both counts, checked directly rather than taken on trust. RG 112 has no worked example in any of the three source documents (the transcription included) -- there was nothing to drop. The Holy Family Mass propers' own 13-January rubric is absent from the transcription not because it silently drops content it otherwise has (the project's own documented defect, dropped calendarium commemoration lines) but because that specific document (a 2006 web capture) contains almost no Mass-propers text of any day: 5 Introit-line occurrences across 26,322 lines, against 61 and 402 in the two photographic scans; its own "Proprium de Tempore" page is a table of contents linking to PDFs the capture never pulled in. A coverage gap in a partial web capture, not an instance of the narrower, different defect the methodology note actually describes. The ruling is unaffected -- the propers' quotation is real, on two independent photographic scans, and settles 13 January on its own -- only the attribution is struck, here and in test_precedence_ef.ml (the register and the task report are corrected separately). F7: RG 95's own second paragraph -- present in all three documents, including the transcription -- is a more direct, occurrence-level authority for the exact collision than RG 112(a): "if two feasts of the same Divine Person... occur together, the one higher in the table is kept, the other omitted." Added as the primary citation on disposition's RG112(a) branch, with RG 112(a) and the propers' note kept as corroboration. Also corrects RG 112(b)'s own framing: it is bidirectional ("et vicissim"), and only the Lord-feast-wins direction (RG 16(a)) is implemented -- the Sunday-wins direction has no witness anywhere in this codebase's data and was wrongly described as already covered.
| * precedence(ef): fix round 1 (F1) -- band's -14 sentinel inverted the tableLukasz Kasprzak2026-08-133-146/+276
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | entry_14_movable_band = -14 was justified only by "cannot collide with a real table position (1..28) or unclassified" -- a collision argument, not an ordering one. band's own value is compared by plain <, so a negative number beats every I-class entry (1-13), not merely the fixed Baptism it was built to beat. Not live against the shipped universal sanctoral data (no I-class universal feast falls 7-13 January, which is why the original 1583-9999 sweep showed only the intended shape), but entries 12/13 admit PROPER and INDULT I-class feasts too, and those arrive via adjustments.sexp-style overlays -- this architecture's own advertised extension path. A diocesan patronal feast landing in Holy Family's window would have made the inversion live immediately: the I-class feast displaced and transferred to the next day, reproduced and confirmed before this fix, reverted after. Fixed by rescaling every band branch to the real RG 91 entry number times ten (unclassified untouched at max_int) instead of the bare 1..28, reserving genuine headroom immediately before each entry for a movable sub-rank -- not an arbitrary rescale: RG 91's own text records a "primum mobilia, deinde fixa" split at three rows, not only entry 14 (entry 12's own ninth sub-item, entry 14, and entry 20), so this leaves room for the other two without a second rescale if either ever gets a live witness. entry_14_movable_band now derives from entry_14_fixed_band - 1, tied together so they cannot drift apart. Added a synthetic I-class end-to-end test reproducing the exact counter-example that found this: a universal I-class candidate inside Holy Family's own 7-13 January window is now observed and does not transfer, with Holy Family itself falling to RG109(a)'s ordinary privileged-Sunday-commemoration path, the same treatment any genuine feast outranking an ordinary Sunday gets.
| * docs: Holy Family + RG112(a) resolved; layer 4 observed-identity gap closedLukasz Kasprzak2026-08-131-21/+86
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | CLAUDE.md's own carried-item list (item 1, RG16(a)) named two open items it did not fix: 13 January mistagged Saint (independently fixed upstream by ef-rebootstrap, not this task) and RG 112 unimplemented. Both close now, plus a third: the 'know what each layer cannot see' section did not record that layer 4 (the missalemeum oracle) compared the observed day's rank and colour and never its identity -- exactly why the missing Holy Family went unnoticed by every layer for as long as it did. Recorded as a new, third RESOLVED item alongside RG16(a) and commemoration identity, with the same shape: what broke, what was found while fixing it, the measured blast radius, what stays open. docs/research/rules-register.md (gitignored, not part of this commit) carries the full account as its own new §6.2 -- the complete RG 91 entry 14 and RG 112 primary texts (all four sub-clauses, not only the two the register quoted before), the Holy Family Mass propers' own more specific 13-January rubric found while building this, and the independently cross-verified 1,220-day blast radius.
| * test(golden): pin Holy Family in three shapes (RG 17(b))Lukasz Kasprzak2026-08-131-0/+73
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | An ordinary year (2026-01-11, no fixed-date competitor), the latest possible date and the one 13-January collision (2030-01-13, the fixed Baptism of the Lord excluded entirely by RG91 e14 + RG112(a)), and the earliest possible date (2024-01-07, Epiphany a Saturday) -- proving RG 17(b)'s own 7-13 January window at both ends, not only its middle. Every field independently traced against the primary text before typing it in, per this file's own header rule: season stays christmastide (RG 72-73, unaffected by which Sunday of it this is), week stays unset (Christmastide has no numbered weeks at all), slug is unchanged from the plain Sunday key this date always carried (temporal_ef.ml's own comment on why RG 17(b) needs no new lectionary key), rank II class, colour white. Each weekday independently cross-checked against "date -d <iso> +%A" (GNU coreutils).
| * test(oracle): green -- widen five entries, add M18 for observed identityLukasz Kasprzak2026-08-132-13/+92
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | layer_m_reason's own five entries whose diff shape was checked by EXACT list equality (M1, M2, M3, M13, M16) lost their match once the observed-identity axis widened every row's diff set two commits ago. Each is widened the same way commemoration-identity was already widened for M13 once before: the axis now ALSO fires alongside their existing citation, same root cause, same id -- M1/M3 (temporal-origin observed day, no name), M2 (same, plus five Paschaltide dates that used to match cleanly and now surface for the first time), M13 (Joseph, sanctoral, now a genuine title MISMATCH, not merely unresolved), M16 (the temporal Passiontide feria observed there). M18 covers the remainder: 373 of 730 days whose observed celebration is temporal-origin and so carries no English name at all -- the overwhelming majority of the window, including Holy Family's own two dates in it (2026-01-11, 2027-01-10), counted here rather than shown as a false Matched. Gated on the diff SHAPE alone (this file's own convention for a population this size, the same reasoning M2's own title-substring predicate already uses instead of a date list), verdict unresolvable -- the same fourth verdict M15 already established for the identical limit on the commemoration axis. Building an English name onto the temporal cycle is Plan 4's own scope, register §6. Teeth, per the brief: temporarily corrupted hilary's own English name in data/ef/sanctoral.sexp (14 January 2026, an OBSERVED sanctoral day, rank and colour left untouched) and reran. Reddened immediately: 2026-01-14: observed-identity-mismatch differ -- colitur=(rank=3 colour=w ...) oracle=(rank=3 colours=[w] title="St. Hilary" ...) rank and colour agree on both sides -- exactly the shape the pre-strengthening comparator would have slept through completely. Reverted (git diff on the data file is empty) before this commit.
| * test(differential): split the Holy Family/Baptism collision out of C1 (C15)Lukasz Kasprzak2026-08-132-2/+41
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Before this task's Holy Family fix, colitur's generic Sunday fallback lost outright to the fixed Commemoration of the Baptism of the Lord on 13 January whenever it fell on a Sunday, producing the SAME slug lectio's own tridentine-calendar.ini shows there -- squarely inside C1's own 6-13 January blanket (only Season differed). Now that Holy Family (RG 17(b)) correctly outranks the fixed Baptism and excludes it as a commemoration (RG 91 entry 14, RG 112(a)), colitur's own slug on those seven dates (2008, 2013, 2019, 2030, 2036, 2041, 2047) changes to ef-time-after-epiphany-sunday-1 -- a genuine identity divergence against lectio, which has no Holy Family at all. C1's own predicate does not absorb it (jan_6_13_slug has no entry for that slug), so it surfaced as unexplained, exactly the check the task brief asked for: split it out into its own cited entry rather than widening C1's predicate to swallow it silently. C1's own expected_rows moves 368 -> 361 (back to its pre-rebootstrap value, for a third and different reason than either of the first two moves recorded in its own note); the new C15 covers the 7 rows, gated on the literal date list AND colitur's own slug, the same identity guard C1/C6/C8/C14 already apply.
| * precedence(ef): RG91 e14 "primum mobilia" + RG112(a) inseparable exclusionLukasz Kasprzak2026-08-133-8/+248
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Two related fixes, both needed for Holy Family to actually observe correctly on the seven years it coincides with the fixed Commemoration of the Baptism of the Lord (13 January): 2008, 2013, 2019, 2030, 2036, 2041, 2047. band's entry 14 ("Festa Domini II classis") gated on sanctoral origin only, so a movable Class2 Lord feast had no row in the table at all. RG 91 entry 14's own text says otherwise: "primum mobilia, deinde fixa" -- movable first, then fixed. entry_14_movable_band gives Holy Family (the one movable candidate this codebase builds with subject Lord) a value strictly better than the fixed half's own literal 14, negative so it can never collide with a real table position -- without it, the two would tie at 14 and fall to Precedence.resolve's own alphabetical tie-break, which picks the WRONG side ("commemoration-of-the-baptism-of-the-lord" sorts before "ef-time-after-epiphany-sunday-1"). disposition gets a new branch for RG 112(a) (Caput XVI, "De Commemorationibus"): the Office, Mass or commemoration of a mystery of one Divine Person excludes a commemoration of another mystery of the SAME Divine Person. Winner and loser both subject Lord -> Omit, not Commemorate -- without it, Holy Family observing correctly still left the Baptism admitted as an ordinary Class2 commemoration under RG111(b), which the primary text does not allow. Confirmed by a MORE SPECIFIC primary source than RG 112(a) alone: the Holy Family Mass propers' own note, found on both photographic scans, word for word, immediately after the Postcommunio -- "Si festum S. Familiae occurrerit die 13 ianuarii, Missa dicitur de festo S. Familiae, sine commemoratione Baptismatis D.N.I.C., et sine commemoratione dominicae." The electronic transcription carries neither this rubric nor RG 112(a)'s own worked example -- another instance of its documented defect, not merely absent from one check. Still expected red: the lectio differential (2005-2050) now shows a new, real divergence on those seven 13-January-Sunday dates -- lectio has no Holy Family at all, so it still shows the fixed Baptism observed there, unlike colitur now. The oracle's own M-series entries also still need widening for the observed-identity axis added two commits ago. Both are the next commits.
| * temporal(ef): the Holy Family, first Sunday after Epiphany (RG 17(b))Lukasz Kasprzak2026-08-133-11/+201
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | RG 17(b), verified against both photographic scans (missale-romanum- 1962.pdf and "Missale Romanum 1962_text.pdf" -- the electronic transcription carries the same paragraph, so this one is not itself a transcription-vs-scan divergence): the Holy Family of Jesus, Mary and Joseph is celebrated on the first Sunday after Epiphany, II class, EVERY year, taking the Sunday's own place "cum omnibus iuribus et privilegiis" -- the same formula RG 16(a) already uses. The slug, rank and colour temporal_ef.ml already computed for that Sunday (ef-time-after-epiphany-sunday-1, Class2, white) turn out to be exactly right by coincidence -- an ordinary, unnamed Sunday and Holy Family share both. The only field that was silently wrong is subject: always Temporal before this, when RG 91 entry 14 ("Festa Domini II classis, primum mobilia, deinde fixa") calls Holy Family a movable Feast of the Lord. temporal's build now takes an optional ~subject, applied only on Holy Family's own date -- every other Sunday, including the still-unbuilt Holy Name of Jesus (RG 17(a)), is unaffected. RG 17(b)'s window (7-13 January) can never be empty of a Sunday -- sunday_on_or_before(6 Jan) + 7 always lands in [7, 13] regardless of 6 January's weekday -- unlike RG 17(a)'s Holy Name (2-5 January, CAN be empty), whose calendarium entry carries an explicit "vel ea deficiente, die 2 ianuarii" fallback right next to Holy Family's own, fallback-free one. No fallback needed or built. Added to anchors (holy_family_sunday is independently computed, not routed through named -- see temporal_ef.ml's own comment on why) and to its own dedicated anchor/erosion test in test_temporal_ef.ml, kept separate from the generic named-days coverage test since this genuinely isn't one of named's own outputs. Does not yet touch precedence: band still has no notion of a movable Class2 Lord feast (entry 14 gates on sanctoral origin only), so on the seven years 13 January is itself Holy Family's date (2008, 2013, 2019, 2030, 2036, 2041, 2047), the fixed Commemoration of the Baptism of the Lord still wins the day exactly as before this commit -- the next commit fixes the ordering RG 91 entry 14's own text states ("primum mobilia, deinde fixa").
| * test(oracle): compare the observed day's identity, not only rank/colourLukasz Kasprzak2026-08-131-2/+70
|/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Layer 4 (test_oracle.ml, vs missalemeum) compared the observed celebration's rank and colour and stopped there -- it never checked whether the observed day is actually the RIGHT one. Holy Family (11 January 2026: oracle title "The Holy Family: Jesus, Mary & Joseph") is rank 2/white on both sides purely by coincidence -- an ordinary, unnamed Sunday and Holy Family share both -- so this layer has been silently blind to the missing feast since it was built. Adds Observed_identity_mismatch/Observed_identity_unresolved, following the shape and honesty of yesterday's commemoration-identity comparison (Comm_identity_mismatch/Comm_identity_unresolved): colitur identifies its own observed day by slug, missalemeum by an English title, and the bridge is Celebration.t.names, read directly off LD.observed. That name is only ever set for a SANCTORAL-origin celebration -- a TEMPORAL-origin one (an ordinary Sunday, a feria, a movable named feast) carries none, so most of the 730 days in the fixture window land in Observed_identity_unresolved, not a clean match. That is counted and reported, never silently skipped -- the same discipline this file already applies to an unresolvable commemoration. WIP, expected red: 399 days now show observed-identity-unresolved with nothing in the allow-list naming it, and five of the six existing M-series entries whose own diff shape is checked by exact list equality (M1, M2, M3, M13, M16) lose their match now that this axis widens their diff set. Landed on its own, ahead of any production fix, so it is the regression net the following commits are checked against rather than a change bundled in alongside the fix they enable. The next commits widen those five entries' own diff shapes and add the new bucket's own cited allow-list entry, then build Holy Family itself.
* Merge branch 'ef-rebootstrap': re-bootstrap the sanctoral, refresh the ↵Lukasz Kasprzak2026-08-1312-17061/+17408
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | differential Re-bootstraps data/ef/sanctoral.sexp from lectio's corrected generator (322 -> 327 entries), propagating fixes colitur had inherited wholesale: 15 entries wrongly marked commemoration-only that are really III-class feasts, four entries missing entirely, six commemorations an electronic transcription had hidden, and two class corrections. 38639 days change across 1583-9999, in three shapes with no remainder: 2245 where a III-class feast now correctly beats a class-4 feria, 35174 where one of five restored commemorations appears, and 1220 on 13 January. All five restored entries were verified against a photographic scan -- real, correctly ranked, and confined to their own dates. 13 January is NOT fixed by this. It moves from one wrong answer to a different one, because RG 112 and a Holy Family office are both unbuilt. Recorded as its own allow-list entry with a citation and a count, rather than left inside a season-boundary entry's cardinality pin, and deliberately not pinned by a golden test. Then refreshes the lectio differential fixture, which predated the seven EF defects fixed in that project. Nine allow-list entries close -- each was a real divergence adjudicated in colitur's favour, and each closes because lectio was fixed, with its RG citation preserved. The list goes from twelve entries to four; the remaining 540 differences are fully attributed with none unexplained.
| * test(differential): two Layer C predicates that counted rows, not identitiesLukasz Kasprzak2026-08-121-4/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Both are the "cardinality where identity was required" flavour, and both were demonstrated passing a real defect by the fixture-refresh review rather than argued. C6 accepted `subset diffs [ Slug_f; Rank ]` while its own note said the shape had narrowed to slug-only after lectio's Christmas-octave rank was corrected. That did not merely over-permit: every one of the 138 rows already carries a Slug_f diff, so an added Rank diff changed neither the diff-set membership nor the count, and the entry was blind. Dropping the RG 91 entry 17 elevation in temporal_ef (Class2 -> Class4 on octave days 5-7) left both differential tests green with C6 still reporting 138. Narrowed to `diffs = [ Slug_f ]`; the same mutation now reddens both. C14 gated on lectio's date alone, with no colitur-slug guard, though fix round 1's finding 1 had established that a predicate must pin which celebration its citation is about -- C1, C6 and C8 all carry that guard. With compare_deferred switched to RG 98 origin order the observed celebration flips to the Annunciation on all three dates, and C14 still matched exactly 3 rows with its count pin green; the suite reddened only because the sibling dates fell outside every predicate. Guard added. No behaviour change: 277 tests green, and the allow-list counts are unmoved (C6 138, C14 3).
| * test(differential): refresh the lectio fixture, close 9 entries, add C14Lukasz Kasprzak2026-08-124-16964/+16966
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | lectio moved 2386a45 -> 3b32c00 (seven EF calendar defects fixed, plus a sanctoral-generator root-cause fix); the committed fixture predates all of them. Regenerated with the same command the provenance note already named (`go run ./cmd/lectio-ef-dump 2005 2050`), read-only against lectio -- nothing there was touched. New SHA-256 asserted in both the provenance note and test_differential.ml's fixture_sha256. The dumper's two new name_en/name_pl columns are kept verbatim (the fixture is meant to be the exact command's raw output; the comparator already discards everything past field 7). Every C-entry's expected_rows was re-derived independently against the refreshed fixture (a Python re-implementation of diff_fields/ layer_c_reason, cross-checked against the real OCaml comparator's own failure output), not transcribed from a green run. Nine entries -- C2, C3, C4, C5, C7, C10, C11, C12, C13 -- now match zero rows and are closed: sexp row removed, layer_c_reason predicate and its now-dead helper bindings removed, citation preserved in docs/research/rules-register.md's new §3d with the specific lectio commit that fixed each one. C1 (361 -> 368) absorbs C13's former 7 rows now that lectio's own slug matches there too. C6 (138, unchanged count) narrows to a slug-only shape now that lectio's rank agrees. C8 (31, unchanged) survives untouched -- lectio still computes no Rogation days. C9's old shape ("Joseph observed ON a Lent Sunday") is also closed, but a narrower, different divergence survived under the same saint's slug: 3 years (2008, 2035, 2046) where Joseph's own congested RG96 walk collides with the Annunciation's separately-transferred "sedes propria". The old predicate's broad "any diff involving this slug" match was silently absorbing both under one citation -- split into a new id, C14, rather than folded back into C9, since the two are unrelated rules. lectio's own commit history (09a1444) documents this residual as a gap it deliberately left unresolved; colitur gives Joseph a real transferred day either way, which is why C14's verdict stands regardless of a genuinely open sub-question (recorded in the register, not resolved here) about which of the two feasts should claim the contested day first under RG98's "prius impeditum" wording. Re-triaged the full remaining 4975 raw differences: only 10 distinct field-diff signatures now, all resolving to Layer A/B noise or the four surviving citations, 0 unexplained. The crude "Sunday-rank" and "Holy Thursday" residues the task flagged both fully resolve once the real Layer A/B machinery runs (season-spelling and week-numbering artifacts, not substantive divergences) -- see the task report for the derivation. Teeth proof: perturbing ferial_rank to reproduce C4's old defect made 140 rows reappear as unexplained (the exact prior C4 count), reverted after capturing the failure message. 277 tests green (dune test) and 278 with COLITUR_EXHAUSTIVE_SWEEP=1 (the extra case is the 1583-9999 sweep itself).
| * test(sanctoral_ef): fix round 1 (F8) -- guard against wholesale name.pl lossLukasz Kasprzak2026-08-121-0/+21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The previous commit's bootstrap_sanctoral.ml change (name.pl optional) is correct and verified not to silently drop a present name, but nothing in the suite would have caught a regeneration that dropped name.pl WHOLESALE -- the exact defect lectio itself shipped once (a regeneration that lost all 322 Polish names, only caught because that project's own review ran cmd/lectio-ef-dump, which happens to include name fields; this project's own test_load_and_counts checks entry/status/rank counts only, none of which move if every name.pl vanishes). Added a 322-of-327 count assertion (5 legitimately lack it, matching parse_names's own list), independently re-derived: `grep -c '^name.pl' tridentine-calendar.ini` = 322, cross-checked against `grep -c '(pl' data/ef/sanctoral.sexp` = 322 exactly.
| * data(ef): fix round 1 (F7) -- track the 5 new entries' primary citationsLukasz Kasprzak2026-08-121-2/+29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Removing M4/M6/M7/M9/M14 (an earlier commit) deleted the only TRACKED primary-source citations for these five entries: docs/research/ (where the full quotes originally lived) is gitignored, and data/ef/sanctoral.sexp is generated data with no citations field of its own, so the public repo held no record of why agnes-secundo, boniface-martyr, eusebius-confessor, evaristus and theodore exist. Added a provenance note quoting each one's calendarium line verbatim from the photographic scan. Also fixes a name omitted from the "FIVE MORE REMOVED" note's own list (boniface-martyr was missing; no other consequence, since neither the removal itself nor the row-count pin ever depended on that prose list).
| * tools(bootstrap_sanctoral): fix round 1 (F6) -- stale entry-count commentsLukasz Kasprzak2026-08-121-8/+18
| | | | | | | | | | | | | | | | | | | | | | Three comments still said "322" after the previous commit's regeneration moved the total to 327: the date-form comment (rewritten to not carry a count at all, since it is about a FORM, not a quantity); the explicit-class comment (327, plus recorded that the 6 entries carrying it changed membership -- 12 September dropped it, 13 January gained it -- even though the count of 6 itself did not move); the name.pl comment (327 total, 5 missing it, 322 carrying it -- was "5 of the source's 322 entries", conflating the new total with the old one).
| * data(ef): fix round 1 (F3) -- eusebius-confessor is white, not lectio's redLukasz Kasprzak2026-08-122-1/+54
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | data/ef/sanctoral.sexp bootstraps colour=red for this new entry (14 Aug), inherited from lectio's own ini; missalemeum's fixture independently tags it :r too -- two non-primary witnesses agreeing with each other, not with the Missal, the exact "trap" this project's own transcription-audit task already named once. Checked directly against the scan (missale-romanum-1962.pdf), not taken on a reviewer's transcription: the 14 August proper reads "S. Eusebii Conf. / Commemoratio / Missa Iustus, ut in festo S. Pauli primi Eremitae, die 15 ianuarii" -- Conf. (Confessor, not Martyr), borrowing the SAME Mass 15 January's own Paul the First Hermit uses, a Confessor's Common, white in both engines' own data for THAT entry. Every other Confessor/Abbot commemoration in lectio's own data is white (maur-abbot, giles, remigius, didacus, ubaldus, hilarion, sabbas, silvester, alexis); Eusebius Confessor is the one exception, with no textual support found for it. No behavioural impact today (Commemoration_only entries are never the printed observed colour under the current pipeline), fixed via the overlay mechanism since sanctoral.sexp is generated and the source is upstream. New test proves it through the real pipeline, the same discipline already applied to the subject retags.
| * test(differential): fix round 1 (F2, F5) -- split 13-Jan-Sunday into C13Lukasz Kasprzak2026-08-122-8/+47
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 13 January retagged subject=Lord (previous commit's regeneration) makes RG16(a) fire on the 7 years it falls on a Sunday within 2005-2050 (2008, 2013, 2019, 2030, 2036, 2041, 2047): colitur now observes the Baptism of the Lord itself where it used to observe the generic Sunday slug. The diff signature against lectio's fixture widens from {season;colour} to {season;slug;colour} -- but jan_6_13_slug already pre-authorised this exact slug across the whole 6-13 January window (correctly, for the other 39 non-Sunday years), so layer_c_reason routed the new, wider-shape rows into C1 unchanged, and C1's own expected_rows (a pure row count) did not move. A count proving cardinality where identity was required -- on the one day this branch itself already flags as still wrong under RG 112. Split into its own entry, C13, matched by an exact 7-date literal list checked before C1 in the if/elif chain. C1's own expected_rows corrected 368 -> 361 (independently re-derived: a Python script reading data/ef/sanctoral.sexp's regenerated output and the committed lectio fixture directly, replicating diff_fields/layer_c_reason's own logic outside the OCaml comparator -- not transcribed from the failing comparator's own count). C13's own citation records a refinement over the coordinator's framing, checked directly rather than assumed: lectio's committed fixture is a frozen snapshot that predates lectio's own equivalent fix to this entry's class field (the same staleness shape as C12). Confirmed by building lectio's own cmd/lectio-ef-dump from its current source tree (read-only) and running it fresh for all 7 dates -- lectio's LIVE engine now agrees with colitur's slug/rank/colour exactly, disagreeing only on season (the already-understood C1 divergence). This is not evidence colitur's answer is right against the Missal -- it is not (register's own RG112 item) -- only that this specific divergence from the fixture is a staleness artifact, not a live disagreement between the two engines' current logic. Also fixes F5: C12's own note said "5 of the 15 corrected slugs" while listing and counting 7 -- corrected to 7. Also corrects the module header's stale "13 January ... slug/rank/colour already equal lectio's exactly, in all 46 years" claim (true only for the 39 non-Sunday years now).
| * test(golden): fix round 1 (F1) -- correct why the other 8 reclassified slugs ↵Lukasz Kasprzak2026-08-121-7/+29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | are silent The comment on test_iii_class_feast_wins_class4_feria gave a single reason for why 8 of the 15 rank-corrected slugs produce zero diff rows anywhere in the domain: "always fall inside Lent/Passiontide proper, RG 91 entry 22, which already outranks entry 24". Wrong for 3 of the 8: gabriel-the- archangel (24 Mar), john-damascene (27 Mar) and john-of-capistrano (28 Mar) land in Paschaltide 226/846/1108 times domain-wide, always at class-1 (inside the Easter Octave, RG91 entry 2/10), never entry 22. The conclusion (zero diff rows) was and remains right; only the reason was wrong -- exactly the "correct code, wrong explanation" defect this project has repeatedly caught before. Corrected to the actual, checked shield: every context these 8 dates ever land in domain-wide is either class-1/2 (trivially outranking any class-3 candidate and excluding it from commemoration by RG111's own rank floors, regardless of status) or the season's own class-3 feria at entry 22 (which outranks entry 24 for observation but admits the losing saint's commemoration identically whether Commemoration_only or Feast, RG111(c)/(d) having no ferial-class gate on an ordinary sanctoral candidate).
| * test(golden): pin the six days RG91 entry24>28 now resolves correctlyLukasz Kasprzak2026-08-121-11/+84
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 2008-04-02/04/05 and 2038-03-06/08/09 are the six dates the re-bootstrap's own brief named as producing a wrong observed office under the old data (a III-class feast wrongly demoted to Commemoration_only, unable to win against an ordinary class-4 feria it should trivially outrank). Verified against the Missal before pinning, per this file's own rule: RG 91 entry 24 ("Festa III classis, in calendario Ecclesiae universae inscripta") outranks entry 28 ("feriae IV classis"), a plain, unqualified table reading, and the calendarium text for all six was already primary-verified in the register before this task ran -- only the data was wrong. Each pin proves the mechanism, not merely the answer: an omitted_has check (one per season family, Paschaltide and Septuagesima) confirms the displaced class-4 feria actually reached disposition and was actively excluded under RG26, not merely absent because nothing was ever offered. test_easter_extreme_2038_late_modern's own header previously recorded these three March dates as a DELIBERATE EXCLUSION because they were known wrong; corrected in place to point at the now-existing pin instead of continuing to justify an exclusion whose reason no longer holds.
| * test(oracle): close M4, M6, M7, M9 and M14 -- the five now-fixed data gapsLukasz Kasprzak2026-08-122-93/+44
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Each was recorded as a genuine data gap "traced upstream into lectio, unfixable without touching lectio". That constraint is gone: all five commemorations (St Agnes secundo 28 Jan, St Eusebius Confessor 14 Aug, St Evaristus 26 Oct, St Theodore 9 Nov, St Boniface Martyr 14 May) are now present in the re-bootstrapped sanctoral.sexp, and each divergence stops occurring in the 2026-2027 oracle fixture -- verified by re-running the comparator and confirming zero rows for all five ids, not assumed from the data change alone. Removed rather than kept as dead 0-row citations, matching the M17 precedent already in this file: the count pin (test_layer_m_counts_match_citations) now enforces that none of these five divergences can silently reappear. Corresponding dead code (m4_dates .. m14_dates and their layer_m_reason branches) removed from test_oracle.ml; a short pointer comment left at each id's old location.
| * test(differential): allow-list C12 for the 15-entry rank correctionLukasz Kasprzak2026-08-122-4/+27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Re-bootstrapping sanctoral.sexp (previous commit) makes 7 of the 15 newly-corrected III-class feasts win an occurrence they previously lost as Commemoration_only: RG 91 entry 24 (a universal III-class feast) outranks entry 28 (a IV-class feria), and the occurrence code that resolves this already existed and needed no change. lectio's own committed differential fixture (test/fixtures/lectio-ef-2005-2050.txt) is a frozen snapshot predating lectio's own equivalent generator fix, so it still shows the class-4 feria observed with the same saint only as a trailing commemoration -- a new, expected divergence from that fixture, 14 rows in the 2005-2050 window. expected_rows (14) is independently re-derived by grepping the regenerated sanctoral.sexp's own post-regeneration civil-day output against the committed lectio fixture directly (two flat-file extractions cross-checked against each other), not transcribed from the comparator's own failing-test output. C12 reuses an id last used, and removed, by the RG16(a) task's own reverted Purification retag -- noted at both the old and new entries' own comments so the id's history is visible to a future reader.
| * data(ef): document why adjustments.sexp's directives survive the re-bootstrapLukasz Kasprzak2026-08-122-8/+60
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Neither of adjustments.sexp's two directives is a no-op after the regeneration, and neither is removed -- reasoned through deliberately rather than deleted on sight, per Overlay.apply's own documented diagnostic behaviour (Edit has no "already correct" case; it unconditionally folds every field_edit over the current value when the slug is present, no diagnostic either way). `Edit most-holy-name-of-mary (Set_subject Bvm)`: the base bootstrap no longer needs this correction (the source dropped `class = lord` for this slug, so the default is already Subject.Saint), but the overlay still forces `Saint -> Bvm`. Kept for two reasons: data precision (the calendarium's "Sanctissimi Nominis Mariae" title still argues for Bvm over the generic Saint default, independent of what lectio's class field says) and as a regression guard (Set_subject is unconditional, so it would also correct a future re-introduction of `class = lord` for this slug, the one subject value RG16(a) behaviourally reads). `Suppress vigil-of-christmas`: re-verified, not assumed -- the slug is still present, unchanged, in both the regenerated source and the regenerated sanctoral.sexp, so the directive still fires its ordinary slug-present path. test_rite_ef.ml's own comment on the overlay-in-effect test previously claimed the base file carries `subject Lord` for most-holy-name-of-mary, which the regeneration made false; corrected in place rather than left stale, per this project's own discipline around wrong claims.
| * data(ef): re-bootstrap sanctoral.sexp from the corrected lectio sourceLukasz Kasprzak2026-08-122-37/+74
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Regenerated via tools/bootstrap_sanctoral.ml against lectio's tridentine-calendar.ini (SHA-256 6a25e634... -> 1b303ef2...), whose own generator was independently fixed in a concurrent session. 327 entries (223 feast, 104 commemoration-only), up from 322 (208/114): - 15 entries wrongly bootstrapped `rank = commemoration` are now `class-3` (a real III-class Feast) -- all 6 March-5 April, all primary-source-verified against the calendarium (register's own "Commemoration-only entries' inferred STATUS" item). - 5 new entries: agnes-secundo (28 Jan), boniface-martyr (14 May), eusebius-confessor (14 Aug), evaristus (26 Oct), theodore (9 Nov) -- all Commemoration_only, all primary-source-verified (register's "Four confirmed sanctoral DATA GAPS" item + expected-divergences-missalemeum .sexp's former M4/M6/M7/M9/M14). - commemoration-of-the-baptism-of-the-lord (13 Jan) is now `(subject Lord)` (the source's own `class` field, not a colitur overlay); most-holy-name-of-mary (12 Sep) no longer carries `class = lord` at all (the source dropped it), so the bootstrap default (Subject.Saint) is now correct there without help from adjustments.sexp's own Edit. test_sanctoral_ef.ml's pinned counts (327/104/12 Class1) are re-derived directly from the source INI (`grep -c '^\['`, `grep '^rank' | sort | uniq -c`), not transcribed from a bootstrap-tool or `colitur day` run. data/ef/adjustments.sexp and the differential/oracle allow-lists still need updating for the consequences of this regeneration -- follow-up commits.
| * tools(bootstrap_sanctoral): name.pl is optional, not requiredLukasz Kasprzak2026-08-121-2/+17
|/ | | | | | | | | | | | | | | | | lectio's regenerated tridentine-calendar.ini (the fix that corrects the 15-entry rank cluster and adds the 5 missing entries this branch re-bootstraps from) has 5 entries with no name.pl field at all (agnes-secundo, boniface-martyr, eusebius-confessor, evaristus, theodore -- all either newly added or newly un-hidden). parse_names previously required name.pl unconditionally (`field sec "name.pl"`, which dies on absence) -- correct for a source that always had it, wrong now that it legitimately does not. Names.t is an open, per-language assoc list (names.mli) with no rule that every entry must carry every language colitur happens to know about, so requiring pl here was this tool's own invented constraint, not a kernel one. Falls back to an en-only Names.t when pl is absent, never a placeholder string.
* Merge branch 'ef-rg16a': RG 16(a), RG 111(b), RG 113, and commemoration identityLukasz Kasprzak2026-08-1221-982/+2440
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Closes the largest known-wrong-output item on record (RG 16(a): a Feast of the Lord occurring on a II-class Sunday leaves the Sunday uncommemorated -- 5996 wrong days over 1583-9999) together with RG 111(b)'s rank floor on the day it holds, and gives the oracle layer the ability to compare commemoration identity rather than only presence and count. Also corrects a methodological defect that had produced wrong rulings in both this project and its sibling: docs/research/ holds an electronic transcription alongside two photographic scans, and the transcription silently drops commemoration lines -- seven across the year. Reasoning from its silence had convicted the oracle wrongly on 14 August and ruled a genuine 9 August commemoration spurious. The scans are the primary source; the rule is now recorded at the top of the register. RG 113 replaces an alphabetical same-rank tie-break that had no rubrical warrant. A bare Commemoratio has no row in RG 91's table at all, so band no longer hands one the entry of a III-class universal feast: 4451 days, all four reordered pairs verified against a photographic scan, zero observed-day changes.