aboutsummaryrefslogtreecommitdiff
path: root/lib/rites/rite_of/precedence_of.ml
Commit message (Collapse)AuthorAgeFilesLines
* fix(of): correct subject over-match, provenance truth, and stale hazard commentLukasz Kasprzak2026-08-251-19/+38
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Four fixes from fix round 2 review: classify_subject's "maria"/"b.m.v" substring test over-matched 12 saints who merely carry "Maria" in their own name (Maximilian Mary Kolbe, John Mary Vianney, Mary Magdalene among them) as Bvm. Replaced with an explicit BVM_DATES table of the 13 genuinely Marian entries. Bvm 25 -> 13. The provenance header claimed lectio is "never a source", which omitted that slugs and English names both come from it. Corrected to state exactly what does (slugs, en names) and does not (every substantive field) come from lectio. A missing lectio file used to degrade silently to a different SHA-256 with no en names and no warning; it now fails loudly. lectio's own SHA-256 is now pinned alongside the Missal PDF's. Four more entries carried a second pdftotext artifact distinct from the letter-spacing already handled -- a combining diacritic rendered as a stray spacing character (Kim Taegŏn/Chŏng Ha-sang, Đũng Lạc, Makhlūf, Kęty). Hand-repaired the same way Peter Damian was, each corroborated by the identical corruption recurring in the Missal's own index. precedence_of.ml's PHASE 3 HAZARD comment about All Souls (2 November) was asserting a gap that no longer exists now that OF sanctoral data ships. Added test_all_souls_beats_an_ordinary_sunday, which resolves the shipped All Souls entry against a real per-annum Sunday (2025-11-02) through the actual Precedence.resolve pipeline, and updated the comment to record the resolution instead of demanding it.
* fix(of): correct season citation, note All Souls gap, guard transfer searchLukasz Kasprzak2026-08-251-14/+70
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fix wave from the final whole-branch review of OF Phase 2 (0 Critical, 5 Important, 8 Minor). Applies the five items ruled in-scope and records two more, per the controller's R7/R8/R9 rulings. Fixes: - temporal_of.ml: season-boundary header cited "Normae n. 71-77", a range that does not exist (the Normae end at n. 61) and collides with real IGMR nn. 71-77 (Preparation of the Gifts) in the same PDF -- EF leakage from RG 71-77. Corrected to Normae Titulus II, nn. 17-47, with a note against reintroducing the wrong range. - precedence_of.ml entry 3: added the Tabula's second clause (Commemoratio omnium fidelium defunctorum / All Souls) to the comment, and recorded the Phase 3 hazard -- Vocab_of.rank has no constructor for it yet, and every natural tagging choice gets 2 November's precedence wrong in a different way. No code change; nothing can construct the entity yet. - precedence_of.ml transfer_target's search: added a domain_max_date guard (following Rite_ef.Precedence_ef's existing shape and reasoning) so the walk can no longer probe Computus past 9999-12-31, and it now returns the last date visited on bound exhaustion instead of failwith-ing. .mli updated to drop the @raise Failure clause. - precedence_of.ml is_privileged_sunday: added its own inline Tabula I.2 citation, matching its sibling helpers. - precedence_of.ml entry 10: trimmed the reused "universal or temporal-origin" comment -- Temporal_of never constructs a Memoria_obligatoria candidate, so the temporal-origin half was vacuous there. Recorded without fixing (both comment-only, per explicit scope ruling): - test_precedence_of.ml: corrected the entry-3 Nativity Vigil test's characterisation. The pinned band-30 assertion (2026-12-24, a Thursday) is correct, but is not the value on a 24-December Sunday (e.g. 2028, 2034), where is_privileged_sunday instead bands the same candidate 20. Named the underlying Phase 1 defect this exposes -- named() claims 24 December unconditionally and is matched before sunday_slug, so the Fourth Sunday of Advent gets no office at all in those years, invisible to the litcal layer -- as known and carried to the next task. - precedence_of.mli transfer_target: documented Normae n. 56(f) (St Joseph on Palm Sunday anticipates backward to 18 March) as a known, cited, unimplemented fourth transfer rule, and named the underlying kernel constraint (Rite.t.transfer_target's strictly-later obligation, justified only by the EF's RG 96) as the reason a real fix needs a kernel change. dune test: 799 tests, exit 0. make check (exhaustive sweep): 805 tests, exit 0, 224.7s. No kernel/rite_ef/data changes (git diff empty).
* feat(of): transfer_target per Normae nn. 5 and 60Lukasz Kasprzak2026-08-251-0/+90
| | | | | | | | | | | | | | | | Three rules, in priority order: the Annunciation in Holy Week goes to Easter+8; any other solemnity on a Sunday of Advent, Lent or Easter goes to the following Monday (n. 5, which n. 60 defers to explicitly), except on Palm Sunday or Easter Sunday; otherwise the nearest later day free of Tabula entries 1-8. The n. 5 Monday rule is easy to miss -- n. 60 names it only by cross reference, and reading n. 60 alone yields a single search rule where the sources give three. Shaped to match Rite.t.transfer_target so a later phase wires it unchanged, with its own step bound: Calendar's round guard bounds rounds, not one call's internal search.
* fix(of): correct vigil_feast's justification for of-nativity-vigilLukasz Kasprzak2026-08-251-6/+20
| | | | | | | | | | | | | | | | | | | | The prior comment claimed of-nativity-vigil is 'not a distinct celebration' - wrong: Temporal_of.named (temporal_of.ml:230) constructs it as its own Sollemnitas-rank candidate on 24 December, a genuine contestant in band/Precedence.resolve. The real reason None is safe is structural, not that. The Nativity is Tabula entry 2 (band 20); only entry 1, the Paschal Triduum (band 10), bands lower. The Triduum's Easter-2..Easter window is confined to 20 March-25 April because Gregorian Easter never falls outside [22 March, 25 April] over the whole 1583-9999 domain (measured exhaustively in test_computus.ml, not assumed), so it can never reach 25 December. The Nativity therefore always keeps its own day and its vigil can never be orphaned by a transfer or reduction. Behaviour is unchanged: vigil_feast still returns None unconditionally. RG 33 (EF-only) and Normae nn. 11/13 remain the reason the hook exists at all and returns None for every other candidate.
* feat(of): admit and vigil_feast, both argued degenerateLukasz Kasprzak2026-08-251-0/+40
| | | | | | | | | | admit returns the empty list because disposition never returns Commemorate; vigil_feast returns None because the OF has no vigil office that its feast's movement could orphan -- 'of-nativity-vigil' is a Mass formulary of the solemnity, not a separate celebration. Both are argued from the sources rather than stubbed, and Precedence_of.rules now assembles the four functions the kernel resolver consumes.
* feat(of): disposition per Normae n. 60Lukasz Kasprzak2026-08-251-0/+32
| | | | | | | | | | An impeded solemnity transfers; every other loser is omitted for that year ('Reliquae celebrationes eo anno omittuntur'). Commemorate is never returned, and that is the rule rather than a gap: the OF has no commemoration of a losing celebration in the EF's sense, and an optional memorial is an election rather than a commemoration. A property over every rank pairing asserts it, so a later edit cannot quietly introduce one.
* feat(of): transcribe Tabula part III, completing the tableLukasz Kasprzak2026-08-251-0/+18
| | | | | | | | | | | | | | | | Entries 10-13. Entry 12 is one undivided row -- the Tabula draws no universal/proper split for optional memorials, unlike entries 3/4, 7/8 and 10/11 -- so it deliberately does not read the layer. Entry 13's four clauses need no date arithmetic of their own: every privileged feria is entries 2 and 9, tested earlier in the chain, so what reaches the final branch is exactly the residue those clauses name. Entry 10 uses [not (is_proper layer)], not the brief's original [is_universal layer]: is_universal was deleted as dead code in Task 2, because every temporal-origin candidate carries layer = "temporal", never universal_layer, so a positive is_universal test can never match one -- the same correction entries 3, 5 and 7 already apply.
* feat(of): transcribe Tabula part II into precedence_ofLukasz Kasprzak2026-08-251-4/+59
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Entries 5-9. Entries 5 and 7 differ only by subject -- 'Festa Domini' against 'Festa beatae Mariae Virginis et Sanctorum' -- so they key on Celebration.t.subject, the same field RG 91 entry 14 uses on the EF side, never on the slug. Entry 9's three clauses (late-Advent ferias from 17 December, the Nativity octave, Lenten ferias) are what separates a privileged feria from the ordinary one at entry 13. CORRECTION to the task brief, applied here rather than after: entries 3, 5 and 7 test 'not (is_proper layer)', not 'is_universal layer'. Every temporal-origin candidate Temporal_of.temporal constructs carries layer = "temporal" unconditionally, never universal_layer, so a positive universal-layer test silently excluded every temporal-cycle solemnity and Lord-subject feast from these entries -- Corpus Christi came out unclassified outright, and Trinity/Christ the King/Holy Family/the Baptism of the Lord landed one entry too low. is_universal is now dead and removed; entry 3's branch (written in Task 1) is amended along with the new entries 5 and 7. Only entries 4 and 8 still test is_proper directly, matching the Tabula's own proper-calendar rows. Also fixes a pre-existing typo in the brief's own 'entry 6: a Sunday per annum' test row: rank was Sollemnitas, which -- being tested at entry 3, earlier in the chain -- made the row fail regardless of the is_universal/is_proper question, since no real Sunday per annum is ever Sollemnitas. Changed to Festum, matching the adjacent 'Sunday of Christmas time' row and real Temporal_of output.
* feat(of): transcribe Tabula part I into precedence_ofLukasz Kasprzak2026-08-251-0/+97
The Tabula dierum liturgicorum's entries 1-4, one band branch each, scaled x10 as Precedence_ef's own table is. The Triduum is identified structurally by Easter offset because Temporal_of emits Good Friday and Holy Saturday as ordinary Lent week-6 ferias, leaving no slug to key on. Holy Thursday sits at entry 2, not entry 1: the Tabula's own entry 2 runs 'a feria II ad feriam V inclusive' and the Triduum opens with an evening Mass inside that civil day. Same granularity decision the litcal layer's L1 records on the season axis.