dep validation of deployment

core wf valication uses a &mut List, this returns a List, hmmmm
This commit is contained in:
lda
2026-05-11 15:24:52 +07:00 Verified
parent 958195ddce
commit 32f80f756d
8 changed files with 388 additions and 22 deletions
+178
View File
@@ -0,0 +1,178 @@
from __future__ import annotations
from wf_artifacts import (
AvailableCapability,
AvailableSource,
DriftPolicy,
RequiredCapability,
WorkflowArtifact,
WorkflowDeployment,
validate_deployment_dependencies,
)
def required_capability(
*,
logical_source: str = "context7",
capability_name: str = "query-docs",
input_hash: str = "sha256:input",
output_hash: str = "sha256:output",
) -> RequiredCapability:
return RequiredCapability(
logical_source=logical_source,
capability_name=capability_name,
kind="tool",
input_schema_hash=input_hash,
input_schema_snapshot={"type": "object", "properties": {}},
output_schema_hash=output_hash,
output_schema_snapshot={"type": "object", "properties": {}},
)
def artifact_with(capability: RequiredCapability) -> WorkflowArtifact:
return WorkflowArtifact(
id="summarize_docs",
version=1,
title="Summarize Docs",
input_schema={"type": "object", "properties": {}},
output_schema={"type": "object", "properties": {}},
outcomes=("done",),
plan={"name": "summarize_docs", "nodes": [], "edges": []},
required_capabilities={
f"{capability.logical_source}.{capability.capability_name}": capability
},
)
def deployment(
*,
bindings: dict[str, str] | None = None,
drift_policy: DriftPolicy = DriftPolicy.BLOCK,
) -> WorkflowDeployment:
return WorkflowDeployment(
id="summarize_docs.personal",
artifact_id="summarize_docs",
artifact_version=1,
bindings={"context7": "context7.personal"} if bindings is None else bindings,
drift_policy=drift_policy,
)
def source(
*,
id: str = "context7.personal",
enabled: bool = True,
capability_name: str = "query-docs",
input_hash: str = "sha256:input",
output_hash: str = "sha256:output",
) -> AvailableSource:
return AvailableSource(
id=id,
enabled=enabled,
capabilities={
capability_name: AvailableCapability(
name=capability_name,
kind="tool",
input_schema_hash=input_hash,
output_schema_hash=output_hash,
)
},
)
def test_validate_deployment_accepts_matching_bound_capability() -> None:
diagnostics = validate_deployment_dependencies(
artifact=artifact_with(required_capability()),
deployment=deployment(),
sources=[source()],
)
assert diagnostics == []
def test_validate_deployment_reports_missing_binding() -> None:
diagnostics = validate_deployment_dependencies(
artifact=artifact_with(required_capability()),
deployment=deployment(bindings={}),
sources=[source()],
)
assert len(diagnostics) == 1
assert diagnostics[0].severity == "error"
assert diagnostics[0].code == "binding_missing"
assert diagnostics[0].logical_ref == "context7.query-docs"
assert diagnostics[0].bound_source is None
def test_validate_deployment_reports_missing_source() -> None:
diagnostics = validate_deployment_dependencies(
artifact=artifact_with(required_capability()),
deployment=deployment(),
sources=[],
)
assert len(diagnostics) == 1
assert diagnostics[0].severity == "error"
assert diagnostics[0].code == "source_missing"
assert diagnostics[0].logical_ref == "context7.query-docs"
assert diagnostics[0].bound_source == "context7.personal"
def test_validate_deployment_reports_disabled_source() -> None:
diagnostics = validate_deployment_dependencies(
artifact=artifact_with(required_capability()),
deployment=deployment(),
sources=[source(enabled=False)],
)
assert len(diagnostics) == 1
assert diagnostics[0].severity == "error"
assert diagnostics[0].code == "source_disabled"
assert diagnostics[0].bound_source == "context7.personal"
def test_validate_deployment_reports_missing_capability() -> None:
diagnostics = validate_deployment_dependencies(
artifact=artifact_with(required_capability()),
deployment=deployment(),
sources=[source(capability_name="other-tool")],
)
assert len(diagnostics) == 1
assert diagnostics[0].severity == "error"
assert diagnostics[0].code == "capability_missing"
assert diagnostics[0].logical_ref == "context7.query-docs"
def test_validate_deployment_blocks_changed_schema_by_default() -> None:
diagnostics = validate_deployment_dependencies(
artifact=artifact_with(required_capability()),
deployment=deployment(),
sources=[source(input_hash="sha256:changed")],
)
assert len(diagnostics) == 1
assert diagnostics[0].severity == "error"
assert diagnostics[0].code == "schema_changed"
def test_validate_deployment_warns_for_changed_schema_when_policy_warns() -> None:
diagnostics = validate_deployment_dependencies(
artifact=artifact_with(required_capability()),
deployment=deployment(drift_policy=DriftPolicy.WARN),
sources=[source(output_hash="sha256:changed")],
)
assert len(diagnostics) == 1
assert diagnostics[0].severity == "warning"
assert diagnostics[0].code == "schema_changed"
def test_validate_deployment_allows_changed_schema_when_policy_allows() -> None:
diagnostics = validate_deployment_dependencies(
artifact=artifact_with(required_capability()),
deployment=deployment(drift_policy=DriftPolicy.ALLOW),
sources=[source(input_hash="sha256:changed")],
)
assert diagnostics == []