feat: add Season temporal value object with block-to-season helper #204

Merged
manlycucumber merged 1 commit from feature/12-season into develop 2026-07-01 05:29:27 +00:00
manlycucumber commented 2026-07-01 05:28:51 +00:00 (Migrated from github.com)

Closes #12.

Models the liturgical season (tempus) so temporal fill and the output contract agree on one typed value rather than free strings. New under src/Temporal/ (Introibo\Core\Temporal) — season is structural to the temporal cycle, neither Layer-1 identity nor a per-edition attribute.

What lands

  • Season — the eight traditional Roman seasons of the 1962 calendar: advent, christmastide, epiphany (Time after Epiphany), septuagesima, lent, passiontide, eastertide, pentecost (Time after Pentecost). Guarded fromString() + named factories; value() is the stable machine name for output.
  • Season::forBlock() — maps a coarse temporal block (a named stretch of the Proper of Time) to its season, with a genuine many-to-one: Passion Week (passiontide) and Holy Week (holy-week) both resolve to PASSIONTIDE. This is the seam the temporal factory (#14) will feed.

Septuagesima and Passiontide are first-class seasons — the two most easily folded into their neighbours (the pre-Lenten fore-season, and the last two weeks of Lent). The tests pin both boundaries.

Acceptance criteria

  • Enumerates the traditional Roman seasons used by the 1962 calendar
  • Each season exposes a stable machine name for output (value())
  • Helper maps a temporal block to its season (forBlock())
  • Unit tests cover boundary seasons (Septuagesima, Passiontide)

Verification

Local (portable toolchain): composer lint 22/22 · composer analyse PHPStan L6 [OK] · composer test 85/85 green.

Closes #12. Models the liturgical **season** (tempus) so temporal fill and the output contract agree on one typed value rather than free strings. New under `src/Temporal/` (`Introibo\Core\Temporal`) — season is structural to the temporal cycle, neither Layer-1 identity nor a per-edition attribute. ## What lands - **`Season`** — the eight traditional Roman seasons of the 1962 calendar: `advent`, `christmastide`, `epiphany` (Time after Epiphany), `septuagesima`, `lent`, `passiontide`, `eastertide`, `pentecost` (Time after Pentecost). Guarded `fromString()` + named factories; `value()` is the stable machine name for output. - **`Season::forBlock()`** — maps a coarse temporal block (a named stretch of the Proper of Time) to its season, with a genuine many-to-one: Passion Week (`passiontide`) and Holy Week (`holy-week`) both resolve to `PASSIONTIDE`. This is the seam the temporal factory (#14) will feed. Septuagesima and Passiontide are first-class seasons — the two most easily folded into their neighbours (the pre-Lenten fore-season, and the last two weeks of Lent). The tests pin both boundaries. ## Acceptance criteria - [x] Enumerates the traditional Roman seasons used by the 1962 calendar - [x] Each season exposes a stable machine name for output (`value()`) - [x] Helper maps a temporal block to its season (`forBlock()`) - [x] Unit tests cover boundary seasons (Septuagesima, Passiontide) ## Verification Local (portable toolchain): `composer lint` 22/22 · `composer analyse` PHPStan L6 `[OK]` · `composer test` 85/85 green.
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!204
No description provided.