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,153 @@
|
|
|
1
|
+
"""CLM Domain Error Hierarchy (Sprint 175).
|
|
2
|
+
|
|
3
|
+
Stratified domain exception hierarchy for the CLM Python reference runtime.
|
|
4
|
+
Enforces cause chaining (raise ... from err), zero swallowed exceptions,
|
|
5
|
+
and machine-readable JSON-RPC serialization (to_payload()) for Satori protocol bridges.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import datetime
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ClmDomainError(Exception):
|
|
15
|
+
"""Base exception for all domain errors within CLM."""
|
|
16
|
+
|
|
17
|
+
code: int = 1000
|
|
18
|
+
category: str = "kernel"
|
|
19
|
+
is_retriable: bool = False
|
|
20
|
+
|
|
21
|
+
def __init__(
|
|
22
|
+
self,
|
|
23
|
+
message: str,
|
|
24
|
+
*,
|
|
25
|
+
details: dict[str, Any] | None = None,
|
|
26
|
+
cause: Exception | None = None,
|
|
27
|
+
is_retriable: bool = False,
|
|
28
|
+
) -> None:
|
|
29
|
+
super().__init__(message)
|
|
30
|
+
self.message = message
|
|
31
|
+
self.details = details or {}
|
|
32
|
+
self.is_retriable = is_retriable
|
|
33
|
+
self.timestamp = datetime.datetime.now(datetime.timezone.utc).isoformat()
|
|
34
|
+
if cause is not None:
|
|
35
|
+
self.__cause__ = cause
|
|
36
|
+
|
|
37
|
+
def to_payload(self) -> dict[str, Any]:
|
|
38
|
+
"""Serialize into a machine-readable JSON-RPC error payload for Satori bridges and Maxwell's Demon."""
|
|
39
|
+
return {
|
|
40
|
+
"error": {
|
|
41
|
+
"code": self.code,
|
|
42
|
+
"category": self.category,
|
|
43
|
+
"name": self.__class__.__name__,
|
|
44
|
+
"message": self.message,
|
|
45
|
+
"details": self.details,
|
|
46
|
+
"is_retriable": self.is_retriable,
|
|
47
|
+
"timestamp": self.timestamp,
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class ExecutionEngineError(ClmDomainError):
|
|
53
|
+
"""Execution error within CLM runtime adapters or runner engines."""
|
|
54
|
+
code: int = 1500
|
|
55
|
+
category: str = "kernel.execution"
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# -- Layer 0: Kenotic Core & Type System ---------------------------
|
|
59
|
+
class TypeLatticeError(ClmDomainError):
|
|
60
|
+
code = 1100
|
|
61
|
+
category = "layer0.type_lattice"
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class StratificationViolationError(TypeLatticeError):
|
|
65
|
+
code = 1101 # Level N item referencing Level N+1 item
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class AlgebraicClosedOperatorError(ClmDomainError):
|
|
69
|
+
code = 1200 # Split, Exclude, Augment, Substitute, Invert, Port failure
|
|
70
|
+
category = "layer0.algebra"
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# -- Layer 1: Colored Petri Net VM & VCard Gates -------------------
|
|
74
|
+
class CpnVMError(ClmDomainError):
|
|
75
|
+
code = 2000
|
|
76
|
+
category = "layer1.cpn"
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class TokenConservationViolationError(CpnVMError):
|
|
80
|
+
code = 2001 # x^T D != 0 Noetherian conservation failure
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class DeadlockDetectedError(CpnVMError):
|
|
84
|
+
code = 2002 # Net locked with non-terminal markings
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class TransitionAclDeniedError(CpnVMError):
|
|
88
|
+
code = 2003 # Agent DID not authorized to fire transition
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class VCardGateError(ClmDomainError):
|
|
92
|
+
code = 2100
|
|
93
|
+
category = "layer1.vcard"
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class PreconditionViolationError(VCardGateError):
|
|
97
|
+
code = 2101 # {P} failed before PCard execution
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class PostconditionViolationError(VCardGateError):
|
|
101
|
+
code = 2102 # {Q} failed after PCard execution
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class VCardEvaluationFaultError(VCardGateError):
|
|
105
|
+
code = 2103 # Unexpected system/IO fault during gate execution
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
# -- Layer 2: Storage, CAS & Merkle DAG ----------------------------
|
|
109
|
+
class StorageEngineError(ClmDomainError):
|
|
110
|
+
code = 3000
|
|
111
|
+
category = "layer2.storage"
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class ContentHashMismatchError(StorageEngineError):
|
|
115
|
+
code = 3001 # Computed BLAKE3/SHA-256 does not match MCard key
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class HandleNotFoundError(StorageEngineError):
|
|
119
|
+
code = 3002
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class DatabaseLockTimeoutError(StorageEngineError):
|
|
123
|
+
code = 3003
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class ManifestParseError(StorageEngineError):
|
|
127
|
+
code = 3004
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
# -- Layer 3: Identity, Auth & Network Mesh -------------------------
|
|
131
|
+
class IdentityAuthError(ClmDomainError):
|
|
132
|
+
code = 4000
|
|
133
|
+
category = "layer3.auth"
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class InvalidDidSignatureError(IdentityAuthError):
|
|
137
|
+
code = 4001
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class PeerUnreachableError(ClmDomainError):
|
|
141
|
+
code = 4100
|
|
142
|
+
category = "layer3.network"
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
# -- Layer 4: CEL, Dispatch & Surface ------------------------------
|
|
146
|
+
class CelEvaluationError(ClmDomainError):
|
|
147
|
+
code = 5000
|
|
148
|
+
category = "layer4.cel"
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class OperationNotFoundError(ClmDomainError):
|
|
152
|
+
code = 5100
|
|
153
|
+
category = "layer4.dispatch"
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Token Arithmetics Governance Computation Module.
|
|
3
|
+
|
|
4
|
+
Pure-function module containing the quantitative governance metrics defined in:
|
|
5
|
+
- Architecture §1.7: Inherent Governance
|
|
6
|
+
- Architecture §03: Token Arithmetics — Governance Through Possibility Space Assessment
|
|
7
|
+
- Specifications §04 §2.5: Type-Based Possibility Arithmetics
|
|
8
|
+
|
|
9
|
+
All functions are side-effect-free and operate exclusively on primitive values.
|
|
10
|
+
No database access, no I/O — just math.
|
|
11
|
+
|
|
12
|
+
Metrics computed:
|
|
13
|
+
- M (Possibility Magnitude): |B|^|A| — total combinatorial space
|
|
14
|
+
- N (Governance Narrowing): 1 - |B'|^|A'| / |B|^|A| — policy restrictiveness
|
|
15
|
+
- E (Epiplexity Yield): S_T / M — structured knowledge per possibility
|
|
16
|
+
- Pi (Product Dependency Count): number of concurrent precondition evaluations
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
import logging
|
|
22
|
+
from dataclasses import dataclass
|
|
23
|
+
from typing import Any
|
|
24
|
+
|
|
25
|
+
logger = logging.getLogger(__name__)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass(frozen=True)
|
|
29
|
+
class GovernanceTelemetry:
|
|
30
|
+
"""Immutable governance telemetry triple (+ product dependency count).
|
|
31
|
+
|
|
32
|
+
Embedded as structured metadata within VCard postconditions.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
possibility_magnitude: float | None = None
|
|
36
|
+
governance_narrowing: float | None = None
|
|
37
|
+
epiplexity_yield: float | None = None
|
|
38
|
+
product_dependency_count: int | None = None
|
|
39
|
+
|
|
40
|
+
def to_dict(self) -> dict[str, Any]:
|
|
41
|
+
"""Serialize to a plain dict for VCard metadata embedding."""
|
|
42
|
+
result: dict[str, Any] = {}
|
|
43
|
+
if self.possibility_magnitude is not None:
|
|
44
|
+
result["M"] = self.possibility_magnitude
|
|
45
|
+
if self.governance_narrowing is not None:
|
|
46
|
+
result["N"] = self.governance_narrowing
|
|
47
|
+
if self.epiplexity_yield is not None:
|
|
48
|
+
result["E"] = self.epiplexity_yield
|
|
49
|
+
if self.product_dependency_count is not None:
|
|
50
|
+
result["Pi"] = self.product_dependency_count
|
|
51
|
+
return result
|
|
52
|
+
|
|
53
|
+
@classmethod
|
|
54
|
+
def from_dict(cls, data: dict[str, Any]) -> GovernanceTelemetry:
|
|
55
|
+
"""Deserialize from a plain dict."""
|
|
56
|
+
return cls(
|
|
57
|
+
possibility_magnitude=data.get("M"),
|
|
58
|
+
governance_narrowing=data.get("N"),
|
|
59
|
+
epiplexity_yield=data.get("E"),
|
|
60
|
+
product_dependency_count=data.get("Pi"),
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
# ---------------------------------------------------------------------------
|
|
65
|
+
# Core metric computations
|
|
66
|
+
# ---------------------------------------------------------------------------
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def compute_possibility_magnitude(inputs_count: int, outputs_count: int) -> float:
|
|
70
|
+
"""Compute Possibility Magnitude M = |B|^|A|.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
inputs_count: |A| — number of input dimensions (Categorical Types).
|
|
74
|
+
outputs_count: |B| — number of output options (Categorical Types).
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
The total combinatorial space as a float.
|
|
78
|
+
Returns 1.0 when both counts are 0 (trivial identity transition).
|
|
79
|
+
"""
|
|
80
|
+
if inputs_count < 0 or outputs_count < 0:
|
|
81
|
+
raise ValueError(
|
|
82
|
+
f"Type counts must be non-negative: inputs={inputs_count}, outputs={outputs_count}"
|
|
83
|
+
)
|
|
84
|
+
if inputs_count == 0 and outputs_count == 0:
|
|
85
|
+
return 1.0
|
|
86
|
+
if outputs_count == 0:
|
|
87
|
+
return 0.0
|
|
88
|
+
return float(outputs_count**inputs_count)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def compute_governance_narrowing(m_full: float, m_admitted: float) -> float:
|
|
92
|
+
"""Compute Governance Narrowing N = 1 - M_admitted / M_full.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
m_full: |B|^|A| — full possibility magnitude before VCard constraints.
|
|
96
|
+
m_admitted: |B'|^|A'| — admitted possibility magnitude after VCard constraints.
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
Fraction of the possibility space excluded by governance policy.
|
|
100
|
+
Range: [0.0, 1.0] where 1.0 means total restriction, 0.0 means no restriction.
|
|
101
|
+
"""
|
|
102
|
+
if m_full <= 0:
|
|
103
|
+
return 0.0
|
|
104
|
+
if m_admitted < 0:
|
|
105
|
+
raise ValueError(f"Admitted magnitude must be non-negative: {m_admitted}")
|
|
106
|
+
ratio = m_admitted / m_full
|
|
107
|
+
# Clamp to [0.0, 1.0] to handle floating-point edge cases
|
|
108
|
+
return max(0.0, min(1.0, 1.0 - ratio))
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def compute_epiplexity_yield(structured_knowledge: float, magnitude: float) -> float:
|
|
112
|
+
"""Compute Epiplexity Yield E = S_T / M.
|
|
113
|
+
|
|
114
|
+
Uses alignment_score as the proxy for S_T (semantic vector confidence score).
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
structured_knowledge: S_T — semantic confidence score (e.g., alignment_score).
|
|
118
|
+
magnitude: M — possibility magnitude computed during PREP.
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
Ratio of structured knowledge extracted per possibility explored.
|
|
122
|
+
Returns 0.0 when magnitude is 0 (no possibilities to explore).
|
|
123
|
+
"""
|
|
124
|
+
if magnitude <= 0:
|
|
125
|
+
return 0.0
|
|
126
|
+
return structured_knowledge / magnitude
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
# ---------------------------------------------------------------------------
|
|
130
|
+
# CLM spec extraction helpers
|
|
131
|
+
# ---------------------------------------------------------------------------
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def extract_type_counts_from_clm(clm_spec: dict[str, Any]) -> tuple[int, int]:
|
|
135
|
+
"""Extract |A| and |B| from a parsed CLM abstract_spec.
|
|
136
|
+
|
|
137
|
+
Looks for typed inputs/outputs in the CLM YAML structure:
|
|
138
|
+
- abstract_spec.inputs → list of input type descriptors → |A|
|
|
139
|
+
- abstract_spec.outputs → list of output type descriptors → |B|
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
clm_spec: Parsed CLM YAML as a dict (the full PCard content).
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
Tuple of (inputs_count, outputs_count). Returns (0, 0) if the CLM
|
|
146
|
+
spec does not contain typed inputs/outputs (graceful degradation).
|
|
147
|
+
"""
|
|
148
|
+
abstract = clm_spec.get("abstract_spec", {})
|
|
149
|
+
if not abstract:
|
|
150
|
+
# Try alternative key names
|
|
151
|
+
abstract = clm_spec.get("abstract", {})
|
|
152
|
+
|
|
153
|
+
inputs = abstract.get("inputs", [])
|
|
154
|
+
outputs = abstract.get("outputs", [])
|
|
155
|
+
|
|
156
|
+
# Handle both list and dict formats
|
|
157
|
+
inputs_count = len(inputs) if isinstance(inputs, list | dict) else 0
|
|
158
|
+
outputs_count = len(outputs) if isinstance(outputs, list | dict) else 0
|
|
159
|
+
|
|
160
|
+
return (inputs_count, outputs_count)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def extract_admitted_counts_from_vcard(
|
|
164
|
+
clm_spec: dict[str, Any],
|
|
165
|
+
vcard_constraints: dict[str, Any] | None,
|
|
166
|
+
) -> tuple[int, int]:
|
|
167
|
+
"""Extract |A'| and |B'| — the admitted subsets after VCard policy application.
|
|
168
|
+
|
|
169
|
+
The admitted counts are derived by intersecting the CLM's full type space
|
|
170
|
+
with the VCard precondition constraints. If no constraints are specified,
|
|
171
|
+
the admitted space equals the full space (N = 0, no narrowing).
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
clm_spec: Parsed CLM YAML.
|
|
175
|
+
vcard_constraints: VCard precondition constraints (may be None).
|
|
176
|
+
|
|
177
|
+
Returns:
|
|
178
|
+
Tuple of (admitted_inputs, admitted_outputs).
|
|
179
|
+
"""
|
|
180
|
+
full_a, full_b = extract_type_counts_from_clm(clm_spec)
|
|
181
|
+
|
|
182
|
+
if not vcard_constraints:
|
|
183
|
+
return (full_a, full_b)
|
|
184
|
+
|
|
185
|
+
# Check for explicit admitted type lists in VCard constraints
|
|
186
|
+
admitted_inputs = vcard_constraints.get("admitted_inputs")
|
|
187
|
+
admitted_outputs = vcard_constraints.get("admitted_outputs")
|
|
188
|
+
|
|
189
|
+
# If constraints specify admitted subsets, use their counts
|
|
190
|
+
a_prime = (
|
|
191
|
+
len(admitted_inputs) if isinstance(admitted_inputs, list | dict) else full_a
|
|
192
|
+
)
|
|
193
|
+
b_prime = (
|
|
194
|
+
len(admitted_outputs) if isinstance(admitted_outputs, list | dict) else full_b
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
# Check for exclusion lists (alternative constraint format)
|
|
198
|
+
excluded_inputs = vcard_constraints.get("excluded_inputs")
|
|
199
|
+
excluded_outputs = vcard_constraints.get("excluded_outputs")
|
|
200
|
+
|
|
201
|
+
if isinstance(excluded_inputs, list) and admitted_inputs is None:
|
|
202
|
+
a_prime = max(0, full_a - len(excluded_inputs))
|
|
203
|
+
if isinstance(excluded_outputs, list) and admitted_outputs is None:
|
|
204
|
+
b_prime = max(0, full_b - len(excluded_outputs))
|
|
205
|
+
|
|
206
|
+
return (a_prime, b_prime)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def count_product_dependencies(clm_spec: dict[str, Any]) -> int:
|
|
210
|
+
"""Count the Product Dependency Count (Pi).
|
|
211
|
+
|
|
212
|
+
Pi = number of concurrent precondition evaluations required for
|
|
213
|
+
transition firing. Derived from the CLM's preconditions list.
|
|
214
|
+
|
|
215
|
+
Args:
|
|
216
|
+
clm_spec: Parsed CLM YAML.
|
|
217
|
+
|
|
218
|
+
Returns:
|
|
219
|
+
Number of precondition evaluations (minimum 1 for any valid CLM).
|
|
220
|
+
"""
|
|
221
|
+
abstract = clm_spec.get("abstract_spec", {}) or clm_spec.get("abstract", {})
|
|
222
|
+
preconditions = abstract.get("preconditions", [])
|
|
223
|
+
|
|
224
|
+
if isinstance(preconditions, list):
|
|
225
|
+
return max(1, len(preconditions))
|
|
226
|
+
if isinstance(preconditions, dict):
|
|
227
|
+
return max(1, len(preconditions))
|
|
228
|
+
return 1
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
# ---------------------------------------------------------------------------
|
|
232
|
+
# High-level orchestration
|
|
233
|
+
# ---------------------------------------------------------------------------
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def compute_prep_governance(
|
|
237
|
+
clm_spec: dict[str, Any],
|
|
238
|
+
vcard_constraints: dict[str, Any] | None = None,
|
|
239
|
+
) -> GovernanceTelemetry:
|
|
240
|
+
"""Compute governance metrics available during the PREP phase.
|
|
241
|
+
|
|
242
|
+
Called after CLM verification succeeds. Computes M, N, and Pi.
|
|
243
|
+
E (Epiplexity Yield) is deferred to the POST phase.
|
|
244
|
+
|
|
245
|
+
Args:
|
|
246
|
+
clm_spec: Parsed CLM YAML spec.
|
|
247
|
+
vcard_constraints: Optional VCard precondition constraints.
|
|
248
|
+
|
|
249
|
+
Returns:
|
|
250
|
+
GovernanceTelemetry with M, N, Pi populated (E = None).
|
|
251
|
+
"""
|
|
252
|
+
try:
|
|
253
|
+
a, b = extract_type_counts_from_clm(clm_spec)
|
|
254
|
+
|
|
255
|
+
if a == 0 and b == 0:
|
|
256
|
+
# CLM spec lacks typed inputs/outputs → graceful degradation
|
|
257
|
+
logger.debug(
|
|
258
|
+
"[GOVERNANCE] CLM spec has no typed inputs/outputs; "
|
|
259
|
+
"governance metrics set to None."
|
|
260
|
+
)
|
|
261
|
+
return GovernanceTelemetry()
|
|
262
|
+
|
|
263
|
+
m_full = compute_possibility_magnitude(a, b)
|
|
264
|
+
|
|
265
|
+
a_prime, b_prime = extract_admitted_counts_from_vcard(
|
|
266
|
+
clm_spec, vcard_constraints
|
|
267
|
+
)
|
|
268
|
+
m_admitted = compute_possibility_magnitude(a_prime, b_prime)
|
|
269
|
+
|
|
270
|
+
narrowing = compute_governance_narrowing(m_full, m_admitted)
|
|
271
|
+
pi = count_product_dependencies(clm_spec)
|
|
272
|
+
|
|
273
|
+
logger.info(
|
|
274
|
+
f"[GOVERNANCE] PREP metrics: M={m_full}, N={narrowing:.4f}, Pi={pi} "
|
|
275
|
+
f"(|A|={a}, |B|={b}, |A'|={a_prime}, |B'|={b_prime})"
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
return GovernanceTelemetry(
|
|
279
|
+
possibility_magnitude=m_full,
|
|
280
|
+
governance_narrowing=narrowing,
|
|
281
|
+
product_dependency_count=pi,
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
except Exception:
|
|
285
|
+
logger.warning(
|
|
286
|
+
"[GOVERNANCE] Failed to compute PREP governance metrics", exc_info=True
|
|
287
|
+
)
|
|
288
|
+
return GovernanceTelemetry()
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def compute_post_governance(
|
|
292
|
+
prep_telemetry: GovernanceTelemetry,
|
|
293
|
+
alignment_score: float | None,
|
|
294
|
+
) -> GovernanceTelemetry:
|
|
295
|
+
"""Compute the final governance telemetry including Epiplexity Yield.
|
|
296
|
+
|
|
297
|
+
Called during the POST phase after execution and alignment scoring.
|
|
298
|
+
Uses alignment_score as the proxy for S_T (semantic confidence).
|
|
299
|
+
|
|
300
|
+
Args:
|
|
301
|
+
prep_telemetry: GovernanceTelemetry from the PREP phase.
|
|
302
|
+
alignment_score: The directional alignment score (proxy for S_T).
|
|
303
|
+
|
|
304
|
+
Returns:
|
|
305
|
+
Complete GovernanceTelemetry with all four metrics.
|
|
306
|
+
"""
|
|
307
|
+
if alignment_score is None or prep_telemetry.possibility_magnitude is None:
|
|
308
|
+
return prep_telemetry
|
|
309
|
+
|
|
310
|
+
try:
|
|
311
|
+
epiplexity = compute_epiplexity_yield(
|
|
312
|
+
alignment_score, prep_telemetry.possibility_magnitude
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
logger.info(
|
|
316
|
+
f"[GOVERNANCE] POST metrics: E={epiplexity:.6f} "
|
|
317
|
+
f"(S_T={alignment_score}, M={prep_telemetry.possibility_magnitude})"
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
return GovernanceTelemetry(
|
|
321
|
+
possibility_magnitude=prep_telemetry.possibility_magnitude,
|
|
322
|
+
governance_narrowing=prep_telemetry.governance_narrowing,
|
|
323
|
+
epiplexity_yield=epiplexity,
|
|
324
|
+
product_dependency_count=prep_telemetry.product_dependency_count,
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
except Exception:
|
|
328
|
+
logger.warning(
|
|
329
|
+
"[GOVERNANCE] Failed to compute POST governance metrics", exc_info=True
|
|
330
|
+
)
|
|
331
|
+
return prep_telemetry
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""RAII Resource Guards for Process Descriptors and Temporary Storage (Sprint 178).
|
|
2
|
+
|
|
3
|
+
Ensures deterministic cleanup of redirected file descriptors and temporary directories.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import shutil
|
|
9
|
+
import sys
|
|
10
|
+
import tempfile
|
|
11
|
+
from contextlib import contextmanager
|
|
12
|
+
from typing import Any, Generator
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@contextmanager
|
|
16
|
+
def fd_redirect_guard(
|
|
17
|
+
stdout: Any | None = None,
|
|
18
|
+
stderr: Any | None = None,
|
|
19
|
+
) -> Generator[None, None, None]:
|
|
20
|
+
"""RAII guard that redirects stdout and stderr, guaranteeing restoration on exit."""
|
|
21
|
+
old_stdout = sys.stdout
|
|
22
|
+
old_stderr = sys.stderr
|
|
23
|
+
try:
|
|
24
|
+
if stdout is not None:
|
|
25
|
+
sys.stdout = stdout
|
|
26
|
+
if stderr is not None:
|
|
27
|
+
sys.stderr = stderr
|
|
28
|
+
yield
|
|
29
|
+
finally:
|
|
30
|
+
sys.stdout = old_stdout
|
|
31
|
+
sys.stderr = old_stderr
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@contextmanager
|
|
35
|
+
def temp_dir_guard(prefix: str = "clm_tmp_") -> Generator[str, None, None]:
|
|
36
|
+
"""RAII temporary directory manager with guaranteed recursive cleanup even on exceptions."""
|
|
37
|
+
tmp_path = tempfile.mkdtemp(prefix=prefix)
|
|
38
|
+
try:
|
|
39
|
+
yield tmp_path
|
|
40
|
+
finally:
|
|
41
|
+
shutil.rmtree(tmp_path, ignore_errors=True)
|