@adcp/client 4.23.0 → 4.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/README.md +23 -9
  2. package/bin/adcp.js +83 -18
  3. package/dist/lib/index.d.ts +2 -4
  4. package/dist/lib/index.d.ts.map +1 -1
  5. package/dist/lib/index.js +16 -12
  6. package/dist/lib/index.js.map +1 -1
  7. package/dist/lib/server/index.d.ts +5 -1
  8. package/dist/lib/server/index.d.ts.map +1 -1
  9. package/dist/lib/server/index.js +10 -1
  10. package/dist/lib/server/index.js.map +1 -1
  11. package/dist/lib/server/postgres-task-store.d.ts +105 -0
  12. package/dist/lib/server/postgres-task-store.d.ts.map +1 -0
  13. package/dist/lib/server/postgres-task-store.js +267 -0
  14. package/dist/lib/server/postgres-task-store.js.map +1 -0
  15. package/dist/lib/server/responses.d.ts +1 -0
  16. package/dist/lib/server/responses.d.ts.map +1 -1
  17. package/dist/lib/server/responses.js +1 -0
  18. package/dist/lib/server/responses.js.map +1 -1
  19. package/dist/lib/server/test-controller.d.ts +88 -0
  20. package/dist/lib/server/test-controller.d.ts.map +1 -0
  21. package/dist/lib/server/test-controller.js +227 -0
  22. package/dist/lib/server/test-controller.js.map +1 -0
  23. package/dist/lib/testing/agent-tester.d.ts +1 -1
  24. package/dist/lib/testing/agent-tester.d.ts.map +1 -1
  25. package/dist/lib/testing/agent-tester.js +13 -1
  26. package/dist/lib/testing/agent-tester.js.map +1 -1
  27. package/dist/lib/testing/compliance/comply.d.ts +2 -0
  28. package/dist/lib/testing/compliance/comply.d.ts.map +1 -1
  29. package/dist/lib/testing/compliance/comply.js +76 -1
  30. package/dist/lib/testing/compliance/comply.js.map +1 -1
  31. package/dist/lib/testing/compliance/index.d.ts +1 -1
  32. package/dist/lib/testing/compliance/index.d.ts.map +1 -1
  33. package/dist/lib/testing/compliance/platform-storyboards.d.ts.map +1 -1
  34. package/dist/lib/testing/compliance/platform-storyboards.js +2 -0
  35. package/dist/lib/testing/compliance/platform-storyboards.js.map +1 -1
  36. package/dist/lib/testing/compliance/storyboard-tracks.d.ts.map +1 -1
  37. package/dist/lib/testing/compliance/storyboard-tracks.js +11 -2
  38. package/dist/lib/testing/compliance/storyboard-tracks.js.map +1 -1
  39. package/dist/lib/testing/compliance/types.d.ts +22 -1
  40. package/dist/lib/testing/compliance/types.d.ts.map +1 -1
  41. package/dist/lib/testing/orchestrator.d.ts.map +1 -1
  42. package/dist/lib/testing/orchestrator.js +5 -1
  43. package/dist/lib/testing/orchestrator.js.map +1 -1
  44. package/dist/lib/testing/scenarios/brand-rights.d.ts +19 -1
  45. package/dist/lib/testing/scenarios/brand-rights.d.ts.map +1 -1
  46. package/dist/lib/testing/scenarios/brand-rights.js +138 -1
  47. package/dist/lib/testing/scenarios/brand-rights.js.map +1 -1
  48. package/dist/lib/testing/scenarios/deterministic.js +7 -7
  49. package/dist/lib/testing/scenarios/deterministic.js.map +1 -1
  50. package/dist/lib/testing/scenarios/index.d.ts +1 -1
  51. package/dist/lib/testing/scenarios/index.d.ts.map +1 -1
  52. package/dist/lib/testing/scenarios/index.js +4 -2
  53. package/dist/lib/testing/scenarios/index.js.map +1 -1
  54. package/dist/lib/testing/scenarios/media-buy.js +4 -4
  55. package/dist/lib/testing/scenarios/media-buy.js.map +1 -1
  56. package/dist/lib/testing/storyboard/loader.d.ts +1 -0
  57. package/dist/lib/testing/storyboard/loader.d.ts.map +1 -1
  58. package/dist/lib/testing/storyboard/loader.js +14 -0
  59. package/dist/lib/testing/storyboard/loader.js.map +1 -1
  60. package/dist/lib/testing/storyboard/request-builder.d.ts.map +1 -1
  61. package/dist/lib/testing/storyboard/request-builder.js +88 -11
  62. package/dist/lib/testing/storyboard/request-builder.js.map +1 -1
  63. package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
  64. package/dist/lib/testing/storyboard/runner.js +83 -5
  65. package/dist/lib/testing/storyboard/runner.js.map +1 -1
  66. package/dist/lib/testing/storyboard/task-map.d.ts +2 -0
  67. package/dist/lib/testing/storyboard/task-map.d.ts.map +1 -1
  68. package/dist/lib/testing/storyboard/task-map.js +23 -9
  69. package/dist/lib/testing/storyboard/task-map.js.map +1 -1
  70. package/dist/lib/testing/storyboard/types.d.ts +6 -2
  71. package/dist/lib/testing/storyboard/types.d.ts.map +1 -1
  72. package/dist/lib/testing/storyboard/validations.d.ts.map +1 -1
  73. package/dist/lib/testing/storyboard/validations.js +21 -4
  74. package/dist/lib/testing/storyboard/validations.js.map +1 -1
  75. package/dist/lib/testing/types.d.ts +1 -1
  76. package/dist/lib/testing/types.d.ts.map +1 -1
  77. package/dist/lib/types/core.generated.d.ts +1 -1
  78. package/dist/lib/types/core.generated.d.ts.map +1 -1
  79. package/dist/lib/types/core.generated.js +1 -1
  80. package/dist/lib/types/schemas.generated.d.ts +16 -13
  81. package/dist/lib/types/schemas.generated.d.ts.map +1 -1
  82. package/dist/lib/types/schemas.generated.js +7 -4
  83. package/dist/lib/types/schemas.generated.js.map +1 -1
  84. package/dist/lib/types/tools.generated.d.ts +14 -5
  85. package/dist/lib/types/tools.generated.d.ts.map +1 -1
  86. package/dist/lib/utils/capabilities.d.ts +2 -2
  87. package/dist/lib/utils/capabilities.d.ts.map +1 -1
  88. package/dist/lib/utils/capabilities.js +9 -3
  89. package/dist/lib/utils/capabilities.js.map +1 -1
  90. package/dist/lib/utils/response-schemas.d.ts.map +1 -1
  91. package/dist/lib/utils/response-schemas.js +9 -0
  92. package/dist/lib/utils/response-schemas.js.map +1 -1
  93. package/docs/llms.txt +10 -2
  94. package/package.json +8 -2
  95. package/skills/adcp/SKILL.md +118 -33
  96. package/skills/build-creative-agent/SKILL.md +221 -0
  97. package/skills/build-generative-seller-agent/SKILL.md +288 -0
  98. package/skills/build-retail-media-agent/SKILL.md +237 -0
  99. package/skills/build-seller-agent/SKILL.md +313 -0
  100. package/skills/build-signals-agent/SKILL.md +203 -0
  101. package/storyboards/campaign_governance_conditions.yaml +2 -2
  102. package/storyboards/campaign_governance_delivery.yaml +1 -1
  103. package/storyboards/campaign_governance_denied.yaml +1 -0
  104. package/storyboards/creative_generative.yaml +317 -0
  105. package/storyboards/creative_sales_agent.yaml +2 -2
  106. package/storyboards/creative_template.yaml +2 -1
  107. package/storyboards/deterministic_testing.yaml +271 -245
  108. package/storyboards/media_buy_catalog_creative.yaml +2 -1
  109. package/storyboards/media_buy_generative_seller.yaml +581 -0
  110. package/storyboards/media_buy_governance_escalation.yaml +1 -1
  111. package/storyboards/media_buy_guaranteed_approval.yaml +14 -14
  112. package/storyboards/media_buy_non_guaranteed.yaml +2 -2
  113. package/storyboards/media_buy_proposal_mode.yaml +5 -5
  114. package/storyboards/media_buy_seller.yaml +10 -10
  115. package/storyboards/media_buy_state_machine.yaml +4 -4
  116. package/storyboards/schema.yaml +2 -1
  117. package/storyboards/signal_marketplace.yaml +3 -0
  118. package/storyboards/signal_owned.yaml +1 -0
  119. package/storyboards/test-kits/acme-outdoor.yaml +118 -0
  120. package/storyboards/test-kits/nova-motors.yaml +134 -0
