1 import Base 2 import ./change_tick.bend as Tick 3 import ./trace_facts.bend as TraceFacts 4 import ./ordinary_query_declaration.bend as Query 5 import ./compose.bend as Q 6 import ./world.bend as W 7 import ./system.bend as Sys 8 import ./transaction.bend as T 9 import ./ordinary_query_observable.bend as O 10 import ./inspector.bend as I 11 12 # Retain clauses from the same declaration used to execute the registered body. 13 # This is ordinary registration state, not a caller-supplied debug description. 14 # Registered ordinary-query system owner retaining its actual Registry, 15 # authored slot and clauses derived from the operational declaration. 16 # Contains registration metadata, not a second user-authored debug schema. 17 type Owner<-S:Data,-Registry:Type> is Type: 18 Owner{registry:Registry,slot:String,clauses:List<&2,Query.Clause>} 19 # Defined returns World and ordinary registration owner; Rejected returns 20 # World on registration refusal. No system body is executed by definition. 21 type Defined<-S:Data,-World:Type,-Registry:Type> is Type: 22 Defined{world:World,owner:Owner} 23 Rejected{world:World} 24 # Project ordered component names from declaration clauses as registration 25 # access metadata. Does not validate runtime identity or grant payload access. 26 def access(~S:Data,clauses:List<&2,Query.Clause>) -> List<&2,String>: 27 match clauses: 28 case []:[] 29 case Query.Clause{name,_} <> rest:name <> access(~S,rest) 30 31 def plan_parts(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,declaration:Query.Declaration,Ops(Q.Frame)>) -> Q.Plan: 32 match declaration: 33 case Query.Declaration{grant,select,_}:Q.Plan{grant,select} 34 # Lower a closed ordinary declaration into its operational query plan. 35 # Grant and row predicate come from that declaration; this performs no scan. 36 # Trusted setup must keep the declaration consistent with the body Ops. 37 def plan(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,~A:Data,~U:Data,~Out:Data,~query:Query.Declaration,Ops(Q.Frame)>,~body:@-H:Type -> @-caps:Ops(H) -> A -> H -> H & (T.Outcome & Out)) -> Q.Plan: 38 plan_parts(~S,~C,~R,~E,~Ops,query) 39 def completed(~S:Data,~C:Type,~R:Type,~E:Data,~U:Data,~Out:Data,result:Q.Executed,Q.Error,Out>) -> Sys.Outcome,Q.Error,List<&2,Out>>: 40 match result: 41 case Q.Executed{world,T.Success{},values}:Sys.Succeeded{world,values} 42 case Q.Executed{world,T.Failure{error},_}:Sys.Failed{world,error} 43 # Lower-level query execution with Data arguments and explicit lifecycle 44 # cursor. Runs the enclosing Compose transaction over selected rows; failure 45 # reports query error and discards row outputs. This bypasses Registry checks; 46 # use define/run or App registration for ordinary runtime-bound execution. 47 def runner(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,~A:Data,~U:Data,~Out:Data,~query:Query.Declaration,Ops(Q.Frame)>,~body:@-H:Type -> @-caps:Ops(H) -> A -> H -> H & (T.Outcome & Out),world:W.World,args:A & Maybe<&2,Tick.Tick>) -> Sys.Outcome,Q.Error,List<&2,Out>>: 48 match args: 49 case (args,cursor):completed(~S,~C,~R,~E,~U,~Out,Q.each_since(~S,~C,~R,~E,~Ops,~A,~U,~Out,~plan(~S,~C,~R,~E,~Ops,~A,~U,~Out,~query,~body),~body,args,world,cursor)) 50 def registered(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,~A:Data,~U:Data,~Out:Data,~query:Query.Declaration,Ops(Q.Frame)>,~body:@-H:Type -> @-caps:Ops(H) -> A -> H -> H & (T.Outcome & Out),slot:String,clauses:List<&2,Query.Clause>,result:Sys.RegistrationResult,Q.Error,List<&2,Out>,runner(~S,~C,~R,~E,~Ops,~A,~U,~Out,~query,~body)>) -> Defined,Sys.Registry,Q.Error,List<&2,Out>,runner(~S,~C,~R,~E,~Ops,~A,~U,~Out,~query,~body)>>: 51 match result: 52 case Sys.RegistrationFailed{world}:Rejected{world} 53 case Sys.Registered{world,registry}:Defined{world,Owner{registry,slot,clauses}} 54 # Register an ordinary query body with access derived from query clauses. 55 # Returns Defined with World/owner, or Rejected with World. Does not execute 56 # body or flush deferred commands. Schema/query/body indices must agree. 57 # Application starting point: examples/scheduled-health/registration.bend. 58 def define(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,~A:Data,~U:Data,~Out:Data,~query:Query.Declaration,Ops(Q.Frame)>,~body:@-H:Type -> @-caps:Ops(H) -> A -> H -> H & (T.Outcome & Out),world:W.World,name:String,slot:String) -> Defined,Sys.Registry,Q.Error,List<&2,Out>,runner(~S,~C,~R,~E,~Ops,~A,~U,~Out,~query,~body)>>: 59 registered(~S,~C,~R,~E,~Ops,~A,~U,~Out,~query,~body,slot,Query.clauses(~S,~Q.Frame,~Ops(Q.Frame),query),Sys.register(~S,~C,~R,~E,~(A & Maybe<&2,Tick.Tick>),~Q.Error,~List<&2,Out>,~runner(~S,~C,~R,~E,~Ops,~A,~U,~Out,~query,~body),world,name,access(~S,Query.clauses(~S,~Q.Frame,~Ops(Q.Frame),query)))) 60 def run_cursor(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,~A:Data,~U:Data,~Out:Data,~query:Query.Declaration,Ops(Q.Frame)>,~body:@-H:Type -> @-caps:Ops(H) -> A -> H -> H & (T.Outcome & Out),slot:String,clauses:List<&2,Query.Clause>,observed:Sys.Registry,Q.Error,List<&2,Out>,runner(~S,~C,~R,~E,~Ops,~A,~U,~Out,~query,~body)> & Maybe<&2,Tick.Tick>,world:W.World,args:A) -> Sys.RunResult,Q.Error,List<&2,Out>,runner(~S,~C,~R,~E,~Ops,~A,~U,~Out,~query,~body)> & (String & List<&2,Query.Clause>): 61 match observed: 62 case (registry,cursor):(Sys.run(~S,~C,~R,~E,~(A & Maybe<&2,Tick.Tick>),~Q.Error,~List<&2,Out>,~runner(~S,~C,~R,~E,~Ops,~A,~U,~Out,~query,~body),registry,world,(args,cursor)),(slot,clauses)) 63 # Execute the registered query using its retained lifecycle cursor. 64 # Returns System.RunResult plus retained slot/clauses; Registry is inside 65 # the RunResult and can be rewrapped as Owner. Success advances cursor to 66 # the captured execution tick; completed failure consumes it too. Row transaction 67 # rollback and deferred visibility follow Compose/explicit barriers. 68 def run(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,~A:Data,~U:Data,~Out:Data,~query:Query.Declaration,Ops(Q.Frame)>,~body:@-H:Type -> @-caps:Ops(H) -> A -> H -> H & (T.Outcome & Out),owner:Owner,Q.Error,List<&2,Out>,runner(~S,~C,~R,~E,~Ops,~A,~U,~Out,~query,~body)>>,world:W.World,args:A) -> Sys.RunResult,Q.Error,List<&2,Out>,runner(~S,~C,~R,~E,~Ops,~A,~U,~Out,~query,~body)> & (String & List<&2,Query.Clause>): 69 match owner: 70 case Owner{registry,slot,clauses}:run_cursor(~S,~C,~R,~E,~Ops,~A,~U,~Out,~query,~body,slot,clauses,Sys.cursor(~S,~C,~R,~E,~(A & Maybe<&2,Tick.Tick>),~Q.Error,~List<&2,Out>,~runner(~S,~C,~R,~E,~Ops,~A,~U,~Out,~query,~body),registry),world,args) 71 72 # The same ordinary declaration also retains detached inspection lowering. 73 # The Registry runner index retains this declaration; execution projects only 74 # its operational part. Runtime-bound registered inspection is supplied by 75 # the separate checked Inspector entry points, not this execution adapter. 76 # Lower only the operational half of an observable query declaration. 77 # Detached inspection remains separate; writes do not enter Inspector grants. 78 def observable_plan(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,~A:Data,~U:Data,~Out:Data,~V:Data,~query:O.Declaration,Ops(Q.Frame),I.Frame,V>,~body:@-H:Type -> @-caps:Ops(H) -> A -> H -> H & (T.Outcome & Out)) -> Q.Plan: 79 plan_parts(~S,~C,~R,~E,~Ops,O.operational(~S,~Q.Frame,~Ops(Q.Frame),~I.Frame,~V,query)) 80 # Lower-level observable-declaration query runner with explicit cursor. 81 # Executes operational grants in the Compose transaction; runtime registration 82 # validation belongs to observable_run or the derived App dispatch path. 83 def observable_runner(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,~A:Data,~U:Data,~Out:Data,~V:Data,~query:O.Declaration,Ops(Q.Frame),I.Frame,V>,~body:@-H:Type -> @-caps:Ops(H) -> A -> H -> H & (T.Outcome & Out),world:W.World,args:A & Maybe<&2,Tick.Tick>) -> Sys.Outcome,Q.Error,List<&2,Out>>: 84 match args: 85 case (args,cursor):completed(~S,~C,~R,~E,~U,~Out,Q.each_since(~S,~C,~R,~E,~Ops,~A,~U,~Out,~observable_plan(~S,~C,~R,~E,~Ops,~A,~U,~Out,~V,~query,~body),~body,args,world,cursor)) 86 def observable_registered(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,~A:Data,~U:Data,~Out:Data,~V:Data,~query:O.Declaration,Ops(Q.Frame),I.Frame,V>,~body:@-H:Type -> @-caps:Ops(H) -> A -> H -> H & (T.Outcome & Out),slot:String,clauses:List<&2,Query.Clause>,result:Sys.RegistrationResult,Q.Error,List<&2,Out>,observable_runner(~S,~C,~R,~E,~Ops,~A,~U,~Out,~V,~query,~body)>) -> Defined,Sys.Registry,Q.Error,List<&2,Out>,observable_runner(~S,~C,~R,~E,~Ops,~A,~U,~Out,~V,~query,~body)>>: 87 match result: 88 case Sys.RegistrationFailed{world}:Rejected{world} 89 case Sys.Registered{world,registry}:Defined{world,Owner{registry,slot,clauses}} 90 # Register from one observable declaration, deriving operational access 91 # and retaining its typed runner. Returns Defined or Rejected with World. 92 # Inspection is a separate read-only route; defining a system reads no rows. 93 def observable_define(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,~A:Data,~U:Data,~Out:Data,~V:Data,~query:O.Declaration,Ops(Q.Frame),I.Frame,V>,~body:@-H:Type -> @-caps:Ops(H) -> A -> H -> H & (T.Outcome & Out),world:W.World,name:String,slot:String) -> Defined,Sys.Registry,Q.Error,List<&2,Out>,observable_runner(~S,~C,~R,~E,~Ops,~A,~U,~Out,~V,~query,~body)>>: 94 observable_registered(~S,~C,~R,~E,~Ops,~A,~U,~Out,~V,~query,~body,slot,Query.clauses(~S,~Q.Frame,~Ops(Q.Frame),O.operational(~S,~Q.Frame,~Ops(Q.Frame),~I.Frame,~V,query)),Sys.register(~S,~C,~R,~E,~(A & Maybe<&2,Tick.Tick>),~Q.Error,~List<&2,Out>,~observable_runner(~S,~C,~R,~E,~Ops,~A,~U,~Out,~V,~query,~body),world,name,access(~S,Query.clauses(~S,~Q.Frame,~Ops(Q.Frame),O.operational(~S,~Q.Frame,~Ops(Q.Frame),~I.Frame,~V,query))))) 95 def observable_run_cursor(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,~A:Data,~U:Data,~Out:Data,~V:Data,~query:O.Declaration,Ops(Q.Frame),I.Frame,V>,~body:@-H:Type -> @-caps:Ops(H) -> A -> H -> H & (T.Outcome & Out),slot:String,clauses:List<&2,Query.Clause>,observed:Sys.Registry,Q.Error,List<&2,Out>,observable_runner(~S,~C,~R,~E,~Ops,~A,~U,~Out,~V,~query,~body)> & Maybe<&2,Tick.Tick>,world:W.World,args:A) -> Sys.RunResult,Q.Error,List<&2,Out>,observable_runner(~S,~C,~R,~E,~Ops,~A,~U,~Out,~V,~query,~body)> & (String & List<&2,Query.Clause>): 96 match observed: 97 case (registry,cursor):(Sys.run(~S,~C,~R,~E,~(A & Maybe<&2,Tick.Tick>),~Q.Error,~List<&2,Out>,~observable_runner(~S,~C,~R,~E,~Ops,~A,~U,~Out,~V,~query,~body),registry,world,(args,cursor)),(slot,clauses)) 98 # Execute the runtime-bound observable query system and retain Registry 99 # plus slot/clauses in the result. Uses its real cursor, advancing only on 100 # success. Registration refusal returns unconsumed (args,cursor) with World. 101 def observable_run(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,~A:Data,~U:Data,~Out:Data,~V:Data,~query:O.Declaration,Ops(Q.Frame),I.Frame,V>,~body:@-H:Type -> @-caps:Ops(H) -> A -> H -> H & (T.Outcome & Out),owner:Owner,Q.Error,List<&2,Out>,observable_runner(~S,~C,~R,~E,~Ops,~A,~U,~Out,~V,~query,~body)>>,world:W.World,args:A) -> Sys.RunResult,Q.Error,List<&2,Out>,observable_runner(~S,~C,~R,~E,~Ops,~A,~U,~Out,~V,~query,~body)> & (String & List<&2,Query.Clause>): 102 match owner: 103 case Owner{registry,slot,clauses}:observable_run_cursor(~S,~C,~R,~E,~Ops,~A,~U,~Out,~V,~query,~body,slot,clauses,Sys.cursor(~S,~C,~R,~E,~(A & Maybe<&2,Tick.Tick>),~Q.Error,~List<&2,Out>,~observable_runner(~S,~C,~R,~E,~Ops,~A,~U,~Out,~V,~query,~body),registry),world,args) 104 105 def completed_observed(~S:Data,~C:Type,~R:Type,~E:Data,~U:Data,~Out:Data,result:Q.Executed,Q.Error,Out> & TraceFacts.State) -> Sys.Outcome,Q.Error,List<&2,Out>> & TraceFacts.State: 106 match result: 107 case (executed,trace):(completed(~S,~C,~R,~E,~U,~Out,executed),trace) 108 109 # Trusted traced adapter for the same operational query/body and cursor. 110 # Returns runner outcome with actual transaction facts; does not register 111 # another system or consume detached Inspector visibility. 112 def observable_runner_observed(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,~A:Data,~U:Data,~Out:Data,~V:Data,~query:O.Declaration,Ops(Q.Frame),I.Frame,V>,~body:@-H:Type -> @-caps:Ops(H) -> A -> H -> H & (T.Outcome & Out),trace:TraceFacts.State,world:W.World,args:A & Maybe<&2,Tick.Tick>) -> Sys.Outcome,Q.Error,List<&2,Out>> & TraceFacts.State: 113 match args: 114 case (args,cursor):completed_observed(~S,~C,~R,~E,~U,~Out,Q.each_since_observed(~S,~C,~R,~E,~Ops,~A,~U,~Out,~observable_plan(~S,~C,~R,~E,~Ops,~A,~U,~Out,~V,~query,~body),~body,trace,args,world,cursor))