tigrbl-kernel 0.4.4.dev1__py3-none-any.whl → 0.4.4.dev8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
tigrbl_kernel/_compile.py CHANGED
@@ -5,7 +5,17 @@ from types import SimpleNamespace
5
5
  from typing import Any, Mapping
6
6
 
7
7
  from tigrbl_atoms import StepFn
8
- from tigrbl_core._spec.binding_spec import HttpRestBindingSpec
8
+ from tigrbl_core._spec.binding_spec import (
9
+ HttpJsonRpcProtocolBindingSpec,
10
+ HttpRestBindingSpec,
11
+ HttpRestProtocolBindingSpec,
12
+ WebSocketProtocolBindingSpec,
13
+ WebTransportProtocolBindingSpec,
14
+ derive_websocket_subprotocol_for_framing,
15
+ derive_session_metadata_for_framing,
16
+ framing_kind,
17
+ framing_spec_name,
18
+ )
9
19
  from tigrbl_core.config.constants import __JSONRPC_DEFAULT_ENDPOINT__
10
20
  from tigrbl_core._spec.op_spec import OpSpec
11
21
  from tigrbl_core._spec.well_known_spec import well_known_op_alias
@@ -28,6 +38,69 @@ from .utils import (
28
38
  DEFAULT_PHASE_ORDER = tuple(getattr(_ev, "PHASES", ())) or _DEFAULT_PHASE_ORDER
29
39
 
30
40
 
41
+ def _route_metadata_for_binding(binding: Any) -> dict[str, Any]:
42
+ framing_obj = getattr(binding, "framing", None)
43
+ framing = framing_kind(framing_obj)
44
+ metadata: dict[str, Any] = {
45
+ "framing": framing,
46
+ "framing_kind": framing,
47
+ "framing_spec": framing_spec_name(framing_obj),
48
+ }
49
+ proto = str(getattr(binding, "proto", "") or "")
50
+ if isinstance(binding, WebSocketProtocolBindingSpec):
51
+ derived_subprotocol = derive_websocket_subprotocol_for_framing(framing_obj)
52
+ if derived_subprotocol is not None:
53
+ metadata["websocket_subprotocol"] = derived_subprotocol
54
+ elif proto in {"ws", "wss"}:
55
+ metadata.update(
56
+ derive_session_metadata_for_framing(
57
+ binding_kind=proto,
58
+ framing=framing_obj,
59
+ subprotocols=tuple(getattr(binding, "subprotocols", ()) or ()),
60
+ )
61
+ )
62
+ if isinstance(binding, WebTransportProtocolBindingSpec):
63
+ if binding.control_stream is not None:
64
+ control = binding.control_stream
65
+ metadata["control_stream"] = {
66
+ "name": control.name,
67
+ "kind": control.kind,
68
+ "opens": control.opens,
69
+ "purpose": control.purpose,
70
+ "framing": framing_kind(control.framing),
71
+ "framing_spec": framing_spec_name(control.framing),
72
+ }
73
+ metadata["streams"] = tuple(
74
+ {
75
+ "name": stream.name,
76
+ "kind": stream.kind,
77
+ "purpose": stream.purpose,
78
+ "framing": framing_kind(stream.framing),
79
+ "framing_spec": framing_spec_name(stream.framing),
80
+ }
81
+ for stream in binding.streams
82
+ )
83
+ metadata["datagrams"] = tuple(
84
+ {
85
+ "name": datagram.name,
86
+ "purpose": datagram.purpose,
87
+ "framing": framing_kind(datagram.framing),
88
+ "framing_spec": framing_spec_name(datagram.framing),
89
+ }
90
+ for datagram in binding.datagrams
91
+ )
92
+ elif proto == "webtransport":
93
+ lane = getattr(binding, "lane", None) or getattr(binding, "profile", None)
94
+ inner_framing = getattr(binding, "inner_framing", None)
95
+ metadata["lane"] = lane
96
+ metadata["inner_framing"] = framing_kind(inner_framing)
97
+ metadata["inner_framing_spec"] = framing_spec_name(inner_framing)
98
+ if inner_framing is not None:
99
+ metadata["inner_framing_kind"] = str(inner_framing)
100
+ metadata["inner_framing_spec"] = framing_spec_name(inner_framing)
101
+ return metadata
102
+
103
+
31
104
  def _pathspec_iter(app: Any) -> tuple[Any, ...]:
32
105
  collected: list[Any] = []
33
106
  collected.extend(tuple(getattr(app, "_tigrbl_path_specs", ()) or ()))
@@ -133,9 +206,13 @@ def _compile_plan(self: Any, app: Any) -> KernelPlan:
133
206
  from tigrbl_core._spec.binding_spec import (
134
207
  HttpJsonRpcBindingSpec,
135
208
  HttpRestBindingSpec,
209
+ HttpJsonRpcProtocolBindingSpec,
210
+ HttpRestProtocolBindingSpec,
136
211
  HttpStreamBindingSpec,
137
212
  SseBindingSpec,
213
+ WebSocketProtocolBindingSpec,
138
214
  WebTransportBindingSpec,
215
+ WebTransportProtocolBindingSpec,
139
216
  WsBindingSpec,
140
217
  )
141
218
 
@@ -169,7 +246,12 @@ def _compile_plan(self: Any, app: Any) -> KernelPlan:
169
246
  for binding in getattr(sp, "bindings", ()) or ():
170
247
  if isinstance(
171
248
  binding,
172
- (HttpRestBindingSpec, HttpStreamBindingSpec, SseBindingSpec),
249
+ (
250
+ HttpRestBindingSpec,
251
+ HttpRestProtocolBindingSpec,
252
+ HttpStreamBindingSpec,
253
+ SseBindingSpec,
254
+ ),
173
255
  ):
174
256
  bucket = route_data.setdefault(
175
257
  binding.proto, {"exact": {}, "templated": []}
@@ -199,34 +281,53 @@ def _compile_plan(self: Any, app: Any) -> KernelPlan:
199
281
  meta_index
200
282
  )
201
283
 
202
- elif isinstance(binding, HttpJsonRpcBindingSpec):
203
- endpoint = str(
204
- getattr(binding, "endpoint", __JSONRPC_DEFAULT_ENDPOINT__)
284
+ elif isinstance(binding, (HttpJsonRpcBindingSpec, HttpJsonRpcProtocolBindingSpec)):
285
+ rpc_path = str(
286
+ getattr(
287
+ binding,
288
+ "path",
289
+ getattr(binding, "endpoint", __JSONRPC_DEFAULT_ENDPOINT__),
290
+ )
205
291
  or __JSONRPC_DEFAULT_ENDPOINT__
206
292
  )
207
- selector = f"{endpoint}:{binding.rpc_method}"
293
+ rpc_method = getattr(
294
+ binding,
295
+ "method",
296
+ getattr(binding, "rpc_method", None),
297
+ )
298
+ selector = f"{rpc_path}:{rpc_method}"
208
299
  opkey_to_meta[OpKey(proto=binding.proto, selector=selector)] = (
209
300
  meta_index
210
301
  )
211
302
  proto_bucket = route_data.setdefault(
212
- binding.proto, {"endpoints": {}}
213
- )
214
- endpoint_bucket = proto_bucket.setdefault("endpoints", {}).setdefault(
215
- endpoint, {}
303
+ binding.proto, {"paths": {}, "endpoints": {}}
216
304
  )
217
- proto_bucket[binding.rpc_method] = meta_index
218
- endpoint_bucket[binding.rpc_method] = {
305
+ path_bucket = proto_bucket.setdefault("paths", {}).setdefault(rpc_path, {})
306
+ endpoint_bucket = proto_bucket.setdefault("endpoints", {}).setdefault(rpc_path, {})
307
+ proto_bucket[rpc_method] = meta_index
308
+ row = {
219
309
  "meta_index": meta_index,
220
310
  "selector": selector,
221
- "rpc_method": binding.rpc_method,
222
- "endpoint": endpoint,
311
+ "method": rpc_method,
312
+ "path": rpc_path,
223
313
  }
314
+ path_bucket[rpc_method] = row
315
+ endpoint_bucket[rpc_method] = row
224
316
 
225
- elif isinstance(binding, (WsBindingSpec, WebTransportBindingSpec)):
317
+ elif isinstance(
318
+ binding,
319
+ (
320
+ WsBindingSpec,
321
+ WebSocketProtocolBindingSpec,
322
+ WebTransportBindingSpec,
323
+ WebTransportProtocolBindingSpec,
324
+ ),
325
+ ):
226
326
  bucket = route_data.setdefault(
227
327
  binding.proto, {"exact": {}, "templated": []}
228
328
  )
229
329
  selector = binding.path
330
+ route_metadata = _route_metadata_for_binding(binding)
230
331
  opkey_to_meta[OpKey(proto=binding.proto, selector=selector)] = (
231
332
  meta_index
232
333
  )
@@ -240,13 +341,17 @@ def _compile_plan(self: Any, app: Any) -> KernelPlan:
240
341
  "names": names,
241
342
  "meta_index": meta_index,
242
343
  "selector": selector,
243
- "subprotocols": tuple(
244
- getattr(binding, "subprotocols", ()) or ()
245
- ),
344
+ **route_metadata,
246
345
  }
247
346
  )
248
347
  else:
249
348
  bucket["exact"][selector] = meta_index
349
+ bucket.setdefault("exact_metadata", {})[selector] = {
350
+ "path": binding.path,
351
+ "meta_index": meta_index,
352
+ "selector": selector,
353
+ **route_metadata,
354
+ }
250
355
 
251
356
  semantic = KernelPlan(
252
357
  proto_indices=route_data,
@@ -61,6 +61,9 @@ CANONICAL_CONTRACT_EVENTS: tuple[str, ...] = (
61
61
  "webtransport.stream.stop_sending",
62
62
  "webtransport.datagram.receive",
63
63
  "webtransport.datagram.send",
64
+ "stream.resume.request",
65
+ "stream.resume.accept",
66
+ "stream.resume.reject",
64
67
  "webtransport.disconnect",
65
68
  "webtransport.close",
66
69
  "transport.emit.complete",
@@ -71,6 +74,7 @@ _EVENT_SCOPE_PREFIXES: dict[str, str] = {
71
74
  "http.": "http",
72
75
  "websocket.": "websocket",
73
76
  "webtransport.": "webtransport",
77
+ "stream.resume.": "webtransport",
74
78
  "transport.emit.": "webtransport",
75
79
  }
76
80
 
tigrbl_kernel/core.py CHANGED
@@ -24,7 +24,6 @@ from .cache import _SpecsOnceCache, _WeakMaybeDict
24
24
  from .models import KernelPlan, OpView
25
25
  from .opview_compiler import compile_opview_from_specs
26
26
  from .types import DEFAULT_PHASE_ORDER as _DEFAULT_PHASE_ORDER
27
- from .rust_compile import build_rust_kernel as _build_rust_kernel
28
27
  from .utils import (
29
28
  _opspecs,
30
29
  _table_iter,
@@ -155,9 +154,6 @@ class Kernel:
155
154
  return payload
156
155
  return {}
157
156
 
158
- def compile_rust_plan(self, app: Any):
159
- return _build_rust_kernel(app)
160
-
161
157
  def invalidate_kernelz_payload(self, app: Optional[Any] = None) -> None:
162
158
  with self._lock:
163
159
  if app is None:
@@ -27,7 +27,7 @@ TRANSPORT_ENVELOPE_KEYS = frozenset(
27
27
  class EquivalenceCase:
28
28
  op_id: str
29
29
  category: str
30
- bindings: tuple[Mapping[str, Any], ...]
30
+ bindings: tuple[Any, ...]
31
31
 
32
32
 
33
33
  def canonical_operation_id(op_id: str) -> str:
@@ -42,7 +42,7 @@ def canonical_operation_id(op_id: str) -> str:
42
42
 
43
43
  def compile_equivalence_manifest(
44
44
  op_id: str,
45
- bindings: Iterable[Mapping[str, Any]],
45
+ bindings: Iterable[Any],
46
46
  *,
47
47
  schema_identity: str = "schema:v1",
48
48
  runtime_plan_identity: str = "runtime-plan:v1",
@@ -80,7 +80,7 @@ def equivalent_transport_results(*results: Mapping[str, Any]) -> bool:
80
80
  return all(normalized_transport_result(result) == first for result in results[1:])
81
81
 
82
82
 
83
- def equivalent_binding_group(op_id: str, bindings: Iterable[Mapping[str, Any]]) -> bool:
83
+ def equivalent_binding_group(op_id: str, bindings: Iterable[Any]) -> bool:
84
84
  manifest = compile_equivalence_manifest(op_id, bindings)
85
85
  families = {binding["family"] for binding in manifest["bindings"]}
86
86
  return bool(families) and len({manifest["op_id"]}) == 1
@@ -1,7 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from typing import Any
4
- import warnings
5
4
 
6
5
 
7
6
  def canonical_protocol_anchor_order(
@@ -32,18 +31,7 @@ def python_protocol_anchor_trace(case: dict[str, Any]) -> tuple[str, ...]:
32
31
  )
33
32
 
34
33
 
35
- def rust_protocol_anchor_trace(case: dict[str, Any]) -> tuple[str, ...]:
36
- del case
37
- warnings.warn(
38
- "rust_protocol_anchor_trace is deprecated; protocol anchors are Python-only.",
39
- DeprecationWarning,
40
- stacklevel=2,
41
- )
42
- raise RuntimeError("rust_protocol_anchor_trace is unavailable.")
43
-
44
-
45
34
  __all__ = [
46
35
  "canonical_protocol_anchor_order",
47
36
  "python_protocol_anchor_trace",
48
- "rust_protocol_anchor_trace",
49
37
  ]
@@ -4,6 +4,16 @@ from collections.abc import Mapping
4
4
  from typing import Any
5
5
 
6
6
  from tigrbl_core._spec.binding_spec import (
7
+ BytesFramingSpec,
8
+ derive_websocket_subprotocol_for_framing,
9
+ framing_spec_name,
10
+ framing_kind as framing_spec_kind,
11
+ framing_spec_from_kind,
12
+ JsonFramingSpec,
13
+ JsonRpcFramingSpec,
14
+ normalize_framing_spec,
15
+ SseFramingSpec,
16
+ TextFramingSpec,
7
17
  validate_app_framing_for_binding,
8
18
  validate_binding_profile_exchange,
9
19
  validate_webtransport_inner_framing,
@@ -18,30 +28,61 @@ def _unsupported(message: str) -> ValueError:
18
28
  return ValueError(f"binding protocol unsupported before runtime: {message}")
19
29
 
20
30
 
21
- def compile_binding_protocol_plan(op_id: str, binding: Mapping[str, Any]) -> dict[str, object]:
22
- kind = binding.get("kind") or binding.get("proto")
31
+ def _binding_get(binding: Any, key: str, default: Any = None) -> Any:
32
+ if isinstance(binding, Mapping):
33
+ return binding.get(key, default)
34
+ return getattr(binding, key, default)
35
+
36
+
37
+ def _lane_mapping(value: Any, *, lane_kind: str | None = None) -> dict[str, Any]:
38
+ if isinstance(value, Mapping):
39
+ return dict(value)
40
+ row: dict[str, Any] = {}
41
+ for key in ("name", "kind", "opens", "purpose", "framing"):
42
+ item = getattr(value, key, None)
43
+ if item is not None:
44
+ row[key] = item
45
+ if lane_kind is not None:
46
+ row.setdefault("kind", lane_kind)
47
+ return row
48
+
49
+
50
+ def compile_binding_protocol_plan(op_id: str, binding: Any) -> dict[str, object]:
51
+ kind = _binding_get(binding, "kind") or _binding_get(binding, "proto")
23
52
  if not kind:
24
53
  raise ValueError(
25
54
  "BindingSpec binding source is required; transport guessing is ambiguous"
26
55
  )
27
56
 
28
57
  kind = str(kind)
29
- profile = binding.get("profile")
58
+ profile = _binding_get(binding, "profile")
30
59
  if kind in {"http", "https"} and profile:
31
60
  kind = f"{kind}.{profile}"
32
61
  elif kind == "websocket":
33
- kind = str(binding.get("proto") or "ws")
34
- framing = binding.get("framing")
62
+ kind = str(_binding_get(binding, "proto") or "ws")
63
+ framing = _binding_get(binding, "framing")
64
+ framing_kind = ""
65
+ framing_spec = ""
66
+ subprotocols: tuple[str, ...] = ()
67
+ inner_framing: str | None = None
35
68
  rows: tuple[dict[str, str], ...]
69
+ rpc_path: str | None = None
70
+ rpc_method: str | None = None
36
71
 
37
72
  if kind in {"http.rest", "https.rest"}:
38
73
  validate_binding_profile_exchange(
39
74
  binding_kind=kind,
40
- exchange=str(binding.get("exchange") or "request_response"),
75
+ exchange=str(_binding_get(binding, "exchange") or "request_response"),
41
76
  )
42
- validate_app_framing_for_binding(binding_kind=kind, framing=str(framing or "json"))
77
+ framing_spec_obj = normalize_framing_spec(
78
+ framing_spec_from_kind(framing),
79
+ default=JsonFramingSpec(),
80
+ )
81
+ validate_app_framing_for_binding(binding_kind=kind, framing=framing_spec_obj)
43
82
  family = "request"
44
- framing = "json"
83
+ framing = framing_spec_obj.kind
84
+ framing_kind = framing
85
+ framing_spec = framing_spec_obj.__class__.__name__
45
86
  anchors = (
46
87
  "ingress.receive",
47
88
  "dispatch.subevent.derive",
@@ -53,15 +94,27 @@ def compile_binding_protocol_plan(op_id: str, binding: Mapping[str, Any]) -> dic
53
94
  {"family": "request", "subevent": "response.emit"},
54
95
  )
55
96
  elif kind in {"http.jsonrpc", "https.jsonrpc"}:
56
- if not binding.get("rpc_method"):
57
- raise _unsupported("http.jsonrpc requires rpc_method")
97
+ rpc_method = _binding_get(binding, "method") or _binding_get(binding, "rpc_method")
98
+ if not rpc_method:
99
+ raise _unsupported("http.jsonrpc requires method")
100
+ rpc_method = str(rpc_method)
101
+ rpc_path = str(
102
+ _binding_get(binding, "path", _binding_get(binding, "endpoint", "/rpc"))
103
+ or "/rpc"
104
+ )
58
105
  validate_binding_profile_exchange(
59
106
  binding_kind=kind,
60
- exchange=str(binding.get("exchange") or "request_response"),
107
+ exchange=str(_binding_get(binding, "exchange") or "request_response"),
108
+ )
109
+ framing_spec_obj = normalize_framing_spec(
110
+ framing_spec_from_kind(framing),
111
+ default=JsonRpcFramingSpec(),
61
112
  )
62
- validate_app_framing_for_binding(binding_kind=kind, framing=str(framing or "jsonrpc"))
113
+ validate_app_framing_for_binding(binding_kind=kind, framing=framing_spec_obj)
63
114
  family = "request"
64
- framing = "jsonrpc"
115
+ framing = framing_spec_obj.kind
116
+ framing_kind = framing
117
+ framing_spec = framing_spec_obj.__class__.__name__
65
118
  anchors = (
66
119
  "framing.decode",
67
120
  "dispatch.subevent.derive",
@@ -75,11 +128,17 @@ def compile_binding_protocol_plan(op_id: str, binding: Mapping[str, Any]) -> dic
75
128
  elif kind in {"http.stream", "https.stream"}:
76
129
  exchange = validate_binding_profile_exchange(
77
130
  binding_kind=kind,
78
- exchange=str(binding.get("exchange") or "server_stream"),
131
+ exchange=str(_binding_get(binding, "exchange") or "server_stream"),
79
132
  )
80
- validate_app_framing_for_binding(binding_kind=kind, framing=str(framing or "stream"))
133
+ framing_spec_obj = normalize_framing_spec(
134
+ framing_spec_from_kind(framing),
135
+ default=BytesFramingSpec(),
136
+ )
137
+ validate_app_framing_for_binding(binding_kind=kind, framing=framing_spec_obj)
81
138
  family = "stream"
82
- framing = str(framing or "stream")
139
+ framing = framing_spec_obj.kind
140
+ framing_kind = framing
141
+ framing_spec = framing_spec_obj.__class__.__name__
83
142
  if exchange == "client_stream":
84
143
  anchors = (
85
144
  "transport.receive",
@@ -100,11 +159,17 @@ def compile_binding_protocol_plan(op_id: str, binding: Mapping[str, Any]) -> dic
100
159
  elif kind in {"http.sse", "https.sse"}:
101
160
  validate_binding_profile_exchange(
102
161
  binding_kind=kind,
103
- exchange=str(binding.get("exchange") or "server_stream"),
162
+ exchange=str(_binding_get(binding, "exchange") or "server_stream"),
163
+ )
164
+ framing_spec_obj = normalize_framing_spec(
165
+ framing_spec_from_kind(framing),
166
+ default=SseFramingSpec(),
104
167
  )
105
- validate_app_framing_for_binding(binding_kind=kind, framing=str(framing or "sse"))
168
+ validate_app_framing_for_binding(binding_kind=kind, framing=framing_spec_obj)
106
169
  family = "stream"
107
- framing = "sse"
170
+ framing = framing_spec_obj.kind
171
+ framing_kind = framing
172
+ framing_spec = framing_spec_obj.__class__.__name__
108
173
  anchors = (
109
174
  "framing.encode",
110
175
  "handler.invoke",
@@ -117,18 +182,25 @@ def compile_binding_protocol_plan(op_id: str, binding: Mapping[str, Any]) -> dic
117
182
  {"family": "stream", "subevent": "stream.close"},
118
183
  )
119
184
  elif kind in {"ws", "wss", "websocket"}:
120
- if binding.get("methods"):
185
+ if _binding_get(binding, "methods"):
121
186
  raise _unsupported("websocket bindings do not accept HTTP methods")
122
187
  family = "message"
123
- framing = str(framing or "text")
124
- subprotocols = tuple(str(item).lower() for item in binding.get("subprotocols", ()))
188
+ framing_spec_obj = normalize_framing_spec(
189
+ framing_spec_from_kind(framing),
190
+ default=TextFramingSpec(),
191
+ )
192
+ framing = framing_spec_obj.kind
193
+ framing_kind = framing
194
+ framing_spec = framing_spec_obj.__class__.__name__
195
+ subprotocols = tuple(str(item).lower() for item in (_binding_get(binding, "subprotocols", ()) or ()))
196
+ websocket_subprotocol = derive_websocket_subprotocol_for_framing(framing_spec_obj)
125
197
  validate_binding_profile_exchange(
126
198
  binding_kind="wss" if kind == "wss" else "ws",
127
- exchange=str(binding.get("exchange") or "bidirectional_stream"),
199
+ exchange=str(_binding_get(binding, "exchange") or "bidirectional_stream"),
128
200
  )
129
201
  validate_app_framing_for_binding(
130
202
  binding_kind="wss" if kind == "wss" else "ws",
131
- framing=framing,
203
+ framing=framing_spec_obj,
132
204
  subprotocols=subprotocols,
133
205
  )
134
206
  anchors = (
@@ -144,31 +216,65 @@ def compile_binding_protocol_plan(op_id: str, binding: Mapping[str, Any]) -> dic
144
216
  {"family": "session", "subevent": "session.close"},
145
217
  )
146
218
  elif kind == "webtransport":
147
- if binding.get("exchange") == "request_response":
219
+ if _binding_get(binding, "exchange") == "request_response":
148
220
  raise _unsupported("webtransport request_response exchange")
149
- validate_app_framing_for_binding(binding_kind=kind, framing=str(framing or "webtransport"))
150
- if framing and str(framing) != "webtransport":
151
- raise _unsupported("webtransport outer framing must remain webtransport")
152
- lane = webtransport_lane_for_profile(
153
- binding.get("lane") or binding.get("profile") or "webtransport"
154
- )
155
- validate_webtransport_lane_exchange(
156
- lane=lane,
157
- exchange=str(binding.get("exchange") or {
158
- "session": "bidirectional_stream",
159
- "bidi_stream": "bidirectional_stream",
160
- "unidi_client_stream": "client_stream",
161
- "unidi_server_stream": "server_stream",
162
- "datagram": "bidirectional_stream",
163
- }[lane]),
164
- )
165
- inner_framing = validate_webtransport_inner_framing(
166
- lane=lane,
167
- inner_framing=binding.get("inner_framing"),
168
- )
169
- family = webtransport_runtime_family(lane)
170
- framing = "webtransport"
171
- if lane == "session":
221
+ if framing is not None:
222
+ raise _unsupported("webtransport bindings do not accept top-level app framing")
223
+ framing_kind = ""
224
+ framing_spec = ""
225
+ control_stream = _binding_get(binding, "control_stream")
226
+ streams = tuple(_binding_get(binding, "streams", ()) or ())
227
+ datagrams = tuple(_binding_get(binding, "datagrams", ()) or ())
228
+ if control_stream is not None or streams or datagrams:
229
+ control = None
230
+ if control_stream is not None:
231
+ control = _lane_mapping(control_stream, lane_kind="bidi_stream")
232
+ if control.get("kind") != "bidi_stream":
233
+ raise _unsupported("webtransport control_stream must use bidi_stream")
234
+ if control.get("opens") != "first":
235
+ raise _unsupported("webtransport control_stream must open first")
236
+ control_framing = validate_webtransport_inner_framing(
237
+ lane="bidi_stream",
238
+ inner_framing=framing_spec_from_kind(control.get("framing")),
239
+ )
240
+ control["framing"] = framing_spec_kind(control_framing)
241
+ control["framing_spec"] = framing_spec_name(control_framing)
242
+ stream_rows = []
243
+ datagram_rows = []
244
+ names: list[str] = []
245
+ for stream in streams:
246
+ row = _lane_mapping(stream)
247
+ name = str(row.get("name") or "")
248
+ if not name:
249
+ raise _unsupported("webtransport streams require name")
250
+ names.append(name)
251
+ lane_kind = str(row.get("kind") or "")
252
+ stream_framing = validate_webtransport_inner_framing(
253
+ lane=lane_kind,
254
+ inner_framing=framing_spec_from_kind(row.get("framing")),
255
+ )
256
+ row["framing"] = framing_spec_kind(stream_framing)
257
+ row["framing_spec"] = framing_spec_name(stream_framing)
258
+ stream_rows.append(row)
259
+ for datagram in datagrams:
260
+ row = _lane_mapping(datagram)
261
+ name = str(row.get("name") or "")
262
+ if not name:
263
+ raise _unsupported("webtransport datagrams require name")
264
+ names.append(name)
265
+ datagram_framing = validate_webtransport_inner_framing(
266
+ lane="datagram",
267
+ inner_framing=framing_spec_from_kind(row.get("framing")),
268
+ )
269
+ row["framing"] = framing_spec_kind(datagram_framing)
270
+ row["framing_spec"] = framing_spec_name(datagram_framing)
271
+ datagram_rows.append(row)
272
+ if len(set(names)) != len(names):
273
+ raise _unsupported("webtransport lane names must be unique")
274
+ family = "session"
275
+ lane = "session"
276
+ inner_framing = None
277
+ framing = ""
172
278
  anchors = (
173
279
  "transport.accept",
174
280
  "dispatch.subevent.derive",
@@ -179,68 +285,107 @@ def compile_binding_protocol_plan(op_id: str, binding: Mapping[str, Any]) -> dic
179
285
  {"family": "session", "subevent": "session.open"},
180
286
  {"family": "session", "subevent": "session.close"},
181
287
  )
182
- elif lane == "bidi_stream":
183
- anchors = (
184
- "transport.accept",
185
- "transport.receive",
186
- "framing.decode",
187
- "dispatch.subevent.derive",
188
- "handler.invoke",
189
- "framing.encode",
190
- "transport.emit",
191
- "transport.close",
192
- )
193
- rows = (
194
- {"family": "stream", "subevent": "stream.open"},
195
- {"family": "stream", "subevent": "stream.chunk.received"},
196
- {"family": "stream", "subevent": "stream.chunk.emit"},
197
- {"family": "stream", "subevent": "stream.close"},
198
- )
199
- elif lane == "unidi_client_stream":
200
- anchors = (
201
- "transport.accept",
202
- "transport.receive",
203
- "framing.decode",
204
- "dispatch.subevent.derive",
205
- "handler.invoke",
206
- "transport.close",
207
- )
208
- rows = (
209
- {"family": "stream", "subevent": "stream.open"},
210
- {"family": "stream", "subevent": "stream.chunk.received"},
211
- {"family": "stream", "subevent": "stream.close"},
212
- )
213
- elif lane == "unidi_server_stream":
214
- anchors = (
215
- "transport.accept",
216
- "handler.invoke",
217
- "framing.encode",
218
- "transport.emit",
219
- "transport.close",
220
- )
221
- rows = (
222
- {"family": "stream", "subevent": "stream.open"},
223
- {"family": "stream", "subevent": "stream.chunk.emit"},
224
- {"family": "stream", "subevent": "stream.emit_complete"},
225
- {"family": "stream", "subevent": "stream.close"},
288
+ lane_catalog = {
289
+ "control_stream": control,
290
+ "streams": tuple(stream_rows),
291
+ "datagrams": tuple(datagram_rows),
292
+ }
293
+ else:
294
+ lane_catalog = None
295
+ lane = webtransport_lane_for_profile(
296
+ _binding_get(binding, "lane") or _binding_get(binding, "profile") or "webtransport"
226
297
  )
227
- elif lane == "datagram":
228
- anchors = (
229
- "transport.accept",
230
- "transport.receive",
231
- "framing.decode",
232
- "dispatch.subevent.derive",
233
- "handler.invoke",
234
- "framing.encode",
235
- "transport.emit",
298
+ validate_webtransport_lane_exchange(
299
+ lane=lane,
300
+ exchange=str(_binding_get(binding, "exchange") or {
301
+ "session": "bidirectional_stream",
302
+ "bidi_stream": "bidirectional_stream",
303
+ "unidi_client_stream": "client_stream",
304
+ "unidi_server_stream": "server_stream",
305
+ "datagram": "bidirectional_stream",
306
+ }[lane]),
236
307
  )
237
- rows = (
238
- {"family": "datagram", "subevent": "datagram.received"},
239
- {"family": "datagram", "subevent": "datagram.emit"},
240
- {"family": "datagram", "subevent": "datagram.emit_complete"},
308
+ inner_framing = validate_webtransport_inner_framing(
309
+ lane=lane,
310
+ inner_framing=framing_spec_from_kind(_binding_get(binding, "inner_framing")),
241
311
  )
242
- else: # pragma: no cover - guarded by webtransport_lane_for_profile
243
- raise _unsupported(f"webtransport lane {lane}")
312
+ family = webtransport_runtime_family(lane)
313
+ framing = framing_spec_kind(inner_framing)
314
+ framing_kind = framing
315
+ framing_spec = framing_spec_name(inner_framing)
316
+ if lane == "session":
317
+ anchors = (
318
+ "transport.accept",
319
+ "dispatch.subevent.derive",
320
+ "handler.invoke",
321
+ "transport.close",
322
+ )
323
+ rows = (
324
+ {"family": "session", "subevent": "session.open"},
325
+ {"family": "session", "subevent": "session.close"},
326
+ )
327
+ elif lane == "bidi_stream":
328
+ anchors = (
329
+ "transport.accept",
330
+ "transport.receive",
331
+ "framing.decode",
332
+ "dispatch.subevent.derive",
333
+ "handler.invoke",
334
+ "framing.encode",
335
+ "transport.emit",
336
+ "transport.close",
337
+ )
338
+ rows = (
339
+ {"family": "stream", "subevent": "stream.open"},
340
+ {"family": "stream", "subevent": "stream.chunk.received"},
341
+ {"family": "stream", "subevent": "stream.chunk.emit"},
342
+ {"family": "stream", "subevent": "stream.close"},
343
+ )
344
+ elif lane == "unidi_client_stream":
345
+ anchors = (
346
+ "transport.accept",
347
+ "transport.receive",
348
+ "framing.decode",
349
+ "dispatch.subevent.derive",
350
+ "handler.invoke",
351
+ "transport.close",
352
+ )
353
+ rows = (
354
+ {"family": "stream", "subevent": "stream.open"},
355
+ {"family": "stream", "subevent": "stream.chunk.received"},
356
+ {"family": "stream", "subevent": "stream.close"},
357
+ )
358
+ elif lane == "unidi_server_stream":
359
+ anchors = (
360
+ "transport.accept",
361
+ "handler.invoke",
362
+ "framing.encode",
363
+ "transport.emit",
364
+ "transport.close",
365
+ )
366
+ rows = (
367
+ {"family": "stream", "subevent": "stream.open"},
368
+ {"family": "stream", "subevent": "stream.chunk.emit"},
369
+ {"family": "stream", "subevent": "stream.emit_complete"},
370
+ {"family": "stream", "subevent": "stream.close"},
371
+ )
372
+ elif lane == "datagram":
373
+ anchors = (
374
+ "transport.accept",
375
+ "transport.receive",
376
+ "framing.decode",
377
+ "dispatch.subevent.derive",
378
+ "handler.invoke",
379
+ "framing.encode",
380
+ "transport.emit",
381
+ )
382
+ rows = (
383
+ {"family": "datagram", "subevent": "datagram.received"},
384
+ {"family": "datagram", "subevent": "datagram.emit"},
385
+ {"family": "datagram", "subevent": "datagram.emit_complete"},
386
+ )
387
+ else: # pragma: no cover - guarded by webtransport_lane_for_profile
388
+ raise _unsupported(f"webtransport lane {lane}")
244
389
  else:
245
390
  raise _unsupported(kind)
246
391
 
@@ -249,10 +394,21 @@ def compile_binding_protocol_plan(op_id: str, binding: Mapping[str, Any]) -> dic
249
394
  "binding": kind,
250
395
  "framing": framing,
251
396
  }
397
+ if subprotocols:
398
+ event_key_inputs["subprotocols"] = subprotocols
399
+ if kind in {"http.jsonrpc", "https.jsonrpc"}:
400
+ event_key_inputs["path"] = rpc_path
401
+ event_key_inputs["method"] = rpc_method
402
+ if kind in {"ws", "wss", "websocket"} and websocket_subprotocol is not None:
403
+ event_key_inputs["websocket_subprotocol"] = websocket_subprotocol
252
404
  if kind == "webtransport":
253
405
  event_key_inputs["lane"] = lane
254
- event_key_inputs["inner_framing"] = inner_framing
255
- resume_policy = compile_resume_policy(kind, binding)
406
+ if lane_catalog is not None:
407
+ event_key_inputs["lane_catalog"] = lane_catalog
408
+ else:
409
+ event_key_inputs["inner_framing"] = framing_spec_kind(inner_framing)
410
+ event_key_inputs["inner_framing_spec"] = framing_spec_name(inner_framing)
411
+ resume_policy = compile_resume_policy(kind, binding if isinstance(binding, Mapping) else {})
256
412
  if resume_policy.enabled:
257
413
  event_key_inputs["resume_mode"] = resume_policy.mode
258
414
 
@@ -261,6 +417,8 @@ def compile_binding_protocol_plan(op_id: str, binding: Mapping[str, Any]) -> dic
261
417
  "binding_kind": kind,
262
418
  "family": family,
263
419
  "framing": framing,
420
+ "framing_kind": framing_kind or str(framing),
421
+ "framing_spec": framing_spec,
264
422
  "atom_anchors": anchors,
265
423
  "event_key_inputs": event_key_inputs,
266
424
  "capability_requirements": {
@@ -268,6 +426,20 @@ def compile_binding_protocol_plan(op_id: str, binding: Mapping[str, Any]) -> dic
268
426
  },
269
427
  "lifecycle_rows": rows,
270
428
  }
429
+ if subprotocols:
430
+ plan["subprotocols"] = subprotocols
431
+ if kind in {"http.jsonrpc", "https.jsonrpc"}:
432
+ plan["path"] = rpc_path
433
+ plan["method"] = rpc_method
434
+ if kind in {"ws", "wss", "websocket"} and websocket_subprotocol is not None:
435
+ plan["websocket_subprotocol"] = websocket_subprotocol
436
+ if kind == "webtransport":
437
+ if lane_catalog is not None:
438
+ plan["lane_catalog"] = lane_catalog
439
+ else:
440
+ plan["inner_framing"] = framing_spec_kind(inner_framing)
441
+ plan["inner_framing_kind"] = framing_spec_kind(inner_framing)
442
+ plan["inner_framing_spec"] = framing_spec_name(inner_framing)
271
443
  if resume_policy.enabled:
272
444
  plan["resume_policy"] = resume_policy.as_dict()
273
445
  return plan
tigrbl_kernel/types.py CHANGED
@@ -41,6 +41,10 @@ EFFECT_BY_ATOM_NAME = {
41
41
  "sys.handler_append_chunk": EFFECT_WIRE,
42
42
  "sys.handler_send_datagram": EFFECT_WIRE,
43
43
  "sys.handler_checkpoint": EFFECT_WIRE,
44
+ "sys.handler_open_bidi_stream": EFFECT_WIRE,
45
+ "sys.handler_open_unidi_stream": EFFECT_WIRE,
46
+ "sys.handler_close_stream": EFFECT_WIRE,
47
+ "sys.handler_close_session": EFFECT_WIRE,
44
48
  "egress.to_transport_response": EFFECT_WIRE,
45
49
  "egress.asgi_send": EFFECT_WIRE,
46
50
  }
tigrbl_kernel/utils.py CHANGED
@@ -161,8 +161,8 @@ def _route_payload_template() -> dict[str, Any]:
161
161
  return {
162
162
  "http.rest": {"exact": {}, "templated": []},
163
163
  "https.rest": {"exact": {}, "templated": []},
164
- "http.jsonrpc": {"endpoints": {}},
165
- "https.jsonrpc": {"endpoints": {}},
164
+ "http.jsonrpc": {"paths": {}, "endpoints": {}},
165
+ "https.jsonrpc": {"paths": {}, "endpoints": {}},
166
166
  "ws": {"exact": {}, "templated": []},
167
167
  "wss": {"exact": {}, "templated": []},
168
168
  }
@@ -3,7 +3,10 @@ from __future__ import annotations
3
3
  from collections.abc import Sequence
4
4
  from typing import Any
5
5
 
6
- from tigrbl_core._spec.binding_spec import validate_webtransport_inner_framing
6
+ from tigrbl_core._spec.binding_spec import (
7
+ framing_spec_from_kind,
8
+ validate_webtransport_inner_framing,
9
+ )
7
10
 
8
11
 
9
12
  def _event(subevent: str, atom: str, family: str) -> dict[str, str]:
@@ -194,7 +197,7 @@ def _validate_stream_payload(
194
197
  raise ValueError("client_to_server unidirectional streams cannot be send events")
195
198
  validate_webtransport_inner_framing(
196
199
  lane=lane,
197
- inner_framing=payload.get("framing"),
200
+ inner_framing=framing_spec_from_kind(payload.get("framing")),
198
201
  )
199
202
  projection = {
200
203
  "family": "stream",
@@ -228,7 +231,7 @@ def _validate_datagram_payload(
228
231
  _forbid(payload, "stream_id", "stream_direction", "stream_initiator", "lane_id")
229
232
  validate_webtransport_inner_framing(
230
233
  lane="datagram",
231
- inner_framing=payload.get("framing"),
234
+ inner_framing=framing_spec_from_kind(payload.get("framing")),
232
235
  )
233
236
  return {"family": "datagram", "lane": "datagram", "exchange": "bidirectional_stream"}
234
237
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tigrbl-kernel
3
- Version: 0.4.4.dev1
3
+ Version: 0.4.4.dev8
4
4
  Summary: Kernel orchestration for composing Tigrbl runtime plans, bindings, operation dispatch, and optimized ASGI execution.
5
5
  License: Apache License
6
6
  Version 2.0, January 2004
@@ -318,7 +318,6 @@ Package catalog:
318
318
  - `tigrbl_kernel/protocol_bindings.py`, `tigrbl_kernel/protocol_phase_tree.py`, `tigrbl_kernel/protocol_chains/`, `tigrbl_kernel/protocol_completion.py`, `tigrbl_kernel/protocol_fusion.py`, and `tigrbl_kernel/protocol_legality_matrix.py`: transport-specific plan compilation, phase tree construction, chain definitions, completion semantics, fusion, and legality checks.
319
319
  - `tigrbl_kernel/eventkey.py`, `tigrbl_kernel/events.py`, `tigrbl_kernel/transport_events.py`, `tigrbl_kernel/webtransport_events.py`, `tigrbl_kernel/subevent_taxonomy.py`, and `tigrbl_kernel/subevent_handlers.py`: event-key construction, subevent taxonomy, and protocol subevent handler mapping.
320
320
  - `tigrbl_kernel/opchannel_capabilities.py`, `tigrbl_kernel/loop_modes.py`, `tigrbl_kernel/loop_regions.py`, `tigrbl_kernel/segment_fusion.py`, and `tigrbl_kernel/contract_classification.py`: channel capability checks, loop planning, segment grouping, and contract classification.
321
- - `tigrbl_kernel/rust_plan.py`, `tigrbl_kernel/rust_compile.py`, and `tigrbl_kernel/rust_spec.py`: deprecated compatibility shims; kernel planning is Python-only.
322
321
 
323
322
  ## Public API and Import Surface
324
323
 
@@ -354,9 +353,9 @@ Protocol planning keeps binding kind, family, framing, exchange, lane, subevent
354
353
  | `http.stream` / `https.stream` | stream | stream | handler invoke, transport emit, stream close. |
355
354
  | `http.sse` / `https.sse` | stream | SSE | encode event, emit event, close stream. |
356
355
  | `ws` / `wss` / `websocket` | message | text or negotiated JSON-RPC | accept, decode, dispatch, handler, emit/close. |
357
- | `webtransport` | session, stream, or datagram | WebTransport outer framing | lane-specific session, stream, or datagram rows with inner-framing validation. |
356
+ | `webtransport` | session, stream, or datagram | no top-level app framing | lane-specific session, stream, or datagram rows with lane-local framing validation. |
358
357
 
359
- Unsupported or ambiguous bindings raise planning errors. For example, WebSocket bindings do not accept HTTP methods, HTTP JSON-RPC requires an RPC method, WebTransport request/response exchange is unsupported, and WebTransport outer framing must remain `webtransport`.
358
+ Unsupported or ambiguous bindings raise planning errors. For example, WebSocket bindings do not accept HTTP methods, HTTP JSON-RPC requires an RPC method, WebTransport request/response exchange is unsupported, and WebTransport app framing must be declared on the relevant control stream, stream, or datagram lane.
360
359
 
361
360
  ## Hook Ordering and Labels
362
361
 
@@ -1,13 +1,13 @@
1
1
  tigrbl_kernel/__init__.py,sha256=fE63Iyq2XrWqFTsvSC28iomE5nW6HsDUOEoQQtPNZ0I,2233
2
2
  tigrbl_kernel/_build.py,sha256=kHaS9k4cD5hg1eRj8aQnbPbUkTbOM8npE_yeOsiwUK8,50397
3
- tigrbl_kernel/_compile.py,sha256=D8Vohdh3ryhdC9--yBIeKNxbkqpqzJZlmW2dbbkbmyE,11054
3
+ tigrbl_kernel/_compile.py,sha256=g1_TP-wMp-O2qLjWkBupXHJ_cAFjeoldXl9L2hDF_gw,15248
4
4
  tigrbl_kernel/atoms.py,sha256=ZNGj2PBUMu1BvPjNYlz4_vu4vhx4gD20C7zNE_GKfe8,12253
5
5
  tigrbl_kernel/cache.py,sha256=NxuqvH03xYwcQoY86ie1hmtDeA36XdiLmNyx2ImLQ6k,2596
6
6
  tigrbl_kernel/callbacks.py,sha256=r_ZI19nbAoDM-uf-FMUmWWAF9WaEKJK3Fpg-58ui8a4,772
7
7
  tigrbl_kernel/channel_taxonomy.py,sha256=x_cZHXz_Bw6NGaTK3YdZGUrzH1nBVAMlzViGKiv2K6s,4330
8
- tigrbl_kernel/contract_classification.py,sha256=5ZbhtJr88VtIPAtPWD5eL4BKKQU734kZeMEvEqh9cvU,6009
9
- tigrbl_kernel/core.py,sha256=3lR3VrlHOFiP-POLluEpBKWeGDdaqX8tJYHQ0eRluP0,6667
10
- tigrbl_kernel/cross_transport.py,sha256=Dk01IRjQ6LVvPeRRxB5r6UXwqzOsSl_mJh1gjoh61jk,5396
8
+ tigrbl_kernel/contract_classification.py,sha256=Qfrn_aDPlCKvJGmAgdu0CuL-bZINW553TqD411rew4E,6132
9
+ tigrbl_kernel/core.py,sha256=7xa4zhMxth7MGzgXnxxnHumchVKcyYHBf5mWNfMk4_M,6518
10
+ tigrbl_kernel/cross_transport.py,sha256=24A4Hm-E6czX7o09EgwqL3WzGQtvifwnXMPB-ztZZzs,5354
11
11
  tigrbl_kernel/dispatch_taxonomy.py,sha256=lj-_4hVKzrlPkavAlNqu7eImhjJn-7QoyccquQylCn0,1658
12
12
  tigrbl_kernel/eventkey.py,sha256=aTwzBkAjeC-kaEUItL1Mcfcq_Ur1fUbZDY6XxKdwWdg,1980
13
13
  tigrbl_kernel/eventkey_hooks.py,sha256=Cbkev0GXgSH27dlFoVeaKC7XuQ9yJq4bI1Mlc3qB4Qs,2480
@@ -26,8 +26,8 @@ tigrbl_kernel/ordering.py,sha256=C6fHkAwQA_1AY7sEAUy_FC5U3eFmsyqcls1li1qG5MA,135
26
26
  tigrbl_kernel/packed_access.py,sha256=KhvAt-X4_bsowYVQ47tWEIfQhpcvTmPG7BqzuEWF87U,3587
27
27
  tigrbl_kernel/packed_selectors.py,sha256=ZgPvOTUsTSF_ZIpQHM3acQhdIbM0-c6lBW7WjdAROI4,8609
28
28
  tigrbl_kernel/payload.py,sha256=eyHo-cAUXLWQQ9-xZVOl_rjFudA-djMZji9hoK-v9IE,2167
29
- tigrbl_kernel/protocol_anchors.py,sha256=4yGS_66x-VEdoq6aFg6UM2qBP7Lz7cLfjLq2O_NdysI,1232
30
- tigrbl_kernel/protocol_bindings.py,sha256=mRf4X-9jKcnAPm__IsE3LdNiHxYeWLDtaJViVq8lIXs,10784
29
+ tigrbl_kernel/protocol_anchors.py,sha256=0jAXmSQ-OD3AGv7MM-2vF7hQmZtHG2bXwFM1ooi0Geg,863
30
+ tigrbl_kernel/protocol_bindings.py,sha256=oE50T0YIEDAPXqxpXnmSAmJWX_SbSPdXBL8FtFF7OgI,18760
31
31
  tigrbl_kernel/protocol_chains/__init__.py,sha256=iSnOw5R4ahGypm59bQgPpsBwFXbPcnKPozjSfc9N6GQ,151
32
32
  tigrbl_kernel/protocol_chains/http_stream.py,sha256=nop3qMn-zpS5yK9QjqrFA68e1lO-uOb0dWAZf5fPrBg,2427
33
33
  tigrbl_kernel/protocol_chains/http_unary.py,sha256=7EABv0bUAJ5UI3TWP-S-8LtgwZJLj5pw-ZnZ_8qiD4g,1776
@@ -42,9 +42,6 @@ tigrbl_kernel/protocol_phase_tree.py,sha256=LhJdoKfQivKHSDu75KYoq1VoYYkbXaekuN32
42
42
  tigrbl_kernel/protocol_streams.py,sha256=UUCNn3L5n9PkgSydI4LGzJXFAKT1D9GPPnq6-xbMnBI,17141
43
43
  tigrbl_kernel/resume_policy.py,sha256=rHBySvRJKfJ4J2NCb1D49FAXUsSp9rpzg4ev7ewXrSk,2931
44
44
  tigrbl_kernel/runtime_contracts.py,sha256=I13L8mWQyYeojll9U2IbPFqZlvcv3MpCU376iNO4RbA,8243
45
- tigrbl_kernel/rust_compile.py,sha256=dB36g6w1PCh1sOubd7XKUaJlGyrFC4hr__4PfJfnZiE,608
46
- tigrbl_kernel/rust_plan.py,sha256=N-YZ6oGRtIJKuxS5f7HwhTldrTnozLXWgfpOD2XDGjI,502
47
- tigrbl_kernel/rust_spec.py,sha256=cMzlYsUwVcJLcIJAbX5gcCnRzhqrJZyeYb5whn_gIBU,853
48
45
  tigrbl_kernel/segment_fusion.py,sha256=zbPNGd1eFJGFZHJxrfanaNMyrJjJw1aPRsl_jJfN4sM,1607
49
46
  tigrbl_kernel/subevent_handlers.py,sha256=4j4780QjQiqY4qpRsyxrPh_znRK3SkLAFDN_x6eidwU,1779
50
47
  tigrbl_kernel/subevent_taxonomy.py,sha256=67RJ7ZkfJMLfa7evzVfTlFqtdWSnhp65zwA4qhNwSG8,2274
@@ -52,11 +49,11 @@ tigrbl_kernel/trace.py,sha256=dWILtq9seOj-WwCx__Pk_VZAbFIN1tqTbs0gIndYkU8,9816
52
49
  tigrbl_kernel/transaction_units.py,sha256=_NeQHycjjDoLG1kmD74o10wDQpdA5qjs-Sd_fxPb0_E,863
53
50
  tigrbl_kernel/transport_atoms.py,sha256=enfNCMuLgLMKi8zraMm-QOk7ys5d9kcP-WPr0-wK6KE,2136
54
51
  tigrbl_kernel/transport_events.py,sha256=CyPhs69H7mnKU7gNgt4XtH-eRJcihSaXxQDzC0iD4w4,3903
55
- tigrbl_kernel/types.py,sha256=p5AU0BGfvhDQxNHn8T5TY62V4iBCL8PKKjL4iy908w0,2241
56
- tigrbl_kernel/utils.py,sha256=iCcm0flQfAi4w4cbVEaq6yiPR-kAoXx2owiRpbBf-0o,6953
57
- tigrbl_kernel/webtransport_events.py,sha256=iLWkM0sef48osaIAJ34KfV9ZEkDkUWWR5DwowyA5XFI,10735
58
- tigrbl_kernel-0.4.4.dev1.dist-info/METADATA,sha256=q3uqIOQ9sVgK3eLA8pZFT6LviXPCwIqPjT27B96rmIM,28075
59
- tigrbl_kernel-0.4.4.dev1.dist-info/WHEEL,sha256=eY7nduwzv-ldUxpzbRlxwvC693Hg6PX8bWDjEHjZ_dk,88
60
- tigrbl_kernel-0.4.4.dev1.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
61
- tigrbl_kernel-0.4.4.dev1.dist-info/licenses/NOTICE,sha256=EvJMTshzsWz43LiK-DeN2ZuLtrP49cxvlrFlJ8F_buc,221
62
- tigrbl_kernel-0.4.4.dev1.dist-info/RECORD,,
52
+ tigrbl_kernel/types.py,sha256=Pf2e6xvZAcxD_uJZ7inMETpmhNyz4YGT27YuWdSHZ-I,2431
53
+ tigrbl_kernel/utils.py,sha256=xf4lZAIH64DhpdHHyzPJ0LSAiUKWSaC5wIL1NJkHVro,6979
54
+ tigrbl_kernel/webtransport_events.py,sha256=SWADw4m2JsCHHvMfH7QcVPtjOZ0kfjiCwwoiLhCokmk,10820
55
+ tigrbl_kernel-0.4.4.dev8.dist-info/METADATA,sha256=dpEAt_8EUxxhZj_2Y1zIB4XoWkpWsxSV0zIUHoTFbwM,27960
56
+ tigrbl_kernel-0.4.4.dev8.dist-info/WHEEL,sha256=eY7nduwzv-ldUxpzbRlxwvC693Hg6PX8bWDjEHjZ_dk,88
57
+ tigrbl_kernel-0.4.4.dev8.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
58
+ tigrbl_kernel-0.4.4.dev8.dist-info/licenses/NOTICE,sha256=EvJMTshzsWz43LiK-DeN2ZuLtrP49cxvlrFlJ8F_buc,221
59
+ tigrbl_kernel-0.4.4.dev8.dist-info/RECORD,,
@@ -1,24 +0,0 @@
1
- from __future__ import annotations
2
- from typing import Any
3
-
4
- from .rust_plan import RustPlan
5
- import warnings
6
-
7
-
8
- def _raise_deprecated(action: str) -> None:
9
- warnings.warn(
10
- "tigrbl_kernel Rust planning is deprecated; kernel planning is Python-only.",
11
- DeprecationWarning,
12
- stacklevel=3,
13
- )
14
- raise RuntimeError(f"{action} is unavailable; Tigrbl kernel planning is Python-only.")
15
-
16
-
17
- def build_rust_kernel(app: Any) -> RustPlan:
18
- del app
19
- _raise_deprecated("build_rust_kernel")
20
-
21
-
22
- def normalize_rust_spec(app: Any) -> str:
23
- del app
24
- _raise_deprecated("normalize_rust_spec")
@@ -1,20 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from dataclasses import dataclass
4
- from typing import Any
5
- import warnings
6
-
7
-
8
- @dataclass(slots=True)
9
- class RustPlan:
10
- description: str
11
- compiled_plan: dict[str, Any] | None = None
12
- backend: str = "deprecated-rust"
13
- normalized_spec: str | None = None
14
-
15
- def __post_init__(self) -> None:
16
- warnings.warn(
17
- "RustPlan is deprecated; Tigrbl kernel planning is Python-only.",
18
- DeprecationWarning,
19
- stacklevel=2,
20
- )
@@ -1,36 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import warnings
4
- from typing import Any, NoReturn
5
-
6
-
7
- def _raise_deprecated(action: str) -> NoReturn:
8
- warnings.warn(
9
- "tigrbl_kernel Rust spec serialization is deprecated; "
10
- "Tigrbl runtime execution is Python-only.",
11
- DeprecationWarning,
12
- stacklevel=3,
13
- )
14
- raise RuntimeError(f"{action} is unavailable; Tigrbl runtime execution is Python-only.")
15
-
16
-
17
- def build_rust_app_spec(app: Any) -> dict[str, Any]:
18
- del app
19
- _raise_deprecated("build_rust_app_spec")
20
-
21
-
22
- def coerce_rust_spec_dict(app: Any) -> dict[str, Any]:
23
- del app
24
- _raise_deprecated("coerce_rust_spec_dict")
25
-
26
-
27
- def coerce_rust_spec_json(app: Any) -> str:
28
- del app
29
- _raise_deprecated("coerce_rust_spec_json")
30
-
31
-
32
- __all__ = [
33
- "build_rust_app_spec",
34
- "coerce_rust_spec_dict",
35
- "coerce_rust_spec_json",
36
- ]