Skip to content

02 Architecture Constraints

Alex Flom edited this page May 22, 2026 · 14 revisions

Architecture Constraints

This section enumerates the constraints that bind every conforming implementation of Prism. The constraints are normative: an implementation that does not satisfy a constraint listed here is not a Prism implementation.

Technical Constraints

TC-01 Zero-cost runtime

The executable produced from source code that imports prism MUST NOT contain a Prism runtime layer. All trait dispatch, validation, and pipeline work MUST be resolved by the Rust toolchain at compile time. At runtime, the executable performs only the work the application author specified, with no interpretive layer between source and execution.

TC-02 Sealing of certified types

The types Validated, Grounded, Certified, Triad, Derivation, FreeRank, and Datum MUST be sealed. The three Prism-mechanism types — Validated, Grounded, Certified — are sealed in prism: code outside prism MUST NOT construct values of these types except via pipeline::run return values or via certify_from_trace. The four UOR-domain types — Datum, Triad, Derivation, FreeRank — are sealed in uor-foundation: code outside uor-foundation MUST NOT construct values of these types except by calling uor-foundation's public mint primitives (which the architectural commitment, not a Rust-language restriction, reserves to prism's pipeline as the only sanctioned caller; see ADR-016). The marker traits that gate sealed-type carriership — GroundedShape (ADR-027), FoundationClosed (ADR-022 D6), IntoBindingValue (ADR-023), and the SDK seal idiom __sdk_seal::Sealed (ADR-022 D1) — extend this discipline to the SDK-macro emission lane: external direct impls of these traits are flagged as architecturally non-conforming. Sealing MUST be enforced by the Rust type system; no runtime check is acceptable as a substitute. (ADR-011, ADR-016, ADR-022, ADR-023, ADR-027.)

TC-03 Singularity of the principal data path

