1 import Base 2 import ./execution_resource_policy.bend as Policy 3 import ./execution_reservation_bundle.bend as Bundle 4 import ./execution_composer_layout.bend as Layout 5 import ./execution_command_permission.bend as Permission 6 import ./execution_query_identity.bend as Index 7 import ./execution_command_removed.bend as Removed 8 import ./owner_product.bend as Product 9 import ./chunk_column.bend as Column 10 import ./change_tick.bend as Tick 11 import ./world.bend as W 12 import ./lifecycle.bend as L 13 import ./chunk_shape.bend as Part 14 import ./execution_lifecycle_notices.bend as Notice 15 import ./clock_state.bend as Clock 16 import ./deferred_command.bend as Deferred 17 import ./entity_allocator.bend as A 18 19 type Remainder<-S:Data,-C:Type,-R:Type,-E:Data> is Type: 20 Remainder{namespace:U32,resource:R,events:List<&2,E>,pending:List>>,registrations:List<&2,W.RegistrationMeta>,nextSystemId:U32,clock:Clock.State,lifecycle:Notice.Journal} 21 22 # Preflight inspects actual presence without a callback or schema refresher. 23 # No incoming payload is initialized until the full tree has been checked. 24 def reason(ok:Bool,key:String) -> Maybe<&2,Bundle.Refusal>: 25 match ok: 26 case True{}:None{} 27 case False{}:Some{Bundle.OccupiedFamily{key}} 28 def first(left:Maybe<&2,Bundle.Refusal>,right:Maybe<&2,Bundle.Refusal>) -> Maybe<&2,Bundle.Refusal>: 29 match left: 30 case None{}:right 31 case Some{error}:Some{error} 32 def leaf_checked(~S:Data,-P:Type,-V:Data,+key:String,-origin:Layout.Layout,bundle:Maybe<&1,P>,result:Column.Column> & Maybe<&2,Bool>) -> Layout.ColumnSlot,key,origin> & (Maybe<&1,P> & Maybe<&2,Bundle.Refusal>): 33 match result: 34 case (column,None{}):(Layout.ColumnSlot{column},(bundle,Some{Bundle.MalformedColumn{key}})) 35 case (column,Some{vacant}):(Layout.ColumnSlot{column},(bundle,reason(vacant,key))) 36 def vacancy_within(~S:Data,-P:Type,-V:Data,+key:String,-origin:Layout.Layout,index:U32,bundle:Maybe<&1,P>,column:Column.Column>,within:Bool) -> Layout.ColumnSlot,key,origin> & (Maybe<&1,P> & Maybe<&2,Bundle.Refusal>): 37 match within: 38 case False{}:(Layout.ColumnSlot{column},(bundle,None{})) 39 case True{}:leaf_checked(~S,P,V,key,origin,bundle,Column.vacancy_generic(S,Layout.Viewed,column,index)) 40 def shape_allowed(~S:Data,-P:Type,-V:Data,+key:String,-origin:Layout.Layout,+index:U32,capacity:U32,bundle:Maybe<&1,P>,column:Column.Column>,valid:Bool) -> Layout.ColumnSlot,key,origin> & (Maybe<&1,P> & Maybe<&2,Bundle.Refusal>): 41 match valid: 42 case False{}:(Layout.ColumnSlot{column},(bundle,Some{Bundle.MalformedColumn{key}})) 43 case True{}:vacancy_within(~S,P,V,key,origin,index,bundle,column,U32.is_lt(index,capacity)) 44 def shape_checked(~S:Data,-P:Type,-V:Data,+key:String,-origin:Layout.Layout,index:U32,bundle:Maybe<&1,P>,result:Column.Column> & Part.Inspection) -> Layout.ColumnSlot,key,origin> & (Maybe<&1,P> & Maybe<&2,Bundle.Refusal>): 45 match result: 46 case (column,Part.Inspection{_,+capacity,valid}):shape_allowed(~S,P,V,key,origin,index,capacity,bundle,column,Bool.and(valid,U32.is_le(capacity,Column.maximum_capacity()))) 47 def check_leaf(~S:Data,-P:Type,-V:Data,+key:String,-origin:Layout.Layout,index:U32,slot:Layout.ColumnSlot,key,origin>,bundle:Maybe<&1,P>) -> Layout.ColumnSlot,key,origin> & (Maybe<&1,P> & Maybe<&2,Bundle.Refusal>): 48 match slot bundle: 49 case slot None{}:(slot,(None{},None{})) 50 case Layout.ColumnSlot{column} Some{owner}:shape_checked(~S,P,V,key,origin,index,Some{owner},Part.inspect(S,Layout.Viewed,column)) 51 def check_right(~S:Data,-left:Layout.Layout,-right:Layout.Layout,leftOwner:Layout.columns(~S,left),leftBundle:Bundle.Payload(left),leftReason:Maybe<&2,Bundle.Refusal>,result:Layout.columns(~S,right) & (Bundle.Payload(right) & Maybe<&2,Bundle.Refusal>)) -> Layout.columns(~S,Layout.LayoutPair{left,right}) & (Bundle.Payload(Layout.LayoutPair{left,right}) & Maybe<&2,Bundle.Refusal>): 52 match result: 53 case (rightOwner,(rightBundle,rightReason)):(Product.Owner{leftOwner,rightOwner},(Product.Owner{leftBundle,rightBundle},first(leftReason,rightReason))) 54 def check_left(~S:Data,-left:Layout.Layout,-right:Layout.Layout,checkRight:U32 -> Layout.columns(~S,right) -> Bundle.Payload(right) -> Layout.columns(~S,right) & (Bundle.Payload(right) & Maybe<&2,Bundle.Refusal>),index:U32,rightOwner:Layout.columns(~S,right),rightBundle:Bundle.Payload(right),result:Layout.columns(~S,left) & (Bundle.Payload(left) & Maybe<&2,Bundle.Refusal>)) -> Layout.columns(~S,Layout.LayoutPair{left,right}) & (Bundle.Payload(Layout.LayoutPair{left,right}) & Maybe<&2,Bundle.Refusal>): 55 match result: 56 case (leftOwner,(leftBundle,leftReason)):check_right(~S,left,right,leftOwner,leftBundle,leftReason,checkRight(index,rightOwner,rightBundle)) 57 def check_pair(~S:Data,-left:Layout.Layout,-right:Layout.Layout,checkLeft:U32 -> Layout.columns(~S,left) -> Bundle.Payload(left) -> Layout.columns(~S,left) & (Bundle.Payload(left) & Maybe<&2,Bundle.Refusal>),checkRight:U32 -> Layout.columns(~S,right) -> Bundle.Payload(right) -> Layout.columns(~S,right) & (Bundle.Payload(right) & Maybe<&2,Bundle.Refusal>),+index:U32,store:Layout.columns(~S,Layout.LayoutPair{left,right}),bundle:Bundle.Payload(Layout.LayoutPair{left,right})) -> Layout.columns(~S,Layout.LayoutPair{left,right}) & (Bundle.Payload(Layout.LayoutPair{left,right}) & Maybe<&2,Bundle.Refusal>): 58 match store bundle: 59 case Product.Owner{lo,ro} Product.Owner{lb,rb}:check_left(~S,left,right,checkRight,index,ro,rb,checkLeft(index,lo,lb)) 60 def check(~S:Data,layout:Layout.Layout) -> U32 -> Layout.columns(~S,layout) -> Bundle.Payload(layout) -> Layout.columns(~S,layout) & (Bundle.Payload(layout) & Maybe<&2,Bundle.Refusal>): 61 match layout: 62 case Layout.EmptyLayout{}:index => store => bundle => (store,(bundle,None{})) 63 case Layout.LayoutLeaf{P,V,refresh,key,accessPolicy}:check_leaf(~S,P,V,key,Layout.LayoutLeaf{P,V,refresh,key,accessPolicy}) 64 case Layout.ClassifiedLayoutLeaf{P,V,refresh,key,policy,accessPolicy}:check_leaf(~S,P,V,key,Layout.ClassifiedLayoutLeaf{P,V,refresh,key,policy,accessPolicy}) 65 case Layout.LayoutPair{left,right}:index => store => bundle => check_pair(~S,left,right,check(~S,left),check(~S,right),index,store,bundle) 66 67 # Internal storage primitive, called only after whole-tree preflight and ensure. 68 # Like canonical Column.swap_leaf, it preserves the displaced affine owner and 69 # updates both lifecycle stamps using the captured publication tick. 70 def written_stamp(~S:Data,-P:Type,values:Array>,previous:Maybe<&1,P>,+index:U32,tick:Tick.Tick,wasPresent:Bool,result:Array & L.Stamp) -> Column.Column & Maybe<&1,P>: 71 match result: 72 case (stamps,stamp):(Column.Leaf{values,Array.set(L.Stamp,stamps,index,L.after_write(True{},wasPresent,stamp,tick))},previous) 73 def written_value(~S:Data,-P:Type,stamps:Array,+index:U32,tick:Tick.Tick,result:Array> & Maybe<&1,P>) -> Column.Column & Maybe<&1,P>: 74 match result: 75 case (values,None{}):written_stamp(~S,P,values,None{},index,tick,False{},Array.get(L.Stamp,stamps,index)) 76 case (values,Some{previous}):written_stamp(~S,P,values,Some{previous},index,tick,True{},Array.get(L.Stamp,stamps,index)) 77 def replace_left(~S:Data,-P:Type,half:U32,right:Column.Column,result:Column.Column & Maybe<&1,P>) -> Column.Column & Maybe<&1,P>: 78 match result: 79 case (left,previous):(Column.Branch{half,left,right},previous) 80 def replace_right(~S:Data,-P:Type,half:U32,left:Column.Column,result:Column.Column & Maybe<&1,P>) -> Column.Column & Maybe<&1,P>: 81 match result: 82 case (right,previous):(Column.Branch{half,left,right},previous) 83 def branch_results(~S:Data,-P:Type,half:U32,resultLeft:Column.Column & Maybe<&1,P>,resultRight:Column.Column & Maybe<&1,P>,first:Bool) -> Column.Column & Maybe<&1,P>: 84 match resultLeft resultRight first: 85 case (left,previous), (right,_), True{}:(Column.Branch{half,left,right},previous) 86 case (left,_), (right,previous), False{}:(Column.Branch{half,left,right},previous) 87 def write_branch(~S:Data,-P:Type,writeLeft:Maybe<&1,P> -> Column.Column & Maybe<&1,P>,writeRight:Maybe<&1,P> -> Column.Column & Maybe<&1,P>,half:U32,incoming:P,first:Bool) -> Column.Column & Maybe<&1,P>: 88 match first: 89 case True{}:branch_results(~S,P,half,writeLeft(Some{incoming}),writeRight(None{}),True{}) 90 case False{}:branch_results(~S,P,half,writeLeft(None{}),writeRight(Some{incoming}),False{}) 91 def write_column(~S:Data,-P:Type,column:Column.Column,+index:U32,+tick:Tick.Tick,incoming:Maybe<&1,P>) -> Column.Column & Maybe<&1,P>: 92 match column incoming: 93 case column None{}:(column,None{}) 94 case Column.Leaf{values,stamps} Some{incoming}:written_value(~S,P,stamps,index,tick,Array.swap(Maybe<&1,P>,values,index,Some{incoming})) 95 case Column.Branch{+half,left,right} Some{incoming}:write_branch(~S,P,write_column(~S,P,left,index,tick),write_column(~S,P,right,U32.sub(index,half),tick),half,incoming,U32.is_lt(index,half)) 96 def installed_leaf(~S:Data,-P:Type,-V:Data,-key:String,-origin:Layout.Layout,result:Column.Column> & Maybe<&1,Layout.Viewed>) -> Layout.ColumnSlot,key,origin> & Maybe<&1,P>: 97 match result: 98 case (column,previous):(Layout.ColumnSlot{column},Removed.raw(P,V,previous)) 99 def install_leaf(~S:Data,-P:Type,-V:Data,refresh:P -> P & V,-key:String,-origin:Layout.Layout,+index:U32,tick:Tick.Tick,slot:Layout.ColumnSlot,key,origin>,bundle:Maybe<&1,P>) -> Layout.ColumnSlot,key,origin> & Maybe<&1,P>: 100 match slot bundle: 101 case slot None{}:(slot,None{}) 102 case Layout.ColumnSlot{column} Some{incoming}:installed_leaf(~S,P,V,key,origin,write_column(~S,Layout.Viewed,Column.ensure_generic(S,Layout.Viewed,column,U32.add(index,1)),index,tick,Some{Layout.initialized(P,V,refresh(incoming))})) 103 def installed_right(~S:Data,-left:Layout.Layout,-right:Layout.Layout,leftOwner:Layout.columns(~S,left),leftPrevious:Bundle.Payload(left),result:Layout.columns(~S,right) & Bundle.Payload(right)) -> Layout.columns(~S,Layout.LayoutPair{left,right}) & Bundle.Payload(Layout.LayoutPair{left,right}): 104 match result: 105 case (rightOwner,rightPrevious):(Product.Owner{leftOwner,rightOwner},Product.Owner{leftPrevious,rightPrevious}) 106 def installed_left(~S:Data,-left:Layout.Layout,-right:Layout.Layout,installRight:U32 -> Tick.Tick -> Layout.columns(~S,right) -> Bundle.Payload(right) -> Layout.columns(~S,right) & Bundle.Payload(right),index:U32,tick:Tick.Tick,rightOwner:Layout.columns(~S,right),rightBundle:Bundle.Payload(right),result:Layout.columns(~S,left) & Bundle.Payload(left)) -> Layout.columns(~S,Layout.LayoutPair{left,right}) & Bundle.Payload(Layout.LayoutPair{left,right}): 107 match result: 108 case (leftOwner,leftPrevious):installed_right(~S,left,right,leftOwner,leftPrevious,installRight(index,tick,rightOwner,rightBundle)) 109 def install_pair(~S:Data,-left:Layout.Layout,-right:Layout.Layout,installLeft:U32 -> Tick.Tick -> Layout.columns(~S,left) -> Bundle.Payload(left) -> Layout.columns(~S,left) & Bundle.Payload(left),installRight:U32 -> Tick.Tick -> Layout.columns(~S,right) -> Bundle.Payload(right) -> Layout.columns(~S,right) & Bundle.Payload(right),+index:U32,+tick:Tick.Tick,store:Layout.columns(~S,Layout.LayoutPair{left,right}),bundle:Bundle.Payload(Layout.LayoutPair{left,right})) -> Layout.columns(~S,Layout.LayoutPair{left,right}) & Bundle.Payload(Layout.LayoutPair{left,right}): 110 match store bundle: 111 case Product.Owner{lo,ro} Product.Owner{lb,rb}:installed_left(~S,left,right,installRight,index,tick,ro,rb,installLeft(index,tick,lo,lb)) 112 def install(~S:Data,layout:Layout.Layout) -> U32 -> Tick.Tick -> Layout.columns(~S,layout) -> Bundle.Payload(layout) -> Layout.columns(~S,layout) & Bundle.Payload(layout): 113 match layout: 114 case Layout.EmptyLayout{}:index => tick => store => bundle => (store,Unit{}) 115 case Layout.LayoutLeaf{P,V,refresh,key,accessPolicy}:index => tick => slot => bundle => install_leaf(~S,P,V,refresh,key,Layout.LayoutLeaf{P,V,refresh,key,accessPolicy},index,tick,slot,bundle) 116 case Layout.ClassifiedLayoutLeaf{P,V,refresh,key,policy,accessPolicy}:index => tick => slot => bundle => install_leaf(~S,P,V,refresh,key,Layout.ClassifiedLayoutLeaf{P,V,refresh,key,policy,accessPolicy},index,tick,slot,bundle) 117 case Layout.LayoutPair{left,right}:index => tick => store => bundle => install_pair(~S,left,right,install(~S,left),install(~S,right),index,tick,store,bundle) 118 119 def assembled(~S:Data,~R:Type,~E:Data,~layout:Layout.Layout,allocator:A.Allocator,rest:Remainder,store:Layout.columns(~S,layout)) -> W.World: 120 match rest: 121 case Remainder{namespace,resource,events,pending,registrations,nextSystemId,clock,lifecycle}:W.World{namespace,allocator,store,resource,events,pending,registrations,nextSystemId,clock,lifecycle} 122 def installed(~S:Data,~R:Type,~E:Data,~layout:Layout.Layout,allocator:A.Allocator,rest:Remainder,+handle:W.Handle,result:Layout.columns(~S,layout) & Bundle.Payload(layout)) -> Bundle.Publication: 123 match result: 124 case (store,previous):Bundle.Materialized{assembled(~S,~R,~E,~layout,A.write_phase(allocator,W.handle_key(~S,handle),A.Live{}),rest,store),handle,previous} 125 def checked_store(~S:Data,~R:Type,~E:Data,~layout:Layout.Layout,installTree:U32 -> Tick.Tick -> Layout.columns(~S,layout) -> Bundle.Payload(layout) -> Layout.columns(~S,layout) & Bundle.Payload(layout),allocator:A.Allocator,rest:Remainder,handle:W.Handle,index:U32,tick:Tick.Tick,result:Layout.columns(~S,layout) & (Bundle.Payload(layout) & Maybe<&2,Bundle.Refusal>)) -> Bundle.Publication: 126 match result: 127 case (store,(bundle,Some{reason})):Bundle.RefusedPublication{assembled(~S,~R,~E,~layout,allocator,rest,store),handle,bundle,reason} 128 case (store,(bundle,None{})):installed(~S,~R,~E,~layout,allocator,rest,handle,installTree(index,tick,store,bundle)) 129 def preflight(~S:Data,~R:Type,~E:Data,~layout:Layout.Layout,world:W.World,handle:W.Handle,bundle:Bundle.Payload(layout),+index:U32,tick:Tick.Tick) -> Bundle.Publication: 130 match world: 131 case W.World{namespace,allocator,store,resource,events,pending,registrations,nextSystemId,clock,lifecycle}:checked_store(~S,~R,~E,~layout,install(~S,layout),allocator,Remainder{namespace,resource,events,pending,registrations,nextSystemId,clock,lifecycle},handle,index,tick,check(~S,layout,index,store,bundle)) 132 def physical(~S:Data,~R:Type,~E:Data,~layout:Layout.Layout,world:W.World,handle:W.Handle,bundle:Bundle.Payload(layout),tick:Tick.Tick,offset:Maybe<&2,U32>) -> Bundle.Publication: 133 match offset: 134 case None{}:Bundle.RefusedPublication{world,handle,bundle,Bundle.PhysicalIndex{}} 135 case Some{index}:preflight(~S,~R,~E,layout,world,handle,bundle,index,tick) 136 def unique(~S:Data,~R:Type,~E:Data,~layout:Layout.Layout,world:W.World,+handle:W.Handle,bundle:Bundle.Payload(layout),tick:Tick.Tick,valid:Bool) -> Bundle.Publication: 137 match valid: 138 case False{}:Bundle.RefusedPublication{world,handle,bundle,Bundle.DuplicateFamily{}} 139 case True{}:physical(~S,~R,~E,layout,world,handle,bundle,tick,Index.physical_index(W.handle_index(~S,handle))) 140 def permitted(~S:Data,~R:Type,~E:Data,~layout:Layout.Layout,world:W.World,handle:W.Handle,bundle:Bundle.Payload(layout),tick:Tick.Tick,permission:Permission.Permission) -> Bundle.Publication: 141 match permission: 142 case Permission.FamilyOnly{}:Bundle.RefusedPublication{world,handle,bundle,Bundle.PermissionDenied{}} 143 case Permission.EntityStructural{}:unique(~S,~R,~E,layout,world,handle,bundle,tick,Layout.unique(layout)) 144 def pending_checked(~S:Data,~R:Type,~E:Data,~layout:Layout.Layout,permission:Permission.Permission,handle:W.Handle,bundle:Bundle.Payload(layout),tick:Tick.Tick,result:W.World & Bool) -> Bundle.Publication: 145 match result: 146 case (world,False{}):Bundle.RefusedPublication{world,handle,bundle,Bundle.InvalidPending{W.MissingEntity{}}} 147 case (world,True{}):permitted(~S,~R,~E,layout,world,handle,bundle,tick,permission) 148 # Existing command publication calls this only at its barrier, with captured tick. 149 # Pending namespace/generation/phase validation precedes even bundle preflight. 150 def apply_at(~S:Data,~R:Type,~E:Data,~layout:Layout.Layout,permission:Permission.Permission,world:W.World,+handle:W.Handle,bundle:Bundle.Payload(layout),tick:Tick.Tick) -> Bundle.Publication: 151 pending_checked(~S,~R,~E,layout,permission,handle,bundle,tick,W.pending_valid(~S,~(Layout.columns(~S,layout)),~R,~E,world,handle))