1 import Base 2 import ./feature.bend as F 3 import ./component.bend as C 4 import ./schema_fragments.bend as SF 5 import ./capabilities.bend as Cap 6 # Trusted schema author closes the getter; universal gameplay receives only H. 7 def read(-H:Type,-V:Data,cap:Cap.Read,ctx:H) -> H & C.Access: 8 match cap: 9 case Cap.Read{get}: get(ctx) 10 def provide(~Ctx:Type,~V:Data,~get:Ctx -> Ctx & C.Access,~body:@-H:Type -> Cap.Read -> H -> H & C.Access,ctx:Ctx) -> Ctx & C.Access: 11 body(Ctx,Cap.Read{get},ctx) 12 # Exact repeated descriptors collapse in access scope; conflicts remain validation errors. 13 def scope_keep(~S:Data,present:Bool,item:SF.Entry,rest:List<&2,SF.Entry>) -> List<&2,SF.Entry>: 14 match present: 15 case True{}: rest 16 case False{}: Con{item,rest} 17 def scope_seen(~S:Data,items:List<&2,SF.Entry>,+seen:List<&2,SF.Entry>) -> List<&2,SF.Entry>: 18 match items: 19 case Nil{}: Nil{} 20 case +item <> rest: scope_keep(~S,SF.descriptor_present(~S,seen,item),item,scope_seen(~S,rest,Con{item,seen})) 21 def scope_unique(~S:Data,items:List<&2,SF.Entry>) -> List<&2,SF.Entry>: 22 scope_seen(~S,items,Nil{}) 23 # Authoring boundary: actual declared scope checked before closed construction. 24 def bind_feature(~S:Data,~Owners:Type,~Output:Type,~build:Owners -> Output,definition:F.Definition,required:List<&2,SF.Entry>,owners:Owners) -> SF.Bound: 25 SF.bind_declared(~S,~Owners,~Output,~build,SF.Fragment{scope_unique(~S,F.visibility(~S,F.definition_tree(~S,definition))),owners},required) 26 def write(-H:Type,-C:Type,-V:Data,cap:Cap.Write,ctx:H,value:C) -> H: 27 match cap: 28 case Cap.Write{_,set}: set(ctx,value) 29 def action(-H:Type,cap:Cap.Action,ctx:H) -> H: 30 match cap: 31 case Cap.Action{run}: run(ctx) 32 def provide_action(~Ctx:Type,~run:Ctx -> Ctx,~body:@-H:Type -> Cap.Action -> H -> H,ctx:Ctx) -> Ctx: 33 body(Ctx,Cap.Action{run},ctx)