feat: 1955 interim edition (Cum nostra hac aetate) — data, engine, validation #456

Merged
manlycucumber merged 4 commits from feature/68-1955-interim-edition into develop 2026-07-06 20:14:24 +00:00
manlycucumber commented 2026-07-06 20:01:38 +00:00 (Migrated from github.com)

Closes #69, #70, #71 — Epic #68 (the 1955 interim / Cum nostra hac aetate engine), milestone v0.3.0.

The 1955 reform (S.R.C. decree of 23 Mar 1955, in force 1 Jan 1956) as an additive edition over the
already-validated 1954 (Divino Afflatu) engine. Like 1954, it is isBuilt: false — it resolves through
DayResolver::forEdition(RubricSystem::rubricae1955()) for validation, and the public CalendarCatalog
boundary refuses day('1955') until the deferred temporal casuistry lands. The 1962 golden fixture is
byte-identical throughout; the corpus is reproducible.

#69 — the dataset (a generator-derived delta)

Rather than author ~250 redundant YAML blocks, deriveCumNostra1955 computes the roman-rubricae-1955
edition from the 1954 data by the reform's mechanical transform: semidouble → simple (II.20), simple →
commemoration (II.21), doubles unchanged. Grades cite the cn-1955 decree; colours inherit ordo-1954.
The transform reconciles exactly (349 → 319 attribute records = the suppressions below).

#70 — octave & vigil suppressions + the precedence engine

  • The derive suppresses the nine 1954-only vigils to the surviving four (II.8-9) and all sanctoral
    octaves (II.11 — octaves.yaml declares none for 1955).
  • Rubrics1955Precedence holds only what Cum nostra changed: no semidouble tier; the 0/1/2 commemoration
    caps (III.4) via a tier-aware dayClassFor() (so an Advent Sunday elevated to the first class by II.3
    takes the zero cap despite its shared 1962 rank); the never-omitted privileged commemorations kept over
    the cap (III.2, an edition-scoped privilegedCommemorationsExemptFromLimit() honoured by the shared
    selector — 1954/1962 return false, so their resolution is unmoved); vigil-on-Sunday omitted not anticipated
    (II.10); translation restricted to first-class feasts; and a mystery of the Lord taking a per-annum
    Sunday's place (II.7, the lord-mystery set).

#71 — validation against Divinum Officium

Day-by-day cross-check of forEdition() resolution against DO's Divino Afflatu - 1954 and Reduced - 1955
engines (1954, 1957, 1958). The derived grade transform is confirmed correct; two real 1955 occurrence
departures the sweep surfaced (the first-class-only transfer rule and the II.7 lord-mystery) are fixed in the
engine. A representative cross-section is pinned as a committed fixture and asserted in CI by
HistoricalEditionOracleTest — no Perl or DO checkout needed at test time (the SSPX approval-test shape).
The differences the grade-level engine defers (the apostle-vs-martyr Tabella; the 1955-instituted St Joseph
the Worker; one single-feast grade disagreement; the shared temporal / Office-of-the-Dead categories) are
catalogued in known-differences.ndjson.

Verification

composer test (all green, incl. the 1962 golden 1583–2200), composer lint, phpstan ([OK]),
npm run verify (corpus reproducible), npm test (generator). Design: docs/design/rubric-system-model.md
Seam 6a, rewritten as built + validated.

Closes #69, #70, #71 — Epic #68 (the 1955 interim / *Cum nostra hac aetate* engine), milestone v0.3.0. The 1955 reform (S.R.C. decree of 23 Mar 1955, in force 1 Jan 1956) as an additive edition over the already-validated 1954 (Divino Afflatu) engine. Like 1954, it is `isBuilt: false` — it resolves through `DayResolver::forEdition(RubricSystem::rubricae1955())` for validation, and the public `CalendarCatalog` boundary refuses `day('1955')` until the deferred temporal casuistry lands. **The 1962 golden fixture is byte-identical throughout; the corpus is reproducible.** ## #69 — the dataset (a generator-*derived* delta) Rather than author ~250 redundant YAML blocks, `deriveCumNostra1955` computes the `roman-rubricae-1955` edition from the 1954 data by the reform's mechanical transform: semidouble → simple (II.20), simple → commemoration (II.21), doubles unchanged. Grades cite the `cn-1955` decree; colours inherit `ordo-1954`. The transform reconciles exactly (349 → 319 attribute records = the suppressions below). ## #70 — octave & vigil suppressions + the precedence engine - The derive suppresses the nine 1954-only vigils to the surviving four (II.8-9) and **all** sanctoral octaves (II.11 — `octaves.yaml` declares none for 1955). - `Rubrics1955Precedence` holds only what *Cum nostra* changed: no semidouble tier; the 0/1/2 commemoration caps (III.4) via a tier-aware `dayClassFor()` (so an Advent Sunday elevated to the first class by II.3 takes the zero cap despite its shared 1962 rank); the never-omitted privileged commemorations kept **over** the cap (III.2, an edition-scoped `privilegedCommemorationsExemptFromLimit()` honoured by the shared selector — 1954/1962 return false, so their resolution is unmoved); vigil-on-Sunday omitted not anticipated (II.10); translation restricted to first-class feasts; and a mystery of the Lord taking a per-annum Sunday's place (II.7, the `lord-mystery` set). ## #71 — validation against Divinum Officium Day-by-day cross-check of `forEdition()` resolution against DO's `Divino Afflatu - 1954` and `Reduced - 1955` engines (1954, 1957, 1958). The derived grade transform is confirmed correct; two real 1955 occurrence departures the sweep surfaced (the first-class-only transfer rule and the II.7 lord-mystery) are fixed in the engine. A representative cross-section is pinned as a committed fixture and asserted in CI by `HistoricalEditionOracleTest` — no Perl or DO checkout needed at test time (the SSPX approval-test shape). The differences the grade-level engine defers (the apostle-vs-martyr Tabella; the 1955-instituted St Joseph the Worker; one single-feast grade disagreement; the shared temporal / Office-of-the-Dead categories) are catalogued in `known-differences.ndjson`. ## Verification `composer test` (all green, incl. the 1962 golden 1583–2200), `composer lint`, `phpstan` (`[OK]`), `npm run verify` (corpus reproducible), `npm test` (generator). Design: `docs/design/rubric-system-model.md` Seam 6a, rewritten as built + validated.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Directorium/Core!456
No description provided.