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.
- clm/__init__.py +230 -0
- clm/__main__.py +25 -0
- clm/cross_cutting/__init__.py +50 -0
- clm/cross_cutting/_test_runner.py +36 -0
- clm/cross_cutting/async_utils.py +25 -0
- clm/cross_cutting/cel_builder.py +123 -0
- clm/cross_cutting/cel_converter.py +697 -0
- clm/cross_cutting/cel_engine.py +252 -0
- clm/cross_cutting/cel_ops.py +72 -0
- clm/cross_cutting/cel_ops_db.py +157 -0
- clm/cross_cutting/cel_ops_files.py +99 -0
- clm/cross_cutting/cel_ops_state.py +71 -0
- clm/cross_cutting/cel_ops_strings.py +64 -0
- clm/cross_cutting/cel_resolver.py +63 -0
- clm/cross_cutting/cel_slices.py +56 -0
- clm/cross_cutting/cel_store.py +330 -0
- clm/cross_cutting/clm_logger.py +140 -0
- clm/cross_cutting/config/__init__.py +155 -0
- clm/cross_cutting/config/config_constants.py +392 -0
- clm/cross_cutting/config/env_parameters.py +90 -0
- clm/cross_cutting/config/logging.py +378 -0
- clm/cross_cutting/config/settings.py +504 -0
- clm/cross_cutting/context.py +5 -0
- clm/cross_cutting/domain_models.py +55 -0
- clm/cross_cutting/domain_types.py +61 -0
- clm/cross_cutting/effects.py +67 -0
- clm/cross_cutting/errors.py +153 -0
- clm/cross_cutting/governance.py +331 -0
- clm/cross_cutting/guards.py +41 -0
- clm/cross_cutting/mcard.py +321 -0
- clm/cross_cutting/native.py +185 -0
- clm/cross_cutting/observability.py +289 -0
- clm/cross_cutting/pcard.py +434 -0
- clm/cross_cutting/registry.py +71 -0
- clm/cross_cutting/resources.py +84 -0
- clm/cross_cutting/secrets.py +44 -0
- clm/cross_cutting/subprocess_utils.py +118 -0
- clm/cross_cutting/telemetry.py +164 -0
- clm/cross_cutting/testing/__init__.py +8 -0
- clm/cross_cutting/testing/comparator.py +187 -0
- clm/cross_cutting/testing/datasets.py +87 -0
- clm/cross_cutting/timeutil.py +20 -0
- clm/cross_cutting/types/new_type_check.py +0 -0
- clm/cross_cutting/utils/__init__.py +1 -0
- clm/cross_cutting/utils/url_safety.py +50 -0
- clm/cross_cutting/vcard.py +560 -0
- clm/cross_cutting/writer.py +118 -0
- clm/layer0/README.md +50 -0
- clm/layer0/__init__.py +223 -0
- clm/layer0/algebra.py +60 -0
- clm/layer0/algebra_baldwin.py +133 -0
- clm/layer0/algebra_baldwin_generators.py +36 -0
- clm/layer0/algebra_equivalence.py +262 -0
- clm/layer0/algebra_ingest.py +306 -0
- clm/layer0/algebra_manifest_io.py +156 -0
- clm/layer0/assembler.py +481 -0
- clm/layer0/cel/__init__.py +23 -0
- clm/layer0/cel_eval.py +491 -0
- clm/layer0/codec.py +106 -0
- clm/layer0/context.py +122 -0
- clm/layer0/db.py +160 -0
- clm/layer0/exceptions.py +73 -0
- clm/layer0/fibration.py +106 -0
- clm/layer0/gates.py +50 -0
- clm/layer0/hash.py +80 -0
- clm/layer0/loader.py +826 -0
- clm/layer0/math_utils.py +163 -0
- clm/layer0/mcard.py +96 -0
- clm/layer0/model/__init__.py +0 -0
- clm/layer0/model/action.py +223 -0
- clm/layer0/model/card.py +280 -0
- clm/layer0/model/card_triad.py +427 -0
- clm/layer0/model/compatibility.py +60 -0
- clm/layer0/model/dictionary.py +46 -0
- clm/layer0/model/dots.py +331 -0
- clm/layer0/model/event_producer.py +88 -0
- clm/layer0/model/g_time.py +89 -0
- clm/layer0/model/handle.py +163 -0
- clm/layer0/model/hash/__init__.py +6 -0
- clm/layer0/model/hash/algorithms/__init__.py +3 -0
- clm/layer0/model/hash/algorithms/custom_hash.py +7 -0
- clm/layer0/model/hash/algorithms/local_sha256.py +178 -0
- clm/layer0/model/hash/constants.py +53 -0
- clm/layer0/model/hash/enums.py +60 -0
- clm/layer0/model/hash/validator.py +307 -0
- clm/layer0/model/interpreter.py +275 -0
- clm/layer0/model/pagination.py +45 -0
- clm/layer0/model/pcard.py +716 -0
- clm/layer0/model/schema.py +44 -0
- clm/layer0/model/utils/__init__.py +1 -0
- clm/layer0/model/utils/content_analyzer.py +152 -0
- clm/layer0/model/validators/__init__.py +1 -0
- clm/layer0/model/validators/base_validator.py +44 -0
- clm/layer0/model/validators/binary_validator.py +66 -0
- clm/layer0/model/validators/text_validator.py +82 -0
- clm/layer0/model/validators/validation_registry.py +49 -0
- clm/layer0/model/vcard.py +823 -0
- clm/layer0/model/vcard_ext/__init__.py +39 -0
- clm/layer0/model/vcard_ext/core.py +60 -0
- clm/layer0/model/vcard_ext/network.py +23 -0
- clm/layer0/model/vcard_ext/observability.py +63 -0
- clm/layer0/model/vcard_ext/storage.py +60 -0
- clm/layer0/model/vcard_ext/vendors.py +211 -0
- clm/layer0/model/vcard_sandwich.py +119 -0
- clm/layer0/model/vcard_vocabulary.py +463 -0
- clm/layer0/model/workflow.py +274 -0
- clm/layer0/narrative.py +431 -0
- clm/layer0/ontology/collection.py +125 -0
- clm/layer0/parser.py +429 -0
- clm/layer0/relations.py +73 -0
- clm/layer0/rule_evaluator.py +251 -0
- clm/layer0/schema/__init__.py +38 -0
- clm/layer0/schema/ddl.py +97 -0
- clm/layer0/templates/abstract.yaml +99 -0
- clm/layer0/templates/balanced.yaml +253 -0
- clm/layer0/templates/concrete.yaml +172 -0
- clm/layer0/type_registry.py +223 -0
- clm/layer0/types.py +204 -0
- clm/layer0/utils.py +886 -0
- clm/layer0/verifier_core.py +262 -0
- clm/layer1/__init__.py +31 -0
- clm/layer1/action_dispatcher.py +275 -0
- clm/layer1/adapter_registry.py +233 -0
- clm/layer1/algebra_baldwin_generators.py +192 -0
- clm/layer1/arrow_compiler.py +525 -0
- clm/layer1/batch_processor.py +152 -0
- clm/layer1/cel/__init__.py +27 -0
- clm/layer1/cel/builder.py +173 -0
- clm/layer1/engine.py +759 -0
- clm/layer1/engine_async.py +89 -0
- clm/layer1/eval_callback.py +49 -0
- clm/layer1/gate_composer.py +229 -0
- clm/layer1/hoare_sandwich.py +298 -0
- clm/layer1/identity_guard.py +348 -0
- clm/layer1/matrix.py +138 -0
- clm/layer1/neural_runtime.py +221 -0
- clm/layer1/operations/__init__.py +123 -0
- clm/layer1/operations/augment.py +156 -0
- clm/layer1/operations/base.py +109 -0
- clm/layer1/operations/builtins.py +338 -0
- clm/layer1/operations/dispatch.py +144 -0
- clm/layer1/operations/exclude.py +107 -0
- clm/layer1/operations/handle.py +197 -0
- clm/layer1/operations/identity.py +139 -0
- clm/layer1/operations/invert.py +66 -0
- clm/layer1/operations/loader.py +116 -0
- clm/layer1/operations/manipulators/__init__.py +23 -0
- clm/layer1/operations/manipulators/document.py +211 -0
- clm/layer1/operations/manipulators/media.py +134 -0
- clm/layer1/operations/manipulators/structured.py +159 -0
- clm/layer1/operations/manipulators/tabular.py +334 -0
- clm/layer1/operations/port.py +65 -0
- clm/layer1/operations/services.py +529 -0
- clm/layer1/operations/split.py +117 -0
- clm/layer1/operations/substitute.py +75 -0
- clm/layer1/petri.py +1052 -0
- clm/layer1/pocketflow_orchestrator.py +408 -0
- clm/layer1/pocketflow_scheduler.py +519 -0
- clm/layer1/protocols.py +197 -0
- clm/layer1/runtime_adapter.py +718 -0
- clm/layer1/runtimes/__init__.py +71 -0
- clm/layer1/runtimes/_generated_assertions.py +125 -0
- clm/layer1/runtimes/_generated_types.py +42 -0
- clm/layer1/runtimes/base.py +265 -0
- clm/layer1/runtimes/binary.py +101 -0
- clm/layer1/runtimes/factory.py +203 -0
- clm/layer1/runtimes/javascript.py +321 -0
- clm/layer1/runtimes/javascript_runtime.js +33 -0
- clm/layer1/runtimes/js_scripts/isomorphism.mjs +22 -0
- clm/layer1/runtimes/js_scripts/loader.mjs +52 -0
- clm/layer1/runtimes/lambda_calc.py +126 -0
- clm/layer1/runtimes/python.py +288 -0
- clm/layer1/runtimes/python_runtime.py +41 -0
- clm/layer1/runtimes/script.py +114 -0
- clm/layer1/sandbox.py +334 -0
- clm/layer1/savepoint_guard.py +136 -0
- clm/layer1/sparse_net.py +122 -0
- clm/layer1/spec_tester.py +165 -0
- clm/layer1/store.py +295 -0
- clm/layer1/test_runner.py +498 -0
- clm/layer1/type_inspector.py +166 -0
- clm/layer1/verifier.py +772 -0
- clm/layer1/vm.py +91 -0
- clm/layer2/__init__.py +78 -0
- clm/layer2/card_collection.py +678 -0
- clm/layer2/classifier.py +479 -0
- clm/layer2/engine/__init__.py +1 -0
- clm/layer2/engine/abstract_sql_engine.py +320 -0
- clm/layer2/engine/base.py +193 -0
- clm/layer2/engine/duckdb_engine.py +576 -0
- clm/layer2/engine/sqlite_engine.py +518 -0
- clm/layer2/fiber/__init__.py +31 -0
- clm/layer2/fiber/context.py +89 -0
- clm/layer2/fiber/disposable.py +163 -0
- clm/layer2/fiber/fiber.py +125 -0
- clm/layer2/fiber/hoare.py +191 -0
- clm/layer2/file_io.py +376 -0
- clm/layer2/file_registrar.py +77 -0
- clm/layer2/ingest.py +202 -0
- clm/layer2/lineage.py +322 -0
- clm/layer2/mcard_fs.py +262 -0
- clm/layer2/merkle.py +11 -0
- clm/layer2/mime.py +244 -0
- clm/layer2/mime_detector.py +245 -0
- clm/layer2/private_collection.py +118 -0
- clm/layer2/shared_store.py +11 -0
- clm/layer2/storage/__init__.py +190 -0
- clm/layer2/storage/db_bitemporal.py +141 -0
- clm/layer2/storage/db_driver.py +331 -0
- clm/layer2/storage/db_hyperlinks.py +214 -0
- clm/layer2/storage/db_pool.py +139 -0
- clm/layer2/storage/db_repository.py +229 -0
- clm/layer2/storage/savepoint.py +78 -0
- clm/layer2/storage/sqlite_wal.py +74 -0
- clm/layer2/tridb.py +245 -0
- clm/layer2/vcard_receipt.py +71 -0
- clm/layer2/vfs.py +17 -0
- clm/layer3/__init__.py +141 -0
- clm/layer3/agency/__init__.py +19 -0
- clm/layer3/agency/config.py +220 -0
- clm/layer3/agency/providers/__init__.py +15 -0
- clm/layer3/agency/providers/base.py +91 -0
- clm/layer3/agency/providers/mlc_llm.py +169 -0
- clm/layer3/agency/providers/ollama.py +203 -0
- clm/layer3/agency/router.py +71 -0
- clm/layer3/agency/runtime.py +524 -0
- clm/layer3/gateway.py +353 -0
- clm/layer3/open_interpreter_adapter.py +159 -0
- clm/layer3/rag/__init__.py +70 -0
- clm/layer3/rag/cli.py +228 -0
- clm/layer3/rag/config.py +153 -0
- clm/layer3/rag/embeddings/__init__.py +16 -0
- clm/layer3/rag/embeddings/base.py +79 -0
- clm/layer3/rag/embeddings/ollama.py +211 -0
- clm/layer3/rag/embeddings/vision.py +290 -0
- clm/layer3/rag/engine.py +276 -0
- clm/layer3/rag/graph/__init__.py +22 -0
- clm/layer3/rag/graph/community.py +198 -0
- clm/layer3/rag/graph/engine.py +433 -0
- clm/layer3/rag/graph/extractor.py +255 -0
- clm/layer3/rag/graph/schema.py +115 -0
- clm/layer3/rag/graph/store.py +641 -0
- clm/layer3/rag/indexer.py +333 -0
- clm/layer3/rag/llm_providers.json +52 -0
- clm/layer3/rag/semantic_versioning.py +313 -0
- clm/layer3/rag/vector/__init__.py +28 -0
- clm/layer3/rag/vector/handle_vector_store.py +749 -0
- clm/layer3/rag/vector/schema.py +151 -0
- clm/layer3/rag/vector/store.py +632 -0
- clm/layer3/reticulum/__init__.py +55 -0
- clm/layer3/reticulum/bridge.py +74 -0
- clm/layer3/reticulum/daemon.py +88 -0
- clm/layer3/reticulum/discovery.py +164 -0
- clm/layer3/reticulum/identity.py +107 -0
- clm/layer3/reticulum/media.py +148 -0
- clm/layer3/reticulum/transport.py +133 -0
- clm/layer3/satori/__init__.py +209 -0
- clm/layer3/satori/alpha_conversion.py +168 -0
- clm/layer3/satori/beta_reduction.py +359 -0
- clm/layer3/satori/continuation.py +38 -0
- clm/layer3/satori/eta_conversion.py +205 -0
- clm/layer3/satori/free_variables.py +163 -0
- clm/layer3/satori/io_effects.py +370 -0
- clm/layer3/satori/lambda_runtime.py +726 -0
- clm/layer3/satori/lambda_term.py +230 -0
- clm/layer3/satori/sheaf_audit.py +261 -0
- clm/layer3/satori/speech_act.py +279 -0
- clm/layer4/README.md +9 -0
- clm/layer4/__init__.py +67 -0
- clm/layer4/_sovereign_executor.py +580 -0
- clm/layer4/action_commands.py +719 -0
- clm/layer4/api.py +236 -0
- clm/layer4/bootstrap/__init__.py +13 -0
- clm/layer4/bootstrap/bootstrapper.py +118 -0
- clm/layer4/bootstrap/cleanup.py +44 -0
- clm/layer4/bootstrap/clm_hooks.py +49 -0
- clm/layer4/bootstrap/genesis.py +77 -0
- clm/layer4/bootstrap/injection.py +125 -0
- clm/layer4/cli.py +549 -0
- clm/layer4/collection_manager.py +553 -0
- clm/layer4/commands/__init__.py +81 -0
- clm/layer4/commands/action_cmd.py +42 -0
- clm/layer4/commands/check_cmd.py +82 -0
- clm/layer4/commands/envelope.py +73 -0
- clm/layer4/commands/evaluate_cmd.py +224 -0
- clm/layer4/commands/mcard_cmd.py +24 -0
- clm/layer4/commands/petri_cmd.py +92 -0
- clm/layer4/commands/tridb_cmd.py +319 -0
- clm/layer4/commands/version_cmd.py +27 -0
- clm/layer4/diff_commands.py +167 -0
- clm/layer4/eoa_sponsor.py +232 -0
- clm/layer4/events.py +69 -0
- clm/layer4/flux_gateway.py +133 -0
- clm/layer4/gateway.py +91 -0
- clm/layer4/loader.py +307 -0
- clm/layer4/mcard_commands.py +166 -0
- clm/layer4/membrane.py +273 -0
- clm/layer4/navigation.py +50 -0
- clm/layer4/protocol/protocol_entry_python.py +108 -0
- clm/layer4/protocol/python_sync.py +126 -0
- clm/layer4/runner.py +150 -0
- clm/layer4/satori.py +262 -0
- clm/layer4/server/python_sync_client.py +150 -0
- clm/layer4/server/python_sync_server.py +139 -0
- clm/layer4/server/service_api.py +315 -0
- clm/layer4/server/start_servers.py +107 -0
- clm/layer4/server/stop_servers.py +24 -0
- clm/layer4/simulated_optimization_fix.py +0 -0
- clm/layer4/storage.py +463 -0
- clm/layer4/tridb_admin.py +268 -0
- clm/layer4/websocket/test_ws_client.py +104 -0
- clm/layer4/websocket/test_ws_server.py +138 -0
- clm/layer4/websocket/ws_server_local.py +160 -0
- clm/layer5/__init__.py +51 -0
- clm/layer5/async_batch_writer.py +133 -0
- clm/layer5/learning.py +276 -0
- clm/layer5/telemetry_hook.py +107 -0
- clm/layer5/type_lattice.py +238 -0
- clm/py.typed +0 -0
- clm/schemas/__init__.py +652 -0
- clm/schemas/abstract_face_schema.yaml +77 -0
- clm/schemas/cel_schema.yaml +416 -0
- clm/schemas/lifecycle/__init__.py +45 -0
- clm/schemas/lifecycle/models.py +123 -0
- clm/schemas/lifecycle/service.py +364 -0
- clm/schemas/mcard_schema.sql +192 -0
- clm/schemas/mcard_vector_schema.sql +283 -0
- clm/schemas/mlp-context-v1.json +91 -0
- clm_kernel-0.0.0.dist-info/METADATA +121 -0
- clm_kernel-0.0.0.dist-info/RECORD +333 -0
- clm_kernel-0.0.0.dist-info/WHEEL +4 -0
- clm_kernel-0.0.0.dist-info/entry_points.txt +3 -0
- 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
|