clm-kernel 0.0.0__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.
Files changed (333) hide show
  1. clm/__init__.py +230 -0
  2. clm/__main__.py +25 -0
  3. clm/cross_cutting/__init__.py +50 -0
  4. clm/cross_cutting/_test_runner.py +36 -0
  5. clm/cross_cutting/async_utils.py +25 -0
  6. clm/cross_cutting/cel_builder.py +123 -0
  7. clm/cross_cutting/cel_converter.py +697 -0
  8. clm/cross_cutting/cel_engine.py +252 -0
  9. clm/cross_cutting/cel_ops.py +72 -0
  10. clm/cross_cutting/cel_ops_db.py +157 -0
  11. clm/cross_cutting/cel_ops_files.py +99 -0
  12. clm/cross_cutting/cel_ops_state.py +71 -0
  13. clm/cross_cutting/cel_ops_strings.py +64 -0
  14. clm/cross_cutting/cel_resolver.py +63 -0
  15. clm/cross_cutting/cel_slices.py +56 -0
  16. clm/cross_cutting/cel_store.py +330 -0
  17. clm/cross_cutting/clm_logger.py +140 -0
  18. clm/cross_cutting/config/__init__.py +155 -0
  19. clm/cross_cutting/config/config_constants.py +392 -0
  20. clm/cross_cutting/config/env_parameters.py +90 -0
  21. clm/cross_cutting/config/logging.py +378 -0
  22. clm/cross_cutting/config/settings.py +504 -0
  23. clm/cross_cutting/context.py +5 -0
  24. clm/cross_cutting/domain_models.py +55 -0
  25. clm/cross_cutting/domain_types.py +61 -0
  26. clm/cross_cutting/effects.py +67 -0
  27. clm/cross_cutting/errors.py +153 -0
  28. clm/cross_cutting/governance.py +331 -0
  29. clm/cross_cutting/guards.py +41 -0
  30. clm/cross_cutting/mcard.py +321 -0
  31. clm/cross_cutting/native.py +185 -0
  32. clm/cross_cutting/observability.py +289 -0
  33. clm/cross_cutting/pcard.py +434 -0
  34. clm/cross_cutting/registry.py +71 -0
  35. clm/cross_cutting/resources.py +84 -0
  36. clm/cross_cutting/secrets.py +44 -0
  37. clm/cross_cutting/subprocess_utils.py +118 -0
  38. clm/cross_cutting/telemetry.py +164 -0
  39. clm/cross_cutting/testing/__init__.py +8 -0
  40. clm/cross_cutting/testing/comparator.py +187 -0
  41. clm/cross_cutting/testing/datasets.py +87 -0
  42. clm/cross_cutting/timeutil.py +20 -0
  43. clm/cross_cutting/types/new_type_check.py +0 -0
  44. clm/cross_cutting/utils/__init__.py +1 -0
  45. clm/cross_cutting/utils/url_safety.py +50 -0
  46. clm/cross_cutting/vcard.py +560 -0
  47. clm/cross_cutting/writer.py +118 -0
  48. clm/layer0/README.md +50 -0
  49. clm/layer0/__init__.py +223 -0
  50. clm/layer0/algebra.py +60 -0
  51. clm/layer0/algebra_baldwin.py +133 -0
  52. clm/layer0/algebra_baldwin_generators.py +36 -0
  53. clm/layer0/algebra_equivalence.py +262 -0
  54. clm/layer0/algebra_ingest.py +306 -0
  55. clm/layer0/algebra_manifest_io.py +156 -0
  56. clm/layer0/assembler.py +481 -0
  57. clm/layer0/cel/__init__.py +23 -0
  58. clm/layer0/cel_eval.py +491 -0
  59. clm/layer0/codec.py +106 -0
  60. clm/layer0/context.py +122 -0
  61. clm/layer0/db.py +160 -0
  62. clm/layer0/exceptions.py +73 -0
  63. clm/layer0/fibration.py +106 -0
  64. clm/layer0/gates.py +50 -0
  65. clm/layer0/hash.py +80 -0
  66. clm/layer0/loader.py +826 -0
  67. clm/layer0/math_utils.py +163 -0
  68. clm/layer0/mcard.py +96 -0
  69. clm/layer0/model/__init__.py +0 -0
  70. clm/layer0/model/action.py +223 -0
  71. clm/layer0/model/card.py +280 -0
  72. clm/layer0/model/card_triad.py +427 -0
  73. clm/layer0/model/compatibility.py +60 -0
  74. clm/layer0/model/dictionary.py +46 -0
  75. clm/layer0/model/dots.py +331 -0
  76. clm/layer0/model/event_producer.py +88 -0
  77. clm/layer0/model/g_time.py +89 -0
  78. clm/layer0/model/handle.py +163 -0
  79. clm/layer0/model/hash/__init__.py +6 -0
  80. clm/layer0/model/hash/algorithms/__init__.py +3 -0
  81. clm/layer0/model/hash/algorithms/custom_hash.py +7 -0
  82. clm/layer0/model/hash/algorithms/local_sha256.py +178 -0
  83. clm/layer0/model/hash/constants.py +53 -0
  84. clm/layer0/model/hash/enums.py +60 -0
  85. clm/layer0/model/hash/validator.py +307 -0
  86. clm/layer0/model/interpreter.py +275 -0
  87. clm/layer0/model/pagination.py +45 -0
  88. clm/layer0/model/pcard.py +716 -0
  89. clm/layer0/model/schema.py +44 -0
  90. clm/layer0/model/utils/__init__.py +1 -0
  91. clm/layer0/model/utils/content_analyzer.py +152 -0
  92. clm/layer0/model/validators/__init__.py +1 -0
  93. clm/layer0/model/validators/base_validator.py +44 -0
  94. clm/layer0/model/validators/binary_validator.py +66 -0
  95. clm/layer0/model/validators/text_validator.py +82 -0
  96. clm/layer0/model/validators/validation_registry.py +49 -0
  97. clm/layer0/model/vcard.py +823 -0
  98. clm/layer0/model/vcard_ext/__init__.py +39 -0
  99. clm/layer0/model/vcard_ext/core.py +60 -0
  100. clm/layer0/model/vcard_ext/network.py +23 -0
  101. clm/layer0/model/vcard_ext/observability.py +63 -0
  102. clm/layer0/model/vcard_ext/storage.py +60 -0
  103. clm/layer0/model/vcard_ext/vendors.py +211 -0
  104. clm/layer0/model/vcard_sandwich.py +119 -0
  105. clm/layer0/model/vcard_vocabulary.py +463 -0
  106. clm/layer0/model/workflow.py +274 -0
  107. clm/layer0/narrative.py +431 -0
  108. clm/layer0/ontology/collection.py +125 -0
  109. clm/layer0/parser.py +429 -0
  110. clm/layer0/relations.py +73 -0
  111. clm/layer0/rule_evaluator.py +251 -0
  112. clm/layer0/schema/__init__.py +38 -0
  113. clm/layer0/schema/ddl.py +97 -0
  114. clm/layer0/templates/abstract.yaml +99 -0
  115. clm/layer0/templates/balanced.yaml +253 -0
  116. clm/layer0/templates/concrete.yaml +172 -0
  117. clm/layer0/type_registry.py +223 -0
  118. clm/layer0/types.py +204 -0
  119. clm/layer0/utils.py +886 -0
  120. clm/layer0/verifier_core.py +262 -0
  121. clm/layer1/__init__.py +31 -0
  122. clm/layer1/action_dispatcher.py +275 -0
  123. clm/layer1/adapter_registry.py +233 -0
  124. clm/layer1/algebra_baldwin_generators.py +192 -0
  125. clm/layer1/arrow_compiler.py +525 -0
  126. clm/layer1/batch_processor.py +152 -0
  127. clm/layer1/cel/__init__.py +27 -0
  128. clm/layer1/cel/builder.py +173 -0
  129. clm/layer1/engine.py +759 -0
  130. clm/layer1/engine_async.py +89 -0
  131. clm/layer1/eval_callback.py +49 -0
  132. clm/layer1/gate_composer.py +229 -0
  133. clm/layer1/hoare_sandwich.py +298 -0
  134. clm/layer1/identity_guard.py +348 -0
  135. clm/layer1/matrix.py +138 -0
  136. clm/layer1/neural_runtime.py +221 -0
  137. clm/layer1/operations/__init__.py +123 -0
  138. clm/layer1/operations/augment.py +156 -0
  139. clm/layer1/operations/base.py +109 -0
  140. clm/layer1/operations/builtins.py +338 -0
  141. clm/layer1/operations/dispatch.py +144 -0
  142. clm/layer1/operations/exclude.py +107 -0
  143. clm/layer1/operations/handle.py +197 -0
  144. clm/layer1/operations/identity.py +139 -0
  145. clm/layer1/operations/invert.py +66 -0
  146. clm/layer1/operations/loader.py +116 -0
  147. clm/layer1/operations/manipulators/__init__.py +23 -0
  148. clm/layer1/operations/manipulators/document.py +211 -0
  149. clm/layer1/operations/manipulators/media.py +134 -0
  150. clm/layer1/operations/manipulators/structured.py +159 -0
  151. clm/layer1/operations/manipulators/tabular.py +334 -0
  152. clm/layer1/operations/port.py +65 -0
  153. clm/layer1/operations/services.py +529 -0
  154. clm/layer1/operations/split.py +117 -0
  155. clm/layer1/operations/substitute.py +75 -0
  156. clm/layer1/petri.py +1052 -0
  157. clm/layer1/pocketflow_orchestrator.py +408 -0
  158. clm/layer1/pocketflow_scheduler.py +519 -0
  159. clm/layer1/protocols.py +197 -0
  160. clm/layer1/runtime_adapter.py +718 -0
  161. clm/layer1/runtimes/__init__.py +71 -0
  162. clm/layer1/runtimes/_generated_assertions.py +125 -0
  163. clm/layer1/runtimes/_generated_types.py +42 -0
  164. clm/layer1/runtimes/base.py +265 -0
  165. clm/layer1/runtimes/binary.py +101 -0
  166. clm/layer1/runtimes/factory.py +203 -0
  167. clm/layer1/runtimes/javascript.py +321 -0
  168. clm/layer1/runtimes/javascript_runtime.js +33 -0
  169. clm/layer1/runtimes/js_scripts/isomorphism.mjs +22 -0
  170. clm/layer1/runtimes/js_scripts/loader.mjs +52 -0
  171. clm/layer1/runtimes/lambda_calc.py +126 -0
  172. clm/layer1/runtimes/python.py +288 -0
  173. clm/layer1/runtimes/python_runtime.py +41 -0
  174. clm/layer1/runtimes/script.py +114 -0
  175. clm/layer1/sandbox.py +334 -0
  176. clm/layer1/savepoint_guard.py +136 -0
  177. clm/layer1/sparse_net.py +122 -0
  178. clm/layer1/spec_tester.py +165 -0
  179. clm/layer1/store.py +295 -0
  180. clm/layer1/test_runner.py +498 -0
  181. clm/layer1/type_inspector.py +166 -0
  182. clm/layer1/verifier.py +772 -0
  183. clm/layer1/vm.py +91 -0
  184. clm/layer2/__init__.py +78 -0
  185. clm/layer2/card_collection.py +678 -0
  186. clm/layer2/classifier.py +479 -0
  187. clm/layer2/engine/__init__.py +1 -0
  188. clm/layer2/engine/abstract_sql_engine.py +320 -0
  189. clm/layer2/engine/base.py +193 -0
  190. clm/layer2/engine/duckdb_engine.py +576 -0
  191. clm/layer2/engine/sqlite_engine.py +518 -0
  192. clm/layer2/fiber/__init__.py +31 -0
  193. clm/layer2/fiber/context.py +89 -0
  194. clm/layer2/fiber/disposable.py +163 -0
  195. clm/layer2/fiber/fiber.py +125 -0
  196. clm/layer2/fiber/hoare.py +191 -0
  197. clm/layer2/file_io.py +376 -0
  198. clm/layer2/file_registrar.py +77 -0
  199. clm/layer2/ingest.py +202 -0
  200. clm/layer2/lineage.py +322 -0
  201. clm/layer2/mcard_fs.py +262 -0
  202. clm/layer2/merkle.py +11 -0
  203. clm/layer2/mime.py +244 -0
  204. clm/layer2/mime_detector.py +245 -0
  205. clm/layer2/private_collection.py +118 -0
  206. clm/layer2/shared_store.py +11 -0
  207. clm/layer2/storage/__init__.py +190 -0
  208. clm/layer2/storage/db_bitemporal.py +141 -0
  209. clm/layer2/storage/db_driver.py +331 -0
  210. clm/layer2/storage/db_hyperlinks.py +214 -0
  211. clm/layer2/storage/db_pool.py +139 -0
  212. clm/layer2/storage/db_repository.py +229 -0
  213. clm/layer2/storage/savepoint.py +78 -0
  214. clm/layer2/storage/sqlite_wal.py +74 -0
  215. clm/layer2/tridb.py +245 -0
  216. clm/layer2/vcard_receipt.py +71 -0
  217. clm/layer2/vfs.py +17 -0
  218. clm/layer3/__init__.py +141 -0
  219. clm/layer3/agency/__init__.py +19 -0
  220. clm/layer3/agency/config.py +220 -0
  221. clm/layer3/agency/providers/__init__.py +15 -0
  222. clm/layer3/agency/providers/base.py +91 -0
  223. clm/layer3/agency/providers/mlc_llm.py +169 -0
  224. clm/layer3/agency/providers/ollama.py +203 -0
  225. clm/layer3/agency/router.py +71 -0
  226. clm/layer3/agency/runtime.py +524 -0
  227. clm/layer3/gateway.py +353 -0
  228. clm/layer3/open_interpreter_adapter.py +159 -0
  229. clm/layer3/rag/__init__.py +70 -0
  230. clm/layer3/rag/cli.py +228 -0
  231. clm/layer3/rag/config.py +153 -0
  232. clm/layer3/rag/embeddings/__init__.py +16 -0
  233. clm/layer3/rag/embeddings/base.py +79 -0
  234. clm/layer3/rag/embeddings/ollama.py +211 -0
  235. clm/layer3/rag/embeddings/vision.py +290 -0
  236. clm/layer3/rag/engine.py +276 -0
  237. clm/layer3/rag/graph/__init__.py +22 -0
  238. clm/layer3/rag/graph/community.py +198 -0
  239. clm/layer3/rag/graph/engine.py +433 -0
  240. clm/layer3/rag/graph/extractor.py +255 -0
  241. clm/layer3/rag/graph/schema.py +115 -0
  242. clm/layer3/rag/graph/store.py +641 -0
  243. clm/layer3/rag/indexer.py +333 -0
  244. clm/layer3/rag/llm_providers.json +52 -0
  245. clm/layer3/rag/semantic_versioning.py +313 -0
  246. clm/layer3/rag/vector/__init__.py +28 -0
  247. clm/layer3/rag/vector/handle_vector_store.py +749 -0
  248. clm/layer3/rag/vector/schema.py +151 -0
  249. clm/layer3/rag/vector/store.py +632 -0
  250. clm/layer3/reticulum/__init__.py +55 -0
  251. clm/layer3/reticulum/bridge.py +74 -0
  252. clm/layer3/reticulum/daemon.py +88 -0
  253. clm/layer3/reticulum/discovery.py +164 -0
  254. clm/layer3/reticulum/identity.py +107 -0
  255. clm/layer3/reticulum/media.py +148 -0
  256. clm/layer3/reticulum/transport.py +133 -0
  257. clm/layer3/satori/__init__.py +209 -0
  258. clm/layer3/satori/alpha_conversion.py +168 -0
  259. clm/layer3/satori/beta_reduction.py +359 -0
  260. clm/layer3/satori/continuation.py +38 -0
  261. clm/layer3/satori/eta_conversion.py +205 -0
  262. clm/layer3/satori/free_variables.py +163 -0
  263. clm/layer3/satori/io_effects.py +370 -0
  264. clm/layer3/satori/lambda_runtime.py +726 -0
  265. clm/layer3/satori/lambda_term.py +230 -0
  266. clm/layer3/satori/sheaf_audit.py +261 -0
  267. clm/layer3/satori/speech_act.py +279 -0
  268. clm/layer4/README.md +9 -0
  269. clm/layer4/__init__.py +67 -0
  270. clm/layer4/_sovereign_executor.py +580 -0
  271. clm/layer4/action_commands.py +719 -0
  272. clm/layer4/api.py +236 -0
  273. clm/layer4/bootstrap/__init__.py +13 -0
  274. clm/layer4/bootstrap/bootstrapper.py +118 -0
  275. clm/layer4/bootstrap/cleanup.py +44 -0
  276. clm/layer4/bootstrap/clm_hooks.py +49 -0
  277. clm/layer4/bootstrap/genesis.py +77 -0
  278. clm/layer4/bootstrap/injection.py +125 -0
  279. clm/layer4/cli.py +549 -0
  280. clm/layer4/collection_manager.py +553 -0
  281. clm/layer4/commands/__init__.py +81 -0
  282. clm/layer4/commands/action_cmd.py +42 -0
  283. clm/layer4/commands/check_cmd.py +82 -0
  284. clm/layer4/commands/envelope.py +73 -0
  285. clm/layer4/commands/evaluate_cmd.py +224 -0
  286. clm/layer4/commands/mcard_cmd.py +24 -0
  287. clm/layer4/commands/petri_cmd.py +92 -0
  288. clm/layer4/commands/tridb_cmd.py +319 -0
  289. clm/layer4/commands/version_cmd.py +27 -0
  290. clm/layer4/diff_commands.py +167 -0
  291. clm/layer4/eoa_sponsor.py +232 -0
  292. clm/layer4/events.py +69 -0
  293. clm/layer4/flux_gateway.py +133 -0
  294. clm/layer4/gateway.py +91 -0
  295. clm/layer4/loader.py +307 -0
  296. clm/layer4/mcard_commands.py +166 -0
  297. clm/layer4/membrane.py +273 -0
  298. clm/layer4/navigation.py +50 -0
  299. clm/layer4/protocol/protocol_entry_python.py +108 -0
  300. clm/layer4/protocol/python_sync.py +126 -0
  301. clm/layer4/runner.py +150 -0
  302. clm/layer4/satori.py +262 -0
  303. clm/layer4/server/python_sync_client.py +150 -0
  304. clm/layer4/server/python_sync_server.py +139 -0
  305. clm/layer4/server/service_api.py +315 -0
  306. clm/layer4/server/start_servers.py +107 -0
  307. clm/layer4/server/stop_servers.py +24 -0
  308. clm/layer4/simulated_optimization_fix.py +0 -0
  309. clm/layer4/storage.py +463 -0
  310. clm/layer4/tridb_admin.py +268 -0
  311. clm/layer4/websocket/test_ws_client.py +104 -0
  312. clm/layer4/websocket/test_ws_server.py +138 -0
  313. clm/layer4/websocket/ws_server_local.py +160 -0
  314. clm/layer5/__init__.py +51 -0
  315. clm/layer5/async_batch_writer.py +133 -0
  316. clm/layer5/learning.py +276 -0
  317. clm/layer5/telemetry_hook.py +107 -0
  318. clm/layer5/type_lattice.py +238 -0
  319. clm/py.typed +0 -0
  320. clm/schemas/__init__.py +652 -0
  321. clm/schemas/abstract_face_schema.yaml +77 -0
  322. clm/schemas/cel_schema.yaml +416 -0
  323. clm/schemas/lifecycle/__init__.py +45 -0
  324. clm/schemas/lifecycle/models.py +123 -0
  325. clm/schemas/lifecycle/service.py +364 -0
  326. clm/schemas/mcard_schema.sql +192 -0
  327. clm/schemas/mcard_vector_schema.sql +283 -0
  328. clm/schemas/mlp-context-v1.json +91 -0
  329. clm_kernel-0.0.0.dist-info/METADATA +121 -0
  330. clm_kernel-0.0.0.dist-info/RECORD +333 -0
  331. clm_kernel-0.0.0.dist-info/WHEEL +4 -0
  332. clm_kernel-0.0.0.dist-info/entry_points.txt +3 -0
  333. clm_kernel-0.0.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,525 @@