@@ -1,8 +1,8 @@
1
1
  id: deterministic_testing
2
- version: "1.0.0"
3
- title: "Deterministic testing"
2
+ version: '1.0.0'
3
+ title: 'Deterministic testing'
4
4
  category: core
5
- summary: "Uses comply_test_controller to force state transitions and simulate delivery/budget, verifying state machines and reporting."
5
+ summary: 'Uses comply_test_controller to force state transitions and simulate delivery/budget, verifying state machines and reporting.'
6
6
  track: core
7
7
  required_tools:
8
8
  - comply_test_controller
@@ -36,22 +36,22 @@ agent:
36
36
  - sells_media
37
37
  - supports_test_controller
38
38
  examples:
39
- - "Any seller with comply_test_controller"
39
+ - 'Any seller with comply_test_controller'
40
40
 
41
41
  caller:
42
42
  role: buyer_agent
43
- example: "Comply test harness"
43
+ example: 'Comply test harness'
44
44
 
45
45
  prerequisites:
46
46
  description: |
47
47
  The seller must expose the comply_test_controller tool. The controller is detected
48
48
  via list_scenarios before any state transitions are attempted. Phases that require
49
49
  specific scenarios are skipped if the controller does not support them.
50
- test_kit: "test-kits/acme-outdoor.yaml"
50
+ test_kit: 'test-kits/acme-outdoor.yaml'
51
51
 
52
52
  phases:
53
53
  - id: controller_validation
54
- title: "Controller validation"
54
+ title: 'Controller validation'
55
55
  narrative: |
56
56
  Validates that the comply_test_controller is functional and responds correctly
57
57
  to scenario discovery, unknown scenarios, missing parameters, and nonexistent
@@ -59,7 +59,7 @@ phases:
59
59
 
60
60
  steps:
61
61
  - id: list_scenarios
62
- title: "List supported scenarios"
62
+ title: 'List supported scenarios'
63
63
  requires_tool: comply_test_controller
64
64
  narrative: |
65
65
  Call the controller with scenario: list_scenarios to discover which
@@ -69,27 +69,27 @@ phases:
69
69
  stateful: false
70
70
  context_outputs:
71
71
  - name: supported_scenarios
72
- path: "scenarios"
72
+ path: 'scenarios'
73
73
  expected: |
74
74
  Return a list of supported scenarios. The response should include:
75
75
  - success: true
76
76
  - scenarios: array or object of scenario names
77
77
 
78
78
  sample_request:
79
- scenario: "list_scenarios"
79
+ scenario: 'list_scenarios'
80
80
 
81
81
  validations:
82
82
  - check: field_present
83
- path: "scenarios"
84
- description: "Controller returns supported scenarios"
83
+ path: 'scenarios'
84
+ description: 'Controller returns supported scenarios'
85
85
  - check: field_value
86
- path: "success"
86
+ path: 'success'
87
87
  allowed_values:
88
88
  - true
89
- description: "list_scenarios succeeds"
89
+ description: 'list_scenarios succeeds'
90
90
 
91
91
  - id: unknown_scenario
92
- title: "Unknown scenario returns error"
92
+ title: 'Unknown scenario returns error'
93
93
  requires_tool: comply_test_controller
94
94
  narrative: |
95
95
  Send a nonexistent scenario name. The controller should return
@@ -97,29 +97,30 @@ phases:
97
97
  task: comply_test_controller
98
98
  comply_scenario: controller_validation
99
99
  stateful: false
100
+ expect_error: true
100
101
  expected: |
101
102
  Return an error response with:
102
103
  - success: false
103
104
  - error: UNKNOWN_SCENARIO
104
105
 
105
106
  sample_request:
106
- scenario: "nonexistent_scenario"
107
+ scenario: 'nonexistent_scenario'
107
108
  params: {}
108
109
 
109
110
  validations:
110
111
  - check: field_value
111
- path: "success"
112
+ path: 'success'
112
113
  allowed_values:
113
114
  - false
114
- description: "Unknown scenario fails"
115
+ description: 'Unknown scenario fails'
115
116
  - check: field_value
