fix: gate capability draft edits on revision

This commit is contained in:
lda
2026-07-22 01:34:02 +07:00 Verified
parent 5eda86b465
commit 8b8be0279a
2 changed files with 92 additions and 3 deletions
+77
View File
@@ -535,6 +535,38 @@ async def test_patch_draft_workspace_updates_revision(tmp_path: Path) -> None:
assert patched["status"] == "valid"
@pytest.mark.asyncio
async def test_patch_draft_workspace_stale_revision_does_not_mutate(
tmp_path: Path,
) -> None:
artifact_store = FileWorkflowArtifactStore(
tmp_path / "drafts_patch_workspace_stale"
)
api, _service, _authoring = _draft_api(artifact_store, register_echo=True)
await api.create_draft_workspace(
workspace_id="echo_ws",
draft=_echo_draft(),
)
before = await api.get_draft_workspace(
workspace_id="echo_ws",
include_draft=True,
)
result = await api.patch_draft_workspace(
workspace_id="echo_ws",
revision=2,
patch=[{"op": "replace", "path": "/name", "value": "must_not_apply"}],
)
after = await api.get_draft_workspace(
workspace_id="echo_ws",
include_draft=True,
)
assert result["status"] == "conflict"
assert result["diagnostics"][0]["code"] == "revision_conflict"
assert after == before
@pytest.mark.asyncio
async def test_draft_workspace_patch_helpers_update_revision_and_bindings(
tmp_path: Path,
@@ -1286,6 +1318,51 @@ async def test_add_step_stale_revision_wins_over_content_preflight(
assert after == before
@pytest.mark.asyncio
@pytest.mark.parametrize("operation", ["bind", "capability_add"])
async def test_capability_aware_edits_stale_revision_wins_over_semantic_errors(
tmp_path: Path,
operation: str,
) -> None:
artifact_store = FileWorkflowArtifactStore(
tmp_path / f"draft_capability_stale_{operation}"
)
api, _service, authoring = _draft_api(artifact_store, register_echo=True)
await api.create_draft_workspace(
workspace_id="draft_ws",
draft=_echo_draft(),
)
before = await api.get_draft_workspace(
workspace_id="draft_ws",
include_draft=True,
)
if operation == "bind":
result = await authoring.bind_draft(
workspace_id="draft_ws",
revision=2,
step_id="missing",
source_path="input.text",
target_path="local.text",
)
else:
result = await authoring.add_step_from_capability(
workspace_id="draft_ws",
revision=2,
step_id="new_step",
capability_name="missing.connection.unknown_tool",
)
after = await api.get_draft_workspace(
workspace_id="draft_ws",
include_draft=True,
)
assert result["status"] == "conflict"
assert result["revision"] == before["revision"]
assert result["diagnostics"][0]["code"] == "revision_conflict"
assert after == before
@pytest.mark.asyncio
async def test_add_step_adds_missing_incoming_route_parent_atomically(
tmp_path: Path,