# colitur — working context for Claude Read this first, then skim the two authoritative docs it points to. This file orients a fresh session; the specs hold the exhaustive detail. ## What colitur is *computus liturgicus* + Latin `colitur` ("He is worshipped"). A **safe, highly-tested, deterministic OCaml engine** that computes and validates **liturgical calendars** for multiple rites and emits universal, template-driven output. It computes the **day identity** (season, week, cycle, observed celebration with rank/colour/flags, commemorations, transfers) and the day's **reading citations** (references like `Jn 3:16`, never Bible text), correct all the way to year **9999**. Starts with the Roman **EF (1962)** and **OF** forms; the architecture generalizes to any deterministic rite (Byzantine, Ambrosian, pre-Trent) as future modules. **Sibling projects** (same author, `~/git/projects/`): **lectio** (Go; the shipped OF+EF readings engine, 0-error vs references 2005–2050 — colitur bootstraps its data from lectio and uses lectio as a differential oracle), **dlectio** (offline Android app over lectio), **clectio** (tiny C build). colitur is a **standalone** tool, not part of lectio. ## The authoritative docs (read these) - **Design:** `docs/superpowers/specs/2026-07-30-colitur-design.md` — the full, approved design (scope, kernel+rites+overlays architecture, data model, output, the 5 validation layers, phasing, success criteria). **This is the contract.** - **Rules register:** `docs/research/rules-register.md` — every temporal/precedence rule the engine computes against, each citing its normative paragraph. The **EF rubrics are primary-source-verified** against the 1962 Missal (RG 91 Table of Precedence full 28 entries, occurrence RG 92–95, commemorations RG 108–111, vigils/octaves/Rogations/Sunday-classes, seasons RG 71–77). OF side cites UNLYC. - **Plans:** `docs/superpowers/plans/` — `…-plan1-computus-skeleton.md` (done). - **Primary scans:** `docs/research/*.pdf` — the 1962 Missale Romanum (Latin) and the *Rubricarum instructum* motu proprio. `docs/` is **gitignored** (research + copyrighted scans stay off the public repo). ## Binding decisions (do not relitigate) 1. **Source of truth = the 1962 Missale Romanum + its Rubricae Generales.** Divinum Officium, missalemeum, gcatholic are **comparison oracles only** — any **divergence from a reference is flagged LOUDLY** in validation, never silently swallowed. 2. **Scope is strictly the 1962 Missal** (1960 rubrics + 1955 Holy Week). Every addition (2020 *Quo Magis*/*Cum Sanctissima*, any community's proper) is an **overlay**, never core. 3. **Data is bootstrapped from lectio** (0-error vs missalemeum), then validated by **rigorous property + differential testing over a large RANDOM sample across the whole 1583–9999 range** — not only 2005–2050. 4. **EF and OF are peer rite modules** — a form is never an overlay of another form. Each has its own `temporal` + `precedence` **code** and its own **data**; they share only the kernel. 5. **Build EF end-to-end first** as the pilot vertical slice (it is the harder, more idiosyncratic form, and its rules are already fully researched), learn from it, *then* add OF as the second module to prove the `RITE` abstraction generalizes. ## Architecture (one screen) Rite-agnostic **kernel** + **rite modules** (plug in via a signature) + **data overlays**. - **Kernel** (`lib/kernel`, pure, total, bounded 1583–9999): `Computus` (Gregorian + Julian Easter + anchors), `Date` (proleptic Gregorian arithmetic), `Overlay` (ordered layer-merge algebra: field-level add/suppress/replace/edit, last-writer- wins, `empty` = identity), `Precedence` (general resolver parameterized by a rite's ruleset → observed day + commemorations + transfers; deterministic, terminating), `Calendar` (orchestrator), `Validate` (the invariant/property harness). - **Rite module** (`lib/rites/`) satisfies: ```ocaml module type RITE = sig val id : string val temporal : Date.t -> Temporal.t (* season, week, cycle, movable feasts — CODE *) val precedence : Precedence.rules (* rite ranking + resolution — CODE *) val sanctoral : Calendar.layer (* fixed-date base calendar — DATA *) val lectionary : Lectionary.t (* slug/day → citations — DATA *) end ``` Temporal + precedence are **code** (auditable, property-tested); sanctoral + lectionary are **data** (`.sexp`, bootstrapped from lectio). `Rite_ef` then `Rite_of`. - **Result type** `LiturgicalDay` = { date; rite; season; week/cycle; observed (slug, names, rank, colour, flags); commemorations; transfer; citations } — the single stable schema for all output. - **Output**: one schema → CSV / JSON / S-expression, rendered by a **logic-less Mustache-family template engine** (user supplies the target-language template; the engine never executes code). Unix-composable CLIs: `compute | render`, `table`. - **Data format**: **S-expressions** (`sexplib`/`ppx_sexp_conv`) — the OCaml type *is* the format, parse/print auto-derived, no hand-written parser. ## Validation (the "sure bet" pillar — 5 layers) 1. **Types** — illegal states unrepresentable (closed variants for ranks/colours/ seasons; dates validated at construction; resolution total). 2. **Property (QCheck), year-independent** — hold for every year 1583–9999: exactly one observed day per date; year covered once, no gaps; seasons contiguous; Easter a Sunday in [Mar 22, Apr 25]; movable feasts at correct Easter-offset weekday; overlay merge deterministic + `empty` identity; sexp round-trips. **This is how confidence extends past the oracle horizon (~2050).** 3. **Differential vs lectio** — every day 2005–2050 agrees (season, rank, observed, citations). 4. **Oracle cross-check** — vs missalemeum (EF) / litcal (OF) in lectio's `sources/`. 5. **Golden regression** — landmark + known-tricky years pinned. ## Current state (Plan 1 DONE — verify with `git log`) Branch **`ef-pilot-plan1`**, ~6 commits. The Computus **walking skeleton** is built and green: - `lib/kernel/date.ml[i]` — `Date`: opaque rata-die (Howard Hinnant civil↔days, as in lectio); `make ~year ~month ~day : (t,string) result` (validates, 1583..9999); `year/month/day/weekday/to_rata/of_rata/add_days/compare`. - `lib/kernel/computus.ml[i]` — `gregorian_easter`, `julian_easter`, and anchors `ash_wednesday/palm_sunday/ascension/pentecost/corpus_christi`. - `bin/main.ml` — CLI `colitur easter ` (prints Easter + anchors; bad year → exit 2). - `test/` — alcotest unit + qcheck property + a `cli.t` cram test. All green. - Build: dune 3.0, **OCaml 5.2.0 project-local opam switch** (`./_opam` already present), deps `dune alcotest qcheck qcheck-alcotest`, `cram enable`, `generate_opam_files`. License **AGPL-3.0-or-later**. `sexplib`/`ppx_sexp_conv` and a Mustache lib are **not yet added** — they arrive with the data model in Plan 2/3. ### Build & test ```sh eval $(opam env) # activate the project-local switch (run from this dir) dune build dune test dune exec colitur -- easter 2026 ``` ## What's next - **Plan 2 — kernel data model & resolution.** `LiturgicalDay` schema; `Overlay` (the layer-merge algebra); the `Precedence` framework (rite-parameterized resolver); the **EF `temporal`** (seasons per RG 71–77 incl. Septuagesima + the cycle); the `Validate` harness. Add `sexplib`/`ppx_sexp_conv`. Each piece property-tested. **Brainstorm → writing-plans → execute.** - **Plan 3 — EF end-to-end (the pilot).** The EF rite module: `temporal` + `precedence` **code** from the register's RG citations (RG 91 table, occurrence RG 92–95, commemorations RG 108–111, transfers RG 95–102); sanctoral + lectionary **data** bootstrapped from lectio; **plus a minimal output path** (CSV + one template) so it produces a real table. Differential vs lectio + oracle vs missalemeum green 2005–2050; deep-tail edges checked vs the Missal PDFs. **Capture the lessons.** - **Then**: OF rite module (proves `RITE` generalizes) → full output/rendering → hardening (property sweep to 9999, golden pins, first tag). Still-open research residuals are listed in the register §6 (EF reading-selection rules; Christ-the-King/Holy-Family placement; data audit) — verify-while-coding, not blockers. ## How to work here - **Superpowers workflow**: `brainstorming` → `writing-plans` → `executing-plans` or `subagent-driven-development`. Present a design and get approval before coding. Plans live in `docs/superpowers/plans/`, specs in `docs/superpowers/specs/`. - **TDD**, bite-sized tasks, a commit per task on the feature branch (never straight to `main` without consent). - **Every temporal/precedence rule carries a source citation** (RG/UNLYC paragraph) in a comment — grep-able, matching the register. - **Kernel is total & deterministic**: no wall-clock, randomness, or environment reads; fallible construction returns `result`/`option`, never raises on in-range input; years outside 1583–9999 rejected at the boundary. - **Commits**: conventional-commit style, subject + body only. **No AI/tool trailer of any kind** (the author considers them noise in a public repo). - **License header**: files may carry a short SPDX `AGPL-3.0-or-later` line. - `docs/` is gitignored — design/research/scans stay local; only code + README + LICENSE + this file are tracked.