sim_expr_tree_calc/calc/receipt.rs
1use sim_incremental_core::ObservationKind;
2
3use super::{AuthorityDigest, CalcError, CalcQuery, CalcTrigger, PolicyDigest};
4
5/// Stable identity of one directed or automatic calculation request.
6#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
7pub struct RequestId(u64);
8
9impl RequestId {
10 /// Creates a request id from persisted bits.
11 #[must_use]
12 pub const fn new(value: u64) -> Self {
13 Self(value)
14 }
15
16 /// Returns the persisted id bits.
17 #[must_use]
18 pub const fn get(self) -> u64 {
19 self.0
20 }
21}
22
23/// Incremental reuse/forcing behavior of a directed request.
24#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
25pub enum CalcRequestMode {
26 /// Verify the roots and reuse every current memo.
27 Verify,
28 /// Force only the selected roots while reusing current dependencies.
29 ForceRoots,
30 /// Force roots and every reachable calculated dependency.
31 ForceRecursive,
32}
33
34/// Why a calculation attempt ran.
35#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
36pub enum CalcReason {
37 /// A caller explicitly requested verification.
38 DirectedVerify,
39 /// A caller explicitly forced selected roots.
40 DirectedForceRoots,
41 /// A caller explicitly forced roots and their calculated dependency closure.
42 DirectedForceRecursive,
43 /// A mutation enqueued automatic work.
44 AutomaticMutation,
45 /// A budget-stopped request resumed through its continuation.
46 Continuation,
47}
48
49impl CalcReason {
50 pub(super) fn for_mode(mode: CalcRequestMode) -> Self {
51 match mode {
52 CalcRequestMode::Verify => Self::DirectedVerify,
53 CalcRequestMode::ForceRoots => Self::DirectedForceRoots,
54 CalcRequestMode::ForceRecursive => Self::DirectedForceRecursive,
55 }
56 }
57}
58
59/// Terminal outcome recorded for one cell attempt.
60#[derive(Clone, Debug, Eq, PartialEq)]
61pub enum CalcOutcome {
62 /// A current value committed.
63 Succeeded,
64 /// A deterministic calculation failure committed.
65 Failed {
66 /// Stable failure text.
67 message: String,
68 },
69 /// Policy prevented the requested cell from running.
70 Blocked {
71 /// Stable blocking explanation.
72 message: String,
73 },
74 /// The request was cancelled without corrupting an earlier memo.
75 Cancelled,
76 /// A bounded request stopped and retained an explicit continuation.
77 BudgetExhausted {
78 /// Stable exhausted-budget explanation.
79 message: String,
80 /// Incremental continuation token bits, when supplied.
81 continuation: Option<u64>,
82 },
83}
84
85/// One bounded dependency observation in a calculation receipt.
86#[derive(Clone, Debug, Eq, PartialEq)]
87pub struct DependencyStamp {
88 /// Observed query key.
89 pub query: CalcQuery,
90 /// Observation class.
91 pub kind: ObservationKind,
92 /// Observed revision.
93 pub revision: u64,
94 /// Observed value fingerprint for query reads.
95 pub fingerprint: Option<u64>,
96}
97
98/// One existing kernel effect-ledger record summarized into a receipt.
99#[derive(Clone, Debug, Eq, PartialEq)]
100pub struct EffectStamp {
101 /// Effect kind symbol.
102 pub kind: String,
103 /// Whether resolution aborted.
104 pub aborted: bool,
105}
106
107/// Bounded immutable evidence for one calculation attempt.
108#[derive(Clone, Debug, Eq, PartialEq)]
109pub struct CalcReceipt {
110 /// Owning request.
111 pub request_id: RequestId,
112 /// Canonical absolute cell path.
113 pub cell: String,
114 /// Source observation revision used by the attempt.
115 pub source_revision: u64,
116 /// Effective inherited calculation-policy digest.
117 pub policy_digest: PolicyDigest,
118 /// Effective diminished authority digest.
119 pub authority_digest: AuthorityDigest,
120 /// Direct dependency observations retained under the receipt bound.
121 pub dependencies: Vec<DependencyStamp>,
122 /// Number of direct dependencies omitted from `dependencies`.
123 pub omitted_dependencies: usize,
124 /// Digest covering the complete direct dependency list.
125 pub dependency_digest: u64,
126 /// Existing effect-ledger evidence retained under the receipt bound.
127 pub effects: Vec<EffectStamp>,
128 /// Number of effect records omitted from `effects`.
129 pub omitted_effects: usize,
130 /// Monotone logical tick at attempt start.
131 pub started_tick: u64,
132 /// Monotone logical tick at attempt finish.
133 pub finished_tick: u64,
134 /// Optional human wall-clock observation at attempt start.
135 pub wall_started_ms: Option<u64>,
136 /// Optional human wall-clock observation at attempt finish.
137 pub wall_finished_ms: Option<u64>,
138 /// Terminal attempt outcome.
139 pub outcome: CalcOutcome,
140 /// Current result fingerprint, when a memo committed.
141 pub result_fingerprint: Option<u64>,
142 /// Request reason.
143 pub reason: CalcReason,
144 /// Effective trigger in force for the attempted cell.
145 pub trigger: CalcTrigger,
146}
147
148/// Non-evaluating status exposed by the explanation model.
149#[derive(Clone, Copy, Debug, Eq, PartialEq)]
150pub enum CalcStatus {
151 /// No attempt has committed or failed.
152 NeverCalculated,
153 /// The committed memo is current.
154 Fresh,
155 /// An input changed and verification has not yet established cutoff.
156 MaybeStale,
157 /// Automatic work is queued.
158 Pending,
159 /// The last attempt failed.
160 Failed,
161 /// The effective policy is frozen.
162 Frozen,
163 /// Policy or missing authority blocked the last attempt.
164 Blocked,
165}
166
167/// Inspectable, non-evaluating explanation of one cell's current state.
168#[derive(Clone, Debug, Eq, PartialEq)]
169pub struct CalcExplanation {
170 /// Canonical cell path.
171 pub cell: String,
172 /// Current non-evaluating status.
173 pub status: CalcStatus,
174 /// Current source revision.
175 pub source_revision: u64,
176 /// Current effective policy digest.
177 pub policy_digest: PolicyDigest,
178 /// Current effective authority digest.
179 pub authority_digest: AuthorityDigest,
180 /// Latest bounded receipt, when any.
181 pub receipt: Option<CalcReceipt>,
182 /// Stable human-readable reasons for the status.
183 pub reasons: Vec<String>,
184}
185
186/// Result of one directed root in a stable multi-root request.
187#[derive(Clone)]
188pub struct DirectedCellResult {
189 /// Canonical root path.
190 pub cell: String,
191 /// Current ordinary value or typed calculation error.
192 pub result: Result<sim_kernel::Value, CalcError>,
193}
194
195/// Aggregate result of a directed calculation request.
196#[derive(Clone)]
197pub struct DirectedCalcReport {
198 /// Stable request identity.
199 pub request_id: RequestId,
200 /// Root outcomes in canonical path order.
201 pub cells: Vec<DirectedCellResult>,
202}