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
clm/layer1/sandbox.py ADDED
@@ -0,0 +1,334 @@
1
+ from __future__ import annotations
2
+
3
+ """
4
+ Sandbox execution environment for PCards with multi-language runtime support.
5
+ """
6
+
7
+ import logging
8
+ from pathlib import Path
9
+ from typing import Any
10
+
11
+ from clm.layer0.model.card import MCard
12
+ from clm.layer0.narrative import IO, Either, Left, Right
13
+ from clm.layer1.runtimes import RuntimeFactory
14
+ from clm.layer1.store import PTRSharedStore
15
+
16
+ # ─────────────────────────────────────────────────────────────────────────────
17
+ # Configuration
18
+ # ─────────────────────────────────────────────────────────────────────────────
19
+
20
+ DEFAULT_RUNTIME = "python"
21
+
22
+ # Error message patterns for system errors (these should raise exceptions)
23
+ SYSTEM_ERROR_PATTERNS = (
24
+ "Failed to parse PCard",
25
+ "Sandbox execution failed",
26
+ )
27
+
28
+ # Fallback resolution order
29
+ FALLBACK_SOURCES = ("mcard", "file", "url")
30
+
31
+
32
+ # ─────────────────────────────────────────────────────────────────────────────
33
+ # Code Resolution Strategies
34
+ # ─────────────────────────────────────────────────────────────────────────────
35
+
36
+
37
+ class CodeResolver:
38
+ """Resolves code from multiple sources with fallback chain."""
39
+
40
+ def __init__(self, collection=None, logger=None):
41
+ self.collection = collection
42
+ self.logger = logger or logging.getLogger(__name__)
43
+
44
+ def resolve(
45
+ self, concrete_impl: dict, context: dict | PTRSharedStore
46
+ ) -> Either[str, str | None]:
47
+ """
48
+ Resolve code from available sources in priority order.
49
+
50
+ Returns:
51
+ Right(code) on success, Left(error) on failure
52
+ """
53
+ # Already have code
54
+ if concrete_impl.get("code"):
55
+ return Right(concrete_impl["code"])
56
+
57
+ # No code hash means no content-addressed lookup needed
58
+ code_hash = concrete_impl.get("code_hash")
59
+
60
+ # If no code source is specified, return None (success, no code needed)
61
+ if not any(
62
+ [
63
+ code_hash,
64
+ concrete_impl.get("code_file"),
65
+ concrete_impl.get("fallback_file"),
66
+ concrete_impl.get("fallback_url"),
67
+ ]
68
+ ):
69
+ return Right(None)
70
+
71
+ # Try resolution sources in order
72
+ resolvers = [
73
+ ("mcard", lambda: self._from_mcard(code_hash) if code_hash else None),
74
+ (
75
+ "file",
76
+ lambda: self._from_file(
77
+ concrete_impl.get("code_file")
78
+ or concrete_impl.get("fallback_file"),
79
+ context,
80
+ code_hash or "unknown",
81
+ ),
82
+ ),
83
+ (
84
+ "url",
85
+ lambda: self._from_url(
86
+ concrete_impl.get("fallback_url"), code_hash or "unknown"
87
+ ),
88
+ ),
89
+ ]
90
+
91
+ for _source_name, resolver in resolvers:
92
+ result = resolver()
93
+ if result is not None:
94
+ return Right(result)
95
+
96
+ return Left(
97
+ f"Error: Code resolution failed. MCard {code_hash} not found, and fallbacks failed."
98
+ )
99
+
100
+ def _from_mcard(self, code_hash: str) -> str | None:
101
+ """Try to resolve code from MCard collection."""
102
+ if not self.collection:
103
+ return None
104
+
105
+ code_card = self.collection.get(code_hash)
106
+ if code_card:
107
+ self.logger.info(f"Resolved code from MCard: {code_hash}")
108
+ return code_card.get_content().decode("utf-8")
109
+ return None
110
+
111
+ def _from_file(
112
+ self, fallback_file: str | None, context: dict | PTRSharedStore, code_hash: str
113
+ ) -> str | None:
114
+ """Try to resolve code from fallback file."""
115
+ if not fallback_file:
116
+ return None
117
+
118
+ try:
119
+ path = self._resolve_file_path(fallback_file, context)
120
+ if path and path.exists():
121
+ self.logger.warning(
122
+ f"MCard not found for hash {code_hash}, loaded from fallback file: {fallback_file}"
123
+ )
124
+ return path.read_text()
125
+ self.logger.warning(f"Fallback file not found: {path}")
126
+ except OSError as e:
127
+ self.logger.error(
128
+ f"Failed to load fallback file {fallback_file}: {e}", exc_info=True
129
+ )
130
+ return None
131
+
132
+ def _from_url(self, fallback_url: str | None, code_hash: str) -> str | None:
133
+ """Try to resolve code from fallback URL."""
134
+ if not fallback_url:
135
+ return None
136
+
137
+ try:
138
+ import urllib.request
139
+
140
+ with urllib.request.urlopen(fallback_url) as response: # nosec B310
141
+ status = getattr(response, "status", None) or getattr(
142
+ response, "code", 200
143
+ )
144
+ if status == 200:
145
+ self.logger.warning(
146
+ f"Loaded code from fallback URL: {fallback_url}"
147
+ )
148
+ return response.read().decode("utf-8")
149
+ self.logger.error(
150
+ f"Failed to fetch fallback URL {fallback_url}: Status {status}"
151
+ )
152
+ except (OSError, ValueError, UnicodeDecodeError) as e:
153
+ self.logger.error(
154
+ f"Failed to fetch fallback URL {fallback_url}: {e}", exc_info=True
155
+ )
156
+ return None
157
+
158
+ @staticmethod
159
+ def _resolve_file_path(
160
+ file_path: str, context: dict | PTRSharedStore
161
+ ) -> Path | None:
162
+ """Resolve a file path, handling relative paths."""
163
+ path = Path(file_path)
164
+ if path.is_absolute():
165
+ return path
166
+
167
+ # Try pcard_dir first, then cwd
168
+ context_dict = (
169
+ context.inputs if isinstance(context, PTRSharedStore) else context
170
+ )
171
+ pcard_dir = context_dict.get("pcard_dir") if context_dict else None
172
+ if pcard_dir:
173
+ candidate = Path(pcard_dir) / path
174
+ if candidate.exists():
175
+ return candidate
176
+
177
+ return Path.cwd() / path
178
+
179
+
180
+ # ─────────────────────────────────────────────────────────────────────────────
181
+ # Sandbox Executor
182
+ # ─────────────────────────────────────────────────────────────────────────────
183
+
184
+
185
+ class SandboxExecutor:
186
+ """
187
+ Executes PCard logic in a sandboxed environment with multi-language support.
188
+
189
+ The sandbox dynamically selects the appropriate runtime (Python, JavaScript,
190
+ Rust, C, etc.) based on the Concrete Implementation specification in the PCard.
191
+
192
+ Production deployments should use:
193
+ - WebAssembly (WASM) for true sandboxing
194
+ - Container isolation (Docker/Kubernetes)
195
+ - Resource limits and timeout enforcement
196
+ """
197
+
198
+ def __init__(self, collection=None):
199
+ self.logger = logging.getLogger(__name__)
200
+ self.collection = collection
201
+ self._code_resolver = CodeResolver(collection, self.logger)
202
+
203
+ def execute(
204
+ self, pcard: MCard, target: MCard, context: dict[str, Any] | PTRSharedStore
205
+ ) -> Any:
206
+ """
207
+ Execute PCard logic using the specified runtime.
208
+
209
+ The runtime is determined from the Concrete Implementation's 'runtime' field.
210
+ Defaults to 'python' if not specified.
211
+ """
212
+ result_either = self.execute_monad(pcard, target, context).unsafe_run()
213
+
214
+ if result_either.is_left():
215
+ error_msg = result_either.value
216
+ if self._is_system_error(error_msg):
217
+ raise RuntimeError(error_msg)
218
+ return error_msg
219
+ return result_either.value
220
+
221
+ async def aexecute(
222
+ self, pcard: MCard, target: MCard, context: dict[str, Any] | PTRSharedStore
223
+ ) -> Any:
224
+ """Async wrapper for execute() using a thread pool.
225
+
226
+ This provides an awaitable interface for sandbox execution without
227
+ altering runtime semantics. When true async runtimes are available,
228
+ this method can be updated to call them directly.
229
+ """
230
+ import asyncio
231
+
232
+ return await asyncio.to_thread(self.execute, pcard, target, context)
233
+
234
+ def execute_monad(
235
+ self, pcard: MCard, target: MCard, context: dict[str, Any] | PTRSharedStore
236
+ ) -> IO[Either[str, Any]]:
237
+ """Monadic execution pipeline returning IO[Either[Error, Result]]."""
238
+
239
+ def run() -> Either[str, Any]:
240
+ try:
241
+ return self._pipeline(pcard, target, context)
242
+ except Exception as e:
243
+ return Left(f"Sandbox execution failed: {e}")
244
+
245
+ return IO(run)
246
+
247
+ async def execute_monad_async(
248
+ self, pcard: MCard, target: MCard, context: dict[str, Any] | PTRSharedStore
249
+ ) -> Either[str, Any]:
250
+ """Async wrapper that returns Either by running the monadic pipeline in a thread pool."""
251
+ import asyncio
252
+
253
+ return await asyncio.to_thread(
254
+ lambda: self.execute_monad(pcard, target, context).unsafe_run()
255
+ )
256
+
257
+ def _pipeline(
258
+ self, pcard: MCard, target: MCard, context: dict | PTRSharedStore
259
+ ) -> Either[str, Any]:
260
+ """Execute the main processing pipeline."""
261
+ # 1. Parse PCard
262
+ pcard_data = self._parse_pcard(pcard)
263
+ if pcard_data.is_left():
264
+ return pcard_data
265
+
266
+ clm_base = pcard_data.value.get("clm", pcard_data.value)
267
+ concrete_impl = clm_base.get("concrete_impl", clm_base.get("concrete", {}))
268
+
269
+ # 2. Resolve Code
270
+ code_result = self._code_resolver.resolve(concrete_impl, context)
271
+ if code_result.is_left():
272
+ return code_result
273
+
274
+ if code_result.value:
275
+ concrete_impl["code"] = code_result.value
276
+
277
+ # 3. Get Executor
278
+ runtime_type = concrete_impl.get("runtime", DEFAULT_RUNTIME)
279
+ self.logger.info(f"Executing PCard with runtime: {runtime_type}")
280
+
281
+ executor = RuntimeFactory.get_executor(runtime_type)
282
+ if not executor:
283
+ return Left(
284
+ f"Error: Runtime '{runtime_type}' is not available or not supported"
285
+ )
286
+
287
+ # 4. Execute
288
+ return self._execute_runtime(executor, concrete_impl, target, context)
289
+
290
+ def _parse_pcard(self, pcard: MCard) -> Either[str, dict]:
291
+ """Parse PCard YAML content."""
292
+ try:
293
+ import yaml
294
+
295
+ return Right(yaml.safe_load(pcard.get_content().decode("utf-8")))
296
+ except (yaml.YAMLError, UnicodeDecodeError, ValueError, TypeError) as e:
297
+ return Left(f"Failed to parse PCard: {e}")
298
+
299
+ def _execute_runtime(
300
+ self,
301
+ executor: Any,
302
+ concrete_impl: dict,
303
+ target: MCard,
304
+ context: dict | PTRSharedStore,
305
+ ) -> Either[str, Any]:
306
+ """Execute using the selected runtime."""
307
+ try:
308
+ context_dict = (
309
+ context.inputs if isinstance(context, PTRSharedStore) else context
310
+ )
311
+ result = executor.execute(concrete_impl, target, context_dict)
312
+ if isinstance(result, str) and result.startswith("Error:"):
313
+ return Left(result)
314
+ return Right(result)
315
+ except (RuntimeError, ValueError, TypeError, OSError) as e:
316
+ return Left(f"Runtime execution failed: {e}")
317
+
318
+ @staticmethod
319
+ def _is_system_error(error_msg: str) -> bool:
320
+ """Check if error message indicates a system-level error."""
321
+ return any(pattern in error_msg for pattern in SYSTEM_ERROR_PATTERNS)
322
+
323
+ def list_available_runtimes(self) -> dict[str, bool]:
324
+ """Get list of available runtimes on this system."""
325
+ return RuntimeFactory.list_available_runtimes()
326
+
327
+
328
+ __all__ = [
329
+ "DEFAULT_RUNTIME",
330
+ "SYSTEM_ERROR_PATTERNS",
331
+ "FALLBACK_SOURCES",
332
+ "CodeResolver",
333
+ "SandboxExecutor",
334
+ ]
@@ -0,0 +1,136 @@
1
+ """
2
+ Layer 1: ℤ₄ Savepoint Guard & Reversibility Engine (DV-373-03, INV-339-02).
3
+
4
+ Implements transactional atomicity across the 4-phase cyclic group ℤ₄ = ℤ / 4ℤ:
5
+ 0 (Idle) -> 1 (Pre-Gate) -> 2 (Transform) -> 3 (Post-Gate) -> 0 (Committed)
6
+
7
+ On any VCard meet failure (T_valid = ⊥) or execution exception:
8
+ - Automatically rolls back to the named SQLite savepoint
9
+ - Executes all Cordis DisposableList callbacks in strict reverse-LIFO order
10
+ - Guarantees zero residual state in the G-Set CAS (card, handle_history, learning_event)
11
+ - Records safety and liveness telemetry metrics
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import sqlite3
17
+ import sys
18
+ import uuid
19
+ from contextlib import contextmanager
20
+ from dataclasses import dataclass
21
+ from typing import Any, Callable, Generator
22
+
23
+ _target = "clm.layer2.fiber"
24
+ _mod = sys.modules.get(_target)
25
+ if _mod is None:
26
+ __import__(_target)
27
+ _mod = sys.modules.get(_target)
28
+ DisposableList = _mod.DisposableList
29
+
30
+
31
+ class VCardMeetViolation(Exception):
32
+ """Raised when pre- or post-condition meet collapses to ⊥."""
33
+ pass
34
+
35
+
36
+ @dataclass
37
+ class CPNExecutionTelemetry:
38
+ """Telemetry counters for CPN transition safety and liveness."""
39
+
40
+ total_transitions: int = 0
41
+ successful_transitions: int = 0
42
+ aborted_transitions: int = 0
43
+ safety_violation_count: int = 0
44
+ liveness_metric: float = 1.0
45
+
46
+ def record_success(self) -> None:
47
+ self.total_transitions += 1
48
+ self.successful_transitions += 1
49
+ self._update_liveness()
50
+
51
+ def record_abort(self) -> None:
52
+ self.total_transitions += 1
53
+ self.aborted_transitions += 1
54
+ self.safety_violation_count += 1
55
+ self._update_liveness()
56
+
57
+ def _update_liveness(self) -> None:
58
+ if self.total_transitions == 0:
59
+ self.liveness_metric = 1.0
60
+ else:
61
+ self.liveness_metric = self.successful_transitions / self.total_transitions
62
+
63
+ def to_dict(self) -> dict[str, Any]:
64
+ return {
65
+ "total_transitions": self.total_transitions,
66
+ "successful_transitions": self.successful_transitions,
67
+ "aborted_transitions": self.aborted_transitions,
68
+ "safety_violation_count": self.safety_violation_count,
69
+ "liveness_metric": round(self.liveness_metric, 4),
70
+ }
71
+
72
+
73
+ # Vault-level singleton telemetry for CPN execution
74
+ GLOBAL_CPN_TELEMETRY = CPNExecutionTelemetry()
75
+
76
+
77
+ class Z4TransitionContext:
78
+ """State manager for a single ℤ₄ transition step."""
79
+
80
+ def __init__(self, step_id: str, conn: sqlite3.Connection, disposables: DisposableList) -> None:
81
+ self.step_id = step_id
82
+ self.conn = conn
83
+ self.disposables = disposables
84
+ self.phase: int = 0 # 0: Idle, 1: Prep, 2: Exec, 3: Post
85
+ self.vcard_meet_satisfied: bool = True
86
+
87
+ def advance_phase(self, new_phase: int) -> None:
88
+ """Transitions state: 0 -> 1 -> 2 -> 3 -> 0."""
89
+ self.phase = new_phase % 4
90
+
91
+ def register_disposable(self, callback: Callable[[], None]) -> None:
92
+ """Registers a reverse-LIFO rollback callback."""
93
+ self.disposables.push(callback)
94
+
95
+ def fail_meet(self, reason: str = "State collapsed to ⊥") -> None:
96
+ """Explicitly collapses transition to ⊥."""
97
+ self.vcard_meet_satisfied = False
98
+ raise VCardMeetViolation(f"Step '{self.step_id}' VCard Meet Violation: {reason}")
99
+
100
+
101
+ @contextmanager
102
+ def z4_savepoint_guard(
103
+ conn: sqlite3.Connection,
104
+ step_id: str | None = None,
105
+ telemetry: CPNExecutionTelemetry | None = None,
106
+ ) -> Generator[Z4TransitionContext, None, None]:
107
+ """
108
+ Executes a CPN transition in an isolated SQLite savepoint with ℤ₄ reversibility.
109
+
110
+ Guarantees zero partial writes on error.
111
+ """
112
+ tel = telemetry or GLOBAL_CPN_TELEMETRY
113
+ name = step_id or f"ptr_step_{uuid.uuid4().hex[:8]}"
114
+ sp_name = f"sp_{name}"
115
+ disposables = DisposableList()
116
+
117
+ conn.execute(f"SAVEPOINT {sp_name};")
118
+ t_ctx = Z4TransitionContext(step_id=name, conn=conn, disposables=disposables)
119
+
120
+ try:
121
+ t_ctx.advance_phase(1) # Prep
122
+ yield t_ctx
123
+
124
+ if not t_ctx.vcard_meet_satisfied:
125
+ raise VCardMeetViolation("VCard meet collapsed to ⊥")
126
+
127
+ t_ctx.advance_phase(0) # Sealed
128
+ conn.execute(f"RELEASE SAVEPOINT {sp_name};")
129
+ tel.record_success()
130
+
131
+ except Exception:
132
+ disposables.dispose()
133
+ conn.execute(f"ROLLBACK TO SAVEPOINT {sp_name};")
134
+ conn.execute(f"RELEASE SAVEPOINT {sp_name};")
135
+ tel.record_abort()
136
+ raise
@@ -0,0 +1,122 @@
1
+ """Layer 1: Compressed Sparse Incidence Matrix & Precomputed P-Invariants (INV-419).
2
+
3
+ Sprint 419 / DEL-419-02.
4
+ Provides zero-allocation token transitions and O(1) Noetherian conservation verification.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from dataclasses import dataclass, field
10
+
11
+ from clm.layer0.math_utils import solve_nullspace
12
+
13
+
14
+ @dataclass
15
+ class PrecomputedInvariants:
16
+ """Pre-computed nullspace basis for Noetherian P-invariants (INV-419).
17
+
18
+ Replaces dynamic Gaussian elimination during transitions with O(1) dot-product checks.
19
+ """
20
+
21
+ basis_vectors: list[list[int]]
22
+ initial_constants: list[int]
23
+
24
+ @classmethod
25
+ def compile(
26
+ cls,
27
+ matrix: list[list[int]],
28
+ rows: int,
29
+ cols: int,
30
+ initial_marking: list[int],
31
+ ) -> PrecomputedInvariants:
32
+ """Compile nullspace invariants from an incidence matrix D and initial marking."""
33
+ basis = solve_nullspace(matrix, rows, cols, transpose=True)
34
+ initial_constants: list[int] = []
35
+ for b in basis:
36
+ s = sum(w * initial_marking[p] for p, w in enumerate(b) if p < len(initial_marking))
37
+ initial_constants.append(s)
38
+ return cls(basis_vectors=basis, initial_constants=initial_constants)
39
+
40
+ def verify_marking(self, marking: list[int]) -> bool:
41
+ """Fast-path check: returns True if current marking satisfies all basis conservation laws."""
42
+ for i, b in enumerate(self.basis_vectors):
43
+ s = sum(w * marking[p] for p, w in enumerate(b) if p < len(marking))
44
+ if i < len(self.initial_constants) and s != self.initial_constants[i]:
45
+ return False
46
+ return True
47
+
48
+ def verify_delta(self, delta: list[int]) -> bool:
49
+ """Fast-path check on marking delta: returns True if delta * v_k == 0 for all basis vectors."""
50
+ for b in self.basis_vectors:
51
+ s = sum(w * delta[p] for p, w in enumerate(b) if p < len(delta))
52
+ if s != 0:
53
+ return False
54
+ return True
55
+
56
+
57
+ @dataclass
58
+ class SparseIncidenceMatrix:
59
+ """Compressed Sparse Incidence Matrix for high-performance CPN evaluation."""
60
+
61
+ place_count: int
62
+ trans_count: int
63
+ consumed: list[list[tuple[int, int]]] = field(default_factory=list)
64
+ produced: list[list[tuple[int, int]]] = field(default_factory=list)
65
+ deltas: list[list[tuple[int, int]]] = field(default_factory=list)
66
+
67
+ @classmethod
68
+ def from_dense(
69
+ cls,
70
+ d: list[list[int]],
71
+ place_count: int,
72
+ trans_count: int,
73
+ ) -> SparseIncidenceMatrix:
74
+ """Construct from dense incidence matrix D (rows=places, cols=transitions)."""
75
+ consumed: list[list[tuple[int, int]]] = [[] for _ in range(trans_count)]
76
+ produced: list[list[tuple[int, int]]] = [[] for _ in range(trans_count)]
77
+ deltas: list[list[tuple[int, int]]] = [[] for _ in range(trans_count)]
78
+
79
+ for t in range(trans_count):
80
+ for p in range(place_count):
81
+ val = d[p][t] if p < len(d) and t < len(d[p]) else 0
82
+ if val < 0:
83
+ consumed[t].append((p, -val))
84
+ deltas[t].append((p, val))
85
+ elif val > 0:
86
+ produced[t].append((p, val))
87
+ deltas[t].append((p, val))
88
+
89
+ return cls(
90
+ place_count=place_count,
91
+ trans_count=trans_count,
92
+ consumed=consumed,
93
+ produced=produced,
94
+ deltas=deltas,
95
+ )
96
+
97
+ def is_enabled(self, t: int, marking: list[int]) -> bool:
98
+ """Check if transition t is enabled under the given marking."""
99
+ if t >= self.trans_count:
100
+ return False
101
+ for p, required in self.consumed[t]:
102
+ if p >= len(marking) or marking[p] < required:
103
+ return False
104
+ return True
105
+
106
+ def fire(self, t: int, marking: list[int]) -> bool:
107
+ """Fire transition t in-place on marking. Returns True on success, False if disabled."""
108
+ if not self.is_enabled(t, marking):
109
+ return False
110
+ for p, delta in self.deltas[t]:
111
+ if p < len(marking):
112
+ marking[p] += delta
113
+ return True
114
+
115
+ def get_delta(self, t: int) -> list[int]:
116
+ """Compute flat delta vector for transition t."""
117
+ res = [0] * self.place_count
118
+ if t < self.trans_count:
119
+ for p, delta in self.deltas[t]:
120
+ if p < len(res):
121
+ res[p] = delta
122
+ return res