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,230 @@
1
+ """
2
+ Lambda Term - Algebraic Data Type for Lambda Calculus
3
+
4
+ Represents Lambda Calculus terms as content-addressable MCards.
5
+ Each term variant is stored as JSON in MCard content, with sub-terms
6
+ referenced by their SHA-256 hashes for structural sharing.
7
+
8
+ The three term constructors mirror the BNF grammar:
9
+ M, N ::= x | λx.M | M N
10
+
11
+ This module provides Python parity with mcard-js/src/ptr/lambda/LambdaTerm.ts
12
+ """
13
+
14
+ import json
15
+ from dataclasses import dataclass
16
+ from typing import Literal
17
+
18
+ from clm.layer0.model.card import MCard
19
+ from clm.layer2.card_collection import CardCollection
20
+
21
+ # ─────────────────────────────────────────────────────────────────────────────
22
+ # Lambda Term ADT
23
+ # ─────────────────────────────────────────────────────────────────────────────
24
+
25
+
26
+ @dataclass(frozen=True)
27
+ class VarTerm:
28
+ """Variable term: x"""
29
+
30
+ tag: Literal["Var"] = "Var"
31
+ name: str = ""
32
+
33
+ def __init__(self, name: str):
34
+ object.__setattr__(self, "name", name)
35
+ object.__setattr__(self, "tag", "Var")
36
+
37
+
38
+ @dataclass(frozen=True)
39
+ class AbsTerm:
40
+ """Abstraction term: λx.M - Body is stored as MCard hash"""
41
+
42
+ tag: Literal["Abs"] = "Abs"
43
+ param: str = ""
44
+ body: str = "" # MCard hash of body term
45
+
46
+ def __init__(self, param: str, body: str):
47
+ object.__setattr__(self, "param", param)
48
+ object.__setattr__(self, "body", body)
49
+ object.__setattr__(self, "tag", "Abs")
50
+
51
+
52
+ @dataclass(frozen=True)
53
+ class AppTerm:
54
+ """Application term: M N - Both func and arg are MCard hashes"""
55
+
56
+ tag: Literal["App"] = "App"
57
+ func: str = "" # MCard hash of function
58
+ arg: str = "" # MCard hash of argument
59
+
60
+ def __init__(self, func: str, arg: str):
61
+ object.__setattr__(self, "func", func)
62
+ object.__setattr__(self, "arg", arg)
63
+ object.__setattr__(self, "tag", "App")
64
+
65
+
66
+ LambdaTerm = VarTerm | AbsTerm | AppTerm
67
+
68
+
69
+ # ─────────────────────────────────────────────────────────────────────────────
70
+ # Constructors (Smart Constructors)
71
+ # ─────────────────────────────────────────────────────────────────────────────
72
+
73
+
74
+ def mk_var(name: str) -> VarTerm:
75
+ """Create a variable term"""
76
+ return VarTerm(name=name)
77
+
78
+
79
+ def mk_abs(param: str, body_hash: str) -> AbsTerm:
80
+ """Create an abstraction term"""
81
+ return AbsTerm(param=param, body=body_hash)
82
+
83
+
84
+ def mk_app(func_hash: str, arg_hash: str) -> AppTerm:
85
+ """Create an application term"""
86
+ return AppTerm(func=func_hash, arg=arg_hash)
87
+
88
+
89
+ # ─────────────────────────────────────────────────────────────────────────────
90
+ # Serialization
91
+ # ─────────────────────────────────────────────────────────────────────────────
92
+
93
+
94
+ def serialize_term(term: LambdaTerm) -> str:
95
+ """Serialize a Lambda term to MCard content (JSON string)"""
96
+ if isinstance(term, VarTerm):
97
+ return json.dumps({"tag": "Var", "name": term.name})
98
+ elif isinstance(term, AbsTerm):
99
+ return json.dumps({"tag": "Abs", "param": term.param, "body": term.body})
100
+ elif isinstance(term, AppTerm):
101
+ return json.dumps({"tag": "App", "func": term.func, "arg": term.arg})
102
+ else:
103
+ raise ValueError(f"Unknown term type: {type(term)}")
104
+
105
+
106
+ def deserialize_term(content: str) -> LambdaTerm:
107
+ """Deserialize MCard content to Lambda term"""
108
+ parsed = json.loads(content)
109
+
110
+ if not parsed.get("tag"):
111
+ raise ValueError("Invalid Lambda term: missing tag")
112
+
113
+ tag = parsed["tag"]
114
+
115
+ if tag == "Var":
116
+ if not isinstance(parsed.get("name"), str):
117
+ raise ValueError("Invalid Var term: name must be string")
118
+ return mk_var(parsed["name"])
119
+
120
+ elif tag == "Abs":
121
+ if not isinstance(parsed.get("param"), str) or not isinstance(
122
+ parsed.get("body"), str
123
+ ):
124
+ raise ValueError("Invalid Abs term: param and body must be strings")
125
+ return mk_abs(parsed["param"], parsed["body"])
126
+
127
+ elif tag == "App":
128
+ if not isinstance(parsed.get("func"), str) or not isinstance(
129
+ parsed.get("arg"), str
130
+ ):
131
+ raise ValueError("Invalid App term: func and arg must be strings")
132
+ return mk_app(parsed["func"], parsed["arg"])
133
+
134
+ else:
135
+ raise ValueError(f"Unknown Lambda term tag: {tag}")
136
+
137
+
138
+ def term_to_mcard(term: LambdaTerm) -> MCard:
139
+ """Create an MCard from a Lambda term"""
140
+ return MCard(content=serialize_term(term))
141
+
142
+
143
+ def mcard_to_term(mcard: MCard) -> LambdaTerm:
144
+ """Extract Lambda term from MCard"""
145
+ content = mcard.get_content(as_text=True)
146
+ return deserialize_term(content)
147
+
148
+
149
+ # ─────────────────────────────────────────────────────────────────────────────
150
+ # Collection Operations
151
+ # ─────────────────────────────────────────────────────────────────────────────
152
+
153
+
154
+ def store_term(collection: CardCollection, term: LambdaTerm) -> str:
155
+ """Store a Lambda term in the collection and return its hash"""
156
+ mcard = term_to_mcard(term)
157
+ collection.add(mcard)
158
+ return mcard.hash
159
+
160
+
161
+ def load_term(collection: CardCollection, hash_value: str) -> LambdaTerm | None:
162
+ """Retrieve a Lambda term from the collection by hash"""
163
+ mcard = collection.get(hash_value)
164
+ if mcard is None:
165
+ return None
166
+ return mcard_to_term(mcard)
167
+
168
+
169
+ def term_exists(collection: CardCollection, hash_value: str) -> bool:
170
+ """Check if a term exists in the collection"""
171
+ return collection.get(hash_value) is not None
172
+
173
+
174
+ # ─────────────────────────────────────────────────────────────────────────────
175
+ # Pretty Printing
176
+ # ─────────────────────────────────────────────────────────────────────────────
177
+
178
+
179
+ def pretty_print_shallow(term: LambdaTerm) -> str:
180
+ """Pretty-print a Lambda term (shallow - shows hashes for subterms)"""
181
+ if isinstance(term, VarTerm):
182
+ return term.name
183
+ elif isinstance(term, AbsTerm):
184
+ return f"λ{term.param}.〈{term.body[:8]}…〉"
185
+ elif isinstance(term, AppTerm):
186
+ return f"(〈{term.func[:8]}…〉 〈{term.arg[:8]}…〉)"
187
+ else:
188
+ return str(term)
189
+
190
+
191
+ def pretty_print_deep(collection: CardCollection, hash_value: str) -> str:
192
+ """Pretty-print a Lambda term (deep - resolves all subterms from collection)"""
193
+ term = load_term(collection, hash_value)
194
+ if term is None:
195
+ return f"〈missing:{hash_value[:8]}…〉"
196
+
197
+ if isinstance(term, VarTerm):
198
+ return term.name
199
+
200
+ elif isinstance(term, AbsTerm):
201
+ body = pretty_print_deep(collection, term.body)
202
+ return f"(λ{term.param}.{body})"
203
+
204
+ elif isinstance(term, AppTerm):
205
+ func = pretty_print_deep(collection, term.func)
206
+ arg = pretty_print_deep(collection, term.arg)
207
+ return f"({func} {arg})"
208
+
209
+ else:
210
+ return str(term)
211
+
212
+
213
+ # ─────────────────────────────────────────────────────────────────────────────
214
+ # Type Guards
215
+ # ─────────────────────────────────────────────────────────────────────────────
216
+
217
+
218
+ def is_var(term: LambdaTerm) -> bool:
219
+ """Check if term is a variable"""
220
+ return isinstance(term, VarTerm)
221
+
222
+
223
+ def is_abs(term: LambdaTerm) -> bool:
224
+ """Check if term is an abstraction"""
225
+ return isinstance(term, AbsTerm)
226
+
227
+
228
+ def is_app(term: LambdaTerm) -> bool:
229
+ """Check if term is an application"""
230
+ return isinstance(term, AppTerm)
@@ -0,0 +1,261 @@
1
+ """Layer 3 Satori Sheaf Cohomology & Multi-Agent Consensus Auditing (DEL-390-02, INV-390-02).
2
+
3
+ Implements Sheaf-theoretic multi-agent state consistency and Maxwell's Demon gating:
4
+ - Local sections s_i over open sets U_i must agree on intersections:
5
+ s_i|_{U_i ∩ U_j} == s_j|_{U_i ∩ U_j} ∀ i, j
6
+ - Vanishing first cohomology class H¹ = 0 guarantees zero conflict obstruction,
7
+ enabling unique global gluing into the SSOT state section.
8
+ - Maxwell's Demon (§3.2, INV-362-04): validates contributor DID grounding,
9
+ non-empty content, and zero synthetic hallucination markers.
10
+ """
11
+ from __future__ import annotations
12
+
13
+ import hashlib
14
+ from dataclasses import dataclass, field
15
+ from typing import Any, Dict, List, Optional, Set, Tuple
16
+
17
+ from clm.layer3.satori.speech_act import encode_satori_binary
18
+
19
+
20
+ @dataclass(frozen=True)
21
+ class Place:
22
+ """An open-set place identifier in a distributed topological space."""
23
+ id: str
24
+
25
+
26
+ @dataclass
27
+ class Marking:
28
+ """Maps token places / colors to their associated content hashes or values."""
29
+ tokens: Dict[str, List[str]] = field(default_factory=dict)
30
+
31
+ def with_token(self, place: str, val: str) -> Marking:
32
+ tokens = dict(self.tokens)
33
+ if place not in tokens:
34
+ tokens[place] = []
35
+ else:
36
+ tokens[place] = list(tokens[place])
37
+ tokens[place].append(val)
38
+ return Marking(tokens=tokens)
39
+
40
+ def restrict(self, places: Set[Place]) -> Marking:
41
+ """Restrict marking to a subset of places."""
42
+ place_ids = {p.id for p in places}
43
+ restricted = {k: list(v) for k, v in self.tokens.items() if k in place_ids}
44
+ return Marking(tokens=restricted)
45
+
46
+ def to_digest(self) -> str:
47
+ items = sorted((k, sorted(v)) for k, v in self.tokens.items())
48
+ raw = str(items).encode("utf-8")
49
+ return hashlib.sha256(raw).hexdigest()
50
+
51
+
52
+ @dataclass(frozen=True)
53
+ class OpenSet:
54
+ """An open set consisting of a collection of discrete Places."""
55
+ places: frozenset[Place] = field(default_factory=frozenset)
56
+
57
+ @classmethod
58
+ def from_ids(cls, *ids: str) -> OpenSet:
59
+ return cls(frozenset(Place(id=i) for i in ids))
60
+
61
+ def intersection(self, other: OpenSet) -> OpenSet:
62
+ return OpenSet(self.places.intersection(other.places))
63
+
64
+ def union(self, other: OpenSet) -> OpenSet:
65
+ return OpenSet(self.places.union(other.places))
66
+
67
+ def is_empty(self) -> bool:
68
+ return len(self.places) == 0
69
+
70
+ def is_subset(self, other: OpenSet) -> bool:
71
+ return self.places.issubset(other.places)
72
+
73
+
74
+ @dataclass
75
+ class Section:
76
+ """A local section pairing an open set cover with a state marking."""
77
+ open_set: OpenSet
78
+ marking: Marking
79
+
80
+ def restrict(self, subset: OpenSet) -> Section:
81
+ if not subset.is_subset(self.open_set):
82
+ raise ValueError("Cannot restrict section to non-subset open set")
83
+ return Section(open_set=subset, marking=self.marking.restrict(set(subset.places)))
84
+
85
+
86
+ @dataclass
87
+ class SheafAuditReport:
88
+ """Outcome of a sheaf consensus audit evaluating the H¹ = 0 condition."""
89
+ h1_vanishes: bool
90
+ cohomology_h1: int
91
+ obstructions: List[str]
92
+ global_section: Optional[Section] = None
93
+
94
+
95
+ class Sheaf:
96
+ """Sheaf engine verifying the gluing axiom on open covers."""
97
+
98
+ @staticmethod
99
+ def gluing_check(sections: List[Section], open_cover: List[OpenSet]) -> Tuple[Optional[Section], List[str]]:
100
+ """Verifies that local sections agree on all pairwise intersections.
101
+ Returns:
102
+ (global_section, []) if H¹ = 0 holds.
103
+ (None, [obstruction_reasons...]) if H¹ != 0 (obstruction detected).
104
+ """
105
+ if len(sections) != len(open_cover):
106
+ return None, ["Input length mismatch between sections and open cover"]
107
+
108
+ if not sections:
109
+ return Section(open_set=OpenSet(), marking=Marking()), []
110
+
111
+ obstructions: List[str] = []
112
+ n = len(sections)
113
+
114
+ for i in range(n):
115
+ for j in range(i + 1, n):
116
+ u_ij = open_cover[i].intersection(open_cover[j])
117
+ if u_ij.is_empty():
118
+ continue
119
+
120
+ sec_i_res = sections[i].restrict(u_ij)
121
+ sec_j_res = sections[j].restrict(u_ij)
122
+
123
+ if sec_i_res.marking.to_digest() != sec_j_res.marking.to_digest():
124
+ obstructions.append(
125
+ f"Cohomology class H¹ != 0 obstruction on overlap {sorted(p.id for p in u_ij.places)}: "
126
+ f"Section {i} digest {sec_i_res.marking.to_digest()[:8]} != Section {j} digest {sec_j_res.marking.to_digest()[:8]}"
127
+ )
128
+
129
+ if obstructions:
130
+ return None, obstructions
131
+
132
+ # Glue into unified global section
133
+ all_places = set()
134
+ merged_tokens: Dict[str, List[str]] = {}
135
+ for s in sections:
136
+ all_places.update(s.open_set.places)
137
+ for k, v in s.marking.tokens.items():
138
+ if k not in merged_tokens:
139
+ merged_tokens[k] = list(v)
140
+
141
+ global_sec = Section(open_set=OpenSet(frozenset(all_places)), marking=Marking(tokens=merged_tokens))
142
+ return global_sec, []
143
+
144
+
145
+ class SheafAuditor:
146
+ """Auditor for multi-agent distributed consensus."""
147
+
148
+ @classmethod
149
+ def audit_consensus(
150
+ cls,
151
+ sections: List[Section],
152
+ open_cover: Optional[List[OpenSet]] = None,
153
+ ) -> SheafAuditReport:
154
+ """Audit pairwise section agreement. Vanishing H¹ (cohomology_h1 = 0) indicates consensus."""
155
+ if open_cover is None:
156
+ open_cover = [s.open_set for s in sections]
157
+
158
+ global_sec, obstructions = Sheaf.gluing_check(sections, open_cover)
159
+ if obstructions:
160
+ return SheafAuditReport(
161
+ h1_vanishes=False,
162
+ cohomology_h1=1,
163
+ obstructions=obstructions,
164
+ global_section=None,
165
+ )
166
+ return SheafAuditReport(
167
+ h1_vanishes=True,
168
+ cohomology_h1=0,
169
+ obstructions=[],
170
+ global_section=global_sec,
171
+ )
172
+
173
+ @classmethod
174
+ def audit_partitions(
175
+ cls,
176
+ partitions: List[Dict[str, Any]],
177
+ shared_keys: Optional[Set[str]] = None,
178
+ ) -> SheafAuditReport:
179
+ """Audit distributed agent state partition dictionaries.
180
+ Each partition has a 'did', 'places' (keys), and 'state' (mapping).
181
+ """
182
+ sections: List[Section] = []
183
+ covers: List[OpenSet] = []
184
+
185
+ for p in partitions:
186
+ keys = set(p.get("places", p.get("state", {}).keys()))
187
+ open_set = OpenSet.from_ids(*keys)
188
+ tokens = {}
189
+ for k, v in p.get("state", {}).items():
190
+ tokens[k] = [str(v)] if not isinstance(v, list) else [str(x) for x in v]
191
+ sections.append(Section(open_set=open_set, marking=Marking(tokens=tokens)))
192
+ covers.append(open_set)
193
+
194
+ return cls.audit_consensus(sections, covers)
195
+
196
+
197
+ def audit_maxwell_demon(node: Dict[str, Any]) -> Dict[str, Any]:
198
+ """Audits a Satori message speech act via Maxwell's Demon (§3.2, INV-362-04).
199
+ Validates DID grounding, non-empty content, and absence of synthetic hallucination markers.
200
+ Returns receipt dict with 'verified', 'cohomology_h1', 'lagrangian_delta', 'hash', 'rejection_reason'.
201
+ """
202
+ encoded = encode_satori_binary(node)
203
+ msg_hash = hashlib.sha256(encoded).hexdigest()
204
+
205
+ user_did = node.get("user_did", "")
206
+ if not isinstance(user_did, str) or not user_did.startswith("did:"):
207
+ return {
208
+ "verified": False,
209
+ "cohomology_h1": 1,
210
+ "lagrangian_delta": -1,
211
+ "hash": msg_hash,
212
+ "rejection_reason": f"Cohomology Class H^1 != 0: Un-grounded DID contributor identity '{user_did}'",
213
+ }
214
+
215
+ children = node.get("elements", node.get("children", []))
216
+ if not children:
217
+ return {
218
+ "verified": False,
219
+ "cohomology_h1": 1,
220
+ "lagrangian_delta": -1,
221
+ "hash": msg_hash,
222
+ "rejection_reason": "Cohomology Class H^1 != 0: Empty message section cannot glue into Data Harness",
223
+ }
224
+
225
+ def _has_hallucination(n: Dict[str, Any]) -> bool:
226
+ txt = str(n.get("text", ""))
227
+ if "[HALLUCINATED]" in txt or "<hallucination>" in txt:
228
+ return True
229
+ for c in n.get("elements", n.get("children", [])):
230
+ if _has_hallucination(c):
231
+ return True
232
+ return False
233
+
234
+ if _has_hallucination(node):
235
+ return {
236
+ "verified": False,
237
+ "cohomology_h1": 1,
238
+ "lagrangian_delta": -1,
239
+ "hash": msg_hash,
240
+ "rejection_reason": "Cohomology Class H^1 != 0: Detected ungrounded hallucinated tokens in execution section",
241
+ }
242
+
243
+ return {
244
+ "verified": True,
245
+ "cohomology_h1": 0,
246
+ "lagrangian_delta": 1,
247
+ "hash": msg_hash,
248
+ "rejection_reason": None,
249
+ }
250
+
251
+
252
+ __all__ = [
253
+ "Place",
254
+ "Marking",
255
+ "OpenSet",
256
+ "Section",
257
+ "Sheaf",
258
+ "SheafAuditReport",
259
+ "SheafAuditor",
260
+ "audit_maxwell_demon",
261
+ ]