feat: rubric-system (edition) abstraction seam (#59) #446

Merged
manlycucumber merged 1 commit from feature/59-rubric-system into develop 2026-07-04 00:05:01 +00:00
manlycucumber commented 2026-07-04 00:03:41 +00:00 (Migrated from github.com)

The seam for Core v0.3 — the rubric-system (edition) axis — so the engine can run the 1954 (Divino Afflatu), 1955 (interim), and 1962 (Rubricae 1960) systems from one codebase. 1962 is the only built system today; 1954/1955 are declared on the axis and arrive with #63/#68.

What lands

  • RubricSystem value object (src/Edition/) — each system's edition URN, corpus directory, label, and validity window; isBuilt() gates the reserved ones. Threaded through day()/contract()/explain() as an appended, backward-compatible $rubricSystem selector (null → default 1962). (#60)
  • Per-edition data selection (#62) — CorpusSanctoralData and PrecedenceTable read the edition directory the system names instead of a hard-coded roman-rubricae-1960 constant. The PrecedenceTable cache key gains the edition dir so two editions in one corpus tree never collide.
  • Per-edition rank/commemoration semantics (#61) — the resolver reads ranks and commemoration limits from the selected edition's tables; DayResolver::forEdition() builds the right rules + stamps the edition into the contract provenance. Selecting an unbuilt edition throws a clear message.

Orthogonal axes

The particular-calendar overlay axis (SSPX/FSSP) is unchanged; an overlay layers over an edition (per edition-governance.md). (1962, sspx) — today's live path — is unaffected.

Safety

The default resolves 1962 byte-identically: the 1583–2200 golden fixture is unmoved, and all prior tests pass. 719 tests / 37,372 assertions (15 new), phpcs + PHPStan L6 green.

Commits the approved design: docs/design/rubric-system-model.md.

Closes #60, closes #61, closes #62. Part of Epic #59.

The seam for Core v0.3 — the **rubric-system (edition) axis** — so the engine can run the 1954 (Divino Afflatu), 1955 (interim), and 1962 (Rubricae 1960) systems from one codebase. **1962 is the only built system today**; 1954/1955 are declared on the axis and arrive with #63/#68. ## What lands - **`RubricSystem`** value object (`src/Edition/`) — each system's edition URN, corpus directory, label, and validity window; `isBuilt()` gates the reserved ones. Threaded through `day()`/`contract()`/`explain()` as an **appended, backward-compatible** `$rubricSystem` selector (null → default 1962). (#60) - **Per-edition data selection** (#62) — `CorpusSanctoralData` and `PrecedenceTable` read the edition directory the system names instead of a hard-coded `roman-rubricae-1960` constant. The `PrecedenceTable` cache key gains the edition dir so two editions in one corpus tree never collide. - **Per-edition rank/commemoration semantics** (#61) — the resolver reads ranks and commemoration limits from the selected edition's tables; `DayResolver::forEdition()` builds the right rules + stamps the edition into the contract provenance. Selecting an unbuilt edition throws a clear message. ## Orthogonal axes The particular-calendar overlay axis (SSPX/FSSP) is unchanged; an overlay layers *over* an edition (per `edition-governance.md`). `(1962, sspx)` — today's live path — is unaffected. ## Safety The default resolves 1962 **byte-identically**: the 1583–2200 golden fixture is unmoved, and all prior tests pass. **719 tests / 37,372 assertions** (15 new), phpcs + PHPStan L6 green. Commits the approved design: `docs/design/rubric-system-model.md`. Closes #60, closes #61, closes #62. Part of Epic #59.
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!446
No description provided.