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,321 @@
1
+ """Cross-Cutting — MCard (Σ-type / Data Plane / Carrier)
2
+
3
+ MCard is the root type / Dependent Sum (Σ-type) of the MVP Cards triad.
4
+ It is the irreducible, content-addressed, immutable unit of data.
5
+ Every other card (PCard, VCard) is ultimately stored *as* an MCard
6
+ (the Empty Schema Principle).
7
+
8
+ Design references:
9
+ - MVP Cards Design Rationale (§MCard — Data Plane)
10
+ - The Empty Schema Principle
11
+ - Function-Number Duality
12
+ """
13
+
14
+ import os
15
+ import time
16
+ from typing import Any, Literal
17
+
18
+ from pydantic import BaseModel, Field
19
+
20
+ from clm.cross_cutting.telemetry import jsonl_emit_typed
21
+ from clm.cross_cutting.timeutil import default_agent_did as _default_agent_did
22
+ from clm.cross_cutting.timeutil import now_g_time as _now_g_time
23
+ from clm.layer0.context import CLMContext
24
+ from clm.layer0.utils import clm_hash_string as hash_string
25
+ from clm.layer0.utils import prefixed_hash_raw
26
+
27
+ # Unified Card Model (Sprint 131.1)
28
+ # ---------------------------------------------------------------------------
29
+
30
+ _TOKEN_WRAPPER = {
31
+ "mcard": "mcard",
32
+ "state": "state_token",
33
+ "pcard": "pcard_token",
34
+ "vcard": "vcard_token",
35
+ }
36
+ _WRAPPER_TO_TOKEN = {v: k for k, v in _TOKEN_WRAPPER.items()}
37
+
38
+
39
+ class Card(BaseModel):
40
+ """The unified Monadic Card primitive (Sprint 131).
41
+
42
+ CLM is the single meta-language; this is its one object. ``token_type``
43
+ selects both the MLTT role and the YAML wrapper key emitted by
44
+ :meth:`to_yaml`, preserving byte-parity with the four legacy manual
45
+ formatters (``make_mcard_content``, ``emit_state_token``,
46
+ ``serialize_pcard``, ``vcard_gate``):
47
+
48
+ mcard -> mcard: (Σ-type / Noun Phrase / data plane)
49
+ state -> state_token: (Σ-subtype / PCard output snapshot)
50
+ pcard -> pcard_token: (Π-type / Verb Phrase / control plane)
51
+ vcard -> vcard_token: (Id-type / Sentence / verification witness)
52
+ """
53
+ token_type: Literal["mcard", "state", "pcard", "vcard"] = "mcard"
54
+ g_time: str = Field(default_factory=_now_g_time)
55
+ agent_did: str = Field(default_factory=_default_agent_did)
56
+ timestamp: str | None = None
57
+ operation: str | None = None
58
+
59
+ # mcard (data) payload
60
+ content_hash: str | None = None
61
+ content: str | None = None
62
+ source: dict[str, str] | None = None
63
+ runtime_facts: Any | None = None
64
+
65
+ # state (PCard output) payload
66
+ producer_pcard_hash: str | None = None
67
+ vcard_dispatch_hash: str | None = None
68
+ content_snapshot: str | None = None
69
+
70
+ # pcard (control) payload
71
+ runtime: str | None = None
72
+ script_hash: str | None = None
73
+ input_place_hashes: list[str] = Field(default_factory=list)
74
+ pcard_hash: str | None = None
75
+
76
+ # vcard (witness) payload
77
+ gate_type: Literal["callback", "dispatch"] | None = None
78
+ result: Literal["pass", "fail"] | None = None
79
+ sponsor_did: str | None = None
80
+ delegation_proof: str | None = None
81
+ execution_locale_hash: str | None = None
82
+ transport_ref: str | None = None
83
+ failure_reason: str | None = None
84
+ triggering_dispatch_hash: str | None = None
85
+ downstream_callback_targets: list[str] | None = None
86
+
87
+ # Sprint 132.5: cached hash (manual _hash_cache instead of frozen=True +
88
+ # cached_property, to avoid breaking list[str]/Any fields per spec §9.4).
89
+ _hash_cache: str | None = None
90
+
91
+ def __setattr__(self, name: str, value: Any) -> None:
92
+ if name != "_hash_cache" and hasattr(self, "_hash_cache"):
93
+ object.__setattr__(self, "_hash_cache", None)
94
+ super().__setattr__(name, value)
95
+
96
+ # -- serialization ------------------------------------------------
97
+
98
+ def _q(self, v: Any) -> str:
99
+ """Quote a scalar the way the legacy formatters do (always double-quoted)."""
100
+ s = str(v).replace("\\", "\\\\").replace('"', '\\"')
101
+ return f'"{s}"'
102
+
103
+ def _yaml_list(self, key: str, items: list[str] | None, indent: str = " ") -> str:
104
+ """Render a list field exactly like the legacy formatters."""
105
+ if not items:
106
+ return f"{indent}{key}: []"
107
+ out = f"{indent}{key}:\n"
108
+ for h in items:
109
+ out += f'{indent} - {self._q(h)}\n'
110
+ return out.rstrip("\n")
111
+
112
+ def to_yaml(self) -> str:
113
+ """Canonical YAML with the wrapper key preserved.
114
+
115
+ Byte-parity target for the four legacy formatters. Each token_type
116
+ emits only the fields its legacy counterpart emits, in the same
117
+ order, with the same double-quoting and 4-space list indentation.
118
+ """
119
+ tt = self.token_type
120
+ if tt == "mcard":
121
+ src = self.source or {}
122
+ parts = ["mcard:"]
123
+ parts.append(f' g_time: {self._q(self.g_time)}')
124
+ if self.content_hash is not None:
125
+ parts.append(f' content_hash: {self._q(self.content_hash)}')
126
+ if src:
127
+ parts.append(" source:")
128
+ for k in ("filename", "mime_type", "encoding"):
129
+ if k in src:
130
+ parts.append(f' {k}: {self._q(src[k])}')
131
+ if self.content is not None:
132
+ parts.append(f' content: {self._q(self.content)}')
133
+ return "\n".join(parts) + "\n"
134
+
135
+ if tt == "pcard":
136
+ parts = ["pcard_token:"]
137
+ parts.append(f' operation: {self._q(self.operation or "")}')
138
+ parts.append(f' runtime: {self._q(self.runtime or "")}')
139
+ parts.append(f' script_hash: {self._q(self.script_hash or "")}')
140
+ parts.append(f' timestamp: {self._q(self.timestamp or "")}')
141
+ parts.append(self._yaml_list("input_place_hashes", self.input_place_hashes))
142
+ return "\n".join(parts)
143
+
144
+ if tt == "state":
145
+ parts = ["state_token:"]
146
+ parts.append(f' token_type: {self._q("state")}')
147
+ parts.append(f' producer_pcard_hash: {self._q(self.producer_pcard_hash or "")}')
148
+ parts.append(f' vcard_dispatch_hash: {self._q(self.vcard_dispatch_hash or "")}')
149
+ parts.append(f' timestamp: {self._q(self.timestamp or "")}')
150
+ parts.append(f' agent_did: {self._q(self.agent_did)}')
151
+ parts.append(f' content_snapshot: {self._q(self.content_snapshot or "")}')
152
+ return "\n".join(parts)
153
+
154
+ if tt == "vcard":
155
+ parts = ["vcard_token:"]
156
+ parts.append(f' gate_type: {self._q(self.gate_type or "")}')
157
+ parts.append(f' result: {self._q(self.result or "")}')
158
+ parts.append(f' pcard_hash: {self._q(self.pcard_hash or "")}')
159
+ if self.gate_type == "callback":
160
+ parts.append(f' triggering_dispatch_hash: {self._q(self.triggering_dispatch_hash or "")}')
161
+ parts.append(f' timestamp: {self._q(self.timestamp or "")}')
162
+ parts.append(f' agent_did: {self._q(self.agent_did)}')
163
+ parts.append(f' sponsor_did: {self._q(self.sponsor_did or "")}')
164
+ parts.append(f' delegation_proof: {self._q(self.delegation_proof or "")}')
165
+ parts.append(f' execution_locale_hash: {self._q(self.execution_locale_hash or "")}')
166
+ parts.append(f' transport_ref: {self._q(self.transport_ref or "")}')
167
+ if self.failure_reason is not None:
168
+ parts.append(f' failure_reason: {self._q(self.failure_reason)}')
169
+ if self.gate_type == "callback":
170
+ # callback mode omits input_place_hashes entirely when empty
171
+ # (matches legacy formatter); only renders when non-empty
172
+ if self.input_place_hashes:
173
+ parts.append(self._yaml_list("input_place_hashes", self.input_place_hashes))
174
+ else:
175
+ parts.append(self._yaml_list("downstream_callback_targets", self.downstream_callback_targets))
176
+ return "\n".join(parts)
177
+
178
+ raise ValueError(f"Unknown token_type: {tt}")
179
+
180
+ @classmethod
181
+ def from_yaml(cls, yaml_str: str) -> "Card":
182
+ """Parse a Card from its wrapper-key YAML representation."""
183
+ import yaml
184
+ data = yaml.safe_load(yaml_str)
185
+ if isinstance(data, dict) and len(data) == 1:
186
+ wrapper, payload = next(iter(data.items()))
187
+ token_type = _WRAPPER_TO_TOKEN.get(wrapper, "mcard")
188
+ if isinstance(payload, dict):
189
+ return cls(**{**payload, "token_type": token_type})
190
+ raise ValueError(f"Unrecognized card YAML: {yaml_str[:80]!r}")
191
+
192
+ def compute_hash(self) -> str:
193
+ """SHA-256 of the canonical YAML (deterministic, cached).
194
+
195
+ Sprint 132.5: result is cached via ``_hash_cache`` and invalidated
196
+ on any field mutation via ``__setattr__``.
197
+ """
198
+ if self._hash_cache is None:
199
+ object.__setattr__(self, "_hash_cache", hash_string(self.to_yaml()))
200
+ return self._hash_cache
201
+
202
+
203
+ # ---------------------------------------------------------------------------
204
+ # Sprint 384 (DEL-384-02): Re-export canonical MCard from Layer 0 card_triad
205
+ from clm.layer0.model.card_triad import MCard # noqa: F401
206
+
207
+ # ---------------------------------------------------------------------------
208
+
209
+ def emit_state_token(
210
+ ctx: CLMContext,
211
+ pcard_hash: str,
212
+ vcard_dispatch_hash: str,
213
+ content_input: str,
214
+ ) -> str:
215
+ """Emit a state token MCard and persist it to the execution log.
216
+
217
+ A state token captures the output of a PCard execution as a new
218
+ MCard, maintaining the algebraic closure invariant:
219
+ PCard(MCard) → MCard'.
220
+
221
+ Sprint 131.5: YAML emission now delegates to ``Card(token_type="state", ...).to_yaml()``
222
+ so the unified model is the single source of truth; the ``save_card_and_handle``,
223
+ ``jsonl_emit``, and on-disk log side effects are preserved.
224
+ """
225
+ timestamp = _now_g_time()
226
+ agent_did = _default_agent_did()
227
+
228
+ if os.path.exists(content_input):
229
+ file_size = os.path.getsize(content_input)
230
+ if file_size > 4096:
231
+ with open(content_input, "rb") as f:
232
+ h = hash_string(f.read())
233
+ content_snapshot = prefixed_hash_raw(h)
234
+ else:
235
+ with open(content_input, encoding="utf-8") as f:
236
+ content_snapshot = f.read()
237
+ else:
238
+ content_snapshot = content_input
239
+
240
+ state_yaml = Card(
241
+ token_type="state",
242
+ producer_pcard_hash=pcard_hash,
243
+ vcard_dispatch_hash=vcard_dispatch_hash,
244
+ timestamp=timestamp,
245
+ agent_did=agent_did,
246
+ content_snapshot=content_snapshot,
247
+ ).to_yaml()
248
+
249
+ state_hash = hash_string(state_yaml)
250
+ handle_name = f"mcard:state:{state_hash}"
251
+ ctx.repo.save_card_and_handle(
252
+ handle_name, state_hash, state_yaml, "execution_log",
253
+ timestamp=timestamp, replace=False,
254
+ )
255
+
256
+ jsonl_emit_typed("state_emitted", {
257
+ "state_hash": state_hash,
258
+ "producer_pcard_hash": pcard_hash,
259
+ "vcard_dispatch_hash": vcard_dispatch_hash,
260
+ }, ctx.root)
261
+
262
+ if not ctx.zero_fs:
263
+ logs_dir = os.path.join(ctx.root, "data", "execution_logs")
264
+ os.makedirs(logs_dir, exist_ok=True)
265
+ unix_ts = int(time.time())
266
+ log_file = os.path.join(logs_dir, f"state_{unix_ts}_{state_hash[:8]}.yaml")
267
+ with open(log_file, "w", encoding="utf-8") as fh:
268
+ fh.write(state_yaml)
269
+
270
+ return state_hash
271
+
272
+
273
+ def emit_state_failed(
274
+ ctx: CLMContext,
275
+ pcard_hash: str,
276
+ exit_code: str,
277
+ reason: str,
278
+ ) -> None:
279
+ """Emit a state-failed event for a PCard that did not complete."""
280
+ jsonl_emit_typed("state_failed", {
281
+ "pcard_hash": pcard_hash,
282
+ "exit_code": exit_code,
283
+ "reason": reason,
284
+ }, ctx.root)
285
+
286
+
287
+ def make_mcard_content(
288
+ content_hash: str,
289
+ content: str,
290
+ filename: str = "test.txt",
291
+ mime: str = "text/plain",
292
+ ) -> str:
293
+ """Return a canonical MCard YAML content block (Sprint 131.5: thin delegate).
294
+
295
+ Delegates to :class:`Card` so the unified model is the single source of
296
+ truth for serialization, while preserving the exact signature and output
297
+ that ``build_store``'s ``services.modules`` injection and the
298
+ ``make_mcard_content`` CLM expression op depend on.
299
+ """
300
+ return Card(
301
+ token_type="mcard",
302
+ g_time="sha256|2026-04-29T00:00:00+0800|Asia/Makassar",
303
+ content_hash=content_hash,
304
+ content=content,
305
+ source={"filename": filename, "mime_type": mime, "encoding": "inline"},
306
+ ).to_yaml()
307
+
308
+
309
+ # Sprint 133.1: moved from layer0/db.py — parses MCard YAML, belongs with Card.
310
+ def parse_yaml_mcard(mcard_content_str: str) -> tuple[str | None, str | None, str | None]:
311
+ """Extract content_hash, g_time, and source filename from MCard YAML."""
312
+ import re
313
+ hash_match = re.search(r'content_hash:\s*["\']?([a-fA-F0-9]{64})["\']?', mcard_content_str)
314
+ gtime_match = re.search(r'g_time:\s*["\']?([^"\n\']+)["\']?', mcard_content_str)
315
+ filename_match = re.search(r'filename:\s*["\']?([^"\n\']+)["\']?', mcard_content_str)
316
+
317
+ content_hash = hash_match.group(1) if hash_match else None
318
+ g_time = gtime_match.group(1) if gtime_match else None
319
+ source_filename = filename_match.group(1) if filename_match else None
320
+
321
+ return content_hash, g_time, source_filename
@@ -0,0 +1,185 @@
1
+ """Native acceleration dispatcher with transparent pure-Python fallback.
2
+
3
+ Provides high-performance in-memory bindings to the Rust core runtime (_rust)
4
+ via PyO3 when compiled wheels or maturin development environments are available.
5
+ Automatically falls back to pure-Python implementations when native extensions
6
+ are absent, ensuring zero runtime disruption in interpreted environments.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import json
12
+ from typing import Any, Callable, Optional, Union
13
+
14
+ from clm.cross_cutting.clm_logger import get_logger
15
+
16
+ _logger = get_logger("clm.native")
17
+
18
+ try:
19
+ from clm import _rust # type: ignore[attr-defined]
20
+ HAS_RUST_ACCELERATION: bool = True
21
+ except (ImportError, ModuleNotFoundError):
22
+ try:
23
+ import clm_rust_core as _rust # type: ignore[no-redef]
24
+ HAS_RUST_ACCELERATION = True
25
+ except (ImportError, ModuleNotFoundError):
26
+ try:
27
+ import _rust # type: ignore[no-redef]
28
+ HAS_RUST_ACCELERATION = True
29
+ except (ImportError, ModuleNotFoundError):
30
+ _rust = None # type: ignore[assignment]
31
+ HAS_RUST_ACCELERATION = False
32
+ _logger.debug("Rust native extension (_rust) unavailable; utilizing pure-Python engine.")
33
+
34
+
35
+ def compute_blake3(data: Union[bytes, bytearray, memoryview, str]) -> str:
36
+ """Compute cryptographic hash via native Rust engine if available, or Python fallback.
37
+
38
+ Args:
39
+ data: Input bytes or string to hash.
40
+
41
+ Returns:
42
+ Hex-encoded hash digest string.
43
+ """
44
+ raw_bytes = data.encode("utf-8") if isinstance(data, str) else bytes(data)
45
+
46
+ if HAS_RUST_ACCELERATION and _rust is not None:
47
+ try:
48
+ return _rust.blake3_hash_bytes(raw_bytes)
49
+ except Exception as e:
50
+ _logger.warning(f"Native blake3_hash_bytes failed ({e}); falling back to Python.")
51
+
52
+ # Pure-Python fallback using layer0 cryptographic hash
53
+ from clm.layer0.hash import compute_blake3 as _l0_blake3
54
+ return _l0_blake3(raw_bytes)
55
+
56
+
57
+ def clm_hash_file_fast(path: str) -> str:
58
+ """Compute content hash for a file, releasing GIL in Rust or using Python fallback.
59
+
60
+ Args:
61
+ path: Filesystem path to the target file.
62
+
63
+ Returns:
64
+ Hex-encoded content hash string.
65
+ """
66
+ if HAS_RUST_ACCELERATION and _rust is not None:
67
+ try:
68
+ return _rust.clm_hash_file(path)
69
+ except Exception as e:
70
+ _logger.warning(f"Native clm_hash_file failed ({e}); falling back to Python.")
71
+
72
+ from clm.layer0.utils import clm_hash_file
73
+ return clm_hash_file(path)
74
+
75
+
76
+ def crdt_merge_fast(log_a_json: str, log_b_json: str) -> str:
77
+ """Merge two CRDT logs idempotently via native Rust engine or pure-Python fallback.
78
+
79
+ Args:
80
+ log_a_json: Primary CRDT log serialized as JSON.
81
+ log_b_json: Secondary CRDT log serialized as JSON.
82
+
83
+ Returns:
84
+ Merged CRDT log serialized as JSON.
85
+ """
86
+ if HAS_RUST_ACCELERATION and _rust is not None and hasattr(_rust, "crdt_merge"):
87
+ try:
88
+ return _rust.crdt_merge(log_a_json, log_b_json)
89
+ except Exception as e:
90
+ _logger.warning(f"Native crdt_merge failed ({e}); falling back to Python.")
91
+
92
+ # Pure Python JSON-level idempotent union fallback
93
+ try:
94
+ a = json.loads(log_a_json)
95
+ b = json.loads(log_b_json)
96
+ key = "entries" if "entries" in a else "events"
97
+ events_a = a.get(key, [])
98
+ events_b = b.get(key, [])
99
+ seen_ids = {e.get("event_id") for e in events_a if "event_id" in e}
100
+ for ev in events_b:
101
+ eid = ev.get("event_id")
102
+ if eid and eid not in seen_ids:
103
+ events_a.append(ev)
104
+ seen_ids.add(eid)
105
+ a[key] = events_a
106
+ return json.dumps(a)
107
+ except Exception:
108
+ return log_a_json
109
+
110
+
111
+ ManifestEvaluatorFn = Callable[[str], Any]
112
+ _manifest_evaluator: ManifestEvaluatorFn | None = None
113
+ _manifest_evaluator_resolver: Callable[[], ManifestEvaluatorFn | None] | None = None
114
+
115
+
116
+ def register_manifest_evaluator(evaluator: ManifestEvaluatorFn) -> None:
117
+ """Register a manifest evaluator callback (Dependency Inversion for layer stratification)."""
118
+ global _manifest_evaluator
119
+ _manifest_evaluator = evaluator
120
+
121
+
122
+ def register_manifest_evaluator_resolver(resolver: Callable[[], ManifestEvaluatorFn | None]) -> None:
123
+ """Register a lazy resolver for the manifest evaluator."""
124
+ global _manifest_evaluator_resolver
125
+ _manifest_evaluator_resolver = resolver
126
+
127
+
128
+ def evaluate_manifest(manifest_yaml: str) -> str:
129
+ """Evaluate manifest using in-memory native CPN-VM or pure-Python verifier.
130
+
131
+ Propagates active Cordis monadic context (session_id, agent_did, trace_id)
132
+ across the FFI boundary. Falls back to Python verifier if Rust extension is absent
133
+ or encounters error.
134
+
135
+ Args:
136
+ manifest_yaml: Raw YAML string of the CLM specification.
137
+
138
+ Returns:
139
+ Evaluation result string or generated MCard handle.
140
+ """
141
+ from clm.layer0.context import CLMContext
142
+ current_ctx = CLMContext.current()
143
+ context_json: Optional[str] = None
144
+ if current_ctx is not None:
145
+ context_json = json.dumps({
146
+ "session_id": getattr(current_ctx, "session_id", None),
147
+ "agent_did": getattr(current_ctx, "agent_did", None),
148
+ "trace_id": getattr(current_ctx, "trace_id", None),
149
+ "zero_fs": getattr(current_ctx, "zero_fs", False),
150
+ })
151
+
152
+ if HAS_RUST_ACCELERATION and _rust is not None:
153
+ try:
154
+ return _rust.evaluate_manifest_fast(manifest_yaml, context_json)
155
+ except Exception as e:
156
+ _logger.warning(f"Native evaluate_manifest_fast failed ({e}); falling back to Python.")
157
+
158
+ if _manifest_evaluator is not None:
159
+ return _manifest_evaluator(manifest_yaml)
160
+
161
+ if _manifest_evaluator_resolver is not None:
162
+ evaluator = _manifest_evaluator_resolver()
163
+ if evaluator is not None:
164
+ return evaluator(manifest_yaml)
165
+
166
+ raise RuntimeError(
167
+ "No manifest evaluator registered with cross_cutting.native. "
168
+ "Initialize Layer 1 verifier (clm.layer1.verifier) before evaluating manifests."
169
+ )
170
+
171
+
172
+ def evaluate_in_process(clm_root: str, clm_file: str, payload: Optional[str] = None) -> Optional[tuple[int, str]]:
173
+ """Direct in-process evaluation of a CLM manifest via PyO3 C-extension without process forks.
174
+
175
+ Returns:
176
+ (exit_code, output) tuple, or None if native extension is unavailable.
177
+ """
178
+ if HAS_RUST_ACCELERATION and _rust is not None and hasattr(_rust, "evaluate_in_process"):
179
+ try:
180
+ return _rust.evaluate_in_process(clm_root, clm_file, payload)
181
+ except Exception as e:
182
+ _logger.warning(f"Native evaluate_in_process failed ({e}); falling back.")
183
+ return None
184
+ return None
185
+