@adcp/client 4.20.0 → 4.22.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 (210) hide show
  1. package/AGENTS.md +278 -0
  2. package/README.md +96 -61
  3. package/bin/adcp.js +342 -4
  4. package/dist/lib/agents/index.generated.d.ts +9 -1
  5. package/dist/lib/agents/index.generated.d.ts.map +1 -1
  6. package/dist/lib/agents/index.generated.js +12 -0
  7. package/dist/lib/agents/index.generated.js.map +1 -1
  8. package/dist/lib/core/AgentClient.d.ts.map +1 -1
  9. package/dist/lib/core/SingleAgentClient.d.ts +2 -1
  10. package/dist/lib/core/SingleAgentClient.d.ts.map +1 -1
  11. package/dist/lib/core/SingleAgentClient.js +10 -1
  12. package/dist/lib/core/SingleAgentClient.js.map +1 -1
  13. package/dist/lib/discovery/property-crawler.d.ts +4 -0
  14. package/dist/lib/discovery/property-crawler.d.ts.map +1 -1
  15. package/dist/lib/discovery/property-crawler.js +10 -2
  16. package/dist/lib/discovery/property-crawler.js.map +1 -1
  17. package/dist/lib/index.d.ts +9 -9
  18. package/dist/lib/index.d.ts.map +1 -1
  19. package/dist/lib/index.js +13 -5
  20. package/dist/lib/index.js.map +1 -1
  21. package/dist/lib/protocols/index.d.ts.map +1 -1
  22. package/dist/lib/protocols/index.js +8 -6
  23. package/dist/lib/protocols/index.js.map +1 -1
  24. package/dist/lib/protocols/mcp.d.ts.map +1 -1
  25. package/dist/lib/protocols/mcp.js +24 -11
  26. package/dist/lib/protocols/mcp.js.map +1 -1
  27. package/dist/lib/registry/cursor-store.d.ts +19 -0
  28. package/dist/lib/registry/cursor-store.d.ts.map +1 -0
  29. package/dist/lib/registry/cursor-store.js +44 -0
  30. package/dist/lib/registry/cursor-store.js.map +1 -0
  31. package/dist/lib/registry/index.d.ts +21 -3
  32. package/dist/lib/registry/index.d.ts.map +1 -1
  33. package/dist/lib/registry/index.js +94 -1
  34. package/dist/lib/registry/index.js.map +1 -1
  35. package/dist/lib/registry/property-registry.d.ts +57 -0
  36. package/dist/lib/registry/property-registry.d.ts.map +1 -0
  37. package/dist/lib/registry/property-registry.js +92 -0
  38. package/dist/lib/registry/property-registry.js.map +1 -0
  39. package/dist/lib/registry/sync.d.ts +4 -0
  40. package/dist/lib/registry/sync.d.ts.map +1 -1
  41. package/dist/lib/registry/sync.js +14 -0
  42. package/dist/lib/registry/sync.js.map +1 -1
  43. package/dist/lib/registry/types.d.ts +35 -2
  44. package/dist/lib/registry/types.d.ts.map +1 -1
  45. package/dist/lib/registry/types.generated.d.ts +349 -321
  46. package/dist/lib/registry/types.generated.d.ts.map +1 -1
  47. package/dist/lib/registry/types.generated.js +1 -1
  48. package/dist/lib/server/index.d.ts +2 -0
  49. package/dist/lib/server/index.d.ts.map +1 -1
  50. package/dist/lib/server/index.js +3 -1
  51. package/dist/lib/server/index.js.map +1 -1
  52. package/dist/lib/server/serve.d.ts +45 -0
  53. package/dist/lib/server/serve.d.ts.map +1 -0
  54. package/dist/lib/server/serve.js +86 -0
  55. package/dist/lib/server/serve.js.map +1 -0
  56. package/dist/lib/testing/agent-tester.d.ts +1 -1
  57. package/dist/lib/testing/agent-tester.d.ts.map +1 -1
  58. package/dist/lib/testing/agent-tester.js +10 -1
  59. package/dist/lib/testing/agent-tester.js.map +1 -1
  60. package/dist/lib/testing/client.d.ts.map +1 -1
  61. package/dist/lib/testing/client.js +3 -0
  62. package/dist/lib/testing/client.js.map +1 -1
  63. package/dist/lib/testing/compliance/comply.d.ts.map +1 -1
  64. package/dist/lib/testing/compliance/comply.js +158 -203
  65. package/dist/lib/testing/compliance/comply.js.map +1 -1
  66. package/dist/lib/testing/compliance/storyboard-tracks.d.ts +24 -0
  67. package/dist/lib/testing/compliance/storyboard-tracks.d.ts.map +1 -0
  68. package/dist/lib/testing/compliance/storyboard-tracks.js +157 -0
  69. package/dist/lib/testing/compliance/storyboard-tracks.js.map +1 -0
  70. package/dist/lib/testing/compliance/types.d.ts +1 -1
  71. package/dist/lib/testing/compliance/types.d.ts.map +1 -1
  72. package/dist/lib/testing/index.d.ts +2 -1
  73. package/dist/lib/testing/index.d.ts.map +1 -1
  74. package/dist/lib/testing/index.js +26 -1
  75. package/dist/lib/testing/index.js.map +1 -1
  76. package/dist/lib/testing/orchestrator.d.ts +8 -0
  77. package/dist/lib/testing/orchestrator.d.ts.map +1 -1
  78. package/dist/lib/testing/orchestrator.js +11 -0
  79. package/dist/lib/testing/orchestrator.js.map +1 -1
  80. package/dist/lib/testing/scenarios/brand-rights.d.ts +23 -0
  81. package/dist/lib/testing/scenarios/brand-rights.d.ts.map +1 -0
  82. package/dist/lib/testing/scenarios/brand-rights.js +144 -0
  83. package/dist/lib/testing/scenarios/brand-rights.js.map +1 -0
  84. package/dist/lib/testing/scenarios/capabilities.d.ts.map +1 -1
  85. package/dist/lib/testing/scenarios/capabilities.js +11 -2
  86. package/dist/lib/testing/scenarios/capabilities.js.map +1 -1
  87. package/dist/lib/testing/scenarios/governance.d.ts.map +1 -1
  88. package/dist/lib/testing/scenarios/governance.js +5 -0
  89. package/dist/lib/testing/scenarios/governance.js.map +1 -1
  90. package/dist/lib/testing/scenarios/index.d.ts +2 -0
  91. package/dist/lib/testing/scenarios/index.d.ts.map +1 -1
  92. package/dist/lib/testing/scenarios/index.js +10 -2
  93. package/dist/lib/testing/scenarios/index.js.map +1 -1
  94. package/dist/lib/testing/scenarios/media-buy.d.ts.map +1 -1
  95. package/dist/lib/testing/scenarios/media-buy.js +22 -3
  96. package/dist/lib/testing/scenarios/media-buy.js.map +1 -1
  97. package/dist/lib/testing/scenarios/trusted-match.d.ts +22 -0
  98. package/dist/lib/testing/scenarios/trusted-match.d.ts.map +1 -0
  99. package/dist/lib/testing/scenarios/trusted-match.js +128 -0
  100. package/dist/lib/testing/scenarios/trusted-match.js.map +1 -0
  101. package/dist/lib/testing/storyboard/context.d.ts +34 -0
  102. package/dist/lib/testing/storyboard/context.d.ts.map +1 -0
  103. package/dist/lib/testing/storyboard/context.js +257 -0
  104. package/dist/lib/testing/storyboard/context.js.map +1 -0
  105. package/dist/lib/testing/storyboard/index.d.ts +15 -0
  106. package/dist/lib/testing/storyboard/index.d.ts.map +1 -0
  107. package/dist/lib/testing/storyboard/index.js +48 -0
  108. package/dist/lib/testing/storyboard/index.js.map +1 -0
  109. package/dist/lib/testing/storyboard/loader.d.ts +53 -0
  110. package/dist/lib/testing/storyboard/loader.d.ts.map +1 -0
  111. package/dist/lib/testing/storyboard/loader.js +114 -0
  112. package/dist/lib/testing/storyboard/loader.js.map +1 -0
  113. package/dist/lib/testing/storyboard/path.d.ts +29 -0
  114. package/dist/lib/testing/storyboard/path.d.ts.map +1 -0
  115. package/dist/lib/testing/storyboard/path.js +121 -0
  116. package/dist/lib/testing/storyboard/path.js.map +1 -0
  117. package/dist/lib/testing/storyboard/request-builder.d.ts +28 -0
  118. package/dist/lib/testing/storyboard/request-builder.d.ts.map +1 -0
  119. package/dist/lib/testing/storyboard/request-builder.js +410 -0
  120. package/dist/lib/testing/storyboard/request-builder.js.map +1 -0
  121. package/dist/lib/testing/storyboard/runner.d.ts +24 -0
  122. package/dist/lib/testing/storyboard/runner.d.ts.map +1 -0
  123. package/dist/lib/testing/storyboard/runner.js +280 -0
  124. package/dist/lib/testing/storyboard/runner.js.map +1 -0
  125. package/dist/lib/testing/storyboard/task-map.d.ts +21 -0
  126. package/dist/lib/testing/storyboard/task-map.d.ts.map +1 -0
  127. package/dist/lib/testing/storyboard/task-map.js +84 -0
  128. package/dist/lib/testing/storyboard/task-map.js.map +1 -0
  129. package/dist/lib/testing/storyboard/types.d.ts +156 -0
  130. package/dist/lib/testing/storyboard/types.d.ts.map +1 -0
  131. package/dist/lib/testing/storyboard/types.js +10 -0
  132. package/dist/lib/testing/storyboard/types.js.map +1 -0
  133. package/dist/lib/testing/storyboard/validations.d.ts +17 -0
  134. package/dist/lib/testing/storyboard/validations.d.ts.map +1 -0
  135. package/dist/lib/testing/storyboard/validations.js +166 -0
  136. package/dist/lib/testing/storyboard/validations.js.map +1 -0
  137. package/dist/lib/testing/types.d.ts +4 -1
  138. package/dist/lib/testing/types.d.ts.map +1 -1
  139. package/dist/lib/types/core.generated.d.ts +36 -23
  140. package/dist/lib/types/core.generated.d.ts.map +1 -1
  141. package/dist/lib/types/core.generated.js +1 -1
  142. package/dist/lib/types/schemas.generated.d.ts +1098 -770
  143. package/dist/lib/types/schemas.generated.d.ts.map +1 -1
  144. package/dist/lib/types/schemas.generated.js +163 -76
  145. package/dist/lib/types/schemas.generated.js.map +1 -1
  146. package/dist/lib/types/tools.generated.d.ts +314 -24
  147. package/dist/lib/types/tools.generated.d.ts.map +1 -1
  148. package/dist/lib/utils/capabilities.d.ts +4 -1
  149. package/dist/lib/utils/capabilities.d.ts.map +1 -1
  150. package/dist/lib/utils/capabilities.js +25 -1
  151. package/dist/lib/utils/capabilities.js.map +1 -1
  152. package/dist/lib/utils/response-schemas.d.ts.map +1 -1
  153. package/dist/lib/utils/response-schemas.js +34 -3
  154. package/dist/lib/utils/response-schemas.js.map +1 -1
  155. package/dist/lib/utils/validate-user-agent.d.ts +8 -0
  156. package/dist/lib/utils/validate-user-agent.d.ts.map +1 -0
  157. package/dist/lib/utils/validate-user-agent.js +15 -0
  158. package/dist/lib/utils/validate-user-agent.js.map +1 -0
  159. package/dist/lib/version.d.ts +9 -3
  160. package/dist/lib/version.d.ts.map +1 -1
  161. package/dist/lib/version.js +10 -4
  162. package/dist/lib/version.js.map +1 -1
  163. package/docs/README.md +42 -0
  164. package/docs/guides/BUILD-AN-AGENT.md +292 -0
  165. package/docs/llms.txt +634 -0
  166. package/examples/README.md +106 -0
  167. package/examples/adcp.config.json +30 -0
  168. package/examples/basic-a2a.ts +76 -0
  169. package/examples/basic-mcp.ts +50 -0
  170. package/examples/batch-preview-test.ts +266 -0
  171. package/examples/conversation-client.ts +291 -0
  172. package/examples/debug-preview-response.ts +73 -0
  173. package/examples/debug-preview-with-logging.ts +50 -0
  174. package/examples/easy-config-demo.ts +242 -0
  175. package/examples/env-config.ts +51 -0
  176. package/examples/error-compliant-server.ts +237 -0
  177. package/examples/generative-creative-demo.ts +205 -0
  178. package/examples/inspect-card-formats.ts +161 -0
  179. package/examples/logger-usage.ts +165 -0
  180. package/examples/oauth-cli-example.ts +154 -0
  181. package/examples/pr78-async-patterns-demo.ts +247 -0
  182. package/examples/signals-agent.ts +162 -0
  183. package/examples/simple-getting-started.ts +225 -0
  184. package/examples/simple-protocol-demo.ts +75 -0
  185. package/examples/test-helpers-demo.ts +239 -0
  186. package/examples/zod-validation-example.ts +126 -0
  187. package/package.json +12 -2
  188. package/skills/adcp/SKILL.md +13 -2
  189. package/storyboards/audience_sync.yaml +199 -0
  190. package/storyboards/behavioral_analysis.yaml +244 -0
  191. package/storyboards/brand_rights.yaml +131 -0
  192. package/storyboards/creative_ad_server.yaml +171 -0
  193. package/storyboards/creative_sales_agent.yaml +169 -0
  194. package/storyboards/creative_template.yaml +306 -0
  195. package/storyboards/deterministic_testing.yaml +925 -0
  196. package/storyboards/error_compliance.yaml +231 -0
  197. package/storyboards/governance_content_standards.yaml +213 -0
  198. package/storyboards/governance_property_lists.yaml +372 -0
  199. package/storyboards/media_buy_catalog_creative.yaml +457 -0
  200. package/storyboards/media_buy_governance_escalation.yaml +467 -0
  201. package/storyboards/media_buy_guaranteed_approval.yaml +396 -0
  202. package/storyboards/media_buy_non_guaranteed.yaml +288 -0
  203. package/storyboards/media_buy_proposal_mode.yaml +369 -0
  204. package/storyboards/media_buy_seller.yaml +560 -0
  205. package/storyboards/media_buy_state_machine.yaml +254 -0
  206. package/storyboards/schema.yaml +65 -0
  207. package/storyboards/schema_validation.yaml +166 -0
  208. package/storyboards/si_session.yaml +384 -0
  209. package/storyboards/signal_marketplace.yaml +283 -0
  210. package/storyboards/signal_owned.yaml +211 -0
