| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Task 4 of Phases 3-5: the last Rite.t field OF still needed, `readings`.
The cycle rules are CODE, cited to OLM (Ordo Lectionum Missae) 1981
Praenotanda -- verified against the real page image
(docs/research/of/olm-1981.pdf pp.32-33/"XXXII-XXXIII"), not the
document's own unreliable OCR text layer, per the design spec's own
caveat. n. 66 (with its footnote 102's worked example, 1980=C/1981=A/
1982=B/1983=C) gives the three-year Sunday cycle; n. 69 point 4 gives
the two-year weekday cycle, Year I in odd label years, Year II in
even. Both derive the "label year" the same way: one more than the
civil year Advent I opened in, per n. 66's footnote 102 itself
("nempe a prima hebdomada Adventus, quae cadit in anno civili
praecedente") -- so the cycle turns at Advent I, not 1 January, exactly
where the task brief said to get it right. The design spec's own
citation for the weekday rule, "Praenotanda n. 649", does not survive
a direct check against the primary source (search finds "649" only in
unrelated index/page-number entries); corrected here to n. 69, the
paragraph the rule's own Latin text actually sits under, confirmed by
the page image's own printed margin number.
The data is bootstrapped from lectio's of-lectionary.ini (988 keys,
niedziela.pl, harvest 2020-2025) by tools/bootstrap_lectionary_of.ml
-- OCaml, not the brief's own suggested .py: tools/bootstrap_lectionary
.ml already established this exact shape for EF, including a real
safety net ([assert_reachable], sweeping Rite_of.Temporal_of.temporal
AND the real merged sanctoral layer directly) that a second-language
reimplementation would either duplicate or lose. Handles two real
data anomalies found while building it: one malformed ini line (a
Polish Septuagint-numbering annotation for Sirach 3, "Syr 3,2-6.12-14"
against OLM/CEI/USA's shared Nova Vulgata, matching the design spec's
own sec5 finding); and two Sunday-cycle-labelled bases (Annunciation,
Immaculate Conception) where a scraping-year artifact left one of
three cycle letters carrying a different day's Mass entirely --
resolved by a general, mechanical 2-of-3 majority rule, not a
per-saint hand edit, and logged.
Coverage measured in both directions, per the brief's own Step 1:
- 1 of 365 days in civil year 2026 (25 December, the Christmas DAY
Mass) has no Temporal_of-slug match anywhere in lectio's 988 keys --
only the Vigil is present. Named in the data file's own header.
- 0 of 438 distinct lectio bases map to no colitur slug, after 19 are
deliberately excluded (late-Advent/Christmas-season DATE-keyed
duplicates lectio also carries in a WEEKDAY-keyed form colitur's own
slugs actually match -- Lectionary.t has no date-keyed lookup at
all, so the date-keyed family is transcription-inert, not silently
dropped: named explicitly, not a residual).
Lectionary_of.readings is three steps (no Commons indirection, unlike
EF -- out of this task's scope): the observed celebration's own
embedded citations; else, for a real sanctoral winner, its own slug
looked up directly (flat, then both cycle letters); else the day's
own temporal slug, same lookup. No preceding-Sunday fallback: OF's own
two-year cycle assigns every Ordinary Time weekday its own reading by
design, and no OF norm was found instructing otherwise.
Tests (test/test_lectionary_of.ml, 12 cases): a cycle-arithmetic table
straddling Advent 1980/1981/1982/2025 inside single civil years,
reproducing OLM n.66's own worked example directly; SHA-256 pins on
both the emitted file and lectio's own source (embedded in the
provenance header); a pinned, NAMED 2026 coverage result (364 resolve,
exactly {25 December} does not -- never a bare count); two resolution-
chain spot checks (a plain ferial, and a saint's day beating the
ferial it would otherwise fall on); and a real subprocess test that a
missing lectio source file fails the generator loudly, non-zero exit,
no output written -- the exact bug Task 1's own generator shipped and
needed a review round to fix.
dune test: exit 0, 856 tests. make check (COLITUR_EXHAUSTIVE_SWEEP=1,
full 1583-9999 sweep): exit 0, 862 tests, ~342s, both run unpiped in
the foreground. git diff --stat v1.0.0..HEAD -- lib/rites/rite_ef/
lib/kernel/ data/ef/ still empty.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Fix round 1 for Task 3, addressing review findings.
Rename the exported creed function from `credo` to `creed` across the
.ml, .mli and test call sites, so the OF rite bundle can write
`creed = Rubrics_of.creed` with no gratuitous mismatch against
Rite.t's own field name, matching Rite_ef.Rubrics_ef.creed's own
naming. IGMR n. 67's own heading is "Professio fidei" and its body
says "Symbolum", never "Credo" -- documented as a comment on the
now-correctly-named function rather than kept as the exported name.
Local test helpers (credo_on_temporal, check_credo, test_credo_*) and
Alcotest description strings keep the Latin shorthand, since only the
call sites against RO.creed needed to change.
Corrected two comment inaccuracies:
- The Annunciation (25 March) is NOT always inside Lent, unlike St
Joseph (19 March): 25 March sits after Easter's own earliest
possible date (22 March), so in an early-Easter year (2008, Easter
23 March) it falls inside the Easter Octave instead, or is
transferred under Normae n. 60/5. No functional effect (gloria/creed
read observed/temporal as actually resolved), but the stated reason
was wrong.
- The Requiem-silence argument's counts: three All Souls Mass
formularies (not two), and roughly 147 Gloria+Credo markers combined
elsewhere in the Missal (not "over 150", which conflated Gloria
alone with the combined figure) -- recounted directly against a
fresh pdftotext -layout extraction rather than estimated.
Added: an independent corroborating citation for the Holy Thursday /
Easter Vigil Gloria exception, Vigil n. 31 -- the Easter Vigil's own
praenotanda ("VIGILIA PASCHALIS IN NOCTE SANCTA"), a THIRD
independently-numbered rubric set inside the same Missal PDF,
confirming the Vigil's own Gloria directly rather than resting solely
on the Holy Thursday rubric's forward-looking "usque ad" clause.
dune test: exit 0, 845 tests. make check (COLITUR_EXHAUSTIVE_SWEEP=1,
full 1583-9999 sweep): exit 0, 851 tests, 330.3s, both run unpiped in
the foreground. git diff --stat v1.0.0..HEAD -- lib/rites/rite_ef/
lib/kernel/ data/ef/ still empty.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Task 3 of OF Phases 3-5: the celebrant-rubrics module for the OF rite,
supplying three of Rite.t's four remaining fields.
creed/gloria implement IGMR n. 53 (Gloria) and n. 67-68 (Symbolum),
both quoted in full in the module header. temporal is read, not
observed, for both Sunday clauses: Temporal_of.temporal tags every
Sunday of Advent/Lent/Easter Sollemnitas (the privileged-season
convention), so an observed.rank test alone would wrongly grant Gloria
on an Advent or Lent Sunday, which n. 53's own "extra tempus Adventus
et Quadragesimae" explicitly withholds. Credo is deliberately narrower
than Gloria: n. 68 has no "et festis" clause, so an ordinary Festum
does not get the Creed, unlike EF's RG 475(b)/(c). Two Missale-proper
exceptions (Holy Thursday evening Mass, the Easter Vigil Mass) are
cited from the Missal's own "Dicitur Gloria in excelsis" rubric, not
the IGMR, which is silent on both. The Requiem question is likewise
IGMR-silent (nn. 379-385 say nothing about Gloria/Credo); flagged as
an inference from the Missal's own consistent marker pattern, applied
only to the one Requiem-shaped slug the shipped OF data can construct
(all-souls), the same closed-population discipline Rubrics_ef's own
Colour.Black proxy uses.
preface returns None unconditionally, a measured verdict rather than
a stub. The module header transcribes the 2002 Missal's own "INDEX
PRAEFATIONUM" in full: nine of Preface.t's 15 EF-cited constructors
name an OF occasion with multiple distinct texts (Nativity x3, Lent
x4-9, Easter x5, Ascension x2, Holy_spirit x2, Bvm x5, Apostles x2,
Common split across two independent 7/8-member families, Requiem x5)
-- structurally lossy to collapse into one constructor. The other six
(Epiphany, Trinity, Sacred_heart, Christ_the_king, St_joseph,
Holy_cross) match cardinality with a single OF text apiece, and were
checked and rejected anyway: Preface.t's own constructors are RG-cited
by construction, and IGMR n. 364's own "quibus Missale Romanum
ditatur" (prefaces the Missal is ENRICHED with) is direct textual
evidence the 2002 collection is not a bare carry-over -- corroborated
directly for Sacred Heart, whose OF text was read and found to be a
different composition from its RG 491 namesake. Reusing any of the
six on cardinality and theme alone would be the exact "sounds similar"
trap the task brief warns against.
test/test_rubrics_of.ml: 26 table-driven cases. Every temporal-origin
row builds observed via Temporal_of.temporal on a real date; every
sanctoral-origin row (a solemnity in Lent, an ordinary Festum, a
weekday obligatory memorial, All Souls) pairs a real Temporal_of.temporal
result with an observed record copied verbatim from
data/of/calendar-2002.sexp, since no full OF Rite.t/Calendar pipeline
exists yet to derive one. Includes same-date Gloria/Credo pairs that
prove the two rules genuinely diverge (a Sunday of Advent, an ordinary
Festum) rather than one silently mirroring the other.
dune test: exit 0, 845 tests. make check (COLITUR_EXHAUSTIVE_SWEEP=1,
full 1583-9999 sweep): exit 0, 851 tests, 303.6s, both run unpiped in
the foreground. git diff --stat v1.0.0..HEAD -- lib/rites/rite_ef/
lib/kernel/ data/ef/ is empty.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Adds data/of/amendments/*.sexp: 13 overlay files, one per decree,
carrying the General Roman Calendar's amendments since the 2002 typical
edition (docs/research/of/PROVENANCE-amendments.md's own 15-item
inventory, items 10-12 sharing one decree; items 2 and 3, though issued
the same day, carry different protocol numbers and are counted as two
decrees). 14 Add directives (Padre Pio, Juan Diego, Guadalupe, John
XXIII, John Paul II, Mary Mother of the Church, Paul VI, Loreto,
Faustina Kowalska, Gregory of Narek, John of Avila, Hildegard of Bingen,
Teresa of Calcutta, John Henry Newman) and 2 Edit directives (Mary
Magdalene's rank memoria->festum; Martha/Mary/Lazarus's name widened,
same slug, same date and rank -- a continuation of the existing
memorial per the decree's own text, not a suppression and replacement).
Mary, Mother of the Church is the one movable entry (Easter_offset 50,
the Monday after Pentecost) -- verified against the decree's own text
and against Colitur_kernel.Computus.gregorian_easter in three real
years, no kernel change needed.
data/of/calendar-2002.sexp is untouched, per spec sec4.1.
Adds test/test_amendments_of.ml: every file parses, each has a pinned
SHA-256, applying all 13 in decree order yields 222 entries (208 base +
14 Add) with an empty Overlay.merge diagnostics list, and Mary Mother of
the Church resolves to the Monday after Pentecost in three real years.
Two Precedence_of interactions are recorded, not fixed (out of scope for
a data-only task): a movable Memoria_obligatoria can land on an existing
fixed one (verified for 13 June 2011), a genuine band tie Normae n. 14
does not address and Precedence_of.ml does not implement; and adding
Hildegard of Bingen changes which of two ad-libitum memorials on 17
September Precedence.resolve reports as observed, by alphabetical
tie-break alone.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Four fixes from fix round 2 review:
classify_subject's "maria"/"b.m.v" substring test over-matched 12 saints
who merely carry "Maria" in their own name (Maximilian Mary Kolbe, John
Mary Vianney, Mary Magdalene among them) as Bvm. Replaced with an
explicit BVM_DATES table of the 13 genuinely Marian entries. Bvm 25 -> 13.
The provenance header claimed lectio is "never a source", which omitted
that slugs and English names both come from it. Corrected to state
exactly what does (slugs, en names) and does not (every substantive
field) come from lectio. A missing lectio file used to degrade silently
to a different SHA-256 with no en names and no warning; it now fails
loudly. lectio's own SHA-256 is now pinned alongside the Missal PDF's.
Four more entries carried a second pdftotext artifact distinct from the
letter-spacing already handled -- a combining diacritic rendered as a
stray spacing character (Kim Taegŏn/Chŏng Ha-sang, Đũng Lạc, Makhlūf,
Kęty). Hand-repaired the same way Peter Damian was, each corroborated by
the identical corruption recurring in the Missal's own index.
precedence_of.ml's PHASE 3 HAZARD comment about All Souls (2 November)
was asserting a gap that no longer exists now that OF sanctoral data
ships. Added test_all_souls_beats_an_ordinary_sunday, which resolves the
shipped All Souls entry against a real per-annum Sunday (2025-11-02)
through the actual Precedence.resolve pipeline, and updated the comment
to record the resolution instead of demanding it.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Both are printed in the 2002 calendar table, immediately after 30 June, as
prose headings rather than (kalends, day) rows -- the shape parse_rows'
generic movable-heading skip branch was built for, which is why the first
pass silently dropped them. They belong in the transcription, not in
Temporal_of: adding them completes the table this file transcribes rather
than amending the temporal cycle.
Produced as Date_spec.Easter_offset entries (68 and 69 respectively), the
same variant already used for EF's Rogation Wednesday and needing no
kernel change. Pentecost is Easter+49, so the Friday and Saturday after
the Second Sunday after Pentecost are Easter+68/+69 -- verified against
three real Easter dates (2026, 2027, 2035), not merely computed on paper.
The extractor now recognises these two headings specifically among the
seven "Dominica/Feria/Sabbato ... :" headings the table contains; a full
audit of the other five confirms each is already covered by Temporal_of
and correctly stays excluded here. 206 -> 208 entries.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Extracted from the Latin typical edition, which is the authority; lectio's
roman-calendar.ini is a cross-check only and every divergence is adjudicated
against the Missal in the provenance header.
A blank grade column means Memoria ad libitum, per the calendar's own
footnote, rather than a missing value. 206 entries; 1 January, 6 January and
25 December are deliberately excluded because Temporal_of.named already
computes them, and shipping them here too would create a duplicate
candidate for the same day.
Colour is derived from IGMR n. 346, cited per class in the extractor; the
lectio cross-check surfaces one rank divergence (22 July, Mary Magdalene --
lectio reflects the 2016 post-2002 elevation decree, out of scope here) and
17 colour divergences, all adjudicated in the provenance header.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Temporal_of.named claimed 24 December unconditionally as
of-nativity-vigil (Sollemnitas), and temporal's dispatch matched named
before sunday_slug. On a Sunday 24 December, the Fourth Sunday of
Advent -- Tabula I.2, Normae n. 5's own privileged Sundays of Advent,
Lent and Easter -- was silently replaced by the Vigil.
named now returns None for 24 December when that date is itself a
Sunday, so temporal's dispatch falls through to sunday_slug and the
day resolves as of-advent-sunday-4. The Vigil Mass is an evening Mass
of the following solemnity, not an office belonging to 24 December's
own civil day -- the same civil-day-granularity reasoning already
applied to Holy Thursday (Precedence_of.band's entry-1 comment) and to
expected-divergences-litcal.sexp's L1 entry. Every non-Sunday
24 December is unaffected.
Audited every other named entry for the same latent shape (see
.superpowers/sdd/of-r8-advent-iv-report.md): none of them has it,
either because the date can never fall on a Sunday, or because the
date IS the definition of that Sunday (Palm Sunday, Easter, Pentecost,
Trinity, Christ the King), or because the competing movable-Sunday
windows are constructed to exclude that date.
Added test_nativity_vigil_yields_to_advent_sunday, covering
2028-12-24 and 2034-12-24 (both inside the litcal fixture window) and
the 2026-12-24 non-Sunday control. Re-ran the litcal layer: no
allow-list counts moved, since it compares only season and
Ordinary-Time week, and both readings of 24 December are "advent"
either way. Updated test_precedence_of.ml's "entry 3, not 9" comment,
which had carried this as a known, unfixed defect, to describe the
fix; its own pinned assertion (a hand-built Thursday candidate) needed
no change.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Fix wave from the final whole-branch review of OF Phase 2 (0 Critical,
5 Important, 8 Minor). Applies the five items ruled in-scope and records
two more, per the controller's R7/R8/R9 rulings.
Fixes:
- temporal_of.ml: season-boundary header cited "Normae n. 71-77", a range
that does not exist (the Normae end at n. 61) and collides with real IGMR
nn. 71-77 (Preparation of the Gifts) in the same PDF -- EF leakage from
RG 71-77. Corrected to Normae Titulus II, nn. 17-47, with a note against
reintroducing the wrong range.
- precedence_of.ml entry 3: added the Tabula's second clause (Commemoratio
omnium fidelium defunctorum / All Souls) to the comment, and recorded the
Phase 3 hazard -- Vocab_of.rank has no constructor for it yet, and every
natural tagging choice gets 2 November's precedence wrong in a different
way. No code change; nothing can construct the entity yet.
- precedence_of.ml transfer_target's search: added a domain_max_date guard
(following Rite_ef.Precedence_ef's existing shape and reasoning) so the
walk can no longer probe Computus past 9999-12-31, and it now returns the
last date visited on bound exhaustion instead of failwith-ing. .mli
updated to drop the @raise Failure clause.
- precedence_of.ml is_privileged_sunday: added its own inline Tabula I.2
citation, matching its sibling helpers.
- precedence_of.ml entry 10: trimmed the reused "universal or temporal-origin"
comment -- Temporal_of never constructs a Memoria_obligatoria candidate, so
the temporal-origin half was vacuous there.
Recorded without fixing (both comment-only, per explicit scope ruling):
- test_precedence_of.ml: corrected the entry-3 Nativity Vigil test's
characterisation. The pinned band-30 assertion (2026-12-24, a Thursday) is
correct, but is not the value on a 24-December Sunday (e.g. 2028, 2034),
where is_privileged_sunday instead bands the same candidate 20. Named the
underlying Phase 1 defect this exposes -- named() claims 24 December
unconditionally and is matched before sunday_slug, so the Fourth Sunday of
Advent gets no office at all in those years, invisible to the litcal layer
-- as known and carried to the next task.
- precedence_of.mli transfer_target: documented Normae n. 56(f) (St Joseph
on Palm Sunday anticipates backward to 18 March) as a known, cited,
unimplemented fourth transfer rule, and named the underlying kernel
constraint (Rite.t.transfer_target's strictly-later obligation, justified
only by the EF's RG 96) as the reason a real fix needs a kernel change.
dune test: 799 tests, exit 0. make check (exhaustive sweep): 805 tests,
exit 0, 224.7s. No kernel/rite_ef/data changes (git diff empty).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Three rules, in priority order: the Annunciation in Holy Week goes to
Easter+8; any other solemnity on a Sunday of Advent, Lent or Easter goes to
the following Monday (n. 5, which n. 60 defers to explicitly), except on Palm
Sunday or Easter Sunday; otherwise the nearest later day free of Tabula
entries 1-8.
The n. 5 Monday rule is easy to miss -- n. 60 names it only by cross
reference, and reading n. 60 alone yields a single search rule where the
sources give three.
Shaped to match Rite.t.transfer_target so a later phase wires it unchanged,
with its own step bound: Calendar's round guard bounds rounds, not one call's
internal search.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The prior comment claimed of-nativity-vigil is 'not a distinct celebration' -
wrong: Temporal_of.named (temporal_of.ml:230) constructs it as its own
Sollemnitas-rank candidate on 24 December, a genuine contestant in
band/Precedence.resolve.
The real reason None is safe is structural, not that. The Nativity is
Tabula entry 2 (band 20); only entry 1, the Paschal Triduum (band 10),
bands lower. The Triduum's Easter-2..Easter window is confined to 20
March-25 April because Gregorian Easter never falls outside [22 March, 25
April] over the whole 1583-9999 domain (measured exhaustively in
test_computus.ml, not assumed), so it can never reach 25 December. The
Nativity therefore always keeps its own day and its vigil can never be
orphaned by a transfer or reduction.
Behaviour is unchanged: vigil_feast still returns None unconditionally.
RG 33 (EF-only) and Normae nn. 11/13 remain the reason the hook exists at
all and returns None for every other candidate.
|
| |
|
|
|
|
|
|
|
|
| |
admit returns the empty list because disposition never returns Commemorate;
vigil_feast returns None because the OF has no vigil office that its feast's
movement could orphan -- 'of-nativity-vigil' is a Mass formulary of the
solemnity, not a separate celebration.
Both are argued from the sources rather than stubbed, and Precedence_of.rules
now assembles the four functions the kernel resolver consumes.
|
| |
|
|
|
|
|
|
|
|
| |
An impeded solemnity transfers; every other loser is omitted for that year
('Reliquae celebrationes eo anno omittuntur').
Commemorate is never returned, and that is the rule rather than a gap: the OF
has no commemoration of a losing celebration in the EF's sense, and an
optional memorial is an election rather than a commemoration. A property over
every rank pairing asserts it, so a later edit cannot quietly introduce one.
|
| |
|
|
|
|
|
|
|
|
| |
A hand-transcribed 13-entry table is only trustworthy if nothing the engine
constructs falls through it. Sampled property plus an exhaustive sweep behind
COLITUR_EXHAUSTIVE_SWEEP, matching the claim Precedence_ef.band already
carries for RG 91's 28 entries.
Mutation-proved rather than assumed: deleting the entry-13 branch reddens it
on a named date.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Entries 10-13. Entry 12 is one undivided row -- the Tabula draws no
universal/proper split for optional memorials, unlike entries 3/4, 7/8 and
10/11 -- so it deliberately does not read the layer.
Entry 13's four clauses need no date arithmetic of their own: every
privileged feria is entries 2 and 9, tested earlier in the chain, so what
reaches the final branch is exactly the residue those clauses name.
Entry 10 uses [not (is_proper layer)], not the brief's original
[is_universal layer]: is_universal was deleted as dead code in Task 2,
because every temporal-origin candidate carries layer = "temporal", never
universal_layer, so a positive is_universal test can never match one --
the same correction entries 3, 5 and 7 already apply.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Fix round 1 (coordinator review). The Nativity Vigil (24 December,
Sollemnitas) bands at entry 3 (30) rather than entry 9 (90) as a direct
consequence of this task's ruling, but nothing pinned it -- a future
branch-reorder (e.g. inserting an entry between 3 and 9, or loosening
entry 9's date guard) could silently revert it to 90 with the suite
green.
Adds one row to part2_cases with a comment recording: the Tabula's own
entry 9 textually covers 24 December as a late-Advent feria, yet Phase
1 gives that civil day the of-nativity-vigil identity at Sollemnitas
because the Vigil Mass is celebrated that evening -- the same
civil-day-granularity shape Holy Thursday already settles (entry 2,
not entry 1); Phase 2 classifies Phase 1's emitted identity rather
than overriding it. Unobservable on the universal calendar today (no
competing candidate on 24 December); live under a proper/diocesan
overlay, where a proper solemnity (entry 4, band 40) loses to the
Vigil at 30 but would beat it at the textually-arguable 90.
No production code change -- test-only, per the coordinator's ruling
to pin current behaviour rather than alter it.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Entries 5-9. Entries 5 and 7 differ only by subject -- 'Festa Domini'
against 'Festa beatae Mariae Virginis et Sanctorum' -- so they key on
Celebration.t.subject, the same field RG 91 entry 14 uses on the EF
side, never on the slug.
Entry 9's three clauses (late-Advent ferias from 17 December, the
Nativity octave, Lenten ferias) are what separates a privileged feria
from the ordinary one at entry 13.
CORRECTION to the task brief, applied here rather than after: entries
3, 5 and 7 test 'not (is_proper layer)', not 'is_universal layer'.
Every temporal-origin candidate Temporal_of.temporal constructs
carries layer = "temporal" unconditionally, never universal_layer, so
a positive universal-layer test silently excluded every temporal-cycle
solemnity and Lord-subject feast from these entries -- Corpus Christi
came out unclassified outright, and Trinity/Christ the King/Holy
Family/the Baptism of the Lord landed one entry too low. is_universal
is now dead and removed; entry 3's branch (written in Task 1) is
amended along with the new entries 5 and 7. Only entries 4 and 8 still
test is_proper directly, matching the Tabula's own proper-calendar
rows.
Also fixes a pre-existing typo in the brief's own 'entry 6: a Sunday
per annum' test row: rank was Sollemnitas, which -- being tested at
entry 3, earlier in the chain -- made the row fail regardless of the
is_universal/is_proper question, since no real Sunday per annum is
ever Sollemnitas. Changed to Festum, matching the adjacent 'Sunday of
Christmas time' row and real Temporal_of output.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
The Tabula dierum liturgicorum's entries 1-4, one band branch each, scaled
x10 as Precedence_ef's own table is. The Triduum is identified structurally
by Easter offset because Temporal_of emits Good Friday and Holy Saturday as
ordinary Lent week-6 ferias, leaving no slug to key on.
Holy Thursday sits at entry 2, not entry 1: the Tabula's own entry 2 runs
'a feria II ad feriam V inclusive' and the Triduum opens with an evening
Mass inside that civil day. Same granularity decision the litcal layer's L1
records on the season axis.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Adds a sixth-lineage external validation layer for the OF rite module's
Phase 1 temporal cycle, targeting the single highest-risk function that
report named: the two-block Ordinary Time week arithmetic (Normae n. 44),
which has no external witness anywhere in Phase 1's own suite and whose
output selects the Mass formulary, not merely a label.
Witness: litcal (Liturgical Calendar API), Apache-2.0, already archived
and SHA-256-pinned by the sibling lectio project. AELF was considered and
correctly excluded earlier (its CGU forbids redistribution) -- litcal is
what it was replaced with.
- tools/extract_litcal_ordo.py verifies all twelve archived
calendar-YYYY-en.json files (2024-2035; the task brief said eleven,
but twelve are actually pinned in lectio's manifest -- all twelve are
used) against lectio's own manifest.tsv, then builds one fixture
spanning the contiguous 4382-day range those twelve liturgical-year
files cover.
- test/fixtures/litcal-temporal-2024-2035.sexp: one row per day, season
and (where witnessed) Ordinary Time week, with full provenance,
licence, per-year Easter dates and the row-selection rules in its own
header.
- test/test_litcal_of.ml calls Temporal_of.temporal directly (no Rite.t)
and compares 1:1 against the fixture: zero Ordinary Time week
mismatches on all 1876 witnessed days (zero tolerance, no allow-list);
the only season divergence class is the Sacred Triduum, which litcal
tags with a season value colitur's vocabulary deliberately has none of
-- one cited allow-list entry, data/of/expected-divergences-litcal.sexp,
36 rows, exact.
- Mutation-tested: dropping the backward-from-34 adjustment reddens this
layer (1511 of 1876 days) plus three pre-existing Phase 1 tests; the
mutation was not committed.
Does not touch lib/rites/rite_ef/, data/ef/, or lib/rites/rite_of/ --
this validates Phase 1, it does not change it. Full suite: 786 tests via
dune test, 791 via make check, exit 0 both; lib/bin diff empty throughout.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The first code for a second rite. lib/rites/rite_of/vocab_of implements
the OF's five-way rank vocabulary (Sollemnitas/Festum/Memoria_obligatoria/
Memoria_ad_libitum/Feria) and five-season vocabulary (Advent/Christmas/
Lent/Easter/Ordinary_time), each constructor cited against the 2002
Missale Romanum's Normae universales and the Tabula dierum liturgicorum.
temporal_of implements season boundaries, week numbering — including
Ordinary Time's own two-block resumption, derived from the Missale's own
"HEBDOMADA I/XXXIV 'per annum'" headings and empirically verified across
the whole 1583-9999 domain — named temporal days, and Sunday/ferial
slugs. Both satisfy Colitur_kernel.Temporal.RITE with no kernel change.
No Rite.t is assembled and no CLI wiring is added (Phase 2's own scope);
lib/rites/rite_ef and data/ef are untouched, verified byte-identical
against the v1.0.0 tag across a domain-spanning sample.
test/test_temporal_of.ml adds unit tests for every boundary and named day
plus seven QCheck properties (seasons contiguous, Ordinary Time weeks in
1..34, Advent always four Sundays, slug uniqueness, weekday agreement,
determinism, consecutive liturgical years partition civil time), with a
committed exhaustive sweep mirroring test_validate.ml's own convention.
Full account, including the Ordinary Time derivation's evidence and a
list of EF concepts that do not carry over, in
.superpowers/sdd/of-phase1-report.md (untracked, gitignored).
|
| | |
|
| | |
|
| |\
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
colitur now prints what a real ordo prints for the Mass: which formulary is
said and how it was reached, the Gloria, the Creed, the preface, and the
commemorations with their Low-Mass/sung distinction. colitur rubrics joins
day and readings.
Four defects were found and fixed on the way, each by an external witness
rather than by inspection: the Creed said at Requiem Masses (RG 476(f)),
the missing bissextile shift of St Matthias and St Gabriel (2 041 leap
years), Rogation Monday and Tuesday coloured violet in Paschaltide (RG
119(b)), and the ferias after the Ascension resuming the wrong Sunday's
Mass rather than the Ascension's.
Validation gained a sixth layer and then some: the preface is checked
against three independent publishers over seven witness-years (FIUV, three
LMS editions, three extraordinaryform.org editions), none of which shares
the Divinum Officium -> missalemeum -> lectio lineage the older layers all
descend from.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Both entries reasoned correctly that these feasts are not in the universal
calendar, then recommended adding them to CLAUDE.md's list of sanctoral
entries MISSING from colitur. Those cannot both be true, and acting on the
recommendation would add a particular-calendar feast to the universal core
-- what binding decision 2 exists to forbid.
The Missal classifies both itself, under "Missae pro aliquibus locis":
scan1.txt:52019 for the Miraculous Medal, 48793 for St John before the
Latin Gate. Masses for some places.
So they are not gaps. They are particular feasts colitur correctly excludes
and an overlay would supply, the shape poland.ini and benedictine.ini
already demonstrate; the ordos carry them because those ordos serve
communities that keep them. Verdicts unchanged, now resting on the Missal's
own words rather than on background knowledge of the apparition.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Extends the preface comparison (RG 482-499) with a third, independent
publisher, extraordinaryform.org's three annual Ordo editions
(2024-2025, 2025-2026, 2026-2027), previously declined for two reasons
that are now resolved:
- "Advent" is not a preface: RG 494(b) grants the Trinity preface on
every Advent SUNDAY, RG 498 the residual Common on every Advent
FERIA; this source's own "Advent" label covers both indiscriminately
(confirmed live on all 11 non-impeded Advent Sundays in the corpus).
Classified by the day's own civil weekday, not a static table.
- The known Vigil-of-St-Lawrence gap is reconfirmed, with a nuance not
present in the earlier audits: colitur's own RG33-third-trigger now
omits the vigil in some years too, so the corpus's gap and colitur's
answer coincide in 2025 (a full match, not a coincidence) while 2027
still shows the classic identity-wrong-but-preface-invisible shape.
Re-derives the known menu-trap office filter (Requiem-skip, "and "-chain)
against the live JSON and finds a second, general pattern: "Saturday of
Our Lady" (RG78's BVM Saturday Office), whenever listed, is
unconditionally the office -- checked exhaustively across all 38
instances in the corpus, zero counter-examples. A third, generic
"absorption" rule was deliberately not built: it would resolve 2 of the
11 residual divergences but wrongly misfires on a structurally identical
but semantically different shape (an optional Rogation-day Mass option).
The JSON's own extraction carries a genuine classifier gap: parse_ordo.py's
hardcoded PREFACES set omits "Christ the King", misfiling it into comms;
recovered in the generator, not left blank.
11 of 1088 comparable rows diverge, resolving to 7 adjudicated root
causes (E1-E7): two Commemoration_only Marian titles reduced to
commemorations (Mt Carmel, Ransom), two genuine sanctoral data gaps
cross-confirmed absent by the FIUV/LMS witnesses (Miraculous Medal,
St John before the Latin Gate), two single-witnessed efdotorg outliers
against FIUV/LMS agreement (St Michael's Dedication, All Saints on a
Sunday), and one isolated source labelling slip.
Mutation-tested: corrupting the RG495 BVM-Saturday clause reddens 9
tests across this new layer and both existing Ordo witnesses.
Per-edition agreement: 358/363 (2024-2025), 358/363 (2025-2026),
361/362 (2026-2027).
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
RG 497 ("in Missis festivis et votivis Apostolorum et Evangelistarum")
carries no natalicium restriction, unlike RG 475(e)'s Creed clause --
preface_apostle_slugs already includes one non-natalicium sibling (In
Commemoratione S. Pauli, 30 June) on this exact reasoning.
conversion-of-st-paul (25 January) was left off pending a witness: the
FIUV Ordo's own single window has 25 January impeded by a Sunday.
Now witnessed four times, two independent publishers, four civil
years: the Latin Mass Society Ordo's 2023-2024 and 2024-2025 editions
both read "Pr of the Apostles" on their own unimpeded 25 January
(2024, 2025); extraordinaryform.org's 2024-2025Ordo.pdf and
2026-2027Ordo.pdf independently agree on their own unimpeded years
(2025, 2027, spot-checked, not wired in as a fixture). Every source's
2026 edition agrees 25 January is impeded that year and produces no
data point at all. No source disagreed with the textual reading.
Surveyed every other Apostle/Evangelist-named slug in
data/ef/sanctoral.sexp before concluding the list needed exactly this
one addition: the Dedication of the Basilicas of Sts Peter & Paul (18
November) is confirmed NOT an RG 497 trigger (all three LMS editions
read "Pr of the Dedication of a Church", not "Apostles" -- it is about
the buildings, not the Apostles in person); the Vigil of Sts Peter &
Paul (28 June) is confirmed "Common Pr", corroborating the pre-existing
"no vigil ever reaches this branch" comment.
Blast radius, measured exhaustively (1583-9999, new permanent sweep in
test_rubrics_ef.ml): 7217 domain years have 25 January unimpeded and
observed; all 7217 now read Apostles, zero exceptions.
Claude-Session: https://claude.ai/code/session_017ZBxCCRM2ojnBupp3SBxV9
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Extends tools/extract_lms_ordo.ml's row type with a praef field (the
first "Pr of ..." / "Common Pr" match in each day's universal block,
same first-in-reading-order discipline already used for Gl/Cr) and
regenerates all three LMS fixtures. Also brings lms-ordo-2024-2025.sexp
under the generalised, probe-verified provenance template the Witnesses
task previously added only for the two newer editions -- it had kept
Task 6's original hand-written header.
Characterisation finding: this Ordo prints OPTION LISTS ("Pr of X or Pr
of Y or Common Pr"), not a single value per day, and several named
options (Martyrs, All Saints and Patron Saints, the Dedication of a
Church, the Most Holy Sacrament, St John the Baptist, the Angels) are
genuinely absent from RG 484-497's own fourteen named prefaces. Every
instance found in the universal block pairs such an extra with a
genuine RG-482 answer, so test/test_lms_ordo.ml compares by membership
(classify_praef_options, a 15-entry prefix table split on the
standalone token "or"), not string equality.
Opposite-prediction probes (Nativity/Apostles/Requiem) are hard-
verified inside the extractor itself before any fixture is trusted, the
same discipline already used for the Creed column.
Result: 396/396, 399/399, 398/398 comparable rows agree across the
three editions (Good Friday excluded per edition, no Mass that day),
zero allow-list entries needed.
extraordinaryform.org's own three editions were characterised but
deliberately not wired in this pass -- see
.superpowers/sdd/2026-08-21-colitur-celebrant-rubrics-phase1/preface-witnesses-report.md
for the full account (the field is genuinely per-day, contrary to a
naive header-count read, but carries its own classification anomaly
during Advent and reconfirms the corpus's known St Lawrence vigil
defect, and building a full extractor for it is a separate, comparably
large task not needed to decide the RG 497 question this same report
settles).
Claude-Session: https://claude.ai/code/session_017ZBxCCRM2ojnBupp3SBxV9
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Item 2 of Phase 3 (celebrant-rubrics-phase1), the bulk of this phase
and the last EF Mass rubric this project scoped: which preface is
said, deferring to seasonal/proper-title rules for the fourteen named
prefaces, then RG 498's Common residual.
RG 482 gives the resolution chain: the Mass's own proper preface,
failing that the seasonal one, failing that Common. Read literally,
RG 484-497 look like fourteen separate rules, but each numbered
rubric's own propria/de-Tempore pair produces the SAME preface
identity either way, so the whole chain collapses into one priority-
ordered decision: title/mystery triggers (Holy Cross, Sacred Heart,
Christ the King, Trinity, St Joseph, BVM, the Nativity octave, the
Apostles, Epiphany), each independent of season, then six seasonal
windows (Nativity, Epiphany, Lent, Holy Cross/Passiontide, Easter,
Ascension, Holy Spirit, Trinity-for-ordinary-Sundays), then Common.
The "one genuinely unproven piece" the design spec worried about --
per-feast proper prefaces extracted from the Missal's propers at scale
-- turned out not to be a large-scale extraction problem at all: every
one of the fourteen propers is a closed, small, subject/slug-keyed
trigger (mirroring Precedence_ef.band's own RG 91 table), not
thousands of individual saints' pages. The one genuine open question
(RG 488, the Chrism Mass) is N/A: this engine resolves one Mass per
civil day and has no separate Chrism-Mass dimension.
Preface is a new kernel type (lib/kernel/preface.ml[i]), not an
EF-specific one, the same placement as Colour/Subject/Mass_formulary:
Liturgical_day.t is parameterised only over season/rank, so any field
it carries generically must live in the kernel even though only EF
constructs a value of it today. Wired exactly as creed/gloria were
(Rite.t.preface, Calendar.ml, Rite_ef.context), but Preface.t option,
not a bare bool: unlike creed/gloria, a preface is said only at a
Mass, and Good Friday (1955-restored Holy Week) resolves an observed
celebration but has no Mass at all -- None is the honest answer there,
and also the neutral value an unimplemented rite returns.
Two priority-order findings only the oracle settled, not derivable
from the Latin text in isolation, both cross-checked against 358
individually classified entries in the FIUV Ordo's own praef column
(test/fixtures/fiuv-ordo-2025-2026.sexp, already captured, wired up
here as a new comparison axis): RG 484(b)'s own "except Masses with a
proper of the divine mysteries or Persons" is narrower than every
other window's implicit exception (an Apostle inside the Nativity
octave is overridden to Nativity; outside it, keeps his own preface
even inside another window); and RG 495's "et votivis" half is live
for the one office this engine models without a votive-Mass dimension
(the Saturday Office of the BVM), which also proved a vigil is not a
"festum" for this purpose (the Assumption's own vigil takes Common,
not BVM, correcting an initial reuse of Precedence_ef.marian_slugs
that had no reason to make that distinction for its own, different
rubric). A third, RG16(a)-shaped fix landed the same way: RG 494(b)'s
own Trinity grant must read the day's TEMPORAL season, not the
celebration that actually won it, or a Class1 feast with no preference
of its own (All Saints) wrongly falls to Common on a Sunday it merely
commemorates.
colitur rubrics gains a sixth TAB-separated column. Domain-wide
1583-9999 exhaustive sweep confirms every Christmastide day resolves
Nativity/Epiphany/Bvm, every Paschaltide day one of its own three
windows or a season-independent title, every Lent day Lent or a
title, and Passiontide legitimately produces Easter exactly once a
year (the Vigil Mass) -- 8416 of the domain's 8417 years, the one
short year being the domain's own upper boundary (the liturgical year
opening in 9999 cannot construct dates in year 10000, a pre-existing
edge this sweep re-confirms rather than a new one).
day/readings verified byte-identical to the branch's own state before
this phase (commit 9c96e0a) across a 455-year sample spanning the
whole domain -- not literally to the v0.10.1 tag, which 22 earlier
commits on this same branch (Phase 1/2, the bissextile shift, the
Rogation colour fix) had already moved past before this phase began.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Item 1 of Phase 3 (celebrant-rubrics-phase1): the "at Low Mass"
commemoration-placement rule the design spec recorded as unread. It is
not a new rule -- it is the sung/low axis of RG 111, which colitur
already implements.
RG 111(a) (LT.txt, "Ratio admittendi commemorationes"): a liturgical
day of the first class, AND any non-conventual sung Mass regardless of
the day's own class, admits at most one commemoration, and only if it
is privileged. (b)/(c)/(d), the same rubric's remaining clauses, give
the wider caps colitur's admit already computes -- which is exactly
the LOW MASS answer.
Exposed as Precedence.sung_mass_commemorations, a pure derivation over
the existing Low-Mass admitted list (filter to Privileged, keep the
first), not a new stored field on Liturgical_day.t: the input list is
already validated and privilege-tagged, so a second field would only
create a second place for the same fact to drift out of sync with the
first, with no new information gained. Liturgical_day.t.commemorations
is now documented as the Low Mass set explicitly, removing the
ambiguity its .mli previously left unstated.
Tested against synthetic Low-Mass sets (none/one/two privileged,
already-first, empty) and two real calendar days resolved through the
normal Cal.day pipeline: 2026-08-14 (Vigil of the Assumption, an
ordinary-only commemoration, dropped at Sung Mass) and 2026-04-25 (the
Major Litanies, RG 80/109(f), privileged, kept at both Masses).
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Ascension has no octave under the 1960 rubrics -- confirmed structurally:
the Proprium de Tempore's own table of contents runs straight from "In
Ascensione Domini" to "Dominica post Ascensionem" with no per-feria
headings in between. Step 3 of the reading chain therefore fell through
to Preceding_sunday on every unoccupied weekday in that stretch, walking
each one back to the 5th or 6th Sunday after Easter's own citation.
The Missal's own Proprium de Tempore carries an explicit marginal rubric
immediately after the Ascension's Mass propers, before "Dominica post
Ascensionem" begins: "Diebus a feria VI post Ascensionem usque ad feriam
VI ante vigiliam Pentecostes inclusive, dicitur Missa de festo
Ascensionis, cum Gloria et praefatione de Ascensione, sine Credo et
Communicantes proprio" -- every feria without its own proper, from the
Friday after the Ascension through the Friday before the Vigil of
Pentecost, repeats the Ascension's own Mass. RG 490(b) corroborates
independently: it assigns the Ascension preface "tamquam de Tempore"
across that identical window, which only makes sense if the Mass
actually repeated there is the Ascension's, not a numbered Sunday's
(whose own Mass would carry no need for a preface override at all).
Witnessed directly, not only inferred from the rubric: the LMS Ordo
prints "Mass of the Ascension" literally on every affected day across
all three of its fixture windows, in BOTH the tail of Ascension's own
week and the following week -- ruling out the alternative reading (that
the second week instead resumes "Dominica post Ascensionem"'s own Mass,
which a first pass over the FIUV Ordo's own week-labelled titles could
suggest at a glance; its own [praef] field for the same two dates
independently reads "Ascensionis", resolving the apparent conflict).
Implemented as data, not logic, matching this codebase's own established
precedent for the identical RG 299 shape (the week after Trinity Sunday,
data/ef/lectionary.sexp's [trinity_week_entries]): six new hand-authored
entries, [ascension_week_entries] in tools/bootstrap_lectionary.ml,
regenerated against a git-pinned copy of lectio's own source ini (SHA-256
verified unchanged) so the regeneration carries no unrelated drift. The
window's two Saturdays are deliberately excluded -- RG 78's votive Office
of Our Lady on Saturday always wins an otherwise-unoccupied Class4
Saturday first, before step 2 (this fix's own entry point) is ever
reached, so an entry for either slug would be dead data.
Blast radius measured in-process across the full 1583-9999 domain
(throwaway probe, not committed): 16 350 days total across the six
slugs, every one resolved via step 2 (Own_slug), zero anomalies, and the
window's two Saturdays confirmed to contribute zero hits via this cause
across the whole domain, corroborating the RG78-interception reasoning
by direct sweep.
Closed L2 in data/ef/expected-divergences-lms.sexp. New cited entries:
C41 in data/ef/expected-divergences.sexp (95 of 16801 rows, 2005-2050 --
lectio has no equivalent rubric and still walks these ferias back);
M31 in data/ef/expected-divergences-missalemeum.sexp (3 rows in the
2026-2027 window, plus the same shape independently reconfirmed in the
2035 and 2038 live-capture windows) -- missalemeum, Divinum Officium's
lineage, still gives the same wrong answer colitur itself used to give,
which is why these rows used to agree with M18's shape and now escape it
(M18 373 -> 370, the same mechanism M23-M27 established when the
citation axis was first built).
Golden pin: 2031-05-23, the exact date the bug report was filed against.
Mutation-tested: reverting data/ef/lectionary.sexp alone (a git-diff
capture/restore, not a source-code revert, since the fix is data) reddens
19 tests across the differential, both oracle fixtures, all three LMS
Ordo windows, the golden pin, the lectionary unit test and every Render
golden template; restored and reconfirmed green (681 tests; 683 under
COLITUR_EXHAUSTIVE_SWEEP=1, ~175s).
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Temporal_ef.temporal's Rogation Monday/Tuesday branch hardcoded
Colour.Violet with no citation (data/ef/expected-divergences-lms.sexp's
L6, surfaced by the LMS Ordo). RG 119 assigns white to the de-Tempore
Office and Mass from the Paschal Vigil Mass to the Pentecost Vigil Mass
exclusive; Easter+36/+37 sit inside that window. RG 128's own exhaustive
four-case violet list never names Rogation days, and its vigil clause
(d) is doubly inapplicable: these are not vigils, and they are inside
Paschaltide, not outside it. RG 88 explains the violet actually seen in
print sources: "de Litaniis minoribus nihil fit in Officio, sed tantum
in Missa" -- the violet belongs to the Rogation Mass/procession, a
distinct votive text this engine does not model, not to the day's own
Office. Witnessed directly: LMS Ordo 2023-2024, 2024-05-06, "FERIA IV Cl
W" with "Gl", the Office and Mass printed separately from the optional
violet votive Mass of the Rogations.
Cascade verified, not assumed: RG 432(b) omits the Gloria on every
violet Mass, so the wrong colour was also silencing the Gloria on these
two weekdays even though RG 237(e) (Breviary, ordinary Paschaltide
ferias say Te Deum) already made it true underneath. White removes the
432(b) block, and the Gloria now follows Te Deum via 431(a), matching
the Ordo's own "Gl" -- confirmed with dedicated golden pins in both
test_golden.ml (colour) and test_rubrics_ef.ml (the Gloria flip),
2028-05-22/23 (neither day impeded that year).
Closed L6 in data/ef/expected-divergences-lms.sexp. Reopened C8 in
data/ef/expected-divergences.sexp (26 of 16801 rows, 2005-2050): lectio
independently computes these two days violet too, so the two engines
used to agree by sharing the same uncited assumption; colitur's colour
is now correct and lectio's is not, so the comparator disagrees again,
for the opposite reason. While reopening C8, found and corrected a
genuine misattribution in its own prior closure note, which claimed
lectio's violet was "RG 128(d)" -- 128(d) governs vigils outside
Paschaltide and has nothing to do with Rogation days. Checked
docs/research/rules-register.md for the same claim: not present there,
but a related conflation was found and corrected at its O'Connell
section 4(d) note, which had used a Rogation MASS/procession citation to
"confirm" the day's own OFFICE colour.
Blast radius measured in-process across the full 1583-9999 domain
(throwaway probe, not committed): 4722 days total (2368 Rogation
Mondays + 2354 Rogation Tuesdays actually observed outright, i.e. not
impeded by a stronger sanctoral feast that year), all Violet->White,
all with the Gloria flipping false->true alongside, zero anomalies.
Mutation-tested: reverting the branch to Colour.Violet reddens 16 tests
across Rubrics_ef, the lectio differential, the LMS Ordo suite and both
golden pin files; restored and reconfirmed green (680 tests).
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
data/ef/expected-divergences-lms.sexp's L5 (16 dates, LMS Ordo Gloria=true
vs colitur's false) and data/ef/expected-divergences-fiuv.sexp's F3 (6
dates, FIUV Te Deum=true vs colitur's false) were both misadjudicated as
colitur's own gap under an RG 302(b)/431(b) hypothesis. Both are wrong.
These are occurrence differences from the 2020 decree Cum Sanctissima,
which colitur excludes from its 1962 core by binding design (CLAUDE.md
decision 2). RG 303(b) ("dici potest tantum si occurrit dies liturgicus IV
classis") already prohibits 302(b) on the Class3 privileged ferias both
entries cover -- the original text quoted 303(b) but never followed it to
its conclusion. Decisively, the FIUV Ordo prints BOTH readings on the six
shared dates, separated by a literal "-VEL-" token: the primary, strict-
1962 reading (feria wins, sine Gloria, no Te Deum) matches colitur exactly;
the second, Cum-Sanctissima reading (saint kept, Gloria, Te Deum) matches
the LMS Ordo exactly.
F3 itself was never a real Te Deum finding: tools/extract_fiuv_ordo.ml's
extract_te_deum scanned each block unbounded for "Ad Mat.", so on these six
days -- whose primary office states no "Ad Mat." of its own -- it silently
read the second office's own Te Deum instead. Fixed with a new
split_at_alt_office, cutting every block at "-VEL-" before any field
extraction runs; the alternative is captured, not discarded, in a new
alt_te_deum field. A hard characterisation probe asserts the split fires on
exactly the six known dates.
Auditing for the same trap elsewhere (this is the third such manufactured
divergence in this project) found a related but narrower marker, "Vel (sec.
decretum <<Cum sanct.>>) Missa ...", offering an alternate Mass formulary
within a single office. It never corrupted Gloria/Credo (always stated
before the marker on all 20 real instances, confirmed by diff), only the
uncompared praef field; hardened defensively anyway, before it could ever
fire live. The LMS Ordo (all three editions) carries no equivalent
dual-print mechanism at all. expected-divergences-missalemeum.sexp's M27
is the same genus but was already correctly adjudicated, not touched.
Both allow-list entries are rewritten, not deleted: the original SHAPE/
CITATION/WHY-NOT-FIXED-HERE reasoning is preserved verbatim as a recorded,
superseded hypothesis, matching this project's own correction convention.
test_lms_ordo.ml's matching predicate is unchanged (the 16-date population
still fires, and always will, because it reflects a standing exclusion,
not a bug); only its citation comment is corrected. test_fiuv_ordo.ml's
F3-specific predicate/count assertion is removed, matching this file's own
prior F2/F4 closure discipline.
lib/ is untouched. dune test: 676/676. make check
(COLITUR_EXHAUSTIVE_SWEEP=1, full 1583-9999 domain): 678/678.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
F1 adjudicated the FIUV ordo's Good Friday "Gloria" against the ordo, but
rested on external attestation and left a pdftotext misread unruled-out.
The page image resolves both.
The extraction is faithful: the printed book does carry that line. So the
adjacent-block-misread possibility is ruled out rather than merely doubted.
And the same page shows the compiler knew the distinction. Holy Saturday,
its next entry, carries no Mass line at all -- correctly. Easter, the entry
after, carries a full one -- correctly. Good Friday, which likewise has no
Mass, wrongly receives one, word-for-word identical to Holy Thursday's on
the preceding page, while its own Vespers rubric four lines below calls the
day's rite an Actio liturgica rather than a Mass.
Verdict unchanged. It now rests on internal evidence from the source rather
than on every other authority disagreeing, which is the footing this
project's own standard asks for.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Phase 2 of celebrant-rubrics-phase1: colitur rubrics gains a fifth
column, whether the Gloria is said. Follows the Creed's own seam
exactly -- Rite.t.gloria, Liturgical_day.t.gloria, wired through
calendar.ml the same way.
RG 431(a)/432(a) defer the Gloria to the Breviary's own Te Deum rule
(nn. 237-238), so te_deum is implemented as its own named predicate,
cited clause by clause, not collapsed into a colour heuristic. 431(c)
(Holy Thursday, the Easter Vigil Mass) and 432(b)/(d) (violet; a
Requiem) are independent overrides checked ahead of the Te Deum-derived
answer. Every clause this engine has no dimension to model
(votive Mass classes, the wider n.302 "Missa festiva" categories) is
stated as N/A with its own reasoning, not silently dropped.
Validated against the FIUV universal Ordo (Gloria and Te Deum) and all
three LMS editions (Gloria). A first pass over-trusted a clean-looking
15-for-15 FIUV contradiction of 237(b)'s own Septuagesima exception and
replaced it with a blanket "every Sunday" rule; the evidence was itself
corrupted -- the FIUV extractor recognised only one of the source's two
Te Deum negations ("non dicitur", not "sine"), so every "sine Te Deum"
Sunday read wrongly true. Fixed in tools/extract_fiuv_ordo.ml, fixture
re-extracted, and the literal 237(b) reading restored once the
corrected data confirmed it. A second bug surfaced alongside it (Palm/
Passion Sunday wrongly reading true via Temporal_ef.named's own table
membership, then Christ the King wrongly reading false from an
over-broad fix) is closed with an explicit two-slug exclusion.
Domain-wide 1583-9999: every violet or Rose day is gloria=false except
the Easter Vigil (RG 431(c) lex specialis), every Requiem is
gloria=false, both measured exhaustively, zero exceptions. Mutation-
proved: disabling 431(c) reddens 8 tests including all four oracle
comparisons; disabling 238(c)'s feria-I-classis exclusion reddens
exactly the dedicated Ash Wednesday unit test, a genuine blind spot in
both oracle layers, reported rather than hidden.
Two open, cited findings, neither fixed here (out of this task's
"follow creed's exact seam" scope): a privileged Lenten/Passiontide
feria carrying one commemoration reads Gloria=true in the LMS Ordo but
Te-Deum=true/Gloria=false in FIUV -- the two oracles disagree with each
other, not merely with colitur (data/ef/expected-divergences-lms.sexp
L5, expected-divergences-fiuv.sexp F3); and a pre-existing, uncited
Colour.Violet bug on Rogation Monday/Tuesday in Temporal_ef.temporal,
surfaced by this comparison but root-caused as a separate defect (L6).
day/readings verified byte-identical against a build from the branch
tip before this task (v0.10.1's own tag predates an already-landed
bissextile fix that legitimately changed both, so it is not the right
baseline).
671 tests green (dune test); 678 with the exhaustive sweep
(COLITUR_EXHAUSTIVE_SWEEP=1 dune test --force, ~104s).
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The Missale Romanum's calendarium footnote for February (LT.txt:5011-5014,
scan-corroborated scan2.txt:3050-3058): in a leap year the sixth kalends of
March (24 February) is doubled rather than a 29th day appended, so St
Matthias moves 24->25 February and St Gabriel of Our Lady of Sorrows
27->28, with 24 February itself carrying no fixed office that year.
data/ef/expected-divergences-lms.sexp entry L3 tracked this as an open gap.
Implemented as the rubric's own general mechanism (every fixed entry from
24 through 28 February shifts one civil day later in a leap year), not as
"move these two named saints": the two readings are indistinguishable on
shipped data (nothing else is fixed in that window) and diverge only for a
future --overlay entry in the same range, which the mechanism reading
covers correctly and a two-saints special case would not. This project has
already been bitten once (RG 16(a)) by a rule implemented against shipped
data's coincidental shape rather than the rubric itself.
Kernel stays rite-agnostic: Rite.t gains a fixed_key field (Date.t -> (int
* int) option), the same seam easter already establishes, read only by
Layer.on_date's FIXED half -- the movable half (Easter_offset/Nth_weekday)
is untouched. Default is the identity mapping, an optional argument on
on_date, so every existing caller and every rite that supplies nothing is
byte-identical to before this field existed. Date.is_leap is exposed in
date.mli (already existed in date.ml) so the rite reads the kernel's own
single-sourced leap-year definition. The EF implementation lives in
Rite_ef.Temporal_ef.bissextile_fixed_key, fully cited, wired into
Rite_ef.context.
Blast radius, measured over the full 1583-9999 domain (Calendar.year run
twice per civil year, real fixed_key vs identity, every day diffed): all
2,041 leap years in the domain show a visible change for each saint;
6,983 individual liturgical days change total, zero unclassified, across
four shapes (Matthias vacates 24 Feb in 1,803 years / occupies 25 Feb in
1,811; Gabriel vacates 27 Feb in 1,699 / occupies 28 Feb in 1,670).
L3's own prior estimate (1,650 years, observed-outright only) is confirmed
close on the same definition (1,677 measured); the broader observed-or-
commemorated count is higher, not lower, showing the narrow estimate
undercounted visible impact rather than overcounting it.
The lectio differential (2005-2050 fixture) gains a new cited entry, C40
in data/ef/expected-divergences.sexp: lectio implements no such shift, so
every leap year in its window now diverges on the two shifted days (21
rows, not the naive 44 -- the comparator never compares commemorations, so
a side where the shifted saint has zero comparator-visible footprint on
both engines produces no row). The LMS Ordo's 2023-2024 fixture -- the
window L3 was originally found in -- now matches on the Creed comparison;
its formulary-override bucket count is corrected 182->181 (24 February
leaves the counted Proper population, becoming Own_slug-sourced). The
missalemeum oracle fixtures (2026-2027, 2038, 2035) cover no leap year and
are unaffected.
L3 is closed: converted from an active allow-list record to a prose
closure paragraph (L1's own precedent), citation preserved verbatim, fix
and measured blast radius recorded. The id-list assertion narrows to [L4]
alone, and the now-dead "2024-02-24" -> "L3" date mapping is removed.
Six golden values pinned across four new test cases: Matthias in a leap
year (both the vacated and occupied sides) and a common-year control;
Gabriel likewise, deliberately choosing a leap year where he is admitted
only as an ordinary commemoration rather than winning outright, a
different shape from Matthias's.
Mutation-tested: forcing fixed_key back to identity reddens exactly five
test cases -- the differential's Layer C count-pin (C40 drops to 0 actual
vs 21 expected), the LMS Ordo's Creed and formulary-bucket checks, and
both new golden pins -- confirming the tests actually exercise the fix.
Reverted; dune test, the exhaustive sweep, and make check are all green.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
L3 recorded that the leap-year shift rested on the LT.txt transcription
alone, the scans having been searched without result. It is in scan2.txt
at 3050-3058, OCR-damaged but unmistakable.
The earlier search missed it for a findable reason, now written into the
entry: the OCR mangles the saint and the keyword alike -- "Matthue",
"Cabrielis", "bi&sextili" -- so neither "Matth" nor "bissext" matches. It
turns up on the undamaged phrase "februarius est dierum".
Transcription and scan now agree, which makes this two witnesses of one
document rather than one. Still one document; the citation continues to say
calendarium rather than RG, because a calendarium footnote is what it is.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Wires in the FIUV (Foederatio Internationalis Una Voce) Ordo for
2025-2026 as validation layer seven -- the first UNIVERSAL (not
diocesan) source in this project, and the first compiled by someone
other than the LMS editions' own Peter Day-Milne (Joseph Shaw, FIUV
President).
tools/extract_fiuv_ordo.ml hand-parses pdftotext's -layout dump of the
Latin-language ordo (no Str/regex, frozen deps). Three real parsing
traps were found and fixed by tracing actual false results against the
raw source, not assumed in advance:
- "Gloria" is also the first word of "Gloria Patri" (the psalm
doxology), which can appear INSIDE the very Mass clause being scanned
(Good Friday: "...omittuntur ps. Iudica me et Gloria Patri), Gloria,
sine Credo..."). Guarded by rejecting any "Gloria" hit whose next
token is "Patri".
- Christmas Day's own rubric uses the PLURAL "Missae"/"Missae" ("tres
Missae celebrantur..."), never the singular "Missa" every other real
day anchors on -- silently produced gloria=None/credo=None on the one
most doctrinally unambiguous day in the calendar until traced and
fixed, guarded in turn against "Missae defunctorum" (an unrelated
Requiem-prohibition notice appearing at the end of many day-blocks).
- The Vespers boundary (bounding the primary Mass option before a
second "Vel Missa" alternative or before Vespers information) missed
the ligature spelling "VESPERÆ", the dominant form in this source,
letting a whole day's trailing prose leak into the captured [praef]
field on the task brief's own worked example day (19 September).
A distinct second stop-marker bug: the malformed trailing entry this
source shares structurally with the LMS PDFs (a stray, mislabelled
duplicate of 1 January) was initially over-matched by a generic
"first token is 4 digits" heuristic, which false-positived on an
indulgence-decree date citation wrapped mid-sentence in October
("...20 augusti / 1885, 26 augusti 1886..."), truncating the extraction
to 308 of 400 real days. Fixed by anchoring on the tail entry's own
distinctive "1st Jan" opening instead.
Five opposite-prediction Creed probes are re-verified by the tool
itself against its own extracted rows (a failed probe is a hard exit,
not a printed claim) before the fixture is written.
test/test_fiuv_ordo.ml compares the Creed against colitur across all
399 comparable days (Holy Saturday excluded, no Mass that day) --
CLEAN, zero unexplained divergences, a genuine second confirmation of
{!Rite_ef.Rubrics_ef.creed} independent of the LMS lineage. [praef],
[te_deum] and [class_] (including the FIUV ordo's own "III cl." vs
"III cl. (Priv.)" Cum Sanctissima convention, stated on its title
page) are captured into the fixture but deliberately not compared --
colitur has no Gloria/preface predicate yet, and its default
configuration models no Cum Sanctissima overlay to compare the class
convention against.
All 634 tests green (dune test), 635 with the exhaustive sweep and
make check. No lib/ file touched.
Claude-Session: https://claude.ai/code/session_017ZBxCCRM2ojnBupp3SBxV9
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Generalises tools/extract_lms_ordo.ml's start-of-body detection: the
hardcoded "End of November 2024" sentinel assumed every edition opens
with an "End of November" stub section. The 2023-2024 edition has none
(Advent Sunday 2023 fell on 3 December, so the compiler folded the two
tail days into the "December 2023" header directly) -- the generalised
detector anchors on the body's own "ORDO" title line instead, verified
unique in all three known editions and distinct from the Table of
Contents' lowercase "Ordo" entries.
Extracts test/fixtures/lms-ordo-2023-2024.sexp (397 rows) and
lms-ordo-2025-2026.sexp (399 rows), each with a provenance header
carrying its own SHA-256, source citation, and a per-edition
characterisation record: five opposite-prediction Creed probes,
independently re-verified against this run's own extracted rows (a
failed probe is now a hard die, not a printed claim). The 2025-2026
edition needed a different sharp II-class pairing than 2024-2025's
Joachim/Stephen one, because Joachim (16 August) is impeded by a Sunday
that year -- recorded in the fixture header, not silently swapped.
test/test_lms_ordo.ml is refactored into a parameterised make_suite,
instantiated once per edition; every count Task 6 hardcoded against the
single 2024-2025 window is now a per-edition parameter, several of which
turned out to differ once measured (BVM-Saturday population 12/14/13,
Ascension-week exclusion 1/3/2). Two mapping gaps surfaced only by the
new windows and fixed here (test-side, not colitur): Low Sunday reached
via Preceding_sunday for the first time (absent from 2024-2025's own
window), and the Ascension-week exclusion was wrongly keyed off week
number alone -- Rogation Monday also resumes week 6's Sunday but falls
BEFORE Ascension, not after, and the Ordo prints the ordinary Sunday
text there. Re-bounded by date, against Ascension and Pentecost.
Two genuine divergences surfaced in the 2023-2024 window and are
allow-listed (L3, L4) rather than fixed, per this task's no-lib-changes
scope:
- L3 (verdict ordo): colitur has no bissextile calendar rule. The 1962
Missal's own calendarium moves St Matthias from 24 to 25 February in
leap years (docs/research/LT.txt:5011); colitur keeps him on the 24th
every year. Domain-wide upper bound measured with a throwaway sweep:
1,650 of 2,041 leap years in 1583-9999 currently observe him there.
- L4 (verdict open): Christmas Eve falling on the 4th Sunday of Advent
(2023-12-24, roughly 1 year in 7). colitur says the Creed is said,
reading RG 475(a)'s Sunday clause; the Ordo says it is not. RG 30(a)'s
own "locum tenet ... nulla fit commemoratio" for this exact vigil
reads like RG 16(a)'s Feast-of-the-Lord-on-Sunday shape, which colitur
already treats as Creed-preserving -- but RG 475(a) names "festo"
specifically, and a vigil is its own liturgical-day category (RG 35),
so the counter-reading is real too. Left open rather than adjudicated.
All 630 tests green (dune test), 631 with the exhaustive sweep.
Claude-Session: https://claude.ai/code/session_017ZBxCCRM2ojnBupp3SBxV9
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Task 6 (celebrant-rubrics-phase1) added test_lms_ordo.ml as a sixth
validation layer, comparing 400 days against a printed Latin Mass
Society Ordo -- a genuinely independent fourth lineage, never passed
through Divinum Officium/missalemeum/lectio. README.md's own table
still said "Five validation layers"; man/colitur.1 still said "two
published-calendar oracles"; CLAUDE.md still said "5 layers" in two
places and, worse, stated as fact that "the published Ordo... Not
wired in as a layer" in the file every future session is instructed
to read first.
Updated all three, describing what the new layer covers (the Creed,
the BVM Saturday votive Mass's own seasonal selection, the reading
formulary override) and what it cannot see (one civil year, only
three of the formulary axis's five sources, England & Wales diocesan
propers excluded from every comparison) -- consistent with
docs/research/ordo/PROVENANCE-lms.md, not overstating it.
CLAUDE.md's own stale claim is corrected in place, not silently
rewritten, matching the file's own established convention: the
paragraph it lived in was about a DIFFERENT, earlier Ordo (unreliable
PDF column extraction, still genuinely unwired for that reason), and
its own closing prediction -- "a structured Ordo would be the only
way to add a fourth lineage" -- is exactly what the LMS Ordo's
structured extractor (tools/extract_lms_ordo.ml) has since done.
Historical "five layers" mentions elsewhere in CLAUDE.md, describing
completed state as of earlier branches, are left alone -- they were
true then, and rewriting them would misrepresent the record the same
way overstating layer 6's own coverage would.
Left README's pre-existing v0.9.0/569-tests staleness untouched, as
instructed -- it predates this branch and is a separate matter.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Task 5 (celebrant-rubrics-phase1) added a fourth rubrics column,
creed, and updated the man page for it. bin/main.ml's own built-in
--help was not: its "output formats" section and worked example still
showed three fields (date, formulary slug, source), and nothing
caught it because test/cli.t pins command dispatch but never the help
body.
Fixed the format line and its example, and added a short mention of
the creed column to the surrounding prose paragraph (source, format,
what --overlay/--lang/--raw do to it), matching the man page's own
account without copying it verbatim.
test/cli.t now cross-checks --help's own rubrics example against what
`colitur rubrics 2026` actually prints for the identical day, so the
two cannot silently drift apart again in either direction.
Mutation-proved: reverting the field count in --help alone (output
unchanged) reddens exactly this new check; reverted clean.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The .mli promised said is "the slug whose Mass is said". For Votive
(RG 78/309(a), the Saturday votive Mass of Our Lady) it was set to the
day's own ferial slug -- whose Mass is exactly the one NOT said. A
consumer joining rubrics to readings on that slug would silently get
the wrong Mass: 2026-01-03 reports ef-christmas-1-saturday, which has
zero entries in data/ef/lectionary.sexp, because the citations
actually come from bvm_saturday_citations, a season-keyed function
with no slug of its own anywhere in the shipped data.
Chose the type-honest fix over the interim documentation one: said is
now Slug.t option, None exactly for Votive, because there is
genuinely no slug in the shipped data this field could report for
that one source. Adding real ids for the five seasonal BVM Masses
(the reviewer's first option) is out of scope -- a data restructuring
this round explicitly does not carry. Threading the office slug
through a second field was considered and rejected as redundant: the
day's own office is already available on the same Liturgical_day.t
via observed.slug, which every caller already has in scope regardless
of via, so said does not need to duplicate it.
colitur rubrics stays byte-identical: rubrics_line already has
d.observed in scope and falls back to its slug when said is None,
printing the exact value it always printed for a Votive row (verified
directly, diffed against pre-fix output across four years). colitur
day/readings are unaffected (neither reads Mass_formulary at all).
colitur emit --format sexp's pretty-printed line count for 2027 moved
9011 -> 9025: every day's formulary record widened by said's own
extra option wrapping, and to_string_hum wraps by column width.
Cosmetic only, diffed line by line to confirm every change is this
shape or a consequent wrap shift; recorded in test/cli.t alongside the
476(f) note it now sits next to.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
test_lms_ordo.ml's formulary-override check only asked WHETHER a
Preceding_sunday day showed a "Mass of ..." override line, never WHICH
Sunday it named. colitur could have resumed the wrong Sunday on all
66 such days and this layer would have stayed green -- resuming the
right Sunday is precisely what step 3 of the reading chain exists to
do.
test_formulary_override_matches now derives the Ordo's own expected
prose from Mass_formulary.t.said's own resolved slug (parsed directly,
no Str/regex) and compares it against the Ordo's real text. Two
narrow, evidenced exceptions, both counted rather than silently
absorbed:
- Christ the King's own Sunday reaches this population under a
NAMED slug (ef-christ-the-king) that carries no embedded ordinal;
its position among the Sundays after Pentecost varies by year, so
Temporal_ef.week is read for that one slug specifically, not
called generically (an earlier version of this fix read [week]
for every day and was wrong -- caught by its own assertion on the
very first run, because Time_after_pentecost's own last-Sunday and
surplus-Sunday renumbering diverge from the raw week count. Reading
the number back out of the already-resolved slug sidesteps both
special cases and is not tautological with the wrong-Sunday
failure mode this fix exists to catch).
- Three real days between Ascension and the following Sunday
(2025-05-30, 2025-06-02, 2025-06-03) are a genuine, newly-found
defect: colitur resumes the nearest calendar Sunday, but the
Missal, and the Ordo, keep saying Ascension's own Mass through
this stretch instead. Structural (Ascension is a fixed Easter+39),
not a fixture artefact, and not fixed here -- it needs a
lectionary-data change out of this fix round's own scope.
Documented in expected-divergences-lms.sexp as a prose-only note
(no active sexp record: this file's id-lookup machinery is scoped
to the Creed axis, and a second axis reusing it would let one
test's "declared but never fired" check spuriously trip on the
other's entry) and enforced directly by this test's own count
assertion instead.
Mutation-proved: offsetting step 3's Sunday lookup by an extra 7 days
reddens this test (23 failures total across the suite: layers 3-6,
golden pins, and lectionary_ef's own unit tests), confirmed via the
compiled test binary directly; reverted clean, full suite green again.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
colitur said the Creed IS said on All Souls' Day and every other
Requiem-shaped day: RG 475(b)'s "in festis I classis" branch fired on
rank alone, with nothing checking RG 476(f), "Non dicitur symbolum ...
f) in Missis defunctorum". Allow-listed as L1 in
expected-divergences-lms.sexp on the argument that [creed] has no
notion of a Requiem Mass in its inputs and could not express the rule
without a signature change.
That argument does not hold. Colour.Black is used by exactly two
celebrations in the whole engine, verified by grepping every
occurrence in lib/ and data/: commemoration-of-all-souls
(data/ef/sanctoral.sexp) and Good Friday (temporal_ef.ml, already
false via the earlier RG 23(b) feria exclusion and has no Mass at all
in the 1955-restored Holy Week). So on every day this engine can
construct, colour = Black if and only if the Mass is a Requiem -- a
citable implication (RG 117 assigns black to Masses of the dead) on
this data, not a heuristic.
Rite_ef.Rubrics_ef.creed now reads observed.colour as RG 476(f)'s own
guard, positioned ahead of 475(b)'s rank branch. A new test,
test_colour_black_population_is_exactly_two, sweeps both the shipped
data and Temporal_ef's own code across a century and fails loudly the
day a third Colour.Black celebration is ever introduced, so the proxy
cannot silently rot.
L1 is closed in expected-divergences-lms.sexp, citation preserved.
Blast radius, measured (full 1583-9999 sweep, grouped by observed
slug): 8 416 days change from true to false, every one
commemoration-of-all-souls (missing from exactly 1 of the 8 417 domain
years, a boundary-year transfer effect at 1583/9999). A further 8 416
Colour.Black days are Good Friday, unaffected (already false before
this fix). colitur day/readings stay byte-identical to v0.10.1
(checked directly against a v0.10.1 worktree build, 9 domain-spanning
years); colitur rubrics changes on exactly the 8 416 days above.
colitur emit --format sexp's pretty-printed line count for 2027 moved
9010 -> 9011 as a side effect: Sexplib.Sexp.to_string_hum wraps by
column width, and All Souls' Day 2027's record grew one wrapped line
because "false" is one character longer than "true". Cosmetic only --
no field's data changed -- and pinned in test/cli.t with the
measurement recorded.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
An independent lineage -- neither Divinum Officium, missalemeum nor
lectio -- covering the Mass formulary and the Creed. Characterised
before use, per the discipline the extraordinaryform.org Ordo's
blanket St Lawrence vigil gap taught this session: five opposite-
prediction Creed probes (Sunday/feria, octave-override vs plain
II-class, I-class) all confirmed against the raw extracted text
before a single divergence was adjudicated, recorded in the
fixture's own provenance header.
tools/extract_lms_ordo.ml hand-parses pdftotext -layout output (no
Str/regex, frozen deps) into test/fixtures/lms-ordo-2024-2025.sexp,
400 day-rows (2024-11-27..2025-12-31). Gl/Cr print per Mass-option,
not per day; the extractor takes the first pair in reading order,
which the source's own layout guarantees is the universal entry's,
since a diocesan variant always follows it, never precedes it. The
Ordo's I-V roman numeral ("Missae de sancta Maria in sabbato", RG
309(a)) is matched whole-line only, never by substring -- "V Mass of
BVM" is a substring of "IV Mass of BVM".
test/test_lms_ordo.ml compares two axes 1:1 by date:
- the Creed (RG 475-476): 399 of 400 days comparable (Good Friday
has no Mass at all, asserted as the only such day); one genuine
divergence, adjudicated to the ORDO, not colitur -- All Souls'
Day 2025-11-03 is a Requiem Mass, and colitur's own creed
predicate has no notion of one, a pre-existing scope gap
rubrics_ef.ml already documented in its own header before this
task existed.
- the BVM-Saturday seasonal Mass selection, the addendum's own
"sharper check": all 14 Votive days in the window match their
season's own numeral exactly, both directions, independently
re-derived from RG 309(a) rather than calling colitur's private
function.
- the formulary override, for the three sources it can honestly
discriminate (Proper 179, Preceding_sunday 66, Common 2, all
clean); Own_slug (139) is excluded with evidence, not silently --
several ferial slugs carry citations byte-identical to their
Sunday's own, so the Ordo's override line cannot distinguish the
two representations.
data/ef/expected-divergences-lms.sexp carries the one adjudicated
entry (L1), cited to RG 476(f).
Mutation-tested: inverting RG 475(a)'s Sunday clause reddens 10
existing Rubrics_ef unit tests AND this new layer's own comparator,
independently, on a data source none of the other five layers touch.
Reverted after confirming.
No lib/ changes. day/readings/rubrics output re-confirmed byte-
identical (1583, 2026, 2038, 9999) after this task; all three gates
green (dune test, exhaustive sweep, make check).
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
rubrics_ef.ml's Creed check excluded feriae from 475(b)/(c)/(e) via an
explicit test for feria I classis (Ash Wednesday, Holy Week) and vigils
only. RG 24/25's feriae II and III classis (Advent 17-23 December, the
Advent/Lent/September Ember sets, the numbered Lenten/Passiontide
ferias) were excluded by no check at all, correct today only because of
an unstated Temporal_ef property (no ferial-origin office it builds
carries subject Lord/Bvm or an apostle-list slug). A comment read as if
this were established "by construction of the two exclusions
immediately above", which overclaimed: those two exclusions cover feria
I classis only.
Corrected the comments to name RG 24/25 explicitly, state what is and
is not checked, and cite where the real guarantee comes from. Added a
test that sweeps Temporal_ef.temporal across a century (1583-1682),
asserting the invariant directly against every ferial-origin day found,
with its own coverage counters confirming the span actually reaches
Advent 17-23, all three non-Whitsun Ember sets, and Lenten/Passiontide
ferias. The first run of the test found a real gap in its own
population filter (RG 17(a)'s 2 January Holy Name fallback, a genuine
feast sitting outside Temporal_ef.named for an architectural reason),
fixed by naming that date explicitly rather than narrowing the span.
Proved the test has teeth by mutation: forcing the ferial builder's
default subject to Lord reddened it (and 24 other tests, expected
collateral from an intentionally broad mutation) before being reverted.
No production logic changed -- only comments in rubrics_ef.ml. day,
readings and rubrics output confirmed byte-identical against the
pre-fix binary for four spot years across the domain. Also corrects a
stale test-case count in a prior task report (18 in the array, not the
19 recorded there); the array now genuinely holds 19.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Whether the Creed is said at Mass. New Rubrics_ef.creed, reached through
a new Rite.t.creed field and a new Liturgical_day.t.creed bool (false,
not an option, for a rite that has not implemented the rule); colitur
rubrics gains a fourth TAB-separated column.
475(a) reads the TEMPORAL cycle's own weekday, not the observed day: a
Sunday impeded by a Feast of the Lord (RG 16a) still says the Creed.
475(d)'s three octaves (Nativity, Easter, Pentecost) are pure date/
Easter-offset windows, checked first, since a saint's feast winning the
day inside one of them still says the Creed ("etiam in festis
occurrentibus") -- St Stephen, 26 December, is the live witness.
RG 23 classifies Ash Wednesday and every feria of Holy Week (including
the Sacred Triduum) as feriae, not festa, however high their rank, so
475(b)/(c)'s "in festis" never reaches them; this single check subsumes
476(a)'s own naming of the Chrism/Lord's-Supper Mass and the Easter
Vigil. RG 28-34 vigils are a third liturgical-day category, also
excluded from "in festis" regardless of rank -- reuses the already-
exported Precedence_ef.is_vigil rather than a new list.
475(e)'s Apostle/Evangelist natalicia list (creed_apostle_slugs) was
derived by grepping data/ef/sanctoral.sexp directly and checking each
candidate's own date against whether it is that saint's dies natalis --
not copied from any list supplied with the task. The Conversion of St
Paul and the 30 June Commemoration of St Paul are excluded (neither is
a natalicium); the Chair of St Peter and St Barnabas are included only
because the clause names them explicitly, which is exactly why it has
to: neither is a natalicium either.
475(c)'s BVM half reuses Precedence_ef.marian_slugs (newly exported)
rather than the subject field alone: checked against the shipped data,
almost every Marian sanctoral entry ships subject=Saint, not Bvm.
man/colitur.1's rubrics section is updated to match the new column;
test/cli.t repinned via dune promote for the same reason. Verified
day/readings output byte-identical to v0.10.1 across the whole
1583-9999 domain (both binaries' concatenated day+readings output,
6,148,492 lines each, zero diff). Domain-wide: 882,996 days say the
Creed, 2,191,250 do not; every one of the domain's 439,178 Sundays says
it, zero exceptions.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Separate from day for the reason readings is: a formulary name contains
spaces and day's row is space-separated with a variable-length tail.
Modelled on readings' own structure (year parsing, --overlay plumbing,
error handling): --overlay is accepted, since an overlay can change
which celebration is observed and hence which Mass is said. --lang,
--raw and --sigla-* are refused rather than silently ignored -- this
row resolves no display name and no citation for any of them to
affect.
Output is TAB-separated (date, formulary slug, source), not space or
" | " like the two existing reports: a resolved formulary NAME is a
column a later task may add, and it can carry both spaces and
punctuation a citation never does, ruling out either separator already
in use.
day and readings verified byte-identical (sha256) against a v0.10.1
build across 1583/1900/2026/2038/9999. Man page documents rubrics
beside readings and renders through groff with no errors.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Fix round 1's own comment claimed the Latin Mass Society Ordo witnesses the
Votive tag directly, reading its "V Mass of BVM" as an abbreviation for
"votive". That was wrong: the Ordo's I-V are roman numerals naming WHICH
of the Missal's five seasonal "Missae de sancta Maria in sabbato" (RG
309(a)'s own "iuxta temporum diversitatem") is said on a given Saturday,
not a marker of the Mass's kind. All five numerals occur through the Ordo
(I x1, II x4, III x3, IV x3, V x8); the false reading came from "V Mass of
BVM" also being a substring of "IV Mass of BVM".
Votive itself is unaffected and stays correct on RG 431(e) alone, quoted
verbatim in its place: "e) in Missis votivis IV classis de Angelis,
quocumque die, et de B. Maria Virg. quae in sabbato celebrantur" -- votive
Masses of the IV class, of the BVM, celebrated on Saturday. The retraction
is recorded, not softened, in lectionary_ef.ml/.mli and the test pin's own
comment, together with what the Ordo's numeral actually means so the
mistake is not repeated, and the consequence it leaves behind: because the
numeral names WHICH seasonal Mass is said, a future comparison against the
Ordo (Task 6) can validate bvm_saturday_citations' own season-keyed
selection, not merely that some BVM Mass was chosen.
Comments and docs only -- no behaviour change. Both suites re-run green and
colitur day re-confirmed byte-identical.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Mass_formulary.source was missing a case for a Mass said IN PLACE of the
day's own office's Mass while that office is itself kept unchanged -- RG
309(a) and RG 431(e) both classify the RG 78 Saturday Mass of Our Lady this
way, in the Missal's own words, as a "Missa votiva IV classis... de B.
Maria Virg.", not as the day's own office's Mass. The Latin Mass Society
Ordo (docs/research/ordo/lms-ordo-2024-2025.pdf) witnesses it directly,
printing that day as "V Mass of BVM".
The BVM-Saturday branch in Lectionary_ef.readings was tagged Own_slug for
lack of a better constructor when Task 2 landed, flagged there as a
judgement call rather than a specified answer. That call was wrong: left
as Own_slug, a future comparison against the LMS Ordo (a later task in this
plan) would read every BVM Saturday as a manufactured divergence between
colitur's "own" Mass and the Ordo's votive one. Retagged to Votive; said
is unchanged (still the day's own, reused ferial, temporal slug) since the
office itself is unaffected, only the Mass said for it.
Added the new constructor's source_to_string case ("votive") and its own
test row, and pinned the branch itself in test_lectionary_ef.ml's formulary
cases at 1 August 2026, verified directly against the resolver rather than
assumed.
Both this session's own drifted pins that the earlier commit inherited from
the task brief are unaffected by this change, and both are re-confirmed
independently correct in this round: dune test and the exhaustive sweep are
green, and colitur day stays byte-identical against the pre-fix-round
binary.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Rite.readings now returns (Mass_formulary.t option * Citation.t list)
instead of a bare citation list, and Liturgical_day.t carries the result
as a new formulary field. Validate holds a rite that resolves a formulary
at all to resolving one on every day, the same discipline it already
applies to citations; the EF lectionary chain resolves Some on every day
of every year 1583-9999, confirmed by a direct sweep over 2005-2050 as
well as through Validate itself.
Plan Tasks 2 and 3 are merged into this one commit on the coordinator's
own instruction: Rite.readings' signature and the field that consumes it
are one atomic edit, and the intermediate state does not compile on its
own.
Each of the four lectionary steps now builds its own Mass_formulary.t at
the point it decides, not by re-deriving it afterwards from the citations
it returns: step 1 tags Proper with the observed slug, step 2 tags
Own_slug with the day's own temporal slug, step 3 tags Preceding_sunday
with the resumed Sunday's temporal slug, and step 4 tags Common with the
Common's own id -- Commons.find now returns that id alongside its
citations rather than discarding it, since it is only ever in scope at
the point the assignment is looked up.
The RG 309(a) Saturday votive Mass of Our Lady, which answers between
steps 4 and 2 rather than as one of the four numbered steps, is tagged
Own_slug too: Mass_formulary.source has no dedicated constructor for it,
and its own guard only ever fires when the observed celebration already
is the day's own (reused ferial) temporal slug, which is exactly what
Own_slug documents. Recorded as a judgement call in the task report, not
a specified answer.
test/cli.t's `emit --format sexp` line count is repinned (8472 to 8881):
that command serializes Liturgical_day.t whole, so the new field grows
its output. `colitur day` itself is untouched -- verified byte-identical
against the pre-change binary across 1583, 1900, 2026, 2038 and 9999.
|