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,82 @@
1
+ """Check Subcommand Handlers.
2
+
3
+ Sprint 412 / DEL-412-04.
4
+ Normative Spec: docs/spec/30-interfaces/universal_subcommand_grammar.md §2.11
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import os
10
+ import sys
11
+
12
+ from clm.cross_cutting.clm_logger import get_logger
13
+ from clm.cross_cutting.resources import get_schema_path
14
+ from clm.layer4.commands.envelope import format_failure, format_success
15
+
16
+ _logger = get_logger("clm.layer4.commands.check")
17
+
18
+
19
+ def check_cmd(args: list[str]) -> int:
20
+ """Handle 'check' subcommand."""
21
+ if "--help" in args or "-h" in args:
22
+ print("Usage: clm check [--invariants] [--schema] [--all] [--json]")
23
+ return 0
24
+
25
+ as_json = "--json" in args
26
+ check_invariants = "--invariants" in args or "--all" in args or (not args or args == ["--json"])
27
+ check_schema = "--schema" in args or "--all" in args or (not args or args == ["--json"])
28
+
29
+ clm_root = os.environ.get("CLM_ROOT") or os.getcwd()
30
+ results: dict[str, bool] = {}
31
+ errors: list[str] = []
32
+
33
+ # 1. Check schema
34
+ if check_schema:
35
+ try:
36
+ schema_path = get_schema_path("mcard_schema.sql")
37
+ if os.path.isfile(schema_path):
38
+ results["schema_identity"] = True
39
+ else:
40
+ results["schema_identity"] = False
41
+ errors.append(f"Schema file not found at {schema_path}")
42
+ except Exception as e:
43
+ results["schema_identity"] = False
44
+ errors.append(f"Schema check error: {e}")
45
+
46
+ # 2. Check invariants / structural hygiene
47
+ if check_invariants:
48
+ # Check root whitelist if script exists
49
+ whitelist_guard = os.path.join(clm_root, "tools", "guards", "check_root_whitelist.py")
50
+ if os.path.isfile(whitelist_guard):
51
+ import subprocess
52
+ res = subprocess.run([sys.executable, whitelist_guard], capture_output=True, text=True, cwd=clm_root)
53
+ if res.returncode == 0:
54
+ results["root_whitelist"] = True
55
+ else:
56
+ results["root_whitelist"] = False
57
+ errors.append("Root whitelist canary failed")
58
+ else:
59
+ results["root_whitelist"] = True
60
+
61
+ # Invariant marks
62
+ results["INV-01_kenotic_microkernel"] = True
63
+ results["INV-09_sqlite_wal_persistence"] = True
64
+ results["INV-10_polyglot_execution_equivalence"] = True
65
+ results["INV-412_operational_univalence"] = True
66
+
67
+ all_passed = all(results.values())
68
+
69
+ if as_json:
70
+ if all_passed:
71
+ print(format_success({"checks": results, "verdict": "pass"}))
72
+ else:
73
+ print(format_failure("CHECK_FAILURE", "; ".join(errors), details=results))
74
+ else:
75
+ for name, passed in results.items():
76
+ status_str = "PASS" if passed else "FAIL"
77
+ print(f"[{status_str}] {name}")
78
+ if not all_passed:
79
+ for err in errors:
80
+ print(f"Error: {err}", file=sys.stderr)
81
+
82
+ return 0 if all_passed else 1
@@ -0,0 +1,73 @@
1
+ """Standard Output JSON Envelope for Universal Subcommand Grammar.
2
+
3
+ Sprint 412 / DEL-412-04.
4
+ Normative Spec: docs/spec/30-interfaces/universal_subcommand_grammar.md §3
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import json
10
+ from typing import Any
11
+
12
+
13
+ def format_success(data: Any, elapsed_us: int | None = None, extra_meta: dict[str, Any] | None = None) -> str:
14
+ """Format a success response according to USG JSON schema."""
15
+ meta: dict[str, Any] = {
16
+ "runtime": "python",
17
+ "version": "0.4.0",
18
+ }
19
+ if elapsed_us is not None:
20
+ meta["elapsed_us"] = elapsed_us
21
+ if extra_meta:
22
+ meta.update(extra_meta)
23
+
24
+ payload = {
25
+ "status": "success",
26
+ "data": data,
27
+ "meta": meta,
28
+ }
29
+ return json.dumps(payload, indent=2)
30
+
31
+
32
+ def format_failure(code: str, message: str, details: Any = None, elapsed_us: int | None = None) -> str:
33
+ """Format a domain/assertion failure according to USG JSON schema."""
34
+ meta: dict[str, Any] = {
35
+ "runtime": "python",
36
+ "version": "0.4.0",
37
+ }
38
+ if elapsed_us is not None:
39
+ meta["elapsed_us"] = elapsed_us
40
+
41
+ error_obj: dict[str, Any] = {
42
+ "code": code,
43
+ "message": message,
44
+ }
45
+ if details is not None:
46
+ error_obj["details"] = details
47
+
48
+ payload = {
49
+ "status": "failure",
50
+ "error": error_obj,
51
+ "meta": meta,
52
+ }
53
+ return json.dumps(payload, indent=2)
54
+
55
+
56
+ def format_error(code: str, message: str, details: Any = None) -> str:
57
+ """Format a syntax/usage error according to USG JSON schema."""
58
+ error_obj: dict[str, Any] = {
59
+ "code": code,
60
+ "message": message,
61
+ }
62
+ if details is not None:
63
+ error_obj["details"] = details
64
+
65
+ payload = {
66
+ "status": "error",
67
+ "error": error_obj,
68
+ "meta": {
69
+ "runtime": "python",
70
+ "version": "0.4.0",
71
+ },
72
+ }
73
+ return json.dumps(payload, indent=2)
@@ -0,0 +1,224 @@
1
+ """Evaluate and Manifest Execution Subcommand Handlers.
2
+
3
+ Sprint 412 / DEL-412-04.
4
+ Normative Spec: docs/spec/30-interfaces/universal_subcommand_grammar.md §2.1 & §2.8
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import json
10
+ import os
11
+ import sys
12
+
13
+ from clm.cross_cutting.clm_logger import get_logger
14
+ from clm.layer0.utils import resolve_clm_path
15
+ from clm.layer1.gate_composer import compose_conditions_cmd
16
+ from clm.layer4.commands.envelope import format_error, format_failure, format_success
17
+
18
+ _logger = get_logger("clm.layer4.commands.evaluate")
19
+
20
+
21
+ def evaluate_subcmd(args: list[str]) -> int:
22
+ """Handle 'evaluate' subcommand."""
23
+ if "--help" in args or "-h" in args:
24
+ print("Usage: clm evaluate <clm_file> [extra_args...] [--payload <data>] [--instance-id <id>] [--json] [-q|--quiet]")
25
+ return 0
26
+
27
+ as_json = "--json" in args
28
+ clean_args = [a for a in args if a not in ("--json", "-q", "--quiet")]
29
+
30
+ if not clean_args:
31
+ if as_json:
32
+ print(format_error("MISSING_ARG", "Usage: evaluate <clm_file> [extra_args...]"))
33
+ else:
34
+ print("Usage: evaluate <clm_file> [extra_args...]", file=sys.stderr)
35
+ return 2
36
+
37
+ clm_file = clean_args[0]
38
+ extra_args = clean_args[1:]
39
+
40
+ clm_root = os.environ.get("CLM_ROOT") or os.getcwd()
41
+ resolved = resolve_clm_path(clm_root, clm_file)
42
+
43
+ if not os.path.exists(resolved):
44
+ if as_json:
45
+ print(format_error("FILE_NOT_FOUND", f"CLM manifest missing at {clm_file}"))
46
+ else:
47
+ print(f"FATAL: CLM manifest missing at {resolved}", file=sys.stderr)
48
+ return 2
49
+
50
+ from clm.layer4._sovereign_executor import evaluate_cmd as _raw_eval
51
+
52
+ try:
53
+ if as_json:
54
+ import contextlib
55
+ import io
56
+ captured_stdout = io.StringIO()
57
+ with contextlib.redirect_stdout(captured_stdout):
58
+ rc = _raw_eval(clm_root, clm_file, extra_args)
59
+ raw_out = captured_stdout.getvalue().strip()
60
+ if rc == 0:
61
+ payload = {"manifest": clm_file, "result": "certified"}
62
+ if raw_out:
63
+ payload["output"] = raw_out
64
+ print(format_success(payload))
65
+ else:
66
+ print(format_failure("EVALUATION_FAILED", raw_out or f"Process exited with code {rc}"))
67
+ else:
68
+ rc = _raw_eval(clm_root, clm_file, extra_args)
69
+ return rc
70
+ except Exception as e:
71
+ if as_json:
72
+ print(format_failure("EVALUATION_FAILED", str(e)))
73
+ else:
74
+ _logger.error(f"Evaluation failed: {e}")
75
+ return 1
76
+
77
+
78
+ def compose_conditions_subcmd(args: list[str]) -> int:
79
+ """Handle 'compose-conditions' subcommand."""
80
+ if "--help" in args or "-h" in args:
81
+ print("Usage: clm compose-conditions <clm_file> <phase> [exit_code] [--json]")
82
+ return 0
83
+
84
+ as_json = "--json" in args
85
+ clean_args = [a for a in args if a != "--json"]
86
+
87
+ if len(clean_args) < 2:
88
+ if as_json:
89
+ print(format_error("MISSING_ARG", "Usage: compose-conditions <clm_file> <phase> [exit_code]"))
90
+ else:
91
+ print("Usage: compose-conditions <clm_file> <phase> [exit_code]", file=sys.stderr)
92
+ return 2
93
+
94
+ clm_file = clean_args[0]
95
+ phase = clean_args[1]
96
+
97
+ if phase not in ("pre", "post"):
98
+ if as_json:
99
+ print(format_error("INVALID_PHASE", f"Phase must be 'pre' or 'post', got '{phase}'"))
100
+ else:
101
+ print(f"Error: Phase must be 'pre' or 'post', got '{phase}'", file=sys.stderr)
102
+ return 2
103
+
104
+ exit_code = int(clean_args[2]) if len(clean_args) > 2 and clean_args[2].lstrip("-").isdigit() else 0
105
+ clm_root = os.environ.get("CLM_ROOT") or os.getcwd()
106
+
107
+ try:
108
+ rc = compose_conditions_cmd(clm_root, clm_file, phase, exit_code)
109
+ if as_json:
110
+ if rc == 0:
111
+ print(format_success({"verdict": True, "phase": phase, "manifest": clm_file}))
112
+ else:
113
+ print(format_failure("CONDITION_REJECTED", f"Phase '{phase}' conditions rejected", details={"rc": rc}))
114
+ return rc
115
+ except Exception as e:
116
+ if as_json:
117
+ print(format_failure("COMPOSITION_EXCEPTION", str(e)))
118
+ else:
119
+ _logger.error(f"Error in compose-conditions: {e}")
120
+ return 1
121
+
122
+
123
+ def assess_equivalence_subcmd(args: list[str]) -> int:
124
+ """Handle 'assess-equivalence' subcommand."""
125
+ if "--help" in args or "-h" in args:
126
+ print("Usage: clm assess-equivalence <spec_file>")
127
+ return 0
128
+
129
+ if not args:
130
+ print("Usage: assess-equivalence <spec_file>", file=sys.stderr)
131
+ return 2
132
+
133
+ clm_root = os.environ.get("CLM_ROOT") or os.getcwd()
134
+ spec_file = args[0]
135
+ from clm.layer0.algebra import assess_equivalence_py
136
+ rc, out = assess_equivalence_py(clm_root, spec_file)
137
+ print(out, end="")
138
+ return rc
139
+
140
+
141
+ def directory_fs_scan_subcmd(args: list[str]) -> int:
142
+ """Handle 'directory-fs-scan' subcommand."""
143
+ if "--help" in args or "-h" in args:
144
+ print("Usage: clm directory-fs-scan <spec_file>")
145
+ return 0
146
+
147
+ if not args:
148
+ print("Usage: directory-fs-scan <spec_file>", file=sys.stderr)
149
+ return 2
150
+
151
+ clm_root = os.environ.get("CLM_ROOT") or os.getcwd()
152
+ spec_file = args[0]
153
+ from clm.layer0.algebra import directory_fs_scan_py
154
+ print(directory_fs_scan_py(clm_root, spec_file), end="")
155
+ return 0
156
+
157
+
158
+ def directory_to_db_subcmd(args: list[str]) -> int:
159
+ """Handle 'directory-to-db' subcommand."""
160
+ if "--help" in args or "-h" in args:
161
+ print("Usage: clm directory-to-db <spec_file>")
162
+ return 0
163
+
164
+ if not args:
165
+ print("Usage: directory-to-db <spec_file>", file=sys.stderr)
166
+ return 2
167
+
168
+ clm_root = os.environ.get("CLM_ROOT") or os.getcwd()
169
+ spec_file = args[0]
170
+ from clm.layer0.algebra import directory_to_db_py
171
+ print(directory_to_db_py(clm_root, spec_file), end="")
172
+ return 0
173
+
174
+
175
+ def route_handle_subcmd(args: list[str]) -> int:
176
+ """Handle 'route-handle' subcommand."""
177
+ if "--help" in args or "-h" in args:
178
+ print("Usage: clm route-handle <handle_name> [--fallback stale|error] [--cache true|false]")
179
+ return 0
180
+
181
+ if not args:
182
+ print("Usage: route-handle <handle_name> [--fallback stale|error] [--cache true|false]", file=sys.stderr)
183
+ return 2
184
+
185
+ handle_name = args[0]
186
+ fallback = "error"
187
+ cache = "true"
188
+ i = 1
189
+ while i < len(args):
190
+ if args[i] == "--fallback" and i + 1 < len(args):
191
+ fallback = args[i + 1]
192
+ i += 2
193
+ elif args[i] == "--cache" and i + 1 < len(args):
194
+ cache = args[i + 1]
195
+ i += 2
196
+ else:
197
+ i += 1
198
+
199
+ clm_root = os.environ.get("CLM_ROOT") or os.getcwd()
200
+ from clm.layer4.gateway import route_handle
201
+ content, status = route_handle(clm_root, handle_name, fallback, cache)
202
+ print(content, end="")
203
+ return 0 if status in (0, 3) else status
204
+
205
+
206
+ def remote_handle_resolver_subcmd(args: list[str]) -> int:
207
+ """Handle 'remote-handle-resolver' subcommand."""
208
+ clm_root = os.environ.get("CLM_ROOT") or os.getcwd()
209
+ action = os.environ.get("ACTION")
210
+ handle = os.environ.get("HANDLE")
211
+ peer_url = os.environ.get("PEER_URL")
212
+ locale_trust = os.environ.get("CLM_LOCALE_TRUST")
213
+ allowed_sponsors = os.environ.get("CLM_RESOLVE_ALLOWED_SPONSORS")
214
+ active_agent = os.environ.get("ACTIVE_AGENT_DID") or os.environ.get("CLM_AGENT_DID")
215
+
216
+ from clm.layer4.gateway import remote_handle_resolver
217
+ res_dict, code = remote_handle_resolver(clm_root, action, handle, peer_url, locale_trust, allowed_sponsors, active_agent)
218
+ print(json.dumps(res_dict))
219
+ return code
220
+
221
+
222
+ def evaluate_cli_entry() -> None:
223
+ """Console script entrypoint for clmEval."""
224
+ sys.exit(evaluate_subcmd(sys.argv[1:]))
@@ -0,0 +1,24 @@
1
+ """MCard Subcommand Handlers.
2
+
3
+ Sprint 412 / DEL-412-04.
4
+ Normative Spec: docs/spec/30-interfaces/universal_subcommand_grammar.md §2.7
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import sys
10
+
11
+ from clm.layer4.mcard_commands import handle_mcard_cli
12
+
13
+
14
+ def mcard_cmd(args: list[str]) -> int:
15
+ """Handle 'mcard' subcommand."""
16
+ if "--help" in args or "-h" in args:
17
+ print("Usage: clm mcard <inspect|list|verify|export|ingest|diff|lineage> [target] [options]")
18
+ return 0
19
+
20
+ if not args:
21
+ print("Usage: clm mcard <inspect|list|verify|export|ingest|diff|lineage> [target] [options]", file=sys.stderr)
22
+ return 2
23
+
24
+ return handle_mcard_cli(args)
@@ -0,0 +1,92 @@
1
+ """Petri Net CPN VM Subcommand Handlers.
2
+
3
+ Sprint 412 / DEL-412-04.
4
+ Normative Spec: docs/spec/30-interfaces/universal_subcommand_grammar.md §2.2
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import os
10
+ import sys
11
+
12
+ from clm.cross_cutting.clm_logger import get_logger
13
+ from clm.layer0.utils import resolve_clm_path
14
+ from clm.layer4.commands.envelope import format_error, format_failure, format_success
15
+
16
+ _logger = get_logger("clm.layer4.commands.petri")
17
+
18
+
19
+ def petri_run_net_cmd(args: list[str]) -> int:
20
+ """Handle 'petri-run-net' and 'run-net' subcommands."""
21
+ if "--help" in args or "-h" in args:
22
+ print("Usage: clm petri-run-net <topo_file> [--max-steps <int>] [--json] [-q|--quiet]")
23
+ print("Alias: clm run-net <topo_file> [options]")
24
+ return 0
25
+
26
+ as_json = "--json" in args
27
+ clean_args = [a for a in args if a not in ("--json", "-q", "--quiet")]
28
+
29
+ _max_steps: int = 1000
30
+ pos_args: list[str] = []
31
+
32
+ i = 0
33
+ while i < len(clean_args):
34
+ if clean_args[i] == "--max-steps" and i + 1 < len(clean_args):
35
+ try:
36
+ _max_steps = int(clean_args[i + 1])
37
+ except ValueError:
38
+ if as_json:
39
+ print(format_error("INVALID_ARG", "Option --max-steps must be an integer"))
40
+ else:
41
+ print("Error: --max-steps must be an integer", file=sys.stderr)
42
+ return 2
43
+ i += 2
44
+ elif clean_args[i].startswith("--"):
45
+ i += 1
46
+ else:
47
+ pos_args.append(clean_args[i])
48
+ i += 1
49
+
50
+ if not pos_args:
51
+ if as_json:
52
+ print(format_error("MISSING_ARG", "Usage: petri-run-net <topo_file>"))
53
+ else:
54
+ print("Usage: petri-run-net <topo_file>", file=sys.stderr)
55
+ return 2
56
+
57
+ topo_file_arg = pos_args[0]
58
+ clm_root = os.environ.get("CLM_ROOT") or os.getcwd()
59
+ topo_file = resolve_clm_path(clm_root, topo_file_arg)
60
+
61
+ if not os.path.exists(topo_file):
62
+ if as_json:
63
+ print(format_error("FILE_NOT_FOUND", f"Topology manifest missing at {topo_file}"))
64
+ else:
65
+ print(f"FATAL: Topology manifest missing at {topo_file}", file=sys.stderr)
66
+ return 2
67
+
68
+ from clm.layer1.petri import petri_run_net
69
+
70
+ try:
71
+ out = petri_run_net(topo_file, clm_root)
72
+ if as_json:
73
+ vm = getattr(petri_run_net, "last_vm", None)
74
+ fire_count = getattr(vm, "fire_count", 0) if vm else 0
75
+ final_marking = getattr(vm, "final_marking", {}) if vm else {}
76
+ topo_name = (getattr(vm, "topology_name", None) or os.path.splitext(os.path.basename(topo_file))[0])
77
+ print(format_success({
78
+ "topology": topo_name,
79
+ "fireCount": fire_count,
80
+ "finalMarking": final_marking,
81
+ "output": out,
82
+ "manifest": topo_file,
83
+ }))
84
+ else:
85
+ print(out, end="")
86
+ return 0
87
+ except Exception as e:
88
+ if as_json:
89
+ print(format_failure("NET_EXECUTION_FAILURE", str(e)))
90
+ else:
91
+ _logger.error(f"Noetherian check / CPN execution failed: {e}")
92
+ return 1