116
- path: "error"
117
+ path: 'error'
117
118
  allowed_values:
118
- - "UNKNOWN_SCENARIO"
119
- description: "Error code is UNKNOWN_SCENARIO"
119
+ - 'UNKNOWN_SCENARIO'
120
+ description: 'Error code is UNKNOWN_SCENARIO'
120
121
 
121
122
  - id: missing_params
122
- title: "Missing params returns error"
123
+ title: 'Missing params returns error'
123
124
  requires_tool: comply_test_controller
124
125
  narrative: |
125
126
  Call force_creative_status with empty params. The controller should
@@ -127,29 +128,30 @@ phases:
127
128
  task: comply_test_controller
128
129
  comply_scenario: controller_validation
129
130
  stateful: false
131
+ expect_error: true
130
132
  expected: |
131
133
  Return an error response with:
132
134
  - success: false
133
135
  - error: INVALID_PARAMS
134
136
 
135
137
  sample_request:
136
- scenario: "force_creative_status"
138
+ scenario: 'force_creative_status'
137
139
  params: {}
138
140
 
139
141
  validations:
140
142
  - check: field_value
141
- path: "success"
143
+ path: 'success'
142
144
  allowed_values:
143
145
  - false
144
- description: "Missing params fails"
146
+ description: 'Missing params fails'
145
147
  - check: field_value
146
- path: "error"
148
+ path: 'error'
147
149
  allowed_values:
148
- - "INVALID_PARAMS"
149
- description: "Error code is INVALID_PARAMS"
150
+ - 'INVALID_PARAMS'
151
+ description: 'Error code is INVALID_PARAMS'
150
152
 
151
153
  - id: not_found_entity
152
- title: "Nonexistent entity returns NOT_FOUND"
154
+ title: 'Nonexistent entity returns NOT_FOUND'
153
155
  requires_tool: comply_test_controller
154
156
  narrative: |
155
157
  Call force_creative_status with a nonexistent creative_id. The controller
@@ -157,39 +159,61 @@ phases:
157
159
  task: comply_test_controller
158
160
  comply_scenario: controller_validation
159
161
  stateful: false
162
+ expect_error: true
160
163
  expected: |
161
164
  Return an error response with:
162
165
  - success: false
163
166
  - error: NOT_FOUND
164
167
 
165
168
  sample_request:
166
- scenario: "force_creative_status"
169
+ scenario: 'force_creative_status'
167
170
  params:
168
- creative_id: "comply-test-nonexistent-000000000000"
169
- status: "approved"
171
+ creative_id: 'comply-test-nonexistent-000000000000'
172
+ status: 'approved'
170
173
 
171
174
  validations:
172
175
  - check: field_value
173
- path: "success"
176
+ path: 'success'
174
177
  allowed_values:
175
178
  - false
176
- description: "Nonexistent entity fails"
179
+ description: 'Nonexistent entity fails'
177
180
  - check: field_value
178
- path: "error"
181
+ path: 'error'
179
182
  allowed_values:
180
- - "NOT_FOUND"
181
- description: "Error code is NOT_FOUND"
183
+ - 'NOT_FOUND'
184
+ description: 'Error code is NOT_FOUND'
182
185
 
183
186
  - id: deterministic_account
184
- title: "Deterministic account state machine"
187
+ title: 'Deterministic account state machine'
185
188
  narrative: |
186
189
  Forces account status transitions via the controller and verifies them through
187
190
  list_accounts. Tests suspension gating (operations blocked when suspended),
188
191
  payment_required state, and reactivation.
189
192
 
190
193
  steps:
194
+ - id: sync_accounts_for_state
195
+ title: 'Create sandbox account for state machine test'
196
+ requires_tool: comply_test_controller
197
+ narrative: |
198
+ Sync a sandbox account so the state machine has an entity to
199
+ force transitions on.
200
+ task: sync_accounts
201
+ comply_scenario: deterministic_account
202
+ stateful: true
203
+
204
+ sample_request:
205
+ brand:
206
+ domain: 'test.example.com'
207
+ operator: 'test.example.com'
208
+ sandbox: true
209
+
210
+ validations:
211
+ - check: field_present
212
+ path: 'accounts[0].account_id'
213
+ description: 'Account sync returns account_id'
214
+
191
215
  - id: list_accounts_for_state
192
- title: "Find account for state machine test"
216
+ title: 'Find account for state machine test'
193
217
  requires_tool: comply_test_controller
194
218
  narrative: |
195
219
  List accounts to find an active account for state transitions.
@@ -198,7 +222,7 @@ phases:
198
222
  stateful: false
199
223
  context_outputs:
200
224
  - name: account_id
201
- path: "accounts[0].account_id"
225
+ path: 'accounts[0].account_id'
202
226
  expected: |
203
227
  Return at least one account with an account_id.
204
228
 
@@ -206,11 +230,11 @@ phases:
206
230
 
207
231
  validations:
208
232
  - check: field_present
209
- path: "accounts[0].account_id"
210
- description: "At least one account exists"
233
+ path: 'accounts[0].account_id'
234
+ description: 'At least one account exists'
211
235
 
212
236
  - id: force_account_suspended
213
- title: "Force account to suspended"
237
+ title: 'Force account to suspended'
214
238
  requires_tool: comply_test_controller
215
239
  narrative: |
216
240
  Use the controller to force the account into suspended state. Operations
@@ -225,25 +249,25 @@ phases:
225
249
  - current_state: suspended
226
250
 
227
251
  sample_request:
228
- scenario: "force_account_status"
252
+ scenario: 'force_account_status'
229
253
  params:
230
- account_id: "{{account_id}}"
231
- status: "suspended"
254
+ account_id: '$context.account_id'
255
+ status: 'suspended'
232
256
 
233
257
  validations:
234
258
  - check: field_value
235
- path: "success"
259
+ path: 'success'
236
260
  allowed_values:
237
261
  - true
238
- description: "Account suspension succeeds"
262
+ description: 'Account suspension succeeds'
239
263
  - check: field_value
240
- path: "current_state"
264
+ path: 'current_state'
241
265
  allowed_values:
242
- - "suspended"
243
- description: "Account is now suspended"
266
+ - 'suspended'
267
+ description: 'Account is now suspended'
244
268
 
245
269
  - id: force_account_active
246
- title: "Reactivate account"
270
+ title: 'Reactivate account'
247
271
  requires_tool: comply_test_controller
