aboutsummaryrefslogtreecommitdiff
path: root/CLAUDE.md
diff options
context:
space:
mode:
Diffstat (limited to 'CLAUDE.md')
-rw-r--r--CLAUDE.md168
1 files changed, 168 insertions, 0 deletions
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000..cb8b0f4
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,168 @@
+# 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/<rite>`) 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 <year>` (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.