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,553 @@
1
+ """
2
+ Collection Manager - Dynamic CLM assembly using MCard Collections
3
+
4
+ Manages the dynamic assembly of CLM specifications from individual
5
+ components stored in MCard Collections, providing a high-level interface
6
+ for PTR operations.
7
+ """
8
+
9
+ import logging
10
+ from dataclasses import dataclass
11
+ from datetime import datetime, timezone
12
+ from typing import Any
13
+
14
+ from clm.layer0.algebra import AssembledCLM, CLMAssembler
15
+ from clm.layer0.loader import YAMLTemplateLoader
16
+ from clm.layer2.card_collection import CardCollection
17
+
18
+ from .storage import MCardStorage
19
+
20
+
21
+ @dataclass
22
+ class CollectionStats:
23
+ """Statistics for a managed collection"""
24
+
25
+ total_cards: int
26
+ pcard_count: int
27
+ vcard_count: int
28
+ clm_component_count: int
29
+ assembled_clm_count: int
30
+ last_updated: datetime
31
+
32
+
33
+ class CollectionManager:
34
+ """
35
+ High-level manager for PTR operations using MCard Collections.
36
+
37
+ This class provides:
38
+ - Dynamic CLM assembly from components
39
+ - PCard and VCard management
40
+ - Template loading and storage
41
+ - Search and discovery capabilities
42
+ - Statistics and monitoring
43
+ """
44
+
45
+ def __init__(self, collection: CardCollection = None):
46
+ self.logger = logging.getLogger(__name__)
47
+ self.collection = collection or CardCollection()
48
+
49
+ # Initialize sub-components
50
+ self.storage = MCardStorage(self.collection)
51
+ self.template_loader = YAMLTemplateLoader(storage_collection=self.collection)
52
+ self.clm_assembler = CLMAssembler(
53
+ storage_collection=self.collection, template_loader=self.template_loader
54
+ )
55
+
56
+ self.logger.info("Collection Manager initialized")
57
+
58
+ def create_pcard_from_templates(
59
+ self,
60
+ abstract_template: str,
61
+ concrete_template: str,
62
+ balanced_template: str,
63
+ name: str = None,
64
+ metadata: dict[str, Any] = None,
65
+ ) -> dict[str, Any]:
66
+ """
67
+ Create a complete PCard from YAML templates.
68
+
69
+ Args:
70
+ abstract_template: YAML content for abstract dimension
71
+ concrete_template: YAML content for concrete dimension
72
+ balanced_template: YAML content for balanced dimension
73
+ name: Optional name for the PCard
74
+ metadata: Additional metadata
75
+
76
+ Returns:
77
+ Dictionary with creation results and hashes
78
+ """
79
+ try:
80
+ # Parse templates
81
+ import yaml
82
+
83
+ abstract_data = yaml.safe_load(abstract_template)
84
+ concrete_data = yaml.safe_load(concrete_template)
85
+ balanced_data = yaml.safe_load(balanced_template)
86
+
87
+ # Create PCard content
88
+ pcard_content = {
89
+ "abstract": abstract_data,
90
+ "concrete": concrete_data,
91
+ "balanced": balanced_data,
92
+ }
93
+
94
+ # Add metadata
95
+ pcard_metadata = {
96
+ "name": name
97
+ or f"PCard_{datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S')}",
98
+ "created_from": "templates",
99
+ "template_count": 3,
100
+ }
101
+ if metadata:
102
+ pcard_metadata.update(metadata)
103
+
104
+ # Store PCard
105
+ storage_result = self.storage.store_pcard(pcard_content, pcard_metadata)
106
+
107
+ if not storage_result.success:
108
+ raise ValueError(
109
+ f"Failed to store PCard: {storage_result.error_message}"
110
+ )
111
+
112
+ self.logger.info(f"Created PCard from templates: {storage_result.hash}")
113
+
114
+ return {
115
+ "success": True,
116
+ "pcard_hash": storage_result.hash,
117
+ "metadata": storage_result.metadata,
118
+ "components": {
119
+ "abstract": abstract_data,
120
+ "concrete": concrete_data,
121
+ "balanced": balanced_data,
122
+ },
123
+ }
124
+
125
+ except (yaml.YAMLError, ValueError, TypeError, KeyError) as e:
126
+ self.logger.error(
127
+ f"Failed to create PCard from templates: {str(e)}", exc_info=True
128
+ )
129
+ return {"success": False, "error_message": str(e)}
130
+
131
+ def create_pcard_from_clm_assembly(
132
+ self,
133
+ assembled_clm: AssembledCLM,
134
+ name: str = None,
135
+ metadata: dict[str, Any] = None,
136
+ ) -> dict[str, Any]:
137
+ """
138
+ Create a PCard from an assembled CLM.
139
+
140
+ Args:
141
+ assembled_clm: AssembledCLM object
142
+ name: Optional name for the PCard
143
+ metadata: Additional metadata
144
+
145
+ Returns:
146
+ Dictionary with creation results
147
+ """
148
+ try:
149
+ # Extract CLM content from assembly
150
+ pcard_content = {
151
+ "abstract": assembled_clm.abstract.content,
152
+ "concrete": assembled_clm.concrete.content,
153
+ "balanced": assembled_clm.balanced.content,
154
+ }
155
+
156
+ # Create metadata
157
+ pcard_metadata = {
158
+ "name": name or assembled_clm.name,
159
+ "created_from": "clm_assembly",
160
+ "assembly_hash": assembled_clm.assembly_hash,
161
+ "validation": {
162
+ "is_valid": assembled_clm.validation_result.is_valid,
163
+ "errors": assembled_clm.validation_result.errors,
164
+ "warnings": assembled_clm.validation_result.warnings,
165
+ },
166
+ }
167
+ if metadata:
168
+ pcard_metadata.update(metadata)
169
+
170
+ # Store PCard
171
+ storage_result = self.storage.store_pcard(pcard_content, pcard_metadata)
172
+
173
+ if not storage_result.success:
174
+ raise ValueError(
175
+ f"Failed to store PCard: {storage_result.error_message}"
176
+ )
177
+
178
+ self.logger.info(f"Created PCard from CLM assembly: {storage_result.hash}")
179
+
180
+ return {
181
+ "success": True,
182
+ "pcard_hash": storage_result.hash,
183
+ "metadata": storage_result.metadata,
184
+ "assembly_hash": assembled_clm.assembly_hash,
185
+ }
186
+
187
+ except (ValueError, TypeError, KeyError, AttributeError) as e:
188
+ self.logger.error(
189
+ f"Failed to create PCard from CLM assembly: {str(e)}", exc_info=True
190
+ )
191
+ return {"success": False, "error_message": str(e)}
192
+
193
+ def assemble_clm_from_components(
194
+ self,
195
+ abstract_name: str,
196
+ concrete_name: str,
197
+ balanced_name: str,
198
+ assembly_name: str = None,
199
+ ) -> dict[str, Any]:
200
+ """
201
+ Assemble a complete CLM from individual component templates.
202
+
203
+ Args:
204
+ abstract_name: Name of abstract template
205
+ concrete_name: Name of concrete template
206
+ balanced_name: Name of balanced template
207
+ assembly_name: Optional name for the assembled CLM
208
+
209
+ Returns:
210
+ Dictionary with assembly results
211
+ """
212
+ try:
213
+ # Load templates
214
+ abstract_template = self.template_loader.get_template(
215
+ "abstract", abstract_name
216
+ )
217
+ concrete_template = self.template_loader.get_template(
218
+ "concrete", concrete_name
219
+ )
220
+ balanced_template = self.template_loader.get_template(
221
+ "balanced", balanced_name
222
+ )
223
+
224
+ if not abstract_template:
225
+ raise ValueError(f"Abstract template not found: {abstract_name}")
226
+ if not concrete_template:
227
+ raise ValueError(f"Concrete template not found: {concrete_name}")
228
+ if not balanced_template:
229
+ raise ValueError(f"Balanced template not found: {balanced_name}")
230
+
231
+ # Create components from templates
232
+ abstract_component = self.clm_assembler.create_component_from_template(
233
+ "abstract", abstract_name, abstract_template.content
234
+ )
235
+ concrete_component = self.clm_assembler.create_component_from_template(
236
+ "concrete", concrete_name, concrete_template.content
237
+ )
238
+ balanced_component = self.clm_assembler.create_component_from_template(
239
+ "balanced", balanced_name, balanced_template.content
240
+ )
241
+
242
+ # Assemble CLM
243
+ assembled_clm = self.clm_assembler.assemble_clm(
244
+ abstract_component.mcard_hash,
245
+ concrete_component.mcard_hash,
246
+ balanced_component.mcard_hash,
247
+ assembly_name,
248
+ )
249
+
250
+ self.logger.info(
251
+ f"Assembled CLM: {assembled_clm.name} (valid: {assembled_clm.validation_result.is_valid})"
252
+ )
253
+
254
+ return {
255
+ "success": True,
256
+ "assembly_hash": assembled_clm.assembly_hash,
257
+ "assembly_name": assembled_clm.name,
258
+ "validation": {
259
+ "is_valid": assembled_clm.validation_result.is_valid,
260
+ "errors": assembled_clm.validation_result.errors,
261
+ "warnings": assembled_clm.validation_result.warnings,
262
+ },
263
+ "components": {
264
+ "abstract": abstract_component.mcard_hash,
265
+ "concrete": concrete_component.mcard_hash,
266
+ "balanced": balanced_component.mcard_hash,
267
+ },
268
+ }
269
+
270
+ except (ValueError, TypeError, KeyError, AttributeError) as e:
271
+ self.logger.error(f"Failed to assemble CLM: {str(e)}", exc_info=True)
272
+ return {"success": False, "error_message": str(e)}
273
+
274
+ def find_executable_pcards(
275
+ self, filters: dict[str, Any] = None
276
+ ) -> list[dict[str, Any]]:
277
+ """
278
+ Find PCards that are ready for execution (valid CLM assembly).
279
+
280
+ Args:
281
+ filters: Optional filters to apply
282
+
283
+ Returns:
284
+ List of executable PCard information
285
+ """
286
+ try:
287
+ # Search for PCards
288
+ search_results = self.storage.search_pcards("PCard", filters)
289
+ executable_pcards = []
290
+
291
+ for result in search_results:
292
+ if not result.success:
293
+ continue
294
+
295
+ metadata = result.metadata
296
+ content = result.content
297
+
298
+ # Check if it has all CLM dimensions
299
+ has_all_dimensions = (
300
+ "abstract" in content
301
+ and "concrete" in content
302
+ and "balanced" in content
303
+ )
304
+
305
+ # Check validation status
306
+ validation = metadata.get("validation", {})
307
+ is_valid = validation.get(
308
+ "is_valid", True
309
+ ) # Assume valid if not specified
310
+
311
+ if has_all_dimensions and is_valid:
312
+ executable_pcards.append(
313
+ {
314
+ "hash": result.metadata.get("hash", "unknown"),
315
+ "name": metadata.get("name", "unnamed"),
316
+ "created_at": metadata.get("created_at"),
317
+ "validation": validation,
318
+ "dimensions": list(content.keys()),
319
+ }
320
+ )
321
+
322
+ self.logger.info(f"Found {len(executable_pcards)} executable PCards")
323
+
324
+ return executable_pcards
325
+
326
+ except (ValueError, TypeError, KeyError, AttributeError) as e:
327
+ self.logger.error(
328
+ f"Failed to find executable PCards: {str(e)}", exc_info=True
329
+ )
330
+ return []
331
+
332
+ def get_clm_components_by_type(
333
+ self, dimension: str, filters: dict[str, Any] = None
334
+ ) -> list[dict[str, Any]]:
335
+ """
336
+ Get CLM components by dimension type.
337
+
338
+ Args:
339
+ dimension: CLM dimension ('abstract', 'concrete', or 'balanced')
340
+ filters: Optional filters
341
+
342
+ Returns:
343
+ List of component information
344
+ """
345
+ try:
346
+ # Find compatible components
347
+ components = self.clm_assembler.find_compatible_components(
348
+ dimension, filters
349
+ )
350
+
351
+ component_list = []
352
+ for component in components:
353
+ component_list.append(
354
+ {
355
+ "hash": component.mcard_hash,
356
+ "name": component.name,
357
+ "dimension": component.dimension,
358
+ "version": component.version,
359
+ "dependencies": component.dependencies,
360
+ }
361
+ )
362
+
363
+ self.logger.info(f"Found {len(component_list)} {dimension} components")
364
+
365
+ return component_list
366
+
367
+ except (ValueError, TypeError, KeyError, AttributeError) as e:
368
+ self.logger.error(
369
+ f"Failed to get {dimension} components: {str(e)}", exc_info=True
370
+ )
371
+ return []
372
+
373
+ def create_verification_vcard(
374
+ self,
375
+ pcard_hash: str,
376
+ target_hash: str,
377
+ verification_result: dict[str, Any],
378
+ execution_output: Any = None,
379
+ ) -> dict[str, Any]:
380
+ """
381
+ Create a verification VCard as audit evidence.
382
+
383
+ Args:
384
+ pcard_hash: Hash of the executed PCard
385
+ target_hash: Hash of the target MCard/VCard
386
+ verification_result: CLM verification results
387
+ execution_output: Output from execution
388
+
389
+ Returns:
390
+ Dictionary with VCard creation results
391
+ """
392
+ try:
393
+ # Create VCard content
394
+ vcard_content = {
395
+ "type": "VerificationVCard",
396
+ "subject": {"pcard_hash": pcard_hash, "target_hash": target_hash},
397
+ "verifier": "ptr_collection_manager",
398
+ "evidence": {
399
+ "clm_verification": verification_result,
400
+ "execution_output": (
401
+ str(execution_output) if execution_output else None
402
+ ),
403
+ "verification_timestamp": datetime.now(timezone.utc).isoformat(),
404
+ },
405
+ }
406
+
407
+ # Create metadata
408
+ vcard_metadata = {
409
+ "verification_type": "execution",
410
+ "pcard_hash": pcard_hash,
411
+ "target_hash": target_hash,
412
+ "created_at": datetime.now(timezone.utc).isoformat(),
413
+ }
414
+
415
+ # Store VCard
416
+ storage_result = self.storage.store_vcard(vcard_content, vcard_metadata)
417
+
418
+ if not storage_result.success:
419
+ raise ValueError(
420
+ f"Failed to store VCard: {storage_result.error_message}"
421
+ )
422
+
423
+ self.logger.info(f"Created VerificationVCard: {storage_result.hash}")
424
+
425
+ return {
426
+ "success": True,
427
+ "vcard_hash": storage_result.hash,
428
+ "metadata": storage_result.metadata,
429
+ }
430
+
431
+ except (ValueError, TypeError, KeyError) as e:
432
+ self.logger.error(
433
+ f"Failed to create VerificationVCard: {str(e)}", exc_info=True
434
+ )
435
+ return {"success": False, "error_message": str(e)}
436
+
437
+ def get_collection_statistics(self) -> CollectionStats:
438
+ """
439
+ Get comprehensive statistics for the managed collection.
440
+
441
+ Returns:
442
+ CollectionStats object with detailed statistics
443
+ """
444
+ try:
445
+ # Get basic storage statistics
446
+ storage_stats = self.storage.get_storage_statistics()
447
+
448
+ # Count CLM components
449
+ clm_component_count = 0
450
+ for dimension in ["abstract", "concrete", "balanced"]:
451
+ components = self.clm_assembler.find_compatible_components(dimension)
452
+ clm_component_count += len(components)
453
+
454
+ # Count assembled CLMs
455
+ assembled_clms = self.clm_assembler.list_assembled_clms()
456
+ assembled_clm_count = len(assembled_clms)
457
+
458
+ # Create stats object
459
+ stats = CollectionStats(
460
+ total_cards=storage_stats.get("total_cards", 0),
461
+ pcard_count=storage_stats.get("by_type", {}).get("pcard", 0),
462
+ vcard_count=storage_stats.get("by_type", {}).get("vcard", 0),
463
+ clm_component_count=clm_component_count,
464
+ assembled_clm_count=assembled_clm_count,
465
+ last_updated=datetime.now(timezone.utc),
466
+ )
467
+
468
+ return stats
469
+
470
+ except (ValueError, TypeError, KeyError, AttributeError) as e:
471
+ self.logger.error(
472
+ f"Failed to get collection statistics: {str(e)}", exc_info=True
473
+ )
474
+ return CollectionStats(
475
+ total_cards=0,
476
+ pcard_count=0,
477
+ vcard_count=0,
478
+ clm_component_count=0,
479
+ assembled_clm_count=0,
480
+ last_updated=datetime.now(timezone.utc),
481
+ )
482
+
483
+ def search_collection(
484
+ self, query: str, card_type: str = "all"
485
+ ) -> list[dict[str, Any]]:
486
+ """
487
+ Search across the entire collection.
488
+
489
+ Args:
490
+ query: Search query
491
+ card_type: Type of cards to search ('all', 'pcard', 'vcard', 'component')
492
+
493
+ Returns:
494
+ List of search results
495
+ """
496
+ try:
497
+ all_results = []
498
+
499
+ if card_type in ["all", "pcard"]:
500
+ pcard_results = self.storage.search_pcards(query)
501
+ for result in pcard_results:
502
+ if result.success:
503
+ all_results.append(
504
+ {
505
+ "type": "pcard",
506
+ "hash": result.metadata.get("hash", "unknown"),
507
+ "name": result.metadata.get("name", "unnamed"),
508
+ "metadata": result.metadata,
509
+ }
510
+ )
511
+
512
+ if card_type in ["all", "vcard"]:
513
+ vcard_results = self.storage.search_vcards(query)
514
+ for result in vcard_results:
515
+ if result.success:
516
+ all_results.append(
517
+ {
518
+ "type": "vcard",
519
+ "hash": result.metadata.get("hash", "unknown"),
520
+ "verification_type": result.metadata.get(
521
+ "verification_type", "unknown"
522
+ ),
523
+ "metadata": result.metadata,
524
+ }
525
+ )
526
+
527
+ if card_type in ["all", "component"]:
528
+ # Search for CLM components
529
+ for dimension in ["abstract", "concrete", "balanced"]:
530
+ components = self.clm_assembler.find_compatible_components(
531
+ dimension
532
+ )
533
+ for component in components:
534
+ if query.lower() in component.name.lower():
535
+ all_results.append(
536
+ {
537
+ "type": "component",
538
+ "dimension": dimension,
539
+ "hash": component.mcard_hash,
540
+ "name": component.name,
541
+ "version": component.version,
542
+ }
543
+ )
544
+
545
+ self.logger.info(
546
+ f"Search for '{query}' found {len(all_results)} results (type: {card_type})"
547
+ )
548
+
549
+ return all_results
550
+
551
+ except (ValueError, TypeError, KeyError, AttributeError) as e:
552
+ self.logger.error(f"Failed to search collection: {str(e)}", exc_info=True)
553
+ return []
@@ -0,0 +1,81 @@
1
+ """CLM Layer 4 Universal Subcommand Grammar Registry and Dispatcher.
2
+
3
+ Sprint 412 / DEL-412-04.
4
+ Normative Spec: docs/spec/30-interfaces/universal_subcommand_grammar.md
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import sys
10
+ from collections.abc import Callable
11
+
12
+ from clm.layer4.commands.action_cmd import action_cmd, workflow_cmd
13
+ from clm.layer4.commands.check_cmd import check_cmd
14
+ from clm.layer4.commands.envelope import format_error, format_failure, format_success
15
+ from clm.layer4.commands.evaluate_cmd import (
16
+ assess_equivalence_subcmd,
17
+ compose_conditions_subcmd,
18
+ directory_fs_scan_subcmd,
19
+ directory_to_db_subcmd,
20
+ evaluate_subcmd,
21
+ remote_handle_resolver_subcmd,
22
+ route_handle_subcmd,
23
+ )
24
+ from clm.layer4.commands.mcard_cmd import mcard_cmd
25
+ from clm.layer4.commands.petri_cmd import petri_run_net_cmd
26
+ from clm.layer4.commands.tridb_cmd import (
27
+ init_tridb_cmd,
28
+ memorize_mcard_cmd,
29
+ register_handle_cmd,
30
+ resolve_handle_cmd,
31
+ resolve_handle_hash_cmd,
32
+ sql_cmd,
33
+ )
34
+ from clm.layer4.commands.version_cmd import version_cmd
35
+
36
+ # Registry mapping all USG and backward-compatible subcommands to their handlers
37
+ COMMAND_REGISTRY: dict[str, Callable[[list[str]], int]] = {
38
+ # 12 Canonical USG Subcommands
39
+ "evaluate": evaluate_subcmd,
40
+ "petri-run-net": petri_run_net_cmd,
41
+ "run-net": petri_run_net_cmd, # Alias
42
+ "init-tridb": init_tridb_cmd,
43
+ "memorize-mcard": memorize_mcard_cmd,
44
+ "resolve-handle": resolve_handle_cmd,
45
+ "sql": sql_cmd,
46
+ "mcard": mcard_cmd,
47
+ "compose-conditions": compose_conditions_subcmd,
48
+ "action": action_cmd,
49
+ "workflow": workflow_cmd,
50
+ "check": check_cmd,
51
+ "version": version_cmd,
52
+ # Extended & Backward-Compatibility Commands
53
+ "resolve-handle-hash": resolve_handle_hash_cmd,
54
+ "register-handle": register_handle_cmd,
55
+ "assess-equivalence": assess_equivalence_subcmd,
56
+ "directory-fs-scan": directory_fs_scan_subcmd,
57
+ "directory-to-db": directory_to_db_subcmd,
58
+ "route-handle": route_handle_subcmd,
59
+ "remote-handle-resolver": remote_handle_resolver_subcmd,
60
+ }
61
+
62
+ KNOWN_COMMANDS: set[str] = set(COMMAND_REGISTRY.keys())
63
+
64
+
65
+ def dispatch_command(command: str, args: list[str]) -> int:
66
+ """Dispatch a command string and arguments to its registered handler."""
67
+ handler = COMMAND_REGISTRY.get(command)
68
+ if handler is None:
69
+ print(f"Unknown command: {command}", file=sys.stderr)
70
+ return 1
71
+ return handler(args)
72
+
73
+
74
+ __all__ = [
75
+ "COMMAND_REGISTRY",
76
+ "KNOWN_COMMANDS",
77
+ "dispatch_command",
78
+ "format_success",
79
+ "format_failure",
80
+ "format_error",
81
+ ]
@@ -0,0 +1,42 @@
1
+ """Action and Workflow Subcommand Handlers.
2
+
3
+ Sprint 412 / DEL-412-04.
4
+ Normative Spec: docs/spec/30-interfaces/universal_subcommand_grammar.md §2.9 - §2.10
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import sys
10
+
11
+ from clm.layer4.action_commands import handle_action_cli, handle_workflow_cli
12
+
13
+
14
+ def action_cmd(args: list[str]) -> int:
15
+ """Handle 'action' subcommand."""
16
+ if "--help" in args or "-h" in args:
17
+ print("Usage: clm action <apply|run|validate|diff|list> <spec.yaml> [options]")
18
+ return 0
19
+
20
+ if not args:
21
+ print("Usage: clm action <apply|run|validate|diff|list> <spec.yaml> [options]", file=sys.stderr)
22
+ return 2
23
+
24
+ # Translate USG 'apply' to existing 'run' subcommand
25
+ translated = list(args)
26
+ if translated and translated[0] == "apply":
27
+ translated[0] = "run"
28
+
29
+ return handle_action_cli(translated)
30
+
31
+
32
+ def workflow_cmd(args: list[str]) -> int:
33
+ """Handle 'workflow' subcommand."""
34
+ if "--help" in args or "-h" in args:
35
+ print("Usage: clm workflow <run|validate|status> <dag.yaml> [options]")
36
+ return 0
37
+
38
+ if not args:
39
+ print("Usage: clm workflow <run|validate|status> <dag.yaml> [options]", file=sys.stderr)
40
+ return 2
41
+
42
+ return handle_workflow_cli(args)