aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-08-18 16:32:52 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-08-18 16:32:52 +0200
commit5ee75098e1c86fdce195df2e37784c18a2b081a5 (patch)
tree4f5a5a12536087acce3553a4d140f3b5d034faf3
parent2dc44fbbc581430e2038e2ff6d67265fe716791c (diff)
downloadlectio-5ee75098e1c86fdce195df2e37784c18a2b081a5.tar.gz
lectio-5ee75098e1c86fdce195df2e37784c18a2b081a5.zip
fix(ef): the weekdays within the Octave of the Nativity have their own Mass
29, 30 and 31 December are named days in the Missal's calendarium -- "De V die infra octavam Nativitatis Domini, II classis" and so on -- with a direct formulary, "Diebus infra octavam Nativitatis Domini": Titus 3:4-7 / Luke 2:15-20, and each date's own rubric pointing at it ("Die 29 decembris ... Missa Puer natus est nobis, ut supra"). lectio treated them as ordinary Christmas ferias, so they fell back to the preceding Sunday and served "Dominica infra octavam Nativitatis Domini" (Gal 4:1-7 / Luke 2:33-40) -- a different heading, for the Sunday specifically. Worth recording because it is not a guess: colitur made the IDENTICAL mistake, gave these three days the Sunday's citation, measured it against real years and reverted it. Its bootstrap_lectionary.ml keeps the rejection on record with the scan references for both headings, which is how this one was diagnosed rather than re-derived. Only the weekdays. When 29-31 December falls on a Sunday the day really IS Dominica infra octavam and keeps the Sunday's Mass -- 2030-12-29 is the case, and it is asserted, because a fix applied by date alone would pass on the weekdays and silently swallow the Sunday. Mutation-tested: dropping the Sunday exclusion reddens exactly that assertion and nothing else.
-rw-r--r--internal/caldata/caldata_test.go45
-rw-r--r--internal/caldata/readings.go43
2 files changed, 88 insertions, 0 deletions
diff --git a/internal/caldata/caldata_test.go b/internal/caldata/caldata_test.go
index f993a12..2a13d3d 100644
--- a/internal/caldata/caldata_test.go
+++ b/internal/caldata/caldata_test.go
@@ -521,3 +521,48 @@ func TestEFBVMSaturdayReadings(t *testing.T) {
t.Errorf("2026-04-18: gospel = %q, want %q (the Paschaltide formulary)", gospel, "John 19:25-27")
}
}
+
+// TestEFNativityOctaveWeekdayMass pins the Mass of a WEEKDAY within the Octave
+// of the Nativity, and the Sunday it must not swallow.
+//
+// The Missal gives 29-31 December a direct formulary, "Diebus infra octavam
+// Nativitatis Domini, II classis" -- Titus 3:4-7 / Luke 2:15-20 -- and names
+// them in the calendarium ("De V die infra octavam ... II classis"). Treated
+// as ordinary ferias they fell back to the preceding Sunday and served
+// "Dominica infra octavam" (Gal 4:1-7 / Luke 2:33-40), which is a different
+// heading for a different day.
+//
+// The Sunday case is asserted too, because it is the one the wrong citation
+// blurred: when 29-31 December IS a Sunday the day really is "Dominica infra
+// octavam" and keeps that Mass. A fix that applied the weekday formulary by
+// date alone would pass the first half of this test and fail the second.
+func TestEFNativityOctaveWeekdayMass(t *testing.T) {
+ sel := calendar.Selection{Form: "old"}
+ layers := []calendar.Layer{Tridentine()}
+ get := func(date string) (string, string) {
+ day, _ := time.Parse("2006-01-02", date)
+ var first, gospel string
+ for _, r := range Readings(sel, layers, day, calendar.Compute(day, sel, layers)) {
+ switch r.Part {
+ case "first":
+ first = r.Citation
+ case "gospel":
+ gospel = r.Citation
+ }
+ }
+ return first, gospel
+ }
+ // 2026: 29-31 December are Tuesday, Wednesday, Thursday -- weekdays.
+ for _, date := range []string{"2026-12-29", "2026-12-30", "2026-12-31"} {
+ if f, g := get(date); f != "Titus 3:4-7" || g != "Luke 2:15-20" {
+ t.Errorf("%s: got %q / %q, want Titus 3:4-7 / Luke 2:15-20 "+
+ "(Diebus infra octavam Nativitatis Domini)", date, f, g)
+ }
+ }
+ // 2030: 29 December is a SUNDAY, so it is Dominica infra octavam and keeps
+ // the Sunday's own Mass.
+ if f, g := get("2030-12-29"); f != "Gal 4:1-7" || g != "Luke 2:33-40" {
+ t.Errorf("2030-12-29 (a Sunday): got %q / %q, want Gal 4:1-7 / Luke 2:33-40 "+
+ "-- the weekday formulary must not swallow Dominica infra octavam", f, g)
+ }
+}
diff --git a/internal/caldata/readings.go b/internal/caldata/readings.go
index 62ef1fc..44d1bc1 100644
--- a/internal/caldata/readings.go
+++ b/internal/caldata/readings.go
@@ -60,6 +60,9 @@ func Readings(sel calendar.Selection, layers []calendar.Layer, date time.Time, d
if r := efBVMSaturdayReadings(day); len(r) > 0 {
return r
}
+ if r := efNativityOctaveReadings(day); len(r) > 0 {
+ return r
+ }
if r := TemporalReadings("old", day.Observed.Slug); len(r) > 0 {
return r
}
@@ -145,3 +148,43 @@ func efBVMSaturdayReadings(day calendar.LiturgicalDay) []calendar.Reading {
{Part: "gospel", Citation: gospel},
}
}
+
+// efNativityOctaveReadings returns the Mass of a WEEKDAY within the Octave of
+// the Nativity -- 29, 30 and 31 December.
+//
+// The Missal gives those days a direct formulary, "Diebus infra octavam
+// Nativitatis Domini, II classis": Titus 3:4-7 / Luke 2:15-20, and each date's
+// own rubric points at it ("Die 29 decembris ... Missa Puer natus est nobis,
+// ut supra", repeated verbatim on the 30th and 31st). They are named days in
+// the calendarium too -- "De V die infra octavam Nativitatis Domini, II
+// classis" and so on -- not ordinary ferias.
+//
+// lectio treated them as ordinary Christmas ferias, so they fell back to the
+// preceding Sunday and served "Dominica infra octavam Nativitatis Domini"
+// (Gal 4:1-7 / Luke 2:33-40). That is a DIFFERENT heading, for the Sunday
+// specifically. colitur made the identical mistake once, measured it against
+// real years and reverted it; its bootstrap_lectionary.ml records the
+// rejection so it is not re-attempted, with the scan references for both.
+//
+// Only the WEEKDAYS. When 29-31 December falls on a Sunday the day really is
+// "Dominica infra octavam" and keeps the Sunday's Mass, which is the
+// distinction the wrong citation blurred -- so the Sunday is excluded here
+// rather than merely happening not to match.
+func efNativityOctaveReadings(day calendar.LiturgicalDay) []calendar.Reading {
+ if day.Date.Month() != time.December || day.Date.Day() < 29 {
+ return nil
+ }
+ if day.Weekday == time.Sunday {
+ return nil
+ }
+ // The day within the octave, not a feast that outranks it: the observed
+ // office must still be the temporal one. A sanctoral feast keeps its own
+ // readings, as it did before this.
+ if !strings.HasPrefix(day.Observed.Slug, "ef-christmas-") {
+ return nil
+ }
+ return []calendar.Reading{
+ {Part: "first", Citation: "Titus 3:4-7"},
+ {Part: "gospel", Citation: "Luke 2:15-20"},
+ }
+}