# Forward-looking schema co-located with the examples — models the # post-ADR-034 / post-migration-0025 catalog contract so all four example # kinds typecheck today. Replace these imports with `import "../../.ontoref/catalog/schema.ncl"` # once migration 0025 has been applied to your project. # # Contract decisions are taken from .ontoref/adrs/adr-034-catalog-extensibility-beyond-rust.ncl # decision block. Keep this file in sync if ADR-034 evolves. let t_OpKind = [| 'Rust, 'NclTransform, 'Wasm, 'Sidecar, |] in let t_NclTransformOp = [| 'Set, 'Append, 'Remove, 'Merge |] in let t_NclTransformBody = { target | String, selector | String, operation | t_NclTransformOp, value_expr | String, } in let t_WasmBody = { module_path | String, export_name | String, capabilities | Array String, } in let t_SidecarBody = { endpoint | String, auth_token | String | default = "", timeout_ms | Number | default = 5000, } in let t_ValidatorCategory = [| 'Structural, 'Contextual |] in let t_WitnessSignature = { actor_id | String, algorithm | String | default = "Ed25519", } in let t_WitnessShape = { payload_kind | String, proof_paths | Array String | default = [], signature | t_WitnessSignature, } in let t_EffectKind = [| 'Insert, 'Update, 'Delete |] in let t_Effect = { kind | t_EffectKind, entity | String, attrs | Array String, dimensions | Array String | default = [], } in let t_ConstraintBundle = { pre | Array String | default = [], inline | Array String | default = [], post | Array String | default = [], } in let t_ActorPolicy = { roles | Array String | default = [], } in let t_ValidationSla = [| 'Synchronous, 'Background |] in let t_OperationDecl = { id | String, description | String, kind | t_OpKind | default = 'Rust, body | Dyn | optional, inputs | { _ : String } | default = {}, constraints | t_ConstraintBundle | default = {}, validation_sla | t_ValidationSla, effects | Array t_Effect | default = [], witness_shape | t_WitnessShape, actor_policy | t_ActorPolicy | default = {}, render_paths | Array String | default = [], } in # Ondaod-pre Hard contract — ADR-034 `non-rust-kinds-require-ondaod-pre`. # Non-Rust ops MUST list "evaluate_ondaod" in constraints.pre. The # contract is exposed as a SEPARATE annotation that each catalog # declaration applies after `OperationDecl` so the discipline shows up # explicitly at every author site, not hidden inside the record shape. let t_OndaodPreRequired = std.contract.custom ( fun label => fun value => if value.kind == 'Rust then 'Ok value else if std.array.any (fun v => v == "evaluate_ondaod") value.constraints.pre then 'Ok value else 'Error { message = "ADR-034 `non-rust-kinds-require-ondaod-pre`: op '%{value.id}' (kind = %{std.to_string value.kind}) MUST include \"evaluate_ondaod\" in constraints.pre" } ) in # Convenience builder — applies both contracts in the correct order so # every example reads the same way at the bottom: `... | s.make_op`. let make_op = fun data => let result | t_OperationDecl | t_OndaodPreRequired = data in result in { OpKind = t_OpKind, NclTransformBody = t_NclTransformBody, WasmBody = t_WasmBody, SidecarBody = t_SidecarBody, WitnessShape = t_WitnessShape, WitnessSignature = t_WitnessSignature, Effect = t_Effect, EffectKind = t_EffectKind, ConstraintBundle = t_ConstraintBundle, ActorPolicy = t_ActorPolicy, ValidationSla = t_ValidationSla, OperationDecl = t_OperationDecl, OndaodPreRequired = t_OndaodPreRequired, make_op = make_op, }