clm-kernel 0.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (333) hide show
  1. clm/__init__.py +230 -0
  2. clm/__main__.py +25 -0
  3. clm/cross_cutting/__init__.py +50 -0
  4. clm/cross_cutting/_test_runner.py +36 -0
  5. clm/cross_cutting/async_utils.py +25 -0
  6. clm/cross_cutting/cel_builder.py +123 -0
  7. clm/cross_cutting/cel_converter.py +697 -0
  8. clm/cross_cutting/cel_engine.py +252 -0
  9. clm/cross_cutting/cel_ops.py +72 -0
  10. clm/cross_cutting/cel_ops_db.py +157 -0
  11. clm/cross_cutting/cel_ops_files.py +99 -0
  12. clm/cross_cutting/cel_ops_state.py +71 -0
  13. clm/cross_cutting/cel_ops_strings.py +64 -0
  14. clm/cross_cutting/cel_resolver.py +63 -0
  15. clm/cross_cutting/cel_slices.py +56 -0
  16. clm/cross_cutting/cel_store.py +330 -0
  17. clm/cross_cutting/clm_logger.py +140 -0
  18. clm/cross_cutting/config/__init__.py +155 -0
  19. clm/cross_cutting/config/config_constants.py +392 -0
  20. clm/cross_cutting/config/env_parameters.py +90 -0
  21. clm/cross_cutting/config/logging.py +378 -0
  22. clm/cross_cutting/config/settings.py +504 -0
  23. clm/cross_cutting/context.py +5 -0
  24. clm/cross_cutting/domain_models.py +55 -0
  25. clm/cross_cutting/domain_types.py +61 -0
  26. clm/cross_cutting/effects.py +67 -0
  27. clm/cross_cutting/errors.py +153 -0
  28. clm/cross_cutting/governance.py +331 -0
  29. clm/cross_cutting/guards.py +41 -0
  30. clm/cross_cutting/mcard.py +321 -0
  31. clm/cross_cutting/native.py +185 -0
  32. clm/cross_cutting/observability.py +289 -0
  33. clm/cross_cutting/pcard.py +434 -0
  34. clm/cross_cutting/registry.py +71 -0
  35. clm/cross_cutting/resources.py +84 -0
  36. clm/cross_cutting/secrets.py +44 -0
  37. clm/cross_cutting/subprocess_utils.py +118 -0
  38. clm/cross_cutting/telemetry.py +164 -0
  39. clm/cross_cutting/testing/__init__.py +8 -0
  40. clm/cross_cutting/testing/comparator.py +187 -0
  41. clm/cross_cutting/testing/datasets.py +87 -0
  42. clm/cross_cutting/timeutil.py +20 -0
  43. clm/cross_cutting/types/new_type_check.py +0 -0
  44. clm/cross_cutting/utils/__init__.py +1 -0
  45. clm/cross_cutting/utils/url_safety.py +50 -0
  46. clm/cross_cutting/vcard.py +560 -0
  47. clm/cross_cutting/writer.py +118 -0
  48. clm/layer0/README.md +50 -0
  49. clm/layer0/__init__.py +223 -0
  50. clm/layer0/algebra.py +60 -0
  51. clm/layer0/algebra_baldwin.py +133 -0
  52. clm/layer0/algebra_baldwin_generators.py +36 -0
  53. clm/layer0/algebra_equivalence.py +262 -0
  54. clm/layer0/algebra_ingest.py +306 -0
  55. clm/layer0/algebra_manifest_io.py +156 -0
  56. clm/layer0/assembler.py +481 -0
  57. clm/layer0/cel/__init__.py +23 -0
  58. clm/layer0/cel_eval.py +491 -0
  59. clm/layer0/codec.py +106 -0
  60. clm/layer0/context.py +122 -0
  61. clm/layer0/db.py +160 -0
  62. clm/layer0/exceptions.py +73 -0
  63. clm/layer0/fibration.py +106 -0
  64. clm/layer0/gates.py +50 -0
  65. clm/layer0/hash.py +80 -0
  66. clm/layer0/loader.py +826 -0
  67. clm/layer0/math_utils.py +163 -0
  68. clm/layer0/mcard.py +96 -0
  69. clm/layer0/model/__init__.py +0 -0
  70. clm/layer0/model/action.py +223 -0
  71. clm/layer0/model/card.py +280 -0
  72. clm/layer0/model/card_triad.py +427 -0
  73. clm/layer0/model/compatibility.py +60 -0
  74. clm/layer0/model/dictionary.py +46 -0
  75. clm/layer0/model/dots.py +331 -0
  76. clm/layer0/model/event_producer.py +88 -0
  77. clm/layer0/model/g_time.py +89 -0
  78. clm/layer0/model/handle.py +163 -0
  79. clm/layer0/model/hash/__init__.py +6 -0
  80. clm/layer0/model/hash/algorithms/__init__.py +3 -0
  81. clm/layer0/model/hash/algorithms/custom_hash.py +7 -0
  82. clm/layer0/model/hash/algorithms/local_sha256.py +178 -0
  83. clm/layer0/model/hash/constants.py +53 -0
  84. clm/layer0/model/hash/enums.py +60 -0
  85. clm/layer0/model/hash/validator.py +307 -0
  86. clm/layer0/model/interpreter.py +275 -0
  87. clm/layer0/model/pagination.py +45 -0
  88. clm/layer0/model/pcard.py +716 -0
  89. clm/layer0/model/schema.py +44 -0
  90. clm/layer0/model/utils/__init__.py +1 -0
  91. clm/layer0/model/utils/content_analyzer.py +152 -0
  92. clm/layer0/model/validators/__init__.py +1 -0
  93. clm/layer0/model/validators/base_validator.py +44 -0
  94. clm/layer0/model/validators/binary_validator.py +66 -0
  95. clm/layer0/model/validators/text_validator.py +82 -0
  96. clm/layer0/model/validators/validation_registry.py +49 -0
  97. clm/layer0/model/vcard.py +823 -0
  98. clm/layer0/model/vcard_ext/__init__.py +39 -0
  99. clm/layer0/model/vcard_ext/core.py +60 -0
  100. clm/layer0/model/vcard_ext/network.py +23 -0
  101. clm/layer0/model/vcard_ext/observability.py +63 -0
  102. clm/layer0/model/vcard_ext/storage.py +60 -0
  103. clm/layer0/model/vcard_ext/vendors.py +211 -0
  104. clm/layer0/model/vcard_sandwich.py +119 -0
  105. clm/layer0/model/vcard_vocabulary.py +463 -0
  106. clm/layer0/model/workflow.py +274 -0
  107. clm/layer0/narrative.py +431 -0
  108. clm/layer0/ontology/collection.py +125 -0
  109. clm/layer0/parser.py +429 -0
  110. clm/layer0/relations.py +73 -0
  111. clm/layer0/rule_evaluator.py +251 -0
  112. clm/layer0/schema/__init__.py +38 -0
  113. clm/layer0/schema/ddl.py +97 -0
  114. clm/layer0/templates/abstract.yaml +99 -0
  115. clm/layer0/templates/balanced.yaml +253 -0
  116. clm/layer0/templates/concrete.yaml +172 -0
  117. clm/layer0/type_registry.py +223 -0
  118. clm/layer0/types.py +204 -0
  119. clm/layer0/utils.py +886 -0
  120. clm/layer0/verifier_core.py +262 -0
  121. clm/layer1/__init__.py +31 -0
  122. clm/layer1/action_dispatcher.py +275 -0
  123. clm/layer1/adapter_registry.py +233 -0
  124. clm/layer1/algebra_baldwin_generators.py +192 -0
  125. clm/layer1/arrow_compiler.py +525 -0
  126. clm/layer1/batch_processor.py +152 -0
  127. clm/layer1/cel/__init__.py +27 -0
  128. clm/layer1/cel/builder.py +173 -0
  129. clm/layer1/engine.py +759 -0
  130. clm/layer1/engine_async.py +89 -0
  131. clm/layer1/eval_callback.py +49 -0
  132. clm/layer1/gate_composer.py +229 -0
  133. clm/layer1/hoare_sandwich.py +298 -0
  134. clm/layer1/identity_guard.py +348 -0
  135. clm/layer1/matrix.py +138 -0
  136. clm/layer1/neural_runtime.py +221 -0
  137. clm/layer1/operations/__init__.py +123 -0
  138. clm/layer1/operations/augment.py +156 -0
  139. clm/layer1/operations/base.py +109 -0
  140. clm/layer1/operations/builtins.py +338 -0
  141. clm/layer1/operations/dispatch.py +144 -0
  142. clm/layer1/operations/exclude.py +107 -0
  143. clm/layer1/operations/handle.py +197 -0
  144. clm/layer1/operations/identity.py +139 -0
  145. clm/layer1/operations/invert.py +66 -0
  146. clm/layer1/operations/loader.py +116 -0
  147. clm/layer1/operations/manipulators/__init__.py +23 -0
  148. clm/layer1/operations/manipulators/document.py +211 -0
  149. clm/layer1/operations/manipulators/media.py +134 -0
  150. clm/layer1/operations/manipulators/structured.py +159 -0
  151. clm/layer1/operations/manipulators/tabular.py +334 -0
  152. clm/layer1/operations/port.py +65 -0
  153. clm/layer1/operations/services.py +529 -0
  154. clm/layer1/operations/split.py +117 -0
  155. clm/layer1/operations/substitute.py +75 -0
  156. clm/layer1/petri.py +1052 -0
  157. clm/layer1/pocketflow_orchestrator.py +408 -0
  158. clm/layer1/pocketflow_scheduler.py +519 -0
  159. clm/layer1/protocols.py +197 -0
  160. clm/layer1/runtime_adapter.py +718 -0
  161. clm/layer1/runtimes/__init__.py +71 -0
  162. clm/layer1/runtimes/_generated_assertions.py +125 -0
  163. clm/layer1/runtimes/_generated_types.py +42 -0
  164. clm/layer1/runtimes/base.py +265 -0
  165. clm/layer1/runtimes/binary.py +101 -0
  166. clm/layer1/runtimes/factory.py +203 -0
  167. clm/layer1/runtimes/javascript.py +321 -0
  168. clm/layer1/runtimes/javascript_runtime.js +33 -0
  169. clm/layer1/runtimes/js_scripts/isomorphism.mjs +22 -0
  170. clm/layer1/runtimes/js_scripts/loader.mjs +52 -0
  171. clm/layer1/runtimes/lambda_calc.py +126 -0
  172. clm/layer1/runtimes/python.py +288 -0
  173. clm/layer1/runtimes/python_runtime.py +41 -0
  174. clm/layer1/runtimes/script.py +114 -0
  175. clm/layer1/sandbox.py +334 -0
  176. clm/layer1/savepoint_guard.py +136 -0
  177. clm/layer1/sparse_net.py +122 -0
  178. clm/layer1/spec_tester.py +165 -0
  179. clm/layer1/store.py +295 -0
  180. clm/layer1/test_runner.py +498 -0
  181. clm/layer1/type_inspector.py +166 -0
  182. clm/layer1/verifier.py +772 -0
  183. clm/layer1/vm.py +91 -0
  184. clm/layer2/__init__.py +78 -0
  185. clm/layer2/card_collection.py +678 -0
  186. clm/layer2/classifier.py +479 -0
  187. clm/layer2/engine/__init__.py +1 -0
  188. clm/layer2/engine/abstract_sql_engine.py +320 -0
  189. clm/layer2/engine/base.py +193 -0
  190. clm/layer2/engine/duckdb_engine.py +576 -0
  191. clm/layer2/engine/sqlite_engine.py +518 -0
  192. clm/layer2/fiber/__init__.py +31 -0
  193. clm/layer2/fiber/context.py +89 -0
  194. clm/layer2/fiber/disposable.py +163 -0
  195. clm/layer2/fiber/fiber.py +125 -0
  196. clm/layer2/fiber/hoare.py +191 -0
  197. clm/layer2/file_io.py +376 -0
  198. clm/layer2/file_registrar.py +77 -0
  199. clm/layer2/ingest.py +202 -0
  200. clm/layer2/lineage.py +322 -0
  201. clm/layer2/mcard_fs.py +262 -0
  202. clm/layer2/merkle.py +11 -0
  203. clm/layer2/mime.py +244 -0
  204. clm/layer2/mime_detector.py +245 -0
  205. clm/layer2/private_collection.py +118 -0
  206. clm/layer2/shared_store.py +11 -0
  207. clm/layer2/storage/__init__.py +190 -0
  208. clm/layer2/storage/db_bitemporal.py +141 -0
  209. clm/layer2/storage/db_driver.py +331 -0
  210. clm/layer2/storage/db_hyperlinks.py +214 -0
  211. clm/layer2/storage/db_pool.py +139 -0
  212. clm/layer2/storage/db_repository.py +229 -0
  213. clm/layer2/storage/savepoint.py +78 -0
  214. clm/layer2/storage/sqlite_wal.py +74 -0
  215. clm/layer2/tridb.py +245 -0
  216. clm/layer2/vcard_receipt.py +71 -0
  217. clm/layer2/vfs.py +17 -0
  218. clm/layer3/__init__.py +141 -0
  219. clm/layer3/agency/__init__.py +19 -0
  220. clm/layer3/agency/config.py +220 -0
  221. clm/layer3/agency/providers/__init__.py +15 -0
  222. clm/layer3/agency/providers/base.py +91 -0
  223. clm/layer3/agency/providers/mlc_llm.py +169 -0
  224. clm/layer3/agency/providers/ollama.py +203 -0
  225. clm/layer3/agency/router.py +71 -0
  226. clm/layer3/agency/runtime.py +524 -0
  227. clm/layer3/gateway.py +353 -0
  228. clm/layer3/open_interpreter_adapter.py +159 -0
  229. clm/layer3/rag/__init__.py +70 -0
  230. clm/layer3/rag/cli.py +228 -0
  231. clm/layer3/rag/config.py +153 -0
  232. clm/layer3/rag/embeddings/__init__.py +16 -0
  233. clm/layer3/rag/embeddings/base.py +79 -0
  234. clm/layer3/rag/embeddings/ollama.py +211 -0
  235. clm/layer3/rag/embeddings/vision.py +290 -0
  236. clm/layer3/rag/engine.py +276 -0
  237. clm/layer3/rag/graph/__init__.py +22 -0
  238. clm/layer3/rag/graph/community.py +198 -0
  239. clm/layer3/rag/graph/engine.py +433 -0
  240. clm/layer3/rag/graph/extractor.py +255 -0
  241. clm/layer3/rag/graph/schema.py +115 -0
  242. clm/layer3/rag/graph/store.py +641 -0
  243. clm/layer3/rag/indexer.py +333 -0
  244. clm/layer3/rag/llm_providers.json +52 -0
  245. clm/layer3/rag/semantic_versioning.py +313 -0
  246. clm/layer3/rag/vector/__init__.py +28 -0
  247. clm/layer3/rag/vector/handle_vector_store.py +749 -0
  248. clm/layer3/rag/vector/schema.py +151 -0
  249. clm/layer3/rag/vector/store.py +632 -0
  250. clm/layer3/reticulum/__init__.py +55 -0
  251. clm/layer3/reticulum/bridge.py +74 -0
  252. clm/layer3/reticulum/daemon.py +88 -0
  253. clm/layer3/reticulum/discovery.py +164 -0
  254. clm/layer3/reticulum/identity.py +107 -0
  255. clm/layer3/reticulum/media.py +148 -0
  256. clm/layer3/reticulum/transport.py +133 -0
  257. clm/layer3/satori/__init__.py +209 -0
  258. clm/layer3/satori/alpha_conversion.py +168 -0
  259. clm/layer3/satori/beta_reduction.py +359 -0
  260. clm/layer3/satori/continuation.py +38 -0
  261. clm/layer3/satori/eta_conversion.py +205 -0
  262. clm/layer3/satori/free_variables.py +163 -0
  263. clm/layer3/satori/io_effects.py +370 -0
  264. clm/layer3/satori/lambda_runtime.py +726 -0
  265. clm/layer3/satori/lambda_term.py +230 -0
  266. clm/layer3/satori/sheaf_audit.py +261 -0
  267. clm/layer3/satori/speech_act.py +279 -0
  268. clm/layer4/README.md +9 -0
  269. clm/layer4/__init__.py +67 -0
  270. clm/layer4/_sovereign_executor.py +580 -0
  271. clm/layer4/action_commands.py +719 -0
  272. clm/layer4/api.py +236 -0
  273. clm/layer4/bootstrap/__init__.py +13 -0
  274. clm/layer4/bootstrap/bootstrapper.py +118 -0
  275. clm/layer4/bootstrap/cleanup.py +44 -0
  276. clm/layer4/bootstrap/clm_hooks.py +49 -0
  277. clm/layer4/bootstrap/genesis.py +77 -0
  278. clm/layer4/bootstrap/injection.py +125 -0
  279. clm/layer4/cli.py +549 -0
  280. clm/layer4/collection_manager.py +553 -0
  281. clm/layer4/commands/__init__.py +81 -0
  282. clm/layer4/commands/action_cmd.py +42 -0
  283. clm/layer4/commands/check_cmd.py +82 -0
  284. clm/layer4/commands/envelope.py +73 -0
  285. clm/layer4/commands/evaluate_cmd.py +224 -0
  286. clm/layer4/commands/mcard_cmd.py +24 -0
  287. clm/layer4/commands/petri_cmd.py +92 -0
  288. clm/layer4/commands/tridb_cmd.py +319 -0
  289. clm/layer4/commands/version_cmd.py +27 -0
  290. clm/layer4/diff_commands.py +167 -0
  291. clm/layer4/eoa_sponsor.py +232 -0
  292. clm/layer4/events.py +69 -0
  293. clm/layer4/flux_gateway.py +133 -0
  294. clm/layer4/gateway.py +91 -0
  295. clm/layer4/loader.py +307 -0
  296. clm/layer4/mcard_commands.py +166 -0
  297. clm/layer4/membrane.py +273 -0
  298. clm/layer4/navigation.py +50 -0
  299. clm/layer4/protocol/protocol_entry_python.py +108 -0
  300. clm/layer4/protocol/python_sync.py +126 -0
  301. clm/layer4/runner.py +150 -0
  302. clm/layer4/satori.py +262 -0
  303. clm/layer4/server/python_sync_client.py +150 -0
  304. clm/layer4/server/python_sync_server.py +139 -0
  305. clm/layer4/server/service_api.py +315 -0
  306. clm/layer4/server/start_servers.py +107 -0
  307. clm/layer4/server/stop_servers.py +24 -0
  308. clm/layer4/simulated_optimization_fix.py +0 -0
  309. clm/layer4/storage.py +463 -0
  310. clm/layer4/tridb_admin.py +268 -0
  311. clm/layer4/websocket/test_ws_client.py +104 -0
  312. clm/layer4/websocket/test_ws_server.py +138 -0
  313. clm/layer4/websocket/ws_server_local.py +160 -0
  314. clm/layer5/__init__.py +51 -0
  315. clm/layer5/async_batch_writer.py +133 -0
  316. clm/layer5/learning.py +276 -0
  317. clm/layer5/telemetry_hook.py +107 -0
  318. clm/layer5/type_lattice.py +238 -0
  319. clm/py.typed +0 -0
  320. clm/schemas/__init__.py +652 -0
  321. clm/schemas/abstract_face_schema.yaml +77 -0
  322. clm/schemas/cel_schema.yaml +416 -0
  323. clm/schemas/lifecycle/__init__.py +45 -0
  324. clm/schemas/lifecycle/models.py +123 -0
  325. clm/schemas/lifecycle/service.py +364 -0
  326. clm/schemas/mcard_schema.sql +192 -0
  327. clm/schemas/mcard_vector_schema.sql +283 -0
  328. clm/schemas/mlp-context-v1.json +91 -0
  329. clm_kernel-0.0.0.dist-info/METADATA +121 -0
  330. clm_kernel-0.0.0.dist-info/RECORD +333 -0
  331. clm_kernel-0.0.0.dist-info/WHEEL +4 -0
  332. clm_kernel-0.0.0.dist-info/entry_points.txt +3 -0
  333. clm_kernel-0.0.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,334 @@
