Repository: kurtosis-tech/kurtosis
Pull request #301 (2023-03-22 16:48:47)

feat!: This is a breaking change where we are removing the ExecRecipe.service_name, GetHttpRequestRecipe.service_name, and PostHttpRequestRecipe.service_name fields, we suggest users pass this value as an argument in the exec, request and wait instructions where this type is currently used. We are also deprecating the previous exec, request, and wait instructions signature that haven't the service_name field, users must add this field on these instructions call. Another change is that now the service_name field on the exec, request, and wait instructions is mandatory
Description:
feat: Added ReadyConditions type which is used in ServiceConfig for defining how to check services readiness

Is this change user-facing?
YES

References (if applicable):
Fixes https://github.com/kurtosis-tech/kurtosis-private/issues/740

cloudflare-pages[bot]: ## Deploying with &nbsp;<a href="https://pages.dev"><img alt="Cloudflare Pages" src="https://user-images.githubusercontent.com/23264/106598434-9e719e00-654f-11eb-9e59-6167043cfa01.png" width="16"></a> &nbsp;Cloudflare Pages

<table><tr><td><strong>Latest commit:</strong> </td><td>
<code>64f7e68</code>
</td></tr>
<tr><td><strong>Status:</strong></td><td>⚡️&nbsp; Build in progress...</td></tr>
</table>

