(** The temporal identity of a date: where in the liturgical year it sits, and the temporal cycle's own office for it. *) type ('s, 'r) t = { season : 's; week : int option; (** [None] for named days outside a numbered week *) weekday : Date.weekday; office : 'r Celebration.t; } [@@deriving sexp] module type RITE = sig val id : string type season type rank val vocab : (season, rank) Vocab.t (** First day of the liturgical year opening in civil year [y]. *) val year_start : int -> Date.t (** Total over 1583..9999: every date yields exactly one temporal identity. *) val temporal : Date.t -> (season, rank) t end