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,133 @@
|
|
|
1
|
+
"""Layer 3 Reticulum Link Transport (DEL-390-01).
|
|
2
|
+
|
|
3
|
+
Implements:
|
|
4
|
+
- Single-roundtrip ephemeral Link handshake (X25519 ECDH + HKDF)
|
|
5
|
+
- Authenticated AES-256 session encryption with Perfect Forward Secrecy (PFS)
|
|
6
|
+
- Initiator anonymity (packets omit sender identity)
|
|
7
|
+
- Clean session teardown with key zeroization
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import hashlib
|
|
12
|
+
import os
|
|
13
|
+
import sys
|
|
14
|
+
from typing import Optional, Tuple
|
|
15
|
+
|
|
16
|
+
from cryptography.hazmat.primitives import hashes, serialization
|
|
17
|
+
from cryptography.hazmat.primitives.asymmetric import x25519
|
|
18
|
+
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
|
|
19
|
+
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
|
|
20
|
+
|
|
21
|
+
RETICULUM_PATH = os.path.expanduser("~/Documents/Development/Networking/Reticulum")
|
|
22
|
+
if RETICULUM_PATH not in sys.path and os.path.exists(RETICULUM_PATH):
|
|
23
|
+
sys.path.insert(0, RETICULUM_PATH)
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
import RNS
|
|
27
|
+
except (ImportError, ModuleNotFoundError):
|
|
28
|
+
RNS = None # type: ignore
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class ReticulumLinkSession:
|
|
32
|
+
"""Manages an authenticated, encrypted point-to-point session between two
|
|
33
|
+
conversational PKC nodes over Reticulum transport.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def __init__(
|
|
37
|
+
self,
|
|
38
|
+
destination_hash: bytes,
|
|
39
|
+
is_initiator: bool = True,
|
|
40
|
+
link_id: Optional[bytes] = None,
|
|
41
|
+
) -> None:
|
|
42
|
+
self.destination_hash = destination_hash
|
|
43
|
+
self.is_initiator = is_initiator
|
|
44
|
+
self.link_id = link_id or hashlib.sha256(os.urandom(32)).digest()[:16]
|
|
45
|
+
self._ephemeral_prv: Optional[x25519.X25519PrivateKey] = x25519.X25519PrivateKey.generate()
|
|
46
|
+
self._ephemeral_pub: Optional[x25519.X25519PublicKey] = self._ephemeral_prv.public_key()
|
|
47
|
+
self.derived_key: Optional[bytes] = None
|
|
48
|
+
self._cipher: Optional[AESGCM] = None
|
|
49
|
+
self._seq: int = 0
|
|
50
|
+
self.is_closed: bool = False
|
|
51
|
+
|
|
52
|
+
@property
|
|
53
|
+
def ephemeral_public_bytes(self) -> bytes:
|
|
54
|
+
if self._ephemeral_pub is None:
|
|
55
|
+
raise RuntimeError("Session is closed or key dropped")
|
|
56
|
+
return self._ephemeral_pub.public_bytes(
|
|
57
|
+
encoding=serialization.Encoding.Raw,
|
|
58
|
+
format=serialization.PublicFormat.Raw,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
def complete_handshake(self, peer_ephemeral_pub_bytes: bytes) -> None:
|
|
62
|
+
"""Executes X25519 ECDH exchange and HKDF key derivation using link_id as salt.
|
|
63
|
+
Derives 32-byte key for AES-256-GCM session cipher.
|
|
64
|
+
"""
|
|
65
|
+
if self._ephemeral_prv is None:
|
|
66
|
+
raise RuntimeError("Session is closed")
|
|
67
|
+
|
|
68
|
+
peer_pub = x25519.X25519PublicKey.from_public_bytes(peer_ephemeral_pub_bytes)
|
|
69
|
+
shared_secret = self._ephemeral_prv.exchange(peer_pub)
|
|
70
|
+
|
|
71
|
+
hkdf = HKDF(
|
|
72
|
+
algorithm=hashes.SHA256(),
|
|
73
|
+
length=32,
|
|
74
|
+
salt=self.link_id,
|
|
75
|
+
info=b"clm:reticulum:link:session",
|
|
76
|
+
)
|
|
77
|
+
self.derived_key = hkdf.derive(shared_secret)
|
|
78
|
+
self._cipher = AESGCM(self.derived_key)
|
|
79
|
+
|
|
80
|
+
def encrypt(self, plaintext: bytes) -> bytes:
|
|
81
|
+
"""Encrypts plaintext payload using AES-256-GCM.
|
|
82
|
+
Framing: [12-byte nonce (seq + random)] + [ciphertext + 16-byte tag]
|
|
83
|
+
Does NOT leak sender address (INV-L3-RET-355-03).
|
|
84
|
+
"""
|
|
85
|
+
if self._cipher is None or self.is_closed:
|
|
86
|
+
raise RuntimeError("Cannot encrypt on unestablished or closed session")
|
|
87
|
+
|
|
88
|
+
self._seq += 1
|
|
89
|
+
nonce = self._seq.to_bytes(4, byteorder="big") + os.urandom(8)
|
|
90
|
+
ciphertext = self._cipher.encrypt(nonce, plaintext, associated_data=self.link_id)
|
|
91
|
+
return nonce + ciphertext
|
|
92
|
+
|
|
93
|
+
def decrypt(self, frame: bytes) -> bytes:
|
|
94
|
+
"""Decrypts and authenticates AES-256-GCM frame."""
|
|
95
|
+
if self._cipher is None or self.is_closed:
|
|
96
|
+
raise RuntimeError("Cannot decrypt on unestablished or closed session")
|
|
97
|
+
|
|
98
|
+
if len(frame) < 12 + 16:
|
|
99
|
+
raise ValueError("Encrypted frame too short")
|
|
100
|
+
|
|
101
|
+
nonce = frame[:12]
|
|
102
|
+
ciphertext = frame[12:]
|
|
103
|
+
return self._cipher.decrypt(nonce, ciphertext, associated_data=self.link_id)
|
|
104
|
+
|
|
105
|
+
def close(self) -> None:
|
|
106
|
+
"""Drops ephemeral keys and zeroes session key (INV-L3-RET-355-02: PFS)."""
|
|
107
|
+
self._ephemeral_prv = None
|
|
108
|
+
self._ephemeral_pub = None
|
|
109
|
+
self.derived_key = None
|
|
110
|
+
self._cipher = None
|
|
111
|
+
self.is_closed = True
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def establish_link_pair(dest_hash: bytes) -> Tuple[ReticulumLinkSession, ReticulumLinkSession]:
|
|
115
|
+
"""Helper that creates an initiator and responder session and handshakes them."""
|
|
116
|
+
link_id = hashlib.sha256(os.urandom(32)).digest()[:16]
|
|
117
|
+
initiator = ReticulumLinkSession(dest_hash, is_initiator=True, link_id=link_id)
|
|
118
|
+
responder = ReticulumLinkSession(dest_hash, is_initiator=False, link_id=link_id)
|
|
119
|
+
|
|
120
|
+
# Handshake exchange
|
|
121
|
+
initiator.complete_handshake(responder.ephemeral_public_bytes)
|
|
122
|
+
responder.complete_handshake(initiator.ephemeral_public_bytes)
|
|
123
|
+
|
|
124
|
+
return initiator, responder
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
ReticulumTransport = ReticulumLinkSession
|
|
128
|
+
|
|
129
|
+
__all__ = [
|
|
130
|
+
"ReticulumLinkSession",
|
|
131
|
+
"ReticulumTransport",
|
|
132
|
+
"establish_link_pair",
|
|
133
|
+
]
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"""Satori Speech-Act, Delimited Continuation, Sheaf Consensus & Lambda Calculus Package (DEL-390-02).
|
|
2
|
+
|
|
3
|
+
Normative Reference:
|
|
4
|
+
docs/spec/20-architecture/system-architecture.md § 3 (Layer 3 Reticulum & Satori)
|
|
5
|
+
docs/spec/20-architecture/card-triad-architecture.md § Thermodynamic Maxwell's Demon Gate
|
|
6
|
+
|
|
7
|
+
Invariants:
|
|
8
|
+
INV-390-01: Searle-Austin Speech Act Taxonomy (Assertive, Directive, Commissive, Expressive, Declarative).
|
|
9
|
+
INV-390-02: Sheaf Cohomology Obstruction Vanishing (H¹ = 0 consensus, L = S_T - H_T).
|
|
10
|
+
INV-390-03: Delimited Conversational Continuations (prompt/shift turn execution).
|
|
11
|
+
"""
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
# Lambda Term ADT
|
|
15
|
+
# Alpha Conversion
|
|
16
|
+
from clm.layer3.satori.alpha_conversion import (
|
|
17
|
+
alpha_equivalent,
|
|
18
|
+
alpha_normalize,
|
|
19
|
+
alpha_rename,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
# Beta Reduction
|
|
23
|
+
from clm.layer3.satori.beta_reduction import (
|
|
24
|
+
NormalizationResult,
|
|
25
|
+
ReductionStrategy,
|
|
26
|
+
beta_reduce,
|
|
27
|
+
find_innermost_redex,
|
|
28
|
+
find_leftmost_redex,
|
|
29
|
+
has_normal_form,
|
|
30
|
+
is_normal_form,
|
|
31
|
+
is_redex,
|
|
32
|
+
normalize,
|
|
33
|
+
reduce_step,
|
|
34
|
+
substitute_with_capture,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# Delimited Continuations
|
|
38
|
+
from clm.layer3.satori.continuation import ContinuationToken
|
|
39
|
+
|
|
40
|
+
# Eta Conversion
|
|
41
|
+
from clm.layer3.satori.eta_conversion import (
|
|
42
|
+
beta_eta_normalize,
|
|
43
|
+
beta_eta_reduce,
|
|
44
|
+
eta_equivalent,
|
|
45
|
+
eta_expand,
|
|
46
|
+
eta_reduce,
|
|
47
|
+
fully_eta_reduce,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
# Free Variables
|
|
51
|
+
from clm.layer3.satori.free_variables import (
|
|
52
|
+
bound_variables,
|
|
53
|
+
free_variables,
|
|
54
|
+
generate_fresh,
|
|
55
|
+
generate_fresh_for,
|
|
56
|
+
is_closed,
|
|
57
|
+
is_free_in,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
# Lambda Runtime
|
|
61
|
+
from clm.layer3.satori.lambda_runtime import (
|
|
62
|
+
LambdaConfig,
|
|
63
|
+
LambdaOperation,
|
|
64
|
+
LambdaParser,
|
|
65
|
+
LambdaRuntime,
|
|
66
|
+
LambdaRuntimeResult,
|
|
67
|
+
ParseError,
|
|
68
|
+
parse_lambda_expression,
|
|
69
|
+
)
|
|
70
|
+
from clm.layer3.satori.lambda_term import (
|
|
71
|
+
AbsTerm,
|
|
72
|
+
AppTerm,
|
|
73
|
+
LambdaTerm,
|
|
74
|
+
VarTerm,
|
|
75
|
+
deserialize_term,
|
|
76
|
+
is_abs,
|
|
77
|
+
is_app,
|
|
78
|
+
is_var,
|
|
79
|
+
load_term,
|
|
80
|
+
mcard_to_term,
|
|
81
|
+
mk_abs,
|
|
82
|
+
mk_app,
|
|
83
|
+
mk_var,
|
|
84
|
+
pretty_print_deep,
|
|
85
|
+
pretty_print_shallow,
|
|
86
|
+
serialize_term,
|
|
87
|
+
store_term,
|
|
88
|
+
term_exists,
|
|
89
|
+
term_to_mcard,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
# Sheaf Cohomology & Maxwell's Demon
|
|
93
|
+
from clm.layer3.satori.sheaf_audit import (
|
|
94
|
+
Marking,
|
|
95
|
+
OpenSet,
|
|
96
|
+
Place,
|
|
97
|
+
Section,
|
|
98
|
+
Sheaf,
|
|
99
|
+
SheafAuditor,
|
|
100
|
+
SheafAuditReport,
|
|
101
|
+
audit_maxwell_demon,
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
# Speech Acts & Binary AST
|
|
105
|
+
from clm.layer3.satori.speech_act import (
|
|
106
|
+
OPCODES_TO_TYPE,
|
|
107
|
+
SATORI_OPCODES,
|
|
108
|
+
SpeechAct,
|
|
109
|
+
SpeechActType,
|
|
110
|
+
classify_speech_act,
|
|
111
|
+
create_assert,
|
|
112
|
+
create_commissive,
|
|
113
|
+
create_commit,
|
|
114
|
+
create_declarative,
|
|
115
|
+
create_declare,
|
|
116
|
+
create_directive,
|
|
117
|
+
create_expressive,
|
|
118
|
+
create_request,
|
|
119
|
+
decode_satori_binary,
|
|
120
|
+
encode_satori_binary,
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
__all__ = [
|
|
124
|
+
# Speech Acts & Binary AST
|
|
125
|
+
"SATORI_OPCODES",
|
|
126
|
+
"OPCODES_TO_TYPE",
|
|
127
|
+
"SpeechActType",
|
|
128
|
+
"SpeechAct",
|
|
129
|
+
"encode_satori_binary",
|
|
130
|
+
"decode_satori_binary",
|
|
131
|
+
"classify_speech_act",
|
|
132
|
+
"create_assert",
|
|
133
|
+
"create_directive",
|
|
134
|
+
"create_request",
|
|
135
|
+
"create_commissive",
|
|
136
|
+
"create_commit",
|
|
137
|
+
"create_expressive",
|
|
138
|
+
"create_declarative",
|
|
139
|
+
"create_declare",
|
|
140
|
+
# Sheaf Cohomology & Maxwell's Demon
|
|
141
|
+
"Place",
|
|
142
|
+
"Marking",
|
|
143
|
+
"OpenSet",
|
|
144
|
+
"Section",
|
|
145
|
+
"Sheaf",
|
|
146
|
+
"SheafAuditReport",
|
|
147
|
+
"SheafAuditor",
|
|
148
|
+
"audit_maxwell_demon",
|
|
149
|
+
# Delimited Continuations
|
|
150
|
+
"ContinuationToken",
|
|
151
|
+
# Lambda Term ADT
|
|
152
|
+
"LambdaTerm",
|
|
153
|
+
"VarTerm",
|
|
154
|
+
"AbsTerm",
|
|
155
|
+
"AppTerm",
|
|
156
|
+
"mk_var",
|
|
157
|
+
"mk_abs",
|
|
158
|
+
"mk_app",
|
|
159
|
+
"serialize_term",
|
|
160
|
+
"deserialize_term",
|
|
161
|
+
"term_to_mcard",
|
|
162
|
+
"mcard_to_term",
|
|
163
|
+
"store_term",
|
|
164
|
+
"load_term",
|
|
165
|
+
"term_exists",
|
|
166
|
+
"pretty_print_shallow",
|
|
167
|
+
"pretty_print_deep",
|
|
168
|
+
"is_var",
|
|
169
|
+
"is_abs",
|
|
170
|
+
"is_app",
|
|
171
|
+
# Free Variables
|
|
172
|
+
"free_variables",
|
|
173
|
+
"bound_variables",
|
|
174
|
+
"is_free_in",
|
|
175
|
+
"is_closed",
|
|
176
|
+
"generate_fresh",
|
|
177
|
+
"generate_fresh_for",
|
|
178
|
+
# Alpha Conversion
|
|
179
|
+
"alpha_rename",
|
|
180
|
+
"alpha_equivalent",
|
|
181
|
+
"alpha_normalize",
|
|
182
|
+
# Beta Reduction
|
|
183
|
+
"ReductionStrategy",
|
|
184
|
+
"NormalizationResult",
|
|
185
|
+
"substitute_with_capture",
|
|
186
|
+
"is_redex",
|
|
187
|
+
"find_leftmost_redex",
|
|
188
|
+
"find_innermost_redex",
|
|
189
|
+
"beta_reduce",
|
|
190
|
+
"reduce_step",
|
|
191
|
+
"normalize",
|
|
192
|
+
"is_normal_form",
|
|
193
|
+
"has_normal_form",
|
|
194
|
+
# Eta Conversion
|
|
195
|
+
"eta_reduce",
|
|
196
|
+
"eta_expand",
|
|
197
|
+
"eta_equivalent",
|
|
198
|
+
"fully_eta_reduce",
|
|
199
|
+
"beta_eta_reduce",
|
|
200
|
+
"beta_eta_normalize",
|
|
201
|
+
# Lambda Runtime
|
|
202
|
+
"parse_lambda_expression",
|
|
203
|
+
"ParseError",
|
|
204
|
+
"LambdaParser",
|
|
205
|
+
"LambdaOperation",
|
|
206
|
+
"LambdaConfig",
|
|
207
|
+
"LambdaRuntimeResult",
|
|
208
|
+
"LambdaRuntime",
|
|
209
|
+
]
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Alpha Conversion - Variable renaming in Lambda Calculus
|
|
3
|
+
|
|
4
|
+
Alpha conversion (α-conversion) allows renaming of bound variables
|
|
5
|
+
without changing the meaning of the term:
|
|
6
|
+
λx.M ≡α λy.M[x:=y] (where y is fresh)
|
|
7
|
+
|
|
8
|
+
This module provides Python parity with mcard-js/src/ptr/lambda/AlphaConversion.ts
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from clm.layer2.card_collection import CardCollection
|
|
12
|
+
from clm.layer3.satori.lambda_term import (
|
|
13
|
+
is_abs,
|
|
14
|
+
is_app,
|
|
15
|
+
is_var,
|
|
16
|
+
load_term,
|
|
17
|
+
mk_abs,
|
|
18
|
+
mk_app,
|
|
19
|
+
mk_var,
|
|
20
|
+
store_term,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
24
|
+
# Alpha Renaming
|
|
25
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def alpha_rename(
|
|
29
|
+
collection: CardCollection, hash_value: str, old_name: str, new_name: str
|
|
30
|
+
) -> str | None:
|
|
31
|
+
"""
|
|
32
|
+
Rename a bound variable in a Lambda term.
|
|
33
|
+
Returns the hash of the renamed term, or None if term not found.
|
|
34
|
+
|
|
35
|
+
Only renames the binding occurrence and all bound occurrences.
|
|
36
|
+
"""
|
|
37
|
+
term = load_term(collection, hash_value)
|
|
38
|
+
if term is None:
|
|
39
|
+
return None
|
|
40
|
+
|
|
41
|
+
if is_var(term):
|
|
42
|
+
# Variable: rename if it matches
|
|
43
|
+
if term.name == old_name:
|
|
44
|
+
return store_term(collection, mk_var(new_name))
|
|
45
|
+
return hash_value
|
|
46
|
+
|
|
47
|
+
elif is_abs(term):
|
|
48
|
+
if term.param == old_name:
|
|
49
|
+
# This is the binder we're renaming
|
|
50
|
+
new_body = alpha_rename(collection, term.body, old_name, new_name)
|
|
51
|
+
if new_body is None:
|
|
52
|
+
return None
|
|
53
|
+
return store_term(collection, mk_abs(new_name, new_body))
|
|
54
|
+
else:
|
|
55
|
+
# Not bound here, recurse into body
|
|
56
|
+
new_body = alpha_rename(collection, term.body, old_name, new_name)
|
|
57
|
+
if new_body is None:
|
|
58
|
+
return None
|
|
59
|
+
return store_term(collection, mk_abs(term.param, new_body))
|
|
60
|
+
|
|
61
|
+
elif is_app(term):
|
|
62
|
+
new_func = alpha_rename(collection, term.func, old_name, new_name)
|
|
63
|
+
new_arg = alpha_rename(collection, term.arg, old_name, new_name)
|
|
64
|
+
if new_func is None or new_arg is None:
|
|
65
|
+
return None
|
|
66
|
+
return store_term(collection, mk_app(new_func, new_arg))
|
|
67
|
+
|
|
68
|
+
return hash_value
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
72
|
+
# Alpha Equivalence
|
|
73
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def alpha_equivalent(
|
|
77
|
+
collection: CardCollection,
|
|
78
|
+
hash1: str,
|
|
79
|
+
hash2: str,
|
|
80
|
+
env: dict[str, str] | None = None,
|
|
81
|
+
) -> bool | None:
|
|
82
|
+
"""
|
|
83
|
+
Check if two Lambda terms are α-equivalent.
|
|
84
|
+
|
|
85
|
+
Two terms are α-equivalent if they differ only in the names of bound variables.
|
|
86
|
+
Uses a bijection to track corresponding bound variable names.
|
|
87
|
+
"""
|
|
88
|
+
if env is None:
|
|
89
|
+
env = {}
|
|
90
|
+
|
|
91
|
+
term1 = load_term(collection, hash1)
|
|
92
|
+
term2 = load_term(collection, hash2)
|
|
93
|
+
|
|
94
|
+
if term1 is None or term2 is None:
|
|
95
|
+
return None
|
|
96
|
+
|
|
97
|
+
if is_var(term1) and is_var(term2):
|
|
98
|
+
# Check if variables correspond via environment
|
|
99
|
+
mapped = env.get(term1.name)
|
|
100
|
+
if mapped is not None:
|
|
101
|
+
return mapped == term2.name
|
|
102
|
+
# Not bound - must be same free variable
|
|
103
|
+
return term1.name == term2.name
|
|
104
|
+
|
|
105
|
+
elif is_abs(term1) and is_abs(term2):
|
|
106
|
+
# Extend environment with parameter correspondence
|
|
107
|
+
new_env = dict(env)
|
|
108
|
+
new_env[term1.param] = term2.param
|
|
109
|
+
return alpha_equivalent(collection, term1.body, term2.body, new_env)
|
|
110
|
+
|
|
111
|
+
elif is_app(term1) and is_app(term2):
|
|
112
|
+
func_eq = alpha_equivalent(collection, term1.func, term2.func, env)
|
|
113
|
+
if not func_eq:
|
|
114
|
+
return func_eq
|
|
115
|
+
return alpha_equivalent(collection, term1.arg, term2.arg, env)
|
|
116
|
+
|
|
117
|
+
return False
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
121
|
+
# Alpha Normalization
|
|
122
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def alpha_normalize(
|
|
126
|
+
collection: CardCollection, hash_value: str, counter: list | None = None
|
|
127
|
+
) -> str | None:
|
|
128
|
+
"""
|
|
129
|
+
Normalize bound variable names using de Bruijn-style naming.
|
|
130
|
+
|
|
131
|
+
All bound variables are renamed to x0, x1, x2, etc. in order of binding.
|
|
132
|
+
This produces a canonical form for α-equivalent terms.
|
|
133
|
+
"""
|
|
134
|
+
if counter is None:
|
|
135
|
+
counter = [0]
|
|
136
|
+
|
|
137
|
+
term = load_term(collection, hash_value)
|
|
138
|
+
if term is None:
|
|
139
|
+
return None
|
|
140
|
+
|
|
141
|
+
if is_var(term):
|
|
142
|
+
return hash_value
|
|
143
|
+
|
|
144
|
+
elif is_abs(term):
|
|
145
|
+
# Generate fresh normalized name
|
|
146
|
+
new_name = f"x{counter[0]}"
|
|
147
|
+
counter[0] += 1
|
|
148
|
+
|
|
149
|
+
# Rename this binding
|
|
150
|
+
renamed_body = alpha_rename(collection, term.body, term.param, new_name)
|
|
151
|
+
if renamed_body is None:
|
|
152
|
+
return None
|
|
153
|
+
|
|
154
|
+
# Recursively normalize the body
|
|
155
|
+
normalized_body = alpha_normalize(collection, renamed_body, counter)
|
|
156
|
+
if normalized_body is None:
|
|
157
|
+
return None
|
|
158
|
+
|
|
159
|
+
return store_term(collection, mk_abs(new_name, normalized_body))
|
|
160
|
+
|
|
161
|
+
elif is_app(term):
|
|
162
|
+
norm_func = alpha_normalize(collection, term.func, counter)
|
|
163
|
+
norm_arg = alpha_normalize(collection, term.arg, counter)
|
|
164
|
+
if norm_func is None or norm_arg is None:
|
|
165
|
+
return None
|
|
166
|
+
return store_term(collection, mk_app(norm_func, norm_arg))
|
|
167
|
+
|
|
168
|
+
return hash_value
|