248
272
  narrative: |
249
273
  Restore the account to active state. Verify the transition from suspended
@@ -258,25 +282,25 @@ phases:
258
282
  - current_state: active
259
283
 
260
284
  sample_request:
261
- scenario: "force_account_status"
285
+ scenario: 'force_account_status'
262
286
  params:
263
- account_id: "{{account_id}}"
264
- status: "active"
287
+ account_id: '$context.account_id'
288
+ status: 'active'
265
289
 
266
290
  validations:
267
291
  - check: field_value
268
- path: "success"
292
+ path: 'success'
269
293
  allowed_values:
270
294
  - true
271
- description: "Account reactivation succeeds"
295
+ description: 'Account reactivation succeeds'
272
296
  - check: field_value
273
- path: "current_state"
297
+ path: 'current_state'
274
298
  allowed_values:
275
- - "active"
276
- description: "Account is now active"
299
+ - 'active'
300
+ description: 'Account is now active'
277
301
 
278
302
  - id: force_account_payment_required
279
- title: "Force account to payment_required"
303
+ title: 'Force account to payment_required'
280
304
  requires_tool: comply_test_controller
281
305
  narrative: |
282
306
  Force the account into payment_required state. This tests a distinct
@@ -288,20 +312,20 @@ phases:
288
312
  Return a successful state transition to payment_required.
289
313
 
290
314
  sample_request:
291
- scenario: "force_account_status"
315
+ scenario: 'force_account_status'
292
316
  params:
293
- account_id: "{{account_id}}"
294
- status: "payment_required"
317
+ account_id: '$context.account_id'
318
+ status: 'payment_required'
295
319
 
296
320
  validations:
297
321
  - check: field_value
298
- path: "success"
322
+ path: 'success'
299
323
  allowed_values:
300
324
  - true
301
- description: "Transition to payment_required succeeds"
325
+ description: 'Transition to payment_required succeeds'
302
326
 
303
327
  - id: restore_account_active
304
- title: "Restore account to active"
328
+ title: 'Restore account to active'
305
329
  requires_tool: comply_test_controller
306
330
  narrative: |
307
331
  Restore the account to active state after the payment_required test.
@@ -312,20 +336,20 @@ phases:
312
336
  Account restored to active state.
313
337
 
314
338
  sample_request:
315
- scenario: "force_account_status"
339
+ scenario: 'force_account_status'
316
340
  params:
317
- account_id: "{{account_id}}"
318
- status: "active"
341
+ account_id: '$context.account_id'
342
+ status: 'active'
319
343
 
320
344
  validations:
321
345
  - check: field_value
322
- path: "success"
346
+ path: 'success'
323
347
  allowed_values:
324
348
  - true
325
- description: "Account restored to active"
349
+ description: 'Account restored to active'
326
350
 
327
351
  - id: deterministic_media_buy
328
- title: "Deterministic media buy state machine"
352
+ title: 'Deterministic media buy state machine'
329
353
  narrative: |
330
354
  Creates a media buy through the normal flow, then uses the controller to force
331
355
  it through status transitions: active, completed (terminal). Verifies that
@@ -333,43 +357,43 @@ phases:
333
357
 
334
358
  steps:
335
359
  - id: create_media_buy
336
- title: "Create media buy for state machine test"
360
+ title: 'Create media buy for state machine test'
337
361
  requires_tool: comply_test_controller
338
362
  narrative: |
339
363
  Create a media buy through the standard create_media_buy task. The resulting
340
364
  media_buy_id is used for controller-driven state transitions.
341
365
  task: create_media_buy
342
- schema_ref: "media-buy/create-media-buy-request.json"
343
- response_schema_ref: "media-buy/create-media-buy-response.json"
344
- doc_ref: "/media-buy/task-reference/create_media_buy"
366
+ schema_ref: 'media-buy/create-media-buy-request.json'
367
+ response_schema_ref: 'media-buy/create-media-buy-response.json'
368
+ doc_ref: '/media-buy/task-reference/create_media_buy'
345
369
  comply_scenario: deterministic_media_buy
346
370
  stateful: true
347
371
  context_outputs:
348
372
  - name: media_buy_id
349
- path: "media_buy_id"
373
+ path: 'media_buy_id'
350
374
  expected: |
351
375
  Create a media buy and return a media_buy_id for state machine testing.
352
376
 
353
377
  sample_request:
354
378
  account:
355
379
  brand:
356
- domain: "acmeoutdoor.com"
357
- operator: "pinnacle-agency.com"
380
+ domain: 'acmeoutdoor.com'
381
+ operator: 'pinnacle-agency.com'
358
382
  brand:
359
- domain: "acmeoutdoor.com"
360
- start_time: "2026-04-01T00:00:00Z"
361
- end_time: "2026-06-30T23:59:59Z"
383
+ domain: 'acmeoutdoor.com'
384
+ start_time: '2026-04-01T00:00:00Z'
385
+ end_time: '2026-06-30T23:59:59Z'
362
386
  packages:
363
- - product_id: "test-product"
387
+ - product_id: 'test-product'
364
388
  budget: 5000
365
- pricing_option_id: "test-pricing"
389
+ pricing_option_id: 'test-pricing'
366
390
 
367
391
  validations:
368
392
  - check: response_schema
369
- description: "Response matches create-media-buy-response.json schema"
393
+ description: 'Response matches create-media-buy-response.json schema'
370
394
 
371
395
  - id: force_media_buy_active
372
- title: "Force media buy to active"
396
+ title: 'Force media buy to active'
373
397
  requires_tool: comply_test_controller
374
398
  narrative: |
375
399
  Use the controller to force the media buy into active state.
@@ -380,33 +404,33 @@ phases:
380
404
  Return a successful state transition to active.
381
405
 
382
406
  sample_request:
383
- scenario: "force_media_buy_status"
407
+ scenario: 'force_media_buy_status'
384
408
  params:
385
- media_buy_id: "{{media_buy_id}}"
386
- status: "active"
409
+ media_buy_id: '$context.media_buy_id'
410
+ status: 'active'
387
411
 
388
412
  validations:
389
413
  - check: field_value
390
- path: "success"
414
+ path: 'success'
391
415
  allowed_values:
392
416
  - true
393
- description: "Media buy activation succeeds"
417
+ description: 'Media buy activation succeeds'
394
418
  - check: field_value