[View logs](https://dash.cloudflare.com/?to=/:account/pages/view/kurtosis-docs/b261cbbe-4b9e-496c-aaf5-25f73e45f8f8)


Patch:
diff --git a/api/golang/core/kurtosis_core_rpc_api_bindings/api_container_service.pb.go b/api/golang/core/kurtosis_core_rpc_api_bindings/api_container_service.pb.go
index 511881f9c..1d86b68ad 100644
--- a/api/golang/core/kurtosis_core_rpc_api_bindings/api_container_service.pb.go
+++ b/api/golang/core/kurtosis_core_rpc_api_bindings/api_container_service.pb.go
@@ -3737,141 +3737,140 @@ var file_api_container_service_proto_rawDesc = []byte{
 	0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x46, 0x69,
 	0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x41,
 	0x6e, 0x64, 0x55, 0x75, 0x69, 0x64, 0x52, 0x11, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65,
-	0x73, 0x41, 0x6e, 0x64, 0x55, 0x75, 0x69, 0x64, 0x73, 0x32, 0xf9, 0x0f, 0x0a, 0x13, 0x41, 0x70,
-	0x69, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
-	0x65, 0x12, 0x6d, 0x0a, 0x11, 0x52, 0x75, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x6c, 0x61, 0x72, 0x6b,
-	0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x28, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e,
-	0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x75, 0x6e, 0x53, 0x74,
-	0x61, 0x72, 0x6c, 0x61, 0x72, 0x6b, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x41, 0x72, 0x67, 0x73,
-	0x1a, 0x2a, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
-	0x5f, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x6c, 0x61, 0x72, 0x6b, 0x52, 0x75, 0x6e,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4c, 0x69, 0x6e, 0x65, 0x22, 0x00, 0x30, 0x01,
-	0x12, 0x6f, 0x0a, 0x12, 0x52, 0x75, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x6c, 0x61, 0x72, 0x6b, 0x50,
-	0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x29, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e,
-	0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x75, 0x6e, 0x53, 0x74,
-	0x61, 0x72, 0x6c, 0x61, 0x72, 0x6b, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x41, 0x72, 0x67,
-	0x73, 0x1a, 0x2a, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
-	0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x6c, 0x61, 0x72, 0x6b, 0x52, 0x75,
-	0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4c, 0x69, 0x6e, 0x65, 0x22, 0x00, 0x30,
-	0x01, 0x12, 0x61, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
-	0x65, 0x73, 0x12, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
-	0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76,
-	0x69, 0x63, 0x65, 0x73, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x28, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63,
-	0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x61,
-	0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69,
-	0x63, 0x65, 0x73, 0x12, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69,
-	0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69,
-	0x63, 0x65, 0x73, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x26, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f,
-	0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x53,
-	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
-	0x00, 0x12, 0x8d, 0x01, 0x0a, 0x2a, 0x47, 0x65, 0x74, 0x45, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e,
-	0x67, 0x41, 0x6e, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x53, 0x65,
-	0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73,
-	0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
-	0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x45, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63,
-	0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74,
-	0x45, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x41, 0x6e, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f,
-	0x72, 0x69, 0x63, 0x61, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e,
-	0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
-	0x00, 0x12, 0x61, 0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69,
-	0x63, 0x65, 0x12, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
-	0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x72,
-	0x76, 0x69, 0x63, 0x65, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x28, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63,
-	0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x6d,
-	0x6f, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x0b, 0x52, 0x65, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74,
-	0x69, 0x6f, 0x6e, 0x12, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69,
-	0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74,
-	0x69, 0x6f, 0x6e, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
-	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22,
-	0x00, 0x12, 0x5b, 0x0a, 0x0b, 0x45, 0x78, 0x65, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64,
-	0x12, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
-	0x5f, 0x61, 0x70, 0x69, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64,
-	0x41, 0x72, 0x67, 0x73, 0x1a, 0x26, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61,
-	0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x43, 0x6f, 0x6d,
-	0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4d,
-	0x0a, 0x0c, 0x50, 0x61, 0x75, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x23,
-	0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61,
-	0x70, 0x69, 0x2e, 0x50, 0x61, 0x75, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41,
-	0x72, 0x67, 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x51, 0x0a,
-	0x0e, 0x55, 0x6e, 0x70, 0x61, 0x75, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12,
-	0x25, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f,
-	0x61, 0x70, 0x69, 0x2e, 0x55, 0x6e, 0x70, 0x61, 0x75, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69,
+	0x73, 0x41, 0x6e, 0x64, 0x55, 0x75, 0x69, 0x64, 0x73, 0x32, 0xf9, 0x0f, 0x0a,
+	0x13, 0x41, 0x70, 0x69, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x65, 0x72,
+	0x76, 0x69, 0x63, 0x65, 0x12, 0x6d, 0x0a, 0x11, 0x52, 0x75, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x6c,
+	0x61, 0x72, 0x6b, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x28, 0x2e, 0x61, 0x70, 0x69, 0x5f,
+	0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x75,
+	0x6e, 0x53, 0x74, 0x61, 0x72, 0x6c, 0x61, 0x72, 0x6b, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x41,
+	0x72, 0x67, 0x73, 0x1a, 0x2a, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69,
+	0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x6c, 0x61, 0x72, 0x6b,
+	0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4c, 0x69, 0x6e, 0x65, 0x22,
+	0x00, 0x30, 0x01, 0x12, 0x6f, 0x0a, 0x12, 0x52, 0x75, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x6c, 0x61,
+	0x72, 0x6b, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x29, 0x2e, 0x61, 0x70, 0x69, 0x5f,
+	0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x75,
+	0x6e, 0x53, 0x74, 0x61, 0x72, 0x6c, 0x61, 0x72, 0x6b, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65,
+	0x41, 0x72, 0x67, 0x73, 0x1a, 0x2a, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61,
+	0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x6c, 0x61, 0x72,
+	0x6b, 0x52, 0x75, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4c, 0x69, 0x6e, 0x65,
+	0x22, 0x00, 0x30, 0x01, 0x12, 0x61, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x65, 0x72,
+	0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74,
+	0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53,
+	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x28, 0x2e, 0x61, 0x70,
+	0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e,
+	0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x53, 0x65,
+	0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e,
+	0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65,
+	0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x26, 0x2e, 0x61, 0x70, 0x69,
+	0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x47,
+	0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x22, 0x00, 0x12, 0x8d, 0x01, 0x0a, 0x2a, 0x47, 0x65, 0x74, 0x45, 0x78, 0x69, 0x73,
+	0x74, 0x69, 0x6e, 0x67, 0x41, 0x6e, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61,
+	0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69,
+	0x65, 0x72, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x45, 0x2e, 0x61, 0x70,
+	0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e,
+	0x47, 0x65, 0x74, 0x45, 0x78, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x41, 0x6e, 0x64, 0x48, 0x69,
+	0x73, 0x74, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49,
+	0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x22, 0x00, 0x12, 0x61, 0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65,
+	0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74,
+	0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65,
+	0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x28, 0x2e, 0x61, 0x70,
+	0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e,
+	0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x0b, 0x52, 0x65, 0x70, 0x61, 0x72,
+	0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e,
+	0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x70, 0x61, 0x72,
+	0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
+	0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70,
+	0x74, 0x79, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x0b, 0x45, 0x78, 0x65, 0x63, 0x43, 0x6f, 0x6d, 0x6d,
+	0x61, 0x6e, 0x64, 0x12, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69,
+	0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x43, 0x6f, 0x6d, 0x6d,
+	0x61, 0x6e, 0x64, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x26, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f,
+	0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x45, 0x78, 0x65, 0x63,
+	0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
+	0x00, 0x12, 0x4d, 0x0a, 0x0c, 0x50, 0x61, 0x75, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x12, 0x23, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
+	0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x75, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69,
 	0x63, 0x65, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
 	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00,
-	0x12, 0x79, 0x0a, 0x22, 0x57, 0x61, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x48, 0x74, 0x74, 0x70, 0x47,
-	0x65, 0x74, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61,
-	0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x39, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e,
-	0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x57, 0x61, 0x69, 0x74, 0x46,
-	0x6f, 0x72, 0x48, 0x74, 0x74, 0x70, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e,
+	0x12, 0x51, 0x0a, 0x0e, 0x55, 0x6e, 0x70, 0x61, 0x75, 0x73, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69,
+	0x63, 0x65, 0x12, 0x25, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
+	0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x6e, 0x70, 0x61, 0x75, 0x73, 0x65, 0x53, 0x65,
+	0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
+	0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74,
+	0x79, 0x22, 0x00, 0x12, 0x79, 0x0a, 0x22, 0x57, 0x61, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x48, 0x74,
+	0x74, 0x70, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x41, 0x76, 0x61,
+	0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x39, 0x2e, 0x61, 0x70, 0x69, 0x5f,
+	0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x57, 0x61,
+	0x69, 0x74, 0x46, 0x6f, 0x72, 0x48, 0x74, 0x74, 0x70, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x64, 0x70,
+	0x6f, 0x69, 0x6e, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79,
+	0x41, 0x72, 0x67, 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x7b,
+	0x0a, 0x23, 0x57, 0x61, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x48, 0x74, 0x74, 0x70, 0x50, 0x6f, 0x73,
+	0x74, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62,
+	0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x3a, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74,
+	0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x57, 0x61, 0x69, 0x74, 0x46, 0x6f,
+	0x72, 0x48, 0x74, 0x74, 0x70, 0x50, 0x6f, 0x73, 0x74, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e,
 	0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x41, 0x72, 0x67,
 	0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x7b, 0x0a, 0x23, 0x57,
-	0x61, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x48, 0x74, 0x74, 0x70, 0x50, 0x6f, 0x73, 0x74, 0x45, 0x6e,
-	0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69,
-	0x74, 0x79, 0x12, 0x3a, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
-	0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x57, 0x61, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x48, 0x74,
-	0x74, 0x70, 0x50, 0x6f, 0x73, 0x74, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x41, 0x76,
-	0x61, 0x69, 0x6c, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x16,
-	0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
-	0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x13, 0x55, 0x70, 0x6c, 0x6f,
-	0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12,
-	0x2a, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f,
-	0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41,
-	0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x2e, 0x2e, 0x61, 0x70,
-	0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e,
-	0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66,
-	0x61, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x79, 0x0a,
-	0x15, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x72,
-	0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x2c, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e,
-	0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c,
-	0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74,
-	0x41, 0x72, 0x67, 0x73, 0x1a, 0x30, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61,
-	0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61,
-	0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x79, 0x0a, 0x15, 0x53, 0x74, 0x6f, 0x72,
-	0x65, 0x57, 0x65, 0x62, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63,
-	0x74, 0x12, 0x2c, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
-	0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x57, 0x65, 0x62, 0x46, 0x69,
-	0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x41, 0x72, 0x67, 0x73, 0x1a,
-	0x30, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f,
-	0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x57, 0x65, 0x62, 0x46, 0x69, 0x6c, 0x65,
-	0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x22, 0x00, 0x12, 0x91, 0x01, 0x0a, 0x1d, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x69, 0x6c,
-	0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x53, 0x65,
-	0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x34, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74,
-	0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x46,
-	0x69, 0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x46, 0x72, 0x6f, 0x6d,
-	0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x38, 0x2e, 0x61, 0x70,
-	0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e,
-	0x53, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61,
-	0x63, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x94, 0x01, 0x0a, 0x1e, 0x52, 0x65, 0x6e, 0x64,
-	0x65, 0x72, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x54, 0x6f, 0x46, 0x69, 0x6c,
-	0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x35, 0x2e, 0x61, 0x70, 0x69,
-	0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x52,
+	0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x13, 0x55,
+	0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61,
+	0x63, 0x74, 0x12, 0x2a, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
+	0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c,
+	0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x2e,
+	0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61,
+	0x70, 0x69, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x72,
+	0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
+	0x12, 0x79, 0x0a, 0x15, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65,
+	0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x2c, 0x2e, 0x61, 0x70, 0x69, 0x5f,
+	0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x6f,
+	0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66,
+	0x61, 0x63, 0x74, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x30, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f,
+	0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x6f, 0x77, 0x6e,
+	0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63,
+	0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x79, 0x0a, 0x15, 0x53,
+	0x74, 0x6f, 0x72, 0x65, 0x57, 0x65, 0x62, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69,
+	0x66, 0x61, 0x63, 0x74, 0x12, 0x2c, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61,
+	0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x57, 0x65,
+	0x62, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x41, 0x72,
+	0x67, 0x73, 0x1a, 0x30, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
+	0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x57, 0x65, 0x62, 0x46,
+	0x69, 0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x91, 0x01, 0x0a, 0x1d, 0x53, 0x74, 0x6f, 0x72, 0x65,
+	0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x46, 0x72, 0x6f,
+	0x6d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x34, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63,
+	0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x6f,
+	0x72, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x46,
+	0x72, 0x6f, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x38,
+	0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61,
+	0x70, 0x69, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x72, 0x74,
+	0x69, 0x66, 0x61, 0x63, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x94, 0x01, 0x0a, 0x1e, 0x52,
 	0x65, 0x6e, 0x64, 0x65, 0x72, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x54, 0x6f,
-	0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x41, 0x72, 0x67,
-	0x73, 0x1a, 0x39, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
-	0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x54, 0x65, 0x6d, 0x70,
-	0x6c, 0x61, 0x74, 0x65, 0x73, 0x54, 0x6f, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69,
+	0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x35, 0x2e,
+	0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70,
+	0x69, 0x2e, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65,
+	0x73, 0x54, 0x6f, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74,
+	0x41, 0x72, 0x67, 0x73, 0x1a, 0x39, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61,
+	0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x54,
+	0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x54, 0x6f, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69,
 	0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x75,
-	0x0a, 0x1e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66,
-	0x61, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x41, 0x6e, 0x64, 0x55, 0x75, 0x69, 0x64, 0x73,
+	0x0a, 0x1e, 0x4c, 0x69, 0x73, 0x74,0x46, 0x69, 0x6c, 0x65, 0x73, 0x41,
+	0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x41, 0x6e, 0x64, 0x55, 0x75, 0x69, 0x64, 0x73,
 	0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
 	0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x39, 0x2e, 0x61, 0x70, 0x69, 0x5f, 0x63,
 	0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73,
 	0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x4e, 0x61,
-	0x6d, 0x65, 0x73, 0x41, 0x6e, 0x64, 0x55, 0x75, 0x69, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x52, 0x5a, 0x50, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
-	0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x75, 0x72, 0x74, 0x6f, 0x73, 0x69, 0x73, 0x2d, 0x74, 0x65, 0x63,
-	0x68, 0x2f, 0x6b, 0x75, 0x72, 0x74, 0x6f, 0x73, 0x69, 0x73, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67,
-	0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x6b, 0x75, 0x72, 0x74, 0x6f,
-	0x73, 0x69, 0x73, 0x5f, 0x63, 0x6f, 0x72, 0x65, 0x5f, 0x72, 0x70, 0x63, 0x5f, 0x61, 0x70, 0x69,
-	0x5f, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x33,
+	0x6d, 0x65, 0x73, 0x41, 0x6e, 0x64, 0x55, 0x75, 0x69, 0x64, 0x73,0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
+	0x00, 0x42, 0x52, 0x5a, 0x50, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+	0x6b, 0x75, 0x72, 0x74, 0x6f, 0x73, 0x69, 0x73, 0x2d, 0x74, 0x65, 0x63, 0x68, 0x2f, 0x6b, 0x75,
+	0x72, 0x74, 0x6f, 0x73, 0x69, 0x73, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e,
+	0x67, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x6b, 0x75, 0x72, 0x74, 0x6f, 0x73, 0x69, 0x73, 0x5f,
+	0x63, 0x6f, 0x72, 0x65, 0x5f, 0x72, 0x70, 0x63, 0x5f, 0x61, 0x70, 0x69, 0x5f, 0x62, 0x69, 0x6e,
+	0x64, 0x69, 0x6e, 0x67, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
diff --git a/core/server/.golangci.yml b/core/server/.golangci.yml
index 49142043a..a9c0846b4 100644
--- a/core/server/.golangci.yml
+++ b/core/server/.golangci.yml
@@ -2,6 +2,9 @@ issues:
   exclude-rules:
     - path: "api_container/server/api_container_service.go"
       text: "SA4023"
+    - path: "api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/"
+      linters:
+        - exhaustruct
 
 linters-settings:
   staticcheck:
diff --git a/core/server/api_container/server/service_network/default_service_network.go b/core/server/api_container/server/service_network/default_service_network.go
index 7c2753d38..72e1ed545 100644
--- a/core/server/api_container/server/service_network/default_service_network.go
+++ b/core/server/api_container/server/service_network/default_service_network.go
@@ -343,6 +343,7 @@ func (network *DefaultServiceNetwork) StartService(
 	serviceConfigMap := map[service.ServiceName]*kurtosis_core_rpc_api_bindings.ServiceConfig{
 		serviceName: serviceConfig,
 	}
+
 	startedServices, serviceFailed, err := network.StartServices(ctx, serviceConfigMap, singleServiceStartupBatch)
 	if err != nil {
 		return nil, err
diff --git a/core/server/api_container/server/service_network/mock_service_network.go b/core/server/api_container/server/service_network/mock_service_network.go
index 7a6e8b3c1..acb36cde9 100644
--- a/core/server/api_container/server/service_network/mock_service_network.go
+++ b/core/server/api_container/server/service_network/mock_service_network.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.20.0. DO NOT EDIT.
+// Code generated by mockery v2.20.2. DO NOT EDIT.
 
 package service_network
 
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_builtins.go b/core/server/api_container/server/startosis_engine/kurtosis_builtins.go
index 67899f15d..a857101c3 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_builtins.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_builtins.go
@@ -90,5 +90,6 @@ func KurtosisTypeConstructors() []*starlark.Builtin {
 		starlark.NewBuiltin(port_spec.PortSpecTypeName, port_spec.NewPortSpecType().CreateBuiltin()),
 		starlark.NewBuiltin(service_config.ServiceConfigTypeName, service_config.NewServiceConfigType().CreateBuiltin()),
 		starlark.NewBuiltin(update_service_config.UpdateServiceConfigTypeName, update_service_config.NewUpdateServiceConfigType().CreateBuiltin()),
+		starlark.NewBuiltin(service_config.ReadyConditionsTypeName, service_config.NewReadyConditionsType().CreateBuiltin()),
 	}
 }
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_service.go b/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_service.go
index 947ad91f1..2f8ff90fa 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_service.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_service.go
@@ -46,7 +46,7 @@ func NewAddService(serviceNetwork service_network.ServiceNetwork, runtimeValueSt
 					Validator: func(value starlark.Value) *startosis_errors.InterpretationError {
 						// we just try to convert the configs here to validate their shape, to avoid code duplication
 						// with Interpret
-						if _, err := validateAndConvertConfig(value); err != nil {
+						if _, _, err := validateAndConvertConfigAndReadyConditions(value); err != nil {
 							return err
 						}
 						return nil
@@ -63,7 +63,8 @@ func NewAddService(serviceNetwork service_network.ServiceNetwork, runtimeValueSt
 				serviceName:   "",  // populated at interpretation time
 				serviceConfig: nil, // populated at interpretation time
 
-				resultUuid: "", // populated at interpretation time
+				resultUuid:      "",  // populated at interpretation time
+				readyConditions: nil, // populated at interpretation time
 			}
 		},
 
@@ -78,8 +79,9 @@ type AddServiceCapabilities struct {
 	serviceNetwork    service_network.ServiceNetwork
 	runtimeValueStore *runtime_value_store.RuntimeValueStore
 
-	serviceName   service.ServiceName
-	serviceConfig *kurtosis_core_rpc_api_bindings.ServiceConfig
+	serviceName     service.ServiceName
+	serviceConfig   *kurtosis_core_rpc_api_bindings.ServiceConfig
+	readyConditions *service_config.ReadyConditions
 
 	resultUuid string
 }
@@ -94,17 +96,19 @@ func (builtin *AddServiceCapabilities) Interpret(arguments *builtin_argument.Arg
 	if err != nil {
 		return nil, startosis_errors.WrapWithInterpretationError(err, "Unable to extract value for '%s' argument", ServiceConfigArgName)
 	}
-	apiServiceConfig, interpretationErr := validateAndConvertConfig(serviceConfig)
+	apiServiceConfig, readyConditions, interpretationErr := validateAndConvertConfigAndReadyConditions(serviceConfig)
 	if interpretationErr != nil {
 		return nil, interpretationErr
 	}
 
 	builtin.serviceName = service.ServiceName(serviceName.GoString())
 	builtin.serviceConfig = apiServiceConfig
+	builtin.readyConditions = readyConditions
 	builtin.resultUuid, err = builtin.runtimeValueStore.CreateValue()
 	if err != nil {
 		return nil, startosis_errors.WrapWithInterpretationError(err, "Unable to create runtime value to hold '%v' command return values", AddServiceBuiltinName)
 	}
+
 	returnValue, interpretationErr := makeAddServiceInterpretationReturnValue(builtin.serviceConfig, builtin.resultUuid)
 	if interpretationErr != nil {
 		return nil, interpretationErr
@@ -129,19 +133,38 @@ func (builtin *AddServiceCapabilities) Execute(ctx context.Context, _ *builtin_a
 	if err != nil {
 		return "", stacktrace.Propagate(err, "Unexpected error occurred starting service '%s'", replacedServiceName)
 	}
+
+	if err := runServiceReadinessCheck(
+		ctx,
+		builtin.serviceNetwork,
+		builtin.runtimeValueStore,
+		replacedServiceName,
+		builtin.readyConditions,
+	); err != nil {
+		return "", stacktrace.Propagate(err, "An error occurred while checking if service '%v' is ready", replacedServiceName)
+	}
+
 	fillAddServiceReturnValueWithRuntimeValues(startedService, builtin.resultUuid, builtin.runtimeValueStore)
 	instructionResult := fmt.Sprintf("Service '%s' added with service UUID '%s'", replacedServiceName, startedService.GetRegistration().GetUUID())
 	return instructionResult, nil
 }
 
-func validateAndConvertConfig(rawConfig starlark.Value) (*kurtosis_core_rpc_api_bindings.ServiceConfig, *startosis_errors.InterpretationError) {
+func validateAndConvertConfigAndReadyConditions(
+	rawConfig starlark.Value,
+) (*kurtosis_core_rpc_api_bindings.ServiceConfig, *service_config.ReadyConditions, *startosis_errors.InterpretationError) {
 	config, ok := rawConfig.(*service_config.ServiceConfig)
 	if !ok {
-		return nil, startosis_errors.NewInterpretationError("The '%s' argument is not a ServiceConfig (was '%s').", ConfigsArgName, reflect.TypeOf(rawConfig))
+		return nil, nil, startosis_errors.NewInterpretationError("The '%s' argument is not a ServiceConfig (was '%s').", ConfigsArgName, reflect.TypeOf(rawConfig))
 	}
 	apiServiceConfig, interpretationErr := config.ToKurtosisType()
 	if interpretationErr != nil {
-		return nil, interpretationErr
+		return nil, nil, interpretationErr
 	}
-	return apiServiceConfig, nil
+
+	readyConditions, interpretationErr := config.GetReadyConditions()
+	if interpretationErr != nil {
+		return nil, nil, interpretationErr
+	}
+
+	return apiServiceConfig, readyConditions, nil
 }
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_service_shared.go b/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_service_shared.go
index dd9b5bd7c..7ceaf43fe 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_service_shared.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_service_shared.go
@@ -1,19 +1,25 @@
 package add_service
 
 import (
+	"context"
 	"fmt"
 	"github.com/kurtosis-tech/kurtosis/api/golang/core/kurtosis_core_rpc_api_bindings"
 	"github.com/kurtosis-tech/kurtosis/api/golang/core/lib/services"
 	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service"
+	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/service_network"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/service_network/partition_topology"
+	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/shared_helpers"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/shared_helpers/magic_string_helper"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_types"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_types/port_spec"
+	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_types/service_config"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/runtime_value_store"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_errors"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_validator"
 	"github.com/kurtosis-tech/stacktrace"
+	"github.com/sirupsen/logrus"
 	"go.starlark.net/starlark"
+	"time"
 )
 
 const (
@@ -130,3 +136,82 @@ func replaceMagicStrings(
 
 	return service.ServiceName(serviceNameStr), serviceConfigBuilder.Build(), nil
 }
+
+func runServiceReadinessCheck(
+	ctx context.Context,
+	serviceNetwork service_network.ServiceNetwork,
+	runtimeValueStore *runtime_value_store.RuntimeValueStore,
+	serviceName service.ServiceName,
+	readyConditions *service_config.ReadyConditions,
+) error {
+	if readyConditions != nil {
+
+		recipe, intepretationErr := readyConditions.GetRecipe()
+		if intepretationErr != nil {
+			return stacktrace.Propagate(intepretationErr, "An error occurred getting the recipe value from ready conditions '%v'", readyConditions)
+		}
+
+		field, intepretationErr := readyConditions.GetField()
+		if intepretationErr != nil {
+			return stacktrace.Propagate(intepretationErr, "An error occurred getting the field value from ready conditions '%v'", readyConditions)
+		}
+
+		assertion, intepretationErr := readyConditions.GetAssertion()
+		if intepretationErr != nil {
+			return stacktrace.Propagate(intepretationErr, "An error occurred getting the assertion value from ready conditions '%v'", readyConditions)
+		}
+
+		target, intepretationErr := readyConditions.GetTarget()
+		if intepretationErr != nil {
+			return stacktrace.Propagate(intepretationErr, "An error occurred getting the target value from ready conditions '%v'", readyConditions)
+		}
+
+		interval, intepretationErr := readyConditions.GetInterval()
+		if intepretationErr != nil {
+			return stacktrace.Propagate(intepretationErr, "An error occurred getting the interval value from ready conditions '%v'", readyConditions)
+		}
+
+		timeout, intepretationErr := readyConditions.GetTimeout()
+		if intepretationErr != nil {
+			return stacktrace.Propagate(intepretationErr, "An error occurred getting the timeout value from ready conditions '%v'", readyConditions)
+		}
+
+		startTime := time.Now()
+		logrus.Infof("Checking service readiness for '%s' at '%v'", serviceName, startTime) //TODO change to debug
+		lastResult, tries, err := shared_helpers.ExecuteServiceAssertionWithRecipe(
+			ctx,
+			serviceNetwork,
+			runtimeValueStore,
+			serviceName,
+			recipe,
+			field,
+			assertion,
+			target,
+			interval,
+			timeout,
+		)
+		if err != nil {
+			return stacktrace.Propagate(
+				err,
+				"An error occurred checking if service '%v' is ready, using "+
+					"recipe '%+v', value field '%v', assertion '%v', target '%v', interval '%s' and time-out '%s'.",
+				serviceName,
+				recipe,
+				field,
+				assertion,
+				target,
+				interval,
+				timeout,
+			)
+		}
+		//TODO change to debug
+		logrus.Infof("Checking if service '%v' is ready took %d tries (%v in total). "+
+			"Assertion passed with following:\n%s",
+			serviceName,
+			tries,
+			time.Since(startTime),
+			recipe.ResultMapToString(lastResult),
+		)
+	}
+	return nil
+}
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_services.go b/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_services.go
index f22bb2b26..b82850a97 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_services.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_instruction/add_service/add_services.go
@@ -14,9 +14,11 @@ import (
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_errors"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_validator"
 	"github.com/kurtosis-tech/stacktrace"
+	"github.com/sirupsen/logrus"
 	"go.starlark.net/starlark"
 	"reflect"
 	"strings"
+	"sync"
 )
 
 const (
@@ -39,7 +41,7 @@ func NewAddServices(serviceNetwork service_network.ServiceNetwork, runtimeValueS
 					Validator: func(value starlark.Value) *startosis_errors.InterpretationError {
 						// we just try to convert the configs here to validate their shape, to avoid code duplication
 						// with Interpret
-						if _, err := validateAndConvertConfigs(value); err != nil {
+						if _, _, err := validateAndConvertConfigsAndReadyConditions(value); err != nil {
 							return err
 						}
 						return nil
@@ -55,7 +57,8 @@ func NewAddServices(serviceNetwork service_network.ServiceNetwork, runtimeValueS
 
 				serviceConfigs: nil, // populated at interpretation time
 
-				resultUuids: map[service.ServiceName]string{}, // populated at interpretation time
+				resultUuids:     map[service.ServiceName]string{}, // populated at interpretation time
+				readyConditions: nil,                              // populated at interpretation time
 			}
 		},
 
@@ -73,6 +76,8 @@ type AddServicesCapabilities struct {
 
 	serviceConfigs map[service.ServiceName]*kurtosis_core_rpc_api_bindings.ServiceConfig
 
+	readyConditions map[service.ServiceName]*service_config.ReadyConditions
+
 	resultUuids map[service.ServiceName]string
 }
 
@@ -81,11 +86,12 @@ func (builtin *AddServicesCapabilities) Interpret(arguments *builtin_argument.Ar
 	if err != nil {
 		return nil, startosis_errors.WrapWithInterpretationError(err, "Unable to extract value for '%s' argument", ConfigsArgName)
 	}
-	serviceConfigs, interpretationErr := validateAndConvertConfigs(ServiceConfigsDict)
+	serviceConfigs, readyConditions, interpretationErr := validateAndConvertConfigsAndReadyConditions(ServiceConfigsDict)
 	if interpretationErr != nil {
 		return nil, interpretationErr
 	}
 	builtin.serviceConfigs = serviceConfigs
+	builtin.readyConditions = readyConditions
 
 	resultUuids, returnValue, interpretationErr := makeAddServicesInterpretationReturnValue(builtin.serviceConfigs, builtin.runtimeValueStore)
 	if interpretationErr != nil {
@@ -131,6 +137,24 @@ func (builtin *AddServicesCapabilities) Execute(ctx context.Context, _ *builtin_
 		}
 		return "", stacktrace.NewError("Some errors occurred starting the following services: '%v'. The entire batch was rolled back an no service was started. Errors were: \n%v", failedServiceNames, failedServices)
 	}
+	shouldDeleteAllStartedServices := true
+
+	//TODO we should move the readiness check functionality to the default service network to improve performance
+	///TODO because we won't have to wait for all services to start for checking readiness, but first we have to
+	//TODO propagate the Recipes to this layer too and probably move the wait instruction also
+	if failedServicesChecks := builtin.allServicesReadinessCheck(ctx, startedServices, parallelism); len(failedServicesChecks) > 0 {
+		var allServiceChecksErrMsg string
+		for serviceName, serviceErr := range failedServicesChecks {
+			serviceMsg := fmt.Sprintf("Service '%v' error:\n%v\n", serviceName, serviceErr)
+			allServiceChecksErrMsg = allServiceChecksErrMsg + serviceMsg
+		}
+		return "", stacktrace.NewError("An error occurred while checking al service, these are the errors by service:\n%s", allServiceChecksErrMsg)
+	}
+	defer func() {
+		if shouldDeleteAllStartedServices {
+			builtin.removeAllStartedServices(ctx, startedServices)
+		}
+	}()
 
 	instructionResult := strings.Builder{}
 	instructionResult.WriteString(fmt.Sprintf("Successfully added the following '%d' services:", len(startedServices)))
@@ -139,39 +163,137 @@ func (builtin *AddServicesCapabilities) Execute(ctx context.Context, _ *builtin_
 		instructionResult.WriteString(fmt.Sprintf("\n  Service '%s' added with UUID '%s'", serviceName, serviceObj.GetRegistration().GetUUID()))
 
 	}
+	shouldDeleteAllStartedServices = false
 	return instructionResult.String(), nil
 }
 
-func validateAndConvertConfigs(configs starlark.Value) (map[service.ServiceName]*kurtosis_core_rpc_api_bindings.ServiceConfig, *startosis_errors.InterpretationError) {
+func (builtin *AddServicesCapabilities) removeAllStartedServices(
+	ctx context.Context,
+	startedServices map[service.ServiceName]*service.Service,
+) {
+	//this is not executed with concurrency because the remove service method locks on every call
+	for serviceName, service := range startedServices {
+		serviceIdentifier := string(service.GetRegistration().GetUUID())
+		if _, err := builtin.serviceNetwork.RemoveService(ctx, serviceIdentifier); err != nil {
+			logrus.Debugf("Something fails while started all services and we tried to remove all the  created services to rollback the process, but this one '%s' fails throwing this error: '%v', we suggest you to manually remove it", serviceName, err)
+		}
+	}
+}
+
+func (builtin *AddServicesCapabilities) allServicesReadinessCheck(
+	ctx context.Context,
+	startedServices map[service.ServiceName]*service.Service,
+	batchSize int,
+) map[service.ServiceName]error {
+	logrus.Debugf("Checking for all services readiness...")
+
+	concurrencyControlChan := make(chan bool, batchSize)
+	defer close(concurrencyControlChan)
+
+	failedServiceChecksSyncMap := &sync.Map{}
+
+	wg := &sync.WaitGroup{}
+	for serviceName := range startedServices {
+		wg.Add(1)
+		// The concurrencyControlChan will block if the buffer is currently full
+		concurrencyControlChan <- true
+		go builtin.runServiceReadinessCheck(ctx, wg, concurrencyControlChan, serviceName, failedServiceChecksSyncMap)
+	}
+	wg.Wait()
+
+	failedServiceChecksRegularMap := map[service.ServiceName]error{}
+
+	failedServiceChecksSyncMap.Range(func(serviceNameAny any, serviceErrorAny any) bool {
+		if serviceErrorAny != nil {
+			serviceName := serviceNameAny.(service.ServiceName)
+			serviceError := serviceErrorAny.(error)
+			failedServiceChecksRegularMap[serviceName] = serviceError
+		}
+		return true
+	})
+
+	logrus.Debug("All services are ready")
+
+	return failedServiceChecksRegularMap
+}
+
+func (builtin *AddServicesCapabilities) runServiceReadinessCheck(
+	ctx context.Context,
+	wg *sync.WaitGroup,
+	concurrencyControlChan chan bool,
+	serviceName service.ServiceName,
+	failedServiceChecks *sync.Map,
+) {
+	var serviceErr error
+	defer func() {
+		failedServiceChecks.Store(serviceName, serviceErr)
+		wg.Done()
+		//pop a value from the concurrencyControlChan to allow any potentially waiting subroutine to start
+		<-concurrencyControlChan
+	}()
+
+	readyConditions, found := builtin.readyConditions[serviceName]
+	if !found {
+		serviceErr = stacktrace.NewError("Expected to find ready conditions for service '%s' in map '%+v', but none was found; this is a bug in Kurtosis", serviceName, builtin.readyConditions)
+		return
+	}
+
+	if err := runServiceReadinessCheck(
+		ctx,
+		builtin.serviceNetwork,
+		builtin.runtimeValueStore,
+		serviceName,
+		readyConditions,
+	); err != nil {
+		serviceErr = stacktrace.Propagate(err, "An error occurred while checking if service '%v' is ready", serviceName)
+		return
+	}
+}
+
+func validateAndConvertConfigsAndReadyConditions(
+	configs starlark.Value,
+) (
+	map[service.ServiceName]*kurtosis_core_rpc_api_bindings.ServiceConfig,
+	map[service.ServiceName]*service_config.ReadyConditions,
+	*startosis_errors.InterpretationError,
+) {
 	configsDict, ok := configs.(*starlark.Dict)
 	if !ok {
-		return nil, startosis_errors.NewInterpretationError("The '%s' argument should be a dictionary of matching each service name to their respective ServiceConfig object. Got '%s'", ConfigsArgName, reflect.TypeOf(configs))
+		return nil, nil, startosis_errors.NewInterpretationError("The '%s' argument should be a dictionary of matching each service name to their respective ServiceConfig object. Got '%s'", ConfigsArgName, reflect.TypeOf(configs))
 	}
 	if configsDict.Len() == 0 {
-		return nil, startosis_errors.NewInterpretationError("The '%s' argument should be a non empty dictionary", ConfigsArgName)
+		return nil, nil, startosis_errors.NewInterpretationError("The '%s' argument should be a non empty dictionary", ConfigsArgName)
 	}
 	convertedServiceConfigs := map[service.ServiceName]*kurtosis_core_rpc_api_bindings.ServiceConfig{}
+	readyConditionsByServiceName := map[service.ServiceName]*service_config.ReadyConditions{}
 	for _, serviceName := range configsDict.Keys() {
 		serviceNameStr, isServiceNameAString := serviceName.(starlark.String)
 		if !isServiceNameAString {
-			return nil, startosis_errors.NewInterpretationError("One key of the '%s' dictionary is not a string (was '%s'). Keys of this argument should correspond to service names, which should be strings", ConfigsArgName, reflect.TypeOf(serviceName))
+			return nil, nil, startosis_errors.NewInterpretationError("One key of the '%s' dictionary is not a string (was '%s'). Keys of this argument should correspond to service names, which should be strings", ConfigsArgName, reflect.TypeOf(serviceName))
 		}
 
 		dictValue, found, err := configsDict.Get(serviceName)
 		if err != nil || !found {
-			return nil, startosis_errors.NewInterpretationError("Could not extract the value of the '%s' dictionary for key '%s'. This is Kurtosis bug", ConfigsArgName, serviceName)
+			return nil, nil, startosis_errors.NewInterpretationError("Could not extract the value of the '%s' dictionary for key '%s'. This is Kurtosis bug", ConfigsArgName, serviceName)
 		}
 		serviceConfig, isDictValueAServiceConfig := dictValue.(*service_config.ServiceConfig)
 		if !isDictValueAServiceConfig {
-			return nil, startosis_errors.NewInterpretationError("One value of the '%s' dictionary is not a ServiceConfig (was '%s'). Values of this argument should correspond to the config of the service to be added", ConfigsArgName, reflect.TypeOf(dictValue))
+			return nil, nil, startosis_errors.NewInterpretationError("One value of the '%s' dictionary is not a ServiceConfig (was '%s'). Values of this argument should correspond to the config of the service to be added", ConfigsArgName, reflect.TypeOf(dictValue))
 		}
 		apiServiceConfig, interpretationErr := serviceConfig.ToKurtosisType()
 		if interpretationErr != nil {
-			return nil, interpretationErr
+			return nil, nil, interpretationErr
 		}
 		convertedServiceConfigs[service.ServiceName(serviceNameStr.GoString())] = apiServiceConfig
+
+		readyConditions, interpretationErr := serviceConfig.GetReadyConditions()
+		if interpretationErr != nil {
+			return nil, nil, interpretationErr
+		}
+
+		readyConditionsByServiceName[service.ServiceName(serviceNameStr.GoString())] = readyConditions
 	}
-	return convertedServiceConfigs, nil
+	return convertedServiceConfigs, readyConditionsByServiceName, nil
 }
 
 func makeAddServicesInterpretationReturnValue(serviceConfigs map[service.ServiceName]*kurtosis_core_rpc_api_bindings.ServiceConfig, runtimeValueStore *runtime_value_store.RuntimeValueStore) (map[service.ServiceName]string, *starlark.Dict, *startosis_errors.InterpretationError) {
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_instruction/exec/exec.go b/core/server/api_container/server/startosis_engine/kurtosis_instruction/exec/exec.go
index fcd3bef1b..c02b514c4 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_instruction/exec/exec.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_instruction/exec/exec.go
@@ -4,7 +4,6 @@ import (
 	"context"
 	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/service_network"
-	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/shared_helpers"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/builtin_argument"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/kurtosis_plan_instruction"
@@ -14,7 +13,6 @@ import (
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_errors"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_validator"
 	"github.com/kurtosis-tech/stacktrace"
-	"github.com/sirupsen/logrus"
 	"go.starlark.net/starlark"
 )
 
@@ -48,7 +46,7 @@ func NewExec(serviceNetwork service_network.ServiceNetwork, runtimeValueStore *r
 				},
 				{
 					Name:              ServiceNameArgName,
-					IsOptional:        true, //TODO make it non-optional when we remove recipe.service_name, issue pending: https://github.com/kurtosis-tech/kurtosis-private/issues/1128
+					IsOptional:        false,
 					ZeroValueProvider: builtin_argument.ZeroValueProvider[starlark.String],
 					Validator: func(value starlark.Value) *startosis_errors.InterpretationError {
 						return builtin_argument.NonEmptyString(value, ServiceNameArgName)
@@ -100,23 +98,16 @@ type ExecCapabilities struct {
 }
 
 func (builtin *ExecCapabilities) Interpret(arguments *builtin_argument.ArgumentValuesSet) (starlark.Value, *startosis_errors.InterpretationError) {
-	execRecipe, err := builtin_argument.ExtractArgumentValue[*recipe.ExecRecipe](arguments, RecipeArgName)
+
+	serviceNameArgumentValue, err := builtin_argument.ExtractArgumentValue[starlark.String](arguments, ServiceNameArgName)
 	if err != nil {
-		return nil, startosis_errors.WrapWithInterpretationError(err, "Unable to extract value for '%s' argument", RecipeArgName)
+		return nil, startosis_errors.WrapWithInterpretationError(err, "Unable to extract value for '%s' argument", ServiceNameArgName)
 	}
+	serviceName := service.ServiceName(serviceNameArgumentValue.GoString())
 
-	var serviceName service.ServiceName
-	if arguments.IsSet(ServiceNameArgName) {
-		serviceNameArgumentValue, err := builtin_argument.ExtractArgumentValue[starlark.String](arguments, ServiceNameArgName)
-		if err != nil {
-			return nil, startosis_errors.WrapWithInterpretationError(err, "Unable to extract value for '%s' argument", ServiceNameArgName)
-		}
-		serviceName = service.ServiceName(serviceNameArgumentValue.GoString())
-	} else if execRecipe.GetServiceName() != shared_helpers.EmptyServiceName {
-		serviceName = execRecipe.GetServiceName()
-		logrus.Warnf("The recipe.service_name field will be deprecated soon, users will have to pass the service name value direclty to the 'exec', 'request' and 'wait' instructions")
-	} else {
-		return nil, startosis_errors.NewInterpretationError("Service name is not set, either as an exec instruction's argument or as a recipe field. You can fix it passing the 'service_name' argument in the 'exec' call")
+	execRecipe, err := builtin_argument.ExtractArgumentValue[*recipe.ExecRecipe](arguments, RecipeArgName)
+	if err != nil {
+		return nil, startosis_errors.WrapWithInterpretationError(err, "Unable to extract value for '%s' argument", RecipeArgName)
 	}
 
 	acceptableCodes := defaultAcceptableCodes
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_instruction/request/request.go b/core/server/api_container/server/startosis_engine/kurtosis_instruction/request/request.go
index 440ad6723..a965f2af7 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_instruction/request/request.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_instruction/request/request.go
@@ -4,7 +4,6 @@ import (
 	"context"
 	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/service_network"
-	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/shared_helpers"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/builtin_argument"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/kurtosis_plan_instruction"
@@ -14,7 +13,6 @@ import (
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_errors"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_validator"
 	"github.com/kurtosis-tech/stacktrace"
-	"github.com/sirupsen/logrus"
 	"go.starlark.net/starlark"
 	"net/http"
 )
@@ -59,7 +57,7 @@ func NewRequest(serviceNetwork service_network.ServiceNetwork, runtimeValueStore
 				},
 				{
 					Name:              ServiceNameArgName,
-					IsOptional:        true, //TODO make it non-optional when we remove recipe.service_name, issue pending: https://github.com/kurtosis-tech/kurtosis-private/issues/1128
+					IsOptional:        false,
 					ZeroValueProvider: builtin_argument.ZeroValueProvider[starlark.String],
 					Validator: func(value starlark.Value) *startosis_errors.InterpretationError {
 						return builtin_argument.NonEmptyString(value, ServiceNameArgName)
@@ -111,6 +109,13 @@ type RequestCapabilities struct {
 }
 
 func (builtin *RequestCapabilities) Interpret(arguments *builtin_argument.ArgumentValuesSet) (starlark.Value, *startosis_errors.InterpretationError) {
+
+	serviceNameArgumentValue, err := builtin_argument.ExtractArgumentValue[starlark.String](arguments, ServiceNameArgName)
+	if err != nil {
+		return nil, startosis_errors.WrapWithInterpretationError(err, "Unable to extract value for '%s' argument", ServiceNameArgName)
+	}
+	serviceName := service.ServiceName(serviceNameArgumentValue.GoString())
+
 	httpRequestRecipe, err := builtin_argument.ExtractArgumentValue[*recipe.HttpRequestRecipe](arguments, RecipeArgName)
 	if err != nil {
 		return nil, startosis_errors.WrapWithInterpretationError(err, "Unable to extract value for '%s' argument", RecipeArgName)
@@ -128,20 +133,6 @@ func (builtin *RequestCapabilities) Interpret(arguments *builtin_argument.Argume
 		}
 	}
 
-	var serviceName service.ServiceName
-	if arguments.IsSet(ServiceNameArgName) {
-		serviceNameArgumentValue, err := builtin_argument.ExtractArgumentValue[starlark.String](arguments, ServiceNameArgName)
-		if err != nil {
-			return nil, startosis_errors.WrapWithInterpretationError(err, "Unable to extract value for '%s' argument", ServiceNameArgName)
-		}
-		serviceName = service.ServiceName(serviceNameArgumentValue.GoString())
-	} else if httpRequestRecipe.GetServiceName() != shared_helpers.EmptyServiceName {
-		serviceName = httpRequestRecipe.GetServiceName()
-		logrus.Warnf("The recipe.service_name field will be deprecated soon, users will have to pass the service name value direclty to the 'exec', 'request' and 'wait' instructions")
-	} else {
-		return nil, startosis_errors.NewInterpretationError("Service name is not set, either as a request instruction's argument or as a recipe field. You can fix it passing the 'service_name' argument in the 'request' call")
-	}
-
 	skipCodeCheck := defaultSkipCodeCheck
 	if arguments.IsSet(SkipCodeCheckArgName) {
 		skipCodeCheckArgumentValue, err := builtin_argument.ExtractArgumentValue[starlark.Bool](arguments, SkipCodeCheckArgName)
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_instruction/shared_helpers/service_helpers.go b/core/server/api_container/server/startosis_engine/kurtosis_instruction/shared_helpers/service_helpers.go
new file mode 100644
index 000000000..23ee2d5f2
--- /dev/null
+++ b/core/server/api_container/server/startosis_engine/kurtosis_instruction/shared_helpers/service_helpers.go
@@ -0,0 +1,71 @@
+package shared_helpers
+
+import (
+	"context"
+	"github.com/cenkalti/backoff/v4"
+	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service"
+	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/service_network"
+	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/assert"
+	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/recipe"
+	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/runtime_value_store"
+	"github.com/kurtosis-tech/stacktrace"
+	"go.starlark.net/starlark"
+	"time"
+)
+
+func ExecuteServiceAssertionWithRecipe(
+	ctx context.Context,
+	serviceNetwork service_network.ServiceNetwork,
+	runtimeValueStore *runtime_value_store.RuntimeValueStore,
+	serviceName service.ServiceName,
+	recipe recipe.Recipe,
+	valueField string,
+	assertion string,
+	target starlark.Comparable,
+	interval time.Duration,
+	timeout time.Duration,
+) (map[string]starlark.Comparable, int, error) {
+	var requestErr error
+	var assertErr error
+	tries := 0
+	timedOut := false
+	lastResult := map[string]starlark.Comparable{}
+	startTime := time.Now()
+
+	backoffObj := backoff.NewConstantBackOff(interval)
+
+	//TODO check if we can refactor this portion in order to use the time.Ticker(backoffDuration) pattern here:
+	for {
+		tries += 1
+		backoffDuration := backoffObj.NextBackOff()
+		if backoffDuration == backoff.Stop || time.Since(startTime) > timeout {
+			timedOut = true
+			break
+		}
+		lastResult, requestErr = recipe.Execute(ctx, serviceNetwork, runtimeValueStore, serviceName)
+		if requestErr != nil {
+			time.Sleep(backoffDuration)
+			continue
+		}
+		value, found := lastResult[valueField]
+		if !found {
+			return lastResult, tries, stacktrace.NewError("Error extracting value from key '%v'", valueField)
+		}
+		assertErr = assert.Assert(value, assertion, target)
+		if assertErr == nil {
+			break
+		}
+		time.Sleep(backoffDuration)
+	}
+	if timedOut {
+		return lastResult, tries, stacktrace.NewError("Recipe execution timed-out waiting for the assertion to become valid on service '%v'. Waited for '%v'. Last assertion error was: \n%v", serviceName, time.Since(startTime), assertErr)
+	}
+	if requestErr != nil {
+		return lastResult, tries, stacktrace.Propagate(requestErr, "Error executing recipe on service '%v'", serviceName)
+	}
+	if assertErr != nil {
+		return lastResult, tries, stacktrace.Propagate(assertErr, "Error asserting recipe on service '%v'", serviceName)
+	}
+
+	return lastResult, tries, nil
+}
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_instruction/wait/wait.go b/core/server/api_container/server/startosis_engine/kurtosis_instruction/wait/wait.go
index 429311282..008898b48 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_instruction/wait/wait.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_instruction/wait/wait.go
@@ -3,7 +3,6 @@ package wait
 import (
 	"context"
 	"fmt"
-	"github.com/cenkalti/backoff/v4"
 	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/service_network"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/assert"
@@ -16,7 +15,6 @@ import (
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_errors"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_validator"
 	"github.com/kurtosis-tech/stacktrace"
-	"github.com/sirupsen/logrus"
 	"go.starlark.net/starlark"
 	"time"
 )
@@ -80,7 +78,7 @@ func NewWait(serviceNetwork service_network.ServiceNetwork, runtimeValueStore *r
 				},
 				{
 					Name:              ServiceNameArgName,
-					IsOptional:        true, //TODO make it non-optional when we remove recipe.service_name, issue pending: https://github.com/kurtosis-tech/kurtosis-private/issues/1128
+					IsOptional:        false,
 					ZeroValueProvider: builtin_argument.ZeroValueProvider[starlark.String],
 					Validator: func(value starlark.Value) *startosis_errors.InterpretationError {
 						return builtin_argument.NonEmptyString(value, ServiceNameArgName)
@@ -99,7 +97,7 @@ func NewWait(serviceNetwork service_network.ServiceNetwork, runtimeValueStore *r
 				valueField:  "",  // populated at interpretation time
 				assertion:   "",  // populated at interpretation time
 				target:      nil, // populated at interpretation time
-				backoff:     nil, // populated at interpretation time
+				interval:    0,   // populated at interpretation time
 				timeout:     0,   // populated at interpretation time
 				resultUuid:  "",  // populated at interpretation time
 			}
@@ -125,13 +123,20 @@ type WaitCapabilities struct {
 	valueField  string
 	assertion   string
 	target      starlark.Comparable
-	backoff     backoff.BackOff
+	interval    time.Duration
 	timeout     time.Duration
 
 	resultUuid string
 }
 
 func (builtin *WaitCapabilities) Interpret(arguments *builtin_argument.ArgumentValuesSet) (starlark.Value, *startosis_errors.InterpretationError) {
+
+	serviceNameArgumentValue, err := builtin_argument.ExtractArgumentValue[starlark.String](arguments, ServiceNameArgName)
+	if err != nil {
+		return nil, startosis_errors.WrapWithInterpretationError(err, "Unable to extract value for '%s' argument", ServiceNameArgName)
+	}
+	serviceName := service.ServiceName(serviceNameArgumentValue.GoString())
+
 	var genericRecipe recipe.Recipe
 	httpRecipe, err := builtin_argument.ExtractArgumentValue[*recipe.HttpRequestRecipe](arguments, RecipeArgName)
 	if err != nil {
@@ -144,21 +149,6 @@ func (builtin *WaitCapabilities) Interpret(arguments *builtin_argument.ArgumentV
 		genericRecipe = httpRecipe
 	}
 
-	var serviceName service.ServiceName
-
-	if arguments.IsSet(ServiceNameArgName) {
-		serviceNameArgumentValue, err := builtin_argument.ExtractArgumentValue[starlark.String](arguments, ServiceNameArgName)
-		if err != nil {
-			return nil, startosis_errors.WrapWithInterpretationError(err, "Unable to extract value for '%s' argument", ServiceNameArgName)
-		}
-		serviceName = service.ServiceName(serviceNameArgumentValue.GoString())
-	} else if genericRecipe.GetServiceName() != shared_helpers.EmptyServiceName {
-		serviceName = genericRecipe.GetServiceName()
-		logrus.Warnf("The recipe.service_name field will be deprecated soon, users will have to pass the service name value direclty to the 'exec', 'request' and 'wait' instructions")
-	} else {
-		return nil, startosis_errors.NewInterpretationError("Service name is not set, either as a wait instruction's argument or as a recipe field. You can fix it passing the 'service_name' argument in the 'wait' call")
-	}
-
 	valueField, err := builtin_argument.ExtractArgumentValue[starlark.String](arguments, ValueFieldArgName)
 	if err != nil {
 		return nil, startosis_errors.WrapWithInterpretationError(err, "Unable to extract value for '%s' argument", ValueFieldArgName)
@@ -174,19 +164,19 @@ func (builtin *WaitCapabilities) Interpret(arguments *builtin_argument.ArgumentV
 		return nil, startosis_errors.WrapWithInterpretationError(err, "Unable to extract value for '%s' argument", TargetArgName)
 	}
 
-	var waitBackoff backoff.BackOff
+	var interval time.Duration
 	if arguments.IsSet(IntervalArgName) {
-		interval, err := builtin_argument.ExtractArgumentValue[starlark.String](arguments, IntervalArgName)
+		intervalStr, err := builtin_argument.ExtractArgumentValue[starlark.String](arguments, IntervalArgName)
 		if err != nil {
 			return nil, startosis_errors.WrapWithInterpretationError(err, "Unable to extract value for '%s' argument", IntervalArgName)
 		}
-		parsedDuration, parseErr := time.ParseDuration(interval.GoString())
+		parsedInterval, parseErr := time.ParseDuration(intervalStr.GoString())
 		if parseErr != nil {
-			return nil, startosis_errors.WrapWithInterpretationError(parseErr, "An error occurred when parsing interval '%v'", interval.GoString())
+			return nil, startosis_errors.WrapWithInterpretationError(parseErr, "An error occurred when parsing interval '%v'", intervalStr.GoString())
 		}
-		waitBackoff = backoff.NewConstantBackOff(parsedDuration)
+		interval = parsedInterval
 	} else {
-		waitBackoff = backoff.NewConstantBackOff(defaultInterval)
+		interval = defaultInterval
 	}
 
 	var timeout time.Duration
@@ -197,7 +187,7 @@ func (builtin *WaitCapabilities) Interpret(arguments *builtin_argument.ArgumentV
 		}
 		parsedTimeout, parseErr := time.ParseDuration(starlarkTimeout.GoString())
 		if parseErr != nil {
-			return nil, startosis_errors.WrapWithInterpretationError(parseErr, "An error occurred when parsing interval '%v'", starlarkTimeout.GoString())
+			return nil, startosis_errors.WrapWithInterpretationError(parseErr, "An error occurred when parsing timeout '%v'", starlarkTimeout.GoString())
 		}
 		timeout = parsedTimeout
 	} else {
@@ -223,7 +213,7 @@ func (builtin *WaitCapabilities) Interpret(arguments *builtin_argument.ArgumentV
 	builtin.valueField = valueField.GoString()
 	builtin.assertion = assertion.GoString()
 	builtin.target = target
-	builtin.backoff = waitBackoff
+	builtin.interval = interval
 	builtin.timeout = timeout
 	builtin.resultUuid = resultUuid
 
@@ -236,45 +226,37 @@ func (builtin *WaitCapabilities) Validate(_ *builtin_argument.ArgumentValuesSet,
 }
 
 func (builtin *WaitCapabilities) Execute(ctx context.Context, _ *builtin_argument.ArgumentValuesSet) (string, error) {
-	var requestErr error
-	var assertErr error
-	tries := 0
-	timedOut := false
-	lastResult := map[string]starlark.Comparable{}
+
 	startTime := time.Now()
-	for {
-		tries += 1
-		backoffDuration := builtin.backoff.NextBackOff()
-		if backoffDuration == backoff.Stop || time.Since(startTime) > builtin.timeout {
-			timedOut = true
-			break
-		}
-		lastResult, requestErr = builtin.recipe.Execute(ctx, builtin.serviceNetwork, builtin.runtimeValueStore, builtin.serviceName)
-		if requestErr != nil {
-			time.Sleep(backoffDuration)
-			continue
-		}
-		builtin.runtimeValueStore.SetValue(builtin.resultUuid, lastResult)
-		value, found := lastResult[builtin.valueField]
-		if !found {
-			return "", stacktrace.NewError("Error extracting value from key '%v'", builtin.valueField)
-		}
-		assertErr = assert.Assert(value, builtin.assertion, builtin.target)
-		if assertErr != nil {
-			time.Sleep(backoffDuration)
-			continue
-		}
-		break
-	}
-	if timedOut {
-		return "", stacktrace.NewError("Wait timed-out waiting for the assertion to become valid. Waited for '%v'. Last assertion error was: \n%v", time.Since(startTime), assertErr)
-	}
-	if requestErr != nil {
-		return "", stacktrace.Propagate(requestErr, "Error executing HTTP recipe on '%v'", WaitBuiltinName)
-	}
-	if assertErr != nil {
-		return "", stacktrace.Propagate(assertErr, "Error asserting HTTP recipe on '%v'", WaitBuiltinName)
+
+	lastResult, tries, err := shared_helpers.ExecuteServiceAssertionWithRecipe(
+		ctx,
+		builtin.serviceNetwork,
+		builtin.runtimeValueStore,
+		builtin.serviceName,
+		builtin.recipe,
+		builtin.valueField,
+		builtin.assertion,
+		builtin.target,
+		builtin.interval,
+		builtin.timeout,
+	)
+	if err != nil {
+		return "", stacktrace.Propagate(
+			err,
+			"An error occurred checking if service '%v' is ready.",
+			builtin.serviceName,
+		)
 	}
-	instructionResult := fmt.Sprintf("Wait took %d tries (%v in total). Assertion passed with following:\n%s", tries, time.Since(startTime), builtin.recipe.ResultMapToString(lastResult))
+
+	builtin.runtimeValueStore.SetValue(builtin.resultUuid, lastResult)
+
+	instructionResult := fmt.Sprintf(
+		"Wait took %d tries (%v in total). Assertion passed with following:\n%s",
+		tries,
+		time.Since(startTime),
+		builtin.recipe.ResultMapToString(lastResult),
+	)
+
 	return instructionResult, nil
 }
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/builtin_argument/validators.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/builtin_argument/validators.go
index 6eff28dc3..dff80b4f9 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/builtin_argument/validators.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/builtin_argument/validators.go
@@ -6,6 +6,7 @@ import (
 	"reflect"
 	"regexp"
 	"strings"
+	"time"
 )
 
 func NonEmptyString(value starlark.Value, argNameForLogging string) *startosis_errors.InterpretationError {
@@ -79,3 +80,21 @@ func StringRegexp(value starlark.Value, argNameForLogging string, mustMatchRegex
 		valueStr.GoString(),
 	)
 }
+
+func Duration(value starlark.Value, attributeName string) *startosis_errors.InterpretationError {
+	valueStarlarkStr, ok := value.(starlark.String)
+	if !ok {
+		return startosis_errors.NewInterpretationError("The '%s' attribute is not a valid string type (was '%s').", attributeName, reflect.TypeOf(value))
+	}
+
+	if valueStarlarkStr.GoString() == "" {
+		return nil
+	}
+
+	_, parseErr := time.ParseDuration(valueStarlarkStr.GoString())
+	if parseErr != nil {
+		return startosis_errors.WrapWithInterpretationError(parseErr, "The value '%v' of '%s' attribute is not a valid duration string format", valueStarlarkStr.GoString(), attributeName)
+	}
+
+	return nil
+}
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_types/service_config/ready_conditions.go b/core/server/api_container/server/startosis_engine/kurtosis_types/service_config/ready_conditions.go
new file mode 100644
index 000000000..d13c44964
--- /dev/null
+++ b/core/server/api_container/server/startosis_engine/kurtosis_types/service_config/ready_conditions.go
@@ -0,0 +1,207 @@
+package service_config
+
+import (
+	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/assert"
+	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework"
+	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/builtin_argument"
+	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/kurtosis_type_constructor"
+	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/recipe"
+	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/startosis_errors"
+	"go.starlark.net/starlark"
+	"reflect"
+	"time"
+)
+
+const (
+	ReadyConditionsTypeName = "ReadyConditions"
+
+	RecipeAttr    = "recipe"
+	FieldAttr     = "field"
+	AssertionAttr = "assertion"
+	TargetAttr    = "target_value"
+	IntervalAttr  = "interval"
+	TimeoutAttr   = "timeout"
+
+	defaultInterval = 1 * time.Second
+	defaultTimeout  = 15 * time.Minute //TODO we could move these two to the service helpers method
+)
+
+func NewReadyConditionsType() *kurtosis_type_constructor.KurtosisTypeConstructor {
+	return &kurtosis_type_constructor.KurtosisTypeConstructor{
+		KurtosisBaseBuiltin: &kurtosis_starlark_framework.KurtosisBaseBuiltin{
+			Name: ReadyConditionsTypeName,
+			Arguments: []*builtin_argument.BuiltinArgument{
+				{
+					Name:              RecipeAttr,
+					IsOptional:        false,
+					ZeroValueProvider: builtin_argument.ZeroValueProvider[starlark.Value],
+					Validator:         validateRecipe,
+				},
+				{
+					Name:              FieldAttr,
+					IsOptional:        false,
+					ZeroValueProvider: builtin_argument.ZeroValueProvider[starlark.String],
+					Validator: func(value starlark.Value) *startosis_errors.InterpretationError {
+						return builtin_argument.NonEmptyString(value, FieldAttr)
+					},
+				},
+				{
+					Name:              AssertionAttr,
+					IsOptional:        false,
+					ZeroValueProvider: builtin_argument.ZeroValueProvider[starlark.String],
+					Validator:         assert.ValidateAssertionToken,
+				},
+				{
+					Name:              TargetAttr,
+					IsOptional:        false,
+					ZeroValueProvider: builtin_argument.ZeroValueProvider[starlark.Comparable],
+					Validator: func(value starlark.Value) *startosis_errors.InterpretationError {
+						return builtin_argument.NonEmptyString(value, FieldAttr)
+					},
+				},
+				{
+					Name:              IntervalAttr,
+					IsOptional:        true,
+					ZeroValueProvider: builtin_argument.ZeroValueProvider[starlark.String],
+					Validator: func(value starlark.Value) *startosis_errors.InterpretationError {
+						return builtin_argument.Duration(value, IntervalAttr)
+					},
+				},
+				{
+					Name:              TimeoutAttr,
+					IsOptional:        true,
+					ZeroValueProvider: builtin_argument.ZeroValueProvider[starlark.String],
+					Validator: func(value starlark.Value) *startosis_errors.InterpretationError {
+						return builtin_argument.Duration(value, TimeoutAttr)
+					},
+				},
+			},
+		},
+		Instantiate: instantiateReadyConditions,
+	}
+}
+
+func instantiateReadyConditions(arguments *builtin_argument.ArgumentValuesSet) (kurtosis_type_constructor.KurtosisValueType, *startosis_errors.InterpretationError) {
+	kurtosisValueType, err := kurtosis_type_constructor.CreateKurtosisStarlarkTypeDefault(ReadyConditionsTypeName, arguments)
+	if err != nil {
+		return nil, err
+	}
+	return &ReadyConditions{
+		KurtosisValueTypeDefault: kurtosisValueType,
+	}, nil
+}
+
+// ReadyConditions is a starlark.Value that holds all the information needed for ensuring service readiness
+type ReadyConditions struct {
+	*kurtosis_type_constructor.KurtosisValueTypeDefault
+}
+
+func (readyConditions *ReadyConditions) GetRecipe() (recipe.Recipe, *startosis_errors.InterpretationError) {
+	var genericRecipe recipe.Recipe
+
+	httpRecipe, found, interpretationErr := kurtosis_type_constructor.ExtractAttrValue[*recipe.HttpRequestRecipe](readyConditions.KurtosisValueTypeDefault, RecipeAttr)
+	genericRecipe = httpRecipe
+	if !found {
+		return nil, startosis_errors.NewInterpretationError("Required attribute '%s' could not be found on type '%s'",
+			RecipeAttr, ReadyConditionsTypeName)
+	}
+	//TODO we should rework the recipe types to inherit a single common type, this will avoid the double parsing here.
+	if interpretationErr != nil {
+		execRecipe, _, interpretationErr := kurtosis_type_constructor.ExtractAttrValue[*recipe.ExecRecipe](readyConditions.KurtosisValueTypeDefault, RecipeAttr)
+		if interpretationErr != nil {
+			return nil, interpretationErr
+		}
+		genericRecipe = execRecipe
+	}
+
+	return genericRecipe, nil
+}
+
+func (readyConditions *ReadyConditions) GetField() (string, *startosis_errors.InterpretationError) {
+	field, found, interpretationErr := kurtosis_type_constructor.ExtractAttrValue[starlark.String](readyConditions.KurtosisValueTypeDefault, FieldAttr)
+	if interpretationErr != nil {
+		return "", interpretationErr
+	}
+	if !found {
+		return "", startosis_errors.NewInterpretationError("Required attribute '%s' could not be found on type '%s'",
+			FieldAttr, ReadyConditionsTypeName)
+	}
+	fieldStr := field.GoString()
+
+	return fieldStr, nil
+}
+
+func (readyConditions *ReadyConditions) GetAssertion() (string, *startosis_errors.InterpretationError) {
+	assertion, found, interpretationErr := kurtosis_type_constructor.ExtractAttrValue[starlark.String](readyConditions.KurtosisValueTypeDefault, AssertionAttr)
+	if interpretationErr != nil {
+		return "", interpretationErr
+	}
+	if !found {
+		return "", startosis_errors.NewInterpretationError("Required attribute '%s' could not be found on type '%s'",
+			AssertionAttr, ReadyConditionsTypeName)
+	}
+	assertionStr := assertion.GoString()
+
+	return assertionStr, nil
+}
+
+func (readyConditions *ReadyConditions) GetTarget() (starlark.Comparable, *startosis_errors.InterpretationError) {
+	target, found, interpretationErr := kurtosis_type_constructor.ExtractAttrValue[starlark.Comparable](readyConditions.KurtosisValueTypeDefault, TargetAttr)
+	if interpretationErr != nil {
+		return nil, interpretationErr
+	}
+	if !found {
+		return nil, startosis_errors.NewInterpretationError("Required attribute '%s' could not be found on type '%s'",
+			TargetAttr, ReadyConditionsTypeName)
+	}
+
+	return target, nil
+}
+
+func (readyConditions *ReadyConditions) GetInterval() (time.Duration, *startosis_errors.InterpretationError) {
+	interval := defaultInterval
+
+	intervalStr, found, interpretationErr := kurtosis_type_constructor.ExtractAttrValue[starlark.String](readyConditions.KurtosisValueTypeDefault, IntervalAttr)
+	if interpretationErr != nil {
+		return interval, interpretationErr
+	}
+	if found {
+		parsedInterval, parseErr := time.ParseDuration(intervalStr.GoString())
+		if parseErr != nil {
+			return interval, startosis_errors.WrapWithInterpretationError(parseErr, "An error occurred when parsing interval '%v'", intervalStr.GoString())
+		}
+		interval = parsedInterval
+	}
+
+	return interval, nil
+}
+
+func (readyConditions *ReadyConditions) GetTimeout() (time.Duration, *startosis_errors.InterpretationError) {
+	timeout := defaultTimeout
+
+	timeoutStr, found, interpretationErr := kurtosis_type_constructor.ExtractAttrValue[starlark.String](readyConditions.KurtosisValueTypeDefault, TimeoutAttr)
+	if interpretationErr != nil {
+		return timeout, interpretationErr
+	}
+	if found {
+		parsedTimeout, parseErr := time.ParseDuration(timeoutStr.GoString())
+		if parseErr != nil {
+			return timeout, startosis_errors.WrapWithInterpretationError(parseErr, "An error occurred when parsing timeout '%v'", timeoutStr.GoString())
+		}
+		timeout = parsedTimeout
+	}
+
+	return timeout, nil
+}
+
+func validateRecipe(value starlark.Value) *startosis_errors.InterpretationError {
+	_, ok := value.(*recipe.HttpRequestRecipe)
+	if !ok {
+		//TODO we should rework the recipe types to inherit a single common type, this will avoid the double parsing here.
+		_, ok := value.(*recipe.ExecRecipe)
+		if !ok {
+			return startosis_errors.NewInterpretationError("The '%s' attribute is not a Recipe (was '%s').", RecipeAttr, reflect.TypeOf(value))
+		}
+	}
+	return nil
+}
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_types/service_config/service_config.go b/core/server/api_container/server/startosis_engine/kurtosis_types/service_config/service_config.go
index 1a5a71c14..f6b76f96e 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_types/service_config/service_config.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_types/service_config/service_config.go
@@ -27,6 +27,7 @@ const (
 	SubnetworkAttr                  = "subnetwork"
 	CpuAllocationAttr               = "cpu_allocation"
 	MemoryAllocationAttr            = "memory_allocation"
+	ReadyConditionsAttr             = "ready_conditions"
 )
 
 func NewServiceConfigType() *kurtosis_type_constructor.KurtosisTypeConstructor {
@@ -111,14 +112,20 @@ func NewServiceConfigType() *kurtosis_type_constructor.KurtosisTypeConstructor {
 						return builtin_argument.Uint64InRange(value, MemoryAllocationAttr, 6, math.MaxUint64)
 					},
 				},
+				{
+					Name:              ReadyConditionsAttr,
+					IsOptional:        true,
+					ZeroValueProvider: builtin_argument.ZeroValueProvider[*ReadyConditions],
+					Validator:         nil,
+				},
 			},
 		},
 
-		Instantiate: instantiate,
+		Instantiate: instantiateServiceConfig,
 	}
 }
 
-func instantiate(arguments *builtin_argument.ArgumentValuesSet) (kurtosis_type_constructor.KurtosisValueType, *startosis_errors.InterpretationError) {
+func instantiateServiceConfig(arguments *builtin_argument.ArgumentValuesSet) (kurtosis_type_constructor.KurtosisValueType, *startosis_errors.InterpretationError) {
 	kurtosisValueType, err := kurtosis_type_constructor.CreateKurtosisStarlarkTypeDefault(ServiceConfigTypeName, arguments)
 	if err != nil {
 		return nil, err
@@ -268,6 +275,18 @@ func (config *ServiceConfig) ToKurtosisType() (*kurtosis_core_rpc_api_bindings.S
 	return builder.Build(), nil
 }
 
+func (config *ServiceConfig) GetReadyConditions() (*ReadyConditions, *startosis_errors.InterpretationError) {
+	readyConditions, found, interpretationErr := kurtosis_type_constructor.ExtractAttrValue[*ReadyConditions](config.KurtosisValueTypeDefault, ReadyConditionsAttr)
+	if interpretationErr != nil {
+		return nil, interpretationErr
+	}
+	if !found {
+		return nil, nil
+	}
+
+	return readyConditions, nil
+}
+
 func convertPortMapEntry(attrNameForLogging string, key starlark.Value, value starlark.Value, dictForLogging *starlark.Dict) (string, *kurtosis_core_rpc_api_bindings.Port, *startosis_errors.InterpretationError) {
 	keyStr, ok := key.(starlark.String)
 	if !ok {
diff --git a/core/server/api_container/server/startosis_engine/recipe/exec_recipe.go b/core/server/api_container/server/startosis_engine/recipe/exec_recipe.go
index a318a5b88..b6f65b7b7 100644
--- a/core/server/api_container/server/startosis_engine/recipe/exec_recipe.go
+++ b/core/server/api_container/server/startosis_engine/recipe/exec_recipe.go
@@ -28,15 +28,12 @@ const (
 
 // TODO: maybe change command to startlark.List once remove backward compatability support
 type ExecRecipe struct {
-	// Deprecated: we will deprecate this soon, more here: https://app.zenhub.com/workspaces/engineering-636cff9fc978ceb2aac05a1d/issues/gh/kurtosis-tech/kurtosis-private/1128
-	serviceName service.ServiceName //TODO deprecate
-	command     []string
+	command []string
 }
 
-func NewExecRecipe(serviceName service.ServiceName, command []string) *ExecRecipe {
+func NewExecRecipe(command []string) *ExecRecipe {
 	return &ExecRecipe{
-		serviceName: serviceName,
-		command:     command,
+		command: command,
 	}
 }
 
@@ -44,11 +41,6 @@ func NewExecRecipe(serviceName service.ServiceName, command []string) *ExecRecip
 func (recipe *ExecRecipe) String() string {
 	buffer := new(strings.Builder)
 	buffer.WriteString(ExecRecipeName + "(")
-	//TODO  remove this check when we deprecate the service_name field
-	if recipe.serviceName != "" {
-		buffer.WriteString(serviceNameKey + "=")
-		buffer.WriteString(fmt.Sprintf("%q, ", recipe.serviceName))
-	}
 	buffer.WriteString(commandKey + "=")
 
 	command := convertListToStarlarkList(recipe.command)
@@ -72,7 +64,7 @@ func (recipe *ExecRecipe) Freeze() {
 
 // Truth implements the starlark.Value interface
 func (recipe *ExecRecipe) Truth() starlark.Bool {
-	return recipe.serviceName != ""
+	return len(recipe.command) != 0
 }
 
 // Hash implements the starlark.Value interface
@@ -84,8 +76,6 @@ func (recipe *ExecRecipe) Hash() (uint32, error) {
 // Attr implements the starlark.HasAttrs interface.
 func (recipe *ExecRecipe) Attr(name string) (starlark.Value, error) {
 	switch name {
-	case serviceNameKey:
-		return starlark.String(recipe.serviceName), nil
 	case commandKey:
 		return convertListToStarlarkList(recipe.command), nil
 	default:
@@ -113,14 +103,14 @@ func (recipe *ExecRecipe) Execute(
 		commandWithRuntimeValue = append(commandWithRuntimeValue, maybeSubCommandWithRuntimeValues)
 	}
 
-	if serviceName == emptyServiceName {
+	serviceNameStr := string(serviceName)
+	if serviceNameStr == "" {
 		return nil, stacktrace.NewError("The service name parameter can't be an empty string")
 	}
-	serviceNameStr := string(serviceName)
 
 	exitCode, commandOutput, err := serviceNetwork.ExecCommand(ctx, serviceNameStr, commandWithRuntimeValue)
 	if err != nil {
-		return nil, stacktrace.Propagate(err, "Failed to execute command '%v' on service '%v'", recipe.command, recipe.serviceName)
+		return nil, stacktrace.Propagate(err, "Failed to execute command '%v' on service '%v'", recipe.command, serviceName)
 	}
 	return map[string]starlark.Comparable{
 		execOutputKey:   starlark.String(commandOutput),
@@ -163,18 +153,11 @@ func (recipe *ExecRecipe) CreateStarlarkReturnValue(resultUuid string) (*starlar
 	return dict, nil
 }
 
-// TODO this will be removed when we deprecate the service_name field, more here: https://app.zenhub.com/workspaces/engineering-636cff9fc978ceb2aac05a1d/issues/gh/kurtosis-tech/kurtosis-private/1128
-func (recipe *ExecRecipe) GetServiceName() service.ServiceName {
-	return recipe.serviceName
-}
-
 func MakeExecRequestRecipe(_ *starlark.Thread, builtin *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
-	var serviceNameStr string
 	var unpackedCommandList *starlark.List
 
 	if err := starlark.UnpackArgs(builtin.Name(), args, kwargs,
 		commandKey, &unpackedCommandList,
-		kurtosis_types.MakeOptional(serviceNameKey), &serviceNameStr,
 	); err != nil {
 		return nil, startosis_errors.NewInterpretationError("%v", err.Error())
 	}
@@ -183,8 +166,8 @@ func MakeExecRequestRecipe(_ *starlark.Thread, builtin *starlark.Builtin, args s
 	if err != nil {
 		return nil, err
 	}
-	serviceName := service.ServiceName(serviceNameStr)
-	return NewExecRecipe(serviceName, commands), nil
+
+	return NewExecRecipe(commands), nil
 }
 
 func convertListToStarlarkList(inputList []string) *starlark.List {
diff --git a/core/server/api_container/server/startosis_engine/recipe/http_request_recipe.go b/core/server/api_container/server/startosis_engine/recipe/http_request_recipe.go
index 5a47f489d..99d7c1dd6 100644
--- a/core/server/api_container/server/startosis_engine/recipe/http_request_recipe.go
+++ b/core/server/api_container/server/startosis_engine/recipe/http_request_recipe.go
@@ -27,11 +27,11 @@ const (
 
 	statusCodeKey    = "code"
 	bodyKey          = "body"
-	extractKeyPrefix = "extract"
+	ExtractKeyPrefix = "extract"
 
-	portIdAttr      = "port_id"
+	PortIdAttr      = "port_id"
 	serviceNameAttr = "service_name"
-	endpointAttr    = "endpoint"
+	EndpointAttr    = "endpoint"
 	methodAttr      = "method"
 	contentTypeAttr = "content_type"
 
@@ -44,8 +44,6 @@ const (
 )
 
 type HttpRequestRecipe struct {
-	// Deprecated: we will deprecate this soon, more here: https://app.zenhub.com/workspaces/engineering-636cff9fc978ceb2aac05a1d/issues/gh/kurtosis-tech/kurtosis-private/1128
-	serviceName service.ServiceName //TODO deprecate
 	portId      string
 	contentType string
 	endpoint    string
@@ -54,9 +52,8 @@ type HttpRequestRecipe struct {
 	extractors  map[string]string
 }
 
-func NewPostHttpRequestRecipe(serviceName service.ServiceName, portId string, contentType string, endpoint string, body string, extractors map[string]string) *HttpRequestRecipe {
+func NewPostHttpRequestRecipe(portId string, contentType string, endpoint string, body string, extractors map[string]string) *HttpRequestRecipe {
 	return &HttpRequestRecipe{
-		serviceName: serviceName,
 		portId:      portId,
 		method:      postMethod,
 		contentType: contentType,
@@ -66,9 +63,8 @@ func NewPostHttpRequestRecipe(serviceName service.ServiceName, portId string, co
 	}
 }
 
-func NewGetHttpRequestRecipe(serviceName service.ServiceName, portId string, endpoint string, extractors map[string]string) *HttpRequestRecipe {
+func NewGetHttpRequestRecipe(portId string, endpoint string, extractors map[string]string) *HttpRequestRecipe {
 	return &HttpRequestRecipe{
-		serviceName: serviceName,
 		portId:      portId,
 		method:      getMethod,
 		contentType: unusedContentType,
@@ -84,16 +80,10 @@ func (recipe *HttpRequestRecipe) String() string {
 	instanceName := recipe.GetInstanceName()
 
 	buffer.WriteString(instanceName + "(")
-	buffer.WriteString(portIdAttr + "=")
+	buffer.WriteString(PortIdAttr + "=")
 	buffer.WriteString(fmt.Sprintf("%q, ", recipe.portId))
 
-	//TODO  remove this check when we deprecate the service_name field
-	if recipe.serviceName != "" {
-		buffer.WriteString(serviceNameAttr + "=")
-		buffer.WriteString(fmt.Sprintf("%q, ", recipe.serviceName))
-	}
-
-	buffer.WriteString(endpointAttr + "=")
+	buffer.WriteString(EndpointAttr + "=")
 	buffer.WriteString(fmt.Sprintf("%q, ", recipe.endpoint))
 
 	if recipe.method == postMethod {
@@ -103,7 +93,7 @@ func (recipe *HttpRequestRecipe) String() string {
 		buffer.WriteString(fmt.Sprintf("%q, ", recipe.contentType))
 	}
 
-	buffer.WriteString(extractKeyPrefix + "=")
+	buffer.WriteString(ExtractKeyPrefix + "=")
 	extractors, err := convertMapToStarlarkDict(recipe.extractors)
 
 	if err != nil {
@@ -113,7 +103,7 @@ func (recipe *HttpRequestRecipe) String() string {
 	if extractors.Len() > 0 {
 		buffer.WriteString(fmt.Sprintf("%v)", extractors))
 	} else {
-		buffer.WriteString(fmt.Sprintf("%q)", ""))
+		buffer.WriteString(fmt.Sprintf("%s)", "{}"))
 	}
 	return buffer.String()
 }
@@ -130,7 +120,7 @@ func (recipe *HttpRequestRecipe) Freeze() {
 
 // Truth implements the starlark.Value interface
 func (recipe *HttpRequestRecipe) Truth() starlark.Bool {
-	truth := recipe.portId != "" && recipe.serviceName != "" && recipe.endpoint != "" && recipe.method != ""
+	truth := recipe.portId != "" && recipe.endpoint != "" && recipe.method != ""
 	if recipe.method == postMethod {
 		truth = truth && recipe.body != "" && recipe.contentType != ""
 	}
@@ -154,11 +144,9 @@ func (recipe *HttpRequestRecipe) GetInstanceName() string {
 // Attr implements the starlark.HasAttrs interface.
 func (recipe *HttpRequestRecipe) Attr(name string) (starlark.Value, error) {
 	switch name {
-	case portIdAttr:
+	case PortIdAttr:
 		return starlark.String(recipe.portId), nil
-	case serviceNameAttr:
-		return starlark.String(recipe.serviceName), nil
-	case extractKeyPrefix:
+	case ExtractKeyPrefix:
 		return convertMapToStarlarkDict(recipe.extractors)
 	case bodyKey:
 		return starlark.String(recipe.body), nil
@@ -166,7 +154,7 @@ func (recipe *HttpRequestRecipe) Attr(name string) (starlark.Value, error) {
 		return starlark.String(recipe.contentType), nil
 	case methodAttr:
 		return starlark.String(recipe.method), nil
-	case endpointAttr:
+	case EndpointAttr:
 		return starlark.String(recipe.endpoint), nil
 	default:
 		return nil, startosis_errors.NewInterpretationError("'%v' has no attribute '%v;", HttpRecipeTypeName, name)
@@ -175,20 +163,18 @@ func (recipe *HttpRequestRecipe) Attr(name string) (starlark.Value, error) {
 
 // AttrNames implements the starlark.HasAttrs interface.
 func (recipe *HttpRequestRecipe) AttrNames() []string {
-	return []string{portIdAttr, serviceNameAttr, extractKeyPrefix, endpointAttr, contentTypeAttr, methodAttr, bodyKey}
+	return []string{PortIdAttr, serviceNameAttr, ExtractKeyPrefix, EndpointAttr, contentTypeAttr, methodAttr, bodyKey}
 }
 
 func MakeGetHttpRequestRecipe(_ *starlark.Thread, builtin *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 	var portId string
 	var endpoint string
-	var serviceName string
 	var maybeExtractField starlark.Value
 
 	if err := starlark.UnpackArgs(builtin.Name(), args, kwargs,
-		portIdAttr, &portId,
-		endpointAttr, &endpoint,
-		kurtosis_types.MakeOptional(extractKeyPrefix), &maybeExtractField,
-		kurtosis_types.MakeOptional(serviceNameAttr), &serviceName,
+		PortIdAttr, &portId,
+		EndpointAttr, &endpoint,
+		kurtosis_types.MakeOptional(ExtractKeyPrefix), &maybeExtractField,
 	); err != nil {
 		return nil, startosis_errors.NewInterpretationError(err.Error())
 	}
@@ -197,31 +183,29 @@ func MakeGetHttpRequestRecipe(_ *starlark.Thread, builtin *starlark.Builtin, arg
 	var err *startosis_errors.InterpretationError
 
 	if maybeExtractField != nil {
-		extractedMap, err = kurtosis_types.SafeCastToMapStringString(maybeExtractField, extractKeyPrefix)
+		extractedMap, err = kurtosis_types.SafeCastToMapStringString(maybeExtractField, ExtractKeyPrefix)
 		if err != nil {
 			return nil, err
 		}
 	}
-	recipe := NewGetHttpRequestRecipe(service.ServiceName(serviceName), portId, endpoint, extractedMap)
+	recipe := NewGetHttpRequestRecipe(portId, endpoint, extractedMap)
 	return recipe, nil
 }
 
 func MakePostHttpRequestRecipe(_ *starlark.Thread, builtin *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
 	var portId string
 	var endpoint string
-	var serviceName string
 
 	var maybeBody starlark.Value
 	contentType := defaultContentType
 	var maybeExtractField starlark.Value
 
 	if err := starlark.UnpackArgs(builtin.Name(), args, kwargs,
-		portIdAttr, &portId,
-		endpointAttr, &endpoint,
+		PortIdAttr, &portId,
+		EndpointAttr, &endpoint,
 		kurtosis_types.MakeOptional(bodyKey), &maybeBody,
 		kurtosis_types.MakeOptional(contentTypeAttr), &contentType,
-		kurtosis_types.MakeOptional(extractKeyPrefix), &maybeExtractField,
-		kurtosis_types.MakeOptional(serviceNameAttr), &serviceName,
+		kurtosis_types.MakeOptional(ExtractKeyPrefix), &maybeExtractField,
 	); err != nil {
 		return nil, startosis_errors.NewInterpretationError("%v", err.Error())
 	}
@@ -231,7 +215,7 @@ func MakePostHttpRequestRecipe(_ *starlark.Thread, builtin *starlark.Builtin, ar
 	var err *startosis_errors.InterpretationError
 
 	if maybeExtractField != nil {
-		extractedMap, err = kurtosis_types.SafeCastToMapStringString(maybeExtractField, extractKeyPrefix)
+		extractedMap, err = kurtosis_types.SafeCastToMapStringString(maybeExtractField, ExtractKeyPrefix)
 		if err != nil {
 			return nil, err
 		}
@@ -244,7 +228,7 @@ func MakePostHttpRequestRecipe(_ *starlark.Thread, builtin *starlark.Builtin, ar
 		}
 	}
 
-	recipe := NewPostHttpRequestRecipe(service.ServiceName(serviceName), portId, contentType, endpoint, extractedBody, extractedMap)
+	recipe := NewPostHttpRequestRecipe(portId, contentType, endpoint, extractedBody, extractedMap)
 	return recipe, nil
 }
 
@@ -262,10 +246,10 @@ func (recipe *HttpRequestRecipe) Execute(
 		return nil, stacktrace.Propagate(err, "An error occurred while replacing runtime values in the body of the http recipe")
 	}
 
-	if serviceName == emptyServiceName {
+	serviceNameStr := string(serviceName)
+	if serviceNameStr == "" {
 		return nil, stacktrace.NewError("The service name parameter can't be an empty string")
 	}
-	serviceNameStr := string(serviceName)
 
 	response, err = serviceNetwork.HttpRequestService(
 		ctx,
@@ -299,7 +283,7 @@ func (recipe *HttpRequestRecipe) Execute(
 		return nil, stacktrace.Propagate(err, "An error occurred while running extractors on HTTP response body")
 	}
 	for extractorKey, extractorValue := range extractDict {
-		resultDict[fmt.Sprintf("%v.%v", extractKeyPrefix, extractorKey)] = extractorValue
+		resultDict[fmt.Sprintf("%v.%v", ExtractKeyPrefix, extractorKey)] = extractorValue
 	}
 	return resultDict, nil
 }
@@ -365,7 +349,7 @@ func (recipe *HttpRequestRecipe) ResultMapToString(resultMap map[string]starlark
 	body := resultMap[bodyKey]
 	extractedFieldString := strings.Builder{}
 	for resultKey, resultValue := range resultMap {
-		if strings.Contains(resultKey, extractKeyPrefix) {
+		if strings.Contains(resultKey, ExtractKeyPrefix) {
 			extractedFieldString.WriteString(fmt.Sprintf("\n'%v': %v", resultKey, resultValue))
 		}
 	}
@@ -387,7 +371,7 @@ func (recipe *HttpRequestRecipe) CreateStarlarkReturnValue(resultUuid string) (*
 		return nil, startosis_errors.NewInterpretationError("An error has occurred when creating return value for request recipe, setting field '%v'", statusCodeKey)
 	}
 	for extractorKey := range recipe.extractors {
-		fullExtractorKey := fmt.Sprintf("%v.%v", extractKeyPrefix, extractorKey)
+		fullExtractorKey := fmt.Sprintf("%v.%v", ExtractKeyPrefix, extractorKey)
 		err = dict.SetKey(starlark.String(fullExtractorKey), starlark.String(fmt.Sprintf(magic_string_helper.RuntimeValueReplacementPlaceholderFormat, resultUuid, fullExtractorKey)))
 		if err != nil {
 			return nil, startosis_errors.NewInterpretationError("An error has occurred when creating return value for request recipe, setting field '%v'", fullExtractorKey)
@@ -397,11 +381,6 @@ func (recipe *HttpRequestRecipe) CreateStarlarkReturnValue(resultUuid string) (*
 	return dict, nil
 }
 
-// TODO this will be removed when we deprecate the service_name field, more here: https://app.zenhub.com/workspaces/engineering-636cff9fc978ceb2aac05a1d/issues/gh/kurtosis-tech/kurtosis-private/1128
-func (recipe *HttpRequestRecipe) GetServiceName() service.ServiceName {
-	return recipe.serviceName
-}
-
 func convertMapToStarlarkDict(inputMap map[string]string) (*starlark.Dict, *startosis_errors.InterpretationError) {
 	sizeOfExtractors := len(inputMap)
 	dict := starlark.NewDict(sizeOfExtractors)
diff --git a/core/server/api_container/server/startosis_engine/recipe/recipe.go b/core/server/api_container/server/startosis_engine/recipe/recipe.go
index 5e5e82991..4d8ee8935 100644
--- a/core/server/api_container/server/startosis_engine/recipe/recipe.go
+++ b/core/server/api_container/server/startosis_engine/recipe/recipe.go
@@ -18,5 +18,4 @@ type Recipe interface {
 	) (map[string]starlark.Comparable, error)
 	CreateStarlarkReturnValue(resultUuid string) (*starlark.Dict, *startosis_errors.InterpretationError)
 	ResultMapToString(resultMap map[string]starlark.Comparable) string
-	GetServiceName() service.ServiceName //TODO this will be removed when we deprecate the service_name field, more here: https://app.zenhub.com/workspaces/engineering-636cff9fc978ceb2aac05a1d/issues/gh/kurtosis-tech/kurtosis-private/1128
 }
diff --git a/core/server/api_container/server/startosis_engine/recipe/shared_helpers.go b/core/server/api_container/server/startosis_engine/recipe/shared_helpers.go
deleted file mode 100644
index 9d3ea9ee3..000000000
--- a/core/server/api_container/server/startosis_engine/recipe/shared_helpers.go
+++ /dev/null
@@ -1,9 +0,0 @@
-package recipe
-
-import (
-	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service"
-)
-
-const (
-	emptyServiceName = service.ServiceName("")
-)
diff --git a/docs/docs/reference/cli/feedback.md b/docs/docs/reference/cli/feedback.md
index d5a2ec052..9056dccc0 100644
--- a/docs/docs/reference/cli/feedback.md
+++ b/docs/docs/reference/cli/feedback.md
@@ -6,10 +6,19 @@ slug: /feedback
 
 Your feedback is valuable and helps us improve Kurtosis. We thank you in advance for taking the time to share your suggestions and concerns with us.
 
+To send our team feedback over email straight from the CLI, simply run:
+```bash
+kurtosis feedback "$YOUR_FEEDBACK"
+```
+where `$YOUR_FEEDBACK` is the feedback you would like to send to us. For example, `$YOUR_FEEDBACK` could be: "_I enjoy the enclave names_".
+
+Running the above command will open a draft email using your default email client with the `TO:` line pre-filled with our feedback email list (feedback@kurtosistech.com) and the body of the message pre-filled with `$YOUR_FEEDBACK` (that you entered in the command line).
+
 To quickly see all the ways you can get in touch with us, simply run:
 ```bash
 kurtosis feedback
 ```
+
 which will return:
 - The link to our [Github](https://github.com/kurtosis-tech/kurtosis/issues/new/choose) for filing bug reports and feature requests as Github Issues. 
 - Our [feedback email address](mailto:feedback@kurtosistech.com) for sending us suggestions, comments, or questions about Kurtosis via email.
diff --git a/docs/docs/reference/starlark-instructions.md b/docs/docs/reference/starlark-instructions.md
index 3b1b34646..cb6c3a0ff 100644
--- a/docs/docs/reference/starlark-instructions.md
+++ b/docs/docs/reference/starlark-instructions.md
@@ -160,12 +160,6 @@ plan.assert(
 
 The `exec` instruction on the [`plan`][plan-reference] object executes commands on a given service as if they were running in a shell on the container.
 
-:::caution
-
-The previous `ExecRecipe` type `ExecRecipe(service_name = "my_service", command = ["echo", "Hello, world"])` is also accepted but will be deprecated soon, we suggest users to use this new one where the `service_name` argument is passed in via the `exec` instruction signature instead.
-
-:::
-
 ```python
 exec_recipe = ExecRecipe(
     # The actual command to execute. 
@@ -191,7 +185,7 @@ result = plan.exec(
 
     # A Service name designating a service that already exists inside the enclave
     # If it does not, a validation error will be thrown
-    # OPTIONAL
+    # MANDATORY
     service_name = "my-service",
 )
 
@@ -326,12 +320,6 @@ The `request` instruction on the [`plan`][plan-reference] object executes either
 
 To make a GET or POST request, simply set the `recipe` field to use the specified [GetHttpRequestRecipe][starlark-types-get-http-recipe] or the [PostHttpRequestRecipe][starlark-types-post-http-recipe]. 
 
-:::caution
-
-The previous `GetHttpRequestRecipe` type `GetHttpRequestRecipe(service_name = "my_service", port_id = "my_port", endpoint = "/endpoint?input=data", extract = {"extracted-field": ".name.id", })` is also accepted but will be deprecated soon, we suggest users to use this new one where the `service_name` argument is passed in via the `request` instruction signature instead.
-
-:::
-
 ```python
 http_response = plan.request(
     # The recipe that will determine the request to be performed.
@@ -350,7 +338,7 @@ http_response = plan.request(
     
     # A service name designating a service that already exists inside the enclave
     # If it does not, a validation error will be thrown
-    # OPTIONAL
+    # MANDATORY
     service_name = "my_service",
 )
 plan.print(get_response["body"]) # Prints the body of the request
@@ -523,13 +511,8 @@ The `wait` instruction on the [`plan`][plan-reference] object fails the Starlark
 
 To learn more about the accepted recipe types, please checkout [ExecRecipe][starlark-types-exec-recipe], [GetHttpRequestRecipe][starlark-types-get-http-recipe] or [PostHttpRequestRecipe][starlark-types-post-http-recipe].
 
-If it succedes, it returns a [future references][future-references-reference] with the last recipe run.
-
-:::caution
-
-The previous `GetHttpRequestRecipe` type `GetHttpRequestRecipe(service_name = "my_service", port_id = "my_port", endpoint = "/endpoint?input=data", extract = {"extracted-field": ".name.id", })` is also accepted but will be deprecated soon, we suggest users to use this new one where the `service_name` argument is passed in via the `wait` instruction signature instead.
+If it succeeds, it returns a [future references][future-references-reference] with the last recipe run.
 
-:::
 
 ```python
 # This fails in runtime if response["code"] != 200 for each request in a 5 minute time span
@@ -556,7 +539,7 @@ response = plan.wait(
     # The interval value is the initial interval suggestion for the command to wait between calls
     # It follows a exponential backoff process, where the i-th backoff interval is rand(0.5, 1.5)*interval*2^i
     # Follows Go "time.Duration" format https://pkg.go.dev/time#ParseDuration
-    # OPTIONAL (Default: "500ms")
+    # OPTIONAL (Default: "1s")
     interval = "1s",
 
     # The timeout value is the maximum time that the command waits for the assertion to be true
@@ -566,7 +549,7 @@ response = plan.wait(
 
     # A Service name designating a service that already exists inside the enclave
     # If it does not, a validation error will be thrown
-    # OPTIONAL
+    # MANDATORY
     service_name = "example-datastore-server-1",
 )
 # If this point of the code is reached, the assertion has passed therefore the print statement will print "200"
diff --git a/docs/docs/reference/starlark-types.md b/docs/docs/reference/starlark-types.md
index 12d2cce8a..e4144bf14 100644
--- a/docs/docs/reference/starlark-types.md
+++ b/docs/docs/reference/starlark-types.md
@@ -37,13 +37,6 @@ See [kurtosis.connection][connection-config-prebuilt] for pre-built [ConnectionC
 The ExecRecipe can be used to run the `command` on the service (see [exec][starlark-instructions-exec]
 or [wait][starlark-instructions-wait])
 
-:::caution
-
-The `ExecRecipe.service_name` field is still accepted but it's deprecated, so we suggest users to pass
-this value as an argument in the `exec`, `request` and `wait` instructions where this type is currently used
-
-:::
-
 ```python
 exec_recipe = ExecRecipe(
     # The actual command to execute. 
@@ -57,13 +50,6 @@ exec_recipe = ExecRecipe(
 
 The `GetHttpRequestRecipe` can be used to make `GET` requests to an endpoint, filter for the specific part of the response you care about, and assign that specific output to a key for later use. This can be useful for writing assertions, for example (i.e. validating the response you end up receiving looks the way you expect/intended).
 
-:::caution
-
-The `GetHttpRequestRecipe.service_name` field is still accepted but it's deprecated, so we suggest users to pass
-this value as an argument in the `exec`, `request` and `wait` instructions where this type is currently used.
-
-:::
-
 ```python
 get_request_recipe = GetHttpRequestRecipe(
     # The port ID that is the server port for the request
@@ -116,20 +102,13 @@ The user-defined port IDs in the above `ServiceConfig` are: `http` and `grpc`. B
     )
 ```
 
-The above recipe, when used with `request` or `wait` instruction, will make a `GET` request to a service with name `service-using-test-service-config` on port `5000` with the path `/ping`.
+The above recipe, when used with `request` or `wait` instruction, will make a `GET` request to a service (the `service_name` field must be passed as an instruction's argument) on port `5000` with the path `/ping`.
 :::
 
 ### PostHttpRequestRecipe
 
 The `PostHttpRequestRecipe` can be used to make `POST` requests to an endpoint.
 
-:::caution
-
-The `PostHttpRequestRecipe.service_name` field is still accepted but it's deprecated, so we suggest users to pass
-this value as an argument in the `exec`, `request` and `wait` instructions where this type is currently used
-
-:::
-
 ```python
 post_request_recipe = PostHttpRequestRecipe(
     # The port ID that is the server port for the request
@@ -227,6 +206,48 @@ port_spec = PortSpec(
 The above constructor returns a `PortSpec` object that contains port information in the form of a [future reference][future-references-reference] and can be used with
 [add_service][starlark-instructions-add-service] to create services.
 
+### ReadyConditions
+
+The `ReadyConditions` can be used to execute a readiness check after a service is started to confirm that it is ready to receive connections and traffic 
+
+```python
+ready_conditions = ReadyConditions(
+
+    # The recipe that will be used to check service's readiness.
+    # Valid values are of the following types: (ExecRecipe, GetHttpRequestRecipe or PostHttpRequestRecipe)
+    # MANDATORY
+    recipe = GetHttpRequestRecipe(
+        port_id = "http",
+        endpoint = "/ping",
+    ),
+
+    # The `field's value` will be used to do the asssertions. To learn more about available fields, 
+    # that can be used for assertions, please refer to exec and request instructions.
+    # MANDATORY
+    field = "code",
+
+    # The assertion is the comparison operation between value and target_value.
+    # Valid values are "==", "!=", ">=", "<=", ">", "<" or "IN" and "NOT_IN" (if target_value is list).
+    # MANDATORY
+    assertion = "==",
+
+    # The target value that value will be compared against.
+    # MANDATORY
+    target_value = 200,
+
+    # The interval value is the initial interval suggestion for the command to wait between calls
+    # It follows a exponential backoff process, where the i-th backoff interval is rand(0.5, 1.5)*interval*2^i
+    # Follows Go "time.Duration" format https://pkg.go.dev/time#ParseDuration
+    # OPTIONAL (Default: "1s")
+    interval = "1s",
+
+    # The timeout value is the maximum time that the readiness check waits for the assertion to be true
+    # Follows Go "time.Duration" format https://pkg.go.dev/time#ParseDuration
+    # OPTIONAL (Default: "15m")
+    timeout = "5m",
+)
+```
+
 ### ServiceConfig
 
 The `ServiceConfig` is used to configure a service when it is added to an enclave (see [add_service][starlark-instructions-add-service]).
@@ -304,6 +325,11 @@ config = ServiceConfig(
     # Defines the subnetwork in which the service will be started.
     # OPTIONAL (Default: "default")
     subnetwork = "service_subnetwork",
+    
+    # This field can be used to check the service's readiness after this is started
+    # to confirm that it is ready to receive connections and traffic
+    # OPTIONAL (Default: no ready conditions)
+    ready_conditions = ReadyConditions(...)
 )
 ```
 The `ports` dictionary argument accepts a key value pair, where `key` is a user defined unique port identifier and `value` is a [PortSpec][port-spec] object.
@@ -312,6 +338,8 @@ The `files` dictionary argument accepts a key value pair, where `key` is the pat
 
 For more info about the `subnetwork` argument, see [Kurtosis subnetworks][subnetworks-reference].
 
+You can see how to configure the [`ReadyConditions` type here][ready-conditions]. 
+
 ### UpdateServiceConfig
 
 The `UpdateServiceConfig` contains the attributes of [ServiceConfig][service-config] that are live-updatable. For now, only the `subnetwork`[subnetworks-reference] attribute of a service can be updated once the service is started.
@@ -343,6 +371,7 @@ Kurtosis provides "pre-built" values for types that will be broadly used. Those
 [connection-config]: #connectionconfig
 [service-config]: #serviceconfig
 [port-spec]: #portspec
+[ready-conditions]: #readyconditions
 
 [connection-config-prebuilt]: #connection
 


Test patch:
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/add_service_framework_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/add_service_framework_test.go
index 637d2869c..29f49a5b5 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/add_service_framework_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/add_service_framework_test.go
@@ -16,6 +16,10 @@ import (
 	"github.com/stretchr/testify/mock"
 	"github.com/stretchr/testify/require"
 	"go.starlark.net/starlark"
+	"io"
+	"net/http"
+	"net/url"
+	"strings"
 	"testing"
 )
 
@@ -73,6 +77,34 @@ func (t *addServiceTestCase) GetInstruction() *kurtosis_plan_instruction.Kurtosi
 		nil,
 	)
 
+	serviceNetwork.EXPECT().HttpRequestService(
+		mock.Anything,
+		string(TestServiceName),
+		TestPrivatePortId,
+		TestGetRequestMethod,
+		"",
+		TestReadyConditionsRecipeEndpoint,
+		"",
+	).Times(1).Return(&http.Response{
+		Status:     "200 OK",
+		StatusCode: 200,
+		Proto:      "HTTP/1.1",
+		ProtoMajor: 1,
+		ProtoMinor: 1,
+		Header:     http.Header{},
+		Request: &http.Request{
+			Method: TestGetRequestMethod,
+			URL:    &url.URL{},
+		},
+		Close:            true,
+		ContentLength:    -1,
+		Body:             io.NopCloser(strings.NewReader("{}")),
+		Trailer:          nil,
+		TransferEncoding: nil,
+		Uncompressed:     true,
+		TLS:              nil,
+	}, nil)
+
 	return add_service.NewAddService(serviceNetwork, runtimeValueStore)
 }
 
@@ -88,7 +120,13 @@ func (t *addServiceTestCase) GetStarlarkCode() string {
 		"private_ip_address_placeholder=%q, " +
 		"subnetwork=%q, " +
 		"cpu_allocation=%d, " +
-		"memory_allocation=%d)"
+		"memory_allocation=%d, " +
+		"ready_conditions=ReadyConditions(" +
+		"recipe=GetHttpRequestRecipe(port_id=%q, endpoint=%q, extract={})," +
+		" field=%q," +
+		" assertion=%q," +
+		" target_value=%s" +
+		"))"
 	serviceConfig := fmt.Sprintf(serviceConfigStarlarkStrTemplate,
 		TestContainerImageName,
 		TestPrivatePortId, TestPrivatePortNumber, TestPrivatePortProtocolStr, TestPrivateApplicationProtocol,
@@ -100,7 +138,13 @@ func (t *addServiceTestCase) GetStarlarkCode() string {
 		TestPrivateIPAddressPlaceholder,
 		TestSubnetwork,
 		TestCpuAllocation,
-		TestMemoryAllocation)
+		TestMemoryAllocation,
+		TestPrivatePortId,
+		TestReadyConditionsRecipeEndpoint,
+		TestReadyConditionsField,
+		TestReadyConditionsAssertion,
+		TestReadyConditionsTarget,
+	)
 	return fmt.Sprintf(`%s(%s=%q, %s=%s)`, add_service.AddServiceBuiltinName, add_service.ServiceNameArgName, TestServiceName, add_service.ServiceConfigArgName, serviceConfig)
 }
 
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/add_services_framework_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/add_services_framework_test.go
index 1330e3410..bbe4c53b9 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/add_services_framework_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/add_services_framework_test.go
@@ -14,6 +14,10 @@ import (
 	"github.com/stretchr/testify/mock"
 	"github.com/stretchr/testify/require"
 	"go.starlark.net/starlark"
+	"io"
+	"net/http"
+	"net/url"
+	"strings"
 	"testing"
 )
 
@@ -60,12 +64,109 @@ func (t *addServicesTestCase) GetInstruction() *kurtosis_plan_instruction.Kurtos
 		nil,
 	)
 
+	serviceNetwork.EXPECT().HttpRequestService(
+		mock.Anything,
+		string(TestServiceName),
+		TestReadyConditionsRecipePortId,
+		TestGetRequestMethod,
+		"",
+		TestReadyConditionsRecipeEndpoint,
+		"",
+	).Times(1).Return(&http.Response{
+		Status:     "200 OK",
+		StatusCode: 200,
+		Proto:      "HTTP/1.1",
+		ProtoMajor: 1,
+		ProtoMinor: 1,
+		Header:     http.Header{},
+		Request: &http.Request{
+			Method: TestGetRequestMethod,
+			URL:    &url.URL{},
+		},
+		Close:            true,
+		ContentLength:    -1,
+		Body:             io.NopCloser(strings.NewReader("{}")),
+		Trailer:          nil,
+		TransferEncoding: nil,
+		Uncompressed:     true,
+		TLS:              nil,
+	}, nil)
+
+	serviceNetwork.EXPECT().HttpRequestService(
+		mock.Anything,
+		string(TestServiceName2),
+		TestReadyConditions2RecipePortId,
+		TestGetRequestMethod,
+		"",
+		TestReadyConditions2RecipeEndpoint,
+		"",
+	).Times(1).Return(&http.Response{
+		Status:     "201 OK",
+		StatusCode: 201,
+		Proto:      "HTTP/1.1",
+		ProtoMajor: 1,
+		ProtoMinor: 1,
+		Header:     http.Header{},
+		Request: &http.Request{
+			Method: TestGetRequestMethod,
+			URL: &url.URL{
+				Path:        "",
+				Scheme:      "",
+				Opaque:      "",
+				User:        nil,
+				Host:        "",
+				RawPath:     "",
+				ForceQuery:  false,
+				RawQuery:    "",
+				Fragment:    "",
+				RawFragment: "",
+			},
+			Proto:            "",
+			ProtoMajor:       0,
+			ProtoMinor:       0,
+			Header:           http.Header{},
+			Body:             nil,
+			GetBody:          nil,
+			ContentLength:    0,
+			TransferEncoding: nil,
+			Close:            false,
+			Host:             "",
+			Form:             nil,
+			PostForm:         nil,
+			MultipartForm:    nil,
+			Trailer:          nil,
+			RemoteAddr:       "",
+			RequestURI:       "",
+			TLS:              nil,
+			Cancel:           nil,
+			Response:         nil,
+		},
+		Close:            true,
+		ContentLength:    -1,
+		Body:             io.NopCloser(strings.NewReader("{}")),
+		Trailer:          nil,
+		TransferEncoding: nil,
+		Uncompressed:     true,
+		TLS:              nil,
+	}, nil)
+
 	return add_service.NewAddServices(serviceNetwork, runtimeValueStore)
 }
 
 func (t *addServicesTestCase) GetStarlarkCode() string {
-	serviceConfig1 := fmt.Sprintf("ServiceConfig(image=%q, subnetwork=%q)", TestContainerImageName, TestSubnetwork)
-	serviceConfig2 := fmt.Sprintf("ServiceConfig(image=%q, cpu_allocation=%d, memory_allocation=%d)", TestContainerImageName, TestCpuAllocation, TestMemoryAllocation)
+	service1ReadyConditionsScriptPart := getDefaultReadyConditionsScriptPart()
+	service2ReadyConditionsScriptPart := getCustomReadyConditionsScripPart(
+		TestReadyConditions2RecipePortId,
+		TestReadyConditions2RecipeEndpoint,
+		TestReadyConditions2RecipeExtract,
+		TestReadyConditions2Field,
+		TestReadyConditions2Assertion,
+		TestReadyConditions2Target,
+		TestReadyConditions2Interval,
+		TestReadyConditions2Timeout,
+	)
+	serviceConfig1 := fmt.Sprintf("ServiceConfig(image=%q, subnetwork=%q, ready_conditions=%s)", TestContainerImageName, TestSubnetwork, service1ReadyConditionsScriptPart)
+	serviceConfig2 := fmt.Sprintf("ServiceConfig(image=%q, cpu_allocation=%d, memory_allocation=%d, ready_conditions=%s)", TestContainerImageName, TestCpuAllocation, TestMemoryAllocation, service2ReadyConditionsScriptPart)
 	return fmt.Sprintf(`%s(%s={%q: %s, %q: %s})`, add_service.AddServicesBuiltinName, add_service.ConfigsArgName, TestServiceName, serviceConfig1, TestServiceName2, serviceConfig2)
 }
 
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_framework_test_case_1.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_framework_test_case_1_test.go
similarity index 83%
rename from core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_framework_test_case_1.go
rename to core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_framework_test_case_1_test.go
index bcf0f1e0c..ffe48df85 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_framework_test_case_1.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_framework_test_case_1_test.go
@@ -49,15 +49,14 @@ func (t execTestCase1) GetInstruction() *kurtosis_plan_instruction.KurtosisPlanI
 }
 
 func (t execTestCase1) GetStarlarkCode() string {
-	recipe := fmt.Sprintf(`ExecRecipe(service_name=%q, command=["mkdir", "-p", "/tmp/store"])`, execServiceName)
-	return fmt.Sprintf("%s(%s=%s)", exec.ExecBuiltinName, exec.RecipeArgName, recipe)
+	recipe := `ExecRecipe(command=["mkdir", "-p", "/tmp/store"])`
+	return fmt.Sprintf("%s(%s=%s, %s=%q)", exec.ExecBuiltinName, exec.RecipeArgName, recipe, exec.ServiceNameArgName, execServiceName)
 }
 
 func (t *execTestCase1) GetStarlarkCodeForAssertion() string {
 	return ""
 }
 
-//TODO we should change the assert when we deprecate the recipe.service_name more here: https://app.zenhub.com/workspaces/engineering-636cff9fc978ceb2aac05a1d/issues/gh/kurtosis-tech/kurtosis-private/1128
 func (t execTestCase1) Assert(interpretationResult starlark.Value, executionResult *string) {
 	expectedInterpretationResultMap := `{"code": "{{kurtosis:[0-9a-f]{32}:code.runtime_value}}", "output": "{{kurtosis:[0-9a-f]{32}:output.runtime_value}}"}`
 	require.Regexp(t, expectedInterpretationResultMap, interpretationResult.String())
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_framework_test_case_2.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_framework_test_case_2_test.go
similarity index 70%
rename from core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_framework_test_case_2.go
rename to core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_framework_test_case_2_test.go
index c5dbb934e..0bd6e1ca7 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_framework_test_case_2.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_framework_test_case_2_test.go
@@ -2,7 +2,6 @@ package test_engine
 
 import (
 	"fmt"
-	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/service_network"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/exec"
 	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/kurtosis_plan_instruction"
@@ -13,12 +12,7 @@ import (
 	"testing"
 )
 
-const (
-	execTextCase2ServiceName = service.ServiceName("my-service-for-test-case-3")
-)
-
-//This test case is for testing positional arguments retro-compatibility for those script
-//that are using the recipe value as the first positional argument
+//This test case is for testing positional arguments
 type execTestCase2 struct {
 	*testing.T
 }
@@ -39,7 +33,7 @@ func (t execTestCase2) GetInstruction() *kurtosis_plan_instruction.KurtosisPlanI
 
 	serviceNetwork.EXPECT().ExecCommand(
 		mock.Anything,
-		string(execTextCase2ServiceName),
+		string(execServiceName),
 		[]string{"mkdir", "-p", "/tmp/store"},
 	).Times(1).Return(
 		int32(0),
@@ -51,13 +45,13 @@ func (t execTestCase2) GetInstruction() *kurtosis_plan_instruction.KurtosisPlanI
 }
 
 func (t execTestCase2) GetStarlarkCode() string {
-	recipe := fmt.Sprintf(`ExecRecipe(service_name=%q, command=["mkdir", "-p", "/tmp/store"])`, execTextCase2ServiceName)
-	return fmt.Sprintf("%s(%s)", exec.ExecBuiltinName, recipe)
+	recipe := `ExecRecipe(command=["mkdir", "-p", "/tmp/store"])`
+	return fmt.Sprintf("%s(%s, %q)", exec.ExecBuiltinName, recipe, execServiceName)
 }
 
 func (t *execTestCase2) GetStarlarkCodeForAssertion() string {
-	recipe := fmt.Sprintf(`ExecRecipe(service_name=%q, command=["mkdir", "-p", "/tmp/store"])`, execTextCase2ServiceName)
-	return fmt.Sprintf("%s(%s=%s)", exec.ExecBuiltinName, exec.RecipeArgName, recipe)
+	recipe := `ExecRecipe(command=["mkdir", "-p", "/tmp/store"])`
+	return fmt.Sprintf("%s(%s=%s, %s=%q)", exec.ExecBuiltinName, exec.RecipeArgName, recipe, exec.ServiceNameArgName, execServiceName)
 }
 
 func (t execTestCase2) Assert(interpretationResult starlark.Value, executionResult *string) {
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_framework_test_case_3.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_framework_test_case_3.go
deleted file mode 100644
index 142eb4c77..000000000
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/exec_framework_test_case_3.go
+++ /dev/null
@@ -1,69 +0,0 @@
-package test_engine
-
-import (
-	"fmt"
-	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service"
-	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/service_network"
-	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/exec"
-	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/kurtosis_plan_instruction"
-	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/runtime_value_store"
-	"github.com/stretchr/testify/mock"
-	"github.com/stretchr/testify/require"
-	"go.starlark.net/starlark"
-	"testing"
-)
-
-const (
-	execTextCase3ServiceName = service.ServiceName("my-service-for-test-case-2")
-)
-
-//For a short period (until we deprecate recipe.service_name) the exec instruction will have a
-//dynamic first parameter which will accept the current 'recipe' argument and a new 'service_name' argument
-//In the execTestCase1 we test the current behaviour, it means receiving an 'recipe' as the first argument
-//In this test case we test that 'service_name' is also accepted as the first parameter, and it is used in the exec call
-type execTestCase3 struct {
-	*testing.T
-}
-
-func newExecTestCase3(t *testing.T) *execTestCase3 {
-	return &execTestCase3{
-		T: t,
-	}
-}
-
-func (t execTestCase3) GetId() string {
-	return exec.ExecBuiltinName
-}
-
-func (t execTestCase3) GetInstruction() *kurtosis_plan_instruction.KurtosisPlanInstruction {
-	serviceNetwork := service_network.NewMockServiceNetwork(t)
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
-
-	serviceNetwork.EXPECT().ExecCommand(
-		mock.Anything,
-		string(execTextCase3ServiceName),
-		[]string{"mkdir", "-p", "/tmp/store"},
-	).Times(1).Return(
-		int32(0),
-		"",
-		nil,
-	)
-
-	return exec.NewExec(serviceNetwork, runtimeValueStore)
-}
-
-func (t execTestCase3) GetStarlarkCode() string {
-	recipe := `ExecRecipe(command=["mkdir", "-p", "/tmp/store"])`
-	return fmt.Sprintf("%s(%s=%s, %s=%q)", exec.ExecBuiltinName, exec.RecipeArgName, recipe, exec.ServiceNameArgName, execTextCase3ServiceName)
-}
-
-func (t *execTestCase3) GetStarlarkCodeForAssertion() string {
-	return ""
-}
-
-func (t execTestCase3) Assert(interpretationResult starlark.Value, executionResult *string) {
-	expectedInterpretationResultMap := `{"code": "{{kurtosis:[0-9a-f]{32}:code.runtime_value}}", "output": "{{kurtosis:[0-9a-f]{32}:output.runtime_value}}"}`
-	require.Regexp(t, expectedInterpretationResultMap, interpretationResult.String())
-
-	require.Equal(t, "Command returned with exit code '0' with no output", *executionResult)
-}
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/ready_conditions_framework_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/ready_conditions_framework_test.go
new file mode 100644
index 000000000..9711be4bb
--- /dev/null
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/ready_conditions_framework_test.go
@@ -0,0 +1,120 @@
+package test_engine
+
+import (
+	"fmt"
+	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/kurtosis_type_constructor"
+	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_types/service_config"
+	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/recipe"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+	"go.starlark.net/starlark"
+	"testing"
+	"time"
+)
+
+type readyConditionsTestCase struct {
+	*testing.T
+}
+
+func newReadyConditionsTestCase(t *testing.T) *readyConditionsTestCase {
+	return &readyConditionsTestCase{
+		T: t,
+	}
+}
+
+func (t *readyConditionsTestCase) GetId() string {
+	return service_config.ReadyConditionsTypeName
+}
+
+func (t *readyConditionsTestCase) GetTypeConstructor() *kurtosis_type_constructor.KurtosisTypeConstructor {
+	return service_config.NewReadyConditionsType()
+}
+
+func (t *readyConditionsTestCase) GetStarlarkCode() string {
+	return fmt.Sprintf("%s(%s=%s(%s=%q, %s=%q, %s=%s), %s=%q, %s=%q, %s=%s, %s=%q, %s=%q)",
+		service_config.ReadyConditionsTypeName,
+		service_config.RecipeAttr,
+		recipe.GetHttpRecipeTypeName,
+		recipe.PortIdAttr,
+		TestReadyConditionsRecipePortId,
+		recipe.EndpointAttr,
+		TestReadyConditionsRecipeEndpoint,
+		recipe.ExtractKeyPrefix,
+		TestReadyConditionsRecipeExtract,
+		service_config.FieldAttr,
+		TestReadyConditionsField,
+		service_config.AssertionAttr,
+		TestReadyConditionsAssertion,
+		service_config.TargetAttr,
+		TestReadyConditionsTarget,
+		service_config.IntervalAttr,
+		TestReadyConditionsInterval,
+		service_config.TimeoutAttr,
+		TestReadyConditionsTimeout,
+	)
+}
+
+func (t *readyConditionsTestCase) Assert(typeValue starlark.Value) {
+	receivedReadyConditions, ok := typeValue.(*service_config.ReadyConditions)
+	require.True(t, ok)
+
+	uncastedRecipe, err := receivedReadyConditions.GetRecipe()
+	if assert.Nil(t, err) {
+		castedRecipe, ok := uncastedRecipe.(*recipe.HttpRequestRecipe)
+		require.True(t, ok)
+
+		portIdAttrValue, err := castedRecipe.Attr(recipe.PortIdAttr)
+		if assert.Nil(t, err) {
+			portId, ok := portIdAttrValue.(starlark.String)
+			require.True(t, ok)
+			require.Equal(t, TestReadyConditionsRecipePortId, portId.GoString())
+		}
+
+		endpointAttrValue, err := castedRecipe.Attr(recipe.EndpointAttr)
+		if assert.Nil(t, err) {
+			endpoint, ok := endpointAttrValue.(starlark.String)
+			require.True(t, ok)
+			require.Equal(t, TestReadyConditionsRecipeEndpoint, endpoint.GoString())
+		}
+
+		extractAttrValue, err := castedRecipe.Attr(recipe.ExtractKeyPrefix)
+		if assert.Nil(t, err) {
+			extract, ok := extractAttrValue.(*starlark.Dict)
+			require.True(t, ok)
+			expectedExtractLen := 0
+			require.Equal(t, expectedExtractLen, extract.Len())
+		}
+	}
+
+	field, err := receivedReadyConditions.GetField()
+	if assert.Nil(t, err) {
+		require.Equal(t, TestReadyConditionsField, field)
+	}
+
+	assertion, err := receivedReadyConditions.GetAssertion()
+	if assert.Nil(t, err) {
+		require.Equal(t, TestReadyConditionsAssertion, assertion)
+	}
+
+	target, err := receivedReadyConditions.GetTarget()
+	if assert.Nil(t, err) {
+		require.Equal(t, TestReadyConditionsTarget, target.String())
+	}
+
+	interval, err := receivedReadyConditions.GetInterval()
+	if assert.Nil(t, err) {
+		expectedInterval, err := time.ParseDuration(TestReadyConditionsInterval)
+		if assert.Nil(t, err) {
+			require.Equal(t, expectedInterval, interval)
+		}
+	}
+
+	timeout, err := receivedReadyConditions.GetTimeout()
+	if assert.Nil(t, err) {
+		expectedTimeout, err := time.ParseDuration(TestReadyConditionsTimeout)
+		if assert.Nil(t, err) {
+			require.Equal(t, expectedTimeout, timeout)
+		}
+	}
+
+}
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/request_framework_test_case_1.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/request_framework_test_case_1_test.go
similarity index 82%
rename from core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/request_framework_test_case_1.go
rename to core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/request_framework_test_case_1_test.go
index 5e168c15a..246405ab9 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/request_framework_test_case_1.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/request_framework_test_case_1_test.go
@@ -17,12 +17,12 @@ import (
 )
 
 const (
-	requestTestCase1ServiceName = service.ServiceName("web-server")
-	requestPortId               = "port_id"
-	requestMethod               = "GET"
-	requestContentType          = ""
-	requestEndpoint             = "/"
-	requestBody                 = ""
+	requestTestCaseServiceName = service.ServiceName("web-server")
+	requestPortId              = "port_id"
+	requestMethod              = "GET"
+	requestContentType         = ""
+	requestEndpoint            = "/"
+	requestBody                = ""
 
 	requestResponseBody = `{"value": "Hello World!"}`
 )
@@ -47,7 +47,7 @@ func (t *requestTestCase1) GetInstruction() *kurtosis_plan_instruction.KurtosisP
 
 	serviceNetwork.EXPECT().HttpRequestService(
 		mock.Anything,
-		string(requestTestCase1ServiceName),
+		string(requestTestCaseServiceName),
 		requestPortId,
 		requestMethod,
 		requestContentType,
@@ -77,8 +77,8 @@ func (t *requestTestCase1) GetInstruction() *kurtosis_plan_instruction.KurtosisP
 }
 
 func (t *requestTestCase1) GetStarlarkCode() string {
-	recipe := fmt.Sprintf(`GetHttpRequestRecipe(port_id=%q, service_name=%q, endpoint=%q, extract={"key": ".value"})`, requestPortId, requestTestCase1ServiceName, requestEndpoint)
-	return fmt.Sprintf("%s(%s=%s)", request.RequestBuiltinName, request.RecipeArgName, recipe)
+	recipe := fmt.Sprintf(`GetHttpRequestRecipe(port_id=%q, endpoint=%q, extract={"key": ".value"})`, requestPortId, requestEndpoint)
+	return fmt.Sprintf("%s(%s=%s, %s=%q)", request.RequestBuiltinName, request.RecipeArgName, recipe, request.ServiceNameArgName, requestTestCaseServiceName)
 }
 
 func (t *requestTestCase1) GetStarlarkCodeForAssertion() string {
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/request_framework_test_case_2.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/request_framework_test_case_2_test.go
similarity index 78%
rename from core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/request_framework_test_case_2.go
rename to core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/request_framework_test_case_2_test.go
index 2da322378..05db441ef 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/request_framework_test_case_2.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/request_framework_test_case_2_test.go
@@ -15,8 +15,7 @@ import (
 	"testing"
 )
 
-//This test case is for testing positional arguments retro-compatibility for those script
-//that are using the recipe value as the first positional argument
+//This test case is for testing positional arguments
 type requestTestCase2 struct {
 	*testing.T
 }
@@ -37,7 +36,7 @@ func (t *requestTestCase2) GetInstruction() *kurtosis_plan_instruction.KurtosisP
 
 	serviceNetwork.EXPECT().HttpRequestService(
 		mock.Anything,
-		string(requestTestCase1ServiceName),
+		string(requestTestCaseServiceName),
 		requestPortId,
 		requestMethod,
 		requestContentType,
@@ -67,13 +66,13 @@ func (t *requestTestCase2) GetInstruction() *kurtosis_plan_instruction.KurtosisP
 }
 
 func (t *requestTestCase2) GetStarlarkCode() string {
-	recipe := fmt.Sprintf(`GetHttpRequestRecipe(port_id=%q, service_name=%q, endpoint=%q, extract={"key": ".value"})`, requestPortId, requestTestCase1ServiceName, requestEndpoint)
-	return fmt.Sprintf("%s(%s)", request.RequestBuiltinName, recipe)
+	recipe := fmt.Sprintf(`GetHttpRequestRecipe(port_id=%q, endpoint=%q, extract={"key": ".value"})`, requestPortId, requestEndpoint)
+	return fmt.Sprintf("%s(%s, %q)", request.RequestBuiltinName, recipe, requestTestCaseServiceName)
 }
 
 func (t *requestTestCase2) GetStarlarkCodeForAssertion() string {
-	recipe := fmt.Sprintf(`GetHttpRequestRecipe(port_id=%q, service_name=%q, endpoint=%q, extract={"key": ".value"})`, requestPortId, requestTestCase1ServiceName, requestEndpoint)
-	return fmt.Sprintf("%s(%s=%s)", request.RequestBuiltinName, request.RecipeArgName, recipe)
+	recipe := fmt.Sprintf(`GetHttpRequestRecipe(port_id=%q, endpoint=%q, extract={"key": ".value"})`, requestPortId, requestEndpoint)
+	return fmt.Sprintf("%s(%s=%s, %s=%q)", request.RequestBuiltinName, request.RecipeArgName, recipe, request.ServiceNameArgName, requestTestCaseServiceName)
 }
 
 func (t *requestTestCase2) Assert(interpretationResult starlark.Value, executionResult *string) {
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/request_framework_test_case_3.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/request_framework_test_case_3.go
deleted file mode 100644
index 6c96240e2..000000000
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/request_framework_test_case_3.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package test_engine
-
-import (
-	"fmt"
-	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/service_network"
-	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/request"
-	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/kurtosis_plan_instruction"
-	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/runtime_value_store"
-	"github.com/stretchr/testify/mock"
-	"github.com/stretchr/testify/require"
-	"go.starlark.net/starlark"
-	"io"
-	"net/http"
-	"strings"
-	"testing"
-)
-
-//For a short period (until we deprecate recipe.service_name) the request instruction will have a
-//dynamic first parameter which will accept the current 'recipe' argument and a new 'service_name' argument
-//In the requestTestCase1 we test the current behaviour, it means receiving an 'recipe' as the first argument
-//In this test case we test that 'service_name' is also accepted as the first parameter, and it is used
-//in the serviceNetwork.HttpRequestService call
-type requestTestCase3 struct {
-	*testing.T
-}
-
-func newRequestTestCase3(t *testing.T) *requestTestCase3 {
-	return &requestTestCase3{
-		T: t,
-	}
-}
-
-func (t *requestTestCase3) GetId() string {
-	return request.RequestBuiltinName
-}
-
-func (t *requestTestCase3) GetInstruction() *kurtosis_plan_instruction.KurtosisPlanInstruction {
-	serviceNetwork := service_network.NewMockServiceNetwork(t)
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
-
-	serviceNetwork.EXPECT().HttpRequestService(
-		mock.Anything,
-		string(requestTestCase1ServiceName),
-		requestPortId,
-		requestMethod,
-		requestContentType,
-		requestEndpoint,
-		requestBody,
-	).Times(1).Return(
-		&http.Response{
-			Status:           "200 OK",
-			StatusCode:       200,
-			Proto:            "HTTP/1.0",
-			ProtoMajor:       1,
-			ProtoMinor:       0,
-			Header:           nil,
-			Body:             io.NopCloser(strings.NewReader(requestResponseBody)),
-			ContentLength:    -1,
-			TransferEncoding: nil,
-			Close:            false,
-			Uncompressed:     false,
-			Trailer:          nil,
-			Request:          nil,
-			TLS:              nil,
-		},
-		nil,
-	)
-
-	return request.NewRequest(serviceNetwork, runtimeValueStore)
-}
-
-func (t *requestTestCase3) GetStarlarkCode() string {
-	recipe := fmt.Sprintf(`GetHttpRequestRecipe(port_id=%q, endpoint=%q, extract={"key": ".value"})`, requestPortId, requestEndpoint)
-	return fmt.Sprintf("%s(%s=%s, %s=%q)", request.RequestBuiltinName, request.RecipeArgName, recipe, request.ServiceNameArgName, requestTestCase1ServiceName)
-}
-
-func (t *requestTestCase3) GetStarlarkCodeForAssertion() string {
-	return ""
-}
-
-func (t *requestTestCase3) Assert(interpretationResult starlark.Value, executionResult *string) {
-	expectedInterpretationResultMap := `{"body": "{{kurtosis:[0-9a-f]{32}:body.runtime_value}}", "code": "{{kurtosis:[0-9a-f]{32}:code.runtime_value}}", "extract.key": "{{kurtosis:[0-9a-f]{32}:extract.key.runtime_value}}"}`
-	require.Regexp(t, expectedInterpretationResultMap, interpretationResult.String())
-
-	expectedExecutionResult := `Request had response code '200' and body "{\"value\": \"Hello World!\"}", with extracted fields:
-'extract.key': "Hello World!"`
-	require.Equal(t, expectedExecutionResult, *executionResult)
-}
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_full_framework_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_full_framework_test.go
index 70a73e819..7bddbbd4c 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_full_framework_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/service_config_full_framework_test.go
@@ -31,7 +31,7 @@ func (t *serviceConfigFullTestCase) GetTypeConstructor() *kurtosis_type_construc
 }
 
 func (t *serviceConfigFullTestCase) GetStarlarkCode() string {
-	return fmt.Sprintf("%s(%s=%q, %s=%s, %s=%s, %s=%s, %s=%s, %s=%s, %s=%s, %s=%q, %s=%q, %s=%d, %s=%d)",
+	starlarkCode := fmt.Sprintf("%s(%s=%q, %s=%s, %s=%s, %s=%s, %s=%s, %s=%s, %s=%s, %s=%q, %s=%q, %s=%d, %s=%d, %s=%s)",
 		service_config.ServiceConfigTypeName,
 		service_config.ImageAttr, TestContainerImageName,
 		service_config.PortsAttr, fmt.Sprintf("{%q: PortSpec(number=%d, transport_protocol=%q, application_protocol=%q)}", TestPrivatePortId, TestPrivatePortNumber, TestPrivatePortProtocolStr, TestPrivateApplicationProtocol),
@@ -44,7 +44,10 @@ func (t *serviceConfigFullTestCase) GetStarlarkCode() string {
 		service_config.SubnetworkAttr, TestSubnetwork,
 		service_config.CpuAllocationAttr, TestCpuAllocation,
 		service_config.MemoryAllocationAttr, TestMemoryAllocation,
+		service_config.ReadyConditionsAttr,
+		getDefaultReadyConditionsScriptPart(),
 	)
+	return starlarkCode
 }
 
 func (t *serviceConfigFullTestCase) Assert(typeValue starlark.Value) {
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/shared_functions_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/shared_functions_test.go
new file mode 100644
index 000000000..186dbb3aa
--- /dev/null
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/shared_functions_test.go
@@ -0,0 +1,53 @@
+package test_engine
+
+import (
+	"fmt"
+	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_types/service_config"
+	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/recipe"
+)
+
+func getDefaultReadyConditionsScriptPart() string {
+	return getCustomReadyConditionsScripPart(
+		TestReadyConditionsRecipePortId,
+		TestReadyConditionsRecipeEndpoint,
+		TestReadyConditionsRecipeExtract,
+		TestReadyConditionsField,
+		TestReadyConditionsAssertion,
+		TestReadyConditionsTarget,
+		TestReadyConditionsInterval,
+		TestReadyConditionsTimeout,
+	)
+}
+
+func getCustomReadyConditionsScripPart(
+	portStr string,
+	endpointStr string,
+	extractStr string,
+	fieldStr string,
+	assertionStr string,
+	targetStr string,
+	intervalStr string,
+	timeoutStr string,
+) string {
+	return fmt.Sprintf("%s(%s=%s(%s=%q, %s=%q, %s=%s), %s=%q, %s=%q, %s=%s, %s=%q, %s=%q)",
+		service_config.ReadyConditionsTypeName,
+		service_config.RecipeAttr,
+		recipe.GetHttpRecipeTypeName,
+		recipe.PortIdAttr,
+		portStr,
+		recipe.EndpointAttr,
+		endpointStr,
+		recipe.ExtractKeyPrefix,
+		extractStr,
+		service_config.FieldAttr,
+		fieldStr,
+		service_config.AssertionAttr,
+		assertionStr,
+		service_config.TargetAttr,
+		targetStr,
+		service_config.IntervalAttr,
+		intervalStr,
+		service_config.TimeoutAttr,
+		timeoutStr,
+	)
+}
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/starlark_framework_engine_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/starlark_framework_engine_test.go
index d84307b2d..615568493 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/starlark_framework_engine_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/starlark_framework_engine_test.go
@@ -26,7 +26,6 @@ func TestAllRegisteredBuiltins(t *testing.T) {
 	testKurtosisPlanInstruction(t, newAssertTestCase(t))
 	testKurtosisPlanInstruction(t, newExecTestCase1(t))
 	testKurtosisPlanInstruction(t, newExecTestCase2(t))
-	testKurtosisPlanInstruction(t, newExecTestCase3(t))
 	testKurtosisPlanInstruction(t, newSetConnectionTestCase(t))
 	testKurtosisPlanInstruction(t, newSetConnectionDefaultTestCase(t))
 	testKurtosisPlanInstruction(t, newPrintTestCase(t))
@@ -36,7 +35,6 @@ func TestAllRegisteredBuiltins(t *testing.T) {
 	testKurtosisPlanInstruction(t, newRenderMultipleTemplatesTestCase(t))
 	testKurtosisPlanInstruction(t, newRequestTestCase1(t))
 	testKurtosisPlanInstruction(t, newRequestTestCase2(t))
-	testKurtosisPlanInstruction(t, newRequestTestCase3(t))
 	testKurtosisPlanInstruction(t, newStoreServiceFilesTestCase(t))
 	testKurtosisPlanInstruction(t, newStoreServiceFilesWithoutNameTestCase(t))
 	testKurtosisPlanInstruction(t, newUpdateServiceTestCase(t))
@@ -44,7 +42,6 @@ func TestAllRegisteredBuiltins(t *testing.T) {
 	testKurtosisPlanInstruction(t, newUploadFilesWithoutNameTestCase(t))
 	testKurtosisPlanInstruction(t, newWaitTestCase1(t))
 	testKurtosisPlanInstruction(t, newWaitTestCase2(t))
-	testKurtosisPlanInstruction(t, newWaitTestCase3(t))
 
 	testKurtosisHelper(t, newReadFileTestCase(t))
 	testKurtosisHelper(t, newImportModuleTestCase(t))
@@ -60,6 +57,7 @@ func TestAllRegisteredBuiltins(t *testing.T) {
 	testKurtosisTypeConstructor(t, newServiceConfigFullTestCase(t))
 	testKurtosisTypeConstructor(t, newUniformPacketDelayDistributionTestCase(t))
 	testKurtosisTypeConstructor(t, newUpdateServiceConfigTestCase(t))
+	testKurtosisTypeConstructor(t, newReadyConditionsTestCase(t))
 }
 
 func testKurtosisPlanInstruction(t *testing.T, builtin KurtosisPlanInstructionBaseTest) {
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/static_constants_test.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/static_constants_test.go
index aa577536d..f42b01c58 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/static_constants_test.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/static_constants_test.go
@@ -66,4 +66,24 @@ var (
 	TestCpuAllocation = uint64(2000)
 
 	TestMemoryAllocation = uint64(1024)
+
+	TestReadyConditionsRecipePortId   = "http"
+	TestReadyConditionsRecipeEndpoint = "/endpoint?input=data"
+	TestReadyConditionsRecipeExtract  = "{}"
+	TestReadyConditionsField          = "code"
+	TestReadyConditionsAssertion      = "=="
+	TestReadyConditionsTarget         = "200"
+	TestReadyConditionsInterval       = "1s"
+	TestReadyConditionsTimeout        = "100ms"
+
+	TestReadyConditions2RecipePortId   = "https"
+	TestReadyConditions2RecipeEndpoint = "/user-access"
+	TestReadyConditions2RecipeExtract  = "{}"
+	TestReadyConditions2Field          = "code"
+	TestReadyConditions2Assertion      = "=="
+	TestReadyConditions2Target         = "201"
+	TestReadyConditions2Interval       = "500ms"
+	TestReadyConditions2Timeout        = "2s"
+
+	TestGetRequestMethod = "GET"
 )
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/wait_framework_test_case_1.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/wait_framework_test_case_1_test.go
similarity index 83%
rename from core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/wait_framework_test_case_1.go
rename to core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/wait_framework_test_case_1_test.go
index 3cb841d37..4e725cf98 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/wait_framework_test_case_1.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/wait_framework_test_case_1_test.go
@@ -17,6 +17,8 @@ import (
 )
 
 const (
+	waitRecipeTestCaseServiceName = service.ServiceName("web-server")
+
 	waitAssertion   = "=="
 	waitInterval    = "1s"
 	waitTargetValue = "200"
@@ -24,7 +26,6 @@ const (
 	waitValueField  = "code"
 
 	waitRecipePortId       = "http-port"
-	waitRecipeServiceName  = service.ServiceName("web-server")
 	waitRecipeMethod       = "POST"
 	waitRecipeEndpoint     = "/"
 	waitRecipeBody         = "{}"
@@ -52,7 +53,7 @@ func (t *waitTestCase1) GetInstruction() *kurtosis_plan_instruction.KurtosisPlan
 
 	serviceNetwork.EXPECT().HttpRequestService(
 		mock.Anything,
-		string(waitRecipeServiceName),
+		string(waitRecipeTestCaseServiceName),
 		waitRecipePortId,
 		waitRecipeMethod,
 		waitRecipeContentType,
@@ -82,8 +83,8 @@ func (t *waitTestCase1) GetInstruction() *kurtosis_plan_instruction.KurtosisPlan
 }
 
 func (t *waitTestCase1) GetStarlarkCode() string {
-	recipeStr := fmt.Sprintf(`PostHttpRequestRecipe(port_id=%q, service_name=%q, endpoint=%q, body=%q, content_type=%q, extract={"key": ".value"})`, waitRecipePortId, waitRecipeServiceName, waitRecipeEndpoint, waitRecipeBody, waitRecipeContentType)
-	return fmt.Sprintf("%s(%s=%s, %s=%q, %s=%q, %s=%s, %s=%q, %s=%q)", wait.WaitBuiltinName, wait.RecipeArgName, recipeStr, wait.ValueFieldArgName, waitValueField, wait.AssertionArgName, waitAssertion, wait.TargetArgName, waitTargetValue, wait.IntervalArgName, waitInterval, wait.TimeoutArgName, waitTimeout)
+	recipeStr := fmt.Sprintf(`PostHttpRequestRecipe(port_id=%q, endpoint=%q, body=%q, content_type=%q, extract={"key": ".value"})`, waitRecipePortId, waitRecipeEndpoint, waitRecipeBody, waitRecipeContentType)
+	return fmt.Sprintf("%s(%s=%s, %s=%q, %s=%q, %s=%s, %s=%q, %s=%q, %s=%q)", wait.WaitBuiltinName, wait.RecipeArgName, recipeStr, wait.ValueFieldArgName, waitValueField, wait.AssertionArgName, waitAssertion, wait.TargetArgName, waitTargetValue, wait.IntervalArgName, waitInterval, wait.TimeoutArgName, waitTimeout, wait.ServiceNameArgName, waitRecipeTestCaseServiceName)
 }
 
 func (t *waitTestCase1) GetStarlarkCodeForAssertion() string {
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/wait_framework_test_case_2.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/wait_framework_test_case_2_test.go
similarity index 74%
rename from core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/wait_framework_test_case_2.go
rename to core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/wait_framework_test_case_2_test.go
index cb234cbd3..295409d7d 100644
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/wait_framework_test_case_2.go
+++ b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/wait_framework_test_case_2_test.go
@@ -37,7 +37,7 @@ func (t *waitTestCase2) GetInstruction() *kurtosis_plan_instruction.KurtosisPlan
 
 	serviceNetwork.EXPECT().HttpRequestService(
 		mock.Anything,
-		string(waitRecipeServiceName),
+		string(waitRecipeTestCaseServiceName),
 		waitRecipePortId,
 		waitRecipeMethod,
 		waitRecipeContentType,
@@ -67,13 +67,13 @@ func (t *waitTestCase2) GetInstruction() *kurtosis_plan_instruction.KurtosisPlan
 }
 
 func (t *waitTestCase2) GetStarlarkCode() string {
-	recipeStr := fmt.Sprintf(`PostHttpRequestRecipe(port_id=%q, service_name=%q, endpoint=%q, body=%q, content_type=%q, extract={"key": ".value"})`, waitRecipePortId, waitRecipeServiceName, waitRecipeEndpoint, waitRecipeBody, waitRecipeContentType)
-	return fmt.Sprintf("%s(%s, %q, %q, %s, %q, %q)", wait.WaitBuiltinName, recipeStr, waitValueField, waitAssertion, waitTargetValue, waitInterval, waitTimeout)
+	recipeStr := fmt.Sprintf(`PostHttpRequestRecipe(port_id=%q, endpoint=%q, body=%q, content_type=%q, extract={"key": ".value"})`, waitRecipePortId, waitRecipeEndpoint, waitRecipeBody, waitRecipeContentType)
+	return fmt.Sprintf("%s(%s, %q, %q, %s, %q, %q, %q)", wait.WaitBuiltinName, recipeStr, waitValueField, waitAssertion, waitTargetValue, waitInterval, waitTimeout, waitRecipeTestCaseServiceName)
 }
 
 func (t *waitTestCase2) GetStarlarkCodeForAssertion() string {
-	recipeStr := fmt.Sprintf(`PostHttpRequestRecipe(port_id=%q, service_name=%q, endpoint=%q, body=%q, content_type=%q, extract={"key": ".value"})`, waitRecipePortId, waitRecipeServiceName, waitRecipeEndpoint, waitRecipeBody, waitRecipeContentType)
-	return fmt.Sprintf("%s(%s=%s, %s=%q, %s=%q, %s=%s, %s=%q, %s=%q)", wait.WaitBuiltinName, wait.RecipeArgName, recipeStr, wait.ValueFieldArgName, waitValueField, wait.AssertionArgName, waitAssertion, wait.TargetArgName, waitTargetValue, wait.IntervalArgName, waitInterval, wait.TimeoutArgName, waitTimeout)
+	recipeStr := fmt.Sprintf(`PostHttpRequestRecipe(port_id=%q, endpoint=%q, body=%q, content_type=%q, extract={"key": ".value"})`, waitRecipePortId, waitRecipeEndpoint, waitRecipeBody, waitRecipeContentType)
+	return fmt.Sprintf("%s(%s=%s, %s=%q, %s=%q, %s=%s, %s=%q, %s=%q, %s=%q)", wait.WaitBuiltinName, wait.RecipeArgName, recipeStr, wait.ValueFieldArgName, waitValueField, wait.AssertionArgName, waitAssertion, wait.TargetArgName, waitTargetValue, wait.IntervalArgName, waitInterval, wait.TimeoutArgName, waitTimeout, wait.ServiceNameArgName, waitRecipeTestCaseServiceName)
 }
 
 func (t *waitTestCase2) Assert(interpretationResult starlark.Value, executionResult *string) {
diff --git a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/wait_framework_test_case_3.go b/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/wait_framework_test_case_3.go
deleted file mode 100644
index ecf9078d8..000000000
--- a/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/test_engine/wait_framework_test_case_3.go
+++ /dev/null
@@ -1,95 +0,0 @@
-package test_engine
-
-import (
-	"fmt"
-	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service"
-	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/service_network"
-	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_instruction/wait"
-	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/kurtosis_starlark_framework/kurtosis_plan_instruction"
-	"github.com/kurtosis-tech/kurtosis/core/server/api_container/server/startosis_engine/runtime_value_store"
-	"github.com/stretchr/testify/mock"
-	"github.com/stretchr/testify/require"
-	"go.starlark.net/starlark"
-	"io"
-	"net/http"
-	"strings"
-	"testing"
-)
-
-const (
-	waitServiceName = service.ServiceName("web-server")
-)
-
-//For a short period (until we deprecate recipe.service_name) the wait instruction will have a
-//dynamic first parameter which will accept the current 'recipe' argument and a new 'service_name' argument
-//In the waitTestCase1 we test the current behaviour, it means receiving an 'recipe' as the first argument
-//In this test case we test that 'service_name' is also accepted as the first parameter, and it is used
-//in the serviceNetwork.HttpRequestService call
-type waitTestCase3 struct {
-	*testing.T
-}
-
-func newWaitTestCase3(t *testing.T) *waitTestCase3 {
-	return &waitTestCase3{
-		T: t,
-	}
-}
-
-func (t *waitTestCase3) GetId() string {
-	return wait.WaitBuiltinName
-}
-
-func (t *waitTestCase3) GetInstruction() *kurtosis_plan_instruction.KurtosisPlanInstruction {
-	serviceNetwork := service_network.NewMockServiceNetwork(t)
-	runtimeValueStore := runtime_value_store.NewRuntimeValueStore()
-
-	serviceNetwork.EXPECT().HttpRequestService(
-		mock.Anything,
-		string(waitServiceName),
-		waitRecipePortId,
-		waitRecipeMethod,
-		waitRecipeContentType,
-		waitRecipeEndpoint,
-		waitRecipeBody,
-	).Times(1).Return(
-		&http.Response{
-			Status:           "200 OK",
-			StatusCode:       200,
-			Proto:            "HTTP/1.0",
-			ProtoMajor:       1,
-			ProtoMinor:       0,
-			Header:           nil,
-			Body:             io.NopCloser(strings.NewReader(waitRecipeResponseBody)),
-			ContentLength:    -1,
-			TransferEncoding: nil,
-			Close:            false,
-			Uncompressed:     false,
-			Trailer:          nil,
-			Request:          nil,
-			TLS:              nil,
-		},
-		nil,
-	)
-
-	return wait.NewWait(serviceNetwork, runtimeValueStore)
-}
-
-func (t *waitTestCase3) GetStarlarkCode() string {
-	recipeStr := fmt.Sprintf(`PostHttpRequestRecipe(port_id=%q, endpoint=%q, body=%q, content_type=%q, extract={"key": ".value"})`, waitRecipePortId, waitRecipeEndpoint, waitRecipeBody, waitRecipeContentType)
-	return fmt.Sprintf("%s(%s=%s, %s=%q, %s=%q, %s=%s, %s=%q, %s=%q, %s=%q)", wait.WaitBuiltinName, wait.RecipeArgName, recipeStr, wait.ValueFieldArgName, waitValueField, wait.AssertionArgName, waitAssertion, wait.TargetArgName, waitTargetValue, wait.IntervalArgName, waitInterval, wait.TimeoutArgName, waitTimeout, wait.ServiceNameArgName, waitServiceName)
-}
-
-func (t *waitTestCase3) GetStarlarkCodeForAssertion() string {
-	return ""
-}
-
-func (t *waitTestCase3) Assert(interpretationResult starlark.Value, executionResult *string) {
-	expectedInterpretationResult := `{"body": "{{kurtosis:[0-9a-f]{32}:body.runtime_value}}", "code": "{{kurtosis:[0-9a-f]{32}:code.runtime_value}}", "extract.key": "{{kurtosis:[0-9a-f]{32}:extract.key.runtime_value}}"}`
-	require.Regexp(t, expectedInterpretationResult, interpretationResult.String())
-
-	expectedExecutionResult := `Assertion passed with following:
-Request had response code '200' and body "{\"value\": \"Hello world!\"}", with extracted fields:
-'extract.key': "Hello world!"`
-
-	require.Contains(t, *executionResult, expectedExecutionResult)
-}
diff --git a/core/server/api_container/server/startosis_engine/recipe/exec_recipe_test.go b/core/server/api_container/server/startosis_engine/recipe/exec_recipe_test.go
index 0e3520d9d..b59de44d1 100644
--- a/core/server/api_container/server/startosis_engine/recipe/exec_recipe_test.go
+++ b/core/server/api_container/server/startosis_engine/recipe/exec_recipe_test.go
@@ -1,17 +1,15 @@
 package recipe
 
 import (
-	"github.com/kurtosis-tech/kurtosis/container-engine-lib/lib/backend_interface/objects/service"
 	"github.com/stretchr/testify/require"
 	"testing"
 )
 
 func TestExecRecipe_String(t *testing.T) {
-	serviceName := service.ServiceName("serviceName")
 	commands := []string{"echo", "run"}
 
-	expectedRecipeString := `ExecRecipe(service_name="serviceName", command=["echo", "run"])`
-	execRecipe := NewExecRecipe(serviceName, commands)
+	expectedRecipeString := `ExecRecipe(command=["echo", "run"])`
+	execRecipe := NewExecRecipe(commands)
 	execRecipeString := execRecipe.String()
 	require.Equal(t, expectedRecipeString, execRecipeString)
 }
diff --git a/core/server/api_container/server/startosis_engine/recipe/http_request_recipe_test.go b/core/server/api_container/server/startosis_engine/recipe/http_request_recipe_test.go
index e9f3f76a2..71d3ba35b 100644
--- a/core/server/api_container/server/startosis_engine/recipe/http_request_recipe_test.go
+++ b/core/server/api_container/server/startosis_engine/recipe/http_request_recipe_test.go
@@ -15,15 +15,11 @@ func TestGetHttpRequestRecipe_String(t *testing.T) {
 	builtin.Name()
 	kwargs := []starlark.Tuple{
 		starlark.Tuple([]starlark.Value{
-			starlark.String(serviceNameKey),
-			starlark.String("web-server"),
-		}),
-		starlark.Tuple([]starlark.Value{
-			starlark.String(endpointAttr),
+			starlark.String(EndpointAttr),
 			starlark.String("?input=output"),
 		}),
 		starlark.Tuple([]starlark.Value{
-			starlark.String(portIdAttr),
+			starlark.String(PortIdAttr),
 			starlark.String("portId"),
 		}),
 	}
@@ -31,7 +27,7 @@ func TestGetHttpRequestRecipe_String(t *testing.T) {
 	require.Nil(t, err, "Unexpected error occurred")
 
 	getHttpRequestRecipeString := getHttpRequestRecipe.String()
-	expectedStringOutput := `GetHttpRequestRecipe(port_id="portId", service_name="web-server", endpoint="?input=output", extract="")`
+	expectedStringOutput := `GetHttpRequestRecipe(port_id="portId", endpoint="?input=output", extract="")`
 	require.NotNil(t, expectedStringOutput, getHttpRequestRecipeString)
 
 	extractors := starlark.NewDict(1)
@@ -39,19 +35,15 @@ func TestGetHttpRequestRecipe_String(t *testing.T) {
 	require.Nil(t, err)
 	kwargsWithExtractors := []starlark.Tuple{
 		starlark.Tuple([]starlark.Value{
-			starlark.String(serviceNameKey),
-			starlark.String("web-server"),
-		}),
-		starlark.Tuple([]starlark.Value{
-			starlark.String(endpointAttr),
+			starlark.String(EndpointAttr),
 			starlark.String("?input=output"),
 		}),
 		starlark.Tuple([]starlark.Value{
-			starlark.String(portIdAttr),
+			starlark.String(PortIdAttr),
 			starlark.String("portId"),
 		}),
 		starlark.Tuple([]starlark.Value{
-			starlark.String(extractKeyPrefix),
+			starlark.String(ExtractKeyPrefix),
 			extractors,
 		}),
 	}
@@ -60,7 +52,7 @@ func TestGetHttpRequestRecipe_String(t *testing.T) {
 	require.Nil(t, err, "Unexpected error occurred")
 
 	getHttpRequestRecipeWithExtractorsString := getHttpRequestRecipeWithExtractors.String()
-	expectedStringOutputWithExtractors := `GetHttpRequestRecipe(port_id="portId", service_name="web-server", endpoint="?input=output", extract={"field": ".input.*"})`
+	expectedStringOutputWithExtractors := `GetHttpRequestRecipe(port_id="portId", endpoint="?input=output", extract={"field": ".input.*"})`
 	require.NotNil(t, expectedStringOutputWithExtractors, getHttpRequestRecipeWithExtractorsString)
 }
 
@@ -68,15 +60,11 @@ func TestPostHttpRequestRecipe_String(t *testing.T) {
 	builtin := &starlark.Builtin{}
 	kwargs := []starlark.Tuple{
 		starlark.Tuple([]starlark.Value{
-			starlark.String(serviceNameKey),
-			starlark.String("web-server"),
-		}),
-		starlark.Tuple([]starlark.Value{
-			starlark.String(endpointAttr),
+			starlark.String(EndpointAttr),
 			starlark.String("?input=output"),
 		}),
 		starlark.Tuple([]starlark.Value{
-			starlark.String(portIdAttr),
+			starlark.String(PortIdAttr),
 			starlark.String("portId"),
 		}),
 		starlark.Tuple([]starlark.Value{
@@ -92,7 +80,7 @@ func TestPostHttpRequestRecipe_String(t *testing.T) {
 	require.Nil(t, err, "Unexpected error occurred")
 
 	postHttpRequestRecipeString := postHttpRequestRecipe.String()
-	expectedStringOutput := `PostHttpRequestRecipe(port_id="portId", service_name="web-server", endpoint="?input=output", body="body", content_type="content-type", extract="")`
+	expectedStringOutput := `PostHttpRequestRecipe(port_id="portId", endpoint="?input=output", body="body", content_type="content-type", extract="")`
 	require.NotNil(t, expectedStringOutput, postHttpRequestRecipeString)
 
 	extractors := starlark.NewDict(1)
@@ -100,19 +88,15 @@ func TestPostHttpRequestRecipe_String(t *testing.T) {
 	require.Nil(t, err)
 	kwargsWithExtractors := []starlark.Tuple{
 		starlark.Tuple([]starlark.Value{
-			starlark.String(serviceNameKey),
-			starlark.String("web-server"),
-		}),
-		starlark.Tuple([]starlark.Value{
-			starlark.String(endpointAttr),
+			starlark.String(EndpointAttr),
 			starlark.String("?input=output"),
 		}),
 		starlark.Tuple([]starlark.Value{
-			starlark.String(portIdAttr),
+			starlark.String(PortIdAttr),
 			starlark.String("portId"),
 		}),
 		starlark.Tuple([]starlark.Value{
-			starlark.String(extractKeyPrefix),
+			starlark.String(ExtractKeyPrefix),
 			extractors,
 		}),
 		starlark.Tuple([]starlark.Value{
@@ -129,7 +113,7 @@ func TestPostHttpRequestRecipe_String(t *testing.T) {
 	require.Nil(t, err, "Unexpected error occurred")
 
 	postHttpRequestRecipeWithExtractorsString := postHttpRequestRecipeWithExtractors.String()
-	expectedStringOutputWithExtractors := `PostHttpRequestRecipe(port_id="portId", service_name="web-server", endpoint="?input=output", body="body", content_type="content-type", extract={"field": ".input.*"})`
+	expectedStringOutputWithExtractors := `PostHttpRequestRecipe(port_id="portId", endpoint="?input=output", body="body", content_type="content-type", extract={"field": ".input.*"})`
 	require.NotNil(t, expectedStringOutputWithExtractors, postHttpRequestRecipeWithExtractorsString)
 }
 
@@ -137,11 +121,7 @@ func TestStartosisInterpreter_HttpRequestMissingRequiredFields(t *testing.T) {
 	builtin := &starlark.Builtin{}
 	kwargs := []starlark.Tuple{
 		starlark.Tuple([]starlark.Value{
-			starlark.String(serviceNameKey),
-			starlark.String("web-server"),
-		}),
-		starlark.Tuple([]starlark.Value{
-			starlark.String(endpointAttr),
+			starlark.String(EndpointAttr),
 			starlark.String("?input=output"),
 		}),
 	}
@@ -158,15 +138,11 @@ func TestStartosisInterpreter_MissingRequiredFieldForHttpRecipeWithPostMethod(t
 	require.Nil(t, err)
 	kwargsWithoutBody := []starlark.Tuple{
 		starlark.Tuple([]starlark.Value{
-			starlark.String(serviceNameKey),
-			starlark.String("web-server"),
-		}),
-		starlark.Tuple([]starlark.Value{
-			starlark.String(portIdAttr),
+			starlark.String(PortIdAttr),
 			starlark.String("portId"),
 		}),
 		starlark.Tuple([]starlark.Value{
-			starlark.String(extractKeyPrefix),
+			starlark.String(ExtractKeyPrefix),
 			extractors,
 		}),
 		starlark.Tuple([]starlark.Value{
@@ -186,15 +162,11 @@ func TestHttpRequestRecipe_TestContentIsNotRequiredAndDefaultsToApplicationJson(
 	builtin := &starlark.Builtin{}
 	kwargs := []starlark.Tuple{
 		starlark.Tuple([]starlark.Value{
-			starlark.String(serviceNameKey),
-			starlark.String("web-server"),
-		}),
-		starlark.Tuple([]starlark.Value{
-			starlark.String(endpointAttr),
+			starlark.String(EndpointAttr),
 			starlark.String("?input=output"),
 		}),
 		starlark.Tuple([]starlark.Value{
-			starlark.String(portIdAttr),
+			starlark.String(PortIdAttr),
 			starlark.String("portId"),
 		}),
 		starlark.Tuple([]starlark.Value{
diff --git a/core/server/api_container/server/startosis_engine/startosis_interpreter_test.go b/core/server/api_container/server/startosis_engine/startosis_interpreter_test.go
index d5e45b12d..ef038ca81 100644
--- a/core/server/api_container/server/startosis_engine/startosis_interpreter_test.go
+++ b/core/server/api_container/server/startosis_engine/startosis_interpreter_test.go
@@ -64,14 +64,13 @@ func TestStartosisInterpreter_DefineFactAndWait(t *testing.T) {
 	script := `
 def run(plan):
 	get_recipe = GetHttpRequestRecipe(
-		service_name = "web-server",
 		port_id = "http-port",
 		endpoint = "?input=output",
 		extract = {
 			"input": ".query.input"
 		}
 	)
-	response = plan.wait(get_recipe, "code", "==",  200, timeout="5m", interval="5s")
+	response = plan.wait(get_recipe, "code", "==",  200, timeout="5m", interval="5s", service_name = "web-server")
 	plan.print(response["body"])
 `
 	_, instructions, interpretationError := interpreter.Interpret(context.Background(), startosis_constants.PackageIdPlaceholderForStandaloneScript, script, startosis_constants.EmptyInputArgs)
@@ -527,14 +526,13 @@ func TestStartosisInterpreter_RequestInstruction(t *testing.T) {
 	script := `
 def run(plan):
 	get_recipe = GetHttpRequestRecipe(
-		service_name = "web-server",
 		port_id = "http-port",
 		endpoint = "?input=output",
 		extract = {
 			"input": ".query.input"
 		}
 	)
-	response = plan.request(get_recipe)
+	response = plan.request(get_recipe, service_name = "web-server")
 	plan.print(response["code"])`
 
 	_, instructions, interpretationError := interpreter.Interpret(context.Background(), startosis_constants.PackageIdPlaceholderForStandaloneScript, script, startosis_constants.EmptyInputArgs)
@@ -759,10 +757,9 @@ func TestStartosisInterpreter_ValidExecScript(t *testing.T) {
 def run(plan):
 	plan.print("Executing mkdir!")
 	recipe = ExecRecipe(
-		service_name = "example-datastore-server",
 		command = ["mkdir", "/tmp/foo"]
 	)
-	plan.exec(recipe = recipe)
+	plan.exec(recipe = recipe, service_name = "web-server")
 `
 
 	_, instructions, interpretationError := interpreter.Interpret(context.Background(), startosis_constants.PackageIdPlaceholderForStandaloneScript, script, startosis_constants.EmptyInputArgs)
@@ -770,25 +767,6 @@ def run(plan):
 	require.Len(t, instructions, 2)
 }
 
-func TestStartosisInterpreter_ValidExecRecipeWithoutServiceName(t *testing.T) {
-	packageContentProvider := mock_package_content_provider.NewMockPackageContentProvider()
-	defer packageContentProvider.RemoveAll()
-	testRuntimeValueStore := runtime_value_store.NewRuntimeValueStore()
-	interpreter := NewStartosisInterpreter(testServiceNetwork, packageContentProvider, testRuntimeValueStore)
-	script := `
-def run(plan):
-	plan.print("Executing mkdir!")
-	recipe = ExecRecipe(
-		command = ["mkdir", "/tmp/foo"]
-	)
-	plan.exec(recipe = recipe, service_name="my-service")
-`
-
-	_, _, interpretationError := interpreter.Interpret(context.Background(), startosis_constants.PackageIdPlaceholderForStandaloneScript, script, startosis_constants.EmptyInputArgs)
-
-	require.Nil(t, interpretationError)
-}
-
 func TestStartosisInterpreter_InvalidExecRecipeMissingRequiredCommand(t *testing.T) {
 	packageContentProvider := mock_package_content_provider.NewMockPackageContentProvider()
 	defer packageContentProvider.RemoveAll()
@@ -797,9 +775,7 @@ func TestStartosisInterpreter_InvalidExecRecipeMissingRequiredCommand(t *testing
 	script := `
 def run(plan):
 	plan.print("Executing mkdir!")
-	recipe = ExecRecipe(
-		service_name="example-datastore-server"
-	)
+	recipe = ExecRecipe()
 	plan.exec(recipe = recipe)
 `
 
diff --git a/internal_testsuites/golang/test_helpers/test_helpers.go b/internal_testsuites/golang/test_helpers/test_helpers.go
index 766b49519..afb7803e1 100644
--- a/internal_testsuites/golang/test_helpers/test_helpers.go
+++ b/internal_testsuites/golang/test_helpers/test_helpers.go
@@ -87,11 +87,10 @@ const (
 	waitForGetAvaliabilityStalarkScript = `
 def run(plan, args):
 	get_recipe = GetHttpRequestRecipe(
-		service_name = args.service_name,
 		port_id = args.port_id,
 		endpoint = args.endpoint,
 	)
-	plan.wait(get_recipe, "code", "==", 200, args.interval, args.timeout)
+	plan.wait(get_recipe, "code", "==", 200, args.interval, args.timeout, args.service_name)
 `
 	waitForGetAvaliabilityStalarkScriptParams = `{ "service_name": "%s", "port_id": "%s", "endpoint": "/%s", "interval": "%dms", "timeout": "%dms"}`
 
diff --git a/internal_testsuites/golang/testsuite/network_partition_starlark/network_partition_starlark_test.go b/internal_testsuites/golang/testsuite/network_partition_starlark/network_partition_starlark_test.go
index 40d074715..9e0853f57 100644
--- a/internal_testsuites/golang/testsuite/network_partition_starlark/network_partition_starlark_test.go
+++ b/internal_testsuites/golang/testsuite/network_partition_starlark/network_partition_starlark_test.go
@@ -58,27 +58,24 @@ def run(plan, args):
 
 	# Validate connection is indeed blocked
 	connection_result = plan.exec(recipe=ExecRecipe(
-		service_name=SERVICE_NAME_2,
 		command=["ping", "-W", "1", "-c", "1", service_1.hostname],
-	), acceptable_codes = [CONNECTION_FAILURE])
+	), service_name=SERVICE_NAME_2, acceptable_codes = [CONNECTION_FAILURE])
 
 	# Allow connection between 1 and 2
 	plan.set_connection(subnetworks=(SUBNETWORK_1, SUBNETWORK_2), config=kurtosis.connection.ALLOWED)
 
 	# Connection now works
 	connection_result = plan.exec(recipe=ExecRecipe(
-		service_name=SERVICE_NAME_2,
 		command=["ping", "-W", "1", "-c", "1", service_1.ip_address],
-	), acceptable_codes = [CONNECTION_SUCCESS])
+	), service_name=SERVICE_NAME_2, acceptable_codes = [CONNECTION_SUCCESS])
 
 	# Reset connection to default (which is BLOCKED)
 	plan.remove_connection((SUBNETWORK_1, SUBNETWORK_2))
 
 	# Connection is back to BLOCKED
 	connection_result = plan.exec(recipe=ExecRecipe(
-		service_name=SERVICE_NAME_2,
 		command=["ping", "-W", "1", "-c", "1", service_1.hostname],
-	), acceptable_codes = [CONNECTION_FAILURE])
+	), service_name=SERVICE_NAME_2, acceptable_codes = [CONNECTION_FAILURE])
 
 	# Create a third subnetwork connected to SUBNETWORK_1 and add service2 to it
 	plan.set_connection((SUBNETWORK_3, SUBNETWORK_1), config=ConnectionConfig(packet_loss_percentage=0.0))
@@ -86,9 +83,8 @@ def run(plan, args):
 	
 	# Service 2 can now talk to Service 1 again!
 	connection_result = plan.exec(recipe=ExecRecipe(
-		service_name=SERVICE_NAME_2,
 		command=["ping", "-W", "1", "-c", "1", service_1.ip_address],
-	))
+	), service_name=SERVICE_NAME_2)
 	plan.assert(connection_result["code"], "==", CONNECTION_SUCCESS)
 
 	plan.print("Test successfully executed")
diff --git a/internal_testsuites/golang/testsuite/network_partition_starlark_with_delay/network_partition_starlark_with_delay_test.go b/internal_testsuites/golang/testsuite/network_partition_starlark_with_delay/network_partition_starlark_with_delay_test.go
index de50154a2..7def27666 100644
--- a/internal_testsuites/golang/testsuite/network_partition_starlark_with_delay/network_partition_starlark_with_delay_test.go
+++ b/internal_testsuites/golang/testsuite/network_partition_starlark_with_delay/network_partition_starlark_with_delay_test.go
@@ -65,52 +65,46 @@ def run(plan, args):
 	service_one_cmd =  "ping -c 5 -W 5 " + service_1.ip_address +  " | tail -1| awk '{print $4}' | cut -d '/' -f 2"
 	service_three_cmd =  "ping -c 5 -W 5 " + service_3.ip_address +  " | tail -1| awk '{print $4}' | cut -d '/' -f 2"
 
-	recipe=ExecRecipe(
-		service_name=SERVICE_ID_2,
+	recipe = ExecRecipe(
 		command=["/bin/sh", "-c", service_one_cmd],
 	)
-	res = plan.exec(recipe)
+	res = plan.exec(recipe, SERVICE_ID_2)
 	plan.assert(res["output"], "<", "2")
 
-	recipe=ExecRecipe(
-		service_name=SERVICE_ID_2,
+	recipe = ExecRecipe(
 		command=["/bin/sh", "-c", service_three_cmd],
 	)
-	res = plan.exec(recipe)
+	res = plan.exec(recipe, SERVICE_ID_2)
 	plan.assert(res["output"], "<", "2")
 
 	delay = UniformPacketDelayDistribution(750)
 	plan.set_connection(config=ConnectionConfig(packet_delay_distribution=delay))
 	
-	recipe=ExecRecipe(
-		service_name=SERVICE_ID_2,
+	recipe = ExecRecipe(
 		command=["/bin/sh", "-c", service_one_cmd],
 	)
-	res = plan.exec(recipe)
+	res = plan.exec(recipe, SERVICE_ID_2)
 	plan.assert(res["output"], "<", "2")
 
-	recipe=ExecRecipe(
-		service_name=SERVICE_ID_2,
+	recipe = ExecRecipe(
 		command=["/bin/sh", "-c", service_three_cmd],
 	)
 	
 	# this is doing string comparison
 	# have not found a way to convert output to int
-	res = plan.exec(recipe)
+	res = plan.exec(recipe, SERVICE_ID_2)
 	plan.assert(res["output"], ">", "1449")
     
 	uniform_delay_distribution = UniformPacketDelayDistribution(ms=350)	
 	plan.set_connection(config=ConnectionConfig(packet_delay_distribution=uniform_delay_distribution))
 
-	recipe=ExecRecipe(
-		service_name=SERVICE_ID_2,
+	recipe = ExecRecipe(
 		command=["/bin/sh", "-c", service_one_cmd],
 	)
-	res = plan.exec(recipe)
+	res = plan.exec(recipe, SERVICE_ID_2)
 	plan.assert(res["output"], "<", "2")
 
-	recipe=ExecRecipe(
-		service_name=SERVICE_ID_2,
+	recipe = ExecRecipe(
 		command=["/bin/sh", "-c", service_three_cmd],
 	)
 	
@@ -118,7 +112,7 @@ def run(plan, args):
 	# have not found a way to convert output to int
 	# the overall latency should be greater than 350*2, but
 	# added some buffer to handle 50ms outliers
-	res = plan.exec(recipe)
+	res = plan.exec(recipe, SERVICE_ID_2)
 	plan.assert(res["output"], ">", "649")
 	plan.print("Test successfully executed")
 `
diff --git a/internal_testsuites/golang/testsuite/network_partition_update_connection_with_delay_test/network_partition_update_connection_with_delay_test.go b/internal_testsuites/golang/testsuite/network_partition_update_connection_with_delay_test/network_partition_update_connection_with_delay_test.go
index 8522ebb19..60427d733 100644
--- a/internal_testsuites/golang/testsuite/network_partition_update_connection_with_delay_test/network_partition_update_connection_with_delay_test.go
+++ b/internal_testsuites/golang/testsuite/network_partition_update_connection_with_delay_test/network_partition_update_connection_with_delay_test.go
@@ -59,11 +59,11 @@ def run(plan, args):
 	service_one_cmd =  "ping -c 5 -W 5 " + service_1.ip_address +  " | tail -1| awk '{print $4}' | cut -d '/' -f 2"
 
 	# blocked connection
-	recipe=ExecRecipe(
-		service_name=SERVICE_ID_2,
+	recipe = ExecRecipe(
 		command=["ping", "-c", "1", "-W", "1", service_1.ip_address],
 	)
-	res = plan.exec(recipe, acceptable_codes = [1])
+	res = plan.exec(recipe, SERVICE_ID_2, acceptable_codes = [1])
+
 	
 	# unblock connection with some delay 
 	delay = UniformPacketDelayDistribution(ms=750)
@@ -80,11 +80,10 @@ def run(plan, args):
 		)
 	)
 
-	recipe=ExecRecipe(
-		service_name=SERVICE_ID_2,
+	recipe = ExecRecipe(
 		command=["/bin/sh", "-c", service_one_cmd],
 	)
-	res = plan.exec(recipe)
+	res = plan.exec(recipe, SERVICE_ID_2)
 
 	# given a buffer of 55ms to handle outliers
 	# minimum latency observed (280-55 = 225)
@@ -94,20 +93,18 @@ def run(plan, args):
 
 	# remove connection, should block the connection again
 	plan.remove_connection((SUBNETWORK_1, SUBNETWORK_2))
-	recipe=ExecRecipe(
-		service_name=SERVICE_ID_2,
+	recipe = ExecRecipe(
 		command=["ping", "-c", "1", "-W", "1", service_1.ip_address],
 	)
-	res = plan.exec(recipe, acceptable_codes=[1])
+	res = plan.exec(recipe, SERVICE_ID_2, acceptable_codes=[1])
 
 	plan.set_connection((SUBNETWORK_1, SUBNETWORK_3), config=ConnectionConfig(packet_delay_distribution=delay))
 	plan.update_service(SERVICE_ID_2, config=UpdateServiceConfig(subnetwork=SUBNETWORK_3))
-	recipe=ExecRecipe(
-		service_name=SERVICE_ID_2,
+	recipe = ExecRecipe(
 		command=["/bin/sh", "-c", service_one_cmd],
 	)
 
-	res = plan.exec(recipe)
+	res = plan.exec(recipe, SERVICE_ID_2)
 	plan.assert(res["output"], ">", "1449")
 	plan.print("Test successfully executed")
 `
diff --git a/internal_testsuites/golang/testsuite/render_templates_test/render_templates_test.go b/internal_testsuites/golang/testsuite/render_templates_test/render_templates_test.go
index 2bc8e2ea2..b2bc7b19a 100644
--- a/internal_testsuites/golang/testsuite/render_templates_test/render_templates_test.go
+++ b/internal_testsuites/golang/testsuite/render_templates_test/render_templates_test.go
@@ -53,11 +53,10 @@ def run(plan):
 	)
 	for filePath in template_dict:
 		get_recipe = GetHttpRequestRecipe(
-			service_name = "file-server",
 			port_id = "http",
 			endpoint = "/" + filePath,
 		)
-		response = plan.wait(get_recipe, "code", "==", 200)
+		response = plan.wait(recipe=get_recipe, field="code", assertion="==", target_value=200, service_name="file-server")
 		plan.assert(response["body"], "==", expected_contents)
 `
 	noStarlarkParams = "{}"
diff --git a/internal_testsuites/golang/testsuite/starlark_exec_test/starlark_exec_test.go b/internal_testsuites/golang/testsuite/starlark_exec_test/starlark_exec_test.go
index e3b37f937..ea9047aa7 100644
--- a/internal_testsuites/golang/testsuite/starlark_exec_test/starlark_exec_test.go
+++ b/internal_testsuites/golang/testsuite/starlark_exec_test/starlark_exec_test.go
@@ -37,10 +37,9 @@ def run(plan, args):
 	testStarlarkScriptTemplate = `
 def run(plan, args):
 	exec_recipe = ExecRecipe(
-		service_name = "test",
 		command = %v,
 	)
-	exec_result = plan.exec(exec_recipe, acceptable_codes=[0], skip_code_check=True)
+	exec_result = plan.exec(exec_recipe, "test", acceptable_codes=[0], skip_code_check=True)
 	plan.assert(exec_result["code"], "==", %d)
 	plan.assert(exec_result["output"], "==", "%s")
 `
diff --git a/internal_testsuites/golang/testsuite/startosis_add_service_test/startosis_add_service_test.go b/internal_testsuites/golang/testsuite/startosis_add_service_test/startosis_add_service_test.go
index bd6708bb0..7f14b879e 100644
--- a/internal_testsuites/golang/testsuite/startosis_add_service_test/startosis_add_service_test.go
+++ b/internal_testsuites/golang/testsuite/startosis_add_service_test/startosis_add_service_test.go
@@ -39,17 +39,21 @@ def run(plan):
 	datastore_2 = plan.add_service(service_name = SERVICE_NAME_2, config = config)
 
 	test_hostname_cmd = "nc -zv {0} {1}".format(datastore_1.hostname, GRPC_PORT)
-	connection_result = plan.exec(recipe=ExecRecipe(
-		service_name=SERVICE_NAME_2,
-		command=["sh", "-c", test_hostname_cmd],
-	))
+	connection_result = plan.exec(
+		recipe = ExecRecipe(
+			command=["sh", "-c", test_hostname_cmd],
+		),
+		service_name = SERVICE_NAME_2,
+	)
 	plan.assert(connection_result["code"], "==", SUCCESS_CODE)
 	
 	test_ip_address_cmd = "nc -zv {0} {1}".format(datastore_1.ip_address, GRPC_PORT) 
-	connection_result = plan.exec(recipe=ExecRecipe(
-		service_name=SERVICE_NAME_2,
-		command=["sh", "-c", test_ip_address_cmd],
-	))
+	connection_result = plan.exec(
+		recipe = ExecRecipe(
+			command=["sh", "-c", test_ip_address_cmd],
+		),
+		service_name = SERVICE_NAME_2,
+	)
 	plan.assert(connection_result["code"], "==", SUCCESS_CODE)
 `
 )
diff --git a/internal_testsuites/golang/testsuite/startosis_add_service_test/startosis_add_service_with_ready_conditions_test.go b/internal_testsuites/golang/testsuite/startosis_add_service_test/startosis_add_service_with_ready_conditions_test.go
new file mode 100644
index 000000000..e34267214
--- /dev/null
+++ b/internal_testsuites/golang/testsuite/startosis_add_service_test/startosis_add_service_with_ready_conditions_test.go
@@ -0,0 +1,70 @@
+package startosis_add_service_test
+
+import (
+	"context"
+	"fmt"
+	"github.com/kurtosis-tech/kurtosis-cli/golang_internal_testsuite/test_helpers"
+	"github.com/stretchr/testify/require"
+	"testing"
+)
+
+const (
+	addServiceWithReadyConditionsTestName = "service-test"
+
+	addServiceWithReadyConditionsScript = `
+def run(plan):
+	get_recipe = GetHttpRequestRecipe(
+		port_id = "http-port",
+		endpoint = "?input=foo/bar",
+	)
+
+	ready_conditions = ReadyConditions(
+        recipe=get_recipe,
+		field="code",
+		assertion="==",
+		target_value=%v,
+		interval="1s",
+		timeout="3s"
+    )
+
+	service_config = ServiceConfig(
+		image = "mendhak/http-https-echo:26",
+		ports = {
+			"http-port": PortSpec(number = 8080, transport_protocol = "TCP")
+		},
+        ready_conditions = ready_conditions
+	)
+
+	plan.add_service(service_name = "web-server", config = service_config)
+`
+
+	okStatusCode          = 200
+	serverErrorStatusCode = 500
+)
+
+func TestStartosis_AddServiceWithReadyConditionsCheck(t *testing.T) {
+	ctx := context.Background()
+
+	script := fmt.Sprintf(addServiceWithReadyConditionsScript, okStatusCode)
+
+	runResult := test_helpers.SetupSimpleEnclaveAndRunScript(t, ctx, addServiceWithReadyConditionsTestName, script)
+
+	require.Nil(t, runResult.InterpretationError, "Unexpected interpretation error")
+	require.Empty(t, runResult.ValidationErrors, "Unexpected validation error")
+	require.Empty(t, runResult.ExecutionError, "Unexpected execution error")
+}
+
+func TestStartosis_AddServiceWithReadyConditionsCheckFail(t *testing.T) {
+	ctx := context.Background()
+
+	expectedLastAssertionErrorStr := fmt.Sprintf("Assertion failed '%v' '==' '%v'", okStatusCode, serverErrorStatusCode)
+
+	script := fmt.Sprintf(addServiceWithReadyConditionsScript, serverErrorStatusCode)
+
+	runResult := test_helpers.SetupSimpleEnclaveAndRunScript(t, ctx, addServiceWithReadyConditionsTestName, script)
+
+	require.Nil(t, runResult.InterpretationError, "Unexpected interpretation error")
+	require.Empty(t, runResult.ValidationErrors, "Unexpected validation error")
+	require.NotEmpty(t, runResult.ExecutionError, "Expected execution error coming from failed ready conditions")
+	require.Contains(t, runResult.ExecutionError.ErrorMessage, expectedLastAssertionErrorStr)
+}
diff --git a/internal_testsuites/golang/testsuite/startosis_add_service_test/startosis_add_services_with_ready_conditions_test.go b/internal_testsuites/golang/testsuite/startosis_add_service_test/startosis_add_services_with_ready_conditions_test.go
new file mode 100644
index 000000000..4b915b9b2
--- /dev/null
+++ b/internal_testsuites/golang/testsuite/startosis_add_service_test/startosis_add_services_with_ready_conditions_test.go
@@ -0,0 +1,77 @@
+package startosis_add_service_test
+
+import (
+	"context"
+	"fmt"
+	"github.com/kurtosis-tech/kurtosis-cli/golang_internal_testsuite/test_helpers"
+	"github.com/stretchr/testify/require"
+	"testing"
+)
+
+const (
+	addServicesWithReadyConditionsTestName = "services-test"
+
+	addServicesWithReadyConditionsScript = `
+HTTP_ECHO_IMAGE = "mendhak/http-https-echo:26"
+SERVICE_NAME_PREFIX = "service-"
+NUM_SERVICES = 4
+
+def run(plan):
+    plan.print("Adding {0} services to enclave".format(NUM_SERVICES))
+
+    get_recipe = GetHttpRequestRecipe(
+        port_id = "http-port",
+        endpoint = "?input=foo/bar",
+	)
+
+    ready_conditions = ReadyConditions(
+        recipe=get_recipe,
+        field="code",
+        assertion="==",
+        target_value=%v,
+        interval="1s",
+        timeout="3s"
+    )
+
+    config = ServiceConfig(
+        image = HTTP_ECHO_IMAGE,
+		ports = {
+			"http-port": PortSpec(number = 8080, transport_protocol = "TCP")
+		},
+		ready_conditions = ready_conditions,
+    )
+    configs = {}
+    for index in range(NUM_SERVICES):
+        service_name = SERVICE_NAME_PREFIX + str(index)
+        configs[service_name] = config
+    
+    plan.add_services(configs)
+`
+)
+
+func TestStartosis_AddServicesWithReadyConditionsCheck(t *testing.T) {
+	ctx := context.Background()
+
+	script := fmt.Sprintf(addServicesWithReadyConditionsScript, okStatusCode)
+
+	runResult := test_helpers.SetupSimpleEnclaveAndRunScript(t, ctx, addServicesWithReadyConditionsTestName, script)
+
+	require.Nil(t, runResult.InterpretationError, "Unexpected interpretation error")
+	require.Empty(t, runResult.ValidationErrors, "Unexpected validation error")
+	require.Empty(t, runResult.ExecutionError, "Unexpected execution error")
+}
+
+func TestStartosis_AddServicesWithReadyConditionsCheckFail(t *testing.T) {
+	ctx := context.Background()
+
+	expectedLastAssertionErrorStr := fmt.Sprintf("Assertion failed '%v' '==' '%v'", okStatusCode, serverErrorStatusCode)
+
+	script := fmt.Sprintf(addServicesWithReadyConditionsScript, serverErrorStatusCode)
+
+	runResult := test_helpers.SetupSimpleEnclaveAndRunScript(t, ctx, addServicesWithReadyConditionsTestName, script)
+
+	require.Nil(t, runResult.InterpretationError, "Unexpected interpretation error")
+	require.Empty(t, runResult.ValidationErrors, "Unexpected validation error")
+	require.NotEmpty(t, runResult.ExecutionError, "Expected execution error coming from failed ready conditions")
+	require.Contains(t, runResult.ExecutionError.ErrorMessage, expectedLastAssertionErrorStr)
+}
diff --git a/internal_testsuites/golang/testsuite/startosis_request_wait_assert_test/startosis_assert_fail_test.go b/internal_testsuites/golang/testsuite/startosis_request_wait_assert_test/startosis_assert_fail_test.go
index 6c195e7dd..6a810c27b 100644
--- a/internal_testsuites/golang/testsuite/startosis_request_wait_assert_test/startosis_assert_fail_test.go
+++ b/internal_testsuites/golang/testsuite/startosis_request_wait_assert_test/startosis_assert_fail_test.go
@@ -20,14 +20,13 @@ def run(plan):
 
 	plan.add_service(service_name = "web-server", config = service_config)
 	get_recipe = GetHttpRequestRecipe(
-		service_name = "web-server",
 		port_id = "http-port",
 		endpoint = "?input=foo/bar",
 		extract = {
 			"exploded-slash": ".query.input | split(\"/\") | .[1]"
 		}
 	)
-	response = plan.wait(get_recipe, "code", "==", 200, interval="100ms", timeout="30s")
+	response = plan.wait(recipe=get_recipe, field="code", assertion="==", target_value=200, interval="100ms", timeout="30s", service_name="web-server")
 	plan.assert(response["code"], "!=", 200)
 
 	# dumb test to validate we can pass 2 runtime values here
diff --git a/internal_testsuites/golang/testsuite/startosis_request_wait_assert_test/startosis_complex_request_wait_assert_test.go b/internal_testsuites/golang/testsuite/startosis_request_wait_assert_test/startosis_complex_request_wait_assert_test.go
index 5d81825a9..beea4ee00 100644
--- a/internal_testsuites/golang/testsuite/startosis_request_wait_assert_test/startosis_complex_request_wait_assert_test.go
+++ b/internal_testsuites/golang/testsuite/startosis_request_wait_assert_test/startosis_complex_request_wait_assert_test.go
@@ -21,14 +21,13 @@ def run(plan):
 
 	plan.add_service(service_name = "web-server", config = service_config)
 	get_recipe = GetHttpRequestRecipe(
-		service_name = "web-server",
 		port_id = "http-port",
 		endpoint = "?input=foo/bar",
 		extract = {
 			"exploded-slash": ".query.input | split(\"/\") | .[1]"
 		}
 	)
-	response = plan.wait(get_recipe, "code", "==", 200, interval="10s", timeout="200s")
+	response = plan.wait(get_recipe, "code", "==", 200, interval="10s", timeout="200s", service_name="web-server")
 	plan.assert(response["code"], "==", 200)
 	plan.assert("My test returned " + response["code"], "==", "My test returned 200")
 	plan.assert(response["code"], "!=", 500)
@@ -40,7 +39,6 @@ def run(plan):
 	plan.assert(response["code"], "NOT_IN", [100, 300])
 	plan.assert(response["extract.exploded-slash"], "==", "bar")
 	post_recipe = PostHttpRequestRecipe(
-		service_name = "web-server",
 		port_id = "http-port",
 		endpoint = "/",
 		content_type="text/plain",
@@ -49,27 +47,24 @@ def run(plan):
 			"my-body": ".body"
 		}
 	)
-	plan.wait(post_recipe, "code", "==", 200)
-	post_response = plan.request(post_recipe)
+	plan.wait(post_recipe, "code", "==", 200, service_name="web-server")
+	post_response = plan.request(post_recipe, "web-server")
 	plan.assert(post_response["code"], "==", 200)
 	plan.assert(post_response["extract.my-body"], "==", "bar")
 	post_recipe_no_body = PostHttpRequestRecipe(
-		service_name = "web-server",
 		port_id = "http-port",
 		endpoint = "/",
 		content_type="text/plain",
 	)
-	plan.wait(post_recipe_no_body, "code", "==", 200)
+	plan.wait(post_recipe_no_body, "code", "==", 200, service_name = "web-server")
 	exec_recipe = ExecRecipe(
-		service_name = "web-server",
 		command = ["echo", "hello", post_response["extract.my-body"]]
 	)
-	exec_result = plan.wait(exec_recipe, "code", "==", 0)
+	exec_result = plan.wait(exec_recipe, "code", "==", 0, service_name="web-server")
 	plan.assert(exec_result["output"], "==", "hello bar\n")
 
 	# content_type default to application/json
 	post_json = PostHttpRequestRecipe(
-		service_name = "web-server",
 		port_id = "http-port",
 		endpoint = "/",
 		body='{"a":"b"}',
@@ -77,7 +72,7 @@ def run(plan):
 			"my-json": ".body"
 		}
 	)
-	post_json_response = plan.request(post_json)
+	post_json_response = plan.request(post_json, service_name = "web-server")
 	plan.assert(post_json_response["extract.my-json"], "==", '{"a":"b"}')
 `
 )
diff --git a/internal_testsuites/golang/testsuite/startosis_request_wait_assert_test/startosis_timeout_wait_test.go b/internal_testsuites/golang/testsuite/startosis_request_wait_assert_test/startosis_timeout_wait_test.go
index b5888f052..a2c27a3cf 100644
--- a/internal_testsuites/golang/testsuite/startosis_request_wait_assert_test/startosis_timeout_wait_test.go
+++ b/internal_testsuites/golang/testsuite/startosis_request_wait_assert_test/startosis_timeout_wait_test.go
@@ -20,14 +20,13 @@ def run(plan):
 
 	plan.add_service(service_name = "web-server", config = service_config)
 	get_recipe = GetHttpRequestRecipe(
-		service_name = "web-server",
 		port_id = "http-port",
 		endpoint = "?input=foo/bar",
 		extract = {
 			"exploded-slash": ".query.input | split(\"/\") | .[1]"
 		}
 	)
-	response = plan.wait(get_recipe, "code", "<", 0, interval="100ms", timeout="10s")
+	response = plan.wait(recipe=get_recipe, field="code",  assertion="<", target_value=0, interval="100ms", timeout="10s", service_name="web-server")
 `
 )
 
diff --git a/internal_testsuites/golang/testsuite/startosis_test/startosis_test.go b/internal_testsuites/golang/testsuite/startosis_test/startosis_test.go
index 1c7ffbc64..e16bcf4fa 100644
--- a/internal_testsuites/golang/testsuite/startosis_test/startosis_test.go
+++ b/internal_testsuites/golang/testsuite/startosis_test/startosis_test.go
@@ -53,10 +53,12 @@ def run(plan, args):
 	
 	plan.add_service(service_name = DATASTORE_SERVICE_NAME, config = config)
 	plan.print("Service " + DATASTORE_SERVICE_NAME + " deployed successfully.")
-	plan.exec(ExecRecipe(
+	plan.exec(
+		recipe = ExecRecipe(
+			command = ["touch", FILE_TO_BE_CREATED],
+		),
 		service_name = DATASTORE_SERVICE_NAME,
-		command = ["touch", FILE_TO_BE_CREATED],
-	))
+	)
 	
 	artifact_name = plan.store_service_files(name = "stored-file", service_name = DATASTORE_SERVICE_NAME, src = FILE_TO_BE_CREATED)
 	plan.print("Stored file at " + artifact_name)
diff --git a/internal_testsuites/typescript/src/test_helpers/test_helpers.ts b/internal_testsuites/typescript/src/test_helpers/test_helpers.ts
index 764b91914..a7ea2755f 100644
--- a/internal_testsuites/typescript/src/test_helpers/test_helpers.ts
+++ b/internal_testsuites/typescript/src/test_helpers/test_helpers.ts
@@ -93,11 +93,10 @@ const TEST_DATASTORE_VALUE = "test-value"
 const WAIT_FOR_GET_AVAILABILITY_STARLARK_SCRIPT = `
 def run(plan, args):
 	get_recipe = GetHttpRequestRecipe(
-		service_name = args.service_name,
 		port_id = args.port_id,
 		endpoint = args.endpoint,
 	)
-	plan.wait(get_recipe, "code", "==", 200, args.interval, args.timeout)
+	plan.wait(get_recipe, "code", "==", 200, args.interval, args.timeout, args.service_name)
 `
 
 const DOCKER_GETTING_STARTED_IMAGE = "docker/getting-started";