Verify AI replan and cancellation completion boundaries
Foundry Go checks / check (push) Successful in 2m54s
Foundry Go checks / check (pull_request) Successful in 2m52s

This commit is contained in:
2026-11-08 01:04:34 +08:00
parent f12c4ad8bd
commit cdf48f1691
@@ -315,7 +315,12 @@ func TestCanonicalAIAdmissionAndLifecycle(t *testing.T) {
if read().Elements[node]["data"].(map[string]any)["text"] != "keep this" {
t.Fatal("restore was overwritten")
}
call("POST", stalePath+"/apply", response{"node_id": node, "output_id": staleOutput}, 409, read().Versions[root], modelTestID(6201))
staleApplyKey := modelTestID(6201)
staleApply := call("POST", stalePath+"/apply", response{"protocol_version": 2, "request_id": staleApplyKey, "operation_id": modelTestID(6205), "target_incarnation": 1, "target_canvas_id": root, "node_id": node, "output_id": staleOutput}, 409, read().Versions[root], staleApplyKey)
if staleApply["status"] != "not-applied" || staleApply["terminal"] != true || !modelEqual(staleApply, call("GET", base(root)+"/ai/operations/"+staleApplyKey, nil, 200, 0, "")) {
t.Fatal("stale apply has no queryable zero-effect receipt")
}
bad, badKey := command(root, node, "text", 1)
call("POST", base(root)+"/ai/runs", bad, 409, read().Versions[root], badKey)
restored := start(root, node, "text", 2)
@@ -406,8 +411,22 @@ func TestCanonicalAIAdmissionAndLifecycle(t *testing.T) {
missingInput, missingKey := command(child, imageID, "image", 1)
delete(missingInput, "expected_versions")
call("POST", base(child)+"/ai/runs", missingInput, 400, read().Versions[child], missingKey)
childRun := start(child, imageID, "image", 1)
// An explicit replan can reuse a logical operation after its known zero-effect rejection.
replanned := response{}
for key, value := range staleInput {
replanned[key] = value
}
replanKey := modelTestID(6405)
replanned["request_id"], replanned["expected_versions"] = replanKey, read().Versions
childRun := call("POST", base(child)+"/ai/runs", replanned, 202, read().Versions[child], replanKey)
execute(childRun["run_id"].(string))
beforeLateCancel := read()
lateKey := modelTestID(6406)
lateCancel := call("POST", base(child)+"/ai/runs/"+childRun["run_id"].(string)+"/cancel", response{"protocol_version": 2, "request_id": lateKey, "operation_id": modelTestID(6407)}, 200, 0, lateKey)
if lateCancel["run_status"] != "succeeded" || !modelEqual(beforeLateCancel, read()) {
t.Fatal("late cancellation pretended to undo a completed result")
}
if read().Elements[imageID]["ownerCanvasId"] != child {
t.Fatal("child result moved its target back")
}