docs: plan thesis evidence and reject platform bindings
This commit is contained in:
@@ -234,6 +234,38 @@ def test_platform_source_requirement_does_not_need_binding() -> None:
|
||||
assert diagnostics == []
|
||||
|
||||
|
||||
def test_platform_source_rejects_explicit_deployment_binding() -> None:
|
||||
artifact = artifact_with(
|
||||
required_capability(logical_source="wf.std", capability_name="replace")
|
||||
)
|
||||
deployment = WorkflowDeployment(
|
||||
id="demo.default",
|
||||
artifact_id=artifact.id,
|
||||
artifact_version=artifact.version,
|
||||
bindings={"wf.std": "custom.std"},
|
||||
)
|
||||
|
||||
diagnostics = validate_deployment_dependencies(
|
||||
artifact=artifact,
|
||||
deployment=deployment,
|
||||
sources=[
|
||||
AvailableSource(
|
||||
id="wf.std",
|
||||
platform=True,
|
||||
capabilities={
|
||||
"replace": AvailableCapability(name="replace", kind="node_spec")
|
||||
},
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
assert [diagnostic.code for diagnostic in diagnostics] == [
|
||||
"platform_binding_forbidden"
|
||||
]
|
||||
assert diagnostics[0].logical_ref == "wf.std"
|
||||
assert diagnostics[0].bound_source == "custom.std"
|
||||
|
||||
|
||||
def test_missing_platform_source_still_reports_binding_missing() -> None:
|
||||
artifact = artifact_with(
|
||||
required_capability(logical_source="wf.std", capability_name="replace")
|
||||
|
||||
@@ -665,8 +665,6 @@ def test_wf_remote_draft_artifact_deploy_lifecycle(monkeypatch, tmp_path) -> Non
|
||||
"Remote Artifact",
|
||||
"--outcome",
|
||||
"ok",
|
||||
"--binding",
|
||||
"wf.std=wf.std",
|
||||
],
|
||||
)
|
||||
assert saved_artifact.exit_code == 0, saved_artifact.output
|
||||
@@ -690,8 +688,6 @@ def test_wf_remote_draft_artifact_deploy_lifecycle(monkeypatch, tmp_path) -> Non
|
||||
"remote_artifact",
|
||||
"--version",
|
||||
"1",
|
||||
"--binding",
|
||||
"wf.std=wf.std",
|
||||
],
|
||||
)
|
||||
assert saved_deployment.exit_code == 0, saved_deployment.output
|
||||
@@ -774,7 +770,7 @@ def test_wf_status_uses_rpc_url_override(monkeypatch, tmp_path) -> None:
|
||||
title="Status Constant",
|
||||
plan=_constant_plan(),
|
||||
outcomes=("ok",),
|
||||
source_bindings={"wf.std": "wf.std"},
|
||||
source_bindings={},
|
||||
)
|
||||
)
|
||||
asyncio.run(
|
||||
@@ -783,7 +779,7 @@ def test_wf_status_uses_rpc_url_override(monkeypatch, tmp_path) -> None:
|
||||
"id": "status_constant.default",
|
||||
"artifact_id": "status_constant",
|
||||
"artifact_version": 1,
|
||||
"bindings": [{"logical_source": "wf.std", "concrete_source": "wf.std"}],
|
||||
"bindings": {},
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
@@ -84,14 +84,14 @@ async def test_local_static_server_runs_deployment_and_persists_run(tmp_path) ->
|
||||
title="Server Constant",
|
||||
plan=plan,
|
||||
outcomes=["ok"],
|
||||
source_bindings={"wf.std": "wf.std"},
|
||||
source_bindings={},
|
||||
)
|
||||
deployment_result = await api.save_deployment(
|
||||
{
|
||||
"id": "server_constant.default",
|
||||
"artifact_id": "server_constant",
|
||||
"artifact_version": 1,
|
||||
"bindings": [{"logical_source": "wf.std", "concrete_source": "wf.std"}],
|
||||
"bindings": {},
|
||||
}
|
||||
)
|
||||
run_result = await api.run_deployment(
|
||||
@@ -119,14 +119,14 @@ async def test_local_static_server_inspects_and_reads_bounded_trace(tmp_path) ->
|
||||
title="Server Trace",
|
||||
plan=plan.model_copy(update={"name": "server_trace"}),
|
||||
outcomes=["ok"],
|
||||
source_bindings={"wf.std": "wf.std"},
|
||||
source_bindings={},
|
||||
)
|
||||
await api.save_deployment(
|
||||
{
|
||||
"id": "server_trace.default",
|
||||
"artifact_id": "server_trace",
|
||||
"artifact_version": 1,
|
||||
"bindings": [{"logical_source": "wf.std", "concrete_source": "wf.std"}],
|
||||
"bindings": {},
|
||||
}
|
||||
)
|
||||
run_result = await api.run_deployment(
|
||||
|
||||
@@ -175,7 +175,7 @@ async def test_rpc_draft_artifact_deployment_lifecycle(tmp_path) -> None:
|
||||
},
|
||||
"outcomes": ["ok"],
|
||||
"required_capabilities": {},
|
||||
"source_bindings": {"wf.std": "wf.std"},
|
||||
"source_bindings": {},
|
||||
"plan": compiled_plan,
|
||||
},
|
||||
},
|
||||
@@ -188,9 +188,7 @@ async def test_rpc_draft_artifact_deployment_lifecycle(tmp_path) -> None:
|
||||
"id": "constant_rpc.default",
|
||||
"artifact_id": "constant_rpc",
|
||||
"artifact_version": 1,
|
||||
"bindings": [
|
||||
{"logical_source": "wf.std", "concrete_source": "wf.std"}
|
||||
],
|
||||
"bindings": {},
|
||||
},
|
||||
},
|
||||
)
|
||||
@@ -215,14 +213,14 @@ async def test_rpc_artifact_and_deployment_catalog_methods(tmp_path) -> None:
|
||||
title="RPC Lifecycle",
|
||||
plan=_constant_plan(),
|
||||
outcomes=["ok"],
|
||||
source_bindings={"wf.std": "wf.std"},
|
||||
source_bindings={},
|
||||
)
|
||||
await server.api.save_deployment(
|
||||
{
|
||||
"id": "rpc_lifecycle.default",
|
||||
"artifact_id": "rpc_lifecycle",
|
||||
"artifact_version": 1,
|
||||
"bindings": [{"logical_source": "wf.std", "concrete_source": "wf.std"}],
|
||||
"bindings": {},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -303,7 +301,7 @@ async def test_rpc_draft_workspace_methods(tmp_path) -> None:
|
||||
"title": "Remote Artifact",
|
||||
"outcomes": ["ok"],
|
||||
"kind": "workflow",
|
||||
"source_bindings": {"wf.std": "wf.std"},
|
||||
"source_bindings": {},
|
||||
},
|
||||
)
|
||||
|
||||
@@ -346,7 +344,7 @@ async def test_rpc_artifact_delete(tmp_path) -> None:
|
||||
title="Delete Me",
|
||||
plan=_constant_plan(),
|
||||
outcomes=["ok"],
|
||||
source_bindings={"wf.std": "wf.std"},
|
||||
source_bindings={},
|
||||
)
|
||||
|
||||
app = create_rpc_app(server)
|
||||
@@ -419,14 +417,14 @@ async def test_rpc_runs_deployment_and_reads_bounded_trace(tmp_path) -> None:
|
||||
title="RPC Constant",
|
||||
plan=_constant_plan(),
|
||||
outcomes=["ok"],
|
||||
source_bindings={"wf.std": "wf.std"},
|
||||
source_bindings={},
|
||||
)
|
||||
await server.api.save_deployment(
|
||||
{
|
||||
"id": "rpc_constant.default",
|
||||
"artifact_id": "rpc_constant",
|
||||
"artifact_version": 1,
|
||||
"bindings": [{"logical_source": "wf.std", "concrete_source": "wf.std"}],
|
||||
"bindings": {},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -473,14 +471,14 @@ async def test_rpc_run_list_method(tmp_path) -> None:
|
||||
title="List Runs RPC",
|
||||
plan=_constant_plan(),
|
||||
outcomes=["ok"],
|
||||
source_bindings={"wf.std": "wf.std"},
|
||||
source_bindings={},
|
||||
)
|
||||
await server.api.save_deployment(
|
||||
{
|
||||
"id": "list_runs_rpc.default",
|
||||
"artifact_id": "list_runs_rpc",
|
||||
"artifact_version": 1,
|
||||
"bindings": [{"logical_source": "wf.std", "concrete_source": "wf.std"}],
|
||||
"bindings": {},
|
||||
}
|
||||
)
|
||||
started = await server.api.run_deployment(
|
||||
@@ -584,7 +582,7 @@ async def test_rpc_runs_workflow_from_python_source_capability(tmp_path) -> None
|
||||
"title": "Python Echo",
|
||||
"outcomes": ["ok"],
|
||||
"kind": "workflow",
|
||||
"source_bindings": {"local.ops": "local.ops", "wf.std": "wf.std"},
|
||||
"source_bindings": {"local.ops": "local.ops"},
|
||||
},
|
||||
)
|
||||
deployment = await _rpc(
|
||||
@@ -597,7 +595,6 @@ async def test_rpc_runs_workflow_from_python_source_capability(tmp_path) -> None
|
||||
"artifact_version": 1,
|
||||
"bindings": [
|
||||
{"logical_source": "local.ops", "concrete_source": "local.ops"},
|
||||
{"logical_source": "wf.std", "concrete_source": "wf.std"},
|
||||
],
|
||||
}
|
||||
},
|
||||
|
||||
@@ -145,14 +145,14 @@ async def test_rpc_workflow_client_runs_and_reads_trace(tmp_path) -> None:
|
||||
title="Client Constant",
|
||||
plan=_constant_plan(),
|
||||
outcomes=["ok"],
|
||||
source_bindings={"wf.std": "wf.std"},
|
||||
source_bindings={},
|
||||
)
|
||||
await server.api.save_deployment(
|
||||
{
|
||||
"id": "client_constant.default",
|
||||
"artifact_id": "client_constant",
|
||||
"artifact_version": 1,
|
||||
"bindings": [{"logical_source": "wf.std", "concrete_source": "wf.std"}],
|
||||
"bindings": {},
|
||||
}
|
||||
)
|
||||
app = create_rpc_app(server)
|
||||
@@ -215,7 +215,7 @@ async def test_rpc_workflow_client_lists_and_inspects_artifacts(tmp_path) -> Non
|
||||
title="Client Art",
|
||||
plan=_constant_plan(),
|
||||
outcomes=["ok"],
|
||||
source_bindings={"wf.std": "wf.std"},
|
||||
source_bindings={},
|
||||
)
|
||||
app = create_rpc_app(server)
|
||||
transport = httpx.ASGITransport(app=app)
|
||||
@@ -242,14 +242,14 @@ async def test_rpc_workflow_client_lists_inspects_validates_and_deletes_deployme
|
||||
title="Client Deploy Art",
|
||||
plan=_constant_plan(),
|
||||
outcomes=["ok"],
|
||||
source_bindings={"wf.std": "wf.std"},
|
||||
source_bindings={},
|
||||
)
|
||||
await server.api.save_deployment(
|
||||
{
|
||||
"id": "client_deploy_art.default",
|
||||
"artifact_id": "client_deploy_art",
|
||||
"artifact_version": 1,
|
||||
"bindings": [{"logical_source": "wf.std", "concrete_source": "wf.std"}],
|
||||
"bindings": {},
|
||||
}
|
||||
)
|
||||
app = create_rpc_app(server)
|
||||
@@ -310,7 +310,7 @@ async def test_rpc_workflow_client_draft_workspace_lifecycle(tmp_path) -> None:
|
||||
title="Client WS Art",
|
||||
outcomes=("ok",),
|
||||
kind="workflow",
|
||||
source_bindings={"wf.std": "wf.std"},
|
||||
source_bindings={},
|
||||
)
|
||||
|
||||
assert created["workspace_id"] == "client_ws"
|
||||
@@ -357,7 +357,7 @@ async def test_rpc_workflow_client_deletes_artifact(tmp_path) -> None:
|
||||
title="Delete Me",
|
||||
plan=_constant_plan(),
|
||||
outcomes=["ok"],
|
||||
source_bindings={"wf.std": "wf.std"},
|
||||
source_bindings={},
|
||||
)
|
||||
|
||||
app = create_rpc_app(server)
|
||||
@@ -383,14 +383,14 @@ async def test_rpc_client_lists_runs(tmp_path) -> None:
|
||||
title="Client List Runs",
|
||||
plan=_constant_plan(),
|
||||
outcomes=["ok"],
|
||||
source_bindings={"wf.std": "wf.std"},
|
||||
source_bindings={},
|
||||
)
|
||||
await server.api.save_deployment(
|
||||
{
|
||||
"id": "client_list_runs.default",
|
||||
"artifact_id": "client_list_runs",
|
||||
"artifact_version": 1,
|
||||
"bindings": [{"logical_source": "wf.std", "concrete_source": "wf.std"}],
|
||||
"bindings": {},
|
||||
}
|
||||
)
|
||||
started = await server.api.run_deployment(
|
||||
|
||||
@@ -476,7 +476,6 @@ async def test_mcp_backed_rpc_workflow_reuses_runtime_session_across_runs(
|
||||
"logical_source": "fixture.default",
|
||||
"concrete_source": "fixture.default",
|
||||
},
|
||||
{"logical_source": "wf.std", "concrete_source": "wf.std"},
|
||||
],
|
||||
}
|
||||
)
|
||||
@@ -569,7 +568,6 @@ async def test_mcp_backed_rpc_workflow_reuses_runtime_session_direct_setup(
|
||||
"logical_source": "fixture.default",
|
||||
"concrete_source": "fixture.default",
|
||||
},
|
||||
{"logical_source": "wf.std", "concrete_source": "wf.std"},
|
||||
],
|
||||
}
|
||||
)
|
||||
@@ -665,7 +663,6 @@ async def test_mcp_backed_rpc_deployment_becomes_unrunnable_after_source_removed
|
||||
"logical_source": "fixture.default",
|
||||
"concrete_source": "fixture.default",
|
||||
},
|
||||
{"logical_source": "wf.std", "concrete_source": "wf.std"},
|
||||
],
|
||||
}
|
||||
)
|
||||
@@ -752,7 +749,6 @@ async def test_mcp_backed_rpc_workflow_reuses_real_stdio_fixture_session(
|
||||
"logical_source": "fixture.personal",
|
||||
"concrete_source": "fixture.personal",
|
||||
},
|
||||
{"logical_source": "wf.std", "concrete_source": "wf.std"},
|
||||
],
|
||||
}
|
||||
)
|
||||
@@ -781,7 +777,6 @@ async def test_mcp_backed_rpc_workflow_reuses_real_stdio_fixture_session(
|
||||
"logical_source": "fixture.personal",
|
||||
"concrete_source": "fixture.personal",
|
||||
},
|
||||
{"logical_source": "wf.std", "concrete_source": "wf.std"},
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user