The principal data path is defined by prism. There MUST be exactly one path from application author input to a value of Grounded<T>: through Grounding, Datum (constructed via uor-foundation's mint_datum primitive), CompileUnitBuilder, Validated, and pipeline::run. The path crosses from uor-foundation's mint primitives into prism's pipeline and seal regime. The catamorphism that pipeline::run realizes — the unique morphism from Term to the runtime carrier — is specified normatively at the per-variant fold-rule level by ADR-029; conformant implementations agree on the fold-rule for each of the twenty-one Term variants (the original nine plus AxisInvocation per ADR-030, ProjectField per ADR-033, FirstAdmit per ADR-034, and the nine ψ-chain variants Nerve/ChainComplex/HomologyGroups/Betti/CochainComplex/CohomologyGroups/PostnikovTower/HomotopyGroups/KInvariants per ADR-035). No alternative constructor, no proc-macro back-door, and no second pathway is permitted. (ADR-016, ADR-019, ADR-029, ADR-030, ADR-033, ADR-034, ADR-035, ADR-036.)

TC-04 UORassembly bilateral compile-time enforcement

The UORassembly contract is a set of type-level constraints that any Rust source compiling to a Prism executable MUST satisfy. The contract is enforced by prism through bilateral type-system checks:

  • prism declares the contract through its types, traits, and bounds. uor-foundation MUST satisfy those bounds; if it does not, prism fails to compile against uor-foundation.

  • The application author’s crate MUST satisfy the surface that prism exposes; if it does not, the author’s crate fails to compile.

The contract includes the three-layer closure check (ADR-024): substrate closure under foundation primitives (ADR-013, ADR-025), prism closure of routes under the prism operator set (ADR-026), and implementation closure of verb sets under the prism operator set (ADR-024 verb-graph acyclicity). Each closure is checked at the application’s compile time by the relevant SDK macro (prism_model! for routes, verb! for verbs, output_shape! for output shapes). There is no path by which UORassembly-non-conforming code reaches an executable. (ADR-006, ADR-024.)

TC-05 Replayability without deciders or hashing

Every Grounded<T> produced by Prism MUST be accompanied by a Trace sufficient to re-derive the same Certified<GroundingCertificate> given only the trace and the matching Hasher selection. The verifier MUST NOT invoke the application author’s deciders. The verifier MUST NOT invoke any cryptographic hash function; the content fingerprint MUST be data carried by the trace, computed once at mint time by the author’s Hasher.

TC-06 No application-author infrastructure

The application’s correctness at runtime, the application user’s verification of any produced output, and the delivery of the executable to the user MUST be possible without any service operated by the application author being available. Prism MUST NOT require the author to operate, host, or maintain any infrastructure for any of these to function.

Substitution Axes

The architecture admits variation only along the axes listed below. An implementation MUST treat each axis as a substitution point and MUST NOT introduce variation in any other dimension.

Axis Substituted by Constraint on substitution
HostTypes Application author Provides the host environment’s representations for real-number, opaque-string, and opaque-byte-sequence data. The default is DefaultHostTypes. Any substitute MUST satisfy the contract prism declares for HostTypes.
HostBounds Application author Provides every capacity bound that varies along the principal data path. The architecture admits no capacity bound outside HostBounds. The capacities HostBounds carries include — at minimum — the fingerprint output width range (the byte-width range any selected Hasher impl produces and the wire format encodes), the trace event-count ceiling (the maximum number of TraceEvent values a Trace may carry), and the bit-width ceiling for any algebraic level the principal data path computes against. Per ADR-037 (byte-width subset superseded by ADR-060), the trait additionally carries the 10 retained migrated capacity caps — the structural-element counts (BETTI_DIMENSION_MAX, NERVE_CONSTRAINTS_MAX, NERVE_SITES_MAX, JACOBIAN_SITES_MAX, AFFINE_COEFFS_MAX, CONJUNCTION_TERMS_MAX) and the catamorphism/trace bounds (FOLD_UNROLL_THRESHOLD, RECURSION_TRACE_DEPTH_MAX, OP_CHAIN_DEPTH_MAX, UNFOLD_ITERATIONS_MAX) — bringing the trait to 14 associated constants. Per ADR-060, the 12 byte-width capacity caps (TERM_VALUE_MAX_BYTES, AXIS_OUTPUT_BYTES_MAX, ROUTE_INPUT_BUFFER_BYTES, ROUTE_OUTPUT_BUFFER_BYTES, and the eight ψ-stage *_OUTPUT_BYTES_MAX ceilings) are removed: carrier byte widths are foundation-derived from the structural and Witt/crypto primitives (the source-polymorphic TermValue carrier’s inline width via carrier_inline_bytes::<B>(); the per-ψ-stage carrier widths via foundation const fn), not application-declared. Any substitute MUST satisfy the contract prism declares for HostBounds. There is no default — DefaultHostBounds is removed per ADR-060; every application declares its own impl HostBounds, so every capacity bound the foundation honors traces to an explicit application declaration. Type-system tuple-impl-table caps (MAX_AXIS_TUPLE_ARITY, MAX_RESOLVER_TUPLE_ARITY) stay foundation-vetted per ADR-037 clause (2) with explicit Rust-language carve-out.
AxisTuple (third position; generalizes the original single Hasher axis per ADR-030) Application author A tuple of axis trait selections each declared via the axis! SDK macro per ADR-030, with each axis providing a typed substrate-extension vocabulary (operations whose structural decomposition exceeds PrimitiveOp). The canonical first axis is HashAxis (declared by the prism-crypto standard-library sub-crate per ADR-031, subsuming the prior Hasher trait), providing a content-addressing function. Other axes the application may include: TensorAxis (prism-tensor), FheAxis (prism-fhe), NumericAxis (prism-numerics), or any application-declared axis. Any substitute MUST satisfy the contract prism declares for the AxisTuple trait family (AxisExtension-bounded members per ADR-030). The hash-axis selection used to produce a Trace is identified to the application user out-of-band; the trace alone does not name its hasher.

Model-declaration substrate parameters

Beyond the three substitution axes above, the model declaration carries an additional substrate parameter introduced by ADR-036:

Parameter Substituted by Constraint on substitution
ResolverTuple (fourth model-declaration parameter, per ADR-036; defaults to NullResolverTuple) Application author A tuple of resolver trait selections declared via the resolver! SDK macro per ADR-036, carrying per-value content provision for resolver-bound substrate operations (the eight resolver-bound ψ-Term variants per ADR-035: Nerve, ChainComplex, HomologyGroups, CochainComplex, CohomologyGroups, PostnikovTower, HomotopyGroups, KInvariants). Each resolver trait returns a TermValue directly — fn resolve(&self, input: TermValue<'a, {carrier_inline_bytes::<B>()}>) → Result<TermValue<'a, {carrier_inline_bytes::<B>()}>, ShapeViolation> per ADR-060 (superseding ADR-036’s writer-style &mut [u8]-output form) — constructing whichever carrier variant (Inline / Borrowed / Stream) its output requires, and is parameterized by the model’s A: AxisTuple + Hasher substrate parameter so resolver impls compute content-addressed fingerprints using the model’s canonical hash axis. Any substitute MUST satisfy the contract prism declares for the ResolverTuple trait family. ResolverTuple parallels AxisTuple per ADR-030 — same tuple-of-bounded-types pattern — but the architectural concern is per-value content provision (instance-associated resolve methods taking &self; resolver flows as a value reference through pipeline::run_route) rather than per-domain operation kernels (type-associated axis methods; axis flows as a type parameter only). The model declaration’s parameter shape extends from <H, B, A> to <H, B, A, R> per ADR-036 with R = NullResolverTuple as the default; the resolver! macro emits all eight Has<Category>Resolver<A> marker-trait impls unconditionally so run_route's where-clause is satisfied uniformly across verb-body ψ-Term emission profiles. ADR-035’s ψ-residuals discipline (scope refined by ADR-056) forbids direct syntactic emissions of Term::FirstAdmit, Term::AxisInvocation, and byte-comparison/concat PrimitiveOps from the route body’s syntactic surface (the prism_model!-declared route closure body); compound verbs per ADR-024, axis impl bodies per ADR-055, and resolver bodies per ADR-046 may compose the full substrate vocabulary internally because fold-fusion per ADR-054 inlines them through the catamorphism without exposing residual forms at the route surface. The canonical compiled form is the k-invariants branch ψ_1 → ψ_7 → ψ_8 → ψ_9 producing the maximum-discriminating structural witness.
TypedCommitment (fifth model-declaration parameter, per ADR-048; defaults to EmptyCommitment) Application author A foundation-declared sealed Copy trait carrying the application’s typed-bandwidth admission commitment over the κ-label per ADR-048. Built-in impls: EmptyCommitment (no-commitment baseline, bandwidth 0, accept_prob 1, evaluate-true unconditionally), SingletonCommitment<P: ObservablePredicate> (a single typed predicate over a UOR observable per ADR-049), and AndCommitment<A: TypedCommitment, B: TypedCommitment> (typed conjunction at the type level — bandwidth additive per the Hardening Principle’s U6 axiom per ADR-047, accept_prob multiplicative, static dispatch through monomorphization). Any substitute MUST be Copy and monomorphized per call site (zero allocation, zero dynamic dispatch); dyn TypedCommitment is forbidden by TC-01 + ADR-048’s rejected alternative 2. The model declaration’s parameter shape extends from <H, B, A, R> to <H, B, A, R, C> per ADR-048 with C = EmptyCommitment as the default; the catamorphism per ADR-029 consults C::evaluate(kappa_label) after ψ_9 emits the κ-label per ADR-035, and the catamorphism’s success arm requires C::evaluate to return true in addition to the resolver-bound ψ_9 stage’s well-formedness per ADR-043. The bandwidth scaling 2^K × α^-1 per Hardening Principle U6 holds end-to-end without out-of-band machinery; applications opting into the typed-bandwidth surface declare a non-empty C at the model declaration site through the optional fifth position in the prism_model! macro per ADR-022 D3.

Conventions

CV-01 RFC 2119 vocabulary

The keywords MUST, MUST NOT, SHOULD, SHOULD NOT, MAY, REQUIRED, and OPTIONAL in this wiki are to be interpreted as described in RFC 2119, when and only when they appear in capitalized form.

CV-02 Identifier discipline

When this wiki refers to a component, type, trait, function, or module that exists in the codebase, it uses the identifier from the codebase, in monospace, without prose paraphrase. The crates are referred to by their published crate names: uor-foundation, prism, prism-verify. Prose paraphrases for these names are not used.

CV-03 Coined terms

Terms introduced by this wiki that do not exist as identifiers in the codebase — including UORassembly, the principal data path, the trace, the certificate, the substitution axes — are normative concepts the wiki defines. They appear in the glossary (section 12) with their normative definitions.

Clone this wiki locally