@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,231 @@
1
+ id: error_compliance
2
+ version: "1.0.0"
3
+ title: "Error handling and compliance"
4
+ category: media_buy_seller
5
+ track: error_handling
6
+ summary: "Validates that agents return properly structured AdCP errors with correct codes, recovery hints, and transport bindings."
7
+
8
+ required_tools:
9
+ - get_products
10
+
11
+ narrative: |
12
+ Every AdCP agent must handle invalid input gracefully. When a buyer sends a negative budget,
13
+ a nonexistent product ID, or a malformed request, the agent should return a structured error
14
+ response — not a stack trace or a generic 500.
15
+
16
+ AdCP defines three compliance levels for error responses:
17
+ - L1: isError flag set on the MCP response
18
+ - L2: JSON text fallback with adcp_error object in content
19
+ - L3: structuredContent.adcp_error binding (full compliance)
20
+
21
+ This storyboard sends intentionally bad input and validates that the agent rejects it with
22
+ the correct error code, recovery classification, and transport binding. Agents that use the
23
+ adcpError() helper from @adcp/client get L3 compliance automatically.
24
+
25
+ agent:
26
+ interaction_model: media_buy_seller
27
+ capabilities:
28
+ - sells_media
29
+ examples:
30
+ - "Any AdCP seller agent"
31
+
32
+ caller:
33
+ role: buyer_agent
34
+ example: "Compliance test harness"
35
+
36
+ phases:
37
+ - id: error_responses
38
+ title: "Error responses for invalid input"
39
+ narrative: |
40
+ The buyer sends requests with intentionally invalid data — negative budgets, missing
41
+ required fields, nonexistent product IDs. Each request should be rejected with a
42
+ structured error containing an appropriate AdCP error code.
43
+
44
+ steps:
45
+ - id: negative_budget
46
+ title: "Reject negative budget"
47
+ narrative: |
48
+ A negative budget is never valid. The agent must reject this with INVALID_REQUEST
49
+ or BUDGET_TOO_LOW and a correctable recovery hint so the buyer knows to fix the value.
50
+ task: create_media_buy
51
+ requires_tool: create_media_buy
52
+ expect_error: true
53
+ stateful: false
54
+ expected: |
55
+ Reject the request with an error containing:
56
+ - code: INVALID_REQUEST or BUDGET_TOO_LOW
57
+ - recovery: correctable
58
+ - field: packages[0].budget (optional but recommended)
59
+ sample_request:
60
+ idempotency_key: "error-test-negative-budget"
61
+ start_time: "2026-05-01T00:00:00Z"
62
+ end_time: "2026-05-31T23:59:59Z"
63
+ packages:
64
+ - product_id: "test-product"
65
+ budget: -500
66
+ pricing_option_id: "test-pricing"
67
+ validations:
68
+ - check: error_code
69
+ value: "INVALID_REQUEST"
70
+ description: "Error code is INVALID_REQUEST or BUDGET_TOO_LOW"
71
+
72
+ - id: nonexistent_product
73
+ title: "Reject nonexistent product ID"
74
+ narrative: |
75
+ The buyer references a product ID that does not exist on this platform.
76
+ The agent should return PRODUCT_NOT_FOUND or INVALID_REQUEST.
77
+ task: create_media_buy
78
+ requires_tool: create_media_buy
79
+ expect_error: true
80
+ stateful: false
81
+ expected: |
82
+ Reject the request with an error containing:
83
+ - code: PRODUCT_NOT_FOUND or INVALID_REQUEST
84
+ - recovery: correctable
85
+ sample_request:
86
+ idempotency_key: "error-test-nonexistent-product"
87
+ start_time: "2026-05-01T00:00:00Z"
88
+ end_time: "2026-05-31T23:59:59Z"
89
+ packages:
90
+ - product_id: "NONEXISTENT_PRODUCT_ID_12345"
91
+ budget: 1000
92
+ pricing_option_id: "nonexistent-pricing"
93
+ validations:
94
+ - check: error_code
95
+ value: "PRODUCT_NOT_FOUND"
96
+ description: "Error code is PRODUCT_NOT_FOUND or INVALID_REQUEST"
97
+
98
+ - id: missing_fields
99
+ title: "Handle empty get_products request"
100
+ narrative: |
101
+ The buyer sends an empty get_products request with no brief or brand.
102
+ The agent may accept it (permissive) or reject it (strict validation).
103
+ Both behaviors are acceptable — what matters is that the response is structured.
104
+ task: get_products
105
+ requires_tool: get_products
106
+ stateful: false
107
+ expected: |
108
+ Either:
109
+ - Return products (permissive mode)
110
+ - Return a structured error with INVALID_REQUEST (strict mode)
111
+ Both are acceptable. An unstructured error or crash is not.
112
+ sample_request: {}
113
+ validations:
114
+ - check: response_schema
115
+ description: "Response is a valid get-products-response or structured error"
116
+
117
+ - id: reversed_dates
118
+ title: "Reject end time before start time"
119
+ narrative: |
120
+ The buyer sends a create_media_buy with end_time before start_time.
121
+ The agent must reject this temporal inconsistency.
122
+ task: create_media_buy
123
+ requires_tool: create_media_buy
124
+ expect_error: true
125
+ stateful: false
126
+ expected: |
127
+ Reject the request with an error containing:
128
+ - code: INVALID_REQUEST
129
+ - recovery: correctable
130
+ - field: end_time (optional but recommended)
131
+ sample_request:
132
+ idempotency_key: "error-test-reversed-dates"
133
+ start_time: "2026-05-31T23:59:59Z"
134
+ end_time: "2026-05-01T00:00:00Z"
135
+ packages:
136
+ - product_id: "test-product"
137
+ budget: 1000
138
+ pricing_option_id: "test-pricing"
139
+ validations:
140
+ - check: error_code
141
+ value: "INVALID_REQUEST"
142
+ description: "Error code is INVALID_REQUEST for reversed date range"
143
+
144
+ - id: error_structure
145
+ title: "Error JSON structure validation"
146
+ narrative: |
147
+ Beyond returning the right error code, the error object itself must conform to the
148
+ AdCP error schema. Required fields: code (non-empty string), message (string).
149
+ Optional fields: recovery (transient|correctable|terminal), retry_after (non-negative
150
+ number), field (string), suggestion (string). Non-standard codes must use the X_ prefix.
151
+
152
+ steps:
153
+ - id: validate_error_shape
154
+ title: "Validate error JSON structure"
155
+ narrative: |
156
+ Provoke an error and inspect the JSON structure. The error object must have a
157
+ code and message at minimum. If recovery, retry_after, field, or suggestion are
158
+ present, they must have the correct types. Non-standard codes must use X_ prefix.
159
+ task: create_media_buy
160
+ requires_tool: create_media_buy
161
+ expect_error: true
162
+ stateful: false
163
+ expected: |
164
+ Error object with valid structure:
165
+ - code: non-empty string (standard AdCP code or X_-prefixed vendor code)
166
+ - message: string
167
+ - recovery: transient, correctable, or terminal (if present)
168
+ - retry_after: non-negative number (if present)
169
+ - field: string path to the offending field (if present)
170
+ - suggestion: string with remediation hint (if present)
171
+ sample_request:
172
+ idempotency_key: "error-test-structure"
173
+ start_time: "2026-05-01T00:00:00Z"
174
+ end_time: "2026-05-31T23:59:59Z"
175
+ packages:
176
+ - product_id: "NONEXISTENT_PRODUCT_ID_12345"
177
+ budget: 1000
178
+ pricing_option_id: "nonexistent-pricing"
179
+ validations:
180
+ - check: field_present
181
+ path: "adcp_error.code"
182
+ description: "Error has a code field"
183
+ - check: field_present
184
+ path: "adcp_error.message"
185
+ description: "Error has a message field"
186
+
187
+ - id: error_transport
188
+ title: "Error transport binding validation"
189
+ narrative: |
190
+ AdCP errors must be delivered through the correct MCP transport layers. The isError
191
+ flag signals the error to the MCP client, the JSON text content provides a fallback
192
+ for clients that do not support structuredContent, and structuredContent.adcp_error
193
+ provides the full typed error object.
194
+
195
+ Agents using the adcpError() helper from @adcp/client get all three layers automatically.
196
+
197
+ steps:
198
+ - id: validate_transport_binding
199
+ title: "Validate structuredContent.adcp_error binding"
200
+ narrative: |
201
+ Provoke an error and check that it appears in the correct transport layers:
202
+ - isError: true on the MCP response
203
+ - JSON text content with adcp_error (L2 fallback)
204
+ - structuredContent.adcp_error (L3 full compliance)
205
+
206
+ L2 is the minimum passing level. L3 is expected for agents using adcpError().
207
+ task: create_media_buy
208
+ requires_tool: create_media_buy
209
+ expect_error: true
210
+ stateful: false
211
+ expected: |
212
+ MCP response with:
213
+ - isError: true
214
+ - content[].text contains JSON with adcp_error (L2)
215
+ - structuredContent.adcp_error present (L3)
216
+ - Error code in structuredContent matches error code in text content (consistency)
217
+ sample_request:
218
+ idempotency_key: "error-test-transport"
219
+ start_time: "2026-05-01T00:00:00Z"
220
+ end_time: "2026-05-31T23:59:59Z"
221
+ packages:
222
+ - product_id: "NONEXISTENT_PRODUCT_ID_12345"
223
+ budget: 1000
224
+ pricing_option_id: "nonexistent-pricing"
225
+ validations:
226
+ - check: field_present
227
+ path: "adcp_error"
228
+ description: "structuredContent contains adcp_error object"
229
+ - check: error_code
230
+ value: "PRODUCT_NOT_FOUND"
231
+ description: "Error code is a valid AdCP standard code or X_-prefixed vendor code"
@@ -0,0 +1,213 @@
1
+ id: governance_content_standards
2
+ version: "1.0.0"
3
+ title: "Governance content standards"
4
+ category: governance_content_standards
5
+ summary: "Content standards discovery, calibration, and delivery validation."
6
+ track: governance
7
+ required_tools:
8
+ - list_content_standards
9
+
10
+ narrative: |
11
+ You operate a governance agent that manages content standards — brand safety
12
+ configurations that define what content is acceptable for a brand's ads.
13
+ Buyer agents discover available standards, retrieve their details, calibrate
14
+ content against them, and validate delivery records for compliance.
15
+
16
+ This storyboard covers two concerns: discovering and inspecting content
17
+ standards, and the active calibration/validation workflow where the governance
18
+ agent evaluates content artifacts against those standards.
19
+
20
+ agent:
21
+ interaction_model: governance
22
+ capabilities:
23
+ - manages_content_standards
24
+ - brand_safety
25
+ - content_calibration
26
+ examples:
27
+ - "Brand safety verification platforms"
28
+ - "Content classification services"
29
+ - "Publisher quality assurance tools"
30
+
31
+ caller:
32
+ role: buyer_agent
33
+ example: "Scope3 (DSP)"
34
+
35
+ prerequisites:
36
+ description: |
37
+ The caller needs a brand identity and content artifacts (URLs) for
38
+ calibration and validation testing. The governance agent must have at
39
+ least one content standards configuration available.
40
+ test_kit: "test-kits/acme-outdoor.yaml"
41
+
42
+ phases:
43
+ - id: content_standards_discovery
44
+ title: "Content standards discovery"
45
+ narrative: |
46
+ The buyer discovers what content standards configurations are available
47
+ from the governance agent, then retrieves the details of a specific
48
+ standard. This is the read-only exploration phase before any calibration
49
+ or validation occurs.
50
+
51
+ steps:
52
+ - id: list_content_standards
53
+ title: "List available content standards"
54
+ narrative: |
55
+ The buyer asks the governance agent for all available content
56
+ standards configurations. These represent brand safety rule sets
57
+ that content can be evaluated against — GARM floor categories,
58
+ custom brand policies, or industry-specific compliance rules.
59
+ task: list_content_standards
60
+ stateful: false
61
+ expected: |
62
+ Return available content standards with:
63
+ - standards: array of content standards summaries
64
+ - Each standard has standards_id, name, and optionally provider
65
+ sample_request:
66
+ context: "Discover available brand safety configurations"
67
+ max_results: 10
68
+ validations:
69
+ - check: response_schema
70
+ description: "Response matches list-content-standards response schema"
71
+ - check: field_present
72
+ path: "standards"
73
+ description: "Response contains a standards array"
74
+ context_outputs:
75
+ - path: "standards[0].standards_id"
76
+ key: "standards_id"
77
+
78
+ - id: get_content_standards
79
+ title: "Get content standards detail"
80
+ requires_tool: get_content_standards
81
+ narrative: |
82
+ The buyer retrieves full details of a specific content standards
83
+ configuration discovered in the previous step. The response includes
84
+ the complete rule set — categories, thresholds, and feature
85
+ definitions that the governance agent uses to evaluate content.
86
+ task: get_content_standards
87
+ stateful: true
88
+ expected: |
89
+ Return the content standards configuration with:
90
+ - standards_id: matches the requested ID
91
+ - name: human-readable label
92
+ - features: array of evaluation criteria
93
+ sample_request:
94
+ standards_id: "$context.standards_id"
95
+ context_inputs:
96
+ - key: "standards_id"
97
+ inject_at: "standards_id"
98
+ validations:
99
+ - check: response_schema
100
+ description: "Response matches get-content-standards response schema"
101
+ - check: field_present
102
+ path: "standards_id"
103
+ description: "Response contains the standards ID"
104
+
105
+ - id: get_invalid_content_standards
106
+ title: "Get invalid content standards (error expected)"
107
+ requires_tool: get_content_standards
108
+ narrative: |
109
+ The buyer requests a content standards configuration that does not
110
+ exist. The governance agent should reject the request with an error,
111
+ rather than returning empty or fabricated data.
112
+ task: get_content_standards
113
+ stateful: false
114
+ expect_error: true
115
+ expected: |
116
+ Return an error indicating the standards ID does not exist.
117
+ sample_request:
118
+ standards_id: "INVALID_STANDARDS_ID_DOES_NOT_EXIST_12345"
119
+ validations:
120
+ - check: error_code
121
+ value: "not_found"
122
+ description: "Agent rejects an invalid standards_id"
123
+
124
+ - id: content_calibration
125
+ title: "Content calibration and delivery validation"
126
+ requires_tool: calibrate_content
127
+ narrative: |
128
+ With a content standards configuration identified, the buyer submits
129
+ content artifacts for calibration — asking the governance agent to
130
+ evaluate whether specific pages or content items meet the brand safety
131
+ requirements. After calibration, the buyer validates delivery records
132
+ to confirm that ads were served alongside compliant content.
133
+
134
+ steps:
135
+ - id: calibrate_content
136
+ title: "Calibrate content against standards"
137
+ narrative: |
138
+ The buyer submits content artifacts (web pages, articles) for
139
+ evaluation against a specific content standards configuration.
140
+ The governance agent classifies each artifact and returns
141
+ calibration results — pass/fail per artifact, with scores or
142
+ category assignments.
143
+ task: calibrate_content
144
+ stateful: true
145
+ expected: |
146
+ Return calibration results with:
147
+ - session_id: identifier for this calibration session
148
+ - session_status: completed or in_progress
149
+ - Per-artifact evaluation results (pending or evaluated)
150
+ sample_request:
151
+ context: "Evaluate sample content for brand safety"
152
+ standards_id: "$context.standards_id"
153
+ artifacts:
154
+ - artifact_id: "test-artifact-1"
155
+ artifact_type: "webpage"
156
+ url: "https://example.com/article/safe-content"
157
+ title: "Safe Test Article"
158
+ - artifact_id: "test-artifact-2"
159
+ artifact_type: "webpage"
160
+ url: "https://example.com/article/test-content"
161
+ title: "Another Test Article"
162
+ feedback_type: "binary"
163
+ context_inputs:
164
+ - key: "standards_id"
165
+ inject_at: "standards_id"
166
+ validations:
167
+ - check: response_schema
168
+ description: "Response matches calibrate-content response schema"
169
+ - check: field_present
170
+ path: "session_id"
171
+ description: "Response contains a calibration session ID"
172
+ context_outputs:
173
+ - path: "session_id"
174
+ key: "calibration_session_id"
175
+
176
+ - id: validate_content_delivery
177
+ title: "Validate content delivery records"
178
+ requires_tool: validate_content_delivery
179
+ narrative: |
180
+ The buyer submits delivery records — evidence that ads were served
181
+ alongside specific content — for compliance validation. The
182
+ governance agent checks each record against the content standards
183
+ and returns pass/fail results with a summary.
184
+ task: validate_content_delivery
185
+ stateful: true
186
+ expected: |
187
+ Return validation results with:
188
+ - summary.total_records: number of records validated
189
+ - summary.passed_records: number that met standards
190
+ - summary.failed_records: number that did not meet standards
191
+ - Per-record validation details
192
+ sample_request:
193
+ context: "Validate delivery records against content standards"
194
+ standards_id: "$context.standards_id"
195
+ records:
196
+ - record_id: "test-record-1"
197
+ artifact:
198
+ artifact_id: "test-artifact-1"
199
+ artifact_type: "webpage"
200
+ url: "https://example.com/article/delivered-content"
201
+ delivered_at: "2026-04-01T12:00:00Z"
202
+ context_inputs:
203
+ - key: "standards_id"
204
+ inject_at: "standards_id"
205
+ validations:
206
+ - check: response_schema
207
+ description: "Response matches validate-content-delivery response schema"
208
+ - check: field_present
209
+ path: "summary"
210
+ description: "Response contains a validation summary"
211
+ - check: field_present
212
+ path: "summary.total_records"
213
+ description: "Summary includes total record count"