katalyst-engine 4.0.0__tar.gz → 4.1.0__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.
Files changed (115) hide show
  1. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/CHANGELOG.md +6 -0
  2. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/PKG-INFO +1 -1
  3. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/pyproject.toml +1 -1
  4. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/schema/definition.py +5 -0
  5. katalyst_engine-4.1.0/tests/schema/test_engine_boundary_guard.py +49 -0
  6. katalyst_engine-4.1.0/tests/schema/test_fieldspec_allowed_values.py +23 -0
  7. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/.gitignore +0 -0
  8. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/README.md +0 -0
  9. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/__init__.py +0 -0
  10. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/bundle/__init__.py +0 -0
  11. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/bundle/discovery.py +0 -0
  12. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/bundle/loader.py +0 -0
  13. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/bundle/path_loader.py +0 -0
  14. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/bundle/protocol.py +0 -0
  15. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/core/__init__.py +0 -0
  16. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/core/compatibility.py +0 -0
  17. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/core/compositional.py +0 -0
  18. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/core/definitive.py +0 -0
  19. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/core/evolvable.py +0 -0
  20. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/core/identity.py +0 -0
  21. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/core/lifecycle.py +0 -0
  22. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/core/relation.py +0 -0
  23. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/core/version.py +0 -0
  24. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/discovery/__init__.py +0 -0
  25. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/discovery/declaration.py +0 -0
  26. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/discovery/dispatcher.py +0 -0
  27. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/discovery/protocol.py +0 -0
  28. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/events/__init__.py +0 -0
  29. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/events/bus.py +0 -0
  30. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/events/event.py +0 -0
  31. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/extensions/__init__.py +0 -0
  32. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/extensions/capability.py +0 -0
  33. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/extensions/discovery.py +0 -0
  34. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/extensions/effector.py +0 -0
  35. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/extensions/provider.py +0 -0
  36. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/extensions/registry.py +0 -0
  37. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/extensions/trigger.py +0 -0
  38. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/model/__init__.py +0 -0
  39. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/model/manager.py +0 -0
  40. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/model/materializer.py +0 -0
  41. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/model/node.py +0 -0
  42. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/model/query.py +0 -0
  43. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/model/store.py +0 -0
  44. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/py.typed +0 -0
  45. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/replication/__init__.py +0 -0
  46. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/replication/engine.py +0 -0
  47. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/replication/job.py +0 -0
  48. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/replication/transform.py +0 -0
  49. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/resolution/__init__.py +0 -0
  50. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/resolution/conflict.py +0 -0
  51. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/resolution/engine.py +0 -0
  52. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/resolution/strategies.py +0 -0
  53. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/schema/__init__.py +0 -0
  54. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/schema/manager.py +0 -0
  55. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/schema/registry.py +0 -0
  56. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/schema/versioning.py +0 -0
  57. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/snapshot/__init__.py +0 -0
  58. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/snapshot/diff.py +0 -0
  59. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/snapshot/snapshot.py +0 -0
  60. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/source/__init__.py +0 -0
  61. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/source/manifest.py +0 -0
  62. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/source/registry.py +0 -0
  63. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/source/source.py +0 -0
  64. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/toolkit/__init__.py +0 -0
  65. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/toolkit/file_ops.py +0 -0
  66. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/src/katalyst_engine/toolkit/rendering.py +0 -0
  67. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/bundle/__init__.py +0 -0
  68. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/bundle/test_discovery.py +0 -0
  69. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/bundle/test_loader.py +0 -0
  70. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/bundle/test_path_loader.py +0 -0
  71. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/bundle/test_protocol.py +0 -0
  72. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/conftest.py +0 -0
  73. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/core/__init__.py +0 -0
  74. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/core/test_compatibility.py +0 -0
  75. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/core/test_compositional.py +0 -0
  76. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/core/test_definitive.py +0 -0
  77. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/core/test_evolvable.py +0 -0
  78. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/core/test_identity.py +0 -0
  79. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/core/test_init.py +0 -0
  80. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/core/test_lifecycle.py +0 -0
  81. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/core/test_relation.py +0 -0
  82. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/core/test_version.py +0 -0
  83. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/discovery/__init__.py +0 -0
  84. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/discovery/test_declaration.py +0 -0
  85. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/discovery/test_dispatcher.py +0 -0
  86. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/events/__init__.py +0 -0
  87. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/events/test_bus.py +0 -0
  88. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/extensions/__init__.py +0 -0
  89. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/extensions/test_effector.py +0 -0
  90. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/extensions/test_provider.py +0 -0
  91. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/extensions/test_registry.py +0 -0
  92. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/model/__init__.py +0 -0
  93. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/model/test_materializer.py +0 -0
  94. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/model/test_node.py +0 -0
  95. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/model/test_query.py +0 -0
  96. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/model/test_store.py +0 -0
  97. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/replication/__init__.py +0 -0
  98. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/replication/test_engine.py +0 -0
  99. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/resolution/__init__.py +0 -0
  100. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/resolution/test_engine.py +0 -0
  101. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/resolution/test_strategies.py +0 -0
  102. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/schema/__init__.py +0 -0
  103. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/schema/test_definition.py +0 -0
  104. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/schema/test_manager.py +0 -0
  105. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/schema/test_registry.py +0 -0
  106. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/schema/test_versioning.py +0 -0
  107. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/snapshot/__init__.py +0 -0
  108. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/snapshot/test_diff.py +0 -0
  109. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/snapshot/test_snapshot.py +0 -0
  110. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/source/__init__.py +0 -0
  111. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/source/test_source.py +0 -0
  112. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/toolkit/__init__.py +0 -0
  113. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/toolkit/test_file_ops.py +0 -0
  114. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/tests/toolkit/test_rendering.py +0 -0
  115. {katalyst_engine-4.0.0 → katalyst_engine-4.1.0}/uv.lock +0 -0
