1 import Base 2 import ./trace_facts.bend as Facts 3 import ./world.bend as W 4 import ./system.bend as Sys 5 import ./transaction.bend as T 6 import ./owned_event_journal.bend as Journal 7 import ./ordinary_owned_event_declaration.bend as D 8 # Standalone publisher runs once, including worlds without entities. Actual log 9 # owners enter the world only after success; failure returns the typed receipt. 10 # Publication decision with retained body Out and typed recovery owners. 11 # Body Failure is inside Reply, not an outer System.Failed that would discard 12 # Out/recovery. Commit/abort follows the canonical staged journal contract. 13 type Reply is Type: 14 Reply{outcome:T.Outcome,output:Out,recovered:Recovery} 15 def finished(~S:Data,~C:Type,~R:Type,~E:Data,~Recovery:Type,~Error:Data,~Out:Type,outcome:T.Outcome,output:Out,result:W.World & Recovery) -> Sys.Outcome,Unit,Reply>: 16 match result: 17 case (world,recovered):Sys.Succeeded{world,Reply{outcome,output,recovered}} 18 def returned(~S:Data,~C:Type,~R:Type,~E:Data,~Recovery:Type,~Error:Data,~Out:Type,world:W.World,recovery:Recovery,result:Journal.Stage,Recovery> & (T.Outcome & Out)) -> Sys.Outcome,Unit,Reply>: 19 match result: 20 case (stage,(T.Success{},output)):finished(~S,~C,~R,~E,~Recovery,~Error,~Out,T.Success{},output,Journal.finish(~W.World,~Recovery,stage,True{},world,recovery)) 21 case (stage,(T.Failure{error},output)):finished(~S,~C,~R,~E,~Recovery,~Error,~Out,T.Failure{error},output,Journal.finish(~W.World,~Recovery,stage,False{},world,recovery)) 22 # Advanced standalone staged publisher: invokes the opaque body once even 23 # with no entities. Success commits staged log owners; failure returns typed 24 # recovery for staged publication. No payload copying or arbitrary host-effect 25 # rollback is provided. Use define/run for registration validation. 26 def runner(~S:Data,~C:Type,~R:Type,~E:Data,~Recovery:Type,~Ops:Type -> Type,~builder:D.Builder(~W.World,~Recovery,~Ops),~declaration:D.Declaration,Recovery,Ops,builder>,~Args:Type,~Error:Data,~Out:Type,~body:@-J:Type -> @-caps:Ops(J) -> Args -> J -> J & (T.Outcome & Out),world:W.World,args:Args) -> Sys.Outcome,Unit,Reply>: 27 returned(~S,~C,~R,~E,~Recovery,~Error,~Out,world,D.empty(~S,~W.World,~Recovery,~Ops,~builder,declaration)(Unit{}),body(Journal.Stage,Recovery>,D.root_grant(~S,~W.World,~Recovery,~Ops,~builder),args,Journal.empty(~W.World,~Recovery))) 28 # Advanced type alias for the publisher's actual closed runner registration. 29 # Keep it with its matching World; raw construction is trusted administration. 30 def Registry(~S:Data,~C:Type,~R:Type,~E:Data,~Recovery:Type,~Ops:Type -> Type,~builder:D.Builder(~W.World,~Recovery,~Ops),~declaration:D.Declaration,Recovery,Ops,builder>,~Args:Type,~Error:Data,~Out:Type,~body:@-J:Type -> @-caps:Ops(J) -> Args -> J -> J & (T.Outcome & Out)) -> Type:Sys.Registry,runner(~S,~C,~R,~E,~Recovery,~Ops,~builder,~declaration,~Args,~Error,~Out,~body)> 31 # Register a staged publisher with access from its owned-event declaration. 32 # Returns System registration result retaining World on refusal. Does not 33 # execute body or publish events while registering. 34 def define(~S:Data,~C:Type,~R:Type,~E:Data,~Recovery:Type,~Ops:Type -> Type,~builder:D.Builder(~W.World,~Recovery,~Ops),~declaration:D.Declaration,Recovery,Ops,builder>,~Args:Type,~Error:Data,~Out:Type,~body:@-J:Type -> @-caps:Ops(J) -> Args -> J -> J & (T.Outcome & Out),world:W.World,name:String) -> Sys.RegistrationResult,runner(~S,~C,~R,~E,~Recovery,~Ops,~builder,~declaration,~Args,~Error,~Out,~body)>: 35 Sys.register(~S,~C,~R,~E,~Args,~Unit,~Reply,~runner(~S,~C,~R,~E,~Recovery,~Ops,~builder,~declaration,~Args,~Error,~Out,~body),world,name,D.access(~S,~W.World,~Recovery,~Ops,~builder,declaration)) 36 # Validate the publisher registration, then execute its staged body. 37 # Admission refusal returns original Args/Registry/World. Completion is outer 38 # Succeeded with Reply containing actual publication outcome, Out and typed 39 # recovery; inspect Reply.outcome rather than assuming publication succeeded. 40 # Publication contract: docs/parity/affine-events.md. 41 def run(~S:Data,~C:Type,~R:Type,~E:Data,~Recovery:Type,~Ops:Type -> Type,~builder:D.Builder(~W.World,~Recovery,~Ops),~declaration:D.Declaration,Recovery,Ops,builder>,~Args:Type,~Error:Data,~Out:Type,~body:@-J:Type -> @-caps:Ops(J) -> Args -> J -> J & (T.Outcome & Out),registry:Sys.Registry,runner(~S,~C,~R,~E,~Recovery,~Ops,~builder,~declaration,~Args,~Error,~Out,~body)>,world:W.World,args:Args) -> Sys.RunResult,runner(~S,~C,~R,~E,~Recovery,~Ops,~builder,~declaration,~Args,~Error,~Out,~body)>: 42 Sys.run(~S,~C,~R,~E,~Args,~Unit,~Reply,~runner(~S,~C,~R,~E,~Recovery,~Ops,~builder,~declaration,~Args,~Error,~Out,~body),registry,world,args) 43 44 def finished_observed(~S:Data,~C:Type,~R:Type,~E:Data,~Recovery:Type,~Error:Data,~Out:Type,outcome:T.Outcome,output:Out,result:(W.World & Recovery) & Facts.State) -> Sys.Outcome,Unit,Reply> & Facts.State: 45 match result: 46 case ((world,recovered),trace):(Sys.Succeeded{world,Reply{outcome,output,recovered}},trace) 47 def returned_observed(~S:Data,~C:Type,~R:Type,~E:Data,~Recovery:Type,~Error:Data,~Out:Type,world:W.World,recovery:Recovery,result:Journal.Stage,Recovery> & (T.Outcome & Out)) -> Sys.Outcome,Unit,Reply> & Facts.State: 48 match result: 49 case (stage,(T.Success{},output)):finished_observed(~S,~C,~R,~E,~Recovery,~Error,~Out,T.Success{},output,Journal.finish_observed(~W.World,~Recovery,stage,True{},world,recovery)) 50 case (stage,(T.Failure{error},output)):finished_observed(~S,~C,~R,~E,~Recovery,~Error,~Out,T.Failure{error},output,Journal.finish_observed(~W.World,~Recovery,stage,False{},world,recovery)) 51 # Advanced traced adapter for the same publisher body and typed recovery. 52 # Returns the actual outcome with settled journal facts; observation does not 53 # commit additional payloads or change failure recovery semantics. 54 def runner_observed(~S:Data,~C:Type,~R:Type,~E:Data,~Recovery:Type,~Ops:Type -> Type,~builder:D.Builder(~W.World,~Recovery,~Ops),~declaration:D.Declaration,Recovery,Ops,builder>,~Args:Type,~Error:Data,~Out:Type,~body:@-J:Type -> @-caps:Ops(J) -> Args -> J -> J & (T.Outcome & Out),trace:Facts.State,world:W.World,args:Args) -> Sys.Outcome,Unit,Reply> & Facts.State: 55 returned_observed(~S,~C,~R,~E,~Recovery,~Error,~Out,world,D.empty(~S,~W.World,~Recovery,~Ops,~builder,declaration)(Unit{}),body(Journal.Stage,Recovery>,D.root_grant(~S,~W.World,~Recovery,~Ops,~builder),args,Journal.with_trace(~W.World,~Recovery,trace)))