Clean-room PHP engine for the traditional Roman liturgical calendar.
  • PHP 84.4%
  • JavaScript 14.8%
  • Shell 0.7%
  • Perl 0.1%
Find a file
manlycucumber 10e2d52a09
docs: PROJECT.md — the release train started, and the v1.2 milestone now matches the tree
v0.1.0 was tagged today (7416bbd), the first tag in the project's
history, with release automation ported off release-please to git-cliff
(#508). That closes the "when does the release train start" open
question and falsifies "nothing has ever been released" — replaced with
the two-version-axes warning, since the release tag tracks neither
Directorium::VERSION nor corpusVersion.

Record the v1.2 reconciliation: ten issues closed against tree evidence,
and — more useful — why each survivor stays open, so the next pass does
not re-litigate it. The milestone was stale in both directions.

New open question from that pass (#509): the design says office
structure-shape facts cite catholic-encyclopedia-1910, but the enforced
gate's field map covers only text leaves, so the LOBVM's 88 structure
rows shipped citing nothing and that key has zero datum citations.
2026-08-05 19:59:37 +00:00
.forgejo/workflows ci(release): stop the release publishing notes with commits silently missing 2026-08-05 14:34:06 -04:00
.githooks ci(release): stop the release publishing notes with commits silently missing 2026-08-05 14:34:06 -04:00
.github ci(release): port release automation off release-please to the tier-kit git-cliff flow (#508) 2026-08-05 11:44:39 -04:00
bin feat(contract): corpus-vs-engine golden digest gate; engineVersion 0.5.0 (Stage 0.3b) 2026-07-18 00:59:15 -04:00
data/corpus fix(office): keep the printed period at the Matins responsory repeat-divisions 2026-07-20 00:51:50 -04:00
docs feat(office): seed the Little Office BVM per-annum Lauds (Stage 4b) 2026-07-19 21:42:52 -04:00
LICENSES feat: born-cited provenance gate and CC0 licensing for the corpus (#44) (#414) 2026-07-02 10:43:12 -04:00
scripts ci(release): stop the release publishing notes with commits silently missing 2026-08-05 14:34:06 -04:00
src perf(office): memoise the day-independent office and retarget tests to the seed 2026-07-19 21:51:58 -04:00
tests chore(golden): re-freeze after the responsory repeat-division fix 2026-07-20 04:54:43 +00:00
tools fix(office): keep the printed period at the Matins responsory repeat-divisions 2026-07-20 00:51:50 -04:00
.gitattributes feat(text): ingest Clementine + Douay-Rheims psalters into paired verse streams (Stage 2b) 2026-07-18 10:32:57 -04:00
.gitignore build: scaffold composer package with PSR-4 autoloading (#199) 2026-06-30 22:21:05 -04:00
.zenodo.json feat: citable & reproducible dataset — integrity gate + release artifact + DOI prep (#238, #239, #241) (#473) 2026-07-10 18:03:42 -04:00
CHANGELOG.md chore(release): v0.1.0 2026-08-05 15:02:26 -04:00
CITATION.cff feat: citable & reproducible dataset — integrity gate + release artifact + DOI prep (#238, #239, #241) (#473) 2026-07-10 18:03:42 -04:00
cliff.toml ci(release): port release automation off release-please to the tier-kit git-cliff flow (#508) 2026-08-05 11:44:39 -04:00
composer.json chore: finalise composer metadata and lean packaging for 1.0 (#98) (#477) 2026-07-10 18:52:44 -04:00
ERRATA.md Rebrand: Introibo -> Directorium (#454) 2026-07-06 12:58:00 -04:00
KNOWN-LIMITATIONS.md feat: dated decree overlays make the Novus Ordo a living calendar (#366) (#489) 2026-07-11 22:59:47 -04:00
LICENSE chore: scaffold workflow-full baseline 2026-06-30 18:55:35 -04:00
phpcs.xml.dist Rebrand: Introibo -> Directorium (#454) 2026-07-06 12:58:00 -04:00
phpstan.neon.dist feat: freeze resolveYear() as a golden-fixture safety gate (#365) (#416) 2026-07-02 11:09:20 -04:00
phpunit.xml.dist Rebrand: Introibo -> Directorium (#454) 2026-07-06 12:58:00 -04:00
PROJECT.md docs: PROJECT.md — the release train started, and the v1.2 milestone now matches the tree 2026-08-05 19:59:37 +00:00
README.md docs: reconcile SOURCES.md and README with the shipped corpus 2026-08-05 19:58:05 +00:00
renovate.json chore: enable Renovate dependency updates 2026-07-12 19:34:48 +00:00
REUSE.toml Rebrand: Introibo -> Directorium (#454) 2026-07-06 12:58:00 -04:00
ROADMAP.md ci: dedicated 'validate (overlays)' gate for the particular calendars (#87) (#470) 2026-07-10 16:54:25 -04:00
SOURCES.md docs: reconcile SOURCES.md and README with the shipped corpus 2026-08-05 19:58:05 +00:00

Directorium Core

Liturgical-calendar engine for the traditional Roman rite — Introíbo ad altáre Dei.

Directorium Core is a clean-room PHP library that computes the traditional Roman liturgical calendar. For any date it resolves the office of the day, its rank/class, liturgical colour, season, commemorations, and the occurrence/concurrence between them — beginning with the 1962 Roman rubrics (= 1960) and growing to the other traditional systems. It is the authoritative engine behind the Directorium API, the directorium.app website, and the Ordo WordPress plugin.

The engine is independently validated day-by-day against external oracles (the missalemeum calendar, the SSPX ordo feed, and Divinum Officium's reference implementation), so its output is provably correct across centuries. The compiled calendar corpus ships as generated static data.

Status

v0.1.0 — the first tagged release, cut 2026-08-05 (see CHANGELOG.md).

Note the two version axes, which do not track each other: the release tag is cut by the automation, while Directorium::VERSION (0.5.0) is the engine version and corpusVersion the data version. They are separate on purpose — a golden-digest move is attributed to exactly one of them and never left unexplained.

Four editions (1962, 1954, 1955, Novus Ordo 2002) and four overlays resolve across a proven 15842200. The v1.2 Office/text layer carries the entire per-annum Little Office of the BVM — all eight hours — resolving into every 1962 day. See the roadmap, which predates v1.2.

Install

composer require directorium/core

Requires PHP 7.4+. No runtime dependencies.

Usage

Two free functions in the Directorium\Core namespace are the entry points:

use function Directorium\Core\day;
use function Directorium\Core\contract;

// The resolved office as typed value objects:
$day = day(new DateTimeImmutable('2026-06-30'));
foreach ($day->celebration() as $office) {
    echo $office->id()->toString(), ' — ', $office->rank()->label(), "\n";
}

// The versioned, JSON-ready output contract (what the Api/Site/Ordo build on):
$c = contract(new DateTimeImmutable('2026-06-30'), false, 'sspx', '1954');
echo $c['edition'];               // roman:divino-afflatu
echo $c['celebration'][0]['id'];  // the winning office

Both take optional $calendar (particular-calendar overlay) and $rubricSystem (edition) selectors. The integration guide covers the full API and worked examples; calendars and editions explains the editions (1962/1954/1955) and overlays (SSPX/FSSP/ICKSP) and how to select them.

Output contract

contract() returns the versioned, JSON-ready output contract — the public shape the Api, Site, and Ordo repos build on. It is versioned (currently 1.0.2) and grows only additively within 1.x. Every field, the three-version provenance scheme, the stability guarantees, and worked examples are documented in docs/design/output-contract.md.

Development

Work branches off develop and lands via merge-commit PRs with Conventional-Commit titles — never squash or rebase, which re-author the commit and destroy the ssh signature (commits must land verified). Releases are cut automatically by release-please (see docs/releasing.md). Local checks once the code lands:

composer install
composer exec phpcs        # PSR-12
composer exec phpstan      # static analysis
php tests/validate-oracle.php tests/fixtures/oracle.json   # day-by-day regression

Licence

© 2026 Directorium. Licensed under AGPL-3.0-or-later (see LICENSE). The compiled calendar dataset is released under CC0.