@@ -10,6 +10,12 @@ workspace packages. Tags use the `engine-vX.Y.Z` prefix.
10
10
 
11
11
  ---
12
12
 
13
+ ## [4.1.0] -- 2026-06-26
14
+
15
+ ### Added
16
+
17
+ - **`FieldSpec.allowed_values`** -- a generic, taxonomy-agnostic field-constraint mechanism. When non-empty, it declares the permitted values for a field; empty (the default `()`) means unconstrained. Consumers (e.g. the taxonomy v2 linter) project it to a JSON Schema `enum`. The engine holds only the mechanism; domain-specific values (such as the `work_item` lifecycle) live in the forge consumer, keeping the engine taxonomy-agnostic. Additive and backward-compatible. (#143, #138)
18
+
13
19
  ## [4.0.0] -- 2026-06-16
14
20
 
15
21
  ### Removed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: katalyst-engine
3
- Version: 4.0.0
3
+ Version: 4.1.0
4
4
  Summary: A distributed declaration framework — primitives for schema-aware, multi-source, evolvable artifact graphs
5
5
  Project-URL: Repository, https://github.com/esimplicityinc/katalyst-taxonomy
6
6
  Author: eSimplicity
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "katalyst-engine"
3
- version = "4.0.0"
3
+ version = "4.1.0"
4
4
  description = "A distributed declaration framework — primitives for schema-aware, multi-source, evolvable artifact graphs"
5
5
  readme = "README.md"
6
6
  license = { text = "Proprietary" }
@@ -44,6 +44,11 @@ class FieldSpec(BaseModel, frozen=True):
44
44
  ref_target_kind: str = ""
45
45
  """If field_type is 'ref', the kind of Evolvable it references."""
46
46
 
47
+ allowed_values: tuple[str, ...] = ()
48
+ """If non-empty, the permitted values for this field, projected to a JSON
49
+ Schema ``enum`` by consumers. Empty means unconstrained. The engine holds
50
+ only the mechanism; domain-specific values are supplied by consumers."""
51
+
47
52
 
48
53
  class ParentRule(BaseModel, frozen=True):
49
54
  """Declares what kinds are allowed as parents of a node kind.
@@ -0,0 +1,49 @@
1
+ """Engine boundary guard: engine must stay taxonomy-agnostic.
2
+
3
+ The engine holds the field-constraint MECHANISM (FieldSpec.allowed_values) but
4
+ never taxonomy-specific VALUES (e.g. the work_item lifecycle). Those live in the
5
+ forge consumer. This guard fails if lifecycle status literals or forge/taxonomy
6
+ imports leak into engine/src.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import re
12
+ from pathlib import Path
13
+
14
+ ENGINE_SRC = Path(__file__).resolve().parents[2] / "src" / "katalyst_engine"
15
+ LIFECYCLE_TOKENS = (
16
+ "idea",
17
+ "proposed",
18
+ "accepted",
19
+ "planned",
20
+ "in_progress",
21
+ "blocked",
22
+ "delivered",
23
+ "validated",
24
+ "released",
25
+ "retired",
26
+ )
27
+
28
+
29
+ def _engine_files() -> list[Path]:
30
+ return list(ENGINE_SRC.rglob("*.py"))
31
+
32
+
33
+ def test_no_lifecycle_status_literals_in_engine() -> None:
34
+ offenders: list[str] = []
35
+ for path in _engine_files():
36
+ text = path.read_text(encoding="utf-8")
37
+ present = [t for t in LIFECYCLE_TOKENS if t in text]
38
+ if len(present) >= 2:
39
+ offenders.append(f"{path.name}: {present}")
40
+ assert not offenders, f"Lifecycle values leaked into engine: {offenders}"
41
+
42
+
43
+ def test_engine_does_not_import_consumers() -> None:
44
+ import_re = re.compile(r"^\s*(?:import|from)\s+katalyst_(?:forge|taxonomy)\b", re.MULTILINE)
45
+ offenders: list[str] = []
46
+ for path in _engine_files():
47
+ if import_re.search(path.read_text(encoding="utf-8")):
48
+ offenders.append(path.name)
49
+ assert not offenders, f"Engine imports consumer packages: {offenders}"
@@ -0,0 +1,23 @@
1
+ """WP-3 (#3 mechanism): FieldSpec.allowed_values generic constraint."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from katalyst_engine.schema.definition import FieldSpec
6
+
7
+
8
+ def test_allowed_values_default_empty() -> None:
9
+ assert FieldSpec(name="status").allowed_values == ()
10
+
11
+
12
+ def test_allowed_values_set() -> None:
13
+ f = FieldSpec(name="status", allowed_values=("a", "b"))
14
+ assert f.allowed_values == ("a", "b")
15
+
16
+
17
+ def test_allowed_values_frozen() -> None:
18
+ f = FieldSpec(name="status", allowed_values=("a",))
19
+ try:
20
+ f.allowed_values = ("c",) # type: ignore[misc]
21
+ raise AssertionError("Expected frozen") # noqa: TRY301
22
+ except Exception:
23
+ pass
File without changes