(** Serialization of performed facts, and their replay through the core. The core types are opaque and carry no serializers, by design: the logbook records, it never interprets. This module is the trust boundary for stored data. It captures only what was performed — exercise, load, reps, outcome, timestamps, and the basis on which a workout was begun — and rebuilds a {!Evidence.Workout.t} by driving the same constructors a live session does. A workout's prescription is not stored. It is found again by name in the routine catalog, so a stored workout stays valid only as long as its routine and workout names do. That is the intended coupling: prescriptions are authored, not recorded. *) type error = | Malformed of string (** The stored text does not parse. *) | Unknown_exercise of string | Unknown_routine of string | Unknown_workout_name of { routine : string; workout : string } | Replay_rejected of string (** The core refused a stored stimulus; the store is inconsistent. *) val pp_error : Format.formatter -> error -> unit val encode_workout : routine_name:string -> Evidence.Workout.t -> string (** A stable, single-string encoding of a performed or in-progress workout. [routine_name] identifies the catalog routine the prescription came from. *) val decode_workout : find_routine:(string -> Prescription.Routine.t option) -> string -> (Evidence.Workout.t, error) result (** Rebuilds a workout, resolving its prescription through [find_routine]. *) val encode_feedback : Evidence.Feedback.t -> string (** A stable, single-string encoding of a subjective feedback report. *) val decode_feedback : string -> (Evidence.Feedback.t, error) result (** Rebuilds a feedback report from its encoding. *)