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,133 @@
1
+ """Layer 3 Reticulum Link Transport (DEL-390-01).
2
+
3
+ Implements:
4
+ - Single-roundtrip ephemeral Link handshake (X25519 ECDH + HKDF)
5
+ - Authenticated AES-256 session encryption with Perfect Forward Secrecy (PFS)
6
+ - Initiator anonymity (packets omit sender identity)
7
+ - Clean session teardown with key zeroization
8
+ """
9
+ from __future__ import annotations
10
+
11
+ import hashlib
12
+ import os
13
+ import sys
14
+ from typing import Optional, Tuple
15
+
16
+ from cryptography.hazmat.primitives import hashes, serialization
17
+ from cryptography.hazmat.primitives.asymmetric import x25519
18
+ from cryptography.hazmat.primitives.ciphers.aead import AESGCM
19
+ from cryptography.hazmat.primitives.kdf.hkdf import HKDF
20
+
21
+ RETICULUM_PATH = os.path.expanduser("~/Documents/Development/Networking/Reticulum")
22
+ if RETICULUM_PATH not in sys.path and os.path.exists(RETICULUM_PATH):
23
+ sys.path.insert(0, RETICULUM_PATH)
24
+
25
+ try:
26
+ import RNS
27
+ except (ImportError, ModuleNotFoundError):
28
+ RNS = None # type: ignore
29
+
30
+
31
+ class ReticulumLinkSession:
32
+ """Manages an authenticated, encrypted point-to-point session between two
33
+ conversational PKC nodes over Reticulum transport.
34
+ """
35
+
36
+ def __init__(
37
+ self,
38
+ destination_hash: bytes,
39
+ is_initiator: bool = True,
40
+ link_id: Optional[bytes] = None,
41
+ ) -> None:
42
+ self.destination_hash = destination_hash
43
+ self.is_initiator = is_initiator
44
+ self.link_id = link_id or hashlib.sha256(os.urandom(32)).digest()[:16]
45
+ self._ephemeral_prv: Optional[x25519.X25519PrivateKey] = x25519.X25519PrivateKey.generate()
46
+ self._ephemeral_pub: Optional[x25519.X25519PublicKey] = self._ephemeral_prv.public_key()
47
+ self.derived_key: Optional[bytes] = None
48
+ self._cipher: Optional[AESGCM] = None
49
+ self._seq: int = 0
50
+ self.is_closed: bool = False
51
+
52
+ @property
53
+ def ephemeral_public_bytes(self) -> bytes:
54
+ if self._ephemeral_pub is None:
55
+ raise RuntimeError("Session is closed or key dropped")
56
+ return self._ephemeral_pub.public_bytes(
57
+ encoding=serialization.Encoding.Raw,
58
+ format=serialization.PublicFormat.Raw,
59
+ )
60
+
61
+ def complete_handshake(self, peer_ephemeral_pub_bytes: bytes) -> None:
62
+ """Executes X25519 ECDH exchange and HKDF key derivation using link_id as salt.
63
+ Derives 32-byte key for AES-256-GCM session cipher.
64
+ """
65
+ if self._ephemeral_prv is None:
66
+ raise RuntimeError("Session is closed")
67
+
68
+ peer_pub = x25519.X25519PublicKey.from_public_bytes(peer_ephemeral_pub_bytes)
69
+ shared_secret = self._ephemeral_prv.exchange(peer_pub)
70
+
71
+ hkdf = HKDF(
72
+ algorithm=hashes.SHA256(),
73
+ length=32,
74
+ salt=self.link_id,
75
+ info=b"clm:reticulum:link:session",
76
+ )
77
+ self.derived_key = hkdf.derive(shared_secret)
78
+ self._cipher = AESGCM(self.derived_key)
79
+
80
+ def encrypt(self, plaintext: bytes) -> bytes:
81
+ """Encrypts plaintext payload using AES-256-GCM.
82
+ Framing: [12-byte nonce (seq + random)] + [ciphertext + 16-byte tag]
83
+ Does NOT leak sender address (INV-L3-RET-355-03).
84
+ """
85
+ if self._cipher is None or self.is_closed:
86
+ raise RuntimeError("Cannot encrypt on unestablished or closed session")
87
+
88
+ self._seq += 1
89
+ nonce = self._seq.to_bytes(4, byteorder="big") + os.urandom(8)
90
+ ciphertext = self._cipher.encrypt(nonce, plaintext, associated_data=self.link_id)
91
+ return nonce + ciphertext
92
+
93
+ def decrypt(self, frame: bytes) -> bytes:
94
+ """Decrypts and authenticates AES-256-GCM frame."""
95
+ if self._cipher is None or self.is_closed:
96
+ raise RuntimeError("Cannot decrypt on unestablished or closed session")
97
+
98
+ if len(frame) < 12 + 16:
99
+ raise ValueError("Encrypted frame too short")
100
+
101
+ nonce = frame[:12]
102
+ ciphertext = frame[12:]
103
+ return self._cipher.decrypt(nonce, ciphertext, associated_data=self.link_id)
104
+
105
+ def close(self) -> None:
106
+ """Drops ephemeral keys and zeroes session key (INV-L3-RET-355-02: PFS)."""
107
+ self._ephemeral_prv = None
108
+ self._ephemeral_pub = None
109
+ self.derived_key = None
110
+ self._cipher = None
111
+ self.is_closed = True
112
+
113
+
114
+ def establish_link_pair(dest_hash: bytes) -> Tuple[ReticulumLinkSession, ReticulumLinkSession]:
115
+ """Helper that creates an initiator and responder session and handshakes them."""
116
+ link_id = hashlib.sha256(os.urandom(32)).digest()[:16]
117
+ initiator = ReticulumLinkSession(dest_hash, is_initiator=True, link_id=link_id)
118
+ responder = ReticulumLinkSession(dest_hash, is_initiator=False, link_id=link_id)
119
+
120
+ # Handshake exchange
121
+ initiator.complete_handshake(responder.ephemeral_public_bytes)
122
+ responder.complete_handshake(initiator.ephemeral_public_bytes)
123
+
124
+ return initiator, responder
125
+
126
+
127
+ ReticulumTransport = ReticulumLinkSession
128
+
129
+ __all__ = [
130
+ "ReticulumLinkSession",
131
+ "ReticulumTransport",
132
+ "establish_link_pair",
133
+ ]
@@ -0,0 +1,209 @@
1
+ """Satori Speech-Act, Delimited Continuation, Sheaf Consensus & Lambda Calculus Package (DEL-390-02).
2
+
3
+ Normative Reference:
4
+ docs/spec/20-architecture/system-architecture.md § 3 (Layer 3 Reticulum & Satori)
5
+ docs/spec/20-architecture/card-triad-architecture.md § Thermodynamic Maxwell's Demon Gate
6
+
7
+ Invariants:
8
+ INV-390-01: Searle-Austin Speech Act Taxonomy (Assertive, Directive, Commissive, Expressive, Declarative).
9
+ INV-390-02: Sheaf Cohomology Obstruction Vanishing (H¹ = 0 consensus, L = S_T - H_T).
10
+ INV-390-03: Delimited Conversational Continuations (prompt/shift turn execution).
11
+ """
12
+ from __future__ import annotations
13
+
14
+ # Lambda Term ADT
15
+ # Alpha Conversion
16
+ from clm.layer3.satori.alpha_conversion import (
17
+ alpha_equivalent,
18
+ alpha_normalize,
19
+ alpha_rename,
20
+ )
21
+
22
+ # Beta Reduction
23
+ from clm.layer3.satori.beta_reduction import (
24
+ NormalizationResult,
25
+ ReductionStrategy,
26
+ beta_reduce,
27
+ find_innermost_redex,
28
+ find_leftmost_redex,
29
+ has_normal_form,
30
+ is_normal_form,
31
+ is_redex,
32
+ normalize,
33
+ reduce_step,
34
+ substitute_with_capture,
35
+ )
36
+
37
+ # Delimited Continuations
38
+ from clm.layer3.satori.continuation import ContinuationToken
39
+
40
+ # Eta Conversion
41
+ from clm.layer3.satori.eta_conversion import (
42
+ beta_eta_normalize,
43
+ beta_eta_reduce,
44
+ eta_equivalent,
45
+ eta_expand,
46
+ eta_reduce,
47
+ fully_eta_reduce,
48
+ )
49
+
50
+ # Free Variables
51
+ from clm.layer3.satori.free_variables import (
52
+ bound_variables,
53
+ free_variables,
54
+ generate_fresh,
55
+ generate_fresh_for,
56
+ is_closed,
57
+ is_free_in,
58
+ )
59
+
60
+ # Lambda Runtime
61
+ from clm.layer3.satori.lambda_runtime import (
62
+ LambdaConfig,
63
+ LambdaOperation,
64
+ LambdaParser,
65
+ LambdaRuntime,
66
+ LambdaRuntimeResult,
67
+ ParseError,
68
+ parse_lambda_expression,
69
+ )
70
+ from clm.layer3.satori.lambda_term import (
71
+ AbsTerm,
72
+ AppTerm,
73
+ LambdaTerm,
74
+ VarTerm,
75
+ deserialize_term,
76
+ is_abs,
77
+ is_app,
78
+ is_var,
79
+ load_term,
80
+ mcard_to_term,
81
+ mk_abs,
82
+ mk_app,
83
+ mk_var,
84
+ pretty_print_deep,
85
+ pretty_print_shallow,
86
+ serialize_term,
87
+ store_term,
88
+ term_exists,
89
+ term_to_mcard,
90
+ )
91
+
92
+ # Sheaf Cohomology & Maxwell's Demon
93
+ from clm.layer3.satori.sheaf_audit import (
94
+ Marking,
95
+ OpenSet,
96
+ Place,
97
+ Section,
98
+ Sheaf,
99
+ SheafAuditor,
100
+ SheafAuditReport,
101
+ audit_maxwell_demon,
102
+ )
103
+
104
+ # Speech Acts & Binary AST
105
+ from clm.layer3.satori.speech_act import (
106
+ OPCODES_TO_TYPE,
107
+ SATORI_OPCODES,
108
+ SpeechAct,
109
+ SpeechActType,
110
+ classify_speech_act,
111
+ create_assert,
112
+ create_commissive,
113
+ create_commit,
114
+ create_declarative,
115
+ create_declare,
116
+ create_directive,
117
+ create_expressive,
118
+ create_request,
119
+ decode_satori_binary,
120
+ encode_satori_binary,
121
+ )
122
+
123
+ __all__ = [
124
+ # Speech Acts & Binary AST
125
+ "SATORI_OPCODES",
126
+ "OPCODES_TO_TYPE",
127
+ "SpeechActType",
128
+ "SpeechAct",
129
+ "encode_satori_binary",
130
+ "decode_satori_binary",
131
+ "classify_speech_act",
132
+ "create_assert",
133
+ "create_directive",
134
+ "create_request",
135
+ "create_commissive",
136
+ "create_commit",
137
+ "create_expressive",
138
+ "create_declarative",
139
+ "create_declare",
140
+ # Sheaf Cohomology & Maxwell's Demon
141
+ "Place",
142
+ "Marking",
143
+ "OpenSet",
144
+ "Section",
145
+ "Sheaf",
146
+ "SheafAuditReport",
147
+ "SheafAuditor",
148
+ "audit_maxwell_demon",
149
+ # Delimited Continuations
150
+ "ContinuationToken",
151
+ # Lambda Term ADT
152
+ "LambdaTerm",
153
+ "VarTerm",
154
+ "AbsTerm",
155
+ "AppTerm",
156
+ "mk_var",
157
+ "mk_abs",
158
+ "mk_app",
159
+ "serialize_term",
160
+ "deserialize_term",
161
+ "term_to_mcard",
162
+ "mcard_to_term",
163
+ "store_term",
164
+ "load_term",
165
+ "term_exists",
166
+ "pretty_print_shallow",
167
+ "pretty_print_deep",
168
+ "is_var",
169
+ "is_abs",
170
+ "is_app",
171
+ # Free Variables
172
+ "free_variables",
173
+ "bound_variables",
174
+ "is_free_in",
175
+ "is_closed",
176
+ "generate_fresh",
177
+ "generate_fresh_for",
178
+ # Alpha Conversion
179
+ "alpha_rename",
180
+ "alpha_equivalent",
181
+ "alpha_normalize",
182
+ # Beta Reduction
183
+ "ReductionStrategy",
184
+ "NormalizationResult",
185
+ "substitute_with_capture",
186
+ "is_redex",
187
+ "find_leftmost_redex",
188
+ "find_innermost_redex",
189
+ "beta_reduce",
190
+ "reduce_step",
191
+ "normalize",
192
+ "is_normal_form",
193
+ "has_normal_form",
194
+ # Eta Conversion
195
+ "eta_reduce",
196
+ "eta_expand",
197
+ "eta_equivalent",
198
+ "fully_eta_reduce",
199
+ "beta_eta_reduce",
200
+ "beta_eta_normalize",
201
+ # Lambda Runtime
202
+ "parse_lambda_expression",
203
+ "ParseError",
204
+ "LambdaParser",
205
+ "LambdaOperation",
206
+ "LambdaConfig",
207
+ "LambdaRuntimeResult",
208
+ "LambdaRuntime",
209
+ ]
@@ -0,0 +1,168 @@
1
+ """
2
+ Alpha Conversion - Variable renaming in Lambda Calculus
3
+
4
+ Alpha conversion (α-conversion) allows renaming of bound variables
5
+ without changing the meaning of the term:
6
+ λx.M ≡α λy.M[x:=y] (where y is fresh)
7
+
8
+ This module provides Python parity with mcard-js/src/ptr/lambda/AlphaConversion.ts
9
+ """
10
+
11
+ from clm.layer2.card_collection import CardCollection
12
+ from clm.layer3.satori.lambda_term import (
13
+ is_abs,
14
+ is_app,
15
+ is_var,
16
+ load_term,
17
+ mk_abs,
18
+ mk_app,
19
+ mk_var,
20
+ store_term,
21
+ )
22
+
23
+ # ─────────────────────────────────────────────────────────────────────────────
24
+ # Alpha Renaming
25
+ # ─────────────────────────────────────────────────────────────────────────────
26
+
27
+
28
+ def alpha_rename(
29
+ collection: CardCollection, hash_value: str, old_name: str, new_name: str
30
+ ) -> str | None:
31
+ """
32
+ Rename a bound variable in a Lambda term.
33
+ Returns the hash of the renamed term, or None if term not found.
34
+
35
+ Only renames the binding occurrence and all bound occurrences.
36
+ """
37
+ term = load_term(collection, hash_value)
38
+ if term is None:
39
+ return None
40
+
41
+ if is_var(term):
42
+ # Variable: rename if it matches
43
+ if term.name == old_name:
44
+ return store_term(collection, mk_var(new_name))
45
+ return hash_value
46
+
47
+ elif is_abs(term):
48
+ if term.param == old_name:
49
+ # This is the binder we're renaming
50
+ new_body = alpha_rename(collection, term.body, old_name, new_name)
51
+ if new_body is None:
52
+ return None
53
+ return store_term(collection, mk_abs(new_name, new_body))
54
+ else:
55
+ # Not bound here, recurse into body
56
+ new_body = alpha_rename(collection, term.body, old_name, new_name)
57
+ if new_body is None:
58
+ return None
59
+ return store_term(collection, mk_abs(term.param, new_body))
60
+
61
+ elif is_app(term):
62
+ new_func = alpha_rename(collection, term.func, old_name, new_name)
63
+ new_arg = alpha_rename(collection, term.arg, old_name, new_name)
64
+ if new_func is None or new_arg is None:
65
+ return None
66
+ return store_term(collection, mk_app(new_func, new_arg))
67
+
68
+ return hash_value
69
+
70
+
71
+ # ─────────────────────────────────────────────────────────────────────────────
72
+ # Alpha Equivalence
73
+ # ─────────────────────────────────────────────────────────────────────────────
74
+
75
+
76
+ def alpha_equivalent(
77
+ collection: CardCollection,
78
+ hash1: str,
79
+ hash2: str,
80
+ env: dict[str, str] | None = None,
81
+ ) -> bool | None:
82
+ """
83
+ Check if two Lambda terms are α-equivalent.
84
+
85
+ Two terms are α-equivalent if they differ only in the names of bound variables.
86
+ Uses a bijection to track corresponding bound variable names.
87
+ """
88
+ if env is None:
89
+ env = {}
90
+
91
+ term1 = load_term(collection, hash1)
92
+ term2 = load_term(collection, hash2)
93
+
94
+ if term1 is None or term2 is None:
95
+ return None
96
+
97
+ if is_var(term1) and is_var(term2):
98
+ # Check if variables correspond via environment
99
+ mapped = env.get(term1.name)
100
+ if mapped is not None:
101
+ return mapped == term2.name
102
+ # Not bound - must be same free variable
103
+ return term1.name == term2.name
104
+
105
+ elif is_abs(term1) and is_abs(term2):
106
+ # Extend environment with parameter correspondence
107
+ new_env = dict(env)
108
+ new_env[term1.param] = term2.param
109
+ return alpha_equivalent(collection, term1.body, term2.body, new_env)
110
+
111
+ elif is_app(term1) and is_app(term2):
112
+ func_eq = alpha_equivalent(collection, term1.func, term2.func, env)
113
+ if not func_eq:
114
+ return func_eq
115
+ return alpha_equivalent(collection, term1.arg, term2.arg, env)
116
+
117
+ return False
118
+
119
+
120
+ # ─────────────────────────────────────────────────────────────────────────────
121
+ # Alpha Normalization
122
+ # ─────────────────────────────────────────────────────────────────────────────
123
+
124
+
125
+ def alpha_normalize(
126
+ collection: CardCollection, hash_value: str, counter: list | None = None
127
+ ) -> str | None:
128
+ """
129
+ Normalize bound variable names using de Bruijn-style naming.
130
+
131
+ All bound variables are renamed to x0, x1, x2, etc. in order of binding.
132
+ This produces a canonical form for α-equivalent terms.
133
+ """
134
+ if counter is None:
135
+ counter = [0]
136
+
137
+ term = load_term(collection, hash_value)
138
+ if term is None:
139
+ return None
140
+
141
+ if is_var(term):
142
+ return hash_value
143
+
144
+ elif is_abs(term):
145
+ # Generate fresh normalized name
146
+ new_name = f"x{counter[0]}"
147
+ counter[0] += 1
148
+
149
+ # Rename this binding
150
+ renamed_body = alpha_rename(collection, term.body, term.param, new_name)
151
+ if renamed_body is None:
152
+ return None
153
+
154
+ # Recursively normalize the body
155
+ normalized_body = alpha_normalize(collection, renamed_body, counter)
156
+ if normalized_body is None:
157
+ return None
158
+
159
+ return store_term(collection, mk_abs(new_name, normalized_body))
160
+
161
+ elif is_app(term):
162
+ norm_func = alpha_normalize(collection, term.func, counter)
163
+ norm_arg = alpha_normalize(collection, term.arg, counter)
164
+ if norm_func is None or norm_arg is None:
165
+ return None
166
+ return store_term(collection, mk_app(norm_func, norm_arg))
167
+
168
+ return hash_value