1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//! Runtime proof mode — post-hoc validation of UI invariants against the
//! actual rendered output.
//!
//! # Motivation
//!
//! Compile-time contracts (`Prop` / `Established<P>`) can prove that the *data*
//! fed into the renderer satisfies an invariant, but they cannot see what the
//! renderer actually drew on screen. `RenderVerifiable` closes that gap: after
//! each frame is painted, the framework inspects the live render buffer and
//! asserts that the invariant still holds.
//!
//! # Architecture
//!
//! ```text
//! elicit_ui — RenderContext (abstract buffer inspection)
//! RenderVerifiable<Ctx> (per-Prop impl hook)
//!
//! elicit_ratatui — impl RenderContext for ratatui::buffer::Buffer
//! elicit_egui — impl RenderContext for egui::Context (future)
//! elicit_leptos — impl RenderContext for leptos DOM snapshot (future)
//!
//! user crate — impl RenderVerifiable<RatatuiRenderContext>
//! for BoardColumnsAligned { ... }
//! ```
//!
//! # Usage
//!
//! After rendering a node, call [`verify_in_debug`] with the render context
//! and the area that was painted. In debug builds this runs all registered
//! checks via `debug_assert!`. In release builds it compiles to nothing.
//!
//! ```rust,ignore
//! // In render_node, after drawing the board Article:
//! verify_in_debug::<BoardColumnsAligned, _>(&ctx, &area);
//! ```
use Prop;
// ── RenderContext ─────────────────────────────────────────────────────────────
/// Abstract view into a rendered frame buffer.
///
/// Each frontend crate implements this for its own native buffer type
/// (e.g. `ratatui::buffer::Buffer`, `egui::Context`). The methods are
/// intentionally minimal — just enough to inspect rendered symbol positions
/// without exposing frontend-specific types to `elicit_ui`.
// ── RenderVerifiable ──────────────────────────────────────────────────────────
/// Post-render invariant check for a [`Prop`].
///
/// Implement this on a `Prop` type to declare how to verify — by inspecting
/// the live render buffer — that the invariant is actually preserved in what
/// was drawn on screen.
///
/// Implementations should:
/// - use `debug_assert!` (or [`verify_in_debug`]) so checks are zero-cost in
/// release builds
/// - emit `tracing::error!` before asserting, so the log captures context even
/// if the assert fires
/// - be as specific as possible about *which* cells to inspect, to avoid false
/// positives from unrelated content
// ── verify_in_debug ───────────────────────────────────────────────────────────
/// Run `P::verify_rendered` in debug builds; compile to nothing in release.
///
/// Call this immediately after rendering the node that `P` governs.