ordinary_app_execution.bend

bendvy-ecs-core@0.1.0.0 · 212 lines · 0 definitions

1import Base
2import bendvy-ecs-core@0.1.0.0/change_tick.bend as Tick
3import bendvy-ecs-core@0.1.0.0/machine_world.bend as MachineWorld
4import bendvy-ecs-core@0.1.0.0/ordinary_app_execution_run.bend as ExecuteRun
5import bendvy-ecs-core@0.1.0.0/machine_handler_engine.bend as HandlerEngine
6import bendvy-ecs-core@0.1.0.0/machine_handlers.bend as Handlers
7import bendvy-ecs-core@0.1.0.0/machine.bend as Machine
8import bendvy-ecs-core@0.1.0.0/ordinary_machine_declaration.bend as MachineDecl
9import bendvy-ecs-core@0.1.0.0/ordinary_app_resource_field_declaration.bend as FieldDecl
10import bendvy-ecs-core@0.1.0.0/ordinary_resource_field_system.bend as FieldSystem
11import bendvy-ecs-core@0.1.0.0/transaction.bend as Transaction
12import bendvy-ecs-core@0.1.0.0/execution_context.bend as Ctx
13import bendvy-ecs-core@0.1.0.0/trace_facts.bend as Facts
14import bendvy-ecs-core@0.1.0.0/execution_trace.bend as Trace
15import bendvy-ecs-core@0.1.0.0/ordinary_app_schedule.bend as Single
16import bendvy-ecs-core@0.1.0.0/ordinary_app_schema.bend as App
17import bendvy-ecs-core@0.1.0.0/ordinary_app_composer.bend as Build
18import bendvy-ecs-core@0.1.0.0/ordinary_app_recipe.bend as Tree
19import bendvy-ecs-core@0.1.0.0/ordinary_app_registration_fields.bend as Records
20import bendvy-ecs-core@0.1.0.0/ordinary_app_observation_data.bend as DTO
21import bendvy-ecs-core@0.1.0.0/ordinary_schema.bend as Schema
22import bendvy-ecs-core@0.1.0.0/world.bend as W
23import bendvy-ecs-core@0.1.0.0/system.bend as Sys
24import bendvy-ecs-core@0.1.0.0/schedule.bend as Sch
25import bendvy-ecs-core@0.1.0.0/schedule_provision.bend as SP
26
27# A detached batch is returned only after its actual ECS run has completed.
28# Execution returns a retained application result and a detached trace batch.
29# Inspect result for Finished/Failed/Rejected/Missing; tracing is Disabled or
30# Ready according to the actual run. Subscribers process the copied batch
31# afterward; external printing/file IO is outside ECS rollback.
32# Example: examples/scheduled-health/application.bend, ran().
33type Run<A:Type,S:Data,Error:Data> is Type:
34  Run{result:Single.RunResult<A,S,Error>,batch:Trace.Batch<Error>}
35type Journal<Error:Data> is Data:
36  Journal{catalog:List<&2,Trace.Identity>,events:List<&2,Trace.TraceEvent<Error>>}
37def catalog(~S:Data,fields:List<&2,Records.Fields<S>>) -> List<&2,Trace.Identity>:
38  match fields:
39    case []:[]
40    case Records.Fields{namespace,id,name,_,_,_,_,_} <> rest:Trace.Identity{namespace,id,Some{name}} <> catalog(~S,rest)
41def named(found:Bool,name:Maybe<&2,String>,next:Unit -> Maybe<&2,String>) -> Maybe<&2,String>:
42  match found:
43    case True{}:name
44    case False{}:next(Unit{})
45def registration_name(items:List<&2,Trace.Identity>,+id:U32) -> Maybe<&2,String>:
46  match items:
47    case []:None{}
48    case Trace.Identity{_,candidate,name} <> rest:named(U32.is_eq(candidate,id),name,_ => registration_name(rest,id))
49def identity_clock(~S:Data,~C:Type,~R:Type,~E:Data,namespace:U32,id:U32,name:Maybe<&2,String>,observed:W.World<S,C,R,E> & Tick.Tick) -> W.World<S,C,R,E> & (Trace.Identity & Tick.Tick):
50  match observed:
51    case (world,clock):(world,(Trace.Identity{namespace,id,name},clock))
52def identity_namespace(~S:Data,~C:Type,~R:Type,~E:Data,id:U32,name:Maybe<&2,String>,observed:W.World<S,C,R,E> & U32) -> W.World<S,C,R,E> & (Trace.Identity & Tick.Tick):
53  match observed:
54    case (world,namespace):identity_clock(~S,~C,~R,~E,namespace,id,name,W.clock(~S,~C,~R,~E,world))
55def identity(~S:Data,~C:Type,~R:Type,~E:Data,~Error:Data,journal:Journal<Error>,world:W.World<S,C,R,E>,+id:U32) -> W.World<S,C,R,E> & (Trace.Identity & Tick.Tick):
56  match journal:
57    case Journal{catalog,_}:identity_namespace(~S,~C,~R,~E,id,registration_name(catalog,id),W.namespace(~S,~C,~R,~E,world))
58def record(~Error:Data,event:Trace.TraceEvent<Error>,journal:Journal<Error>) -> Journal<Error>:
59  match journal:
60    case Journal{catalog,events}:Journal{catalog,event <> events}
61def succeeded(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Error:Data,owners:H,fact:Trace.Identity,before:Tick.Tick,journal:Journal<Error>,observed:W.World<S,C,R,E> & Tick.Tick) -> (H & Journal<Error>) & Sys.Outcome<W.World<S,C,R,E>,Error,Unit>:
62  match observed:
63    case (world,after):((owners,record(~Error,Trace.SystemCompleted{fact,before,after,Trace.SystemOk{}},journal)),Sys.Succeeded{world,Unit{}})
64def failed(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Error:Data,owners:H,fact:Trace.Identity,before:Tick.Tick,journal:Journal<Error>,+error:Error,observed:W.World<S,C,R,E> & Tick.Tick) -> (H & Journal<Error>) & Sys.Outcome<W.World<S,C,R,E>,Error,Unit>:
65  match observed:
66    case (world,after):((owners,record(~Error,Trace.SystemCompleted{fact,before,after,Trace.SystemError{error}},journal)),Sys.Failed{world,error})
67def record_operations(~Error:Data,facts:List<&2,Facts.Fact>,+identity:Trace.Identity,journal:Journal<Error>) -> Journal<Error>:
68  match facts:
69    case []:journal
70    case fact <> rest:record_operations(~Error,rest,identity,record(~Error,Trace.OperationObserved{identity,fact},journal))
71def record_barrier_operations(~Error:Data,facts:List<&2,Facts.Fact>,journal:Journal<Error>) -> Journal<Error>:
72  match facts:
73    case []:journal
74    case fact <> rest:record_barrier_operations(~Error,rest,record(~Error,Trace.BarrierOperationObserved{fact},journal))
75def barrier_returned(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Error:Data,owners:H,journal:Journal<Error>,result:W.World<S,C,R,E> & Facts.State) -> (H & Journal<Error>) & W.World<S,C,R,E>:
76  match result:
77    case (world,trace):((owners,record_barrier_operations(~Error,Facts.facts(trace),journal)),world)
78def barrier_recorded(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Error:Data,owners:H & Journal<Error>,world:W.World<S,C,R,E>) -> (H & Journal<Error>) & W.World<S,C,R,E>:
79  match owners:
80    case (owners,journal):barrier_returned(~S,~C,~R,~E,~H,~Error,owners,journal,W.barrier_traced(~S,~C,~R,~E,world,Facts.On{[]}))
81def dispatched(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Error:Data,+fact:Trace.Identity,before:Tick.Tick,journal:Journal<Error>,result:H & Sys.Outcome<Ctx.Context<W.World<S,C,R,E>>,Error,Unit>) -> (H & Journal<Error>) & Sys.Outcome<W.World<S,C,R,E>,Error,Unit>:
82  match result:
83    case (owners,Sys.Succeeded{Ctx.Context{world,trace},_}):succeeded(~S,~C,~R,~E,~H,~Error,owners,fact,before,record_operations(~Error,Facts.facts(trace),fact,journal),W.clock(~S,~C,~R,~E,world))
84    case (owners,Sys.Failed{Ctx.Context{world,trace},error}):failed(~S,~C,~R,~E,~H,~Error,owners,fact,before,record_operations(~Error,Facts.facts(trace),fact,journal),error,W.clock(~S,~C,~R,~E,world))
85def identified(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Error:Data,~dispatch:H -> Ctx.Context<W.World<S,C,R,E>> -> U32 -> H & Sys.Outcome<Ctx.Context<W.World<S,C,R,E>>,Error,Unit>,owners:H,journal:Journal<Error>,+id:U32,result:W.World<S,C,R,E> & (Trace.Identity & Tick.Tick)) -> (H & Journal<Error>) & Sys.Outcome<W.World<S,C,R,E>,Error,Unit>:
86  match result:
87    case (world,(fact,before)):dispatched(~S,~C,~R,~E,~H,~Error,fact,before,journal,dispatch(owners,Ctx.Context{world,Facts.On{[]}},id))
88def dispatch_id(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Error:Data,~dispatch:H -> Ctx.Context<W.World<S,C,R,E>> -> U32 -> H & Sys.Outcome<Ctx.Context<W.World<S,C,R,E>>,Error,Unit>,owners:H & Journal<Error>,world:W.World<S,C,R,E>,+id:U32) -> (H & Journal<Error>) & Sys.Outcome<W.World<S,C,R,E>,Error,Unit>:
89  match owners:
90    case (owners,+journal):identified(~S,~C,~R,~E,~H,~Error,~dispatch,owners,journal,id,identity(~S,~C,~R,~E,~Error,journal,world,id))
91def dispatch_recorded(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Error:Data,~dispatch:H -> Ctx.Context<W.World<S,C,R,E>> -> U32 -> H & Sys.Outcome<Ctx.Context<W.World<S,C,R,E>>,Error,Unit>,owners:H & Journal<Error>,world:W.World<S,C,R,E>,id:U32) -> (H & Journal<Error>) & Sys.Outcome<W.World<S,C,R,E>,Error,Unit>:
92  dispatch_id(~S,~C,~R,~E,~H,~Error,~dispatch,owners,world,id)
93# Sch.Ran supplies position only. The completion/error comes from the actual
94# dispatch result above, never from a guessed interpretation of Ran.
95def ran_chunk_more(~Error:Data,event:Trace.TraceEvent<Error>,chunk:List<&2,Trace.TraceEvent<Error>> & List<&2,Trace.TraceEvent<Error>>) -> List<&2,Trace.TraceEvent<Error>> & List<&2,Trace.TraceEvent<Error>>:
96  match chunk:
97    case (prefix,remaining):(event <> prefix,remaining)
98def ran_chunk(~Error:Data,journal:List<&2,Trace.TraceEvent<Error>>) -> List<&2,Trace.TraceEvent<Error>> & List<&2,Trace.TraceEvent<Error>>:
99  match journal:
100    case []:([],[])
101    case Trace.OperationObserved{identity,fact} <> rest:ran_chunk_more(~Error,Trace.OperationObserved{identity,fact},ran_chunk(~Error,rest))
102    case event <> rest:([event],rest)
103def barrier_chunk(~Error:Data,journal:List<&2,Trace.TraceEvent<Error>>) -> List<&2,Trace.TraceEvent<Error>> & List<&2,Trace.TraceEvent<Error>>:
104  match journal:
105    case []:([],[])
106    case Trace.BarrierOperationObserved{fact} <> rest:ran_chunk_more(~Error,Trace.BarrierOperationObserved{fact},barrier_chunk(~Error,rest))
107    case event <> rest:([],event <> rest)
108def merged_chunk(~Error:Data,next:List<&2,Trace.TraceEvent<Error>> -> List<&2,Trace.TraceEvent<Error>>,chunk:List<&2,Trace.TraceEvent<Error>> & List<&2,Trace.TraceEvent<Error>>) -> List<&2,Trace.TraceEvent<Error>>:
109  match chunk:
110    case (prefix,remaining):List.append(&2,Trace.TraceEvent<Error>,prefix,next(remaining))
111def merge(~Error:Data,observations:List<&2,Sch.Observation>,journal:List<&2,Trace.TraceEvent<Error>>) -> List<&2,Trace.TraceEvent<Error>>:
112  match observations journal:
113    case [], journal:journal
114    case Sch.Entered{name} <> rest, journal:Trace.PhaseEntered{name} <> merge(~Error,rest,journal)
115    case Sch.Skipped{id} <> rest, journal:Trace.SystemSkipped{id} <> merge(~Error,rest,journal)
116    case Sch.Applied{} <> rest, journal:merged_chunk(~Error,(remaining=>Trace.DeferredApplied{} <> merge(~Error,rest,remaining)),barrier_chunk(~Error,journal))
117    case Sch.Ran{_} <> rest, journal:merged_chunk(~Error,(remaining=>merge(~Error,rest,remaining)),ran_chunk(~Error,journal))
118def batch(~Error:Data,namespace:U32,name:String,observations:List<&2,Sch.Observation>,journal:Journal<Error>,outcome:Trace.Completion<Error>) -> Trace.Batch<Error>:
119  match journal:
120    case Journal{_,events}:Trace.Ready{Trace.ScheduleStarted{namespace,name} <> List.append(&2,Trace.TraceEvent<Error>,merge(~Error,observations,List.reverse(&2,Trace.TraceEvent<Error>,events)),[Trace.ScheduleEnded{outcome}])}
121def restored(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,~Error:Data,schema:Schema.Schema<S,C,R>,world:W.World<S,C,R,E>,owners:H,recipe:Tree.Recipe<W.World<S,C,R,E>,Rows,observe>,debug:Bool,plan:SP.Plan<S>,namespace:U32,name:String,steps:List<&2,Sch.Step>,needs:List<&2,SP.Requirement<S>>) -> Single.Application<S,C,R,E,H,Rows,observe,fold>:
122  Single.Application{App.Application{schema,Build.Registered{world,owners,recipe,debug}},plan,namespace,name,steps,needs}
123def disabled_outcome(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Error:Data,result:H & Sys.Outcome<Ctx.Context<W.World<S,C,R,E>>,Error,Unit>) -> H & Sys.Outcome<W.World<S,C,R,E>,Error,Unit>:
124  match result:
125    case (owners,Sys.Succeeded{Ctx.Context{world,_},output}):(owners,Sys.Succeeded{world,output})
126    case (owners,Sys.Failed{Ctx.Context{world,_},error}):(owners,Sys.Failed{world,error})
127def dispatch_disabled(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Error:Data,~dispatch:H -> Ctx.Context<W.World<S,C,R,E>> -> U32 -> H & Sys.Outcome<Ctx.Context<W.World<S,C,R,E>>,Error,Unit>,owners:H,world:W.World<S,C,R,E>,id:U32) -> H & Sys.Outcome<W.World<S,C,R,E>,Error,Unit>:
128  disabled_outcome(~S,~C,~R,~E,~H,~Error,dispatch(owners,Ctx.Context{world,Facts.Off{}},id))
129# Disabled runs use the old ordinary run directly: no identity/clock scan,
130# completion journal, trace-event construction or subscriber delivery occurs.
131# Transition-handler failure identifying its exit/transition/enter phase
132# and error text. Enter failure follows an already committed transition;
133# inspect the phase instead of assuming whole-transition rollback.
134type HandlerFailure is Data:
135  HandlerFailure{phase:Handlers.Phase,error:String}
136# Transition-handler execution retains the App, all handler owners, the
137# captured machine snapshot, optional phase failure and detached trace batch.
138# The captured snapshot is not a rollback command or a copy of affine owners.
139type HandlerRun<App:Type,Owners:Type,Snapshot:Data> is Type:
140  HandlerRun{app:App,owners:Owners,captured:Snapshot,failure:Maybe<&2,HandlerFailure>,batch:Trace.Batch<String>}
141def operation_events(facts:List<&2,Facts.Fact>) -> List<&2,Trace.TraceEvent<String>>:
142  match facts:
143    case []:[]
144    case fact <> rest:Trace.ExecutionOperationObserved{fact} <> operation_events(rest)
145def operation_batch(state:Facts.State) -> Trace.Batch<String>:
146  match state:
147    case Facts.Off{}:Trace.Disabled{}
148    case Facts.On{facts}:Trace.Ready{operation_events(List.reverse(&2,Facts.Fact,facts))}
149def trace_state(debug:Bool) -> Facts.State:
150  match debug:
151    case False{}:Facts.Off{}
152    case True{}:Facts.On{[]}
153def handlers_returned(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,~Value:Data,~declaration:FieldDecl.Declaration<S,C,R,E,Ops,Value>,~K:Data,~MachineV:Data,~take:R -> R & Machine.Slot<S,K,MachineV>,~put:R -> Machine.Slot<S,K,MachineV> -> R,~machine:MachineDecl.Declaration<S,K,MachineV,R,take>,~same:MachineV -> MachineV -> Bool,~publish:W.World<S,C,R,E> -> Machine.Transition<MachineV> -> W.World<S,C,R,E>,~body:@-H:Type -> @-caps:Ops(H) -> Handlers.Invocation<MachineV> -> H -> H & (Transaction.Outcome<String> & Unit),~Owners:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:Owners -> Owners & List<&2,Records.Fields<S>>,schema:Schema.Schema<S,C,R>,previous:Owners,recipe:Tree.Recipe<W.World<S,C,R,E>,Rows,observe>,debug:Bool,plan:SP.Plan<S>,namespace:U32,name:String,steps:List<&2,Sch.Step>,needs:List<&2,SP.Requirement<S>>,captured:Machine.Snapshot<MachineV>,result:HandlerEngine.HandlerResult<Ctx.Context<W.World<S,C,R,E>>,Handlers.Entry<S,C,R,E,MachineV,FieldSystem.runner(~S,~C,~R,~E,~Ops,~Handlers.Invocation<MachineV>,~String,~Unit,~FieldDecl.ordinary(~S,~C,~R,~E,~Ops,~Value,declaration),~body)>,Handlers.Phase>) -> HandlerRun<Single.Application<S,C,R,E,Owners,Rows,observe,fold>,Handlers.Owners<S,C,R,E,MachineV,FieldSystem.runner(~S,~C,~R,~E,~Ops,~Handlers.Invocation<MachineV>,~String,~Unit,~FieldDecl.ordinary(~S,~C,~R,~E,~Ops,~Value,declaration),~body)>,Machine.Snapshot<MachineV>>:
154  match result:
155    case HandlerEngine.Completed{HandlerEngine.Owners{exit,transition,enter},Ctx.Context{world,trace}}:HandlerRun{restored(~S,~C,~R,~E,~Owners,~Rows,~observe,~fold,~String,schema,world,previous,recipe,debug,plan,namespace,name,steps,needs),Handlers.Owners{exit,transition,enter},captured,None{},operation_batch(trace)}
156    case HandlerEngine.Stopped{HandlerEngine.Owners{exit,transition,enter},Ctx.Context{world,trace},phase,error}:HandlerRun{restored(~S,~C,~R,~E,~Owners,~Rows,~observe,~fold,~String,schema,world,previous,recipe,debug,plan,namespace,name,steps,needs),Handlers.Owners{exit,transition,enter},captured,Some{HandlerFailure{phase,error}},operation_batch(trace)}
157def handlers_read(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,~Value:Data,~declaration:FieldDecl.Declaration<S,C,R,E,Ops,Value>,~K:Data,~MachineV:Data,~take:R -> R & Machine.Slot<S,K,MachineV>,~put:R -> Machine.Slot<S,K,MachineV> -> R,~machine:MachineDecl.Declaration<S,K,MachineV,R,take>,~same:MachineV -> MachineV -> Bool,~publish:W.World<S,C,R,E> -> Machine.Transition<MachineV> -> W.World<S,C,R,E>,~body:@-H:Type -> @-caps:Ops(H) -> Handlers.Invocation<MachineV> -> H -> H & (Transaction.Outcome<String> & Unit),~Owners:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:Owners -> Owners & List<&2,Records.Fields<S>>,schema:Schema.Schema<S,C,R>,previous:Owners,recipe:Tree.Recipe<W.World<S,C,R,E>,Rows,observe>,+debug:Bool,plan:SP.Plan<S>,namespace:U32,name:String,steps:List<&2,Sch.Step>,needs:List<&2,SP.Requirement<S>>,owners:Handlers.Owners<S,C,R,E,MachineV,FieldSystem.runner(~S,~C,~R,~E,~Ops,~Handlers.Invocation<MachineV>,~String,~Unit,~FieldDecl.ordinary(~S,~C,~R,~E,~Ops,~Value,declaration),~body)>,read:W.World<S,C,R,E> & Machine.Slot<S,K,MachineV>) -> HandlerRun<Single.Application<S,C,R,E,Owners,Rows,observe,fold>,Handlers.Owners<S,C,R,E,MachineV,FieldSystem.runner(~S,~C,~R,~E,~Ops,~Handlers.Invocation<MachineV>,~String,~Unit,~FieldDecl.ordinary(~S,~C,~R,~E,~Ops,~Value,declaration),~body)>,Machine.Snapshot<MachineV>>:
158  match read:
159    case (world,+slot):handlers_returned(~S,~C,~R,~E,~Ops,~Value,~declaration,~K,~MachineV,~take,~put,~machine,~same,~publish,~body,~Owners,~Rows,~observe,~fold,schema,previous,recipe,debug,plan,namespace,name,steps,needs,Machine.snapshot(~S,~K,~MachineV,slot),ExecuteRun.handlers_resource_field(~S,~C,~R,~E,~Ops,~Value,~declaration,~K,~MachineV,~take,~put,~machine,~same,~publish,~body,owners,Ctx.Context{world,trace_state(debug)},Machine.snapshot(~S,~K,~MachineV,slot)))
160def run_handlers_resource_field(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,~Value:Data,~declaration:FieldDecl.Declaration<S,C,R,E,Ops,Value>,~K:Data,~MachineV:Data,~take:R -> R & Machine.Slot<S,K,MachineV>,~put:R -> Machine.Slot<S,K,MachineV> -> R,~machine:MachineDecl.Declaration<S,K,MachineV,R,take>,~same:MachineV -> MachineV -> Bool,~publish:W.World<S,C,R,E> -> Machine.Transition<MachineV> -> W.World<S,C,R,E>,~body:@-H:Type -> @-caps:Ops(H) -> Handlers.Invocation<MachineV> -> H -> H & (Transaction.Outcome<String> & Unit),~Owners:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:Owners -> Owners & List<&2,Records.Fields<S>>,app:Single.Application<S,C,R,E,Owners,Rows,observe,fold>,owners:Handlers.Owners<S,C,R,E,MachineV,FieldSystem.runner(~S,~C,~R,~E,~Ops,~Handlers.Invocation<MachineV>,~String,~Unit,~FieldDecl.ordinary(~S,~C,~R,~E,~Ops,~Value,declaration),~body)>) -> HandlerRun<Single.Application<S,C,R,E,Owners,Rows,observe,fold>,Handlers.Owners<S,C,R,E,MachineV,FieldSystem.runner(~S,~C,~R,~E,~Ops,~Handlers.Invocation<MachineV>,~String,~Unit,~FieldDecl.ordinary(~S,~C,~R,~E,~Ops,~Value,declaration),~body)>,Machine.Snapshot<MachineV>>:
161  match app:
162    case Single.Application{App.Application{schema,Build.Registered{world,previous,recipe,debug}},plan,namespace,name,steps,needs}:handlers_read(~S,~C,~R,~E,~Ops,~Value,~declaration,~K,~MachineV,~take,~put,~machine,~same,~publish,~body,~Owners,~Rows,~observe,~fold,schema,previous,recipe,debug,plan,namespace,name,steps,needs,owners,MachineWorld.take(~S,~K,~MachineV,~C,~R,~E,~take,world))
163
164type ExecutionState<Error:Data> is Data:
165  Off{}
166  On{journal:Journal<Error>}
167def disabled_dispatched(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Error:Data,result:H & Sys.Outcome<W.World<S,C,R,E>,Error,Unit>) -> (H & ExecutionState<Error>) & Sys.Outcome<W.World<S,C,R,E>,Error,Unit>:
168  match result:
169    case (owners,outcome):((owners,Off{}),outcome)
170def enabled_dispatched(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Error:Data,result:(H & Journal<Error>) & Sys.Outcome<W.World<S,C,R,E>,Error,Unit>) -> (H & ExecutionState<Error>) & Sys.Outcome<W.World<S,C,R,E>,Error,Unit>:
171  match result:
172    case ((owners,journal),outcome):((owners,On{journal}),outcome)
173def dispatch_state(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Error:Data,~dispatch:H -> Ctx.Context<W.World<S,C,R,E>> -> U32 -> H & Sys.Outcome<Ctx.Context<W.World<S,C,R,E>>,Error,Unit>,owner:H & ExecutionState<Error>,world:W.World<S,C,R,E>,id:U32) -> (H & ExecutionState<Error>) & Sys.Outcome<W.World<S,C,R,E>,Error,Unit>:
174  match owner:
175    case (owners,Off{}):disabled_dispatched(~S,~C,~R,~E,~H,~Error,dispatch_disabled(~S,~C,~R,~E,~H,~Error,~dispatch,owners,world,id))
176    case (owners,On{journal}):enabled_dispatched(~S,~C,~R,~E,~H,~Error,dispatch_recorded(~S,~C,~R,~E,~H,~Error,~dispatch,(owners,journal),world,id))
177def enabled_barrier(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Error:Data,result:(H & Journal<Error>) & W.World<S,C,R,E>) -> (H & ExecutionState<Error>) & W.World<S,C,R,E>:
178  match result:
179    case ((owners,journal),world):((owners,On{journal}),world)
180def barrier_state(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Error:Data,owner:H & ExecutionState<Error>,world:W.World<S,C,R,E>) -> (H & ExecutionState<Error>) & W.World<S,C,R,E>:
181  match owner:
182    case (owners,Off{}):((owners,Off{}),W.barrier(~S,~C,~R,~E,world))
183    case (owners,On{journal}):enabled_barrier(~S,~C,~R,~E,~H,~Error,barrier_recorded(~S,~C,~R,~E,~H,~Error,(owners,journal),world))
184def executed(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,~Error:Data,schema:Schema.Schema<S,C,R>,recipe:Tree.Recipe<W.World<S,C,R,E>,Rows,observe>,plan:SP.Plan<S>,needs:List<&2,SP.Requirement<S>>,result:Sch.RunResult<S,C,R,E,H & ExecutionState<Error>,Error>) -> Run<Single.Application<S,C,R,E,H,Rows,observe,fold>,S,Error>:
185  match result:
186    case Sch.Finished{Sch.Schedule{namespace,name,steps,(owners,Off{})},world,observations}:Run{Single.Finished{restored(~S,~C,~R,~E,~H,~Rows,~observe,~fold,~Error,schema,world,owners,recipe,False{},plan,namespace,name,steps,needs),observations},Trace.Disabled{}}
187    case Sch.Finished{Sch.Schedule{+namespace,+name,steps,(owners,On{journal})},world,+observations}:Run{Single.Finished{restored(~S,~C,~R,~E,~H,~Rows,~observe,~fold,~Error,schema,world,owners,recipe,True{},plan,namespace,name,steps,needs),observations},batch(~Error,namespace,name,observations,journal,Trace.EndOk{})}
188    case Sch.Failed{Sch.Schedule{namespace,name,steps,(owners,Off{})},world,error,observations}:Run{Single.Failed{restored(~S,~C,~R,~E,~H,~Rows,~observe,~fold,~Error,schema,world,owners,recipe,False{},plan,namespace,name,steps,needs),error,observations},Trace.Disabled{}}
189    case Sch.Failed{Sch.Schedule{+namespace,+name,steps,(owners,On{journal})},world,+error,+observations}:Run{Single.Failed{restored(~S,~C,~R,~E,~H,~Rows,~observe,~fold,~Error,schema,world,owners,recipe,True{},plan,namespace,name,steps,needs),error,observations},batch(~Error,namespace,name,observations,journal,Trace.EndFailed{error})}
190    case Sch.Rejected{Sch.Schedule{namespace,name,steps,(owners,Off{})},world}:Run{Single.Rejected{restored(~S,~C,~R,~E,~H,~Rows,~observe,~fold,~Error,schema,world,owners,recipe,False{},plan,namespace,name,steps,needs)},Trace.Disabled{}}
191    case Sch.Rejected{Sch.Schedule{+namespace,+name,steps,(owners,On{journal})},world}:Run{Single.Rejected{restored(~S,~C,~R,~E,~H,~Rows,~observe,~fold,~Error,schema,world,owners,recipe,True{},plan,namespace,name,steps,needs)},Trace.Ready{[Trace.ScheduleAdmissionRefused{namespace,name,Trace.EndRejected{}}]}}
192def provisioned(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,~Error:Data,schema:Schema.Schema<S,C,R>,recipe:Tree.Recipe<W.World<S,C,R,E>,Rows,observe>,plan:SP.Plan<S>,result:SP.ProvisionResult<S,C,R,E,H & ExecutionState<Error>,Error>) -> Run<Single.Application<S,C,R,E,H,Rows,observe,fold>,S,Error>:
193  match result:
194    case SP.Executed{result,needs}:executed(~S,~C,~R,~E,~H,~Rows,~observe,~fold,~Error,schema,recipe,plan,needs,result)
195    case SP.Missing{SP.Provisioned{Sch.Schedule{namespace,name,steps,(owners,Off{})},needs},world,missing}:Run{Single.Missing{restored(~S,~C,~R,~E,~H,~Rows,~observe,~fold,~Error,schema,world,owners,recipe,False{},plan,namespace,name,steps,needs),missing},Trace.Disabled{}}
196    case SP.Missing{SP.Provisioned{Sch.Schedule{+namespace,+name,steps,(owners,On{journal})},needs},world,+missing}:Run{Single.Missing{restored(~S,~C,~R,~E,~H,~Rows,~observe,~fold,~Error,schema,world,owners,recipe,True{},plan,namespace,name,steps,needs),missing},Trace.Ready{[Trace.ScheduleAdmissionRefused{namespace,name,Trace.EndMissing{}}]}}
197def start(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,~Error:Data,~dispatch:H -> Ctx.Context<W.World<S,C,R,E>> -> U32 -> H & Sys.Outcome<Ctx.Context<W.World<S,C,R,E>>,Error,Unit>,~condition:W.World<S,C,R,E> -> U32 -> W.World<S,C,R,E> & Bool,~provision:W.World<S,C,R,E> -> W.World<S,C,R,E> & List<&2,SP.Requirement<S>>,schema:Schema.Schema<S,C,R>,world:W.World<S,C,R,E>,recipe:Tree.Recipe<W.World<S,C,R,E>,Rows,observe>,plan:SP.Plan<S>,namespace:U32,name:String,steps:List<&2,Sch.Step>,needs:List<&2,SP.Requirement<S>>,owners:H,state:ExecutionState<Error>) -> Run<Single.Application<S,C,R,E,H,Rows,observe,fold>,S,Error>:
198  provisioned(~S,~C,~R,~E,~H,~Rows,~observe,~fold,~Error,schema,recipe,plan,SP.run_with_barrier(~S,~C,~R,~E,~(H & ExecutionState<Error>),~Error,~dispatch_state(~S,~C,~R,~E,~H,~Error,~dispatch),~condition,~barrier_state(~S,~C,~R,~E,~H,~Error),~provision,SP.Provisioned{Sch.Schedule{namespace,name,steps,(owners,state)},needs},world))
199def prepared(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,~Error:Data,~dispatch:H -> Ctx.Context<W.World<S,C,R,E>> -> U32 -> H & Sys.Outcome<Ctx.Context<W.World<S,C,R,E>>,Error,Unit>,~condition:W.World<S,C,R,E> -> U32 -> W.World<S,C,R,E> & Bool,~provision:W.World<S,C,R,E> -> W.World<S,C,R,E> & List<&2,SP.Requirement<S>>,schema:Schema.Schema<S,C,R>,world:W.World<S,C,R,E>,recipe:Tree.Recipe<W.World<S,C,R,E>,Rows,observe>,plan:SP.Plan<S>,namespace:U32,name:String,steps:List<&2,Sch.Step>,needs:List<&2,SP.Requirement<S>>,value:H & List<&2,Records.Fields<S>>) -> Run<Single.Application<S,C,R,E,H,Rows,observe,fold>,S,Error>:
200  match value:
201    case (owners,fields):start(~S,~C,~R,~E,~H,~Rows,~observe,~fold,~Error,~dispatch,~condition,~provision,schema,world,recipe,plan,namespace,name,steps,needs,owners,On{Journal{catalog(~S,fields),[]}})
202# Advanced traced schedule execution with supplied dispatch/condition/provision
203# callbacks. Returns Run on admission refusal, missing requirements, success
204# or system failure, retaining App ownership throughout. Disabled debug omits
205# trace collection; enabled debug derives identities and operations from actual
206# execution. Supplied callbacks are trusted world-transforming adapters;
207# arbitrary callback mutations/host IO are not automatically transactional.
208# Prefer ordinary-app-run.run for registration-derived dispatch.
209def run(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,~Error:Data,~dispatch:H -> Ctx.Context<W.World<S,C,R,E>> -> U32 -> H & Sys.Outcome<Ctx.Context<W.World<S,C,R,E>>,Error,Unit>,~condition:W.World<S,C,R,E> -> U32 -> W.World<S,C,R,E> & Bool,~provision:W.World<S,C,R,E> -> W.World<S,C,R,E> & List<&2,SP.Requirement<S>>,value:Single.Application<S,C,R,E,H,Rows,observe,fold>) -> Run<Single.Application<S,C,R,E,H,Rows,observe,fold>,S,Error>:
210  match value:
211    case Single.Application{App.Application{schema,Build.Registered{world,owners,recipe,False{}}},plan,namespace,name,steps,needs}:start(~S,~C,~R,~E,~H,~Rows,~observe,~fold,~Error,~dispatch,~condition,~provision,schema,world,recipe,plan,namespace,name,steps,needs,owners,Off{})
212    case Single.Application{App.Application{schema,Build.Registered{world,owners,recipe,True{}}},plan,namespace,name,steps,needs}:prepared(~S,~C,~R,~E,~H,~Rows,~observe,~fold,~Error,~dispatch,~condition,~provision,schema,world,recipe,plan,namespace,name,steps,needs,fold(owners))