1
+ """Tabular Baldwin Modularity Manipulator (Sprint 393 / DEL-393-02).
2
+
3
+ Algebraic operations over CSV and tabular datasets:
4
+ - split: Partition dataset by ratio (e.g., train/test) or predicate filter.
5
+ - substitute: Map/replace values in columns or rename columns.
6
+ - augment: Add derived columns computed from existing fields.
7
+ - exclude: Redact sensitive columns (PII removal) or filter out rows.
8
+ - invert: Invert row order or transpose tabular matrix.
9
+ - port: Transcode CSV to JSON objects or structured records.
10
+
11
+ Layer 1 module (no imports above L1).
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import csv
17
+ import io
18
+ import json
19
+ import random
20
+ import re
21
+ from typing import Any
22
+
23
+
24
+ class TabularManipulator:
25
+ """Modality manipulator for tabular CSV/structured table data."""
26
+
27
+ @staticmethod
28
+ def _parse_csv(data: str | bytes) -> tuple[list[str], list[list[str]]]:
29
+ """Parse raw CSV string or bytes into headers and rows."""
30
+ text = data.decode("utf-8") if isinstance(data, bytes) else str(data)
31
+ reader = csv.reader(io.StringIO(text))
32
+ rows = [r for r in reader if r]
33
+ if not rows:
34
+ return [], []
35
+ headers = rows[0]
36
+ data_rows = rows[1:]
37
+ return headers, data_rows
38
+
39
+ @staticmethod
40
+ def _render_csv(headers: list[str], rows: list[list[str]]) -> str:
41
+ """Render headers and rows back into standard CSV string."""
42
+ out = io.StringIO()
43
+ writer = csv.writer(out, lineterminator="\n")
44
+ if headers:
45
+ writer.writerow(headers)
46
+ writer.writerows(rows)
47
+ return out.getvalue()
48
+
49
+ @classmethod
50
+ def split(
51
+ cls,
52
+ data: str | bytes,
53
+ parameters: dict[str, Any] | None = None,
54
+ ) -> dict[str, str]:
55
+ """Split a tabular dataset into orthogonal partitions.
56
+
57
+ Parameters:
58
+ ratios: dict of partition name -> float ratio (e.g. {'train': 0.8, 'test': 0.2})
59
+ seed: optional random seed for deterministic shuffling
60
+ predicate: optional predicate formula (e.g. "status == 'active'")
61
+ """
62
+ params = parameters or {}
63
+ headers, rows = cls._parse_csv(data)
64
+ if not rows:
65
+ return {"part_1": cls._render_csv(headers, []), "part_2": cls._render_csv(headers, [])}
66
+
67
+ ratios = params.get("ratios")
68
+ predicate = params.get("predicate") or params.get("condition")
69
+
70
+ if predicate and headers:
71
+ # Split into match vs non-match
72
+ # Simple expression evaluation over row dict
73
+ matched: list[list[str]] = []
74
+ unmatched: list[list[str]] = []
75
+ for r in rows:
76
+ row_dict = dict(zip(headers, r))
77
+ val = cls._eval_simple_condition(predicate, row_dict)
78
+ if val:
79
+ matched.append(r)
80
+ else:
81
+ unmatched.append(r)
82
+ return {
83
+ "matched": cls._render_csv(headers, matched),
84
+ "unmatched": cls._render_csv(headers, unmatched),
85
+ }
86
+
87
+ if ratios:
88
+ seed = params.get("seed")
89
+ shuffled_rows = list(rows)
90
+ if seed is not None:
91
+ rng = random.Random(seed)
92
+ rng.shuffle(shuffled_rows)
93
+
94
+ total = len(shuffled_rows)
95
+ partitions: dict[str, str] = {}
96
+ current_idx = 0
97
+ items = list(ratios.items())
98
+
99
+ for i, (name, ratio) in enumerate(items):
100
+ if i == len(items) - 1:
101
+ # Last partition gets all remainder to guarantee exact Noetherian conservation
102
+ part_rows = shuffled_rows[current_idx:]
103
+ else:
104
+ count = int(round(total * ratio))
105
+ part_rows = shuffled_rows[current_idx : current_idx + count]
106
+ current_idx += count
107
+ partitions[name] = cls._render_csv(headers, part_rows)
108
+ return partitions
109
+
110
+ # Default 50/50 split
111
+ mid = len(rows) // 2
112
+ return {
113
+ "part_1": cls._render_csv(headers, rows[:mid]),
114
+ "part_2": cls._render_csv(headers, rows[mid:]),
115
+ }
116
+
117
+ @classmethod
118
+ def substitute(
119
+ cls,
120
+ data: str | bytes,
121
+ parameters: dict[str, Any] | None = None,
122
+ ) -> str:
123
+ """Substitute column names or column values in tabular data.
124
+
125
+ Parameters:
126
+ rename_columns: dict of old_name -> new_name
127
+ value_map: dict of column_name -> dict of old_val -> new_val
128
+ """
129
+ params = parameters or {}
130
+ headers, rows = cls._parse_csv(data)
131
+ rename = params.get("rename_columns", {})
132
+ value_map = params.get("value_map", {})
133
+
134
+ new_headers = [rename.get(h, h) for h in headers]
135
+ col_to_idx = {h: idx for idx, h in enumerate(headers)}
136
+
137
+ new_rows: list[list[str]] = []
138
+ for r in rows:
139
+ new_r = list(r)
140
+ for col, mapping in value_map.items():
141
+ if col in col_to_idx and col_to_idx[col] < len(new_r):
142
+ val = new_r[col_to_idx[col]]
143
+ if val in mapping:
144
+ new_r[col_to_idx[col]] = str(mapping[val])
145
+ new_rows.append(new_r)
146
+
147
+ return cls._render_csv(new_headers, new_rows)
148
+
149
+ @classmethod
150
+ def augment(
151
+ cls,
152
+ data: str | bytes,
153
+ parameters: dict[str, Any] | None = None,
154
+ ) -> str:
155
+ """Augment tabular data with a new derived column.
156
+
157
+ Parameters:
158
+ target_column: name of new column
159
+ source_column: optional source column
160
+ formula: expression or mapping logic
161
+ constant_value: optional constant value
162
+ """
163
+ params = parameters or {}
164
+ headers, rows = cls._parse_csv(data)
165
+ target_col = params.get("column_name") or params.get("target_column") or "augmented_col"
166
+ source_col = params.get("source_column")
167
+ formula = params.get("formula")
168
+ constant_val = params.get("default_value") if params.get("default_value") is not None else params.get("constant_value")
169
+
170
+ new_headers = list(headers) + [target_col]
171
+ col_to_idx = {h: idx for idx, h in enumerate(headers)}
172
+ new_rows: list[list[str]] = []
173
+
174
+ for r in rows:
175
+ row_dict = dict(zip(headers, r))
176
+ if constant_val is not None:
177
+ val = str(constant_val)
178
+ elif formula:
179
+ val = cls._eval_formula(formula, row_dict)
180
+ elif source_col and source_col in col_to_idx:
181
+ val = r[col_to_idx[source_col]]
182
+ else:
183
+ val = ""
184
+ new_rows.append(list(r) + [val])
185
+
186
+ return cls._render_csv(new_headers, new_rows)
187
+
188
+ @classmethod
189
+ def exclude(
190
+ cls,
191
+ data: str | bytes,
192
+ parameters: dict[str, Any] | None = None,
193
+ ) -> str:
194
+ """Exclude (drop) columns or filter out rows.
195
+
196
+ Parameters:
197
+ columns: list of column names to redact/drop
198
+ condition: optional row condition to exclude
199
+ """
200
+ params = parameters or {}
201
+ headers, rows = cls._parse_csv(data)
202
+ drop_cols = set(params.get("columns") or params.get("target_columns") or [])
203
+ condition = params.get("condition") or params.get("predicate")
204
+
205
+ # Column projection
206
+ keep_indices = [i for i, h in enumerate(headers) if h not in drop_cols]
207
+ new_headers = [headers[i] for i in keep_indices]
208
+
209
+ new_rows: list[list[str]] = []
210
+ for r in rows:
211
+ row_dict = dict(zip(headers, r))
212
+ if condition and cls._eval_simple_condition(condition, row_dict):
213
+ # Exclude matching rows
214
+ continue
215
+ new_rows.append([r[i] for i in keep_indices if i < len(r)])
216
+
217
+ return cls._render_csv(new_headers, new_rows)
218
+
219
+ @classmethod
220
+ def invert(
221
+ cls,
222
+ data: str | bytes,
223
+ parameters: dict[str, Any] | None = None,
224
+ ) -> str:
225
+ """Invert tabular data by reversing rows or transposing.
226
+
227
+ Parameters:
228
+ strategy: 'reverse_rows' (default) or 'transpose'
229
+ """
230
+ params = parameters or {}
231
+ strategy = params.get("strategy", "reverse_rows")
232
+ headers, rows = cls._parse_csv(data)
233
+
234
+ if strategy == "transpose" and headers:
235
+ all_matrix = [headers] + rows
236
+ transposed = list(map(list, zip(*all_matrix)))
237
+ new_headers = transposed[0] if transposed else []
238
+ new_rows = transposed[1:] if len(transposed) > 1 else []
239
+ return cls._render_csv(new_headers, new_rows)
240
+
241
+ # Default: reverse row order
242
+ reversed_rows = list(reversed(rows))
243
+ return cls._render_csv(headers, reversed_rows)
244
+
245
+ @classmethod
246
+ def port(
247
+ cls,
248
+ data: str | bytes,
249
+ parameters: dict[str, Any] | None = None,
250
+ ) -> str:
251
+ """Port tabular data across representations (e.g. CSV to JSON array).
252
+
253
+ Parameters:
254
+ target_format: 'json' (default) or 'tsv'
255
+ """
256
+ params = parameters or {}
257
+ target_fmt = params.get("target_format", "json").lower()
258
+ headers, rows = cls._parse_csv(data)
259
+
260
+ if target_fmt == "json":
261
+ records = [dict(zip(headers, r)) for r in rows]
262
+ return json.dumps(records, indent=2)
263
+ elif target_fmt == "tsv":
264
+ out = io.StringIO()
265
+ writer = csv.writer(out, delimiter="\t", lineterminator="\n")
266
+ if headers:
267
+ writer.writerow(headers)
268
+ writer.writerows(rows)
269
+ return out.getvalue()
270
+ return cls._render_csv(headers, rows)
271
+
272
+ @staticmethod
273
+ def _eval_simple_condition(condition: str, row: dict[str, str]) -> bool:
274
+ """Safely evaluate simple conditions like 'col == val' or 'col != val' without eval()."""
275
+ cond = condition.strip()
276
+ # Check !=
277
+ if "!=" in cond:
278
+ parts = cond.split("!=", 1)
279
+ col = parts[0].strip().strip("'\"")
280
+ target = parts[1].strip().strip("'\"")
281
+ return str(row.get(col, "")) != target
282
+ # Check ==
283
+ if "==" in cond:
284
+ parts = cond.split("==", 1)
285
+ col = parts[0].strip().strip("'\"")
286
+ target = parts[1].strip().strip("'\"")
287
+ return str(row.get(col, "")) == target
288
+ # Check >=
289
+ if ">=" in cond:
290
+ parts = cond.split(">=", 1)
291
+ col = parts[0].strip()
292
+ target = float(parts[1].strip())
293
+ return float(row.get(col, 0)) >= target
294
+ # Check <=
295
+ if "<=" in cond:
296
+ parts = cond.split("<=", 1)
297
+ col = parts[0].strip()
298
+ target = float(parts[1].strip())
299
+ return float(row.get(col, 0)) <= target
300
+ # Check >
301
+ if ">" in cond:
302
+ parts = cond.split(">", 1)
303
+ col = parts[0].strip()
304
+ target = float(parts[1].strip())
305
+ return float(row.get(col, 0)) > target
306
+ # Check <
307
+ if "<" in cond:
308
+ parts = cond.split("<", 1)
309
+ col = parts[0].strip()
310
+ target = float(parts[1].strip())
311
+ return float(row.get(col, 0)) < target
312
+
313
+ return bool(row.get(cond))
314
+
315
+ @staticmethod
316
+ def _eval_formula(formula: str, row: dict[str, str]) -> str:
317
+ """Safely evaluate formula/tier rules (e.g. ternary or string replacement)."""
318
+ f = formula.strip()
319
+ # Ternary pattern: cond ? 'val1' : 'val2'
320
+ ternary_match = re.match(r"(.+?)\s*\?\s*['\"](.*?)['\"]\s*:\s*['\"](.*?)['\"]", f)
321
+ if ternary_match:
322
+ cond, true_val, false_val = ternary_match.groups()
323
+ if TabularManipulator._eval_simple_condition(cond, row):
324
+ return true_val
325
+ return false_val
326
+
327
+ # Interpolation pattern: {col1}_{col2}
328
+ if "{" in f and "}" in f:
329
+ res = f
330
+ for k, v in row.items():
331
+ res = res.replace(f"{{{k}}}", str(v))
332
+ return res
333
+
334
+ return f
@@ -0,0 +1,65 @@
1
+ """Baldwin Port Operator (DEL-388-02).
2
+
3
+ Translation Operator (->): A_X -> A_Y.
4
+ Migrates an implementation across heterogeneous host runtime domains
5
+ (e.g., Python -> Rust / Wasm / Bash) without altering its logical abstract
6
+ specification or balanced invariants, preserving triadic syntactic closure.
7
+ """
8
+ from __future__ import annotations
9
+
10
+ import copy
11
+ from typing import Any
12
+
13
+ import yaml
14
+
15
+ from clm.layer0.model.card import MCard
16
+ from clm.layer1.operations.split import _parse_manifest, ensure_triadic_closure
17
+
18
+
19
+ def op_port(impl: dict[str, Any], target: MCard, ctx: dict[str, Any]) -> dict[str, Any]:
20
+ """Execute the Baldwin Port (->) operation.
21
+
22
+ Args:
23
+ impl: Configuration dict for port:
24
+ target_runtime (str): Target runtime (e.g. "rust", "wasm", "node", "bash").
25
+ target: Target MCard to port.
26
+ ctx: Execution context.
27
+
28
+ Returns:
29
+ Dict containing the ported manifest, new MCard, and closure proof.
30
+ """
31
+ manifest = _parse_manifest(target)
32
+ target_runtime = impl.get("target_runtime", ctx.get("target_runtime", "rust"))
33
+
34
+ updated = copy.deepcopy(manifest)
35
+
36
+ # Concrete implementation is adapted to target runtime
37
+ c_impl = updated.get("concrete_impl", {})
38
+ if isinstance(c_impl, dict):
39
+ orig_runtime = c_impl.get("runtime", "python")
40
+ c_impl["runtime"] = target_runtime
41
+ c_impl["ported_from"] = orig_runtime
42
+ else:
43
+ updated["concrete_impl"] = {
44
+ "runtime": target_runtime,
45
+ "ported_from": "python",
46
+ }
47
+
48
+ # Abstract spec and balanced expectations remain invariant
49
+ final_manifest = ensure_triadic_closure(updated)
50
+ yaml_content = yaml.dump(final_manifest, default_flow_style=False)
51
+ new_card = MCard(yaml_content)
52
+
53
+ return {
54
+ "success": True,
55
+ "operator": "port",
56
+ "target_runtime": target_runtime,
57
+ "syntactic_closure": True,
58
+ "manifest": final_manifest,
59
+ "hash": new_card.hash,
60
+ "content": yaml_content,
61
+ "mcard": new_card,
62
+ }
63
+
64
+
65
+ __all__ = ["op_port"]