395
- path: "current_state"
419
+ path: 'current_state'
396
420
  allowed_values:
397
- - "active"
398
- description: "Media buy is now active"
421
+ - 'active'
422
+ description: 'Media buy is now active'
399
423
 
400
424
  - id: verify_media_buy_active
401
- title: "Verify media buy status via get_media_buys"
425
+ title: 'Verify media buy status via get_media_buys'
402
426
  requires_tool: comply_test_controller
403
427
  narrative: |
404
428
  Call get_media_buys to confirm the controller-forced status is reflected
405
429
  in the standard API.
406
430
  task: get_media_buys
407
- schema_ref: "media-buy/get-media-buys-request.json"
408
- response_schema_ref: "media-buy/get-media-buys-response.json"
409
- doc_ref: "/media-buy/task-reference/get_media_buys"
431
+ schema_ref: 'media-buy/get-media-buys-request.json'
432
+ response_schema_ref: 'media-buy/get-media-buys-response.json'
433
+ doc_ref: '/media-buy/task-reference/get_media_buys'
410
434
  comply_scenario: deterministic_media_buy
411
435
  stateful: true
412
436
  expected: |
@@ -415,20 +439,20 @@ phases:
415
439
  sample_request:
416
440
  account:
417
441
  brand:
418
- domain: "acmeoutdoor.com"
419
- operator: "pinnacle-agency.com"
442
+ domain: 'acmeoutdoor.com'
443
+ operator: 'pinnacle-agency.com'
420
444
  media_buy_ids:
421
- - "{{media_buy_id}}"
445
+ - '$context.media_buy_id'
422
446
 
423
447
  validations:
424
448
  - check: response_schema
425
- description: "Response matches get-media-buys-response.json schema"
449
+ description: 'Response matches get-media-buys-response.json schema'
426
450
  - check: field_present
427
- path: "media_buys[0].status"
428
- description: "Media buy has a status field"
451
+ path: 'media_buys[0].status'
452
+ description: 'Media buy has a status field'
429
453
 
430
454
  - id: force_media_buy_completed
431
- title: "Force media buy to completed (terminal)"
455
+ title: 'Force media buy to completed (terminal)'
432
456
  requires_tool: comply_test_controller
433
457
  narrative: |
434
458
  Force the media buy to completed, a terminal state. No further transitions
@@ -440,25 +464,25 @@ phases:
440
464
  Return a successful transition to completed.
441
465
 
442
466
  sample_request:
443
- scenario: "force_media_buy_status"
467
+ scenario: 'force_media_buy_status'
444
468
  params:
445
- media_buy_id: "{{media_buy_id}}"
446
- status: "completed"
469
+ media_buy_id: '$context.media_buy_id'
470
+ status: 'completed'
447
471
 
448
472
  validations:
449
473
  - check: field_value
450
- path: "success"
474
+ path: 'success'
451
475
  allowed_values:
452
476
  - true
453
- description: "Transition to completed succeeds"
477
+ description: 'Transition to completed succeeds'
454
478
  - check: field_value
455
- path: "current_state"
479
+ path: 'current_state'
456
480
  allowed_values:
457
- - "completed"
458
- description: "Media buy is now completed"
481
+ - 'completed'
482
+ description: 'Media buy is now completed'
459
483
 
460
484
  - id: invalid_transition_from_terminal
461
- title: "Reject transition from terminal state"
485
+ title: 'Reject transition from terminal state'
462
486
  requires_tool: comply_test_controller
463
487
  narrative: |
464
488
  Attempt to force the completed media buy back to active. The controller
@@ -466,31 +490,32 @@ phases:
466
490
  task: comply_test_controller
467
491
  comply_scenario: deterministic_media_buy
468
492
  stateful: true
493
+ expect_error: true
469
494
  expected: |
470
495
  Return an error response:
471
496
  - success: false
472
497
  - error: INVALID_TRANSITION
473
498
 
474
499
  sample_request:
475
- scenario: "force_media_buy_status"
500
+ scenario: 'force_media_buy_status'
476
501
  params:
477
- media_buy_id: "{{media_buy_id}}"
478
- status: "active"
502
+ media_buy_id: '$context.media_buy_id'
503
+ status: 'active'
479
504
 
480
505
  validations:
481
506
  - check: field_value
482
- path: "success"
507
+ path: 'success'
483
508
  allowed_values:
484
509
  - false
485
- description: "Terminal state rejects transition"
510
+ description: 'Terminal state rejects transition'
486
511
  - check: field_value
487
- path: "error"
512
+ path: 'error'
488
513
  allowed_values:
489
- - "INVALID_TRANSITION"
490
- description: "Error code is INVALID_TRANSITION"
514
+ - 'INVALID_TRANSITION'
515
+ description: 'Error code is INVALID_TRANSITION'
491
516
 
492
517
  - id: deterministic_creative
493
- title: "Deterministic creative state machine"
518
+ title: 'Deterministic creative state machine'
494
519
  narrative: |
495
520
  Syncs a creative, then uses the controller to force it through status
496
521
  transitions: approved, archived (terminal). Verifies terminal state rejection
@@ -498,46 +523,46 @@ phases:
498
523
 
499
524
  steps:
500
525
  - id: sync_creative_for_state
501
- title: "Sync creative for state machine test"
526
+ title: 'Sync creative for state machine test'
502
527
  requires_tool: comply_test_controller
503
528
  narrative: |
504
529
  Push a test creative via sync_creatives. The creative_id is captured
505
530
  for controller-driven transitions.
506
531
  task: sync_creatives
507
- schema_ref: "creative/sync-creatives-request.json"
508
- response_schema_ref: "creative/sync-creatives-response.json"
509
- doc_ref: "/creative/task-reference/sync_creatives"
532
+ schema_ref: 'creative/sync-creatives-request.json'
533
+ response_schema_ref: 'creative/sync-creatives-response.json'
534
+ doc_ref: '/creative/task-reference/sync_creatives'
510
535
  comply_scenario: deterministic_creative
511
536
  stateful: true
512
537
  context_outputs:
513
538
  - name: creative_id
514
- path: "results[0].creative_id"
539
+ path: 'creatives[0].creative_id'
515
540
  expected: |
516
541
  Accept the creative and return a creative_id for state machine testing.
517
542
 
518
543
  sample_request:
519
544
  account:
520
545
  brand:
