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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
//! Behavioral contract for the `PrismModel` developer surface.
//!
//! Per the UOR-Framework wiki ADR-020 + ADR-022, `PrismModel` codifies
//! the application author's typed-iso contract: an `Input` feature type,
//! an `Output` label type, and a type-level `Route` witness of the term
//! tree mapping one to the other. ADR-022 D4 parameterizes the trait
//! over the three substitution axes (`HostTypes`, `HostBounds`,
//! `Hasher`), expressing the H-indexed family of carriers (ADR-019)
//! directly: every `impl PrismModel<H, B, A> for …` block is one member
//! of the family.
//!
//! ADR-022 D1 specifies the seal mechanism: a `#[doc(hidden)] pub mod
//! __sdk_seal { pub trait Sealed {} }` so the `prism_model!` proc-macro
//! from `uor-foundation-sdk` can emit `impl Sealed for <Model>` and
//! `impl Sealed for <RouteWitness>` alongside the `FoundationClosed`
//! and `PrismModel` impls. Foundation sanctions the identity-route
//! impl (`ConstrainedTypeInput`) directly so trivial models compile
//! without going through the macro.
//!
//! ADR-022 D5 specifies the catamorphism call-site: `run_route<H, B, A,
//! M>(input)`. The macro-emitted `forward` body is exactly
//! `pipeline::run_route::<H, B, A, Self>(input)`.
//!
//! This test pins:
//!
//! 1. `PrismModel`, `FoundationClosed`, `__sdk_seal::Sealed`, and
//! `run_route` are reachable through `pipeline::*`.
//! 2. The trait carries the three associated types ADR-020 specifies
//! (`Input`, `Output`, `Route`) with their respective bounds.
//! 3. The trait's three generic parameters are exactly the three
//! substitution axes (ADR-022 D4) — `H: HostTypes`, `B: HostBounds`,
//! `A: Hasher`.
//! 4. `run_route<H, B, A, M>` is the canonical catamorphism entry point
//! (ADR-022 D5).
use uor_foundation::enforcement::{ConstrainedTypeInput, Grounded, Hasher};
use uor_foundation::pipeline::{run_route, FoundationClosed, PrismModel};
use uor_foundation::{DefaultHostTypes, HostBounds, HostTypes, PipelineFailure};
use uor_foundation_test_helpers::{
ReferenceHostBounds, REFERENCE_FP_MAX as FP, REFERENCE_INLINE_BYTES as N,
};
/// `ConstrainedTypeInput` is foundation's identity route: the default
/// empty shape carrying no constraints. Foundation sanctions its
/// `FoundationClosed` impl directly so test code (and trivial real
/// applications) can declare a `PrismModel` without going through the
/// `prism_model!` macro. The macro is the canonical producer of impls
/// for non-trivial routes.
fn _identity_route_is_foundation_closed() {
fn _accepts<R: FoundationClosed<N>>() {}
_accepts::<ConstrainedTypeInput>();
}
/// A test-only `Hasher` impl emulating what `uor-foundation-test-helpers`
/// provides — duplicated here to keep this behavior test self-contained.
#[derive(Debug, Clone, Copy, Default)]
struct TestHasher;
impl Hasher for TestHasher {
const OUTPUT_BYTES: usize = 16;
fn initial() -> Self {
Self
}
fn fold_byte(self, _: u8) -> Self {
self
}
fn finalize(self) -> [u8; 32] {
[0; 32]
}
}
/// The test-side seal impl emulating what the `prism_model!` macro
/// emits: `impl __sdk_seal::Sealed for <Model>`. The `__sdk_seal`
/// module is `#[doc(hidden)] pub` per ADR-022 D1; external crates
/// that import it are syntactically permitted but architecturally
/// non-conforming. This test crate uses it deliberately to pin the
/// trait surface.
struct IdentityModel;
impl uor_foundation::pipeline::__sdk_seal::Sealed for IdentityModel {}
impl<'a> PrismModel<'a, DefaultHostTypes, ReferenceHostBounds, TestHasher, N, FP>
for IdentityModel
{
type Input = ConstrainedTypeInput;
type Output = ConstrainedTypeInput;
type Route = ConstrainedTypeInput;
/// Per wiki ADR-022 D5, `forward` delegates to `run_route` — that is
/// the architecturally-committed body the `prism_model!` macro
/// emits. This test impl writes it by hand to pin the contract.
fn forward(input: Self::Input) -> Result<Grounded<'a, Self::Output, N, FP>, PipelineFailure> {
run_route::<
DefaultHostTypes,
ReferenceHostBounds,
TestHasher,
Self,
uor_foundation::pipeline::NullResolverTuple,
uor_foundation::pipeline::EmptyCommitment,
N,
FP,
>(
input,
&uor_foundation::pipeline::NullResolverTuple,
&uor_foundation::pipeline::EmptyCommitment,
)
}
}
#[test]
fn prism_model_surface_resolves_at_crate_root() {
fn _accepts_prism_model<'a, H, B, A, M, const INLINE_BYTES: usize, const FP_MAX: usize>()
where
H: HostTypes,
B: HostBounds,
A: Hasher<FP_MAX>,
M: PrismModel<'a, H, B, A, INLINE_BYTES, FP_MAX>,
{
}
fn _accepts_foundation_closed<R: FoundationClosed<N>>() {}
_accepts_prism_model::<DefaultHostTypes, ReferenceHostBounds, TestHasher, IdentityModel, N, FP>(
);
_accepts_foundation_closed::<ConstrainedTypeInput>();
// Pin the associated-type identity: a trivial model carries the
// foundation-empty shape on every position.
let input_name = core::any::type_name::<
<IdentityModel as PrismModel<
'static,
DefaultHostTypes,
ReferenceHostBounds,
TestHasher,
N,
FP,
>>::Input,
>();
let output_name = core::any::type_name::<
<IdentityModel as PrismModel<
'static,
DefaultHostTypes,
ReferenceHostBounds,
TestHasher,
N,
FP,
>>::Output,
>();
let route_name = core::any::type_name::<
<IdentityModel as PrismModel<
'static,
DefaultHostTypes,
ReferenceHostBounds,
TestHasher,
N,
FP,
>>::Route,
>();
assert!(input_name.ends_with("ConstrainedTypeInput"));
assert!(output_name.ends_with("ConstrainedTypeInput"));
assert!(route_name.ends_with("ConstrainedTypeInput"));
}
#[test]
fn prism_model_route_bound_is_foundation_closed() {
// Parametric assertion: any `M: PrismModel<H, B, A>` has its `Route`
// type bound by `FoundationClosed`. This is what enforces wiki
// ADR-020's closure-under-foundation-vocabulary check.
fn _route_is_foundation_closed<'a, H, B, A, M, const INLINE_BYTES: usize, const FP_MAX: usize>()
where
H: HostTypes,
B: HostBounds,
A: Hasher<FP_MAX>,
M: PrismModel<'a, H, B, A, INLINE_BYTES, FP_MAX>,
{
fn _check<R: FoundationClosed<INLINE_BYTES>, const INLINE_BYTES: usize>() {}
_check::<M::Route, INLINE_BYTES>();
}
_route_is_foundation_closed::<
DefaultHostTypes,
ReferenceHostBounds,
TestHasher,
IdentityModel,
N,
FP,
>();
// Pin behaviorally: the witnessing impl exists, observable via
// `core::any::type_name`.
let route_name = core::any::type_name::<
<IdentityModel as PrismModel<
'static,
DefaultHostTypes,
ReferenceHostBounds,
TestHasher,
N,
FP,
>>::Route,
>();
assert_eq!(
route_name,
core::any::type_name::<ConstrainedTypeInput>(),
"IdentityModel's Route is foundation's identity route",
);
}
#[test]
fn prism_model_forward_returns_grounded_result() {
// Wiki ADR-020 specifies
// `forward(input: Input) → Result<Grounded<'static, Output>, PipelineFailure>`.
// ADR-022 D5: the body delegates to `run_route`. The IdentityModel
// above writes that body by hand, so this call exercises the
// architectural surface end-to-end. Pin the result type shape; the
// identity route's empty arena lands somewhere in the
// `PipelineFailure` taxonomy at preflight time (the specific
// variant is foundation-internal).
let result = <IdentityModel as PrismModel<
'static,
DefaultHostTypes,
ReferenceHostBounds,
TestHasher,
N,
FP,
>>::forward(ConstrainedTypeInput::default());
let _: Result<Grounded<'static, ConstrainedTypeInput, N, FP>, PipelineFailure> = result;
// The identity route's preflight resolves to the `Result` shape the
// wiki commits `forward` to. Either an Ok grounded value or any
// PipelineFailure variant — both are valid; what matters is the
// signature is honoured. The shape pin above is itself the
// assertion (the let-binding's type annotation rejects any other
// shape at compile time).
let arena = <<IdentityModel as PrismModel<
'static,
DefaultHostTypes,
ReferenceHostBounds,
TestHasher,
N,
FP,
>>::Route as FoundationClosed<N>>::arena_slice();
assert_eq!(
arena.len(),
0,
"IdentityModel's route is foundation's identity route — empty term arena",
);
}
#[test]
fn prism_model_axes_express_h_indexed_family() {
// Wiki ADR-022 D4: the three generic parameters on `PrismModel`
// express the H-indexed family of carriers (ADR-019, Consequences):
// each `impl PrismModel<…> for …` is one member of the family.
//
// Pin that the trait's three generic positions are exactly the
// three substitution axes by name: `H: HostTypes`, `B: HostBounds`,
// `A: Hasher`.
fn _accepts_axes<H: HostTypes, B: HostBounds, A: Hasher>() {}
_accepts_axes::<DefaultHostTypes, ReferenceHostBounds, TestHasher>();
// The reference-axis impl resolves at compile time.
fn _resolve<
M: PrismModel<'static, DefaultHostTypes, ReferenceHostBounds, TestHasher, N, FP>,
>() {
}
_resolve::<IdentityModel>();
// Sanity: this assertion reflects the test compiles as written.
assert_eq!(
core::any::type_name::<ReferenceHostBounds>(),
"uor_foundation_test_helpers::ReferenceHostBounds",
);
}
#[test]
fn run_route_is_canonical_catamorphism_call_site() {
// Wiki ADR-022 D5: `run_route<H, B, A, M>(input)` is the
// higher-level entry point the macro-emitted `forward` body calls.
// Pin its callability with the identity model. We expect a
// `PipelineFailure` because `IdentityModel`'s route is empty —
// the body of `run_route` validates an empty `CompileUnit` and
// dispatches to `pipeline::run`, which surfaces the empty-route
// failure.
let result = run_route::<
DefaultHostTypes,
ReferenceHostBounds,
TestHasher,
IdentityModel,
uor_foundation::pipeline::NullResolverTuple,
uor_foundation::pipeline::EmptyCommitment,
N,
FP,
>(
ConstrainedTypeInput::default(),
&uor_foundation::pipeline::NullResolverTuple,
&uor_foundation::pipeline::EmptyCommitment,
);
// Surface the categorical commitment: the call returns a
// `Result<Grounded<'static, Output>, PipelineFailure>` — whichever variant
// it lands on, the function is callable as the wiki specifies.
let _: Result<Grounded<'static, ConstrainedTypeInput, N, FP>, PipelineFailure> = result;
// Pin that the entry point exists and produced a Result of the
// committed shape (specific failure variants depend on internal
// CompileUnit construction details).
assert_eq!(
core::any::type_name::<
fn(
ConstrainedTypeInput,
)
-> Result<Grounded<'static, ConstrainedTypeInput, N, FP>, PipelineFailure>,
>(),
core::any::type_name::<
fn(
ConstrainedTypeInput,
)
-> Result<Grounded<'static, ConstrainedTypeInput, N, FP>, PipelineFailure>,
>(),
);
}