cks-core 1.2.0__tar.gz → 1.2.2__tar.gz
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.
- {cks_core-1.2.0 → cks_core-1.2.2}/PKG-INFO +1 -1
- {cks_core-1.2.0 → cks_core-1.2.2}/pyproject.toml +1 -1
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/__init__.py +1 -1
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/engine.py +1 -1
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/evolution.py +84 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/validator.py +1 -1
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks_core.egg-info/PKG-INFO +1 -1
- {cks_core-1.2.0 → cks_core-1.2.2}/LICENSE +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/README.md +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/setup.cfg +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/adapters/cks_to_jsonld.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/adapters/cks_to_rdf.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/adapters/jsonld_to_cks.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/adapters/rdf_to_cks.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/cli/__init__.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/cli/commands/__init__.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/cli/commands/convert.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/cli/commands/evolve.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/cli/commands/export.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/cli/commands/inspect.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/cli/commands/parse.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/cli/commands/plugin.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/cli/commands/schema.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/cli/commands/validate.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/cli/formatters.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/constraints/__init__.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/constraints/base.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/constraints/builtin.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/constraints/registry.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/constraints/semantic.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/constraints/structural.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/core.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/diagnostics.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/interface.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/plugin.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/result.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/schema.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/serialization.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks/validation.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks_core.egg-info/SOURCES.txt +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks_core.egg-info/dependency_links.txt +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks_core.egg-info/entry_points.txt +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks_core.egg-info/requires.txt +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/src/cks_core.egg-info/top_level.txt +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/tests/test_adapters.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/tests/test_cli.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/tests/test_core.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/tests/test_diagnostics.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/tests/test_engine.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/tests/test_evolution.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/tests/test_interface.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/tests/test_plugin.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/tests/test_result.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/tests/test_serialization.py +0 -0
- {cks_core-1.2.0 → cks_core-1.2.2}/tests/test_validator.py +0 -0
|
@@ -193,6 +193,89 @@ class RemoveRelation(StructuralOperator):
|
|
|
193
193
|
)
|
|
194
194
|
|
|
195
195
|
|
|
196
|
+
# ---------------------------------------------------------------------------
|
|
197
|
+
# JSON Deserialization of Operators
|
|
198
|
+
# ---------------------------------------------------------------------------
|
|
199
|
+
#
|
|
200
|
+
# Consumers (the CLI, cks-mcp, and any other adapter) receive evolution
|
|
201
|
+
# requests as plain JSON — a list of dicts such as
|
|
202
|
+
# ``{"type": "add_object", "identity": {...}, "structure": {...}}``.
|
|
203
|
+
# This is the single canonical place that turns that wire format into
|
|
204
|
+
# concrete StructuralOperator instances, so every adapter shares the
|
|
205
|
+
# same admissible operation set and the same error messages.
|
|
206
|
+
|
|
207
|
+
def parse_operations(ops_data: Iterable[dict]) -> list[StructuralOperator]:
|
|
208
|
+
"""
|
|
209
|
+
Parse a JSON-compatible list of operation descriptors into
|
|
210
|
+
StructuralOperators.
|
|
211
|
+
|
|
212
|
+
Parameters
|
|
213
|
+
----------
|
|
214
|
+
ops_data
|
|
215
|
+
A sequence of dicts, each with a ``"type"`` field of
|
|
216
|
+
``"add_object" | "add_relation" | "remove_object" | "remove_relation"``
|
|
217
|
+
and the fields required by that operation.
|
|
218
|
+
|
|
219
|
+
Raises
|
|
220
|
+
------
|
|
221
|
+
ValueError
|
|
222
|
+
If an operation descriptor is missing required fields or has an
|
|
223
|
+
unknown ``"type"``.
|
|
224
|
+
"""
|
|
225
|
+
from .core import ObjectIdentity
|
|
226
|
+
|
|
227
|
+
operators: list[StructuralOperator] = []
|
|
228
|
+
|
|
229
|
+
for i, op in enumerate(ops_data):
|
|
230
|
+
op_type = op.get("type")
|
|
231
|
+
if op_type is None:
|
|
232
|
+
raise ValueError(f"Operation #{i}: missing 'type' field")
|
|
233
|
+
|
|
234
|
+
if op_type == "add_object":
|
|
235
|
+
identity_data = op.get("identity")
|
|
236
|
+
if identity_data is None:
|
|
237
|
+
raise ValueError(f"Operation #{i}: missing 'identity' field")
|
|
238
|
+
identity = ObjectIdentity(**identity_data)
|
|
239
|
+
obj = KnowledgeObject(identity=identity, structure=op.get("structure", {}))
|
|
240
|
+
operators.append(AddObject(obj))
|
|
241
|
+
|
|
242
|
+
elif op_type == "add_relation":
|
|
243
|
+
identity_data = op.get("identity")
|
|
244
|
+
if identity_data is None:
|
|
245
|
+
raise ValueError(f"Operation #{i}: missing 'identity' field")
|
|
246
|
+
identity = ObjectIdentity(**identity_data)
|
|
247
|
+
participants = op.get("participants")
|
|
248
|
+
if participants is None:
|
|
249
|
+
raise ValueError(f"Operation #{i}: missing 'participants' field")
|
|
250
|
+
relation_type = op.get("relation_type")
|
|
251
|
+
if relation_type is None:
|
|
252
|
+
raise ValueError(f"Operation #{i}: missing 'relation_type' field")
|
|
253
|
+
relation = CanonicalRelation(
|
|
254
|
+
identity=identity,
|
|
255
|
+
participants=participants,
|
|
256
|
+
relation_type=relation_type,
|
|
257
|
+
structure=op.get("structure", {}),
|
|
258
|
+
)
|
|
259
|
+
operators.append(AddRelation(relation))
|
|
260
|
+
|
|
261
|
+
elif op_type == "remove_object":
|
|
262
|
+
object_id = op.get("object_id")
|
|
263
|
+
if object_id is None:
|
|
264
|
+
raise ValueError(f"Operation #{i}: missing 'object_id' field")
|
|
265
|
+
operators.append(RemoveObject(object_id))
|
|
266
|
+
|
|
267
|
+
elif op_type == "remove_relation":
|
|
268
|
+
relation_id = op.get("relation_id")
|
|
269
|
+
if relation_id is None:
|
|
270
|
+
raise ValueError(f"Operation #{i}: missing 'relation_id' field")
|
|
271
|
+
operators.append(RemoveRelation(relation_id))
|
|
272
|
+
|
|
273
|
+
else:
|
|
274
|
+
raise ValueError(f"Operation #{i}: unknown operation type '{op_type}'")
|
|
275
|
+
|
|
276
|
+
return operators
|
|
277
|
+
|
|
278
|
+
|
|
196
279
|
# ---------------------------------------------------------------------------
|
|
197
280
|
# Composition
|
|
198
281
|
# ---------------------------------------------------------------------------
|
|
@@ -219,4 +302,5 @@ __all__ = [
|
|
|
219
302
|
"RemoveObject",
|
|
220
303
|
"RemoveRelation",
|
|
221
304
|
"compose",
|
|
305
|
+
"parse_operations",
|
|
222
306
|
]
|
|
@@ -82,7 +82,7 @@ class ReferenceValidator:
|
|
|
82
82
|
# ------------------------------------------------------------------
|
|
83
83
|
|
|
84
84
|
def constraint_validate(self, structure: KnowledgeStructure) -> list[Diagnostic]:
|
|
85
|
-
return self._registry.evaluate(structure)
|
|
85
|
+
return self._registry.evaluate(structure, stage=ValidationStage.CONSTRAINTS)
|
|
86
86
|
|
|
87
87
|
# ------------------------------------------------------------------
|
|
88
88
|
# Pipeline
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|