521
- domain: "acmeoutdoor.com"
522
- operator: "pinnacle-agency.com"
546
+ domain: 'acmeoutdoor.com'
547
+ operator: 'pinnacle-agency.com'
523
548
  creatives:
524
- - creative_id: "comply-state-test-creative"
525
- name: "Comply State Test Creative"
549
+ - creative_id: 'comply-state-test-creative'
550
+ name: 'Comply State Test Creative'
526
551
  format_id:
527
- agent_url: "https://your-platform.example.com"
528
- id: "display_300x250"
552
+ agent_url: 'https://your-platform.example.com'
553
+ id: 'display_300x250'
529
554
  assets:
530
- - asset_id: "image"
531
- asset_type: "image"
532
- url: "https://via.placeholder.com/300x250"
533
- mime_type: "image/png"
555
+ - asset_id: 'image'
556
+ asset_type: 'image'
557
+ url: 'https://via.placeholder.com/300x250'
558
+ mime_type: 'image/png'
534
559
 
535
560
  validations:
536
561
  - check: response_schema
537
- description: "Response matches sync-creatives-response.json schema"
562
+ description: 'Response matches sync-creatives-response.json schema'
538
563
 
539
564
  - id: force_creative_approved
540
- title: "Force creative to approved"
565
+ title: 'Force creative to approved'
541
566
  requires_tool: comply_test_controller
542
567
  narrative: |
543
568
  Use the controller to force the creative into approved state.
@@ -548,25 +573,25 @@ phases:
548
573
  Successful transition to approved.
549
574
 
550
575
  sample_request:
551
- scenario: "force_creative_status"
576
+ scenario: 'force_creative_status'
552
577
  params:
553
- creative_id: "{{creative_id}}"
554
- status: "approved"
578
+ creative_id: '$context.creative_id'
579
+ status: 'approved'
555
580
 
556
581
  validations:
557
582
  - check: field_value
558
- path: "success"
583
+ path: 'success'
559
584
  allowed_values:
560
585
  - true
561
- description: "Creative approval succeeds"
586
+ description: 'Creative approval succeeds'
562
587
  - check: field_value
563
- path: "current_state"
588
+ path: 'current_state'
564
589
  allowed_values:
565
- - "approved"
566
- description: "Creative is now approved"
590
+ - 'approved'
591
+ description: 'Creative is now approved'
567
592
 
568
593
  - id: force_creative_archived
569
- title: "Force creative to archived (terminal)"
594
+ title: 'Force creative to archived (terminal)'
570
595
  requires_tool: comply_test_controller
571
596
  narrative: |
572
597
  Force the creative to archived, a terminal state.
@@ -577,20 +602,20 @@ phases:
577
602
  Successful transition to archived.
578
603
 
579
604
  sample_request:
580
- scenario: "force_creative_status"
605
+ scenario: 'force_creative_status'
581
606
  params:
582
- creative_id: "{{creative_id}}"
583
- status: "archived"
607
+ creative_id: '$context.creative_id'
608
+ status: 'archived'
584
609
 
585
610
  validations:
586
611
  - check: field_value
587
- path: "success"
612
+ path: 'success'
588
613
  allowed_values:
589
614
  - true
590
- description: "Transition to archived succeeds"
615
+ description: 'Transition to archived succeeds'
591
616
 
592
617
  - id: invalid_creative_transition
593
- title: "Reject archived to processing"
618
+ title: 'Reject archived to processing'
594
619
  requires_tool: comply_test_controller
595
620
  narrative: |
596
621
  Attempt to force the archived creative back to processing. The controller
@@ -598,29 +623,30 @@ phases:
598
623
  task: comply_test_controller
599
624
  comply_scenario: deterministic_creative
600
625
  stateful: true
626
+ expect_error: true
601
627
  expected: |
602
628
  Return error with INVALID_TRANSITION.
603
629
 
604
630
  sample_request:
605
- scenario: "force_creative_status"
631
+ scenario: 'force_creative_status'
606
632
  params:
607
- creative_id: "{{creative_id}}"
608
- status: "processing"
633
+ creative_id: '$context.creative_id'
634
+ status: 'processing'
609
635
 
610
636
  validations:
611
637
  - check: field_value
612
- path: "success"
638
+ path: 'success'
613
639
  allowed_values:
614
640
  - false
615
- description: "Terminal state rejects transition"
641
+ description: 'Terminal state rejects transition'
616
642
  - check: field_value
617
- path: "error"
643
+ path: 'error'
618
644
  allowed_values:
619
- - "INVALID_TRANSITION"
620
- description: "Error code is INVALID_TRANSITION"
645
+ - 'INVALID_TRANSITION'
646
+ description: 'Error code is INVALID_TRANSITION'
621
647
 
622
648
  - id: force_creative_rejected
623
- title: "Force fresh creative to rejected with reason"
649
+ title: 'Force fresh creative to rejected with reason'
624
650
  requires_tool: comply_test_controller
625
651
  narrative: |
626
652
  Sync a fresh creative, force it to pending_review, then reject it with a
@@ -632,29 +658,29 @@ phases:
632
658
  Successful transition to rejected with reason preserved.
633
659
 
634
660
  sample_request:
635
- scenario: "force_creative_status"
661
+ scenario: 'force_creative_status'
636
662
  params:
637
- creative_id: "{{creative_id}}"
638
- status: "rejected"
639
- rejection_reason: "Brand safety policy violation (comply test)"
663
+ creative_id: '$context.creative_id'
664
+ status: 'rejected'
665
+ rejection_reason: 'Brand safety policy violation (comply test)'
640
666
 
641
667
  validations:
642
668
  - check: field_value
643
- path: "success"
669
+ path: 'success'
644
670
  allowed_values:
645
671
  - true
646
- description: "Creative rejection succeeds"
672
+ description: 'Creative rejection succeeds'
647
673
 
648
674
  - id: deterministic_session
649
- title: "Deterministic SI session state machine"
675
+ title: 'Deterministic SI session state machine'
650
676
  narrative: |
651
677
  Initiates an SI session, then uses the controller to force session timeout.
652
678
  Verifies that messaging on a terminated session fails appropriately.
653
679
 
654
680
  steps:
655
681
  - id: initiate_session
656
- title: "Initiate SI session"
657
- requires_tool: comply_test_controller
682
+ title: 'Initiate SI session'
683
+ requires_tool: si_initiate_session
658
684
  narrative: |