1
+ """
2
+ Layer 1: Arrow to Colored Petri Net (CPN) Compiler (DV-373-01).
3
+
4
+ Compiles Arrow combinators (arr, >>>, first, ***, &&&) into bipartite Colored
5
+ Petri Net topologies operating under the 4-phase PTR lifecycle:
6
+ prep (P_in -> P_pre) -> exec (P_pre -> P_exec) -> post (P_exec -> P_post) -> seal (P_post -> P_out)
7
+
8
+ Satisfies:
9
+ - INV-REF-01: Headless Kernel Purity (no browser/DOM imports)
10
+ - INV-REF-02: Single Implementation Home (lives in clm/layer1)
11
+ - Noetherian conservation invariants (x^T · D = 0)
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import json
17
+ import uuid
18
+ from collections.abc import Callable
19
+ from dataclasses import dataclass, field
20
+ from typing import Any
21
+
22
+
23
+ @dataclass
24
+ class VCardGuard:
25
+ """Represents a pre- or post-condition guard for an Arrow."""
26
+
27
+ name: str
28
+ predicate: Callable[[Any], bool]
29
+ error_message: str = "VCard guard condition not satisfied"
30
+
31
+ def check(self, val: Any) -> bool:
32
+ try:
33
+ return bool(self.predicate(val))
34
+ except Exception:
35
+ return False
36
+
37
+
38
+ class Arrow:
39
+ """Arrow abstraction for composable computation with VCard sandwich gates."""
40
+
41
+ def __init__(
42
+ self,
43
+ func: Callable[[Any], Any],
44
+ name: str = "arrow",
45
+ v_pre: VCardGuard | list[VCardGuard] | None = None,
46
+ v_post: VCardGuard | list[VCardGuard] | None = None,
47
+ agent_did: str | None = None,
48
+ node_id: str | None = None,
49
+ ) -> None:
50
+ self.func = func
51
+ self.name = name
52
+ self.node_id = node_id or f"arrow_{uuid.uuid4().hex[:8]}"
53
+ self.v_pre: list[VCardGuard] = (
54
+ [v_pre] if isinstance(v_pre, VCardGuard) else (v_pre or [])
55
+ )
56
+ self.v_post: list[VCardGuard] = (
57
+ [v_post] if isinstance(v_post, VCardGuard) else (v_post or [])
58
+ )
59
+ self.agent_did = agent_did or "did:key:z6MkhaXgBZDvotDkL5257faiz48Z8x28xhr554x4tp4MaEBx"
60
+
61
+ def __call__(self, input_val: Any) -> Any:
62
+ return self.func(input_val)
63
+
64
+ def __rshift__(self, other: Arrow) -> Arrow:
65
+ """Sequential composition combinator: a1 >>> a2."""
66
+ return self.compose(self, other)
67
+
68
+ @classmethod
69
+ def arr(
70
+ cls,
71
+ func: Callable[[Any], Any],
72
+ name: str = "arr",
73
+ v_pre: VCardGuard | list[VCardGuard] | None = None,
74
+ v_post: VCardGuard | list[VCardGuard] | None = None,
75
+ agent_did: str | None = None,
76
+ ) -> Arrow:
77
+ """Lifts a pure or effectful function into an Arrow."""
78
+ return cls(func, name=name, v_pre=v_pre, v_post=v_post, agent_did=agent_did)
79
+
80
+ @classmethod
81
+ def compose(cls, first: Arrow, second: Arrow) -> Arrow:
82
+ """Sequential composition: first >>> second."""
83
+ composed_name = f"({first.name} >>> {second.name})"
84
+
85
+ def composed_fn(x: Any) -> Any:
86
+ res1 = first(x)
87
+ return second(res1)
88
+
89
+ arrow = cls(
90
+ composed_fn,
91
+ name=composed_name,
92
+ v_pre=first.v_pre,
93
+ v_post=second.v_post,
94
+ agent_did=first.agent_did,
95
+ )
96
+ arrow._is_composite = True
97
+ arrow._first = first
98
+ arrow._second = second
99
+ return arrow
100
+
101
+ def first(self) -> Arrow:
102
+ """Lifts this Arrow (A -> B) to (A x C -> B x C)."""
103
+ orig_fn = self.func
104
+
105
+ def first_fn(pair: tuple[Any, Any]) -> tuple[Any, Any]:
106
+ if not isinstance(pair, (tuple, list)) or len(pair) != 2:
107
+ raise TypeError(f"Arrow.first expects a 2-tuple, got {type(pair)}")
108
+ a, c = pair[0], pair[1]
109
+ return (orig_fn(a), c)
110
+
111
+ return Arrow(
112
+ first_fn,
113
+ name=f"first({self.name})",
114
+ v_pre=self.v_pre,
115
+ v_post=self.v_post,
116
+ agent_did=self.agent_did,
117
+ )
118
+
119
+ def second(self) -> Arrow:
120
+ """Lifts this Arrow (A -> B) to (C x A -> C x B)."""
121
+ orig_fn = self.func
122
+
123
+ def second_fn(pair: tuple[Any, Any]) -> tuple[Any, Any]:
124
+ if not isinstance(pair, (tuple, list)) or len(pair) != 2:
125
+ raise TypeError(f"Arrow.second expects a 2-tuple, got {type(pair)}")
126
+ c, a = pair[0], pair[1]
127
+ return (c, orig_fn(a))
128
+
129
+ return Arrow(
130
+ second_fn,
131
+ name=f"second({self.name})",
132
+ v_pre=self.v_pre,
133
+ v_post=self.v_post,
134
+ agent_did=self.agent_did,
135
+ )
136
+
137
+ def split(self, other: Arrow) -> Arrow:
138
+ """Parallel product combinator (***): (A -> B) x (C -> D) -> (A x C -> B x D)."""
139
+ f = self.func
140
+ g = other.func
141
+
142
+ def split_fn(pair: tuple[Any, Any]) -> tuple[Any, Any]:
143
+ if not isinstance(pair, (tuple, list)) or len(pair) != 2:
144
+ raise TypeError(f"Arrow.split expects a 2-tuple, got {type(pair)}")
145
+ return (f(pair[0]), g(pair[1]))
146
+
147
+ return Arrow(
148
+ split_fn,
149
+ name=f"({self.name} *** {other.name})",
150
+ agent_did=self.agent_did,
151
+ )
152
+
153
+ def __mul__(self, other: Arrow) -> Arrow:
154
+ """Operator alias for split (***)."""
155
+ return self.split(other)
156
+
157
+ def fanout(self, other: Arrow) -> Arrow:
158
+ """Fanout combinator (&&&): A -> (B x C)."""
159
+ f = self.func
160
+ g = other.func
161
+
162
+ def fanout_fn(x: Any) -> tuple[Any, Any]:
163
+ return (f(x), g(x))
164
+
165
+ return Arrow(
166
+ fanout_fn,
167
+ name=f"({self.name} &&& {other.name})",
168
+ agent_did=self.agent_did,
169
+ )
170
+
171
+ def __and__(self, other: Arrow) -> Arrow:
172
+ """Operator alias for fanout (&&&)."""
173
+ return self.fanout(other)
174
+
175
+
176
+ @dataclass
177
+ class CPNCompiledNet:
178
+ """Compiled Colored Petri Net representation of an Arrow or Arrow pipeline."""
179
+
180
+ net_id: str
181
+ places: list[dict[str, Any]]
182
+ transitions: list[dict[str, Any]]
183
+ incidence_matrix: list[list[int]]
184
+ place_index: dict[str, int]
185
+ transition_index: dict[str, int]
186
+ entry_place: str
187
+ exit_place: str
188
+ arrow: Arrow | None = None
189
+ steps: list[Arrow] = field(default_factory=list)
190
+
191
+ def __call__(self, val: Any) -> Any:
192
+ """Executes the underlying Arrow computation."""
193
+ if self.arrow is not None:
194
+ return self.arrow(val)
195
+ raise RuntimeError("No executable Arrow attached to CPNCompiledNet")
196
+
197
+ def to_dict(self) -> dict[str, Any]:
198
+ serializable_transitions = []
199
+ for t in self.transitions:
200
+ t_copy = dict(t)
201
+ if "arrow_ref" in t_copy and hasattr(t_copy["arrow_ref"], "name"):
202
+ t_copy["arrow_ref"] = t_copy["arrow_ref"].name
203
+ serializable_transitions.append(t_copy)
204
+
205
+ return {
206
+ "net_id": self.net_id,
207
+ "places": self.places,
208
+ "transitions": serializable_transitions,
209
+ "incidence_matrix": self.incidence_matrix,
210
+ "entry_place": self.entry_place,
211
+ "exit_place": self.exit_place,
212
+ }
213
+
214
+ def to_json(self, indent: int = 2) -> str:
215
+ return json.dumps(self.to_dict(), indent=indent)
216
+
217
+ def to_graphviz(self) -> str:
218
+ """Exports CPN net topology as Graphviz DOT notation."""
219
+ lines = [f'digraph "{self.net_id}" {{', ' rankdir=LR;', ' node [fontname="Helvetica"];']
220
+ for p in self.places:
221
+ pid = p["id"]
222
+ label = f"{p.get('label', pid)}\\n(tokens={p.get('initial_tokens', 0)})"
223
+ lines.append(f' "{pid}" [shape=circle, label="{label}"];')
224
+ for t in self.transitions:
225
+ tid = t["id"]
226
+ label = t.get("label", tid)
227
+ lines.append(f' "{tid}" [shape=box, style=filled, fillcolor="#e0e7ff", label="{label}"];')
228
+ for t in self.transitions:
229
+ tid = t["id"]
230
+ for inp in t.get("inputs", []):
231
+ lines.append(f' "{inp}" -> "{tid}";')
232
+ for out in t.get("outputs", []):
233
+ lines.append(f' "{tid}" -> "{out}";')
234
+ lines.append("}")
235
+ return "\n".join(lines)
236
+
237
+ def to_mermaid(self) -> str:
238
+ """Exports CPN net topology as Mermaid flowchart diagram."""
239
+ lines = ["graph LR"]
240
+ for p in self.places:
241
+ pid = p["id"]
242
+ label = p.get("label", pid)
243
+ lines.append(f' {pid}(("{label}"))')
244
+ for t in self.transitions:
245
+ tid = t["id"]
246
+ label = t.get("label", tid)
247
+ lines.append(f' {tid}["{label}"]')
248
+ for t in self.transitions:
249
+ tid = t["id"]
250
+ for inp in t.get("inputs", []):
251
+ lines.append(f" {inp} --> {tid}")
252
+ for out in t.get("outputs", []):
253
+ lines.append(f" {tid} --> {out}")
254
+ return "\n".join(lines)
255
+
256
+
257
+ def _flatten_arrow_sequence(arrow: Arrow) -> list[Arrow]:
258
+ """Flattens a tree of sequentially composed arrows into an ordered list."""
259
+ if getattr(arrow, "_is_composite", False):
260
+ return _flatten_arrow_sequence(arrow._first) + _flatten_arrow_sequence(arrow._second)
261
+ return [arrow]
262
+
263
+
264
+ def compile_to_cpn(arrow: Arrow, net_id: str | None = None) -> CPNCompiledNet:
265
+ """
266
+ Compiles an Arrow (or sequentially composed Arrow chain) into a Colored Petri Net.
267
+
268
+ For each atomic Arrow i in the sequence:
269
+ Places:
270
+ P_in_{i}: Input token place
271
+ P_pre_{i}: Pre-condition satisfied place
272
+ P_exec_{i}: PCard execution completed place
273
+ P_post_{i}: Post-condition verified place
274
+ P_out_{i}: Sealed output place
275
+ Transitions:
276
+ T_prep_{i}: Consumes P_in_{i}, verifies identity and V_pre, produces P_pre_{i}
277
+ T_exec_{i}: Consumes P_pre_{i}, executes PCard, produces P_exec_{i}
278
+ T_post_{i}: Consumes P_exec_{i}, verifies V_post and Noetherian P-invariant, produces P_post_{i}
279
+ T_seal_{i}: Consumes P_post_{i}, commits token, produces P_out_{i}
280
+ Sequential composition joins P_out_{i} with P_in_{i+1}.
281
+ """
282
+ net_id = net_id or f"cpn_{uuid.uuid4().hex[:8]}"
283
+ arrows = _flatten_arrow_sequence(arrow)
284
+
285
+ places: list[dict[str, Any]] = []
286
+ transitions: list[dict[str, Any]] = []
287
+
288
+ prev_out_place: str | None = None
289
+ entry_place: str = ""
290
+ exit_place: str = ""
291
+
292
+ for idx, sub_arr in enumerate(arrows):
293
+ prefix = f"{net_id}_step_{idx}"
294
+
295
+ if idx == 0:
296
+ in_place = f"{prefix}_p_in"
297
+ places.append({"id": in_place, "label": f"P_in_{idx}", "initial_tokens": 1})
298
+ entry_place = in_place
299
+ else:
300
+ in_place = prev_out_place
301
+
302
+ p_pre = f"{prefix}_p_pre"
303
+ p_exec = f"{prefix}_p_exec"
304
+ p_post = f"{prefix}_p_post"
305
+ p_out = f"{prefix}_p_out"
306
+
307
+ places.extend([
308
+ {"id": p_pre, "label": f"P_pre_{idx}", "initial_tokens": 0},
309
+ {"id": p_exec, "label": f"P_exec_{idx}", "initial_tokens": 0},
310
+ {"id": p_post, "label": f"P_post_{idx}", "initial_tokens": 0},
311
+ {"id": p_out, "label": f"P_out_{idx}", "initial_tokens": 0},
312
+ ])
313
+
314
+ # 4-Phase Transitions
315
+ t_prep = {
316
+ "id": f"{prefix}_t_prep",
317
+ "label": f"Prep ({sub_arr.name})",
318
+ "inputs": [in_place],
319
+ "outputs": [p_pre],
320
+ "phase": "prep",
321
+ "agent_did": sub_arr.agent_did,
322
+ "v_pre_count": len(sub_arr.v_pre),
323
+ }
324
+ t_exec = {
325
+ "id": f"{prefix}_t_exec",
326
+ "label": f"Exec ({sub_arr.name})",
327
+ "inputs": [p_pre],
328
+ "outputs": [p_exec],
329
+ "phase": "exec",
330
+ "arrow_ref": sub_arr,
331
+ }
332
+ t_post = {
333
+ "id": f"{prefix}_t_post",
334
+ "label": f"Post ({sub_arr.name})",
335
+ "inputs": [p_exec],
336
+ "outputs": [p_post],
337
+ "phase": "post",
338
+ "v_post_count": len(sub_arr.v_post),
339
+ }
340
+ t_seal = {
341
+ "id": f"{prefix}_t_seal",
342
+ "label": f"Seal ({sub_arr.name})",
343
+ "inputs": [p_post],
344
+ "outputs": [p_out],
345
+ "phase": "seal",
346
+ }
347
+
348
+ transitions.extend([t_prep, t_exec, t_post, t_seal])
349
+ prev_out_place = p_out
350
+ if idx == len(arrows) - 1:
351
+ exit_place = p_out
352
+
353
+ # Compute Incidence Matrix D = D^+ - D^-
354
+ place_ids = [p["id"] for p in places]
355
+ trans_ids = [t["id"] for t in transitions]
356
+ place_index = {pid: i for i, pid in enumerate(place_ids)}
357
+ trans_index = {tid: j for j, tid in enumerate(trans_ids)}
358
+
359
+ num_p = len(places)
360
+ num_t = len(transitions)
361
+ d_matrix = [[0 for _ in range(num_t)] for _ in range(num_p)]
362
+
363
+ for j, t in enumerate(transitions):
364
+ for inp in t.get("inputs", []):
365
+ i = place_index[inp]
366
+ d_matrix[i][j] -= 1
367
+ for out in t.get("outputs", []):
368
+ i = place_index[out]
369
+ d_matrix[i][j] += 1
370
+
371
+ return CPNCompiledNet(
372
+ net_id=net_id,
373
+ places=places,
374
+ transitions=transitions,
375
+ incidence_matrix=d_matrix,
376
+ place_index=place_index,
377
+ transition_index=trans_index,
378
+ entry_place=entry_place,
379
+ exit_place=exit_place,
380
+ arrow=arrow,
381
+ steps=arrows,
382
+ )
383
+
384
+
385
+ class PCardResolver:
386
+ """Resolve PCard references by content hash, CLM handle, or URL (Layer 1).
387
+
388
+ The resolver is the bridge between symbolic PCard references stored
389
+ in PetriNet transitions and the actual PCard MCards in the collection.
390
+ """
391
+
392
+ def __init__(
393
+ self,
394
+ collection: Any,
395
+ trusted_urls: list[str] | None = None,
396
+ allow_file_refs: bool = True,
397
+ ) -> None:
398
+ self.collection = collection
399
+ self.trusted_urls = trusted_urls or []
400
+ self.allow_file_refs = allow_file_refs
401
+ self._resolution_cache: dict[str, str] = {}
402
+ self._recursion_guard: set[str] = set()
403
+
404
+ def resolve_to_hash(self, ref: str) -> str | None:
405
+ """Resolve a PCard reference to a content hash."""
406
+ if not ref:
407
+ return None
408
+
409
+ if ref in self._resolution_cache:
410
+ return self._resolution_cache[ref]
411
+
412
+ resolved = None
413
+
414
+ if self._is_hash_ref(ref):
415
+ resolved = self._resolve_hash(ref)
416
+ elif ref.startswith("/") or "/" in ref:
417
+ resolved = self._resolve_handle(ref)
418
+ elif ref.startswith("file://"):
419
+ resolved = self._resolve_file(ref)
420
+ elif ref.startswith("http://") or ref.startswith("https://"):
421
+ resolved = self._resolve_url(ref)
422
+ else:
423
+ resolved = self._resolve_hash(ref)
424
+
425
+ if resolved:
426
+ self._resolution_cache[ref] = resolved
427
+
428
+ return resolved
429
+
430
+ @staticmethod
431
+ def _is_hash_ref(ref: str) -> bool:
432
+ if ref.startswith("sha256:") or ref.startswith("sha512:"):
433
+ return True
434
+ if len(ref) >= 32 and all(c in "0123456789abcdef" for c in ref[:32]):
435
+ return True
436
+ return False
437
+
438
+ def _resolve_hash(self, ref: str) -> str | None:
439
+ hash_val = ref
440
+ if ":" in ref and ref.index(":") < 10:
441
+ hash_val = ref.split(":", 1)[1] if not ref.startswith("clm:") else ref
442
+
443
+ if hasattr(self.collection, "get"):
444
+ card = self.collection.get(hash_val)
445
+ if card:
446
+ return getattr(card, "hash", hash_val)
447
+
448
+ card = self.collection.get(ref)
449
+ if card:
450
+ return getattr(card, "hash", ref)
451
+
452
+ return None
453
+
454
+ def _resolve_handle(self, ref: str) -> str | None:
455
+ if hasattr(self.collection, "resolve_handle"):
456
+ resolved = self.collection.resolve_handle(ref)
457
+ if resolved:
458
+ return resolved
459
+
460
+ if hasattr(self.collection, "get_by_handle"):
461
+ card = self.collection.get_by_handle(ref)
462
+ if card:
463
+ return getattr(card, "hash", None)
464
+
465
+ return None
466
+
467
+ def _resolve_file(self, ref: str) -> str | None:
468
+ if not self.allow_file_refs:
469
+ return None
470
+
471
+ try:
472
+ from pathlib import Path
473
+
474
+ path_str = ref[len("file://") :] if ref.startswith("file://") else ref
475
+ file_path = Path(path_str)
476
+ if not file_path.exists():
477
+ return None
478
+
479
+ content = file_path.read_bytes()
480
+ from clm.layer0.mcard import MCard
481
+
482
+ card = MCard(content)
483
+ if hasattr(self.collection, "add"):
484
+ self.collection.add(card)
485
+ return getattr(card, "hash", None)
486
+ except Exception:
487
+ return None
488
+
489
+ def _resolve_url(self, ref: str) -> str | None:
490
+ if not self._is_trusted_url(ref):
491
+ return None
492
+
493
+ try:
494
+ import urllib.request
495
+
496
+ from clm.layer0.mcard import MCard
497
+
498
+ response = urllib.request.urlopen(ref, timeout=30) # noqa: S310
499
+ content = response.read()
500
+ card = MCard(content)
501
+ if hasattr(self.collection, "add"):
502
+ self.collection.add(card)
503
+ return getattr(card, "hash", None)
504
+ except Exception:
505
+ return None
506
+
507
+ def _is_trusted_url(self, url: str) -> bool:
508
+ return any(url.startswith(prefix) for prefix in self.trusted_urls)
509
+
510
+ def clear_cache(self) -> None:
511
+ self._resolution_cache.clear()
512
+
513
+ def add_trusted_url(self, url_prefix: str) -> None:
514
+ if url_prefix not in self.trusted_urls:
515
+ self.trusted_urls.append(url_prefix)
516
+
517
+
518
+ __all__ = [
519
+ "Arrow",
520
+ "CPNCompiledNet",
521
+ "VCardGuard",
522
+ "compile_to_cpn",
523
+ "PCardResolver",
524
+ ]
525
+
@@ -0,0 +1,152 @@
1
+ """Layer 1: Batch Processor for PTREngine execution.
2
+
3
+ Handles sequential and parallel batch execution logic for PTREngine.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ import asyncio
9
+ import logging
10
+ from typing import TYPE_CHECKING, Any
11
+
12
+ from clm.layer0.types import ExecutionResult
13
+ from clm.layer1.store import PTRSharedStore
14
+
15
+ if TYPE_CHECKING:
16
+ pass
17
+
18
+
19
+ class BatchProcessor:
20
+ """
21
+ Composition object handling sequential and parallel batch execution logic for the PTREngine.
22
+ """
23
+
24
+ def __init__(self, engine: Any):
25
+ self.engine = engine
26
+ self.logger = logging.getLogger(__name__)
27
+
28
+ def execute_batch(
29
+ self,
30
+ pcard_hash: str,
31
+ target_hashes: list[str],
32
+ context: dict[str, Any] | PTRSharedStore = None,
33
+ specification_embedding: list[float] | None = None,
34
+ fail_fast: bool = False,
35
+ ) -> list[ExecutionResult]:
36
+ context = context or {}
37
+ results = []
38
+ failed_count = 0
39
+
40
+ self.logger.info(
41
+ f"[BATCH] Starting sequential batch execution: "
42
+ f"PCard {pcard_hash[:16]} against {len(target_hashes)} targets"
43
+ )
44
+
45
+ for i, target_hash in enumerate(target_hashes):
46
+ self.logger.debug(
47
+ f"[BATCH] Processing {i + 1}/{len(target_hashes)}: {target_hash[:16]}"
48
+ )
49
+
50
+ result = self.engine.execute_pcard(
51
+ pcard_hash, target_hash, context, specification_embedding
52
+ )
53
+ results.append(result)
54
+
55
+ if not result.success:
56
+ failed_count += 1
57
+ self.logger.warning(
58
+ f"[BATCH] Failed {i + 1}/{len(target_hashes)}: {target_hash[:16]} - {result.error_message}"
59
+ )
60
+ if fail_fast:
61
+ self.logger.error(
62
+ "[BATCH] Fail-fast triggered, stopping batch execution"
63
+ )
64
+ break
65
+
66
+ self.engine.correctness_tracker.record_liveness_metric(
67
+ "batch_completed", 1.0 if failed_count == 0 else 0.5
68
+ )
69
+ self.engine.correctness_tracker.record_liveness_metric(
70
+ "batch_success_rate", (len(results) - failed_count) / len(target_hashes)
71
+ )
72
+
73
+ self.logger.info(
74
+ f"[BATCH] Completed: {len(results) - failed_count}/{len(target_hashes)} succeeded"
75
+ )
76
+ return results
77
+
78
+ async def execute_batch_parallel(
79
+ self,
80
+ pcard_hash: str,
81
+ target_hashes: list[str],
82
+ context: dict[str, Any] | PTRSharedStore = None,
83
+ specification_embedding: list[float] | None = None,
84
+ max_concurrency: int = 10,
85
+ ) -> list[ExecutionResult]:
86
+ context = context or {}
87
+
88
+ self.logger.info(
89
+ f"[BATCH_PARALLEL] Starting parallel batch execution: "
90
+ f"PCard {pcard_hash[:16]} against {len(target_hashes)} targets "
91
+ f"(max_concurrency={max_concurrency})"
92
+ )
93
+
94
+ async def execute_single(target_hash: str) -> ExecutionResult:
95
+ loop = asyncio.get_event_loop()
96
+ return await loop.run_in_executor(
97
+ None,
98
+ self.engine.execute_pcard,
99
+ pcard_hash,
100
+ target_hash,
101
+ context,
102
+ specification_embedding,
103
+ )
104
+
105
+ semaphore = asyncio.Semaphore(max_concurrency)
106
+
107
+ async def execute_with_limit(target_hash: str) -> ExecutionResult:
108
+ async with semaphore:
109
+ return await execute_single(target_hash)
110
+
111
+ results = await asyncio.gather(
112
+ *[execute_with_limit(th) for th in target_hashes], return_exceptions=True
113
+ )
114
+
115
+ processed_results = []
116
+ failed_count = 0
117
+ for i, result in enumerate(results):
118
+ if isinstance(result, Exception):
119
+ failed_count += 1
120
+ error_result = ExecutionResult(
121
+ success=False,
122
+ output=None,
123
+ verification_vcard=None,
124
+ execution_time_ms=0,
125
+ alignment_score=None,
126
+ invariants_preserved=False,
127
+ safety_violations=[],
128
+ liveness_metrics={},
129
+ error_message=str(result),
130
+ )
131
+ processed_results.append(error_result)
132
+ self.logger.error(f"[BATCH_PARALLEL] Exception in {i + 1}: {result}")
133
+ else:
134
+ processed_results.append(result)
135
+ if not result.success:
136
+ failed_count += 1
137
+
138
+ self.engine.correctness_tracker.record_liveness_metric(
139
+ "batch_parallel_completed", 1.0 if failed_count == 0 else 0.5
140
+ )
141
+ self.engine.correctness_tracker.record_liveness_metric(
142
+ "batch_parallel_success_rate",
143
+ (len(processed_results) - failed_count) / len(target_hashes),
144
+ )
145
+
146
+ self.logger.info(
147
+ f"[BATCH_PARALLEL] Completed: {len(processed_results) - failed_count}/{len(target_hashes)} succeeded"
148
+ )
149
+ return processed_results
150
+
151
+
152
+ __all__ = ["BatchProcessor"]
@@ -0,0 +1,27 @@
1
+ """Stratified Runtime CEL Execution in Layer 1 (Sprint 384 / DEL-384-04).
2
+
3
+ Provides runtime store builder and evaluation engines conforming to the
4
+ Six-Layer Stratification architecture.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from clm.layer1.cel.builder import (
10
+ Listener,
11
+ PostMiddleware,
12
+ PreMiddleware,
13
+ action_log_middleware,
14
+ build_store,
15
+ vcard_post_middleware,
16
+ vcard_pre_middleware,
17
+ )
18
+
19
+ __all__ = [
20
+ "Listener",
21
+ "PostMiddleware",
22
+ "PreMiddleware",
23
+ "action_log_middleware",
24
+ "build_store",
25
+ "vcard_post_middleware",
26
+ "vcard_pre_middleware",
27
+ ]