From 3cb45720f5e2ba7bd8be9a5113d866be22ad07a8 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Tue, 11 Aug 2026 12:37:22 +0200 Subject: kernel(overlay): ordered layer-merge algebra with diagnostics add/suppress/replace/field-edit folded in order, last writer wins per field, empty the identity. A directive naming an unknown slug, or adding one that already exists, yields a diagnostic rather than silence or a hard failure: overlays must survive a shifted base while still surfacing authoring errors. --- lib/kernel/overlay.mli | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 lib/kernel/overlay.mli (limited to 'lib/kernel/overlay.mli') diff --git a/lib/kernel/overlay.mli b/lib/kernel/overlay.mli new file mode 100644 index 0000000..fff284e --- /dev/null +++ b/lib/kernel/overlay.mli @@ -0,0 +1,40 @@ +(** The layer-merge algebra: ordered directives over slugs, last writer wins per + field, [empty] the identity. *) + +type 'r field_edit = + | Set_rank of 'r + | Set_colour of Colour.t + | Set_subject of Subject.t + | Set_name of Lang.t * string + | Remove_name of Lang.t + | Set_citation of Citation.part * string + | Remove_citation of Citation.part +[@@deriving sexp] + +type 'r directive = + | Add of 'r Layer.entry + | Suppress of Slug.t + | Replace of Slug.t * 'r Layer.entry + | Edit of Slug.t * 'r field_edit list +[@@deriving sexp] + +type 'r t = { id : string; directives : 'r directive list } [@@deriving sexp] + +(** A directive that did not apply cleanly. Never silently dropped, never fatal: + an overlay written against a slightly different base must stay usable, and an + authoring error must still be visible. *) +type diagnostic = { overlay : string; directive : string; slug : string; message : string } + +val diagnostic_to_string : diagnostic -> string + +(** The identity overlay: [apply l empty = (l, [])]. *) +val empty : 'r t + +val apply : 'r Layer.t -> 'r t -> 'r Layer.t * diagnostic list + +(** Folds overlays in order; diagnostics accumulate in application order. *) +val merge : 'r Layer.t -> 'r t list -> 'r Layer.t * diagnostic list + +(** Loads an overlay from a sexp file. Parse and validation failures come back + as [Error], never as an exception. *) +val load : (Sexplib0.Sexp.t -> 'r) -> string -> ('r t, string) result -- cgit v1.3