1 import Base 2 import ./trace_facts.bend as Facts 3 import ./world.bend as W 4 import ./system.bend as Sys 5 import ./event_runtime.bend as Ev 6 import ./transaction.bend as T 7 import ./capabilities.bend as Cap 8 import ./owned_event_log.bend as Log 9 import ./owned_event_family_storage.bend as Storage 10 import ./owner_product.bend as Product 11 import ./event_stream.bend as Stream 12 import ./event_family_routing.bend as Route 13 import ./ordinary_owned_event.bend as Ord 14 15 # One declared reader folds its unread payloads through a confined request cap. 16 # Providers are trusted schema provisioning; payload ownership stays in the log. 17 type Failure is Data: 18 BodyFailed{error:Error} 19 MissingPayload{} 20 type Reply is Type: 21 Reply{outcome:T.Outcome>,args:Args,lagged:Bool} 22 def stopped(~S:Data,~C:Type,~R:Type,~P:Type,~Rest:Type,~E:Data,~path:Product.Lens,Rest>,~Args:Type,~Error:Data,world:W.World,args:Args,outcome:T.Outcome>,lagged:Bool) -> W.World & Reply: 23 (world,Reply{outcome,args,lagged}) 24 def visited(~S:Data,~C:Type,~R:Type,~P:Type,~Rest:Type,~E:Data,~path:Product.Lens,Rest>,~Args:Type,~Error:Data,lagged:Bool,next:W.World -> Args -> W.World & Reply,result:W.World & Log.ReadResult & Args>) -> W.World & Reply: 25 match result: 26 case (world,Log.Missing{args}):stopped(~S,~C,~R,~P,~Rest,~E,~path,~Args,~Error,world,args,T.Failure{MissingPayload{}},lagged) 27 case (world,Log.Found{(T.Failure{error},args)}):stopped(~S,~C,~R,~P,~Rest,~E,~path,~Args,~Error,world,args,T.Failure{BodyFailed{error}},lagged) 28 case (world,Log.Found{(T.Success{},args)}):next(world,args) 29 def fold_rows(~S:Data,~C:Type,~R:Type,~P:Type,~Rest:Type,~E:Data,~path:Product.Lens,Rest>,~Request:Type,~Projection:Data,~Args:Type,~Error:Data,~at:P -> Request -> P & Projection,~body:@-H:Type -> @-read:Cap.Request -> H -> Args -> H & (T.Outcome & Args),keys:List<&2,Nat>,world:W.World,args:Args,+lagged:Bool) -> W.World & Reply: 30 match keys: 31 case []:stopped(~S,~C,~R,~P,~Rest,~E,~path,~Args,~Error,world,args,T.Success{},lagged) 32 case key <> remaining:visited(~S,~C,~R,~P,~Rest,~E,~path,~Args,~Error,lagged,nextWorld => nextArgs => fold_rows(~S,~C,~R,~P,~Rest,~E,~path,~Request,~Projection,~Args,~Error,~at,~body,remaining,nextWorld,nextArgs,lagged),Storage.read(~S,~C,~R,~P,~Rest,~E,~path,~Request,~Projection,~Args,~(T.Outcome & Args),~at,~body,world,key,args)) 33 def transported(~S:Data,~C:Type,~R:Type,~P:Type,~Rest:Type,~E:Data,~path:Product.Lens,Rest>,~Args:Type,~Error:Data,result:W.World & Reply) -> Sys.Outcome,Unit,Reply>: 34 match result: 35 case (world,reply):Sys.Succeeded{world,reply} 36 def runner(~S:Data,~C:Type,~R:Type,~P:Type,~Rest:Type,~E:Data,~path:Product.Lens,Rest>,~Request:Type,~Projection:Data,~Args:Type,~Error:Data,~at:P -> Request -> P & Projection,~body:@-H:Type -> @-read:Cap.Request -> H -> Args -> H & (T.Outcome & Args),world:W.World,input:Ev.Input) -> Sys.Outcome,Unit,Reply>: 37 match input: 38 case Ev.Input{keys,lagged,args}:transported(~S,~C,~R,~P,~Rest,~E,~path,~Args,~Error,fold_rows(~S,~C,~R,~P,~Rest,~E,~path,~Request,~Projection,~Args,~Error,~at,~body,keys,world,args,lagged)) 39 40 # The closed runner retains affine Args even on semantic failure. Route.run must 41 # see transport success; reconcile its selected stream to the exact existing 42 # failed-reader activation rule afterward, without changing other streams. 43 def restored_stream(~S:Data,old:List<&2,Ev.Position>,id:U32,tick:Nat,stream:Stream.Stream) -> Stream.Stream: 44 match stream: 45 case Stream.Stream{domain,batches,_,nextReader,frameStart,boundary,capacity,dropped}:Stream.Stream{domain,batches,Ev.activate(old,id,Nat.sub(tick,1n)),nextReader,frameStart,boundary,capacity,dropped} 46 def restore_taken(~S:Data,~C:Type,~R:Type,~E:Data,~F:Type,~put:F -> Stream.Stream -> F,world:W.World,+tick:Nat,old:List<&2,Ev.Position>,id:U32,returned:F & Stream.Stream) -> Route.Runtime: 47 match returned: 48 case (family,stream):Route.Runtime{world,put(family,restored_stream(~S,old,id,tick,stream)),tick} 49 def restore(~S:Data,~C:Type,~R:Type,~E:Data,~F:Type,~take:F -> F & Stream.Stream,~put:F -> Stream.Stream -> F,old:List<&2,Ev.Position>,id:U32,runtime:Route.Runtime) -> Route.Runtime: 50 match runtime: 51 case Route.Runtime{world,family,tick}:restore_taken(~S,~C,~R,~E,~F,~put,world,tick,old,id,take(family)) 52 def reconciled(~S:Data,~C:Type,~R:Type,~P:Type,~Rest:Type,~E:Data,~path:Product.Lens,Rest>,~Request:Type,~Projection:Data,~Args:Type,~Error:Data,~at:P -> Request -> P & Projection,~body:@-H:Type -> @-read:Cap.Request -> H -> Args -> H & (T.Outcome & Args),~F:Type,~take:F -> F & Stream.Stream,~put:F -> Stream.Stream -> F,old:List<&2,Ev.Position>,id:U32,result:Route.RunResult,take,put,runner(~S,~C,~R,~P,~Rest,~E,~path,~Request,~Projection,~Args,~Error,~at,~body)>) -> Route.RunResult,take,put,runner(~S,~C,~R,~P,~Rest,~E,~path,~Request,~Projection,~Args,~Error,~at,~body)>: 53 match result: 54 case Route.Ran{runtime,reader,registry,Ev.Succeeded{Reply{T.Failure{error},args,lagged}}}:Route.Ran{restore(~S,~C,~R,~E,~F,~take,~put,old,id,runtime),reader,registry,Ev.Succeeded{Reply{T.Failure{error},args,lagged}}} 55 case result:result 56 def run_taken(~S:Data,~C:Type,~R:Type,~P:Type,~Rest:Type,~E:Data,~path:Product.Lens,Rest>,~Request:Type,~Projection:Data,~Args:Type,~Error:Data,~at:P -> Request -> P & Projection,~body:@-H:Type -> @-read:Cap.Request -> H -> Args -> H & (T.Outcome & Args),~F:Type,~take:F -> F & Stream.Stream,~put:F -> Stream.Stream -> F,~synchronize:W.World -> F -> Nat -> W.World & F,world:W.World,tick:Nat,reader:Route.Reader,registry:Sys.Registry,Unit,Reply,runner(~S,~C,~R,~P,~Rest,~E,~path,~Request,~Projection,~Args,~Error,~at,~body)>,args:Args,returned:F & Stream.Stream) -> Route.RunResult,take,put,runner(~S,~C,~R,~P,~Rest,~E,~path,~Request,~Projection,~Args,~Error,~at,~body)>: 57 match reader returned: 58 case Route.Reader{namespace,+id,registryId}, (family,Stream.Stream{_,_,positions,_,_,_,_,_}):reconciled(~S,~C,~R,~P,~Rest,~E,~path,~Request,~Projection,~Args,~Error,~at,~body,~F,~take,~put,positions,id,Route.run(~S,~C,~R,~E,~Nat,~F,~Args,~Unit,~Reply,~take,~put,~runner(~S,~C,~R,~P,~Rest,~E,~path,~Request,~Projection,~Args,~Error,~at,~body),~synchronize,Route.Runtime{world,family,tick},Route.Reader{namespace,id,registryId},registry,args)) 59 def run(~S:Data,~C:Type,~R:Type,~P:Type,~Rest:Type,~E:Data,~path:Product.Lens,Rest>,~Request:Type,~Projection:Data,~Args:Type,~Error:Data,~at:P -> Request -> P & Projection,~body:@-H:Type -> @-read:Cap.Request -> H -> Args -> H & (T.Outcome & Args),~F:Type,~take:F -> F & Stream.Stream,~put:F -> Stream.Stream -> F,~synchronize:W.World -> F -> Nat -> W.World & F,runtime:Route.Runtime,reader:Route.Reader,registry:Sys.Registry,Unit,Reply,runner(~S,~C,~R,~P,~Rest,~E,~path,~Request,~Projection,~Args,~Error,~at,~body)>,args:Args) -> Route.RunResult,take,put,runner(~S,~C,~R,~P,~Rest,~E,~path,~Request,~Projection,~Args,~Error,~at,~body)>: 60 match runtime: 61 case Route.Runtime{world,family,tick}:run_taken(~S,~C,~R,~P,~Rest,~E,~path,~Request,~Projection,~Args,~Error,~at,~body,~F,~take,~put,~synchronize,world,tick,reader,registry,args,take(family)) 62 def runner_observed(~S:Data,~C:Type,~R:Type,~P:Type,~Rest:Type,~E:Data,~path:Product.Lens,Rest>,~Request:Type,~Projection:Data,~Args:Type,~Error:Data,~at:P -> Request -> P & Projection,~body:@-H:Type -> @-read:Cap.Request -> H -> Args -> H & (T.Outcome & Args),trace:Facts.State,world:W.World,input:Ev.Input) -> Sys.Outcome,Unit,Reply> & Facts.State: 63 (runner(~S,~C,~R,~P,~Rest,~E,~path,~Request,~Projection,~Args,~Error,~at,~body,world,input),trace) 64 def accepted(~Error:Data,~Args:Type,value:Reply) -> Reply & Bool: 65 match value: 66 case Reply{T.Success{},args,lagged}:(Reply{T.Success{},args,lagged},True{}) 67 case Reply{T.Failure{error},args,lagged}:(Reply{T.Failure{error},args,lagged},False{}) 68 def run_traced(~S:Data,~C:Type,~R:Type,~P:Type,~Rest:Type,~E:Data,~path:Product.Lens,Rest>,~Request:Type,~Projection:Data,~Args:Type,~Error:Data,~at:P -> Request -> P & Projection,~body:@-H:Type -> @-read:Cap.Request -> H -> Args -> H & (T.Outcome & Args),~F:Type,~take:F -> F & Stream.Stream,~put:F -> Stream.Stream -> F,~synchronize:W.World -> F -> Nat -> W.World & F,runtime:Route.Runtime,reader:Route.Reader,registry:Sys.Registry,Unit,Reply,runner(~S,~C,~R,~P,~Rest,~E,~path,~Request,~Projection,~Args,~Error,~at,~body)>,args:Args,trace:Facts.State) -> Route.RunResult,take,put,runner(~S,~C,~R,~P,~Rest,~E,~path,~Request,~Projection,~Args,~Error,~at,~body)> & Facts.State: 69 Route.run_traced(~S,~C,~R,~E,~Nat,~F,~Args,~Unit,~Reply,~take,~put,~runner(~S,~C,~R,~P,~Rest,~E,~path,~Request,~Projection,~Args,~Error,~at,~body),~runner_observed(~S,~C,~R,~P,~Rest,~E,~path,~Request,~Projection,~Args,~Error,~at,~body),~accepted(~Error,~Args),~synchronize,runtime,reader,registry,args,trace) 70 71 def register(~S:Data,~C:Type,~R:Type,~P:Type,~Rest:Type,~E:Data,~path:Product.Lens,Rest>,~Request:Type,~Projection:Data,~Args:Type,~Error:Data,~at:P -> Request -> P & Projection,~body:@-H:Type -> @-read:Cap.Request -> H -> Args -> H & (T.Outcome & Args),~F:Type,~take:F -> F & Stream.Stream,~put:F -> Stream.Stream -> F,runtime:Route.Runtime,name:String) -> Route.Registration,take,put,runner(~S,~C,~R,~P,~Rest,~E,~path,~Request,~Projection,~Args,~Error,~at,~body)>: 72 Route.register(~S,~C,~R,~E,~Nat,~F,~Args,~Unit,~Reply,~take,~put,~runner(~S,~C,~R,~P,~Rest,~E,~path,~Request,~Projection,~Args,~Error,~at,~body),runtime,name)