aboutsummaryrefslogtreecommitdiff
path: root/data/ef/expected-divergences.sexp
Commit message (Collapse)AuthorAgeFilesLines
* test(differential): fix round 2 -- Good Friday, Passion Tuesday, stale headerLukasz Kasprzak2026-08-151-29/+40
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Critical, and worse than what it replaced: removing a lectionary key does not mean "no reading" to Lectionary_ef.readings -- it means step 3 silently resumes the preceding Sunday. Good Friday, which has no Mass at all, was emitting Palm Sunday's own Epistle and Passion narrative every year; Holy Wednesday had the same defect. Fixed by authoring both days fully: the Gospel was always unambiguous and is now always authored; the Epistle uses the same "last lesson before the Gospel" convention this file's own Lenten Ember Wednesday entry already established for an identical two-peer-lesson shape, applied for consistency rather than invented to close this gap. C24 is retired, folded into a widened C23 covering all six Holy Week days. Important: Passion Tuesday was shipping Holy Tuesday's Mass, a defect the previous round's own footnote had found and left unrecorded. Fixed at the source -- colitur_keys now excludes lectio's own (wrong) ini section for this one weekday rather than translating it; a new passion_tuesday_entry hand-authors the real Missal citation (Dan 14:27, 28-42 / John 7:1-13, both scans). New entry C26 records the resulting divergence, 43 of 46 years, traced (not merely counted) to three years where a competing I-class feast impedes the day entirely. Important: the allow-list header was stale one level up, still naming and restating the diagnosis of an id (C21) retired in the previous round. Rewritten in full rather than layered with another correction. Minors: all three Lent Ember values now pinned (only Wednesday was before); C22's citation corrected to attribute the date-anchor text and the rank text to their own separate sources; assert_reachable's own comment no longer overclaims what it can catch; C25's falsified reasoning replaced with the directly observed fact (a first replacement derivation was itself found wrong on a second reading and is recorded as rejected, not silently discarded); hand-authored citations standardised to English book names with a colon, matching this file's own dominant convention, with one stated exception where a value must stay byte-identical to lectio's own data rather than be reformatted. dune test: 358/358. COLITUR_EXHAUSTIVE_SWEEP=1 dune test --force: 359/359.
* test(differential): fix round 1 -- Holy Week, Lent Ember, RG 69Lukasz Kasprzak2026-08-151-13/+44
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Two Critical findings, both real: Holy Week (including the entire Sacred Triduum) was reading Passion Week's Masses -- the original colitur_keys widened lectio's single, conflated ini section into both weeks instead of Passion week alone. Narrowed to Passion week only; Holy Week's own four cleanest days (Monday, Tuesday, Thursday, Saturday) are hand-authored directly from the Missal, verified twice against both scans (C23); Holy Wednesday and Good Friday are genuinely multi-lesson liturgies with no single Epistle slot and are deliberately left unanswered, not guessed (C24). The Lenten Ember days were still dead keys: Temporal_ef computes ef-lent-ember-{wed,fri,sat}, lectio's ini names the same data ef-lent-1-{wednesday,friday,saturday}, and colitur_keys never translated it -- both engines independently fell through to the same wrong ferial answer, so even the differential stayed green (C22, a genuine lectio bug recorded for upstream). Fixed the instance and the class: colitur_keys gained the rename, and tools/bootstrap_lectionary.ml gained assert_reachable, sweeping Rite_ef.Temporal_ef.temporal at generation time so a translation table entry naming a slug colitur never computes dies loudly instead of shipping silently, plus an informational log of every real slug with no entry at all. C21 ("colitur's step 3 cannot reach a correct answer for the fixed Christmastide slugs") is retired, superseded rather than merely patched: the Nativity-Octave days now have their own direct Missal formulary (Tit. 3,4-7/Luc. 2,15-20, "Diebus infra octavam Nativitatis Domini"), resolved at step 2, not step 3 at all. That surfaced a real RG 69 gap underneath it: a Sunday landing 26-31 December should keep its own Office, not the fixed weekday placeholder, which Temporal_ef does not currently distinguish. C6's verdict is re-opened (open, not colitur) for the 19 of its 138 rows where this applies directly, and a new entry C25 (57 rows) records the same gap propagating one hop further through step 3 into Holy Name week. Both are out of this task's own scope -- a behaviour change to a shared, multi-round-reviewed kernel-adjacent function -- and recorded, not fixed, per the coordinator's own instruction. C6's own note is rewritten in full rather than layered with another correction; C18's stale trailing count is fixed to match its own pin; the Vigil-misapplication risk flagged as a Minor closed itself once the Nativity-Octave fix landed, confirmed by inspection rather than assumed. dune test: 358/358. COLITUR_EXHAUSTIVE_SWEEP=1 dune test --force: 359/359.
* test(differential): compare reading citations, 16 801 daysLukasz Kasprzak2026-08-151-7/+50
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Layer 3 is NOT blind to the ferial resumption rule, unusually for this project: lectio implements the same rubric independently, so the differential checks colitur's rule against a second implementation rather than against silence. It IS blind to the Commons -- lectio has no such concept -- so chain step 4 rests on layer 4 alone. Divergence triage, 1 532 of 16 801 days differ (15 269 match exactly), 0 unexplained: - A genuine colitur bug found and fixed: data/ef/lectionary.sexp carried lectio's own ini section names verbatim, never translated into the slugs Temporal_ef actually computes for the identical office. Data the bootstrap already held (Passiontide both weeks, the Pentecost Ember days, Holy Name Sunday) was unreachable by chain step 2, silently falling through to a wrong step-3 answer -- invisible until citation content became comparable. tools/bootstrap_lectionary.ml gained colitur_keys (rename/widen), a hand-authored ef-nativity-vigil entry cross-sourced from lectio's own sanctoral calendar and corroborated by colitur's own (overlay-suppressed) sanctoral bootstrap of the same source, and a derived ef-holy-name entry (RG 17(a)'s single Mass heading covers both the Sunday and 2-January shapes). One guess (giving the fixed Nativity-Octave days Holy Name Sunday's own citation uniformly) was tried and reverted once measured against the fixture -- Missal-verified to be right only for the genuine "Sunday within the Octave" case, wrong whenever the true preceding Sunday is Christmas Day or Advent IV instead. - 10 existing/widened Layer C entries (C1/C6/C8/C14/C15/C16/C17/C18 -- C6 and C17 narrowed with the removed population accounted for, not silently re-absorbed) plus two new ones: C19 (the already-adjudicated Time-after-Epiphany week-numbering offset, now visible in citation content), C20 (lectio computes no reading at all for the seven readingless saints Task 6 gave a Common or proper -- colitur is more complete, not wrong). - One entry, C21, is a genuine colitur LOGIC limitation found but not fixed: Lectionary_ef.readings' step 3 is a single hop to the preceding Sunday, insufficient for a run of colitur-only fixed Christmastide slugs whose own preceding Sunday is itself another entry-less fixed slug. Recorded verdict open (data/ef/expected-divergences-missalemeum.sexp's own established precedent for this shape), not left silently failing -- fully diagnosed in task-8-report.md, recommended as a dedicated follow-up task rather than a hasty fix to a shared, multi-round-reviewed kernel-adjacent function.
* fix(ef): three colour corrections that contradicted the Missal by nameLukasz Kasprzak2026-08-141-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The sanctoral audit set chair-of-st-peter (22 Feb), conversion-of-st-paul (25 Jan) and peter (25 Jan, commemoration) to Red on RG 124(b). All three are reverted to White. RG 120(f), fifteen lines above RG 124(b) in the same column of the same page, names two of them in its enumeration of white: "Cathedrae S. Petri (22 februarii); Conversionis S. Pauli (25 ianuarii)". RG 124(b)'s own qualifier "in eorum die natalicio" independently excludes them, and RG 475(e) confirms it a third time by naming the Chair separately from "natalician feasts of Apostles". lectio and missalemeum both said white because both were right. peter rested on "match the host day's Red", whose host is white by that same clause, so the precedent inverts. Root cause: the audit's page-image method, its real advance, was applied to the calendarium and not to the rubric. RG 124 was read from the OCR text layer, where the two-column interleave shreds RG 120(f) across rows belonging to RG 115 and hyphen-splits Cathedrae, so a text-layer grep for it returns nothing while RG 124's enumeration survives cleanly. That read finds 124 and structurally cannot find 120(f). Two sentinels had been reporting this correctly and were overridden. The golden pin at 1902-02-22 asserted colour=white, was changed to red, and had its comment rewritten to guard against "a regression back to the old one" -- the only pin asserting a colour for any of the 21 slugs. And C18 and M21 both listed the two slugs under an RG 124(b) citation where both oracles were right. Pin restored; slugs dropped; C18 re-derived 526->450 from the observed-day counts, M21 20->18, M15 17->18. The audit's own discriminator would have isolated these. Its stated corroboration was that lectio's name.pl contradicts lectio's colour; run as a gate across all 21 that splits 17 genuine defects from 4 needing adjudication, and three of those four are these. It was quoted as illustration rather than used as a gate. 18 of 21 corrections stand, and the twelve whites are recited to RG 120(e) "Sanctorum non Martyrum" rather than to RG 117's negative residual. Also records Anastasia's deliberate non-fix in the tracked tree beside barbara, where the next auditor will be standing.
* data(ef): sanctoral audit — one genuine gap, 21 wrong colours (RG124)Lukasz Kasprzak2026-08-141-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Full re-extraction of the primary CALENDARIUM (both photographic scans, missale-romanum-1962.pdf and Missale Romanum 1962_text.pdf, rendered page images read directly rather than trusting either PDF's own OCR text layer) against all 327 base sanctoral entries plus the two prior overlay Adds. Both scans agree throughout; no OCR ambiguity required adjudication this round. Add `barbara` (4 December): both scans carry a Commemoratio nested under Peter Chrysologus's own entry, absent from data/ef/sanctoral.sexp AND from lectio's own tridentine-calendar.ini (confirmed directly) — the same upstream-gap shape as the five entries the ef-rebootstrap task already added (agnes-secundo/boniface-martyr/eusebius-confessor/evaristus/ theodore). Correct 21 sanctoral colours against RG 124 ("De coloribus paramentorum"), scan-verified word for word: 124(b) red for an Apostle/Evangelist's own feast day except John's (27 December, already correct); 124(e) red for a Martyr's own martyrdom; RG 117's five-colour residual otherwise white. Every one of the 21 is a confirmed lectio/missalemeum bootstrap defect — checked individually against lectio's own ini, several of whose Polish name fields already contradict that same record's own colour tag (e.g. `martha`: "Dziewicy", Virgin, no "Męczennicy", yet `colour = red`) — the identical root cause and mechanism the `eusebius-confessor` fix already established. Colour is confirmed read nowhere in Precedence_ef's resolution logic (grep), so these are output-correctness fixes with zero observed-office blast radius; three (apollinaris/josaphat/chair-of-st- peter) additionally disagree with missalemeum's own oracle, not only with lectio, so they are adjudicated from RG 124's text directly rather than by which engine happens to agree. Both corrections applied via data/ef/adjustments.sexp's established Overlay mechanism (data/ef/sanctoral.sexp stays generated, untouched). Pinned: test_rite_ef.ml (two new tests, verified to fail against the pre-fix data); test_differential.ml's new C18 predicate (526 rows, 2005-2050) and test_oracle.ml's new M21/M22 predicates (20 + 2 rows, 2026-2027), each with data/ef/expected-divergences{,-missalemeum}.sexp entries citing RG124 or the matching upstream-gap precedent; test_golden.ml's 1902-02-22 pin corrected (chair-of-st-peter was white in the stale pin, RG124(b) makes it red). All 329 tests green, including the full 1583-9999 exhaustive sweep. Full method, per-entry adjudication table and corrected bucket counts: docs/research/rules-register.md (gitignored) and .superpowers/sdd/2026-08-12-colitur-rg16a/sanctoral-audit-report.md (gitignored).
* docs: an invented Caput, a list that was not closed, and a blind spotLukasz Kasprzak2026-08-131-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Three corrections from the fix-round re-review, none changing behaviour. RG 431(e) was attributed to "Caput XX, De hymno Gloria in excelsis". There is no Caput XX -- the Rubricae Generales' Caput series ends at XIX. The paragraph number, letter and subsection title were all right; only the containing division was invented. It sits under "VIII -- De diversis Missae partibus", subsection "C) De hymno Gloria in excelsis". Shipping a new invented structural citation in the very round that corrected a source-fidelity overclaim is what the gate exists to catch. marian_slugs claimed TWO entries found and deliberately excluded after individual consideration, "not merely omitted". There was a third: vigil-of-the-assumption, 14 August, which is de B. Maria Virg. and whose collect implores her protection. It was merely omitted. Added to the list -- behaviourally inert, verified: it wins 7196 times domain-wide, always with the non-Marian eusebius-confessor as its only commemoration, and never loses -- but a closed list's whole value is its enumeration claim, and that claim was false as written. And the new rule has no comparison-layer witness at all. Reverting it reddens three tests, none of them a comparison layer: the differential's row type carries no commemorations, and the oracle's window has no 16-July Saturday. Worse, lectio's fixture DOES carry commemorations and prints +our-lady-of-mt-carmel on all 8 in-window dates where colitur now prints nothing -- a real divergence, neither fixed nor cited, swallowed by a blind spot, which binding decision 1 forbids. Recorded, with the note that colitur's reading here has no reference confirmation anywhere and only extending the oracle fixture to 2033 or later would settle it. Also records the RG 112(d) branch's ordering constraint: it precedes RG 95's Transfer branch, which it does not need to, and must move below it if a Class1 Marian entry is ever added.
* data(ef): close and derive the RG 91 entry 27 allow-list rowsLukasz Kasprzak2026-08-131-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* temporal(ef): Holy Name of Jesus, RG 17(a) -- fallback + Lord subjectLukasz Kasprzak2026-08-131-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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").
* 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(differential): split the Holy Family/Baptism collision out of C1 (C15)Lukasz Kasprzak2026-08-131-2/+7
| | | | | | | | | | | | | | | | | | | | | | | 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.
* test(differential): refresh the lectio fixture, close 9 entries, add C14Lukasz Kasprzak2026-08-121-53/+33
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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(differential): fix round 1 (F2, F5) -- split 13-Jan-Sunday into C13Lukasz Kasprzak2026-08-121-3/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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(differential): allow-list C12 for the 15-entry rank correctionLukasz Kasprzak2026-08-121-0/+5
| | | | | | | | | | | | | | | | | | | | | | | 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.
* docs(citations): migrate register line-number pointers to stable anchorsLukasz Kasprzak2026-08-121-5/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 68 "register line N" pointers in tracked code and data cited the register's line numbers directly. The register has moved since: line 334 (cited six times as RG 91 entry 8) is now rose/colour prose; lines 375-376 (cited as "RG 109 leaves Advent/Lent Ember ordinary") are now RG 26, the paragraph that refutes that exact reading; line 374 (cited as RG 109(a)) is now RG 25's Latin; line 378 (RG 111) is blank. expected-divergences.sexp even wrote "RG 91 line 332" three times, as though the line offset were part of the rubric's own identity. Since docs/research/rules-register.md is gitignored, no reader of the public repo could resolve any of these, and -- since the register has moved on its own copy too -- neither can the author's. Replaced every pointer with an anchor that survives editing: the RG paragraph/entry number itself (already present in nearly every case, since the citation text already names "RG 91 entry N" or "RG 109(a)" next to the stale line number -- the line number was redundant, not load-bearing) plus a "§4" or quoted-subsection-heading pointer into the register for readers who want to locate the fuller discussion. Also corrected one genuinely stale content error found while migrating its anchor: test_precedence_ef.ml's RG33 disposition-cases comment still said "a I/II-class vigil impeded by any Sunday" -- the pre-Task-16 mistranscription the register itself corrects to II/III class; fixed the prose alongside its citation, since leaving a wrong RG-class claim next to a freshly-verified anchor would be worse than the stale line number it replaced. Covers lib/rites/rite_ef/precedence_ef.ml (18), precedence_ef.mli (already fixed with item 1), test/test_precedence_ef.ml (44, including two instances that only word-wrapped "register\nline N" across a line break and so did not match a same-line grep), and data/ef/expected-divergences.sexp (5, including three "RG 91 line 332" instances). All 68 original pointers resolved -- none needed guessing; every citation's target rule was already named in the surrounding prose. No behaviour change: every edit is a comment/citation/data-note change. Verified byte-identical `colitur day` output across 1583, 1900, 1902, 2008, 2011, 2026, 2038, 9999. 259/259 tests green.
* kernel(temporal): Holy Thursday is white, per RG128(b)'s named exceptionLukasz Kasprzak2026-08-121-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | RG 128(b) excepts "Missa sive Chrismatis sive in Cena Domini feria V Hebdomadae sanctae" from the Septuagesima-to-Easter-Vigil violet span as a whole-Mass exception (unlike Palm Sunday's blessing/procession, which the same sentence carves out as only part of that day) -- so Holy Thursday's Mass is white, not violet. temporal_ef.ml fell through to the generic Passiontide ferial path (season_colour Passiontide = violet) for this date, since [named] has no entry for the Triduum at all (rank was already correct via [privileged_feria]; only colour was wrong). Found via Task 16's missalemeum oracle comparison: every other Triduum day's oracle colour set includes violet as an option (Good Friday "bv", Holy Saturday "vw" -- already-flagged, deliberately deferred per-action gaps, register §3b), but Holy Thursday's is white alone. This is a genuine NEW divergence from lectio too (lectio has no such exception and still prints violet for Holy Thursday) -- added as Layer C11 to the differential harness and data/ef/expected-divergences .sexp, 46 rows (2005-2050), rather than silently changing what that harness accepts. Also corrected a stale comment on season_colour claiming white's RG paragraph was never pinned -- RG 119 was found and cited in the register on 2026-08-11 but the correction was never copied into this file's own comment.
* test: differential vs lectio 2005-2050 with a cited allow-listLukasz Kasprzak2026-08-121-0/+69
Validation layer 3 (design spec's five): compares colitur's real day-by-day EF output against lectio (sibling project, Go), 2005-2050, one line per civil day. Of 16801 day-pairs, 11206 already agree on the seven leading columns; the 5595 that don't resolve into exactly 25 distinct field-diff signatures, all triaged. Three strictly separate layers, per the controller's ruling (the brief's single flat allow-list assumed a handful of differences, not 5595): - Layer A (test_differential.ml, norm_season/norm_slug): vocabulary. An explicit, closed table of naming synonyms with no liturgical substance (lectio's easter/christmas vs colitur's paschaltide/christmastide; a handful of slugs that are two names for the identical office). No wildcards -- every entry is a literal string pair. - Layer B (strip_epiphany_index): numbering. The one slug family whose lectio/colitur index offset is not a constant (Time-after-Epiphany week numbering, register 3c#5) has its embedded digit stripped to a common form on both sides before comparing; rank and colour stay fully compared. - Layer C (data/ef/expected-divergences.sexp): the cited allow-list. Ten genuine liturgical disagreements, each citing its RG paragraph and naming which engine is right (always colitur, verified against the Missal/register, never against lectio's own behaviour). This is the only layer permitted to cover a difference in rank, colour, or which celebration is observed. Five extend or restate register 3c's already- documented divergences (season boundary, Sunday I-class, Advent Ember ferias, Rogations); five are new, found and adjudicated in this task (Lent Ember days, the Nativity Octave, Ember-day-vs-saint precedence, the St Joseph transfer off a Lent Sunday, and the 2011 Sacred Heart / Precious Blood / Visitation collision). expected_rows on each entry is an exact regression pin, asserted by the test, not documentation. 13 January (register 6's long-open "Baptism of the Lord" item) is confirmed empirically fixed already -- Task 11's sanctoral wiring closed it before this task started -- so it is not allow-listed; the only residual difference there is the season boundary already covered by C1. Two stated limits carried from the brief (commemorations are not comparable; lectio's own EF oracle asserts season only, 2025-2026 only, so a rank/colour difference is not presumptive evidence against colitur) plus a third found during this task (the week column is a display convention on both sides, not a liturgical fact, and is not compared at all) are documented in the test file's own doc comment. Fixture: test/fixtures/lectio-ef-2005-2050.txt, committed as plain text (1.4 MB), generated by lectio commit 2386a45; provenance recorded in the sibling .provenance file. Colitur's side is recomputed fresh from the library on every run, through the same Calendar/Rite_ef pipeline `colitur day` uses, not the compiled binary. Proved the harness has teeth by two reverted perturbations: a genuine colour difference injected into a fully-covered fixture row fails the "no unexplained differences" check with the exact mismatched row printed; a one-row drift in an allow-list entry's expected_rows fails the count check independently, showing it is not merely a duplicate of the first assertion. 236/236 tests green, clean-build verified, deterministic across OCAMLRUNPARAM=R.