feat: make temporal office attributes data-driven (#42, part 2) #419
No reviewers
Labels
No labels
area: build
area: ci
area: compare
area: data
area: engine
area: model
area: provenance
area: rite
area: validation
backport
blocked
breaking
confirmed
dependencies
duplicate
epic
github_actions
invalid
needs-info
needs-triage
php
priority: high
priority: low
priority: medium
regression
type: bug
type: chore
type: correction
type: docs
type: enhancement
type: feature
type: fix
type: perf
type: refactor
type: security
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Directorium/Core!419
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feature/42-temporale-attributes"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Completes #42 — the second and final half. Part 1 (#418) made the temporal skeleton data (Easter offsets, block→season); this makes the per-office overlay data.
What moves to data
Every temporal day belongs to one of 61 archetypes (an Advent Sunday, a Lenten Ember day, the Nativity, …). The six block-fillers held each archetype's
kind,rank,colour, and Latinnameas inline literals. Those facts now live in cited corpus data behind aTemporalAttributesread seam.The fillers still own the structure: they compute which archetype a date is, its runtime ordinal (week / Sunday number), and its weekday. Date arithmetic and the naming grammar (Roman numerals, the Feria/Sabbato prefix) stay in PHP — only the edition-varying facts became data. Same principle as part 1 (arithmetic in code, offsets in data).
Shape (matches the frozen #39 schemas exactly)
facts/temporale.yaml→identity/temporale.ndjson(edition-invariant:archetype,kind,names.latemplate) +editions/roman-rubricae-1960/attributes.temporale.ndjson(per edition:rank,colour), joined by the archetype key — the same identity/attributes split as the sanctoral.names.lais a template:{ord}is filled with a Roman numeral; a leading{feria}marker is composed into a Feria-N / Sabbato name by the engine's existingferiaLatin(), so the rendered string is byte-identical to the old inline code.mr-1920);rank/colourcite the 1960 rubrics (rg-1960). The born-cited provenance gate covers both new shapes (fail-closed).New code
TemporalArchetypevalue object (kind + rank + colour + name renderer)TemporalAttributesreader seam (memoised, joins the two shapes)Corpus::identityTemporale()/attributesTemporale()ChristmasCycle,LentenCycle,HolyWeek,Eastertide,TimeAfterPentecost,MovableFeastsread through the seam.Safety
The golden fixture is unchanged —
resolveYear()output is byte-identical across the whole swap (1584–2200), proving the refactor inert by construction. The pre-existing corpus outputs and their hashes are untouched; the change is purely additive (2 new NDJSON files + their manifest entries + usage counts).composer test→ 608 tests, 31 566 assertions green (9 newTemporalAttributesTestcases pin the join + the feria/ordinal renderer)composer lintclean ·composer analyse[OK] No errorsnpm run verify→ reproducible across builds, matching the committed copyCloses #42.