docs: plan thesis evidence and reject platform bindings

This commit is contained in:
lda
2026-06-14 16:42:16 +07:00 Verified
parent 35e1c169c0
commit 03762b1aa9
16 changed files with 1557 additions and 69 deletions
+32
View File
@@ -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")
+2 -6
View File
@@ -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": {},
}
)
)
+4 -4
View File
@@ -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(
+11 -14
View File
@@ -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"},
],
}
},
+9 -9
View File
@@ -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"},
],
}
)