659
685
  Create an SI session via si_initiate_session. The session_id is captured
660
686
  for controller-driven termination.
@@ -663,24 +689,24 @@ phases:
663
689
  stateful: true
664
690
  context_outputs:
665
691
  - name: session_id
666
- path: "session_id"
692
+ path: 'session_id'
667
693
  expected: |
668
694
  Return a session with a session_id.
669
695
 
670
696
  sample_request:
671
697
  identity:
672
- user_type: "consumer"
698
+ user_type: 'consumer'
673
699
  supported_capabilities:
674
700
  response_formats:
675
- - "text"
701
+ - 'text'
676
702
 
677
703
  validations:
678
704
  - check: field_present
679
- path: "session_id"
680
- description: "Session has a session_id"
705
+ path: 'session_id'
706
+ description: 'Session has a session_id'
681
707
 
682
708
  - id: force_session_terminated
683
- title: "Force session timeout"
709
+ title: 'Force session timeout'
684
710
  requires_tool: comply_test_controller
685
711
  narrative: |
686
712
  Use the controller to force the session into terminated state with
@@ -692,21 +718,21 @@ phases:
692
718
  Successful transition to terminated.
693
719
 
694
720
  sample_request:
695
- scenario: "force_session_status"
721
+ scenario: 'force_session_status'
696
722
  params:
697
- session_id: "{{session_id}}"
698
- status: "terminated"
699
- termination_reason: "session_timeout"
723
+ session_id: '$context.session_id'
724
+ status: 'terminated'
725
+ termination_reason: 'session_timeout'
700
726
 
701
727
  validations:
702
728
  - check: field_value
703
- path: "success"
729
+ path: 'success'
704
730
  allowed_values:
705
731
  - true
706
- description: "Session termination succeeds"
732
+ description: 'Session termination succeeds'
707
733
 
708
734
  - id: verify_terminated_session
709
- title: "Verify messaging fails on terminated session"
735
+ title: 'Verify messaging fails on terminated session'
710
736
  requires_tool: comply_test_controller
711
737
  narrative: |
712
738
  Attempt to send a message on the terminated session. The agent should
@@ -719,60 +745,60 @@ phases:
719
745
  must not accept messages on a terminated session.
720
746
 
721
747
  sample_request:
722
- session_id: "{{session_id}}"
723
- message: "comply test — session should be terminated"
748
+ session_id: '$context.session_id'
749
+ message: 'comply test — session should be terminated'
724
750
 
725
751
  validations:
726
752
  - check: field_value
727
- path: "success"
753
+ path: 'success'
728
754
  allowed_values:
729
755
  - false
730
- description: "Message on terminated session fails"
756
+ description: 'Message on terminated session fails'
731
757
 
732
758
  - id: deterministic_delivery
733
- title: "Deterministic delivery simulation"
759
+ title: 'Deterministic delivery simulation'
734
760
  narrative: |
735
761
  Creates a media buy, simulates delivery data via the controller, then verifies
736
762
  the simulated metrics are reflected in get_media_buy_delivery.
737
763
 
738
764
  steps:
739
765
  - id: create_media_buy_for_delivery
740
- title: "Create media buy for delivery test"
766
+ title: 'Create media buy for delivery test'
741
767
  requires_tool: comply_test_controller
742
768
  narrative: |
743
769
  Create a media buy to receive simulated delivery data.
744
770
  task: create_media_buy
745
- schema_ref: "media-buy/create-media-buy-request.json"
746
- response_schema_ref: "media-buy/create-media-buy-response.json"
747
- doc_ref: "/media-buy/task-reference/create_media_buy"
771
+ schema_ref: 'media-buy/create-media-buy-request.json'
772
+ response_schema_ref: 'media-buy/create-media-buy-response.json'
773
+ doc_ref: '/media-buy/task-reference/create_media_buy'
748
774
  comply_scenario: deterministic_delivery
749
775
  stateful: true
750
776
  context_outputs:
751
777
  - name: delivery_media_buy_id
752
- path: "media_buy_id"
778
+ path: 'media_buy_id'
753
779
  expected: |
754
780
  Create a media buy and return a media_buy_id.
755
781
 
756
782
  sample_request:
757
783
  account:
758
784
  brand:
759
- domain: "acmeoutdoor.com"
760
- operator: "pinnacle-agency.com"
785
+ domain: 'acmeoutdoor.com'
786
+ operator: 'pinnacle-agency.com'
761
787
  brand:
762
- domain: "acmeoutdoor.com"
763
- start_time: "2026-04-01T00:00:00Z"
764
- end_time: "2026-06-30T23:59:59Z"
788
+ domain: 'acmeoutdoor.com'
789
+ start_time: '2026-04-01T00:00:00Z'
790
+ end_time: '2026-06-30T23:59:59Z'
765
791
  packages:
766
- - product_id: "test-product"
792
+ - product_id: 'test-product'
767
793
  budget: 5000
768
- pricing_option_id: "test-pricing"
794
+ pricing_option_id: 'test-pricing'
769
795
 
770
796
  validations:
771
797
  - check: response_schema
772
- description: "Response matches create-media-buy-response.json schema"
798
+ description: 'Response matches create-media-buy-response.json schema'
773
799
 
774
800
  - id: simulate_delivery
775
- title: "Simulate delivery data"
801
+ title: 'Simulate delivery data'
776
802
  requires_tool: comply_test_controller
777
803
  narrative: |
778
804
  Inject simulated delivery metrics (impressions, clicks, spend) into the
@@ -784,32 +810,32 @@ phases:
784
810
  Return success with simulated delivery metrics acknowledged.
785
811
 
786
812
  sample_request:
787
- scenario: "simulate_delivery"
813
+ scenario: 'simulate_delivery'
788
814
  params:
789
- media_buy_id: "{{delivery_media_buy_id}}"
815
+ media_buy_id: '$context.delivery_media_buy_id'
790
816
  impressions: 10000
791
817
  clicks: 150
792
818
  reported_spend:
793
819
  amount: 150.00
794
- currency: "USD"
820
+ currency: 'USD'
795
821
 
796
822
  validations:
797
823
  - check: field_value
798
- path: "success"
824
+ path: 'success'
799
825
  allowed_values:
800
826
  - true
801
- description: "Delivery simulation succeeds"
827
+ description: 'Delivery simulation succeeds'
802
828
 
803
829
  - id: verify_delivery
