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/layer0/cel_eval.py ADDED
@@ -0,0 +1,491 @@
1
+ """CEL Evaluator — Common Expression Language Evaluator for CLM.
2
+
3
+ Layer 0 Canonical Path: clm/kernel/scripts/clm/layer0/cel_eval.py
4
+ Provides side-effect-free deterministic evaluation of VCard pre/post constraints,
5
+ gate predicates, field assertions, and RLCD calibrated meet predicates.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import math
11
+ import re
12
+ from dataclasses import dataclass
13
+ from typing import Any
14
+
15
+
16
+ @dataclass
17
+ class BailVerdict:
18
+ verdict: str # "pass" or "bail"
19
+ reason: str = ""
20
+ invariant_code: str = ""
21
+
22
+ @classmethod
23
+ def pass_verdict(cls) -> BailVerdict:
24
+ return cls(verdict="pass")
25
+
26
+ @classmethod
27
+ def bail(cls, reason: str, invariant_code: str = "") -> BailVerdict:
28
+ return cls(verdict="bail", reason=reason, invariant_code=invariant_code)
29
+
30
+
31
+ @dataclass
32
+ class CelEvaluationResult:
33
+ matched: bool
34
+ verdict: BailVerdict
35
+ evaluated_value: Any = None
36
+
37
+ @property
38
+ def passed(self) -> bool:
39
+ return self.verdict.verdict == "pass"
40
+
41
+
42
+ def _is_payload_empty(card: Any) -> bool:
43
+ if card is None:
44
+ return True
45
+ if isinstance(card, dict):
46
+ if "payload" in card:
47
+ payload = card["payload"]
48
+ elif "content" in card:
49
+ payload = card["content"]
50
+ else:
51
+ payload = card
52
+ else:
53
+ payload = getattr(card, "payload", getattr(card, "content", None))
54
+
55
+ if payload is None:
56
+ return True
57
+ if isinstance(payload, (bytes, str)):
58
+ return len(payload) == 0
59
+ if isinstance(payload, list):
60
+ return len(payload) == 0
61
+
62
+ # Check payload object / dict
63
+ if isinstance(payload, dict):
64
+ kind = payload.get("kind")
65
+ val = payload.get("value")
66
+ data = payload.get("data")
67
+ if kind == "scalar":
68
+ return val is None or val == ""
69
+ if kind == "text":
70
+ return val is None or str(val).strip() == ""
71
+ if kind == "binary":
72
+ return data is None or len(data) == 0
73
+ if kind == "structured":
74
+ if val is None:
75
+ return True
76
+ if isinstance(val, (list, dict)):
77
+ return len(val) == 0
78
+ if "kind" not in payload:
79
+ return len(payload) == 0
80
+ return val is None or val == ""
81
+
82
+ # Attribute-based payload
83
+ kind = getattr(payload, "kind", None)
84
+ val = getattr(payload, "value", None)
85
+ data = getattr(payload, "data", None)
86
+ if kind == "scalar":
87
+ return val is None or val == ""
88
+ if kind == "text":
89
+ return val is None or str(val).strip() == ""
90
+ if kind == "binary":
91
+ return data is None or len(data) == 0
92
+ if kind == "structured":
93
+ if val is None:
94
+ return True
95
+ if isinstance(val, (list, dict)):
96
+ return len(val) == 0
97
+ return False
98
+ return False
99
+
100
+
101
+ def _resolve_context_value(key: str, context: dict) -> Any:
102
+ key = key.strip()
103
+ if not key:
104
+ return None
105
+
106
+ # Handle RLCD access e.g., rlcd(decision).confidence or rlcd(decision).is_admissible
107
+ rlcd_match = re.match(r"^rlcd\(([^)]+)\)\.([a-zA-Z0-9_]+)$", key)
108
+ if rlcd_match:
109
+ target_name, prop = rlcd_match.groups()
110
+ target_obj = _resolve_context_value(target_name, context)
111
+ if isinstance(target_obj, dict):
112
+ if prop == "confidence":
113
+ return float(target_obj.get("confidence", target_obj.get("prob", 0.0)))
114
+ if prop == "is_admissible":
115
+ return bool(target_obj.get("is_admissible", target_obj.get("admissible", False)))
116
+ return target_obj.get(prop)
117
+ if hasattr(target_obj, prop):
118
+ return getattr(target_obj, prop)
119
+ return None
120
+
121
+ # Strip optional context. prefix if looking inside context root
122
+ if key.startswith("context."):
123
+ clean_key = key[len("context."):]
124
+ resolved = _resolve_context_value(clean_key, context)
125
+ if resolved is not None:
126
+ return resolved
127
+
128
+ # Handle context direct lookups
129
+ parts = key.split(".")
130
+ curr: Any = context
131
+ for p in parts:
132
+ if isinstance(curr, dict):
133
+ if p in curr:
134
+ curr = curr[p]
135
+ elif p.lower() in curr:
136
+ curr = curr[p.lower()]
137
+ else:
138
+ return None
139
+ elif hasattr(curr, p):
140
+ curr = getattr(curr, p)
141
+ elif hasattr(curr, "payload"):
142
+ payload = curr.payload
143
+ if isinstance(payload, dict) and p in payload:
144
+ curr = payload[p]
145
+ elif hasattr(payload, "value") and isinstance(payload.value, dict) and p in payload.value:
146
+ curr = payload.value[p]
147
+ elif hasattr(payload, p):
148
+ curr = getattr(payload, p)
149
+ elif hasattr(curr, "metadata") and isinstance(curr.metadata, dict) and p in curr.metadata:
150
+ curr = curr.metadata[p]
151
+ else:
152
+ return None
153
+ elif hasattr(curr, "metadata") and isinstance(curr.metadata, dict) and p in curr.metadata:
154
+ curr = curr.metadata[p]
155
+ else:
156
+ return None
157
+ return curr
158
+
159
+
160
+ def _compare_values(left: Any, op: str, right: Any) -> bool:
161
+ try:
162
+ # Numeric coerce
163
+ if isinstance(left, (int, float, str)) and isinstance(right, (int, float, str)):
164
+ try:
165
+ lf = float(left)
166
+ rf = float(right)
167
+ if op == "==":
168
+ return math.isclose(lf, rf, rel_tol=1e-6, abs_tol=1e-9)
169
+ if op == "!=":
170
+ return not math.isclose(lf, rf, rel_tol=1e-6, abs_tol=1e-9)
171
+ if op == "<":
172
+ return lf < rf
173
+ if op == "<=":
174
+ return lf <= rf
175
+ if op == ">":
176
+ return lf > rf
177
+ if op == ">=":
178
+ return lf >= rf
179
+ except (ValueError, TypeError):
180
+ pass
181
+
182
+ # String coerce for booleans
183
+ if isinstance(right, bool) and isinstance(left, str):
184
+ left = left.lower() in ("true", "1", "yes")
185
+ elif isinstance(left, bool) and isinstance(right, str):
186
+ right = right.lower() in ("true", "1", "yes")
187
+
188
+ if op == "==":
189
+ return left == right
190
+ if op == "!=":
191
+ return left != right
192
+ if op == "<":
193
+ return left < right
194
+ if op == "<=":
195
+ return left <= right
196
+ if op == ">":
197
+ return left > right
198
+ if op == ">=":
199
+ return left >= right
200
+ except Exception:
201
+ return False
202
+ return False
203
+
204
+
205
+ def _parse_scalar_literal(val_str: str) -> Any:
206
+ val_str = val_str.strip()
207
+ if val_str.lower() == "true":
208
+ return True
209
+ if val_str.lower() == "false":
210
+ return False
211
+ if val_str.lower() == "null" or val_str.lower() == "none":
212
+ return None
213
+ if (val_str.startswith('"') and val_str.endswith('"')) or (
214
+ val_str.startswith("'") and val_str.endswith("'")
215
+ ):
216
+ return val_str[1:-1]
217
+ try:
218
+ if "." in val_str:
219
+ return float(val_str)
220
+ return int(val_str)
221
+ except ValueError:
222
+ return val_str
223
+
224
+
225
+ class _EvaluatorDescriptor:
226
+ def __get__(self, obj: Any, objtype: type | None = None) -> Any:
227
+ if obj is None:
228
+ assert objtype is not None
229
+ return objtype._evaluate_impl
230
+ def _instance_evaluate(expr_or_context: Any = None, context: dict | None = None) -> CelEvaluationResult:
231
+ if isinstance(expr_or_context, str):
232
+ return objtype._evaluate_impl(expr_or_context, context)
233
+ ctx = expr_or_context if isinstance(expr_or_context, dict) else (context or {})
234
+ return objtype._evaluate_impl(obj.expr, ctx)
235
+ return _instance_evaluate
236
+
237
+
238
+ class CelEvaluator:
239
+ """Canonical CEL (Common Expression Language) evaluator for CLM."""
240
+
241
+ def __init__(self, expr: str = "") -> None:
242
+ self.expr = expr
243
+
244
+ def __call__(self, context: dict | None = None) -> CelEvaluationResult:
245
+ return self.evaluate(context=context)
246
+
247
+ evaluate = _EvaluatorDescriptor()
248
+
249
+ @classmethod
250
+ def evaluate_atomic(cls, expr: str, context: dict) -> CelEvaluationResult:
251
+ expr = expr.strip()
252
+ lower = expr.lower()
253
+
254
+ # 0. Literal constants
255
+ if lower in ("true", "pass"):
256
+ return CelEvaluationResult(matched=True, verdict=BailVerdict.pass_verdict(), evaluated_value=True)
257
+ if lower in ("false", "fail"):
258
+ return CelEvaluationResult(
259
+ matched=True,
260
+ verdict=BailVerdict.bail(f'Expression explicitly fails: "{expr}"', expr),
261
+ evaluated_value=False,
262
+ )
263
+
264
+ # 1. Gate predicates
265
+ if lower == "gate:payload_nonempty":
266
+ inp = context.get("input") or context.get("mcard")
267
+ if inp is None and "payload" in context:
268
+ inp = {"payload": context["payload"]}
269
+ if inp is None:
270
+ return CelEvaluationResult(
271
+ matched=True,
272
+ verdict=BailVerdict.bail("gate:payload_nonempty failed — no input MCard", expr),
273
+ )
274
+ if _is_payload_empty(inp):
275
+ return CelEvaluationResult(
276
+ matched=True,
277
+ verdict=BailVerdict.bail("gate:payload_nonempty failed — input payload is empty", expr),
278
+ )
279
+ return CelEvaluationResult(matched=True, verdict=BailVerdict.pass_verdict())
280
+
281
+ if lower == "gate:result_sealed":
282
+ out = context.get("output") or context.get("input")
283
+ if out is None or not getattr(out, "hash", None):
284
+ return CelEvaluationResult(
285
+ matched=True,
286
+ verdict=BailVerdict.bail("gate:result_sealed failed — output MCard has no sealed hash", expr),
287
+ )
288
+ return CelEvaluationResult(matched=True, verdict=BailVerdict.pass_verdict())
289
+
290
+ if lower == "gate:authorized":
291
+ card = context.get("input")
292
+ author = ""
293
+ if isinstance(card, dict):
294
+ author = str(card.get("author", "") or "")
295
+ elif card is not None:
296
+ author = str(getattr(card, "author", "") or "")
297
+ if not author.startswith("did:"):
298
+ return CelEvaluationResult(
299
+ matched=True,
300
+ verdict=BailVerdict.bail("gate:authorized failed — ungrounded DID", expr),
301
+ )
302
+ return CelEvaluationResult(matched=True, verdict=BailVerdict.pass_verdict())
303
+
304
+ # 2. Metadata field existence: exists:field
305
+ if lower.startswith("exists:"):
306
+ field_name = expr[7:].strip()
307
+ card = context.get("input")
308
+ has_field = False
309
+ if isinstance(card, dict):
310
+ meta = card.get("metadata", {})
311
+ if isinstance(meta, dict) and field_name in meta or field_name in card:
312
+ has_field = True
313
+ elif card is not None:
314
+ meta = getattr(card, "metadata", None)
315
+ if isinstance(meta, dict) and field_name in meta or hasattr(meta, "has") and meta.has(field_name) or hasattr(card, field_name):
316
+ has_field = True
317
+
318
+ if not has_field and "variables" in context and isinstance(context["variables"], dict):
319
+ has_field = field_name in context["variables"]
320
+ if not has_field and field_name in context:
321
+ has_field = True
322
+
323
+ if has_field:
324
+ return CelEvaluationResult(matched=True, verdict=BailVerdict.pass_verdict())
325
+ return CelEvaluationResult(
326
+ matched=True,
327
+ verdict=BailVerdict.bail(f'Field "{field_name}" not found in metadata', expr),
328
+ )
329
+
330
+ # 3. Type check: type:kind
331
+ if lower.startswith("type:"):
332
+ expected_kind = expr[5:].strip()
333
+ card = context.get("input")
334
+ actual_kind = None
335
+ if isinstance(card, dict):
336
+ payload = card.get("payload")
337
+ if isinstance(payload, dict):
338
+ actual_kind = payload.get("kind")
339
+ else:
340
+ actual_kind = card.get("kind")
341
+ elif card is not None:
342
+ payload = getattr(card, "payload", None)
343
+ actual_kind = getattr(payload, "kind", None) if payload else None
344
+ if actual_kind is None and isinstance(payload, dict):
345
+ actual_kind = payload.get("kind")
346
+
347
+ if actual_kind == expected_kind:
348
+ return CelEvaluationResult(matched=True, verdict=BailVerdict.pass_verdict())
349
+ return CelEvaluationResult(
350
+ matched=True,
351
+ verdict=BailVerdict.bail(
352
+ f'Expected payload kind "{expected_kind}", got "{actual_kind}"', expr
353
+ ),
354
+ )
355
+
356
+ # 4. Built-in size checks e.g. size(str) > 0
357
+ size_match = re.match(r"^size\(([^)]+)\)\s*(==|!=|<=|>=|<|>)\s*(.*)$", expr)
358
+ if size_match:
359
+ var_name, op, right_str = size_match.groups()
360
+ val = _resolve_context_value(var_name, context)
361
+ length = len(val) if val is not None and hasattr(val, "__len__") else 0
362
+ right_val = _parse_scalar_literal(right_str)
363
+ passed = _compare_values(length, op, right_val)
364
+ if passed:
365
+ return CelEvaluationResult(matched=True, verdict=BailVerdict.pass_verdict(), evaluated_value=passed)
366
+ return CelEvaluationResult(
367
+ matched=True,
368
+ verdict=BailVerdict.bail(f"Size constraint failed: size({var_name})={length} {op} {right_val}", expr),
369
+ evaluated_value=passed,
370
+ )
371
+
372
+ # 5. Comparison: leftKey op rightVal
373
+ comp_match = re.match(r"^([a-zA-Z0-9_.()]+)\s*(==|!=|<=|>=|<|>)\s*(.*)$", expr)
374
+ if comp_match:
375
+ left_key, op, right_str = comp_match.groups()
376
+ left_val = _parse_scalar_literal(left_key)
377
+ if isinstance(left_val, str) and not (left_key.startswith('"') or left_key.startswith("'")):
378
+ resolved_left = _resolve_context_value(left_key, context)
379
+ if resolved_left is not None:
380
+ left_val = resolved_left
381
+ elif left_key not in ("true", "false", "null"):
382
+ left_val = None
383
+
384
+ right_val = _parse_scalar_literal(right_str)
385
+ if isinstance(right_val, str) and not (right_str.startswith('"') or right_str.startswith("'")):
386
+ resolved_right = _resolve_context_value(right_val, context)
387
+ if resolved_right is not None:
388
+ right_val = resolved_right
389
+
390
+ result = _compare_values(left_val, op, right_val)
391
+ if result:
392
+ return CelEvaluationResult(matched=True, verdict=BailVerdict.pass_verdict(), evaluated_value=result)
393
+ return CelEvaluationResult(
394
+ matched=True,
395
+ verdict=BailVerdict.bail(f"Comparison failed: {left_key} ({left_val}) {op} {right_str}", expr),
396
+ evaluated_value=result,
397
+ )
398
+
399
+ # 6. Boolean identifier / property lookup e.g. "is_valid", "rlcd(decision).is_admissible"
400
+ val = _resolve_context_value(expr, context)
401
+ if val is not None:
402
+ if bool(val):
403
+ return CelEvaluationResult(matched=True, verdict=BailVerdict.pass_verdict(), evaluated_value=True)
404
+ return CelEvaluationResult(
405
+ matched=True,
406
+ verdict=BailVerdict.bail(f"Boolean expression '{expr}' evaluated to {val}", expr),
407
+ evaluated_value=False,
408
+ )
409
+
410
+ # Default fallback
411
+ return CelEvaluationResult(matched=False, verdict=BailVerdict.pass_verdict())
412
+
413
+ @classmethod
414
+ def _evaluate_impl(cls, expr: str, context: dict | None = None) -> CelEvaluationResult:
415
+ if context is None:
416
+ context = {}
417
+ expr = expr.strip()
418
+ if not expr:
419
+ return CelEvaluationResult(matched=True, verdict=BailVerdict.pass_verdict())
420
+
421
+ # Handle logical AND (&&)
422
+ if "&&" in expr:
423
+ parts = [p.strip() for p in expr.split("&&")]
424
+ for part in parts:
425
+ res = cls._evaluate_impl(part, context)
426
+ if not res.passed:
427
+ return res
428
+ return CelEvaluationResult(matched=True, verdict=BailVerdict.pass_verdict())
429
+
430
+ # Handle logical OR (||)
431
+ if "||" in expr:
432
+ parts = [p.strip() for p in expr.split("||")]
433
+ last_res = None
434
+ for part in parts:
435
+ res = cls._evaluate_impl(part, context)
436
+ if res.passed:
437
+ return res
438
+ last_res = res
439
+ return last_res or CelEvaluationResult(
440
+ matched=True,
441
+ verdict=BailVerdict.bail(f"All branches of OR failed: {expr}", expr),
442
+ )
443
+
444
+ return cls.evaluate_atomic(expr, context)
445
+
446
+ evaluate = _EvaluatorDescriptor()
447
+
448
+ @classmethod
449
+ def evaluate_vcard_meet(
450
+ cls,
451
+ input_card: Any,
452
+ output_card: Any,
453
+ v_pre: str | list[str] | None = None,
454
+ v_post: str | list[str] | None = None,
455
+ context: dict | None = None,
456
+ ) -> bool:
457
+ """Evaluates formal lattice meet: T_valid = T_cand ∧ V_pre ∧ V_post.
458
+
459
+ Returns True if all preconditions and postconditions hold, else False (collapses to ⊥).
460
+ """
461
+ ctx = dict(context or {})
462
+ ctx["input"] = input_card
463
+ ctx["output"] = output_card
464
+
465
+ pre_list = []
466
+ if isinstance(v_pre, str):
467
+ pre_list = [v_pre]
468
+ elif isinstance(v_pre, list):
469
+ pre_list = v_pre
470
+
471
+ for cond in pre_list:
472
+ res = cls.evaluate(cond, ctx)
473
+ if not res.passed:
474
+ return False
475
+
476
+ post_list = []
477
+ if isinstance(v_post, str):
478
+ post_list = [v_post]
479
+ elif isinstance(v_post, list):
480
+ post_list = v_post
481
+
482
+ for cond in post_list:
483
+ res = cls.evaluate(cond, ctx)
484
+ if not res.passed:
485
+ return False
486
+
487
+ return True
488
+
489
+
490
+ evaluate_vcard_meet = CelEvaluator.evaluate_vcard_meet
491
+
clm/layer0/codec.py ADDED
@@ -0,0 +1,106 @@
1
+ """Layer 0: Stateless Kenotic Codecs & Canonical Serialization.
2
+
3
+ Canonical Path: kernel/scripts/clm/layer0/codec.py
4
+ Parity: Rust `src/layer0/codec.rs`, TypeScript `src/layer0/codec.ts`
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import json
10
+ from typing import Any
11
+
12
+ import yaml
13
+
14
+ _B58_ALPHABET = b"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
15
+ _B58_MAP = [-1] * 128
16
+ for i, c in enumerate(_B58_ALPHABET):
17
+ _B58_MAP[c] = i
18
+
19
+
20
+ def to_hex(data: bytes) -> str:
21
+ """Encode bytes to lowercase hexadecimal string."""
22
+ return data.hex().lower()
23
+
24
+
25
+ def from_hex(hex_str: str) -> bytes:
26
+ """Decode hexadecimal string into bytes."""
27
+ return bytes.fromhex(hex_str.strip())
28
+
29
+
30
+ def to_base58(data: bytes) -> str:
31
+ """Encode bytes to Base58 string (Bitcoin alphabet)."""
32
+ zeroes = 0
33
+ while zeroes < len(data) and data[zeroes] == 0:
34
+ zeroes += 1
35
+
36
+ size = (len(data) - zeroes) * 138 // 100 + 1
37
+ b58 = bytearray(size)
38
+
39
+ for b in data[zeroes:]:
40
+ carry = b
41
+ j = 0
42
+ for k in range(size - 1, -1, -1):
43
+ if carry == 0 and j >= size:
44
+ break
45
+ carry += 256 * b58[k]
46
+ b58[k] = carry % 58
47
+ carry //= 58
48
+ j += 1
49
+
50
+ it = 0
51
+ while it < size and b58[it] == 0:
52
+ it += 1
53
+
54
+ res = "1" * zeroes + "".join(chr(_B58_ALPHABET[d]) for d in b58[it:])
55
+ return res
56
+
57
+
58
+ def from_base58(s: str) -> bytes:
59
+ """Decode Base58 string into bytes."""
60
+ clean = s.strip()
61
+ zeroes = 0
62
+ while zeroes < len(clean) and clean[zeroes] == "1":
63
+ zeroes += 1
64
+
65
+ size = len(clean) * 733 // 1000 + 1
66
+ b256 = bytearray(size)
67
+
68
+ for ch in clean[zeroes:]:
69
+ code = ord(ch)
70
+ if code >= 128 or _B58_MAP[code] == -1:
71
+ raise ValueError(f"Invalid Base58 character: {ch}")
72
+ carry = _B58_MAP[code]
73
+ j = 0
74
+ for k in range(size - 1, -1, -1):
75
+ if carry == 0 and j >= size:
76
+ break
77
+ carry += 58 * b256[k]
78
+ b256[k] = carry % 256
79
+ carry //= 256
80
+ j += 1
81
+
82
+ it = 0
83
+ while it < size and b256[it] == 0:
84
+ it += 1
85
+
86
+ return bytes(zeroes) + bytes(b256[it:])
87
+
88
+
89
+ def _sort_json_value(val: Any) -> Any:
90
+ if isinstance(val, dict):
91
+ return {k: _sort_json_value(v) for k, v in sorted(val.items())}
92
+ if isinstance(val, list):
93
+ return [_sort_json_value(x) for x in val]
94
+ return val
95
+
96
+
97
+ def canonical_json(val: Any) -> str:
98
+ """Canonical JSON serialization with recursively sorted keys and no whitespace."""
99
+ sorted_obj = _sort_json_value(val)
100
+ return json.dumps(sorted_obj, sort_keys=True, separators=(",", ":"), ensure_ascii=False)
101
+
102
+
103
+ def canonical_yaml(val: Any) -> str:
104
+ """Canonical YAML serialization."""
105
+ sorted_obj = _sort_json_value(val)
106
+ return yaml.safe_dump(sorted_obj, sort_keys=True)