1 import Base 2 3 # Metadata is kind-local, as in the pinned Schema merge. Declaration packs stay affine. 4 # Descriptor namespace: component/resource/event/relation/service. 5 # Keys and names collide within one kind, not across distinct kinds. 6 type RegistryKind is Data: 7 Component{} 8 Resource{} 9 Event{} 10 Relation{} 11 Service{} 12 # Schema/token/payload-indexed descriptor metadata without a live payload. 13 # Raw construction is trusted schema setup and grants no operational access. 14 type Descriptor is Data: 15 Descriptor{kind: RegistryKind,key: String,name: String} 16 # Authored persistence classification for descriptor metadata; does not 17 # implement a codec, validate raw input or export a snapshot by itself. 18 type PersistenceKind is Data: 19 Plain{} 20 Transient{} 21 Constructed{} 22 # Detached descriptor entry, optionally classified by persistence policy. 23 # Both variants retain the same kind/key/name collision rules. 24 type Entry is Data: 25 Entry{kind: RegistryKind,key: String,name: String} 26 Classified{kind: RegistryKind,key: String,name: String,persistence:PersistenceKind} 27 # Descriptor entries and their actual affine declaration owners. Metadata 28 # is Data; Owners may contain arbitrary Type payloads and are never duplicated. 29 type Fragment is Type: 30 Fragment{entries: List<&2,Entry>,owners: Owners} 31 # Schema refusal identifies duplicate kind-local key/name or a descriptor 32 # required by a declared initializer but absent from the fragment. 33 type Error is Data: 34 DuplicateKey{kind: RegistryKind,key: String} 35 DuplicateName{kind: RegistryKind,name: String} 36 UndeclaredDescriptor{kind: RegistryKind,key: String,name: String} 37 # Pure metadata-validation result, without consuming declaration owners. 38 type Validation is Data: 39 Valid{} 40 Invalid{error: Error} 41 # Merged owns the combined fragment; Rejected returns both original affine 42 # fragments with the conflict. Refusal does not execute an initializer. 43 type Merge is Type: 44 Merged{fragment: Fragment} 45 Rejected{error: Error,left: Fragment,right: Fragment} 46 # Built owns the initializer output; BindRejected returns the original 47 # fragment and metadata error, allowing caller recovery without copied owners. 48 type Bound is Type: 49 Built{output: Output} 50 BindRejected{error: Error,fragment: Fragment} 51 52 # Only the operational extension builders choose a classification. Raw schema construction is trusted. 53 def bare_entry(~S:Data,value:Entry) -> Entry: 54 match value: 55 case Entry{kind,key,name}:Entry{kind,key,name} 56 case Classified{kind,key,name,_}:Entry{kind,key,name} 57 def bare_entries(~S:Data,values:List<&2,Entry>) -> List<&2,Entry>: 58 match values: 59 case []:[] 60 case head <> rest:bare_entry(~S,head) <> bare_entries(~S,rest) 61 def same_kind(a: RegistryKind,b: RegistryKind) -> Bool: 62 match a b: 63 case Component{} Component{}: True{} 64 case Resource{} Resource{}: True{} 65 case Event{} Event{}: True{} 66 case Relation{} Relation{}: True{} 67 case Service{} Service{}: True{} 68 case _ _: False{} 69 # Project a typed descriptor to its kind/key/name metadata entry. Does not 70 # read payloads or grant access to the descriptor's runtime storage. 71 def entry(~S: Data,~Token: Data,~Payload: Type,descriptor: Descriptor) -> Entry: 72 match descriptor: 73 case Descriptor{kind,key,name}: Entry{kind,key,name} 74 # Create an empty fragment with a Unit owner and no metadata entries. 75 # Use fragment when supplying arbitrary affine declaration owners. 76 def empty(~S: Data,owners: Unit) -> Fragment: 77 Fragment{[],owners} 78 # Trusted setup constructor pairing authored entries with actual owners. 79 # Does not verify their semantic relationship or reject duplicate entries; 80 # validate/merge/bind perform their stated metadata checks later. 81 def fragment(~S: Data,~Owners: Type,entries: List<&2,Entry>,owners: Owners) -> Fragment: 82 Fragment{entries,owners} 83 def key_exists_bare(~S: Data,xs: List<&2,Entry>,+kind: RegistryKind,+key: String) -> Bool: 84 match xs: 85 case Nil{}: False{} 86 case Con{Entry{other,otherKey,_},rest}: Bool.or(Bool.and(same_kind(kind,other),String.eq(key,otherKey)),key_exists_bare(~S,rest,kind,key)) 87 case Con{Classified{other,otherKey,_,_},rest}: Bool.or(Bool.and(same_kind(kind,other),String.eq(key,otherKey)),key_exists_bare(~S,rest,kind,key)) 88 def key_exists(~S:Data,xs:List<&2,Entry>,kind:RegistryKind,key:String) -> Bool:key_exists_bare(~S,bare_entries(~S,xs),kind,key) 89 def name_exists_bare(~S: Data,xs: List<&2,Entry>,+kind: RegistryKind,+name: String) -> Bool: 90 match xs: 91 case Nil{}: False{} 92 case Con{Entry{other,_,otherName},rest}: Bool.or(Bool.and(same_kind(kind,other),String.eq(name,otherName)),name_exists_bare(~S,rest,kind,name)) 93 case Con{Classified{other,_,otherName,_},rest}: Bool.or(Bool.and(same_kind(kind,other),String.eq(name,otherName)),name_exists_bare(~S,rest,kind,name)) 94 def name_exists(~S:Data,xs:List<&2,Entry>,kind:RegistryKind,name:String) -> Bool:name_exists_bare(~S,bare_entries(~S,xs),kind,name) 95 def check_entry(keyConflict: Bool,nameConflict: Bool,kind: RegistryKind,key: String,name: String) -> Validation: 96 match keyConflict nameConflict: 97 case True{} _: Invalid{DuplicateKey{kind,key}} 98 case False{} True{}: Invalid{DuplicateName{kind,name}} 99 case False{} False{}: Valid{} 100 def check_one_bare(~S: Data,+seen: List<&2,Entry>,item: Entry) -> Validation: 101 match item: 102 case Entry{+kind,+key,+name}: check_entry(key_exists(~S,seen,kind,key),name_exists(~S,seen,kind,name),kind,key,name) 103 case Classified{+kind,+key,+name,_}: check_entry(key_exists(~S,seen,kind,key),name_exists(~S,seen,kind,name),kind,key,name) 104 def check_one(~S:Data,seen:List<&2,Entry>,item:Entry) -> Validation:check_one_bare(~S,bare_entries(~S,seen),bare_entry(~S,item)) 105 def validation_continue(~S: Data,result: Validation,next: Unit -> Validation) -> Validation: 106 match result: 107 case Invalid{error}: Invalid{error} 108 case Valid{}: next(Unit{}) 109 def validate_loop(~S: Data,xs: List<&2,Entry>,+seen: List<&2,Entry>) -> Validation: 110 match xs: 111 case Nil{}: Valid{} 112 case Con{+item,rest}: validation_continue(~S,check_one(~S,seen,item),_ => validate_loop(~S,rest,item <> seen)) 113 def filter_kind_done(~S: Data,selected: Bool,item: Entry,rest: List<&2,Entry>) -> List<&2,Entry>: 114 match selected: 115 case True{}: item <> rest 116 case False{}: rest 117 def filter_kind(~S:Data,xs:List<&2,Entry>,+kind:RegistryKind) -> List<&2,Entry>: 118 match xs: 119 case []:[] 120 case Entry{+itemKind,+key,+name} <> rest:filter_kind_done(~S,same_kind(kind,itemKind),Entry{itemKind,key,name},filter_kind(~S,rest,kind)) 121 case Classified{+itemKind,+key,+name,+persistence} <> rest:filter_kind_done(~S,same_kind(kind,itemKind),Classified{itemKind,key,name,persistence},filter_kind(~S,rest,kind)) 122 def first_failure(first: Validation,second: Validation) -> Validation: 123 match first: 124 case Invalid{error}: Invalid{error} 125 case Valid{}: second 126 # Check descriptor key/name collisions within each registry kind. 127 # Preserves kind-specific error order; this is metadata validation, not proof 128 # of lens laws, actual payload values or correctness of arbitrary adapters. 129 def validate(~S: Data,+entries: List<&2,Entry>) -> Validation: 130 first_failure(validate_loop(~S,filter_kind(~S,entries,Component{}),[]),first_failure(validate_loop(~S,filter_kind(~S,entries,Resource{}),[]),first_failure(validate_loop(~S,filter_kind(~S,entries,Event{}),[]),first_failure(validate_loop(~S,filter_kind(~S,entries,Relation{}),[]),validate_loop(~S,filter_kind(~S,entries,Service{}),[]))))) 131 def merge_checked(~S: Data,~L: Type,~R: Type,result: Validation,+entries: List<&2,Entry>,left: Fragment,right: Fragment) -> Merge: 132 match result left right: 133 case Invalid{error} left right: Rejected{error,left,right} 134 case Valid{} Fragment{_,l} Fragment{_,r}: Merged{Fragment{entries,(l,r)}} 135 # Validate both fragments and their combined entries before combining owners. 136 # Success retains left-then-right entries and (L & R) owners; refusal returns 137 # both original fragments. No initializer or gameplay callback is invoked. 138 def merge(~S: Data,~L: Type,~R: Type,left: Fragment,right: Fragment) -> Merge: 139 match left right: 140 case Fragment{+le,l} Fragment{+re,r}: merge_checked(~S,~L,~R,first_failure(validate(~S,le),first_failure(validate(~S,re),validate(~S,List.append(&2,Entry,le,re)))),List.append(&2,Entry,le,re),Fragment{le,l},Fragment{re,r}) 141 def bind_checked(~S: Data,~Owners: Type,~Output: Type,~build: Owners -> Output,result: Validation,fragment: Fragment) -> Bound: 142 match result fragment: 143 case Invalid{error} fragment: BindRejected{error,fragment} 144 case Valid{} Fragment{_,owners}: Built{build(owners)} 145 # Validate fragment metadata before consuming Owners with a trusted builder. 146 # BindRejected returns the original fragment; Built contains builder output. 147 # For a builder with explicit descriptor prerequisites use bind_declared. 148 def bind(~S: Data,~Owners: Type,~Output: Type,~build: Owners -> Output,fragment: Fragment) -> Bound: 149 match fragment: 150 case Fragment{+entries,owners}: bind_checked(~S,~Owners,~Output,~build,validate(~S,entries),Fragment{entries,owners}) 151 152 # A closed initializer states its required descriptors before receiving any owners. 153 # As with Family lenses, caller-authored adapters remain trusted provisioning. 154 def descriptor_equal(~S:Data,a:Entry,b:Entry) -> Bool: 155 match a b: 156 case Entry{ak,ax,an} Entry{bk,bx,bn}:Bool.and(same_kind(ak,bk),Bool.and(String.eq(ax,bx),String.eq(an,bn))) 157 case _ _:False{} 158 def descriptor_present(~S:Data,xs:List<&2,Entry>,+item:Entry) -> Bool: 159 match xs: 160 case []:False{} 161 case head <> rest:Bool.or(descriptor_equal(~S,bare_entry(~S,head),bare_entry(~S,item)),descriptor_present(~S,rest,item)) 162 def required_continue(result: Validation,next: Unit -> Validation) -> Validation: 163 match result: 164 case Invalid{error}: Invalid{error} 165 case Valid{}: next(Unit{}) 166 def required_check_bare(~S: Data,present: Bool,item: Entry) -> Validation: 167 match present item: 168 case True{} _: Valid{} 169 case False{} Entry{kind,key,name}: Invalid{UndeclaredDescriptor{kind,key,name}} 170 case False{} Classified{kind,key,name,_}: Invalid{UndeclaredDescriptor{kind,key,name}} 171 def required_check(~S:Data,present:Bool,item:Entry) -> Validation:required_check_bare(~S,present,bare_entry(~S,item)) 172 def requirements(~S: Data,required: List<&2,Entry>,+entries: List<&2,Entry>) -> Validation: 173 match required: 174 case []: Valid{} 175 case +item <> rest: required_continue(required_check(~S,descriptor_present(~S,entries,item),item),_ => requirements(~S,rest,entries)) 176 def bind_requirements(~S: Data,~Owners: Type,~Output: Type,~build: Owners -> Output,result: Validation,required: List<&2,Entry>,fragment: Fragment) -> Bound: 177 match result fragment: 178 case Invalid{error} fragment: BindRejected{error,fragment} 179 case Valid{} Fragment{+entries,owners}: bind_checked(~S,~Owners,~Output,~build,requirements(~S,required,entries),Fragment{entries,owners}) 180 # Validate fragment collisions and every explicitly required descriptor 181 # before invoking the closed builder. Missing kind/key/name yields 182 # BindRejected with the original fragment, without executing build. Trusted 183 # builders must still obey their declared requirements; arbitrary callbacks 184 # are not runtime-confined by metadata alone. 185 def bind_declared(~S: Data,~Owners: Type,~Output: Type,~build: Owners -> Output,fragment: Fragment,required: List<&2,Entry>) -> Bound: 186 match fragment: 187 case Fragment{+entries,owners}: bind_requirements(~S,~Owners,~Output,~build,validate(~S,entries),required,Fragment{entries,owners})