| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
RG 110 (Caput XIV): "In Officio et Missa S. Petri semper fit
commemoratio S. Pauli, et vicissim... pro unica habeantur" -- in the
Office and Mass of either Peter or Paul, a commemoration of the other
is always made, uncapped by RG 111's own admission count. Both
photographic scans, full text including sub-clause (c) (a separate
trigger this register previously had not transcribed: the same rule
also fires when one Apostle's oration is admitted merely as an
ordinary/privileged commemoration, not only when it is the day's own
office).
Three real pairs in the 1962 calendar, all confirmed on both scans:
25 January (conversion-of-st-paul + peter), 22 February
(chair-of-st-peter + paul), 30 June
(in-commemoratione-sancti-pauli-apostoli + a new
commemoration-of-st-peter). The first two already existed as ordinary
sanctoral candidates but were wired into RG 111's ordinary, capped
admission contest instead of this rule's own uncapped one -- the
defect this closes. 30 June had no companion at all: a genuine gap
in lectio's own source data (confirmed directly against
tridentine-calendar.ini) and in missalemeum's own oracle output for
both fixture years, not only a colitur bootstrap miss, so colitur is
now uniquely correct on this date among the three engines compared.
Added via data/ef/adjustments.sexp's own Add directive, the
architecture's existing extension point for exactly this shape of
gap, since data/ef/sanctoral.sexp is generated and lectio must not be
touched.
Precedence_ef.admit gained rg110_additions/rg110_companion_slug,
layered on after admit's own four ordinarily-capped branches decide
their normal result: checks both the observed candidate and every
already-admitted candidate against the three-pair lookup and prepends
any companion found, uncapped and additional, never competing for
RG 111's own slot.
Measured full blast radius (1583-9999, pre-change binary from git
archive at 59fbda8 vs the fixed binary, 3,074,246 days each side,
14,627 differing days, all four predicted shapes, zero unclassified):
3,619 Holy Name fallback days (previous commit), 3,533 days Paul was
wrongly excluded from Chair of St Peter's own day by a competing
privileged feria, 593 days Chair of St Peter itself was admitted only
as an ordinary commemoration with Paul entirely absent, and 6,882 days
the new 30 June companion is added. The 3,533+593 figure supersedes an
earlier, narrower 852-day estimate that measured only the delta
between two older code commits, not the rule's full scope.
The lectio differential needed no change: it does not compare
commemorations at all, and this fix never touches season, slug, rank,
or colour. The missalemeum oracle allow-list needed three changes:
M12 removed (22 February 2027 no longer diverges in commemoration
count), M15's date list gained 2027-02-22 (now reaching identity
comparison for the first time, where it lands on that entry's own
pre-existing, unrelated limit -- one of the two commemorations is
temporal-origin and unnamed), and a new M19 for the 30 June gap.
Mutation-tested, both halves separately: disabling the admit-level
addition reddens the two new unit tests, the oracle's own M12-shaped
checks, and an existing golden pin (updated to expect the Paul
companion); removing only the 30 June data entry reddens solely the
oracle's new M19 count, confirming the code and data halves are
independently load-bearing.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
RG 17(a): "festum Ss.mi Nominis Iesu, celebrandum dominica quae occurrit
a die 2 ad 5 ianuarii (secus die 2 ianuarii)" -- both photographic scans,
confirmed on the calendarium's own January table and the Mass propers'
own heading. Two defects closed together, since they interact through
RG 91 entry 14/RG 16(a):
1. The Sunday shape (2-5 January) now tags subject = Lord, matching
RG 91 entry 14 ("Festa Domini II classis") -- previously subject =
Temporal, the same defect shape Holy Family had before it.
2. The fallback (RG 17(a)'s own "secus die 2 ianuarii", the calendarium's
"vel, ea deficiente, die 2 ianuarii") is now built: 2 January carries
the feast whenever no Sunday falls 2-5 January that year. Before this
fix colitur emitted no Holy Name office at all in such a year -- a
real II-class feast simply missing, on 3,619 of 8,417 years in the
domain (43%; 20 of the 46 years 2005-2050, independently re-derived
against `date -d`).
Both shapes band identically at RG 91 entry 14's MOVABLE half
(Precedence_ef.entry_14_movable_band) -- one feast, not two differently
classified ones, per the Mass propers' own single heading covering both
dates. No live collision exists in the current sanctoral data (nothing
fixed-date falls 2-5 January besides a Commemoration_only entry on 5
Jan), so the RG 16(a)/RG 112(a) interaction is proved with synthetic
precedence-level fixtures mirroring Holy Family's own precedent, not a
live-data regression. One asymmetry the synthetic tests found and kept
honest rather than forced: a losing Holy-Name-Sunday is privileged
(RG 109(a), "of a Sunday") and survives RG 111(a)'s cap; a losing
Holy-Name-fallback is not (2 January is not a Sunday, and no other
RG 109(a)-(f) category applies to it), so it gets no commemoration at
all if ever outranked -- both individually correct readings of RG 109/111's
closed lists.
Golden pins follow the brief's own vacuity warning: the Sunday shape
already emitted the right slug/rank/colour before this fix (an ordinary
Sunday and Holy Name coincide on those fields), so its pin asserts
subject explicitly rather than pinning the whole line uncritically; the
fallback pin (2029-01-02) is the one with teeth against the larger
defect, reddening on slug/rank/subject together if reverted.
Mutation-tested: each half of the fix reverted separately reddens
exactly its own tests (Sunday subject: the dedicated unit test, the
golden pin's subject field, one precedence end-to-end test; fallback:
the fallback unit/anchor/golden tests, the new C16 differential count,
and both shapes of the precedence end-to-end tests) and nothing else.
Adds data/ef/expected-divergences.sexp's C16 (lectio has no fallback for
this window at all) -- the lectio differential's own count, independently
re-derived against `date -d` for the fixture's 2005-2050 span, not
transcribed from the domain-wide figure. The missalemeum oracle window
(2026-2027) exercises only the Sunday shape and needed no new entry:
subject is not one of its compared fields, and both years' rows already
corroborate the Sunday-shape ranking (missalemeum's own 2026-01-04 and
2027-01-03 rows: rank 2, white, title "Holy Name of Jesus").
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
cite RG95's real primary authority
F2: the disposition comment for RG112(a) claimed the electronic
transcription "carries NEITHER this paragraph's own worked example
NOR its own more specific Mass-proper rubric... exactly the
transcription's documented defect" -- wrong on both counts, checked
directly rather than taken on trust.
RG 112 has no worked example in any of the three source documents
(the transcription included) -- there was nothing to drop. The Holy
Family Mass propers' own 13-January rubric is absent from the
transcription not because it silently drops content it otherwise
has (the project's own documented defect, dropped calendarium
commemoration lines) but because that specific document (a 2006 web
capture) contains almost no Mass-propers text of any day: 5
Introit-line occurrences across 26,322 lines, against 61 and 402 in
the two photographic scans; its own "Proprium de Tempore" page is a
table of contents linking to PDFs the capture never pulled in. A
coverage gap in a partial web capture, not an instance of the
narrower, different defect the methodology note actually describes.
The ruling is unaffected -- the propers' quotation is real, on two
independent photographic scans, and settles 13 January on its own --
only the attribution is struck, here and in test_precedence_ef.ml
(the register and the task report are corrected separately).
F7: RG 95's own second paragraph -- present in all three documents,
including the transcription -- is a more direct, occurrence-level
authority for the exact collision than RG 112(a): "if two feasts of
the same Divine Person... occur together, the one higher in the
table is kept, the other omitted." Added as the primary citation on
disposition's RG112(a) branch, with RG 112(a) and the propers' note
kept as corroboration. Also corrects RG 112(b)'s own framing: it is
bidirectional ("et vicissim"), and only the Lord-feast-wins direction
(RG 16(a)) is implemented -- the Sunday-wins direction has no witness
anywhere in this codebase's data and was wrongly described as already
covered.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
entry_14_movable_band = -14 was justified only by "cannot collide
with a real table position (1..28) or unclassified" -- a collision
argument, not an ordering one. band's own value is compared by plain
<, so a negative number beats every I-class entry (1-13), not merely
the fixed Baptism it was built to beat. Not live against the shipped
universal sanctoral data (no I-class universal feast falls 7-13
January, which is why the original 1583-9999 sweep showed only the
intended shape), but entries 12/13 admit PROPER and INDULT I-class
feasts too, and those arrive via adjustments.sexp-style overlays --
this architecture's own advertised extension path. A diocesan
patronal feast landing in Holy Family's window would have made the
inversion live immediately: the I-class feast displaced and
transferred to the next day, reproduced and confirmed before this
fix, reverted after.
Fixed by rescaling every band branch to the real RG 91 entry number
times ten (unclassified untouched at max_int) instead of the bare
1..28, reserving genuine headroom immediately before each entry for
a movable sub-rank -- not an arbitrary rescale: RG 91's own text
records a "primum mobilia, deinde fixa" split at three rows, not
only entry 14 (entry 12's own ninth sub-item, entry 14, and entry
20), so this leaves room for the other two without a second rescale
if either ever gets a live witness. entry_14_movable_band now
derives from entry_14_fixed_band - 1, tied together so they cannot
drift apart.
Added a synthetic I-class end-to-end test reproducing the exact
counter-example that found this: a universal I-class candidate
inside Holy Family's own 7-13 January window is now observed and
does not transfer, with Holy Family itself falling to RG109(a)'s
ordinary privileged-Sunday-commemoration path, the same treatment
any genuine feast outranking an ordinary Sunday gets.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Two related fixes, both needed for Holy Family to actually observe
correctly on the seven years it coincides with the fixed
Commemoration of the Baptism of the Lord (13 January): 2008, 2013,
2019, 2030, 2036, 2041, 2047.
band's entry 14 ("Festa Domini II classis") gated on sanctoral
origin only, so a movable Class2 Lord feast had no row in the table
at all. RG 91 entry 14's own text says otherwise: "primum mobilia,
deinde fixa" -- movable first, then fixed. entry_14_movable_band
gives Holy Family (the one movable candidate this codebase builds
with subject Lord) a value strictly better than the fixed half's own
literal 14, negative so it can never collide with a real table
position -- without it, the two would tie at 14 and fall to
Precedence.resolve's own alphabetical tie-break, which picks the
WRONG side ("commemoration-of-the-baptism-of-the-lord" sorts before
"ef-time-after-epiphany-sunday-1").
disposition gets a new branch for RG 112(a) (Caput XVI, "De
Commemorationibus"): the Office, Mass or commemoration of a mystery
of one Divine Person excludes a commemoration of another mystery of
the SAME Divine Person. Winner and loser both subject Lord -> Omit,
not Commemorate -- without it, Holy Family observing correctly still
left the Baptism admitted as an ordinary Class2 commemoration under
RG111(b), which the primary text does not allow.
Confirmed by a MORE SPECIFIC primary source than RG 112(a) alone: the
Holy Family Mass propers' own note, found on both photographic scans,
word for word, immediately after the Postcommunio -- "Si festum S.
Familiae occurrerit die 13 ianuarii, Missa dicitur de festo S.
Familiae, sine commemoratione Baptismatis D.N.I.C., et sine
commemoratione dominicae." The electronic transcription carries
neither this rubric nor RG 112(a)'s own worked example -- another
instance of its documented defect, not merely absent from one check.
Still expected red: the lectio differential (2005-2050) now shows a
new, real divergence on those seven 13-January-Sunday dates -- lectio
has no Holy Family at all, so it still shows the fixed Baptism
observed there, unlike colitur now. The oracle's own M-series entries
also still need widening for the observed-identity axis added two
commits ago. Both are the next commits.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Fix round 1 on the commemoration-identity/tie-break work: the "genuine
same-band tie" M17 adjudicated as open was not a tie at all. RG 91's
table enumerates only "dies liturgici" (real feasts) -- entry 24's own
text is "Festa III classis, in calendario Ecclesiae universae
inscripta" -- so a Celebration.t.status = Commemoration_only candidate
(a saint reduced to a bare commemoration) has no row in the table to
begin with. Precedence_ef.band used to read rank alone, so it silently
lent such a candidate the same table entry as a genuine Feast of its
own rank; the calendarium's own 22 September row confirms the
distinction in its own notation ("S. Thomae de Villanova ... III
classis. / Commemoratio Ss. Mauritii et Soc. Mm." -- Thomas carries a
class number, Maurice carries none).
Fixed at the source, not by adding a status tier to compare_precedence:
band now checks status first, ahead of every rank-keyed branch, and
returns unclassified for any Commemoration_only candidate. M17 deleted
(not re-adjudicated) -- 22 September now resolves identically on both
sides, with no divergence left to name.
Blast radius measured independently (a temporary git worktree at the
pre-fix commit): 4451 days change across the whole 1583-9999 domain,
exactly 4 verified shapes -- 3576 x maurice-and-companions-martyrs ->
thomas-of-villanova and 282 x eleutherius -> philip-neri (admitted set
changes), 502 x appollonia/cyril-of-alexandria and 91 x dorothy/titus
(order only, independently confirmed against the calendarium's own
listing convention). Zero days change who is observed. Further swept
the whole domain for a genuine "two different candidates on the
identical real table entry" residual -- the shape RG 113 truly gives
no instruction for -- and found it empty: of 109201 same-rank ties
domain-wide, 83950 now resolve by band alone and the remaining 25251
are exclusively two Commemoration_only candidates tied at unclassified,
never two real feasts. The residual admit still breaks alphabetically
is real, but narrower than previously documented.
The "66 days" figure is reconciled, not merely disputed: 599 is the
tie population, 65 (whole-comparator: 67) is the real admitted-set
decision count within it (independently reproduced against the
pre-Task-B binary), 149 is order-only. Every one of the 65 real
decisions traces to the same Commemoration_only/Feast root cause as
Maurice/Thomas.
Also: validate.ml's admission fixed-point check recovers a
commemoration's real origin (by matching its slug against the day's
own temporal office) instead of reconstructing every candidate as
Sanctoral, since band -- unlike EF's own admit -- does read origin;
precedence_ef.ml/.mli's motivating example and blast-radius claims
corrected to no longer rest on the fixed Maurice/Thomas case;
test_identity_rank_corroboration's own population count corrected now
that 22 September (and 21 other Feast-status matches) became reachable;
its rank-agreement pin documents exactly what it does and does not
prove. Register (§4, §6.1, §6 checklist) and CLAUDE.md corrected in
place, including the RG 113 first-sentence gap this exercise surfaced
but did not close, recorded as a new open item.
275 -> 276 tests (with the exhaustive sweep), all green.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
precedence, not slug
Precedence_ef.admit broke a same-rank tie among commemoration candidates
alphabetically by slug -- a deterministic engineering convention with no
rubrical citation. RG 113's own second sentence, primary-source-verified
against two independent scans and previously uncited in the register
(only "commemoratio de Tempore fit primo loco" was quoted before), gives
the real rule: "in admittendis et ordinandis aliis commemorationibus,
servetur ordo tabellae praecedentiae" -- admitting and ordering
commemorations both run on the rite's own table of precedence (band's
28-entry table), not RG 8's coarse four-class rank.
Precedence.resolve now computes each commemoration candidate's own band
value once, generically, and hands it to rules.admit as a third tuple
element (Precedence.rules.admit's signature changed accordingly, ditto
Precedence_ef.admit; every rule-record stub in the test suite updated to
match). Precedence_ef.admit's own compare_dignity is replaced by
compare_precedence, ordering by band then slug; a residual tie within one
identical band value still falls back to slug, since RG 113 gives no
further instruction there -- documented as a still-uncited engineering
convention, not dressed up as a rubric.
RG 98 ("in paritate autem Officium prius impeditum praecedit") was
considered as a candidate authority for that residual and rejected: it
governs the transfer queue order among several simultaneously-impeded
I-class feasts (Caput XIII), a different operation in a different
chapter from RG 113's commemoration admission (Caput XVI); nothing in the
primary text connects the two.
Blast radius measured against the pre-change binary across the entire
1583-9999 domain (not only 2005-2050): the admitted-commemoration-slug
set is byte-identical, day for day, before and after this change. The
fix corrects the citation and mechanism, not the answer, on this
codebase's current data -- both of the task brief's named examples
(22 Feb Chair-of-Peter/Lent-vs-Paul, 22 Sept Maurice-vs-Thomas-of-
Villanova) are confirmed present and unchanged in both streams. A new
test (RG113: admit picks by precedence order, not slug, when they
disagree) proves admit actually consults the passed-in precedence value
with a synthetic pair whose slug order and precedence order disagree --
teeth a same-band-only regression test could not have caught, since
every real collision found in the domain happens to agree on both axes.
271 -> 272 tests, all green; COLITUR_EXHAUSTIVE_SWEEP=1 unaffected.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Fix round 1 review, MINOR finding (item 4). Both precedence_ef.ml and
test_precedence_ef.ml claimed the loser-side Class2 conjunct held because
'entry 6's own band value (6) is lower than every entry [3, 11-14]' --
false on its face (6 is not lower than 3) and, worse, the claim proves the
opposite of what it was cited for: if a band-3 candidate really did
contest a Class1 Sunday, the lower number would win, meaning the Sunday
would lose, not beat it as claimed.
The conclusion itself was never wrong, only the justification. Against
entries 11-14 (sanctoral-origin Lord feasts) the numeric argument holds
(6 < 11-14). Against entry 3 (Epiphany, Ascension, Trinity, Corpus
Christi, Sacred Heart, Christ the King) it is not numeric at all but
structural: every band-3 celebration is temporal-origin, and
Precedence.resolve takes exactly one temporal candidate per day, so a
band-3 Lord feast IS that date's own single temporal candidate, never a
second one contesting a separately-produced Sunday -- there is no band
comparison to make in the first place. Comment-only; no behaviour change.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
day's own Sunday-ness, not observed
Fix round 1 review, two findings landed together because each golden pin's
correctness depends on both.
CRITICAL (item 1): reverts this branch's own first-pass retag of the
Purification (2 February) from Lord back to Bvm -> Lord. The calendarium
titles it 'B. Mariae Virg.', but missalemeum -- this project's designated
EF oracle -- treats it as taking an occurring II-class Sunday's place
outright, commemorations empty, exactly RG16(a)'s own festum Domini
treatment (2020-02-02, 2014-02-02, independently fetched). Control,
2019-09-08 (the Nativity of the BVM, an ordinary Marian feast, on a
Sunday): the Sunday observed, the feast merely commemorated -- the
opposite pattern, proving the Purification's own oracle treatment is
deliberate, not a gap. RG16(a) alone, on the untouched data, would have
matched the oracle character for character; retagging Bvm is what moved
colitur away from it on 1200 domain-wide days. The user has ruled: follow
the oracle. Genuine primary-text counter-evidence (RG120(b), the colour
rule grouping 2 February under 'B. Mariae Virg.', a category separate
from 'Domini') is recorded in the register, not discarded -- a different
project could reasonably rule the other way on the same evidence.
most-holy-name-of-mary stays retagged Bvm; that one was never disputed.
Removes the now-unneeded C12 lectio allow-list entry (data/ef/
expected-divergences.sexp, test_differential.ml): with the Purification
Lord again, colitur matches lectio's own class = lord on every affected
date, no divergence to allow-list.
IMPORTANT (item 2): Precedence.rules.admit gains a ~temporal parameter --
a genuine kernel signature change, unlike RG16(a) itself. RG111(b)'s own
Sunday rank floor ('one commemoration, namely of a II-class feast') used
to be detected by reading observed's own slug for a Sunday marker, which
silently assumed observed IS the day's temporal-cycle office. RG16(a)
breaks that assumption on purpose: a Feast of the Lord standing in for an
impeded Sunday 'cum omnibus iuribus et privilegiis' keeps the day a
dominica II classis for RG111(b) too, even though the FEAST, not the
Sunday, is observed. Before this fix an unrelated saint (Pope Sixtus II
et al., 6 August, Class3) was wrongly admitted into the freed slot on
every one of 1178 domain-wide days. Oracle-confirmed directly: 2023-08-06
(a Sunday) shows him displaced, commemorations empty; 2026-08-06 (an
ordinary Thursday) shows him admitted -- being a Sunday is exactly what
excludes him. admit now reads Sunday-ness off ~temporal (the day's own
temporal-cycle candidate, passed through from Precedence.resolve
unchanged) instead of observed. Validate's own admission fixed-point
invariant updated to pass the same real temporal candidate through.
Both golden pins in test_golden.ml were promoted from actual colitur day
output without independently consulting the rubric or the oracle first --
a real defect the review caught. Re-derived from both before re-pinning:
2028-08-06 and 2025-02-02 now pin comms=[], no commemoration at all,
matching missalemeum exactly in both cases.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Sunday uncommemorated
Caput III "De Dominicis", RG 16(a): a Feast of the Lord, I or II class,
occurring on a II-class Sunday takes the Sunday's own place with all its
rights and privileges -- of the Sunday, therefore, no commemoration is
made. band's entry 14 already ranked such a feast above the Sunday
correctly; disposition had no exception for the collision, so the impeded
Sunday fell through to the ordinary RG 95/109(a) commemorate-or-omit
catch-all and was wrongly admitted as a privileged commemoration.
Adds a branch to Rite_ef.Precedence_ef.disposition, gated on all four of:
loser is temporal-origin, loser rank Class2, loser carries the Sunday slug
marker, winner rank Class1-or-2 with subject Lord. No signature change --
disposition already receives the winner (RG 33's own vigil-omission branch
already reads it); each conjunct is proved independently load-bearing by
a dedicated disposition_cases row, including one real-data case each for
the winner's subject and rank conjuncts, and a defensive synthetic case
for the winner rank conjunct's currently-unreachable Class3 shape. A new
end-to-end resolve-level test (2028-08-06, the Transfiguration) proves the
real band/disposition pipeline together, checking the Omit reason string
distinguishes this from admit's own admission-limit cut.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
68 "register line N" pointers in tracked code and data cited the
register's line numbers directly. The register has moved since: line 334
(cited six times as RG 91 entry 8) is now rose/colour prose; lines
375-376 (cited as "RG 109 leaves Advent/Lent Ember ordinary") are now
RG 26, the paragraph that refutes that exact reading; line 374 (cited as
RG 109(a)) is now RG 25's Latin; line 378 (RG 111) is blank.
expected-divergences.sexp even wrote "RG 91 line 332" three times, as
though the line offset were part of the rubric's own identity. Since
docs/research/rules-register.md is gitignored, no reader of the public
repo could resolve any of these, and -- since the register has moved on
its own copy too -- neither can the author's.
Replaced every pointer with an anchor that survives editing: the RG
paragraph/entry number itself (already present in nearly every case,
since the citation text already names "RG 91 entry N" or "RG 109(a)"
next to the stale line number -- the line number was redundant, not
load-bearing) plus a "§4" or quoted-subsection-heading pointer into the
register for readers who want to locate the fuller discussion. Also
corrected one genuinely stale content error found while migrating its
anchor: test_precedence_ef.ml's RG33 disposition-cases comment still said
"a I/II-class vigil impeded by any Sunday" -- the pre-Task-16
mistranscription the register itself corrects to II/III class; fixed the
prose alongside its citation, since leaving a wrong RG-class claim next
to a freshly-verified anchor would be worse than the stale line number it
replaced.
Covers lib/rites/rite_ef/precedence_ef.ml (18), precedence_ef.mli
(already fixed with item 1), test/test_precedence_ef.ml (44, including
two instances that only word-wrapped "register\nline N" across a line
break and so did not match a same-line grep), and
data/ef/expected-divergences.sexp (5, including three "RG 91 line 332"
instances). All 68 original pointers resolved -- none needed guessing;
every citation's target rule was already named in the surrounding prose.
No behaviour change: every edit is a comment/citation/data-note change.
Verified byte-identical `colitur day` output across 1583, 1900, 1902,
2008, 2011, 2026, 2038, 9999. 259/259 tests green.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
guard claim
Item 2(a): the RG 26 omission gate (rank = Class4) is extensionally
identical, over every candidate this engine actually constructs, to the
refuted "privilege_of loser = Ordinary" predicate it replaced -- confirmed
by enumerating the whole candidate space over 1583-9999, substituting the
old predicate back leaves 257/257 green and byte-identical output. Adds a
synthetic row: a temporal-origin, Ordinary-privilege Class3 loser, which
the two gates disagree on (RG26: Commemorate; the refuted gate: Omit,
since it never looked at rank). Reverting the gate to the old predicate
turns exactly this row red:
Expected: "Commemorate(Ordinary)"
Received: "Omit"
Item 2(b): the existing "RG33 boundary" row's comment claimed it proved
the RG26 branch's own (not (is_vigil ...)) guard. It does not: the vigil
sourced there is Class2, already excluded by the branch's rank = Class4
test alone, with or without the vigil guard -- verified by deleting the
guard, which leaves 257/257 green. Corrected the comment to say what the
row actually shows (RG31's "if impeded, commemorated" vigil mandate, a
real and separate fact worth keeping) and added a genuinely discriminating
synthetic row: a temporal-origin Class4 loser whose slug is ALSO
vigil-shaped, a combination RG 91 does not describe but Precedence.resolve
can still be asked to construct. Deleting the guard turns this row red:
Expected: "Commemorate(Ordinary)"
Received: "Omit"
Both reversions were applied locally to precedence_ef.ml, confirmed, and
reverted; the committed .ml is unchanged. Test count 257 -> 259, both new
rows green under the current, correct code.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
RG109
Review round 1 (F1, Critical): the commemoration-eligibility fix from
the previous commit silently dropped II-class Advent and Lent Ember
ferias when impeded, while ordinary (lower-solemnity) ferias of the
same seasons kept their commemoration -- backwards on any reading.
Reproduced: 1900-12-21 (an Advent Ember Friday) lost its commemoration
entirely; 2026-12-21 (an ordinary Advent feria the same week) kept
its.
F2 (Important, the direct cause of F1): the branch's own justification
mis-stated RG 109 as an exhaustive list of the only temporal
circumstances that generate a commemoration. RG 109 is headed
"Commemorationes privilegiatae sunt commemorationes" and closes
"Omnes aliae commemorationes sunt commemorationes ordinariae" -- it
sorts commemorations that already exist into two HONOUR classes
(RG 108's differing liturgical hours), and says nothing about which
offices have the right to be commemorated at all. That right belongs
to Caput IV, "De feriis" (RG 21-27), never opened by the original
pass:
RG 24 (II-class ferias): "si vero impediuntur, commemorari debent"
-- if impeded, MUST be commemorated. Not optional.
RG 25 (III-class ferias): same mandate.
RG 26: every feria not named in 23-25 is IV class, and IV-class
ferias are NEVER commemorated -- the one exclusion RG 21-27 actually
states.
The omission branch is now gated on `rank = Class4` (RG 26) directly,
not on `privilege_of = Ordinary` -- the old gate happened to reach the
right answer for IV-class ferias (RG 26 also excludes them, for a
reason the old citation did not give) and the wrong one for II/III-
class Ember ferias RG 109(e) did not name by letter.
RG 109(e) itself is also corrected: its bare "feriis Adventus,
Quadragesimae et Passionis" previously excluded the Advent and Lent
Ember sub-days by analogy with (d)'s separate September carve-out.
RG 91's own TABLE needs an explicit "exceptis feriis Quatuor
Temporum" at entries 22 and 25 to keep Ember days from being double-
listed against their own entry 18 -- an exception that would be
unnecessary drafting if "feriae Adventus"/"feriae Quadragesimae" did
not already include their Ember sub-days by default. RG 109(e) carries
no such exception, so it is read at that same default, inclusive
scope: the Advent and Lent Ember ferias are privileged under (e), not
merely ordinary-but-commemorable. (d)'s own existence is unaffected --
September Ember days sit outside Advent/Lent/Passiontide under any
reading, so (d) remains necessary regardless.
Verified: 1900-12-21 and 1902-02-22 now correctly commemorate their
Ember ferias; 2026-12-21 and 1902-02-24 (ordinary ferias) unchanged.
Blast radius re-measured against the prior commit, 1900-2100: 102
civil days changed, every one an Advent/Lent Ember (or Ember-vs-
Joseph-collision) day regaining its commemoration, nothing else.
Validate re-swept exhaustively, 1583-9998: 0 failures.
F6: two privilege-boundary test rows that had been bent to expect the
bug's own output (Commemorate -> Omit) are restored to what RG 24/25
actually require, now Commemorate(Privileged) given the RG 109(e)
correction above -- these are the rows that should have caught F1.
F7: admit_cases had no witness for RG 111(b)'s rank floor that wasn't
already Class2, so reverting that filter only reddened the oracle
suite, never this file. Added a row (II-class Sunday, sole candidate
an ordinary Class3) that fails without the filter and passes with it.
F9: RG 122 cited alongside RG 128(b) for Holy Thursday's white --
states the same fact affirmatively ("Demum adhibetur color albus,
feria V Hebdomadae sanctae...") rather than as an exception to violet.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Task 16's missalemeum oracle comparison (2026-2027) surfaced three
distinct precedence-engine bugs, each confirmed against the primary
1962 Missale Romanum text and cross-checked against the oracle:
1. RG 33 (vigil omission) was transcribed backwards. The primary text
reads "Vigilia II AUT III classis penitus omittitur" (a II OR III
class vigil is entirely omitted on any Sunday or I-class feast) --
not "I aut II" as the register and this module's own rank check
(Class1 || Class2) previously had it. I-class vigils (Nativity,
Pentecost) can never actually lose in this engine (band always
ranks them above anything that could coincide with their dates), so
the Class1 half was dead code; the real bug was that Class3 (St
Lawrence's vigil, the sole III-class vigil) was MISSING, so it fell
through to an ordinary commemoration instead of RG 33's mandatory
omission whenever 9 August landed on a Sunday.
2. RG 93/95/109/113 read together: an ordinary, non-privileged
TEMPORAL-cycle office (a bog-standard green-season feria, a plain
Advent/Lent Ember day, a Minor Rogation day) has no standing to be
commemorated at all when impeded -- RG 109's six-item list is a
CLOSED set of the only temporal circumstances that generate a
commemoration, not a floor under which anything ordinary still
gets one. The engine previously commemorated the losing feria
itself in this situation; confirmed wrong against ~190 independent
missalemeum days (2026-2027) showing zero commemorations for the
exact shape. Vigils are explicitly excluded from this new rule --
RG 31/32 give them their own "if impeded, commemorated" mandate,
independent of RG 109's list.
3. RG 111(b)'s Sunday admission slot is restricted to "de festo II
classis" -- a rank restriction, not merely the best available
ordinary candidate. A III/IV-class ordinary saint competing for a
II-class Sunday's single commemoration slot had no such restriction
applied before; confirmed wrong via St Hyginus (11 Jan, Class3)
losing to Holy Family, which missalemeum shows entirely displaced,
never commemorated.
All three fixes are pure disposition/admission changes -- they never
touch band, so the observed day (season/slug/rank/colour) is
unaffected in every case; the lectio differential (which never
compares commemorations) stays green untouched. test_precedence_ef.ml
updated throughout: two previously-wrong test expectations corrected
(the RG33 III-class-vigil boundary row, the IV-class-feria totality
row), three privilege boundary rows sharpened from "commemorated but
unprivileged" to "omitted entirely" now that temporal+ordinary
means omission, and a new contrast row added to keep the SANCTORAL
side of rule 2 covered separately from the TEMPORAL side.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The register was transcribed faithfully but was itself wrong: RG 96's
Attamen (a), primary-source-verified from the scans and now corrected
in the register, reads 'festum Annuntiationis B. Mariae Virg., quando
est transferendum post Pascha, transfertur ... in feriam II post
dominicam in albis' -- the Monday-after-Low-Sunday seat applies ONLY
'quando est transferendum post Pascha', when the feast is to be
transferred PAST EASTER. The unconditional transcription made the
exception fire on every impeded Annunciation regardless of cause.
transfer_target now computes the general RG 96 target first, for every
candidate, and overrides to the Monday after Low Sunday only when that
general target itself falls after Easter Sunday -- testing the rubric's
own condition directly rather than re-deriving a date-proximity rule
from first principles.
Confirmed against three real years the review named: 2007, 2012 and
2057 all previously sent the Annunciation to Easter + 8 (16 April,
16 April, 30 April respectively) when the correct, now-produced target
is the next free day before Easter (26 March in each case -- Passion
Sunday in 2007/2012, Lent III Sunday in 2057). Verified with actual CLI
output for all three, before and after.
Also cites RG 96 Attamen (b), the same primary-source passage, as the
direct authority for All Souls' own move to the following Monday when
impeded by a Sunday -- previously inferred from RG 91 entry 8's
parenthetical plus the general walk, which happened to produce the
right date; now stated directly.
Rewrote the two existing Annunciation unit tests, whose synthetic
occupants no longer trigger the (now correctly conditional) exception,
and added a 2057 regression test using the real Temporal_ef.temporal as
occupant plus a real-data cram pin -- both mutation-verified against
the unconditional reading.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
search_from could walk up to 400 days past origin before Calendar's own
~start ~stop clamp is ever consulted, and nothing stopped it probing
occupant on a date past 31 December 9999 -- occupant chains through the
real EF rite's temporal, which calls Computus.gregorian_easter, not
total outside 1583..9999 (it Date.makes and failwiths on Error).
Not reachable with the shipped sanctoral data alone, but reachable
through the project's own primary extension path: an overlay adding an
I-class feast on 25 December leaves nothing but Class2 Nativity-octave
days for the rest of civil year 9999, so the unguarded search reached 1
January of year 10000 and crashed there with 'computus: year 10000 out
of range 1583..9999'. 9999 is an in-range year and the kernel's contract
is 'never raises on in-range input'.
search_from now also stops, without probing occupant again, once it
passes Date's own domain ceiling -- the same 'return a finite date, let
Calendar's own out-of-range handling record it, never pretend to have
found something admissible' contract the existing step-count guard
already follows.
Two new tests, both mutation-verified to actually reproduce the crash
when the guard is removed (see the task report): a precedence_ef.ml unit
test using the real Temporal_ef.temporal as occupant (a synthetic
occupant can never discriminate this, since it never calls Computus
itself), and a Calendar-level integration test reproducing the exact
overlay-based scenario the review found.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Assembles Rite_ef.context (lib/rites/rite_ef/rite_ef.ml[i]): temporal,
anchors and vocab from Temporal_ef; rules from Precedence_ef's band,
disposition and admit; season_runs = Vocab_ef.seasons; transfer_target
newly implemented here.
transfer_target (RG 96): the next following day that is not I or II
class, with the Annunciation's own exception (Monday after Low Sunday).
Terminates by a structural step bound on its internal search, independent
of Calendar's own round guard, which bounds rounds across a year, not one
call's walk; documented as an obligation on rite.mli's transfer_target
field, which did not previously state it.
Fixes the vigil-naming mismatch Task 7's review predicted: the sanctoral
bootstrap names its vigils with a vigil-of-X prefix (lectio's own
convention), while Precedence_ef's is_vigil only recognised the temporal
cycle's own X-vigil suffix. Both are now recognised, fixing RG 91 entries
21/26 and RG 33's vigil omission for the four affected celebrations.
Verified by unit test and by mutation-testing the fix (reverting it fails
exactly the new rows) and against real output across several years.
Suppresses data/ef/sanctoral.sexp's vigil-of-christmas via a new overlay,
data/ef/adjustments.sexp: it is the same celebration as the temporal
cycle's own ef-nativity-vigil, both dated 24 December.
colitur day <year>: one line per civil-year day, temporal and sanctoral
fully resolved through Layer, Overlay, Precedence_ef and Calendar -- the
first CLI path exercising the whole Plan 3 pipeline against real data.
Verified the All Souls transfer chain (Tasks 7-8-11) end to end against
real output for both a Sunday year (2025, lands on 3 Nov) and a
non-Sunday year (2026, observed directly on 2 Nov).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Adds test_ii_class_sunday_privileged_witness_admitted_end_to_end,
proving RG 111's "II-class Sundays: one, dropped if a privileged one is
due" clause through the real pipeline (band, disposition, privilege_of,
admit together), not only at the isolated admit level.
RG 109(b) is the one privileged category that is sanctoral and
rank-based rather than temporal-origin: a Commemoration_only, Class1
sanctoral candidate (the same shape disposition_cases already uses as
(b)'s witness) is held out of the band contest entirely by
Precedence.resolve, so it always loses regardless of what wins the
day. Paired with an ordinary sanctoral saint, both losing to an
ordinary Class2 Sunday, gives observed_is_sunday = true with one
privileged and one ordinary loser due at once, with no new fixture.
Documents, and mutation-confirms, what this fixture does and does not
prove: RG 109(b)'s only reachable witness is Class1 (the highest
dignity), so the privileged loser here is unavoidably also the
higher-dignity one, and the admission outcome alone cannot distinguish
"privilege overrides dignity" from "dignity alone picked the same
winner" -- that distinction remains admit_cases's job. What this test
does prove, and what a category-(b) regression in privilege_of breaks,
is the privilege tag itself surviving the real pipeline end-to-end.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
disposition's Class1 branch was unconditional on rank, so an impeded
I-class Sunday (Advent/Lent/Passiontide/Low Sunday) currently
transferred like a feast. RG 95 (register lines 323, 363) restricts the
right of translation to I-class FEASTS -- RG 91's own table lists
Sundays as a separate row (entry 6, line 332) from feasts (entries
11-13, lines 337-339) -- and RG 109(a) (line 374) lists "of a Sunday"
as a privileged commemoration category, which presupposes an impeded
Sunday stays put rather than moving to another day.
Excludes is_sunday_slug losers from the Transfer branch so they fall
through to the existing Commemorate (privilege_of loser) branch, which
already tags them Privileged via RG 109(a) with no further change.
Fires on real dates in the 2005-2050 differential window: 24 December
on Advent IV in 2023, 2028, 2034, 2045; 8 December on an Advent Sunday
in 2024, 2030, 2041.
Verified no previously-passing Transfer assertion used a Sunday-shaped
loser (grepped test_precedence_ef.ml, test_calendar.ml -- which uses
its own synthetic rite unrelated to Precedence_ef.disposition --
test_colitur.ml, test_validate.ml); confirmed by mutation-reverting the
fix and observing exactly the one new test fail, nothing else.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Precedence_ef.privilege_of classifies a commemoration candidate against
RG 109's closed list of privileged commemorations (a Sunday; a I-class
day; a day within the Octave of the Nativity; a September Ember day; a
feria of Advent, Lent or Passiontide; the Major Rogations in Mass), read
entirely off the candidate's own rank/slug/origin, no context needed.
Major Rogations (f) is left unimplemented rather than guessed: no
producer for the Major Litanies exists anywhere in this codebase yet.
disposition's two Commemorate sites now call privilege_of instead of
Task 8's interim_privilege placeholder, which is removed entirely
(binding and .mli export both gone).
Precedence_ef.admit applies RG 111's four admission counts, keyed on
the observed day's own class and Sunday-ness: a I-class day admits none
except one privileged commemoration; a II-class Sunday admits one, but
a privileged commemoration due displaces any ordinary one regardless of
dignity; any other II-class day admits one by dignity alone, with no
such override; III/IV-class days admit at most two by dignity. Ties
break on slug, matching Precedence.compare_by, so the admitted set
never depends on input order. Every admitted candidate is a value taken
unchanged from the input list, never rebuilt, so Precedence.resolve's
physical-equality-based dropped/omitted accounting keeps working --
closing a note left open since Task 2.
Tests: RG 109 category rows (one per reachable category, plus boundary
rows proving Advent/Lent Ember days and Minor Rogations are correctly
excluded), RG 111 admission rows checked on slug identity rather than
count, an order-independence check, and three end-to-end integration
tests proving the admission limit's drop lands in resolution.omitted
rather than vanishing.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Precedence_ef.disposition decides the loser's fate in an occurrence: a
Commemoration_only celebration is always commemorated (it can never win or
transfer); a I- or II-class vigil impeded by any Sunday or a I-class feast
is entirely omitted (RG 33), checked before the generic rule below or the
Nativity/Pentecost Vigil could wrongly transfer; any other I-class loser
transfers (RG 95 -- only I class has the right of translation); everything
else is commemorated, with the admit-or-omit decision left to RG 108-111's
admission count (Task 9). RG 94 needs no code: resolve always compares a
loser against the day's actual winner, never against a departed sibling, so
no commemoration can ride along with a transferred feast in this design.
This is the branch that completes Task 7's carried All Souls fix: once it
loses to an occurring Sunday, its untouched Class1 rank routes it to
Transfer via the generic rule, not a special case. Landing on 3 November is
Rite.transfer_target's job, not wired up yet.
Commemorate carries an interim Precedence.Ordinary privilege pending Task
9's RG 109 implementation, exposed as interim_privilege for that task to
replace.
Table-driven tests cover each rule, including RG 33's boundary from both
sides and a Commemoration_only loser that is also Class1 and vigil-shaped
to pin the branch ordering. Mutation-tested: disabling RG 33, either
direction of RG 95's rank condition, or the Commemoration_only priority
check each fail exactly the rows built to catch them.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Review of 436ba75 found two calendar defects and one coupling risk.
Entry 8 (All Souls) dropped register line 334's own qualifier,
"(yields to an occurring Sunday)" -- it returned 8 unconditionally,
so on 2 November falling on a Sunday (2025, 2031, 2036, 2042 in the
2005-2050 differential window), All Souls incorrectly outranked and
observed over the Sunday. 2 November is always Time_after_pentecost
and never coincides with any other entry's own date, so the only
rival this exception ever has is an ordinary entry-15 II-class
Sunday; on such a Sunday, band now returns one worse than entry 15's
own value rather than the literal 8 -- strictly worse, not merely
different, since an exact tie would fall to Precedence.resolve's slug
tie-break, which for "ef-all-souls" against a Sunday slug would make
All Souls win the tie anyway. Entry 8's own rank is untouched, so
Task 8's disposition still sees a true I-class candidate to transfer.
Entry 14 (Feasts of the Lord, II class) added a universal-layer
restriction the register's line 341 does not carry -- contrast entry
16 at line 342, which explicitly says "not of the Lord"; RG 37c
(register line 393) also speaks of "II-class feasts of the Lord"
with no universal qualifier. Dropped the layer test: a proper or
indult feast of the Lord now bands 14, not 19/20.
Also exposes vigil_suffix and ember_prefixes from precedence_ef.mli,
matching universal_layer/indult_prefix's existing "colitur convention,
not an RG citation" treatment -- both were previously private literals
duplicated in the test file, so a rename of temporal_ef.ml's slug
format could have drifted silently past both sides agreeing with each
other. Two test rows now build their candidate from Temporal_ef.temporal's
own real output (entry 18's Lent Ember day, entry 21's Ascension Vigil)
instead of a hand-typed slug, closing that specific coupling.
Adds the three cheap rows review named as closing the remaining
unpinned guards (a temporal-origin Class1 candidate on an unnamed
date; a universal Class2 vigil of the Lord; a non-universal Class3
vigil), plus a resolve()-level test proving the Sunday is actually
observed over All Souls, not just that band returns the right integer
in isolation.
|
|
|
Precedence_ef.band transcribes RG 91's 28-entry Table of Precedence
(rules-register.md §4) for the EF rite: given a day's context and a
candidate celebration, returns the table's own entry number, 1-28
(I class 1-13, II class 14-21, III class 22-26, IV class 27-28); lower
wins. Every branch carries its entry number and register citation in a
comment, checked in the table's own numeric order.
Two entries are transcribed as the register states them even though
they invert the pattern the rest of the table follows: at III class,
23 (particular calendars) outranks 24 (universal), the reverse of how
11/12 and 14/16/19/20 rank a universal feast ahead of a proper one at
I and II class.
Sanctoral-origin, layer-decided entries (11-13, 14/16/19/20, 23/24)
follow the brief's structural insight: a celebration whose layer is
not the universal base is an overlay -- proper, or indult if its
layer id also carries the indult prefix. Neither the universal-layer
id nor the indult prefix is an RG citation; both are colitur's own
data-modelling convention, exposed from the module so whichever task
loads the real EF sanctoral overlays can align to them.
Vigils (21, 26) are read off the temporal cycle's own -vigil slug
suffix rather than gated on origin, since a II/III-class vigil can be
either temporal-origin (Ascension, already produced by temporal_ef) or
sanctoral-origin (a saint's vigil, no task has loaded yet); Ember days
(part of entry 18) are read off temporal_ef's own ember slug prefixes
rather than re-derived, since the September anchor is independently
flagged there as one of the more contested dates in the calendar.
A candidate shape the table has no row for (e.g. a Class1 vigil that
is not Nativity or Pentecost, or a Class4 candidate marked as a vigil
-- RG 91 has no IV-class vigil either) returns a dedicated unclassified
sentinel (max_int) rather than being folded into a same-rank entry it
does not belong to.
test_precedence_ef.ml is table-driven: one Alcotest.test_case per RG
91 entry (55 rows total, several entries covered by more than one
named day so a single missed offset cannot hide behind a passing
sibling), each date computed from Computus.gregorian_easter rather
than hand-typed, so an arithmetic slip cannot pass by accident.
|