@@ -0,0 +1,372 @@
1
+ id: governance_property_lists
2
+ version: "1.0.0"
3
+ title: "Governance property list management"
4
+ category: governance_property_lists
5
+ summary: "CRUD lifecycle for property lists with filter round-trip validation."
6
+ track: governance
7
+ required_tools:
8
+ - create_property_list
9
+
10
+ narrative: |
11
+ You operate a governance agent that manages property lists — curated sets of
12
+ domains and apps where a brand is willing (or unwilling) to run ads. Buyer
13
+ agents create, read, update, and delete property lists through your agent,
14
+ attaching filters like GARM brand-safety categories, MFA thresholds, and
15
+ custom tags.
16
+
17
+ This storyboard covers two concerns: basic CRUD operations on property lists,
18
+ and filter fidelity — ensuring that every filter type set at creation time
19
+ survives the round-trip and comes back unchanged on retrieval.
20
+
21
+ agent:
22
+ interaction_model: governance
23
+ capabilities:
24
+ - manages_property_lists
25
+ - brand_safety
26
+ examples:
27
+ - "Brand safety platforms"
28
+ - "Agency governance dashboards"
29
+ - "Advertiser compliance tools"
30
+
31
+ caller:
32
+ role: buyer_agent
33
+ example: "Scope3 (DSP)"
34
+
35
+ prerequisites:
36
+ description: |
37
+ The caller needs a brand identity for the property list. The test kit
38
+ provides a sample brand (Acme Outdoor) with governance parameters.
39
+ test_kit: "test-kits/acme-outdoor.yaml"
40
+
41
+ phases:
42
+ - id: property_list_crud
43
+ title: "Property list CRUD operations"
44
+ narrative: |
45
+ The buyer creates a property list, retrieves it, updates it, lists all
46
+ property lists, deletes the created list, and verifies the deletion.
47
+ This exercises the full lifecycle of property list management.
48
+
49
+ steps:
50
+ - id: create_property_list
51
+ title: "Create a property list"
52
+ narrative: |
53
+ The buyer creates a new property list with base properties (included
54
+ domains) and filters (GARM exclusions, MFA thresholds). The governance
55
+ agent provisions the list and returns a list_id and auth_token for
56
+ subsequent mutations.
57
+ task: create_property_list
58
+ stateful: true
59
+ expected: |
60
+ Return the created property list with:
61
+ - list.list_id: platform-assigned identifier
62
+ - list.name: echoes the requested name
63
+ - auth_token: credential for update/delete operations
64
+ sample_request:
65
+ name: "E2E Test List"
66
+ description: "E2E test property list for governance testing"
67
+ base_properties:
68
+ include:
69
+ - identifier_type: "domain"
70
+ identifier_value: "example.com"
71
+ - identifier_type: "domain"
72
+ identifier_value: "test.example.com"
73
+ filters:
74
+ garm_categories:
75
+ exclude:
76
+ - "adult"
77
+ - "arms"
78
+ mfa_thresholds:
79
+ min_score: 0.7
80
+ brand_manifest:
81
+ name: "E2E Test Brand"
82
+ url: "https://test.example.com"
83
+ validations:
84
+ - check: response_schema
85
+ description: "Response matches create-property-list response schema"
86
+ - check: field_present
87
+ path: "list.list_id"
88
+ description: "Created list has a platform-assigned ID"
89
+ - check: field_present
90
+ path: "list.name"
91
+ description: "Created list echoes the requested name"
92
+ context_outputs:
93
+ - path: "list.list_id"
94
+ key: "list_id"
95
+ - path: "auth_token"
96
+ key: "auth_token"
97
+
98
+ - id: get_property_list
99
+ title: "Retrieve the property list"
100
+ requires_tool: get_property_list
101
+ narrative: |
102
+ The buyer retrieves the property list just created, requesting
103
+ resolved identifiers. The response should include the list metadata,
104
+ base properties, and filters exactly as they were set.
105
+ task: get_property_list
106
+ stateful: true
107
+ expected: |
108
+ Return the property list with:
109
+ - list.list_id: matches the created ID
110
+ - list.name: matches the created name
111
+ - identifiers: resolved list of included domains
112
+ - list.filters: matches the filters set at creation
113
+ sample_request:
114
+ list_id: "$context.list_id"
115
+ resolve: true
116
+ max_results: 10
117
+ context_inputs:
118
+ - key: "list_id"
119
+ inject_at: "list_id"
120
+ validations:
121
+ - check: response_schema
122
+ description: "Response matches get-property-list response schema"
123
+ - check: field_present
124
+ path: "list.list_id"
125
+ description: "Response contains the list ID"
126
+
127
+ - id: update_property_list
128
+ title: "Update the property list"
129
+ requires_tool: update_property_list
130
+ narrative: |
131
+ The buyer updates the property list, adding a new domain to the
132
+ include set and expanding the GARM exclusion list. The auth_token
133
+ from the create step authorizes the mutation.
134
+ task: update_property_list
135
+ stateful: true
136
+ expected: |
137
+ Return the updated property list with:
138
+ - list.list_id: unchanged
139
+ - list.updated_at: a timestamp reflecting the update
140
+ - Updated description and filters
141
+ sample_request:
142
+ list_id: "$context.list_id"
143
+ auth_token: "$context.auth_token"
144
+ description: "Updated E2E test property list"
145
+ base_properties:
146
+ include:
147
+ - identifier_type: "domain"
148
+ identifier_value: "example.com"
149
+ - identifier_type: "domain"
150
+ identifier_value: "test.example.com"
151
+ - identifier_type: "domain"
152
+ identifier_value: "new.example.com"
153
+ filters:
154
+ garm_categories:
155
+ exclude:
156
+ - "adult"
157
+ - "arms"
158
+ - "gambling"
159
+ mfa_thresholds:
160
+ min_score: 0.8
161
+ context_inputs:
162
+ - key: "list_id"
163
+ inject_at: "list_id"
164
+ - key: "auth_token"
165
+ inject_at: "auth_token"
166
+ validations:
167
+ - check: response_schema
168
+ description: "Response matches update-property-list response schema"
169
+ - check: field_present
170
+ path: "list.list_id"
171
+ description: "Updated list retains its ID"
172
+
173
+ - id: list_property_lists
174
+ title: "List all property lists"
175
+ requires_tool: list_property_lists
176
+ narrative: |
177
+ The buyer lists all property lists visible to them. The response
178
+ should include at least the list created earlier in this storyboard.
179
+ task: list_property_lists
180
+ stateful: false
181
+ expected: |
182
+ Return a paginated list of property lists with:
183
+ - lists: array of property list summaries
184
+ - Each list has list_id and name
185
+ sample_request:
186
+ max_results: 10
187
+ validations:
188
+ - check: response_schema
189
+ description: "Response matches list-property-lists response schema"
190
+ - check: field_present
191
+ path: "lists"
192
+ description: "Response contains a lists array"
193
+
194
+ - id: delete_property_list
195
+ title: "Delete the property list"
196
+ requires_tool: delete_property_list
197
+ narrative: |
198
+ The buyer deletes the test property list. The auth_token from the
199
+ create step authorizes the deletion.
200
+ task: delete_property_list
201
+ stateful: true
202
+ expected: |
203
+ Return confirmation of deletion:
204
+ - deleted: true
205
+ - list_id: matches the deleted list
206
+ sample_request:
207
+ list_id: "$context.list_id"
208
+ auth_token: "$context.auth_token"
209
+ context_inputs:
210
+ - key: "list_id"
211
+ inject_at: "list_id"
212
+ - key: "auth_token"
213
+ inject_at: "auth_token"
214
+ validations:
215
+ - check: response_schema
216
+ description: "Response matches delete-property-list response schema"
217
+ - check: field_present
218
+ path: "deleted"
219
+ description: "Response confirms deletion"
220
+ - check: field_present
221
+ path: "list_id"
222
+ description: "Response echoes the deleted list ID"
223
+
224
+ - id: get_deleted_list
225
+ title: "Retrieve deleted list (error expected)"
226
+ requires_tool: get_property_list
227
+ narrative: |
228
+ The buyer attempts to retrieve the list that was just deleted. The
229
+ agent should reject this request with an error, confirming that the
230
+ list no longer exists.
231
+ task: get_property_list
232
+ stateful: true
233
+ expect_error: true
234
+ expected: |
235
+ Return an error indicating the list does not exist.
236
+ sample_request:
237
+ list_id: "$context.list_id"
238
+ context_inputs:
239
+ - key: "list_id"
240
+ inject_at: "list_id"
241
+ validations:
242
+ - check: error_code
243
+ value: "not_found"
244
+ description: "Agent rejects access to a deleted list"
245
+
246
+ - id: property_list_filters
247
+ title: "Property list filter round-trips"
248
+ narrative: |
249
+ Filter fidelity matters: when a buyer sets GARM exclusions, MFA
250
+ thresholds, custom tags, and feature requirements on a property list,
251
+ those filters must survive storage and come back unchanged on retrieval.
252
+
253
+ This phase creates a property list with every supported filter type,
254
+ retrieves it with resolve:true, and validates each filter round-tripped.
255
+
256
+ steps:
257
+ - id: create_list_with_all_filters
258
+ title: "Create property list with all filter types"
259
+ narrative: |
260
+ The buyer creates a property list with GARM category exclusions,
261
+ MFA thresholds, custom tag include/exclude rules, and optionally
262
+ feature requirements. This exercises the full filter surface area.
263
+ task: create_property_list
264
+ stateful: true
265
+ expected: |
266
+ Return the created property list with:
267
+ - list.list_id: platform-assigned identifier
268
+ - auth_token: credential for subsequent operations
269
+ - All filter types accepted without error
270
+ sample_request:
271
+ name: "E2E Filter Test"
272
+ description: "E2E filter round-trip test"
273
+ base_properties:
274
+ include:
275
+ - identifier_type: "domain"
276
+ identifier_value: "example.com"
277
+ filters:
278
+ garm_categories:
279
+ exclude:
280
+ - "adult"
281
+ - "arms"
282
+ - "gambling"
283
+ - "hate_speech"
284
+ mfa_thresholds:
285
+ min_score: 0.75
286
+ custom_tags:
287
+ include:
288
+ - key: "content_type"
289
+ value: "premium"
290
+ exclude:
291
+ - key: "content_type"
292
+ value: "user_generated"
293
+ brand_manifest:
294
+ name: "E2E Test Brand"
295
+ url: "https://test.example.com"
296
+ validations:
297
+ - check: response_schema
298
+ description: "Response matches create-property-list response schema"
299
+ - check: field_present
300
+ path: "list.list_id"
301
+ description: "Created list has a platform-assigned ID"
302
+ context_outputs:
303
+ - path: "list.list_id"
304
+ key: "filter_list_id"
305
+ - path: "auth_token"
306
+ key: "filter_auth_token"
307
+
308
+ - id: get_list_validate_filters
309
+ title: "Retrieve and validate filter round-trip"
310
+ requires_tool: get_property_list
311
+ narrative: |
312
+ The buyer retrieves the property list with resolve:true and checks
313
+ that every filter type set at creation time is returned unchanged.
314
+ GARM categories, MFA thresholds, and custom tags must all survive
315
+ the round-trip through the governance agent's storage.
316
+ task: get_property_list
317
+ stateful: true
318
+ expected: |
319
+ Return the property list with all filters intact:
320
+ - list.filters.garm_categories.exclude: contains adult, arms, gambling, hate_speech
321
+ - list.filters.mfa_thresholds.min_score: 0.75
322
+ - list.filters.custom_tags.include: content_type=premium
323
+ - list.filters.custom_tags.exclude: content_type=user_generated
324
+ sample_request:
325
+ list_id: "$context.filter_list_id"
326
+ resolve: true
327
+ max_results: 5
328
+ context_inputs:
329
+ - key: "filter_list_id"
330
+ inject_at: "list_id"
331
+ validations:
332
+ - check: response_schema
333
+ description: "Response matches get-property-list response schema"
334
+ - check: field_present
335
+ path: "list.list_id"
336
+ description: "Response contains the list ID"
337
+ - check: field_present
338
+ path: "list.filters"
339
+ description: "Filters object is present in the response"
340
+ - check: field_present
341
+ path: "list.filters.garm_categories"
342
+ description: "GARM category filters survived the round-trip"
343
+ - check: field_present
344
+ path: "list.filters.mfa_thresholds"
345
+ description: "MFA threshold filters survived the round-trip"
346
+ - check: field_present
347
+ path: "list.filters.custom_tags"
348
+ description: "Custom tag filters survived the round-trip"
349
+
350
+ - id: cleanup_filter_list
351
+ title: "Delete filter test list (cleanup)"
352
+ requires_tool: delete_property_list
353
+ narrative: |
354
+ Clean up the filter test list created in this phase.
355
+ task: delete_property_list
356
+ stateful: true
357
+ expected: |
358
+ Return confirmation that the list was deleted.
359
+ sample_request:
360
+ list_id: "$context.filter_list_id"
361
+ auth_token: "$context.filter_auth_token"
362
+ context_inputs:
363
+ - key: "filter_list_id"
364
+ inject_at: "list_id"
365
+ - key: "filter_auth_token"
366
+ inject_at: "auth_token"
367
+ validations:
368
+ - check: response_schema
369
+ description: "Response matches delete-property-list response schema"
370
+ - check: field_present
371
+ path: "deleted"
372
+ description: "Response confirms deletion"