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,279 @@
1
+ """Layer 3 Satori Speech-Act Transducer & Models (DEL-390-02, INV-390-01).
2
+
3
+ Implements Searle-Austin speech act taxonomy:
4
+ - Assertive: statements of fact, belief, or state verification
5
+ - Directive: instructions, queries, and requests for action
6
+ - Commissive: commitments, promises, and contracts
7
+ - Expressive: psychological states, greetings, acknowledgments
8
+ - Declarative: ontological declarations, approvals, and mutations
9
+
10
+ Also implements Satori binary AST encoding/decoding matching TypeScript & Rust.
11
+ """
12
+ from __future__ import annotations
13
+
14
+ import json
15
+ import struct
16
+ import time
17
+ import uuid
18
+ from dataclasses import dataclass, field
19
+ from enum import Enum
20
+ from typing import Any, Dict, List, Tuple
21
+
22
+ SATORI_OPCODES = {
23
+ "text": 0x01,
24
+ "at": 0x02,
25
+ "quote": 0x03,
26
+ "image": 0x04,
27
+ "audio": 0x05,
28
+ "video": 0x06,
29
+ "button": 0x07,
30
+ "action": 0x08,
31
+ "card": 0x09,
32
+ "execute": 0x0A,
33
+ "witness": 0x0B,
34
+ "custom": 0x0C,
35
+ "message": 0x10,
36
+ }
37
+
38
+ OPCODES_TO_TYPE = {v: k for k, v in SATORI_OPCODES.items()}
39
+
40
+
41
+ class SpeechActType(str, Enum):
42
+ """Searle-Austin illocutionary taxonomy."""
43
+ ASSERTIVE = "assertive"
44
+ DIRECTIVE = "directive"
45
+ COMMISSIVE = "commissive"
46
+ EXPRESSIVE = "expressive"
47
+ DECLARATIVE = "declarative"
48
+
49
+
50
+ @dataclass
51
+ class SpeechAct:
52
+ """Conversational Speech Act container."""
53
+ act_type: str
54
+ content: str
55
+ user_did: str
56
+ id: str = field(default_factory=lambda: str(uuid.uuid4()))
57
+ timestamp: float = field(default_factory=time.time)
58
+ metadata: Dict[str, Any] = field(default_factory=dict)
59
+ elements: List[Dict[str, Any]] = field(default_factory=list)
60
+
61
+ def to_message_node(self) -> Dict[str, Any]:
62
+ """Convert speech act into a Satori message AST node."""
63
+ els = list(self.elements)
64
+ if not els:
65
+ els = [{"type": "text", "text": self.content}]
66
+ node = {
67
+ "type": "message",
68
+ "id": self.id,
69
+ "user_did": self.user_did,
70
+ "speech_act_type": self.act_type,
71
+ "timestamp": self.timestamp,
72
+ "elements": els,
73
+ }
74
+ if self.metadata:
75
+ node["metadata"] = self.metadata
76
+ return node
77
+
78
+
79
+ def encode_satori_binary(node: Dict[str, Any]) -> bytes:
80
+ """Encodes a Satori AST node into compact binary frame:
81
+ [1B opcode][2B attrLen BE][attrBytes][2B childCount BE][children...]
82
+ """
83
+ is_message = "elements" in node or node.get("type") == "message"
84
+ opcode = SATORI_OPCODES["message"] if is_message else SATORI_OPCODES.get(node.get("type", "custom"), 0x0C)
85
+
86
+ if is_message:
87
+ attrs = {
88
+ "id": node.get("id", ""),
89
+ "channel_id": node.get("channel_id", ""),
90
+ "user_did": node.get("user_did", ""),
91
+ "timestamp": node.get("timestamp", 0),
92
+ }
93
+ if "speech_act_type" in node:
94
+ attrs["speech_act_type"] = node["speech_act_type"]
95
+ children = node.get("elements", [])
96
+ else:
97
+ attrs = {k: v for k, v in node.items() if k not in ("type", "children")}
98
+ children = node.get("children", [])
99
+
100
+ attr_bytes = json.dumps(attrs, separators=(',', ':')).encode("utf-8")
101
+ encoded_children = [encode_satori_binary(c) for c in children]
102
+
103
+ buf = bytearray()
104
+ buf.append(opcode)
105
+ buf.extend(struct.pack(">H", len(attr_bytes)))
106
+ buf.extend(attr_bytes)
107
+ buf.extend(struct.pack(">H", len(children)))
108
+ for c_bytes in encoded_children:
109
+ buf.extend(c_bytes)
110
+
111
+ return bytes(buf)
112
+
113
+
114
+ def _decode_satori_binary_with_length(buf: bytes, start_offset: int = 0) -> Tuple[Dict[str, Any], int]:
115
+ offset = start_offset
116
+ if len(buf) - offset < 5:
117
+ raise ValueError("Satori binary frame too short")
118
+
119
+ opcode = buf[offset]
120
+ offset += 1
121
+
122
+ attr_len = struct.unpack(">H", buf[offset : offset + 2])[0]
123
+ offset += 2
124
+
125
+ attr_bytes = buf[offset : offset + attr_len]
126
+ offset += attr_len
127
+ attrs = json.loads(attr_bytes.decode("utf-8"))
128
+
129
+ child_count = struct.unpack(">H", buf[offset : offset + 2])[0]
130
+ offset += 2
131
+
132
+ children = []
133
+ for _ in range(child_count):
134
+ child_node, child_bytes_read = _decode_satori_binary_with_length(buf, offset)
135
+ children.append(child_node)
136
+ offset += child_bytes_read
137
+
138
+ total_bytes_read = offset - start_offset
139
+
140
+ if opcode == SATORI_OPCODES["message"]:
141
+ attrs["elements"] = children
142
+ return attrs, total_bytes_read
143
+
144
+ node_type = OPCODES_TO_TYPE.get(opcode, "custom")
145
+ out = {"type": node_type}
146
+ out.update(attrs)
147
+ if children:
148
+ out["children"] = children
149
+ return out, total_bytes_read
150
+
151
+
152
+ def decode_satori_binary(buf: bytes) -> Dict[str, Any]:
153
+ """Decodes binary frame back into Satori AST dictionary."""
154
+ node, _ = _decode_satori_binary_with_length(buf, 0)
155
+ return node
156
+
157
+
158
+ def classify_speech_act(node: Dict[str, Any]) -> str:
159
+ """Classifies a Satori AST node into a Searle-Austin speech act category:
160
+ assertive, directive, commissive, expressive, or declarative.
161
+ """
162
+ if "speech_act_type" in node:
163
+ val = str(node["speech_act_type"]).lower()
164
+ if val in ("assertive", "directive", "commissive", "expressive", "declarative"):
165
+ return val
166
+ if val == "declaration":
167
+ return "declarative"
168
+
169
+ node_type = node.get("type", "")
170
+ if node_type in ("action", "execute"):
171
+ return "directive"
172
+ if node_type == "witness":
173
+ return "declarative"
174
+
175
+ def _extract_text(n: Dict[str, Any]) -> str:
176
+ res = []
177
+ if "text" in n:
178
+ res.append(str(n["text"]))
179
+ for child in n.get("elements", n.get("children", [])):
180
+ res.append(_extract_text(child))
181
+ return " ".join(res)
182
+
183
+ text = _extract_text(node).lower()
184
+ if "?" in text or text.startswith("run ") or text.startswith("can you") or text.startswith("show "):
185
+ return "directive"
186
+ if "i will" in text or "promise" in text or "commit" in text:
187
+ return "commissive"
188
+ if any(w in text for w in ("hello", "thanks", "great", "morning")):
189
+ return "expressive"
190
+ if any(w in text for w in ("declare", "approve", "hereby")):
191
+ return "declarative"
192
+ return "assertive"
193
+
194
+
195
+ def create_assert(text: str, user_did: str, id: str = "msg-assert", **kwargs: Any) -> Dict[str, Any]:
196
+ """Create an assertive speech-act message AST node."""
197
+ return {
198
+ "type": "message",
199
+ "id": id,
200
+ "user_did": user_did,
201
+ "speech_act_type": "assertive",
202
+ "elements": [{"type": "text", "text": text}],
203
+ **kwargs,
204
+ }
205
+
206
+
207
+ def create_directive(text: str, user_did: str, id: str = "msg-directive", **kwargs: Any) -> Dict[str, Any]:
208
+ """Create a directive speech-act message AST node."""
209
+ return {
210
+ "type": "message",
211
+ "id": id,
212
+ "user_did": user_did,
213
+ "speech_act_type": "directive",
214
+ "elements": [{"type": "text", "text": text}],
215
+ **kwargs,
216
+ }
217
+
218
+
219
+ create_request = create_directive
220
+
221
+
222
+ def create_commissive(text: str, user_did: str, id: str = "msg-commissive", **kwargs: Any) -> Dict[str, Any]:
223
+ """Create a commissive speech-act message AST node."""
224
+ return {
225
+ "type": "message",
226
+ "id": id,
227
+ "user_did": user_did,
228
+ "speech_act_type": "commissive",
229
+ "elements": [{"type": "text", "text": text}],
230
+ **kwargs,
231
+ }
232
+
233
+
234
+ create_commit = create_commissive
235
+
236
+
237
+ def create_expressive(text: str, user_did: str, id: str = "msg-expressive", **kwargs: Any) -> Dict[str, Any]:
238
+ """Create an expressive speech-act message AST node."""
239
+ return {
240
+ "type": "message",
241
+ "id": id,
242
+ "user_did": user_did,
243
+ "speech_act_type": "expressive",
244
+ "elements": [{"type": "text", "text": text}],
245
+ **kwargs,
246
+ }
247
+
248
+
249
+ def create_declarative(text: str, user_did: str, id: str = "msg-declarative", **kwargs: Any) -> Dict[str, Any]:
250
+ """Create a declarative speech-act message AST node."""
251
+ return {
252
+ "type": "message",
253
+ "id": id,
254
+ "user_did": user_did,
255
+ "speech_act_type": "declarative",
256
+ "elements": [{"type": "text", "text": text}],
257
+ **kwargs,
258
+ }
259
+
260
+
261
+ create_declare = create_declarative
262
+
263
+ __all__ = [
264
+ "SATORI_OPCODES",
265
+ "OPCODES_TO_TYPE",
266
+ "SpeechActType",
267
+ "SpeechAct",
268
+ "encode_satori_binary",
269
+ "decode_satori_binary",
270
+ "classify_speech_act",
271
+ "create_assert",
272
+ "create_directive",
273
+ "create_request",
274
+ "create_commissive",
275
+ "create_commit",
276
+ "create_expressive",
277
+ "create_declarative",
278
+ "create_declare",
279
+ ]
clm/layer4/README.md ADDED
@@ -0,0 +1,9 @@
1
+ # Layer 4 — Human Interaction Surface (Python Track — Generative Hypermedia CLI)
2
+
3
+ Python-track L4 components: CLI REPL viewers (text-mode Generative Hypermedia surface), human refinement CLI tools, EOA sponsor signing CLI, Data Harness query tools, Process Harness discovery via `clmEval`, non-browser surfaces.
4
+
5
+ Depends on: L0 (Kenotic Core), L1 (CPN VM), L2 (Storage), L3 (Network).
6
+
7
+ **Generative Hypermedia Shell (CLI Track)**: Provides terminal REPL interfaces as the text-mode **Generative Hypermedia Surface** — the LLM-powered generative loop where human users provide refinement advice, navigate asset handles, execute Baldwin refactoring operations, and manage DID-bound VCard witness signatures. The CLI queries the **Data Harness** (MCard collection, Column Space $S_T$) for grounding facts and discovers available controls from the **Process Harness** (PCard/VCard graph) via `clmEval`. The **VCard Sandwich** enforces hallucination prevention at the CLI boundary.
8
+
9
+ **Normative spec**: `docs/spec/30-interfaces/layer4-human-interaction-surface.md`
clm/layer4/__init__.py ADDED
@@ -0,0 +1,67 @@
1
+ """Layer 4 — Human Interaction Surface (Python track).
2
+
3
+ Conversational gateways, visualizers, EOA sponsor signing surfaces,
4
+ human-in-the-loop approval gates, presentation membranes, card navigation.
5
+
6
+ Depends on: L0 (Kenotic Core), L1 (CPN VM), L2 (Storage), L3 (Network).
7
+ L0–L3 MUST NOT import from this package (linear dependency rule).
8
+ """
9
+
10
+ from clm.layer4.eoa_sponsor import (
11
+ derive_did,
12
+ derive_did_from_pubkey,
13
+ generate_in_memory_keypair,
14
+ sign_intent,
15
+ sign_intent_with_key,
16
+ verify_signature,
17
+ )
18
+ from clm.layer4.events import EventLog, EventType, ExecutionEvent, GatewayEvent
19
+ from clm.layer4.gateway import CLMGateway, GatewayRouter
20
+ from clm.layer4.membrane import (
21
+ ActionResult,
22
+ CollectionManager,
23
+ CollectionStats,
24
+ MCardBridge,
25
+ MCardStorage,
26
+ MembraneAction,
27
+ MembraneEvent,
28
+ MembraneSession,
29
+ PresentationMembrane,
30
+ RetrievalResult,
31
+ StorageResult,
32
+ VCardReceiptGenerator,
33
+ WebStudioMembrane,
34
+ )
35
+ from clm.layer4.navigation import CardGraph, CardNode, NavigationDirection
36
+
37
+ __all__ = [
38
+ "ActionResult",
39
+ "CardGraph",
40
+ "CardNode",
41
+ "CLMGateway",
42
+ "CollectionManager",
43
+ "CollectionStats",
44
+ "EventLog",
45
+ "EventType",
46
+ "ExecutionEvent",
47
+ "GatewayEvent",
48
+ "GatewayRouter",
49
+ "MCardBridge",
50
+ "MCardStorage",
51
+ "MembraneAction",
52
+ "MembraneEvent",
53
+ "MembraneSession",
54
+ "NavigationDirection",
55
+ "PresentationMembrane",
56
+ "RetrievalResult",
57
+ "StorageResult",
58
+ "VCardReceiptGenerator",
59
+ "WebStudioMembrane",
60
+ "derive_did",
61
+ "derive_did_from_pubkey",
62
+ "generate_in_memory_keypair",
63
+ "sign_intent",
64
+ "sign_intent_with_key",
65
+ "verify_signature",
66
+ ]
67
+