aboutsummaryrefslogtreecommitdiff
path: root/data/ef
Commit message (Collapse)AuthorAgeFilesLines
* test(differential): C14 and C15 closed -- only slug vocabulary remainsLukasz Kasprzak2026-08-181-10/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | lectio adopted the last two Missal corrections colitur argued: C14 3 -> 0 RG 96(a)/97/98. lectio resolved each impeded I-class feast's transfer independently, so in 2008, 2035 and 2046 St Joseph and the Annunciation both walked onto the Monday after Low Sunday and Joseph, losing there, was observed on no day of those years at all. It now resolves the year's transfers as a set: the Annunciation takes the Monday as its sedes propria, Joseph the Tuesday. C15 7 -> 0 The Holy Family propers' own 13-January rubric, "sine commemoratione Baptismatis D.N.I.C.". lectio kept the Baptism as the observed office on all seven such years in 2005-2050. Those were the last two BEHAVIOUR classes. What is left is C1 (138) and C6 (119), both pure slug vocabulary. Measured across the whole fixture, applying only the season normalisation the test already applies: 579 of 16801 days differ, and every one of them differs on the SLUG ALONE. Zero days differ on season, rank, colour, Epistle or Gospel. (The test's own norm_slug table already maps 322 of the 579; the 257 left are C1 and C6. The field profile is the same either way.) So the two engines now agree on every liturgically meaningful field on every day of 2005-2050. The residue is what the two projects call things -- ef-christmas-2-friday against ef-time-after-epiphany-1-friday for the same day, same Mass. Aligning it means renaming lectio's slugs, and those are keys: its lectionary, clectio's generated tables and any user overlay are built on them. Left as vocabulary rather than forced. Fixture refreshed against lectio e713da2; 13 rows changed, colitur agrees with all of them. 24 divergence classes at the start of this work, 2 now.
* test(differential): C31 closed -- 4 classes left, 257 of 267 rows are namingLukasz Kasprzak2026-08-181-7/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | The ferias between Epiphany and the first Sunday after it repeat Epiphany's own Mass in lectio now; they had been taking the Mass of the Sunday that follows them. C31 98 -> 0 C1 40 -> 138 grew, and changed character C1 is now SLUG VOCABULARY ONLY, and its note says so. Season, rank, colour and both citations agree with colitur on every day of the January window; what differs is the identifier -- ef-christmas-2-thursday against ef-time-after-epiphany-1-thursday for the same day with the same Mass. C6 is the same shape. That is 257 of the 267 remaining rows. Aligning the vocabularies would mean renaming lectio's slugs, and those are keys: its own lectionary, clectio's generated tables and any user overlay are built on them. Recorded as vocabulary rather than closed, because the rows do differ -- just not in anything a reader of either engine's output sees. Measured for 2026: season, rank and colour agree on all 365 days; 14 days differ and every one differs on the slug alone. 5 classes -> 4, agreement 98.4%.
* test(differential): C20 and C38 closed -- agreement 98.4%Lukasz Kasprzak2026-08-181-29/+10
| | | | | | | | | | | | | | | | lectio carries the readings of the nine Common-routed saints and of three more that had proper Masses but no reading at all. Every day of 2005-2050 now resolves a reading there; four days used to come back empty. C38's own note said it could not close without lectio gaining a Commons concept. The readings arrived instead of the abstraction, which was enough: each Common resolves to one first/gospel pair for the saint that names it, so a table plus assignment layer would have bought indirection and nothing else. C20 14 -> 0 C38 70 -> 0 7 classes -> 5, 351 rows -> 267, agreement 97.9% -> 98.4%.
* test(differential): seven classes closed -- agreement 93.9% to 97.1%Lukasz Kasprzak2026-08-181-44/+18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | lectio gained the Passiontide week split and thirteen lectionary entries. C23 230 -> 0 Holy Week's own six Masses C32 99 -> 0 C35 60 -> 0 the first weeks after Epiphany and Pentecost (RG 299) C33 46 -> 0 Corpus Christi C34 46 -> 0 the Sacred Heart C26 43 -> 0 Passion Tuesday C19 7 -> 0 the Holy Family week-index residue C1 75 -> 40 C31 63 -> 98 GREW The Passiontide split is the one that carried most of this. efWeek had no Passiontide case, so both weeks numbered 0 and every day of Holy Week took the slug of its Passion-week namesake -- one set of readings for two weeks with entirely different Masses. Good Friday was reading Passion Friday's. C31 growing is the same bookkeeping as C1's earlier growth and is recorded in its own note: C32 and C35 closed, and rows that carried several causes now carry only this one. Nothing new disagrees. 17 classes -> 10, 1019 rows -> 488, agreement 93.9% -> 97.1%. What remains is almost entirely NAMING rather than disagreement: C6 (119) is colitur's ef-nativity-octave-day-N against lectio's ef-christmas-N-weekday on days where both now read the same Mass, and C1 (40) is the same shape in the January window.
* test(differential): C8 closed, C6 narrowed to namingLukasz Kasprzak2026-08-181-6/+8
| | | | | | | | | | | | | | | | | | | lectio gained Rogation Monday and Tuesday (RG 87, violet under RG 128(d)) and the Missal's own Mass for the weekdays within the Octave of the Nativity ("Diebus infra octavam Nativitatis Domini", Titus 3:4-7 / Luke 2:15-20). C8 26 -> 0 CLOSED C6 119 -> 119 narrowed: the cause halved, the count did not C6 is worth reading carefully rather than skimming the number. Its rows no longer differ on First_f or Gospel_f at all -- the two engines now read the SAME Mass on 29-31 December, where lectio previously served the Sunday's. What is left is Slug_f alone, colitur's ef-nativity-octave-day-N against lectio's ef-christmas-N-weekday. That is vocabulary, not disagreement. The count did not move because the entry's gate already admitted a Slug_f-only subset, which is exactly the case where a row count is a misleading summary. 17 classes, 1019 rows, agreement 93.9%.
* test(differential): C17 closed -- the largest divergence class is goneLukasz Kasprzak2026-08-181-15/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | lectio built the votive Office of Our Lady on Saturday (RG 78) and then said RG 309(a)'s own Mass for it. Both halves were needed: RG 78 keeps the office and gives it white, RG 309(a) picks among the Missal's five seasonal formularies. Fixing only the first leaves the day announcing Our Lady and reading the feria's Mass -- the bug colitur itself shipped briefly and fixed in its v0.3.0. C17 439 -> 0 CLOSED -- the largest class between the two engines C31 103 -> 63 Saturdays that carried both causes; only this one left C35 69 -> 60 same C1 35 -> 75 GREW C1 growing is not a regression and is recorded as such in its own note: the January Saturdays C17 used to absorb now differ only on the slug vocabulary C1 already covers, so they land there instead. Rows moved between entries as the larger cause was removed. Also in this refresh, from the same session: weeks after Epiphany now count from the first Sunday after it rather than from 6 January, which took C19 from 35 to 7 -- what remains there is the Holy Family interaction, a different cause needing RG 17(b) in lectio. 19 classes -> 18, 1493 rows -> 1045, agreement 91.1% -> 93.8%.
* test(differential): refresh the fixture -- three more corrections adoptedLukasz Kasprzak2026-08-181-16/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | lectio has taken three further corrections colitur argued from the Missal: the twelve RG 124 colours (red is for Apostles, Evangelists and Martyrs, and missalemeum had the rule inverted in both directions), Good Friday's black under RG 128(b) with RG 132, and RG 72's Christmas Time boundary at 13 January inclusive. 864 rows changed. Two classes closed outright and two moved: C18 450 -> 0 the RG 124 colours -- the LARGEST single class in this file C36 46 -> 0 Good Friday's colour C1 159 -> 35 the season boundary stopped differing C23 184 -> 230 Good Friday's rows fold back, the split no longer needed C36 is closed rather than kept at zero because the split it represented has dissolved: it existed only to hold Good Friday apart while its diff set had a third member, and with the colour agreeing the rows are the exact pair C23 has always gated on. Restoring 230 is not a regression, it is the number returning to what it was before the split. Cited classes 24 -> 19, divergent rows 2252 -> 1521, agreement 86.6% -> 90.9%. The percentage is again the least interesting part. C18 alone was 450 days on which the two engines agreed about nothing and now agree because both apply RG 124 the same way round.
* test(differential): refresh the lectio fixture -- the lineage invertedLukasz Kasprzak2026-08-181-17/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Every previous refresh of this fixture carried lectio's answers TO colitur, because colitur's data was bootstrapped from lectio. This one carries colitur's answers BACK. lectio has merged eight field corrections colitur argued from the 1962 Missal: ubaldus and didacus promoted from commemoration to III-class feast on the Missal's own calendarium, both August vigils recoloured violet under RG 128, and both Ember Saturdays' readings, which lectio had carrying St Thomas's and St Matthew's Masses respectively. 227 of the 16801 rows changed. Three cited classes went to zero and are CLOSED and REMOVED, citations preserved in the register, the same discipline C2-C5, C7, C9-C13, C21, C22 and C25 already record: C27 40 -> 0 the Advent Ember Saturday's readings C28 40 -> 0 the September Ember Saturday's readings C37 77 -> 0 the two vigil colours C37 is worth noting by name: its own note called the shared lineage "the sharpest demonstration in the project", colitur and lectio and missalemeum all carrying the same two wrong colours. Two of the three now carry the right one. C38 NARROWED rather than closed, and the distinction matters. Its identity half is gone -- lectio ranks both saints class-3 now -- but the same 70 rows still differ on readings, because both saints take their Mass from a Common and lectio has no Commons concept to resolve one. It is gated on diffs = [First_f; Gospel_f] exactly, which is C18's shape. It cannot close without lectio gaining a capability, which is a feature rather than a fix. Net: 24 cited classes to 21, 2252 divergent rows to 2095, agreement 86.6% to 87.5%. The number that matters is not the percentage though -- it is that those 227 days now agree BECAUSE BOTH ENGINES FOLLOW THE MISSAL, where before they agreed because both inherited the same errors from Divinum Officium. That is the failure mode CLAUDE.md's lineage note describes, resolved rather than documented, for the first time in this project.
* fix(examples): pin the three Polish classes from the source, one was wrongLukasz Kasprzak2026-08-181-14/+25
| | | | | | | | | | | | | | | | | | | | | | | | | | | The first version of poland.ini marked three classes INFERRED because the ordo's class column sits several lines below its own date row and the first extraction pass did not reach it. All three are now read from the source: Our Lady Queen of Poland class-1 (line 1114), St Stanislaus class-1 (1233), Our Lady of Czestochowa class-1 (2398). One of the three inferences was WRONG. Czestochowa was written class-2 as "the conservative reading"; the ordo gives class-1. The mistake was treating the ordo's "part." marker -- particular, proper to certain places rather than universal in Poland -- as implying a lower rank. Those are different axes. The extraction method was validated before being trusted, against two entries whose class was already known from a clean single-line row: St Adalbert class-1 and St Andrew Bobola class-2. It reproduced both. Visible consequence, and it is correct: at class-1 Czestochowa no longer commemorates St Zephyrinus, because RG 111(a) admits no ordinary commemoration on a I-class day. The ordo also names the particular sees each patron is proper to -- Stanislaus for four archdioceses and three dioceses, Queen of Poland for Czestochowa and Przemysl and the military ordinariate -- which is now recorded beside them, and which reinforces the header's existing warning that a diocesan calendar is not a national one.
* feat(examples): ship two real local calendars, with their limits statedLukasz Kasprzak2026-08-182-0/+266
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Poland and the Benedictines, in the flat INI form, installed beside the invented diocesan example. poland.ini -- 17 entries from the Calendarium Perpetuum pro Dioecesium Poloniae (1964), promulgated under Rubricarum instructum and applying to the 1962 Missal. Transcribed from a published Polish EF ordo that names that same calendar, cross-checked against missalemeum's supplement page for the two formularies 1964 added (13 and 15 July). Date, Latin name and class were read from the source for every entry; three classes could not be recovered from the PDF's column layout and are marked INFERRED where they appear, with the reasoning. The header carries an edition warning that is a real trap here: the Proprium Poloniae of 1921 and 1934 is still bound into many missals and carries an outdated arrangement of dioceses and ranks. It is not this calendar, and it is exactly the kind of plausible wrong-edition source that has cost this project time before. benedictine.ini -- two entries, and the comment explaining why is the point of shipping it. Counted across the Norcia ordo: 86 "I cl.", 43 "II cl.", ZERO "III cl." and ZERO "IV cl.", against 103 "Semidup." and ~96 "Dup.". The monastic rite uses the Roman classes at the top and the older Duplex / Semiduplex grades below, exactly where the Roman calendar has III and IV class. colitur's rank vocabulary cannot express those, so most Benedictine propers cannot be written here at all -- a mismatch of vocabularies between related rites, not a gap in the data. Rather than invent a Duplex -> Class3 mapping the source never states, that file ships only what its ordo gives in Roman terms and lists roughly two dozen excluded feasts BY NAME, so the omission is visible instead of silent. Both headers say plainly that they are examples and not authorities: they are transcriptions from published ordines, none of the five test layers can vouch for either, and both should be checked against the reader's own ordo. The cram test asserts only what we control -- that they parse, convert and apply -- and says so. They also demonstrate the precedence engine on real data: the Benedictine Transitus is I class and takes 21 March with the Lenten feria commemorated, and Maurus is II class and takes 15 January with Paul the First Hermit commemorated.
* fix(ef): ubaldus and didacus are III-class feasts, not commemorationsLukasz Kasprzak2026-08-184-9/+60
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Both carried rank Class3 with status Commemoration_only, bootstrapped from lectio, which inherits it from missalemeum, which is generated from Divinum Officium. The Missal's own universal calendarium ranks both "III classis" outright, with no commemoration rubric: "S. Ubaldi Ep. et Conf., III classis" (16 May) and "S. Didaci Conf., III classis" (13 November), corroborated in the second scan and in a published 1962 Ordo. Universal by construction, not by assumption: the calendarium carries no "pro aliquibus locis" marker in its 573 lines while the wider Missal carries 79 of them elsewhere. Each saint also has his own Mass entry in the Proprium, which a bare commemoration never has -- a commemoration carries an oration only. Found by auditing ALL 290 fixed-date entries against that calendarium, day by day, anchored on the Roman calends column because the arabic day column is OCR-wrecked and the dominical-letter column vanishes in some months. These two were the only status defects in the whole file. The 15 days the automated pass could not cover were read by hand and all agree. Neither needed a proper authored: each takes its Mass from a Common with only its own Oratio proper, per its own rubric at its own date. ubaldus shares patrick's Common exactly. didacus needed one newly transcribed -- common-of-a-confessor-not-a-bishop-2, the "Altera Missa" Iustus, 1 Cor 4:9-14 and Luke 12:32-34, read independently in both scans, which agree, so the page-image third reading this file's method requires on disagreement was not triggered. Blast radius, full 1583-9999 sweep, every day classified: 13 036. That is 5 564 ubaldus observed, 7 196 didacus observed, and 276 where the Ascension Vigil still wins on 16 May but its single RG 111(c) slot passes from rogation-wednesday to ubaldus -- correct and already pinned, since the Rogation days are the MINOR Litanies and so an ordinary commemoration, which RG 113's table order ranks below a III-class feast. Cited as C38 (70 rows) and M30 (3); C8, C17 and M18 shrink accordingly, each with the reason recorded rather than the count silently adjusted.
* fix(ef): the Assumption and St Lawrence vigils are violet (RG 128)Lukasz Kasprzak2026-08-183-2/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | RG 128, transcribed in the rules register since 2026-08-11, gives violet to "vigils of II and III class outside Paschaltide". The Vigil of the Assumption (14 August, II class) carried White and the Vigil of St Lawrence (9 August, III class) carried Red. Both are outside Paschaltide, so both are violet. The Ascension's vigil is untouched: it is the one II-class vigil inside Paschaltide and was already correctly white. The rule had been sitting in the register, disagreeing with the shipped data, since before the data was bootstrapped. It was invisible because colitur, lectio and missalemeum all carried the same two wrong colours -- colitur was bootstrapped from lectio, lectio's ini is generated from missalemeum, and missalemeum uses Divinum Officium's data files. Three sources agreeing is one source counted three times, and the differential and the oracle both went green on the shared error. It surfaced only against witnesses outside that tree: a published 1962 Ordo flagged the Assumption's, and O'Connell, The Celebration of Mass 4th ed. (1964), section 4(c) and footnote 169, gave the general rule and with it St Lawrence's, which the Ordo omits entirely. Two golden pins added, in years where each vigil is actually observed rather than impeded. The divergence this creates against every DO-lineage source is cited in both allow-lists: C37 (lectio, 77 rows -- 92 possible minus 15 where the vigil falls on a Sunday) and M29 (missalemeum, 3 rows in 2026-2027 and 2 in each of 2035 and 2038). Both gated on the exact slugs or dates and on colour alone, so any other divergence on those days would still surface. Also recorded, no code change: rose on Gaudete and Laetare stays. RG 131 is permissive ("adhiberi possunt") and the Ordo prints violet, so the colour field carries a permission rather than a requirement on those two Sundays a year -- a decided position now, not an unexamined one.
* fix(ef): Good Friday is black, not violet (RG 128(b), RG 132)Lukasz Kasprzak2026-08-181-1/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | RG 128(b)'s own exception list, transcribed in the rules register and primary-source-verified since Task 16, excepts "Actione liturgica feria VI in Passione et Morte Domini usque ad Communionem exclusive" from the violet that otherwise runs from Septuagesima to the Easter Vigil. RG 132 assigns black there. The register recorded this as an acknowledged gap rather than a disputed reading -- the code comment beside the Holy Thursday exception says so in as many words -- and it is closed here. Found by two witnesses outside the Divinum Officium lineage that colitur, lectio and missalemeum all share: O'Connell, The Celebration of Mass, 4th ed. (1964), revised throughout to the Codex Rubricarum (1960) and the 1962 Missal, and a published 1962 Ordo. Both say black. So does missalemeum's own colour set, which orders the day "bv". The rubric is per-action ("usque ad Communionem exclusive") and the model emits one colour per day; black is the day's principal one, the same acknowledged limit RG 126's Palm Sunday blessing already carries. Blast radius: one day per year, colour only, across the whole 1583-9999 domain. Two golden pins re-pinned. Good Friday's 46 differential rows leave C23 for a new C36 gated on the exact triple [First_f; Gospel_f; Colour_f], so C23's own exact-pair gate still means what its note says for its remaining four days: 184 + 46 = 230, no residue, both counts from the comparator rather than hand-counted.
* docs(ef): close C6 and M26; nothing is left adjudicated against coliturLukasz Kasprzak2026-08-182-11/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | C6 was closed by the Nativity-Octave fix rather than by argument. Its own note had already split the 138 rows into 119 weekday rows, where it recorded colitur's citation as confirmed correct and said verdict colitur would be accurate for that subset alone, and 19 Sunday rows where colitur emitted the weekday formulary against RG 69 and was plainly wrong -- a Temporal_ef defect the entry deliberately left out of its own scope. That defect is fixed, and the count fell 138 to 119: exactly the population the note had enumerated by date. Verdict open becomes colitur on reasoning already written there. M26 closed on a positive argument, not an absence. Both its other shapes are now built -- the BVM Saturday Mass selection and Trinity's week -- leaving Christ the King's week. RG 299's rule has an escape clause and the escape requires an assigned proper Mass; none is assigned for that week, checked at the source, unlike Trinity's week which prints one and unlike Holy Name and Holy Family which each carry a ferial rubric. That absence is not a research gap, it is the condition that triggers RG 299's default -- and by the default the ferias say the preceding Sunday's Mass, which on this week is Christ the King's own. The limit is stated in the entry rather than glossed: this reads a printed silence as the default rather than as an oversight, which the text cannot distinguish. It is the same reading applied everywhere else RG 299 governs, and applying it inconsistently here to match an oracle already adjudicated wrong six times would be the worse error. No entry in either allow-list is now verdict open or verdict missalemeum. The only non-colitur entries are M15 and M18, both unresolvable, and both are comparator limits rather than calendar disagreements: a temporal-origin celebration carries no English name, so its identity cannot be matched even where both streams plainly mean the same thing. Register: section 6.18.
* fix(ef): days within the Octave of the Nativity, and RG 69 for 29-31 DecLukasz Kasprzak2026-08-182-9/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | M11 was the one entry in the missalemeum allow-list adjudicated against colitur, and it was right to be. The calendarium directs "Com. octavae Nativitatis" under each of 26, 27 and 28 December (LT.txt:5454-5459) and RG 109(c) makes a commemoration of the days within the Octave privileged. colitur emitted none. The cause was a reasoning error stated in Temporal_ef's own comment: "26-28 Dec are Stephen, John and the Innocents, hence sanctoral". Their office is sanctoral -- those II-class feasts win the day -- but they remain days WITHIN the Octave (RG 67, "Dies infra octavam sunt II classis"), and colitur built them as generic Class4 ferias. With no octave-day candidate there was nothing for the feast to be commemorated over. Building days 2-4 exactly as days 5-7 always were makes the commemoration fall out of the existing machinery rather than needing a special case: the feast wins on rank, the octave day loses, RG 109(c) privileges it, RG 111(c)'s single slot goes to it. A second, independent defect surfaced while fixing it. The octave-day branch covered 29-31 December unconditionally, so a Sunday falling there got a feria identity -- where RG 69 says a Sunday occurring 26-31 December SEMPER keeps its own office and commemorates the feast. Confirmed against the oracle rather than argued: missalemeum shows "Sunday in the Octave of Christmas" on 2035-12-30, a Sunday, where colitur showed a feria. Both named and anchors now exclude Sundays; anchors had asserted the octave slugs unconditionally and was wrong the same way. Blast radius, full sweep against the pre-change binary: 25251 days, every one 26-31 December, exactly two shapes, zero unclassified -- 21653 carrying an octave-day slug and 3598 that are all Sundays, the RG 69 correction. Allow-lists: M11 closed and removed. C6 narrowed 138 to 119, nineteen of its days having changed temporal identity rather than verdict. M15 widened 18 to 22 -- both streams now commemorate the octave, but the candidate is temporal-origin and carries no English name to match against missalemeum's own, this entry's documented limit on four more dates. Stated rather than glossed: this trades a substantive divergence, colitur omitting a commemoration the Missal directs, for a comparator limit, the commemoration existing but not being name-matchable. That is a real improvement, but what the oracle now proves is that both streams commemorate something on those days; the identity rests on the rubric and the calendarium. Register: section 6.17.
* feat(data): ship a worked example overlay calendarLukasz Kasprzak2026-08-181-0/+102
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `--overlay` shipped last week with nothing to point at. The only example was a test fixture, explicitly labelled invented and living where no user would find it, so "colitur supports local calendars" was true but undemonstrated. data/ef/examples/diocesan-example.sexp is installed to <prefix>/share/colitur/examples/ and is runnable documentation: every celebration in it is invented, with example- slugs that cannot collide, and its header explains the four directives, the three date shapes, and the field vocabularies before showing any of them. It demonstrates the range deliberately rather than the minimum: a fixed-date local patron with its own propers; a movable dedication on the first Sunday of October, I class because a church's own dedication anniversary is I class in that church and at III it would lose to the Sunday every year; an Easter-relative commemoration; an Edit raising a universal feast for local use; and a Suppress shown commented out, because suppressing a universal feast is a real liturgical act and an example should not invite it casually. Two things the header says plainly, since this is the one file that lets someone change what colitur computes: an overlay is applied ON TOP of the shipped calendar and never instead of it, and an overlay is applied, NOT validated -- the five test layers assert things about the shipped data and cannot vouch for a user's file. A test asserts it loads against the real EF rank vocabulary, still demonstrates at least four directives, and applies with NO diagnostics. The last matters most: a directive naming a slug the universal calendar lacks would warn, and an example that warns teaches the wrong lesson. It deliberately does not pin which days it produces -- those celebrations are invented, and pinning their dates would make an illustrative file behave like calendar data.
* docs(ef): M13 adjudicated colitur; Mass I is unreachable, not unwitnessedLukasz Kasprzak2026-08-171-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Two open questions closed, both by looking rather than reasoning. M13 listed three possibilities for 19 March 2027 and stayed open because none was confirmed. The live one was (b): a rubric at St Joseph's own Proprium Sanctorum entry overriding the general table, "the same shape as the Annunciation's own Attamen clause", its text simply not yet found. It was looked for directly. Joseph's entry runs from its heading straight into the Introit with no rubric of any kind -- and the analogue does not exist where the note placed it either: the Annunciation's entry does the same. That exception lives in RG 96, a general rubric about transferring an impeded I-class feast, not in its propers, so there is no precedent for a propers-level override at all. With (b) eliminated and (c) still unsupported, (a) stands: RG 91 ranks a I-class feast above a III-class Passiontide feria, Joseph is not impeded so RG 96 never engages, and colitur observes him. Recorded with its limit, because this is elimination and not proof: the specific hypothesis named is false, which is weaker than showing no rubric anywhere says otherwise. Separately, the note that Mass I of the BVM Saturday needed an Advent-Saturday oracle year to corroborate it is answered: there is no such year and cannot be. Advent has no IV-class ferias -- Class2 from 17 December, Class3 before -- and RG 78 requires a IV-class feria. Zero IV-class Advent Saturdays across 2000-2100. Its single witness is not a gap in the research but the only evidence obtainable. The branch is kept: the Missal does print the Mass for Advent, RG 309's subject being Masses that may be celebrated as votive, and an overlay producing such a day would otherwise fall through silently. Register: sections 6.13 addendum and 6.14.
* feat(ef): the votive Mass of Our Lady on Saturday (RG 309(a))Lukasz Kasprzak2026-08-172-23/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | RG 78's office has been built since ef-bvm-saturday: an otherwise unoccupied IV-class Saturday is de sancta Maria in sabbato, white, IV class. The Mass stayed the feria's, so the day observed Our Lady and then read Colossians on the parable of the weeds. That is M26 shape 1. RG 309(a) is the rule -- the Masses the Missal assigns "iuxta temporum diversitatem" -- and it prints five, each under its own season heading. All ten citations are transcribed from the scans with line numbers in the source. Masses II-V were confirmed twice, against the scan and against a live missalemeum capture of 2038 which names them and agrees on both readings. Mass I rests on the scan alone: no oracle year to hand has an Advent Saturday carrying this office. One witness where the others have two, and the code says so rather than blurring it. The mapping looked like the hard part and dissolved. The Missal's ranges are cut by civil dates and movable feasts, not by this rite's seasons -- II ends mid-season at the Purification, III spans four seasons. But measured against what a IV-class Saturday can actually be, it reduces to a seasonal mapping plus one date test at 2/3 February, with no Easter arithmetic at all: III's end to IV's start leaves the Triduum unassigned, unreachable because Holy Saturday is I class; IV's end to V's start leaves Pentecost week unassigned, also unreachable because that week's Saturday is an Ember Saturday. Time after Pentecost then begins exactly at Trinity, exactly where Mass V begins. Both gaps verified by sweep -- zero IV-class Saturdays in either across 2000-2059 -- not inferred. The office is identified structurally, never off the slug, which it deliberately shares with the ordinary feria: subject Bvm, IV class, Saturday. Blast radius: 87611 reading rows over the full domain, every one a Saturday. Allow-lists: M26 27 to 6, shape 1 gone, leaving only the Christ-the-King residue argued in colitur's favour last commit. The 2038 suite's BVM-SATURDAY-MASS class is removed rather than zeroed -- an id with no rows must not be declared. M18 355 to 376. C17 widened 397 to 445, taking its own Saturdays back from C1, C19 and C25, since one cause should not be filed under two ids; C31 89 to 103; C25 closed at 0 rows, its Holy-Name-week Saturdays now answered before step 3 is reached. Three unit tests pinned the old behaviour and are corrected rather than re-pinned: two asserted the day "keeps its ferial Mass", which was the honest thing to assert while this was unimplemented. The third still tests what it always did -- that step 4 refuses a temporal office -- and only what answers instead has changed. Register: section 6.13.
* feat(ef): the Seven Sorrows of Passion Friday, and M16 reversedLukasz Kasprzak2026-08-172-3/+43
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Not the II-class feast of 15 September, which colitur has had since the bootstrap, but the other Seven Sorrows: the movable commemoration of Passion Friday, of which colitur had no trace at all. The 1962 calendarium lists it at the foot of March, below the fixed dates, exactly where a movable entry belongs (LT.txt:5056): "Feria VI post dominicam I Passionis: Commemoratio septem Dolorum B. Mariae Virg." Note the word -- Commemoratio. Under the 1960 rubrics it is a commemoration, not a feast, so it can never win the day. Friday after Passion Sunday I is Easter-9, confirmed independently by both dates the oracle allow-list already disputed: Easter 2026 is 5 April and M16's date is 27 March; Easter 2027 is 28 March and M13's is 19 March. It could not be built before Date_spec grew Easter_offset -- the same wall Rogation Wednesday hit, and the second entity that work has now unblocked. M16 is re-adjudicated and its verdict REVERSED, from missalemeum to colitur. The entry existed because colitur admitted St John Damascene where missalemeum showed the Seven Sorrows, colitur having no candidate to admit. Both streams now name the Seven Sorrows and that mismatch is gone. What remains runs the other way, and the rubric is explicit: RG 111(d) admits TWO commemorations on a III-class day, RG 113 puts the seasonal one first, and RG 114 omits only what exceeds the number. 27 March 2026 is a III-class privileged Passiontide feria; colitur admits exactly two, the Seven Sorrows and John Damascene, a real III-class universal feast genuinely falling that day. missalemeum admits one and reports John Damascene as displaced, dropping a commemoration the rubric allows. That makes four divergences adjudicated colitur where missalemeum drops or mis-assigns something -- Monica's Epistle, Perpetua's Common, Christ the King's week, and this. Recorded as a pattern rather than four coincidences: the oracle stays a comparison instrument, but its error rate on adjudicated cases is no longer negligible. M13 is untouched and stays open: 19 March 2027 is a different dispute, whether Joseph is displaced from Passion Friday at all, and on a I-class day RG 111(a) admits one privileged commemoration which the feria takes. Blast radius, full 1583-9999 sweep against the pre-change binary: 7874 days, every one carrying the new commemoration, zero unclassified, line counts equal both sides. Register: section 6.12.
* fix(lectionary): the week after Trinity says its own assigned MassLukasz Kasprzak2026-08-173-7/+28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | RG 299 located (scan1:1096-1098), which does two things at once. First it closes a standing gap: the ferial-Mass selection rule was recorded in the register as unconfirmed against the primary source, and step 3 said so in its own comment -- "lectio's own observed behaviour, not a confirmed Missal citation". It is confirmed now. "In reliquis feriis dicitur Missa dominicae praecedentis, nisi a rubricis aliter provisum sit", restated in the propers as "...nisi propria Missa assignetur". Second, that escape clause splits M26 shape 2 in half, which is why the shape was never resolvable as one thing. Shape 2(a), the week after Trinity, is fixed. Trinity is the temporal identity of its own Sunday, so a plain walkback lands on Trinity's Mass -- but the Missal prints a named formula for the following week, "Missa dominicae I post Pentecosten" (scan1:21758), precisely because the feast has taken that Sunday's own. Those ferias now resolve at step 2 from it and never reach the walkback. Shape 2(b), Christ the King's week, turns out not to be a bug at all. No proper Mass is assigned there -- checked directly, no rubric precedes that Mass heading (scan1:39163ff) -- so RG 299's default governs and "the Mass of the preceding Sunday" genuinely is Christ the King's own, which is what colitur emits and missalemeum does not. Kept open only because no rubric specific to that week was located either way; the verdict is now argued from the primary text rather than resting on oracle disagreement. No Thursday in the slug list: Corpus Christi is Easter+60, which IS that week's Thursday every year, so the ferial slug never exists. Found by the bootstrap's own reachability guard refusing to emit a key no Temporal_ef slug can match, not reasoned out in advance. Allow-lists: C35 opened (69 rows, verdict colitur -- lectio still walks back); C17 narrowed 406 to 397, nine Saturdays moving to C35 because they carry both a citation and a colour difference, with C35 gated to require the citation so a colour-only Saturday still falls to C17; M26 narrowed 30 to 27; M18 widened 352 to 355, the same three days keeping only their observed-identity difference. Register: section 6.11.
* feat(kernel): movable Date_spec variants, and Rogation WednesdayLukasz Kasprzak2026-08-171-0/+50
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Date_spec carried one variant, Fixed(month, day), and its own header said Sunday- and Easter-relative forms would arrive with the OF sanctoral. They arrive early because two things needed them at once: a user-supplied overlay carrying a local movable feast had no way to express "the first Sunday of October", and Rogation Wednesday's commemoration has been recorded as architecturally blocked since 2026-08-13. That blockage turns out to have been a premise, not a fact. The register concluded the Rogation "is not Commemoration_only sanctoral data by nature... it needs a genuinely THIRD kind of thing this architecture has no name for" -- but the reasoning rested on there being "no civil (month, day) pair to anchor a Fixed entry to". That is a statement about Date_spec's expressiveness. With Easter_offset the entity is ordinary sanctoral data, the identical shape Add major-litanies already ships, differing only in how the date is written. No third channel was needed. The register is corrected rather than left contradicting the code. Two variants: Easter_offset of int, and Nth_weekday of {month; nth; weekday} with negative nth counting from the end. Fixed's sexp representation is untouched, so all 327 sanctoral entries and the whole overlay parse unchanged. Both are re-validated in t_of_sexp through their smart constructors, extending the idiom Fixed already used -- the failure that guards against is invisible, a spec deserialising into something that silently never resolves and a celebration vanishing with no diagnostic. Easter is supplied by the rite, not computed in the kernel. Computus ships Gregorian and Julian both, and picking one here would hard-code a Roman assumption into rite-agnostic code and be silently wrong for a Julian-reckoning rite. Rite.t gains an easter field; Rite_ef supplies the Gregorian one. Layer keeps a split index. Fixed entries stay in the year-independent (month, day) table, which preserves the fast path and the "30 November counted twice in a 371-day span" behaviour validate.mli documents for St Andrew. Movable entries have no year-independent key by construction -- the same spec lands on a different (month, day) each year -- so they resolve per civil year into a rata-die table. index_by_date is removed rather than kept as an alias: two ways to index a layer, one of which silently ignores movable entries, is the trap this change exists to avoid. Two domain-edge defects, both found by the suite rather than reasoning. A liturgical year is Advent-anchored, so resolving civil year y names y +/- 1, and at the edges those are 1582 and 10000, which Computus correctly refuses by raising. The ceiling surfaced through the domain-ceiling test, the floor through `colitur day 1583` failing outright. Fixed once, in Layer.index, the single point that calls the rite's easter -- a clamp repeated per caller would have been two places to get wrong a third time. Rogation Wednesday: RG 87 assigns the Litaniae minores to the Monday, Tuesday AND Wednesday before Ascension (scan1:691); colitur built the first two from the start and never the third. RG 88 keeps it out of the Office, so the Ascension Vigil remains observed. RG 89 routes it through the Major Litanies' rules, but RG 109's closed list names only maiores, so by RG 107 it is an ORDINARY commemoration -- confirmed in the output, not assumed. Name from the Missal's own "feria IV" (scan1:20495-20497), violet to match the Monday and Tuesday offices. Blast radius, full 1583-9999 sweep against the pre-change binary: 2257 days, every one the same shape, zero unclassified, line counts equal both sides. The complement is the informative half -- in the other 6160 years the Rogation does not appear at all, because RG 111 admits one commemoration on a II-class day and an impeded feast takes it under RG 113, a Commemoration_only candidate having no row in RG 91's table. Both shapes are pinned. Allow-lists unmoved: layer 3 compares no commemorations and is blind by construction, and layer 4's 2026-2027 window has a competing feast on both Wednesdays, so the Rogation is capped out in exactly the years the oracle can see. C8 is unchanged, asserted by its own count pin. Not built: Sunday-relative specs, which nothing needs yet, and the --overlay plumbing that would let a user actually supply a local movable feast. Nth_weekday therefore ships with synthetic and property coverage only; inventing a shipped entry to exercise it would be fabricating calendar data. Register: section 6.10.
* fix(lectionary): two Judith citations wrong in both enginesLukasz Kasprzak2026-08-173-10/+30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A live-missalemeum sweep over a full liturgical year (2028, 364 days) returned 333 matching and 31 differing days: 17 already-known or pure notation, 3 new. All three now adjudicated against the photographic scans of the 1962 Missal. The Assumption's Epistle reads "Iudith 13, 22-25; 15, 10" (scan1:35357). Both engines carried "Judith 13:22-25; 13:15; 13:10" -- a chapter carry-over defect that re-applied chapter 13 to the second citation and so invented two verses the Missal never cites. The Seven Sorrows reads "Iudith 13, 22 et 23-25" (scan1:36938, corroborated at 28468); both carried "Judith 13:22; 13:25", dropping the range. The third, St Monica, resolves the other way: the Missal gives 1 Timothy (scan2:32679, heading and incipit both legible; scan1:29524 agrees) where missalemeum serves the Common of Holy Women's Proverbs -- colitur is right, no change. Layer 3 could not have found either citation defect. colitur's data is bootstrapped from lectio, and lectio is the other side of that differential, so while both engines produced the identical wrong answer the comparison held it against itself and reported agreement -- the shared-lineage blindness CLAUDE.md names, now with a second live witness beside Holy Thursday's colour. Only an external oracle could see it, and only outside the committed fixture's own window. Fixed upstream in lectio, re-bootstrapped here (provenance SHA-256 moved to 54f6bfc5, verified against the source), fixture regenerated. The upstream fix inverted layer 3 from blind to load-bearing here: reverting the Assumption citation now reddens both layers, where before it would have reddened neither. Verified by mutation, both directions. Allow-lists: - C22 closed and removed (128 rows -> 0), not re-adjudicated -- the other engine was fixed to agree, the same shape as the C2-C5/C7/C9-C13/C21 closures. Its own note had already flagged the Lenten Ember dead-key bug for upstream; lectio now also fails its build on any unreachable lectionary key rather than serving a plausible wrong Mass. - M28 opened (3 rows, verdict colitur), pinning both sides' citation text rather than the date and diff shape alone, so a different divergence landing on the same date cannot be swallowed. - M8's gate widened, expected_rows unchanged at 2: 2027-08-15 carries both its cause and M28's, and one entry is admitted per day. It stays under M8, which now requires its own commemoration difference to be present and admits the citation difference only when it satisfies M28's two-sided predicate. Neither cause absorbs the other. layer_m_reason's oracle-row parameter, kept named since M2 closed for exactly such a future reader, is live again. Register: docs/research/rules-register.md section 6.6.
* test(oracle): fix round 1 -- C30 disclosure, RG 17(a) misattribution, M26 shapesLukasz Kasprzak2026-08-172-8/+37
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Three Important findings from coordinator review of 8d1eb25, all fixed. 1. C30's own note claimed its 91-row population "is C25's OWN former population, before this task narrowed it" -- false. Independently re-derived against the real resolver (pre-fix vs post-fix binary) and the lectio fixture: only 44 of the 91 rows were ever in C25 (Wed 6/ Thu 19/Fri 19, matching C25's own fix-round-3 breakdown exactly); the other 47 (all of Monday/Tuesday, plus part of Wednesday/Friday) previously matched lectio outright -- both engines independently landing on the same wrong value -- and are newly allow-listed only because colitur is now right. Rewritten to the same "both engines silently agreed on the wrong answer" pattern C33/C34 already used. 2. "Diebus ferialibus" is not RG 17(a) -- RG 17(a) states only the day-identity privilege; the ferial-Mass rubrics are Mass-propers rubrics, a distinction the register's own §6.3 already drew before this task's first pass blurred it in code/allow-list comments. A further slip: C31/C32 called their own rubric "RG 17(a)'s own next/ third sentence" when it is a different rubric block ~230 lines away, in Holy Family's (not Holy Name's) own feast propers. Fixed the attribution chain throughout tools/bootstrap_lectionary.ml, data/ef/expected-divergences.sexp's C29-C34, and (gitignored, outside this commit) docs/research/rules-register.md -- closed the §6.3 park, added §6.5 recording all four citations with corrected attribution. Quotes and line numbers were already right; only the chain of custody to RG 17(a) was wrong. 3. M26's own 30 rows classify into two nameable shapes, not "three confirmed shapes" with an unexplained 23-row residue that was in fact empty: 21 rows are RG 78's own already-documented BVM votive-Mass gap; 9 rows are a second, distinct gap -- a week whose own Sunday was displaced by a movable named feast (Trinity->Corpus Christi, "Missa Dominicae I post Pentecosten"; Christ the King), where the Missal requires the displaced Sunday's own Mass to keep informing that week's ferias but step 3 walks back to the displacing feast's citation instead -- proven directly by colitur's own citation on the Christ- the-King rows being literally that feast's own Gospel. verdict open unchanged (not fixed here); the shape is now named instead of buried. Minors: section count corrected 1458->1456 (four places); "exactly one candidate, zero ambiguous" corrected to "correctness rests on ordering, not uniqueness" (2 of 1456 sections genuinely yield two candidates, Holy Saturday's own Lectio, both years); the stale "nothing in layers 3-5 compares citations" claim corrected (only layer 5 still doesn't); M18's note corrected (five new entries not six; ~18 of its remaining 352 rows only agree now because of this task's own fixes, not "already" before it); "five" corrected to "six" otherwise-unoccupied Saturdays in bootstrap_lectionary.ml; scan2 quotes softened where OCR-garbled. Also done outside the git-tracked files: the step-4 (Commons) coverage gap is now recorded in data/ef/expected-divergences-missalemeum.sexp's own header, not only the commit body and the (gitignored) report. dune test: 358 tests green. COLITUR_EXHAUSTIVE_SWEEP=1 dune test --force: 359 tests green, 95.7s.
* test(oracle): compare reading citations against missalemeumLukasz Kasprzak2026-08-173-18/+138
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Layer 4 (test_oracle.ml) now extracts and compares the Epistle/Gospel citation for every one of the 730 days in the 2026-2027 fixture, the same axis Task 8 already added to layer 3. tools/ extract_missalemeum_oracle.py gained a structural citation-span detector (the first "*...*"-wrapped span under 40 chars containing a chapter:verse-shaped digit pair), verified exhaustively over all 1 458 Lectio/Evangelium sections. 728 of 730 days are comparable; the 2 that are not (Good Friday, both years) have no such section in missalemeum's own JSON at all -- a structural limit on the oracle's own side (M23), not a colitur gap. 451 of 730 days differ and are all explained across 19 cited entries; 0 unexplained. Chain step 4 (the Commons) has no layer-4 witness: confirmed empirically (a scratch sweep, not merely re-asserted from Task 6's own report) that none of the 15 Commons/proper saints is ever the observed office in this window. The comparison surfaced three genuine colitur bugs in data/ef/lectionary.sexp, all fixed at the source in tools/bootstrap_lectionary.ml: 1. Holy Name of Jesus (ef-holy-name-sunday/ef-holy-name) carried a mis-derived citation, borrowed by analogy from an unrelated ini section ("ef-christmas-sunday-0", the Sunday-within-the-Octave's own Mass) on the wrong assumption the two share a Mass. Disproved by missalemeum's own extraction for both real Holy Name Sundays in its window, confirmed against the Missal itself, twice, both scans (Acts 4:8-12/Luke 2:21, not Gal 4:1-7/Luke 2:33-40). 2. RG 17(a)'s own "diebus ferialibus" rubric (immediately following the Holy Name heading, both scans) was never implemented: 2-5 January ferias repeat 1 January's Mass, 7-12 January ferias before Holy Family Sunday repeat Epiphany's, and Holy Family's own week has a named formula ("Missa Dominicae Primae post Epiphaniam"). All three fell to step 3's undifferentiated Sunday walkback instead. Fixed for three 5-weekday families, deliberately excluding Saturday from all three -- RG 78's BVM Saturday Office wins there unconditionally, confirmed against missalemeum's own title on this window's own such Saturdays. 3. Corpus Christi and Sacred Heart (both real, never-impeded I-class movable feasts) had no lectionary entry at all. Both engines independently fell back to Trinity Sunday's own citation and silently agreed on the wrong answer -- the "Holy Thursday violet in both" shape CLAUDE.md names for exactly this reason. Because lectionary.sexp is shared with layer 3 (the lectio differential, 2005-2050), these fixes changed colitur's output for the whole domain, not only 2026-2027. data/ef/expected-divergences.sexp and test_differential.ml needed matching updates: C1 narrowed 361->173 and C25 narrowed 57->13 (rows that now resolve correctly moved to new entries), C16's note corrected (count unchanged), and six new entries added (C29-C34, 397 rows total, all verdict colitur). test_lectionary.ml and test_lectionary_ef.ml's own pins were updated to match (entry count 131->148; one step-3 regression test re-pointed to a date that still genuinely exercises that step). One entry, M26 (30 rows, verdict open), is a genuine unfixed gap: colitur's step-3 "resume the preceding Sunday" fallback is its only ferial-Mass mechanism, and missalemeum's own selection is more granular in three confirmed ways (a rotating votive Mass of the BVM, a named weekly formula for at least one week, and later Time-after-Pentecost weeks this task's own investigation did not narrow to a single rule) -- the same "needs a season-keyed selection mechanism, new behaviour not new data" shape data/ef/expected-divergences.sexp's own C6/C25 and Task 6's own residual concern already name, out of this task's own scope to build. dune test: 358 tests green. COLITUR_EXHAUSTIVE_SWEEP=1 dune test --force: 359 tests green, 89.5s.
* test(differential): fix round 3 -- two more Ember Saturdays, doc fixesLukasz Kasprzak2026-08-152-11/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Two Ember Saturdays shipped an apostle's Mass verbatim from lectio's own ini, the exact shape already found and fixed for Passion Tuesday (C26): ef-advent-ember-sat carried St Thomas the Apostle's Mass (Eph 2:19-22 / John 20:24-29, 21 December) instead of the real "Sabbato Quatuor Temporum Adventus" (2 Thess 2:1-8 / Luke 3:1-6); ef-september- ember-sat carried St Matthew's Mass (Ezek 1:10-14 / Matt 9:9-13, 21 September) instead of the real "Sabbato Quatuor Temporum septembris" (Heb 9:2-12 / Luke 13:6-17). Both verified against both primary-source scans independently. Both readings are explicitly labelled "Lectio Epistolae" in the Missal on both days, so neither needed the "last lesson before the Gospel" convention Holy Wednesday/Good Friday relied on -- a textual fact, not an editorial choice. Fixed at the source in tools/bootstrap_lectionary.ml: colitur_keys excludes both wrong ini sections; a new ember_saturday_corrections list hand-authors the real citations. New allow-list entries C27/C28 (40 rows each, not the naive 46 -- traced to the identical 6 civil years where 21 September and 21 December, always exactly 91 days apart, land on a Saturday and the fixed saint's feast wins outright). Both values pinned in test_lectionary.ml and mutation-tested. Also: C25's per-weekday breakdown was mislabelled (right multiset, rotated weekday labels) in both test_differential.ml and expected- divergences.sexp -- corrected to Wednesday 6/Thursday 19/Friday 19/Saturday 13, and the claim that this split came directly from the comparator's own output is narrowed to what's actually true (only the total, 57, does). C26's scan2 citation range was extended to include the Gospel (previously stopped after the Epistle). lib/kernel/liturgical_day.mli's "citations always empty until Plan 4" comment is now stale on this branch -- left untouched (Task 11's own documentation pass), noted in the task report so it isn't lost. dune test: 358 tests green; COLITUR_EXHAUSTIVE_SWEEP=1: 359 green.
* test(differential): fix round 2 -- Good Friday, Passion Tuesday, stale headerLukasz Kasprzak2026-08-152-52/+73
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-152-40/+79
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-152-23/+97
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* ef(lectionary): the Commons, chain step 4Lukasz Kasprzak2026-08-152-1/+400
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fifteen class-3 saints had no readings anywhere in colitur -- the 6 March - 5 April cluster whose RANKS lectio's generator fix of 2026-08-12 restored without backfilling readings, and lectio has no Commons concept to have backfilled them from. They are exactly the fifteen `status Feast` entries in data/ef/sanctoral.sexp carrying `(citations ())`. The Missal splits them eight/seven, and NOT as the plan predicted. It expected propers for Benedict, Patrick, Thomas Aquinas and Gregory the Great; only Thomas Aquinas has one. Benedict ("Missa Os iusti, de Communi Abbatum"), Patrick ("Missa Statuit, de Communi Confessoris Pontificis I loco") and Gregory the Great ("Missa Si diligis me, de Communi unius aut plurium Summorum Pontificum") are all sent to a Common, with only Oratio, Secreta and Postcommunio printed at the date. All three reversals verified on the page images (pp. 488, 492) as well as in both OCR text layers. PROPERS (data/ef/adjustments.sexp, `Edit ... Set_citation`): thomas-aquinas 7 Mar Sap 7:7-14 / Mt 5:13-19 john-of-god 8 Mar Eccli 31:8-11 / Mt 22:34-46 forty-holy-martyrs 10 Mar Hebr 11:33-39 / Luc 6:17-23 cyril-of-jerusalem 18 Mar Eccli 39:6-14 / Mt 10:23-28 gabriel-the-archangel 24 Mar Dan 9:21-26 / Luc 1:26-38 john-damascene 27 Mar Sap 10:10-17 / Luc 6:6-11 john-of-capistrano 28 Mar Sap 10:10-14 / Luc 9:1-6 francis-of-paola 2 Apr Philipp 3:7-12 / Luc 12:32-34 COMMONS (data/ef/commons.sexp), each quoting the Missal's own instruction at the saint's date: sts-felicitas-perpetua 6 Mar non Virginum I Eccli 51:1-8,12 / Mt 13:44-52 frances-rome 9 Mar non Virginum II Prov 31:10-31 / Mt 13:44-52 gregory-the-great 12 Mar Summ. Pontificum 1 Petri 5:1-4,10-11 / Mt 16:13-19 patrick 17 Mar Conf. Pont. I Eccli 44:16-27;45:3-20 / Mt 25:14-23 benedict 21 Mar Abbatum Eccli 45:1-6 / Mt 19:27-29 isidore-of-seville 4 Apr Doctorum 2 Tim 4:1-8 / Mt 5:13-19 vincent-ferrer 5 Apr Conf. non Pont. I Eccli 31:8-11 / Luc 12:35-40 Every value read in three independent places -- both OCR text layers (two DIFFERENT printings, whose Commune Sanctorum pagination differs by 1-2, so the data keys on heading plus Mass incipit and never on the bracketed page number) and the rendered page images. That caught a genuine typographical error in one printing: it gives St Gabriel's Gospel as "Luc. 2, 26-38" (on the page image, so not an OCR artefact). Luke 1:26-38 is settled by the other printing, by the pericope text in both, and by the SAME edition citing the identical pericope correctly two pages later at the Annunciation. Step 4 EXECUTES SECOND (order 1, 4, 2, 3), not last as the plan sketched. Measured: every day on which one of the fifteen is actually the observed office already has a non-empty step-2 or step-3 answer waiting, so a step 4 placed after the ferial fallback is unreachable on every date in 1583-9999 -- and wrong where it would fire (2038-03-06 would emit Septuagesima II Saturday's Mass on a day whose office is Sts Perpetua and Felicity). Step 4 is also the only step in the chain with a direct primary-source warrant: the Missal names the Mass at each such saint's own date, while steps 2 and 3 rest only on lectio's observed behaviour. Guarded so it can never divert a day whose observed office IS its temporal office -- ferias, Sundays, the Triduum and the RG 78 Saturday Office of the BVM (which deliberately shares the ferial slug) are structurally excluded. Step NUMBERS are unchanged so every "step 3" already written down still names the same branch. The Commons are caller-supplied, like the lectionary: `Rite_ef.context` gains a REQUIRED `~commons`, not an optional one -- a silently-defaulted empty table would give a rite whose class-3 saints quietly lose their Mass, and nothing in layers 3-5 compares citations, so that loss would be invisible. `Commons.load` rejects the four defects indistinguishable downstream from "this saint has no Common": duplicate common id, duplicate assignment, empty formulary, assignment naming a common that does not exist. KNOWN LIMITS, recorded rather than papered over. There is no oracle: lectio has no readings for these feasts and missalemeum's 2026-2027 window never observes one of the fifteen. Eight of the fifteen are NEVER the observed office anywhere in the domain (10-28 March always falls to a Lenten or Passiontide feria that outranks a III-class feast), so they have no end-to-end witness and are covered by dedicated table tests instead. The Commune Sanctorum's own opening rubric permits any Epistle or Gospel of a Common in any Mass of that Common unless one is assigned, so what is emitted is the reading PRINTED WITH the named formulary, not the only lawful one; labelled alternatives (e.g. the widow's Epistle 1 Tim 5:3-10, squarely available to St Frances of Rome) are noted in the data and deliberately not encoded. The BVM Common is NOT authored: the RG 78 Saturday Office shares the ordinary ferial slug, so assigning a Common to it would hand the BVM Mass to every feria sharing that slug; routing it needs a subject-keyed lookup and a season-keyed choice among the Missal's five "Missae de sancta Maria in sabbato" -- new behaviour, not new data. It currently emits its feria's Mass, now pinned as such. Blast radius, measured (git archive HEAD binary vs HEAD, full 1583-9999 `colitur day` sweep, diffed): ZERO differing lines, 3 074 246 lines each side, byte-identical -- the CLI prints no citations, so this change is invisible to layers 2-5 by construction, and the sanctoral overlay perturbed nothing else. 357 tests green (344 before), 358 with the exhaustive sweep. Mutation-tested six ways, all reverted after confirming: relegating step 4 to last reddens exactly the four step-4 pins and nothing else; corrupting a Common's citation, dropping an assignment, dropping a proper Edit, and corrupting either an unreachable proper or an unreachable Common each redden their own pins. The load-bearing assertion is stated over the loaded layer rather than a hard-coded list: every sanctoral entry that can ever BE the observed office now has either a proper or an assigned Common -- fifteen failures before, zero after, and a future re-bootstrap adding a readingless class-3 feast fails there instead of silently emitting its feria's Mass.
* data(ef): carry sanctoral propers on the celebrationLukasz Kasprzak2026-08-151-209/+834
| | | | | | | | | | | | | | Celebration.citations has existed in the type, the .mli and the sexp schema since Plan 2 and has been emitted as () for every entry; the bootstrap now writes the real values for the 208 entries lectio has them for. On the celebration rather than in the lectionary table deliberately: a diocesan overlay adding a saint then carries his readings through the existing overlay algebra, with no second file to edit and no new directive. Asserted both ways -- the 13 January proper is present, and no Commemoration_only entry has readings, because in the EF a commemoration contributes an oration, not a reading.
* data(ef): bootstrap the temporal lectionary from lectioLukasz Kasprzak2026-08-141-0/+366
| | | | | | | 119 entries, Epistle + Gospel only. The generator refuses a section carrying exactly one of the two: an Epistle without a Gospel is malformed and wants investigating, not shipping. SHA-256 of the source INI is in the provenance header, as with sanctoral.sexp.
* fix(ef): three colour corrections that contradicted the Missal by nameLukasz Kasprzak2026-08-143-8/+46
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-143-2/+109
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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: a confidence raised while its revisit trigger was deletedLukasz Kasprzak2026-08-131-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Five follow-ups from the fix-round re-review, none touching a computed result. M20's note had said "moderate-high, not certain" with a specific revisit trigger attached. The fix round raised the label to "near-certain" and deleted the trigger in the same edit. Upgrading a confidence while removing the condition that would lower it again is the one move this record must not make, so the trigger is restored alongside the higher label: no primary text anywhere names the Major Litanies in a Mass-orations-count worked example, only the general II-class-Sunday rule twice over. RG 434(b) closes the Office-shaped doubt and nothing further. "WORD-IDENTICAL" overstated the relation between RG 111(b) and n. 434(b). Only the trailing "quae tamen omittitur si commemoratio privilegiata facienda sit" is verbatim in both; the openings differ, n. 434(b) recasting the rule into the orations register. The claim was self-refuting -- both texts are quoted adjacent to it -- and the argument never depended on it. Now "identical in its operative clause". And n. 434 is not "a different part of the same document": the running heads put RG 111 under Rubricae generales and n. 434 under Rubricae generales Missalis Romani, two distinct corpora bound in one volume, which is the entire force of the corroboration. The code comment had understated its own point. Also corrects the register's LT line range for n. 434(b) (3574-3576, not 3564-3570; the (b) clause is not in the cited range), and records in calendar.ml the diagnostic that channel (3) trades away: a rite whose transfer_target names a date its own disposition omits used to raise a loud, mislabelled Validate failure and is now silent at the origin. The kernel cannot distinguish that from a deliberate omission without rite knowledge it must not have, so accepting it is right -- but the signal is gone, and that should be written down rather than discovered later.
* docs(ef): fix round 1 corrections (F2-F5) -- inert fields, a date, an ↵Lukasz Kasprzak2026-08-131-2/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | attribution, RG434(b) F2: the task report's "colour/subject/names on the Litanies entry are currently inert" was false for names -- test_oracle.ml's identity axis reads Names.find on every commemoration, and the invented English name is exactly why 2026-04-25 registers as a Comm_identity_mismatch, the reason M5 had to be re-gated. Corrected precisely, field by field, in the report. F3: Easter 2027 is 28 March, not 18 April, as previously stated in the report's own "layer 4 is blind to the transfer" reasoning. The conclusion survives (28 March is not 25 April); the date is corrected. F4: "the exhaustive property sweep caught this immediately" was a wrong attribution, in the report, the register, and calendar.ml's own comment. The committed exhaustive sweep walks 1583-9998 in order and aborts at the first failure; the years actually reported (5700, 4747) were draws from prop_invariants, the default dune test run's 200-year random sample. Corrected in all three places. F5: the Litanies' privileged commemoration is due in the MASS specifically (RG 108 + RG 81), never a separate Office answer -- colitur emits one resolved day, and the M20 adjudication rests on that being the Mass reading. Stated explicitly now in M20's own note, the register, and precedence_ef.ml's own RG111(b) comment. Also added to M20 and the register: Rubricae Generales Missalis Romani n. 434(b) ("VIII - De diversis Missae partibus", "D) De orationibus", "I - De orationibus in genere"), verified word for word against all three documents -- word-identical to RG 111(b) but explicitly scoped to the Mass ("post orationem Missae"), answering the objection that RG 111 (Caput XVI, which RG 106 says governs both Office and Mass) might be read as Office-shaped. Moves the M20 adjudication from "moderate-high, not certain" to near-certain.
* test(ef): oracle allow-list for the Major Litanies, and a source-fidelity ↵Lukasz Kasprzak2026-08-131-5/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | correction M5 (the pre-existing register-cited gap this task closes) had a genuine backwards claim in its own note: it said missalemeum's single admitted commemoration on 25 April 2027 (the Sunday-conflict year) was "the Major Litanies". Checked directly against the raw fixture row while adjudicating this task's own new divergence -- missalemeum's own commemorations field there is "St. Mark"; "Pro rogationibus" (the Litanies) is the one listed as displaced. Corrected in place, both the .sexp entry and this file's own header note. M5 itself now covers only the ordinary case (25 April 2026): presence agrees now that the entity is built, identity does not (colitur's own English name vs missalemeum's Latin-ish descriptive string), the same declared comparator limit M15/M18 already document, hit here for a different reason. The real, substantive divergence the correction exposes: colitur now admits the Litanies on 2027-04-25 where missalemeum admits Mark. New entry M20, adjudicated colitur -- RG 109(f) places the Litanies in the same closed privileged list as (a)-(e), and RG 111(b)'s own text is unconditional ("the II-class commemoration is dropped if a privileged one is due", no table-order qualifier). The same mechanism already primary-source-verified and used for other RG 109 categories elsewhere in this codebase; honestly flagged as the first real, non-synthetic test of this specific admit clause, consistent with this oracle's own already-documented pattern of RG 108-111 gaps (M1, M8, M10). M18's own count moves 395 -> 394 (2027-04-25 no longer falls into "observed- identity-unresolved alone"; it moved into M20), traced to the specific date and mechanism, not merely re-baselined. data/ef/expected-divergences.sexp (the lectio allow-list) needed no change: lectio computes no Major Litanies at all, and its own row type carries no commemorations field -- layer 3 is entirely blind to this change, confirmed rather than assumed.
* feat(ef): the Major Litanies -- entity, RG80 transfer, RG109(f) privilegeLukasz Kasprzak2026-08-131-0/+88
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | RG 80 (Caput X, "De Litaniis maioribus et minoribus", A): the Major Litanies are assigned to 25 April, transferred to the following Tuesday (always Easter+2) when that date is Easter Sunday or Easter Monday. RG 81, same division: nothing is done in the Office, only in the Mass. RG 109(f) (Caput XVI): a privileged commemoration. Entity: Commemoration_only, Fixed(4,25), via data/ef/adjustments.sexp's `Add major-litanies` -- RG 81 denies it Office standing entirely, which is exactly what Commemoration_only already means to Precedence.resolve (held out of the observed contest by construction). Rank Class4 deliberately, not Class1, to keep the new RG109(f) privilege branch live rather than shadowed by privilege_of's existing "of a I-class day" branch. Colour Violet by consistency with the sibling Minor Litanies; subject Saint, the same "no special exclusion" default this codebase's other Commemoration_only entries use. Names not primary-sourced, flagged as such in the data file's own comment. Transfer: reuses the existing RG 96 placement machinery (Precedence.disposition's Transfer constructor + Calendar's place_transfers/resolve_with_injected) rather than a new candidate channel -- RG 80's own transfer is structurally the same operation RG 96 already performs for an impeded I-class feast. disposition gains a branch, checked before the Commemoration_only catch-all: the Litanies losing to winner slug "ef-easter-sunday" or "ef-easter-1-monday" is Transfer, not Commemorate. transfer_target gains a branch, checked before the general RG 96 search is even computed, returning Easter+2 directly with no search at all -- necessary, not merely simpler, since Easter+2 is itself I-class and a search from there would walk past the exact day RG 80 names (a commemoration needs no unoccupied day the way a displaced feast does). Privilege: privilege_of's previously-dead RG 109(f) branch now recognises the Litanies' own slug. No other code change -- admit's existing Class1/Class2-Sunday branches already implement "a privileged commemoration categorically takes the slot" correctly, from an earlier task. Full blast-radius measurement, adjudication of the resulting missalemeum divergence, and the mutation proofs are in the task's own report, .superpowers/sdd/2026-08-12-colitur-rg16a/major-litanies-report.md.
* 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-132-18/+49
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* fix round 1: RG 110(c)'s ordering was inverted; M19 lacked an identity gateLukasz Kasprzak2026-08-131-10/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* precedence(ef): RG 110, the inseparable Peter/Paul commemorationLukasz Kasprzak2026-08-132-8/+75
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-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").
* test(oracle): fix round 1 (F8) -- correct the M18 headline, name the blind ↵Lukasz Kasprzak2026-08-131-1/+1
| | | | | | | | | | | | | | | | | | | | 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(oracle): green -- widen five entries, add M18 for observed identityLukasz Kasprzak2026-08-131-2/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-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).
* 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).
* data(ef): fix round 1 (F3) -- eusebius-confessor is white, not lectio's redLukasz Kasprzak2026-08-121-1/+28
| | | | | | | | | | | | | | | | | | | | | | | | 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-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).