804
- title: "Verify delivery via get_media_buy_delivery"
830
+ title: 'Verify delivery via get_media_buy_delivery'
805
831
  requires_tool: comply_test_controller
806
832
  narrative: |
807
833
  Call get_media_buy_delivery and verify the simulated metrics are reflected
808
834
  in the response. Expect at least 10000 impressions.
809
835
  task: get_media_buy_delivery
810
- schema_ref: "media-buy/get-media-buy-delivery-request.json"
811
- response_schema_ref: "media-buy/get-media-buy-delivery-response.json"
812
- doc_ref: "/media-buy/task-reference/get_media_buy_delivery"
836
+ schema_ref: 'media-buy/get-media-buy-delivery-request.json'
837
+ response_schema_ref: 'media-buy/get-media-buy-delivery-response.json'
838
+ doc_ref: '/media-buy/task-reference/get_media_buy_delivery'
813
839
  comply_scenario: deterministic_delivery
814
840
  stateful: true
815
841
  expected: |
@@ -820,62 +846,62 @@ phases:
820
846
  sample_request:
821
847
  account:
822
848
  brand:
823
- domain: "acmeoutdoor.com"
824
- operator: "pinnacle-agency.com"
849
+ domain: 'acmeoutdoor.com'
850
+ operator: 'pinnacle-agency.com'
825
851
  media_buy_ids:
826
- - "{{delivery_media_buy_id}}"
852
+ - '$context.delivery_media_buy_id'
827
853
 
828
854
  validations:
829
855
  - check: response_schema
830
- description: "Response matches get-media-buy-delivery-response.json schema"
856
+ description: 'Response matches get-media-buy-delivery-response.json schema'
831
857
  - check: field_present
832
- path: "media_buys"
833
- description: "Response contains delivery data"
858
+ path: 'media_buy_deliveries'
859
+ description: 'Response contains delivery data'
834
860
 
835
861
  - id: deterministic_budget
836
- title: "Deterministic budget simulation"
862
+ title: 'Deterministic budget simulation'
837
863
  narrative: |
838
864
  Creates a media buy, then uses the controller to simulate budget spend at 95%
839
865
  and 100%. Verifies the agent handles near-depletion and full depletion.
840
866
 
841
867
  steps:
842
868
  - id: create_media_buy_for_budget
843
- title: "Create media buy for budget test"
869
+ title: 'Create media buy for budget test'
844
870
  requires_tool: comply_test_controller
845
871
  narrative: |
846
872
  Create a media buy with a known budget for spend simulation.
847
873
  task: create_media_buy
848
- schema_ref: "media-buy/create-media-buy-request.json"
849
- response_schema_ref: "media-buy/create-media-buy-response.json"
850
- doc_ref: "/media-buy/task-reference/create_media_buy"
874
+ schema_ref: 'media-buy/create-media-buy-request.json'
875
+ response_schema_ref: 'media-buy/create-media-buy-response.json'
876
+ doc_ref: '/media-buy/task-reference/create_media_buy'
851
877
  comply_scenario: deterministic_budget
852
878
  stateful: true
853
879
  context_outputs:
854
880
  - name: budget_media_buy_id
855
- path: "media_buy_id"
881
+ path: 'media_buy_id'
856
882
  expected: |
857
883
  Create a media buy and return a media_buy_id.
858
884
 
859
885
  sample_request:
860
886
  account:
861
887
  brand:
862
- domain: "acmeoutdoor.com"
863
- operator: "pinnacle-agency.com"
888
+ domain: 'acmeoutdoor.com'
889
+ operator: 'pinnacle-agency.com'
864
890
  brand:
865
- domain: "acmeoutdoor.com"
866
- start_time: "2026-04-01T00:00:00Z"
867
- end_time: "2026-06-30T23:59:59Z"
891
+ domain: 'acmeoutdoor.com'
892
+ start_time: '2026-04-01T00:00:00Z'
893
+ end_time: '2026-06-30T23:59:59Z'
868
894
  packages:
869
- - product_id: "test-product"
895
+ - product_id: 'test-product'
870
896
  budget: 10000
871
- pricing_option_id: "test-pricing"
897
+ pricing_option_id: 'test-pricing'
872
898
 
873
899
  validations:
874
900
  - check: response_schema
875
- description: "Response matches create-media-buy-response.json schema"
901
+ description: 'Response matches create-media-buy-response.json schema'
876
902
 
877
903
  - id: simulate_budget_95
878
- title: "Simulate 95% budget spend"
904
+ title: 'Simulate 95% budget spend'
879
905
  requires_tool: comply_test_controller
880
906
  narrative: |
881
907
  Simulate 95% of the media buy budget being spent. The agent should
@@ -887,20 +913,20 @@ phases:
887
913
  Return success with budget spend simulated to 95%.
888
914
 
889
915
  sample_request:
890
- scenario: "simulate_budget_spend"
916
+ scenario: 'simulate_budget_spend'
891
917
  params:
892
- media_buy_id: "{{budget_media_buy_id}}"
918
+ media_buy_id: '$context.budget_media_buy_id'
893
919
  spend_percentage: 95
894
920
 
895
921
  validations:
896
922
  - check: field_value
897
- path: "success"
923
+ path: 'success'
898
924
  allowed_values:
899
925
  - true
900
- description: "95% budget simulation succeeds"
926
+ description: '95% budget simulation succeeds'
901
927
 
902
928
  - id: simulate_budget_100
903
- title: "Simulate 100% budget depletion"
929
+ title: 'Simulate 100% budget depletion'
904
930
  requires_tool: comply_test_controller
905
931
  narrative: |
906
932
  Simulate complete budget depletion. The agent should handle the fully
@@ -912,14 +938,14 @@ phases:
912
938
  Return success with budget fully depleted.
913
939
 
914
940
  sample_request:
915
- scenario: "simulate_budget_spend"
941
+ scenario: 'simulate_budget_spend'
916
942
  params:
917
- media_buy_id: "{{budget_media_buy_id}}"
943
+ media_buy_id: '$context.budget_media_buy_id'
918
944
  spend_percentage: 100
919
945
 
920
946
  validations:
921
947
  - check: field_value
922
- path: "success"
948
+ path: 'success'
923
949
  allowed_values:
924
950
  - true
925
- description: "100% budget depletion simulation succeeds"
951
+ description: '100% budget depletion simulation succeeds'