ax-audit 3.6.0 → 4.0.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 (201) hide show
  1. package/CHANGELOG.md +138 -0
  2. package/LICENSE +1 -1
  3. package/README.md +58 -36
  4. package/dist/baseline.d.ts +2 -0
  5. package/dist/baseline.d.ts.map +1 -1
  6. package/dist/baseline.js +42 -4
  7. package/dist/baseline.js.map +1 -1
  8. package/dist/check-ids.d.ts +19 -0
  9. package/dist/check-ids.d.ts.map +1 -0
  10. package/dist/check-ids.js +53 -0
  11. package/dist/check-ids.js.map +1 -0
  12. package/dist/checks/agent-access.d.ts +23 -6
  13. package/dist/checks/agent-access.d.ts.map +1 -1
  14. package/dist/checks/agent-access.js +200 -54
  15. package/dist/checks/agent-access.js.map +1 -1
  16. package/dist/checks/agent-card.d.ts +37 -0
  17. package/dist/checks/agent-card.d.ts.map +1 -0
  18. package/dist/checks/agent-card.js +352 -0
  19. package/dist/checks/agent-card.js.map +1 -0
  20. package/dist/checks/agent-operability.d.ts +66 -0
  21. package/dist/checks/agent-operability.d.ts.map +1 -0
  22. package/dist/checks/agent-operability.js +383 -0
  23. package/dist/checks/agent-operability.js.map +1 -0
  24. package/dist/checks/agent-skills.d.ts +24 -0
  25. package/dist/checks/agent-skills.d.ts.map +1 -0
  26. package/dist/checks/agent-skills.js +316 -0
  27. package/dist/checks/agent-skills.js.map +1 -0
  28. package/dist/checks/ai-catalog.d.ts +28 -0
  29. package/dist/checks/ai-catalog.d.ts.map +1 -0
  30. package/dist/checks/ai-catalog.js +254 -0
  31. package/dist/checks/ai-catalog.js.map +1 -0
  32. package/dist/checks/ai-directives.d.ts +57 -0
  33. package/dist/checks/ai-directives.d.ts.map +1 -0
  34. package/dist/checks/ai-directives.js +263 -0
  35. package/dist/checks/ai-directives.js.map +1 -0
  36. package/dist/checks/api-discovery.d.ts +26 -0
  37. package/dist/checks/api-discovery.d.ts.map +1 -0
  38. package/dist/checks/api-discovery.js +432 -0
  39. package/dist/checks/api-discovery.js.map +1 -0
  40. package/dist/checks/auth-discovery.d.ts +28 -0
  41. package/dist/checks/auth-discovery.d.ts.map +1 -0
  42. package/dist/checks/auth-discovery.js +213 -0
  43. package/dist/checks/auth-discovery.js.map +1 -0
  44. package/dist/checks/commerce-discovery.d.ts +40 -0
  45. package/dist/checks/commerce-discovery.d.ts.map +1 -0
  46. package/dist/checks/commerce-discovery.js +295 -0
  47. package/dist/checks/commerce-discovery.js.map +1 -0
  48. package/dist/checks/content-negotiation.d.ts.map +1 -1
  49. package/dist/checks/content-negotiation.js +135 -20
  50. package/dist/checks/content-negotiation.js.map +1 -1
  51. package/dist/checks/crawl-efficiency.d.ts +13 -1
  52. package/dist/checks/crawl-efficiency.d.ts.map +1 -1
  53. package/dist/checks/crawl-efficiency.js +65 -1
  54. package/dist/checks/crawl-efficiency.js.map +1 -1
  55. package/dist/checks/frontmatter.d.ts +34 -0
  56. package/dist/checks/frontmatter.d.ts.map +1 -0
  57. package/dist/checks/frontmatter.js +100 -0
  58. package/dist/checks/frontmatter.js.map +1 -0
  59. package/dist/checks/html-rendering.d.ts.map +1 -1
  60. package/dist/checks/html-rendering.js +0 -1
  61. package/dist/checks/html-rendering.js.map +1 -1
  62. package/dist/checks/html-utils.d.ts +10 -0
  63. package/dist/checks/html-utils.d.ts.map +1 -1
  64. package/dist/checks/html-utils.js +19 -0
  65. package/dist/checks/html-utils.js.map +1 -1
  66. package/dist/checks/http-headers.d.ts.map +1 -1
  67. package/dist/checks/http-headers.js +82 -10
  68. package/dist/checks/http-headers.js.map +1 -1
  69. package/dist/checks/http-hygiene.d.ts +26 -0
  70. package/dist/checks/http-hygiene.d.ts.map +1 -0
  71. package/dist/checks/http-hygiene.js +257 -0
  72. package/dist/checks/http-hygiene.js.map +1 -0
  73. package/dist/checks/index.d.ts.map +1 -1
  74. package/dist/checks/index.js +24 -8
  75. package/dist/checks/index.js.map +1 -1
  76. package/dist/checks/llms-txt.d.ts +15 -0
  77. package/dist/checks/llms-txt.d.ts.map +1 -1
  78. package/dist/checks/llms-txt.js +162 -2
  79. package/dist/checks/llms-txt.js.map +1 -1
  80. package/dist/checks/mcp-discovery.d.ts +30 -0
  81. package/dist/checks/mcp-discovery.d.ts.map +1 -0
  82. package/dist/checks/mcp-discovery.js +523 -0
  83. package/dist/checks/mcp-discovery.js.map +1 -0
  84. package/dist/checks/meta-tags.d.ts.map +1 -1
  85. package/dist/checks/meta-tags.js +6 -5
  86. package/dist/checks/meta-tags.js.map +1 -1
  87. package/dist/checks/robots-parser.d.ts +110 -0
  88. package/dist/checks/robots-parser.d.ts.map +1 -0
  89. package/dist/checks/robots-parser.js +277 -0
  90. package/dist/checks/robots-parser.js.map +1 -0
  91. package/dist/checks/robots-txt.d.ts +2 -20
  92. package/dist/checks/robots-txt.d.ts.map +1 -1
  93. package/dist/checks/robots-txt.js +219 -120
  94. package/dist/checks/robots-txt.js.map +1 -1
  95. package/dist/checks/rsl.d.ts +0 -2
  96. package/dist/checks/rsl.d.ts.map +1 -1
  97. package/dist/checks/rsl.js +1 -11
  98. package/dist/checks/rsl.js.map +1 -1
  99. package/dist/checks/security-txt.d.ts.map +1 -1
  100. package/dist/checks/security-txt.js +0 -1
  101. package/dist/checks/security-txt.js.map +1 -1
  102. package/dist/checks/seo-basics.d.ts.map +1 -1
  103. package/dist/checks/seo-basics.js +0 -1
  104. package/dist/checks/seo-basics.js.map +1 -1
  105. package/dist/checks/sitemap.d.ts.map +1 -1
  106. package/dist/checks/sitemap.js +0 -1
  107. package/dist/checks/sitemap.js.map +1 -1
  108. package/dist/checks/structured-data.d.ts.map +1 -1
  109. package/dist/checks/structured-data.js +215 -4
  110. package/dist/checks/structured-data.js.map +1 -1
  111. package/dist/checks/structured-fields.d.ts +46 -0
  112. package/dist/checks/structured-fields.d.ts.map +1 -0
  113. package/dist/checks/structured-fields.js +112 -0
  114. package/dist/checks/structured-fields.js.map +1 -0
  115. package/dist/checks/surface.d.ts +59 -0
  116. package/dist/checks/surface.d.ts.map +1 -0
  117. package/dist/checks/surface.js +106 -0
  118. package/dist/checks/surface.js.map +1 -0
  119. package/dist/checks/tls-https.d.ts.map +1 -1
  120. package/dist/checks/tls-https.js +0 -1
  121. package/dist/checks/tls-https.js.map +1 -1
  122. package/dist/checks/usage-policy.d.ts +53 -0
  123. package/dist/checks/usage-policy.d.ts.map +1 -0
  124. package/dist/checks/usage-policy.js +339 -0
  125. package/dist/checks/usage-policy.js.map +1 -0
  126. package/dist/checks/utils.d.ts +25 -1
  127. package/dist/checks/utils.d.ts.map +1 -1
  128. package/dist/checks/utils.js +33 -1
  129. package/dist/checks/utils.js.map +1 -1
  130. package/dist/checks/waf.d.ts +75 -0
  131. package/dist/checks/waf.d.ts.map +1 -0
  132. package/dist/checks/waf.js +203 -0
  133. package/dist/checks/waf.js.map +1 -0
  134. package/dist/checks/webmcp.d.ts +55 -0
  135. package/dist/checks/webmcp.d.ts.map +1 -0
  136. package/dist/checks/webmcp.js +209 -0
  137. package/dist/checks/webmcp.js.map +1 -0
  138. package/dist/checks/well-known.d.ts +38 -0
  139. package/dist/checks/well-known.d.ts.map +1 -0
  140. package/dist/checks/well-known.js +202 -0
  141. package/dist/checks/well-known.js.map +1 -0
  142. package/dist/cli.d.ts +14 -0
  143. package/dist/cli.d.ts.map +1 -1
  144. package/dist/cli.js +124 -4
  145. package/dist/cli.js.map +1 -1
  146. package/dist/constants.d.ts +195 -14
  147. package/dist/constants.d.ts.map +1 -1
  148. package/dist/constants.js +598 -70
  149. package/dist/constants.js.map +1 -1
  150. package/dist/fetcher.d.ts.map +1 -1
  151. package/dist/fetcher.js +44 -14
  152. package/dist/fetcher.js.map +1 -1
  153. package/dist/guide-urls.js +1 -1
  154. package/dist/guide-urls.js.map +1 -1
  155. package/dist/index.d.ts +2 -1
  156. package/dist/index.d.ts.map +1 -1
  157. package/dist/index.js +1 -0
  158. package/dist/index.js.map +1 -1
  159. package/dist/orchestrator.d.ts.map +1 -1
  160. package/dist/orchestrator.js +5 -1
  161. package/dist/orchestrator.js.map +1 -1
  162. package/dist/reporter/html.d.ts +9 -0
  163. package/dist/reporter/html.d.ts.map +1 -1
  164. package/dist/reporter/html.js +49 -11
  165. package/dist/reporter/html.js.map +1 -1
  166. package/dist/reporter/markdown.d.ts.map +1 -1
  167. package/dist/reporter/markdown.js +36 -6
  168. package/dist/reporter/markdown.js.map +1 -1
  169. package/dist/reporter/terminal.d.ts.map +1 -1
  170. package/dist/reporter/terminal.js +36 -1
  171. package/dist/reporter/terminal.js.map +1 -1
  172. package/dist/scorer.d.ts +10 -0
  173. package/dist/scorer.d.ts.map +1 -1
  174. package/dist/scorer.js +22 -5
  175. package/dist/scorer.js.map +1 -1
  176. package/dist/types.d.ts +90 -3
  177. package/dist/types.d.ts.map +1 -1
  178. package/docs/architecture.md +27 -11
  179. package/docs/checks.md +285 -52
  180. package/docs/cli.md +36 -0
  181. package/docs/concepts.md +27 -13
  182. package/docs/faq.md +18 -6
  183. package/docs/getting-started.md +20 -13
  184. package/docs/roadmap.md +367 -0
  185. package/package.json +13 -5
  186. package/dist/checks/agent-json.d.ts +0 -14
  187. package/dist/checks/agent-json.d.ts.map +0 -1
  188. package/dist/checks/agent-json.js +0 -167
  189. package/dist/checks/agent-json.js.map +0 -1
  190. package/dist/checks/mcp.d.ts +0 -4
  191. package/dist/checks/mcp.d.ts.map +0 -1
  192. package/dist/checks/mcp.js +0 -162
  193. package/dist/checks/mcp.js.map +0 -1
  194. package/dist/checks/openapi.d.ts +0 -4
  195. package/dist/checks/openapi.d.ts.map +0 -1
  196. package/dist/checks/openapi.js +0 -121
  197. package/dist/checks/openapi.js.map +0 -1
  198. package/dist/checks/well-known-ai.d.ts +0 -17
  199. package/dist/checks/well-known-ai.d.ts.map +0 -1
  200. package/dist/checks/well-known-ai.js +0 -123
  201. package/dist/checks/well-known-ai.js.map +0 -1
@@ -0,0 +1,213 @@
1
+ import { guideUrl } from '../guide-urls.js';
2
+ import { buildResult, isHtmlDocument, notApplicable } from './utils.js';
3
+ import { standingNote } from './well-known.js';
4
+ /**
5
+ * "auth-discovery" — if an agent needs credentials here, can it work out how to
6
+ * get them?
7
+ *
8
+ * A human hitting a 401 goes and reads the documentation. An agent cannot. It
9
+ * needs the answer in the response: which authorization server to talk to, what
10
+ * scopes exist, where to register. That is what RFC 9728 Protected Resource
11
+ * Metadata is for, and the MCP specification makes it mandatory for remote
12
+ * servers precisely because agents cannot read docs.
13
+ *
14
+ * The chain is: a `401` carrying `WWW-Authenticate` with a `resource_metadata`
15
+ * parameter, or `/.well-known/oauth-protected-resource`, naming one or more
16
+ * authorization servers; each of those exposing RFC 8414 metadata at
17
+ * `/.well-known/oauth-authorization-server` or OpenID discovery at
18
+ * `/.well-known/openid-configuration`.
19
+ *
20
+ * This check is conditional. A site with no API, no MCP server and no commerce
21
+ * profile has nothing to authorize, and demanding OAuth metadata from a blog
22
+ * would be noise. It reports N/A unless one of those surfaces exists.
23
+ */
24
+ export const meta = {
25
+ id: 'auth-discovery',
26
+ name: 'Auth Discovery',
27
+ description: 'Checks OAuth metadata (RFC 9728 / RFC 8414) so agents can authenticate without documentation',
28
+ category: 'protocols',
29
+ };
30
+ const PROTECTED_RESOURCE = '/.well-known/oauth-protected-resource';
31
+ const AUTHORIZATION_SERVER = '/.well-known/oauth-authorization-server';
32
+ const OPENID_CONFIGURATION = '/.well-known/openid-configuration';
33
+ /** Paths that indicate the site has something worth authorizing. */
34
+ const SURFACE_PROBES = [
35
+ { path: '/openapi.json', label: 'an OpenAPI description' },
36
+ { path: '/.well-known/openapi.json', label: 'an OpenAPI description' },
37
+ { path: '/.well-known/api-catalog', label: 'an API catalog' },
38
+ { path: '/.well-known/mcp/server-card.json', label: 'an MCP server card' },
39
+ { path: '/mcp/server-card', label: 'an MCP server card' },
40
+ { path: '/.well-known/ucp', label: 'a commerce profile' },
41
+ ];
42
+ async function fetchJson(ctx, url) {
43
+ const res = await ctx.fetch(url);
44
+ if (!res.ok || res.body.trim().length === 0 || isHtmlDocument(res.body))
45
+ return null;
46
+ try {
47
+ return JSON.parse(res.body);
48
+ }
49
+ catch {
50
+ return null;
51
+ }
52
+ }
53
+ /** Does this site expose anything an agent would need credentials for? */
54
+ async function findSurface(ctx) {
55
+ for (const probe of SURFACE_PROBES) {
56
+ const res = await ctx.fetch(`${ctx.url}${probe.path}`);
57
+ if (res.ok && res.body.trim().length > 0 && !isHtmlDocument(res.body))
58
+ return probe.label;
59
+ }
60
+ return null;
61
+ }
62
+ /** Read the `resource_metadata` parameter out of a `WWW-Authenticate` challenge. */
63
+ export function resourceMetadataFromChallenge(header) {
64
+ const match = header.match(/resource_metadata\s*=\s*"([^"]+)"/i);
65
+ return match ? match[1] : null;
66
+ }
67
+ export default async function check(ctx) {
68
+ const start = performance.now();
69
+ const findings = [];
70
+ let score = 100;
71
+ // A 401 on the homepage means the whole site is gated, which is the strongest
72
+ // possible signal that auth discovery matters here.
73
+ const challenge = ctx.headers?.['www-authenticate'];
74
+ const metadataUrl = challenge === undefined ? null : resourceMetadataFromChallenge(challenge);
75
+ if (metadataUrl !== null) {
76
+ findings.push({
77
+ status: 'pass',
78
+ message: 'WWW-Authenticate points at protected-resource metadata',
79
+ detail: metadataUrl,
80
+ });
81
+ }
82
+ const resource = (metadataUrl !== null ? await fetchJson(ctx, metadataUrl) : null) ??
83
+ (await fetchJson(ctx, `${ctx.url}${PROTECTED_RESOURCE}`));
84
+ if (resource === null) {
85
+ const surface = await findSurface(ctx);
86
+ if (surface === null) {
87
+ findings.push({
88
+ status: 'pass',
89
+ message: 'Nothing on this site requires authorization — auth discovery does not apply',
90
+ detail: 'No API description, API catalog, MCP server card or commerce profile found.',
91
+ });
92
+ return notApplicable(meta, findings, start);
93
+ }
94
+ findings.push({
95
+ status: 'warn',
96
+ message: `Site exposes ${surface} but publishes no OAuth metadata`,
97
+ detail: `Checked WWW-Authenticate resource_metadata and ${PROTECTED_RESOURCE}. ${standingNote(PROTECTED_RESOURCE) ?? ''}`.trim(),
98
+ hint: 'If any of that surface needs credentials, an agent hitting a 401 has nowhere to look — it cannot read your ' +
99
+ 'documentation. Publish RFC 9728 metadata at /.well-known/oauth-protected-resource naming your authorization ' +
100
+ 'server. If everything is public, this is nothing to fix.',
101
+ learnMoreUrl: guideUrl(meta.id, 'not-found'),
102
+ });
103
+ return buildResult(meta, 0, findings, start);
104
+ }
105
+ findings.push({
106
+ status: 'pass',
107
+ message: 'Protected-resource metadata published (RFC 9728)',
108
+ detail: standingNote(PROTECTED_RESOURCE),
109
+ });
110
+ const servers = Array.isArray(resource.authorization_servers)
111
+ ? resource.authorization_servers.map(String)
112
+ : [];
113
+ if (servers.length === 0) {
114
+ findings.push({
115
+ status: 'fail',
116
+ message: 'Protected-resource metadata names no authorization server',
117
+ hint: 'Add "authorization_servers": ["https://auth.example.com"]. Without it the metadata says a token is needed but not where to get one.',
118
+ learnMoreUrl: guideUrl(meta.id, 'no-authorization-servers'),
119
+ });
120
+ return buildResult(meta, 40, findings, start);
121
+ }
122
+ findings.push({ status: 'pass', message: `${servers.length} authorization server(s) named` });
123
+ if (resource.resource === undefined) {
124
+ findings.push({
125
+ status: 'warn',
126
+ message: 'Protected-resource metadata declares no "resource" identifier',
127
+ hint: 'Declare the canonical resource URI so a client can request a token audienced correctly.',
128
+ learnMoreUrl: guideUrl(meta.id, 'no-resource'),
129
+ });
130
+ score -= 10;
131
+ }
132
+ score = await validateAuthorizationServer(ctx, servers[0], findings, score);
133
+ return buildResult(meta, score, findings, start);
134
+ }
135
+ /** Follow the first authorization server and check it can actually be used. */
136
+ async function validateAuthorizationServer(ctx, issuer, findings, score) {
137
+ let base;
138
+ try {
139
+ base = new URL(issuer).origin;
140
+ }
141
+ catch {
142
+ findings.push({
143
+ status: 'fail',
144
+ message: `Authorization server "${issuer}" is not a valid URL`,
145
+ hint: 'Authorization server entries are absolute https URLs.',
146
+ learnMoreUrl: guideUrl(meta.id, 'invalid-issuer'),
147
+ });
148
+ return score - 25;
149
+ }
150
+ const metadata = (await fetchJson(ctx, `${base}${AUTHORIZATION_SERVER}`)) ??
151
+ (await fetchJson(ctx, `${base}${OPENID_CONFIGURATION}`));
152
+ if (metadata === null) {
153
+ findings.push({
154
+ status: 'fail',
155
+ message: `Authorization server ${base} publishes no discovery metadata`,
156
+ detail: `Checked ${AUTHORIZATION_SERVER} and ${OPENID_CONFIGURATION}`,
157
+ hint: 'The chain stops here: an agent knows which server to ask but not which endpoints it has. Publish RFC 8414 or OpenID discovery metadata.',
158
+ learnMoreUrl: guideUrl(meta.id, 'no-server-metadata'),
159
+ });
160
+ return score - 30;
161
+ }
162
+ findings.push({ status: 'pass', message: `Authorization server ${base} publishes discovery metadata` });
163
+ for (const field of ['issuer', 'authorization_endpoint', 'token_endpoint']) {
164
+ if (metadata[field] !== undefined)
165
+ continue;
166
+ findings.push({
167
+ status: 'fail',
168
+ message: `Authorization server metadata is missing "${field}"`,
169
+ hint: `An OAuth client cannot complete a flow without ${field}.`,
170
+ learnMoreUrl: guideUrl(meta.id, 'incomplete-server-metadata'),
171
+ });
172
+ score -= 15;
173
+ }
174
+ const pkce = Array.isArray(metadata.code_challenge_methods_supported)
175
+ ? metadata.code_challenge_methods_supported.map(String)
176
+ : [];
177
+ if (!pkce.includes('S256')) {
178
+ findings.push({
179
+ status: 'warn',
180
+ message: 'Authorization server does not advertise PKCE with S256',
181
+ hint: 'Agents are public clients: they hold no secret, so PKCE is the only thing standing between an intercepted ' +
182
+ 'authorization code and a stolen session. Advertise code_challenge_methods_supported: ["S256"].',
183
+ learnMoreUrl: guideUrl(meta.id, 'no-pkce'),
184
+ });
185
+ score -= 15;
186
+ }
187
+ else {
188
+ findings.push({ status: 'pass', message: 'PKCE with S256 supported' });
189
+ }
190
+ // Agents appear without warning and cannot fill in a registration form, so
191
+ // either dynamic registration or client-ID metadata documents keeps them out
192
+ // of a manual onboarding queue.
193
+ const dynamic = metadata.registration_endpoint !== undefined;
194
+ const cimd = metadata.client_id_metadata_document_supported === true;
195
+ if (dynamic || cimd) {
196
+ findings.push({
197
+ status: 'pass',
198
+ message: dynamic ? 'Dynamic client registration supported' : 'Client ID Metadata Documents supported',
199
+ });
200
+ }
201
+ else {
202
+ findings.push({
203
+ status: 'warn',
204
+ message: 'No automated client registration',
205
+ hint: 'Without dynamic registration or Client ID Metadata Documents, every new agent needs a human to register it ' +
206
+ 'first. That is a queue, not an integration.',
207
+ learnMoreUrl: guideUrl(meta.id, 'no-registration'),
208
+ });
209
+ score -= 10;
210
+ }
211
+ return score;
212
+ }
213
+ //# sourceMappingURL=auth-discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-discovery.js","sourceRoot":"","sources":["../../src/checks/auth-discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,IAAI,GAAc;IAC7B,EAAE,EAAE,gBAAgB;IACpB,IAAI,EAAE,gBAAgB;IACtB,WAAW,EAAE,8FAA8F;IAC3G,QAAQ,EAAE,WAAW;CACtB,CAAC;AAEF,MAAM,kBAAkB,GAAG,uCAAuC,CAAC;AACnE,MAAM,oBAAoB,GAAG,yCAAyC,CAAC;AACvE,MAAM,oBAAoB,GAAG,mCAAmC,CAAC;AAEjE,oEAAoE;AACpE,MAAM,cAAc,GAAG;IACrB,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,wBAAwB,EAAE;IAC1D,EAAE,IAAI,EAAE,2BAA2B,EAAE,KAAK,EAAE,wBAAwB,EAAE;IACtE,EAAE,IAAI,EAAE,0BAA0B,EAAE,KAAK,EAAE,gBAAgB,EAAE;IAC7D,EAAE,IAAI,EAAE,mCAAmC,EAAE,KAAK,EAAE,oBAAoB,EAAE;IAC1E,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,oBAAoB,EAAE;IACzD,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,oBAAoB,EAAE;CAC1D,CAAC;AAEF,KAAK,UAAU,SAAS,CAAC,GAAiB,EAAE,GAAW;IACrD,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACrF,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAA4B,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,0EAA0E;AAC1E,KAAK,UAAU,WAAW,CAAC,GAAiB;IAC1C,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;QACnC,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACvD,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC,KAAK,CAAC;IAC5F,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,6BAA6B,CAAC,MAAc;IAC1D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACjE,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC;AAED,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,KAAK,CAAC,GAAiB;IACnD,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAChC,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,IAAI,KAAK,GAAG,GAAG,CAAC;IAEhB,8EAA8E;IAC9E,oDAAoD;IACpD,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,kBAAkB,CAAC,CAAC;IACpD,MAAM,WAAW,GAAG,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,6BAA6B,CAAC,SAAS,CAAC,CAAC;IAC9F,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACzB,QAAQ,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,wDAAwD;YACjE,MAAM,EAAE,WAAW;SACpB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,QAAQ,GACZ,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,SAAS,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACjE,CAAC,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,GAAG,GAAG,kBAAkB,EAAE,CAAC,CAAC,CAAC;IAE5D,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,QAAQ,CAAC,IAAI,CAAC;gBACZ,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,6EAA6E;gBACtF,MAAM,EAAE,6EAA6E;aACtF,CAAC,CAAC;YACH,OAAO,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC9C,CAAC;QAED,QAAQ,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,gBAAgB,OAAO,kCAAkC;YAClE,MAAM,EACJ,kDAAkD,kBAAkB,KAAK,YAAY,CAAC,kBAAkB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE;YAC1H,IAAI,EACF,6GAA6G;gBAC7G,8GAA8G;gBAC9G,0DAA0D;YAC5D,YAAY,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,WAAW,CAAC;SAC7C,CAAC,CAAC;QACH,OAAO,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC/C,CAAC;IAED,QAAQ,CAAC,IAAI,CAAC;QACZ,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,kDAAkD;QAC3D,MAAM,EAAE,YAAY,CAAC,kBAAkB,CAAC;KACzC,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAC;QAC3D,CAAC,CAAE,QAAQ,CAAC,qBAAmC,CAAC,GAAG,CAAC,MAAM,CAAC;QAC3D,CAAC,CAAC,EAAE,CAAC;IAEP,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,QAAQ,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,2DAA2D;YACpE,IAAI,EAAE,qIAAqI;YAC3I,YAAY,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,0BAA0B,CAAC;SAC5D,CAAC,CAAC;QACH,OAAO,WAAW,CAAC,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;IAChD,CAAC;IAED,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,gCAAgC,EAAE,CAAC,CAAC;IAE9F,IAAI,QAAQ,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACpC,QAAQ,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,+DAA+D;YACxE,IAAI,EAAE,yFAAyF;YAC/F,YAAY,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,aAAa,CAAC;SAC/C,CAAC,CAAC;QACH,KAAK,IAAI,EAAE,CAAC;IACd,CAAC;IAED,KAAK,GAAG,MAAM,2BAA2B,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;IAE5E,OAAO,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;AACnD,CAAC;AAED,+EAA+E;AAC/E,KAAK,UAAU,2BAA2B,CACxC,GAAiB,EACjB,MAAc,EACd,QAAmB,EACnB,KAAa;IAEb,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,QAAQ,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,yBAAyB,MAAM,sBAAsB;YAC9D,IAAI,EAAE,uDAAuD;YAC7D,YAAY,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,gBAAgB,CAAC;SAClD,CAAC,CAAC;QACH,OAAO,KAAK,GAAG,EAAE,CAAC;IACpB,CAAC;IAED,MAAM,QAAQ,GACZ,CAAC,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,oBAAoB,EAAE,CAAC,CAAC;QACxD,CAAC,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,oBAAoB,EAAE,CAAC,CAAC,CAAC;IAE3D,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,QAAQ,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,wBAAwB,IAAI,kCAAkC;YACvE,MAAM,EAAE,WAAW,oBAAoB,QAAQ,oBAAoB,EAAE;YACrE,IAAI,EAAE,yIAAyI;YAC/I,YAAY,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,oBAAoB,CAAC;SACtD,CAAC,CAAC;QACH,OAAO,KAAK,GAAG,EAAE,CAAC;IACpB,CAAC;IAED,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,wBAAwB,IAAI,+BAA+B,EAAE,CAAC,CAAC;IAExG,KAAK,MAAM,KAAK,IAAI,CAAC,QAAQ,EAAE,wBAAwB,EAAE,gBAAgB,CAAC,EAAE,CAAC;QAC3E,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,SAAS;YAAE,SAAS;QAC5C,QAAQ,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,6CAA6C,KAAK,GAAG;YAC9D,IAAI,EAAE,kDAAkD,KAAK,GAAG;YAChE,YAAY,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,4BAA4B,CAAC;SAC9D,CAAC,CAAC;QACH,KAAK,IAAI,EAAE,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,gCAAgC,CAAC;QACnE,CAAC,CAAE,QAAQ,CAAC,gCAA8C,CAAC,GAAG,CAAC,MAAM,CAAC;QACtE,CAAC,CAAC,EAAE,CAAC;IACP,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,QAAQ,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,wDAAwD;YACjE,IAAI,EACF,4GAA4G;gBAC5G,gGAAgG;YAClG,YAAY,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,CAAC;SAC3C,CAAC,CAAC;QACH,KAAK,IAAI,EAAE,CAAC;IACd,CAAC;SAAM,CAAC;QACN,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,2EAA2E;IAC3E,6EAA6E;IAC7E,gCAAgC;IAChC,MAAM,OAAO,GAAG,QAAQ,CAAC,qBAAqB,KAAK,SAAS,CAAC;IAC7D,MAAM,IAAI,GAAG,QAAQ,CAAC,qCAAqC,KAAK,IAAI,CAAC;IACrE,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;QACpB,QAAQ,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,uCAAuC,CAAC,CAAC,CAAC,wCAAwC;SACtG,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,QAAQ,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,kCAAkC;YAC3C,IAAI,EACF,6GAA6G;gBAC7G,6CAA6C;YAC/C,YAAY,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,iBAAiB,CAAC;SACnD,CAAC,CAAC;QACH,KAAK,IAAI,EAAE,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,40 @@
1
+ import type { CheckContext, CheckResult, CheckMeta } from '../types.js';
2
+ /**
3
+ * "commerce-discovery" — can an agent buy from this site without a human
4
+ * driving the checkout?
5
+ *
6
+ * The Universal Commerce Protocol is the one agentic-commerce specification
7
+ * with a published site-side discovery mechanism: a public profile at
8
+ * `/.well-known/ucp` declaring which commerce services the merchant offers,
9
+ * over which transports, against which schemas, and which payment handlers it
10
+ * accepts. Google leads it, with Shopify, Etsy, Walmart and Stripe
11
+ * participating.
12
+ *
13
+ * The alternatives deliberately have nothing to probe. OpenAI and Stripe's
14
+ * Agentic Commerce Protocol states outright that it defines no discovery
15
+ * endpoint or manifest — merchants are onboarded per platform. Google's AP2
16
+ * advertises itself as an A2A capability extension, not a file. So this check
17
+ * covers UCP and says plainly that the others are not discoverable rather than
18
+ * inventing paths for them.
19
+ *
20
+ * It is conditional. Most sites do not sell anything, and scoring a
21
+ * documentation site zero for lacking a commerce profile would be nonsense. The
22
+ * check reports N/A unless the page shows commerce signals: `Product` or `Offer`
23
+ * structured data, or links into a cart or checkout.
24
+ */
25
+ export declare const meta: CheckMeta;
26
+ /**
27
+ * Evidence that this site has a storefront an agent could transact against.
28
+ *
29
+ * The distinction that matters is between selling and pricing. A SaaS landing
30
+ * page routinely carries a lone `Offer` describing its plans; that is a price
31
+ * statement, not a catalog, and telling such a site to publish a commerce
32
+ * profile would be wrong. So a bare `Offer` counts only alongside a second
33
+ * signal, while an unambiguous storefront type stands on its own.
34
+ */
35
+ export declare function hasCommerceSignals(html: string): {
36
+ found: boolean;
37
+ evidence: string[];
38
+ };
39
+ export default function check(ctx: CheckContext): Promise<CheckResult>;
40
+ //# sourceMappingURL=commerce-discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commerce-discovery.d.ts","sourceRoot":"","sources":["../../src/checks/commerce-discovery.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAW,MAAM,aAAa,CAAC;AAMjF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,IAAI,EAAE,SAKlB,CAAC;AAQF;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAuBvF;AAED,wBAA8B,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAsF3E"}
@@ -0,0 +1,295 @@
1
+ import { guideUrl } from '../guide-urls.js';
2
+ import { buildResult, isHtmlDocument, notApplicable } from './utils.js';
3
+ import { standingNote } from './well-known.js';
4
+ import { findJsonLdBlocks } from './html-utils.js';
5
+ import { forcedBy, profileFrom } from './surface.js';
6
+ /**
7
+ * "commerce-discovery" — can an agent buy from this site without a human
8
+ * driving the checkout?
9
+ *
10
+ * The Universal Commerce Protocol is the one agentic-commerce specification
11
+ * with a published site-side discovery mechanism: a public profile at
12
+ * `/.well-known/ucp` declaring which commerce services the merchant offers,
13
+ * over which transports, against which schemas, and which payment handlers it
14
+ * accepts. Google leads it, with Shopify, Etsy, Walmart and Stripe
15
+ * participating.
16
+ *
17
+ * The alternatives deliberately have nothing to probe. OpenAI and Stripe's
18
+ * Agentic Commerce Protocol states outright that it defines no discovery
19
+ * endpoint or manifest — merchants are onboarded per platform. Google's AP2
20
+ * advertises itself as an A2A capability extension, not a file. So this check
21
+ * covers UCP and says plainly that the others are not discoverable rather than
22
+ * inventing paths for them.
23
+ *
24
+ * It is conditional. Most sites do not sell anything, and scoring a
25
+ * documentation site zero for lacking a commerce profile would be nonsense. The
26
+ * check reports N/A unless the page shows commerce signals: `Product` or `Offer`
27
+ * structured data, or links into a cart or checkout.
28
+ */
29
+ export const meta = {
30
+ id: 'commerce-discovery',
31
+ name: 'Commerce Discovery',
32
+ description: 'Checks the Universal Commerce Protocol profile for agent-driven purchasing',
33
+ category: 'protocols',
34
+ };
35
+ /** UCP profile paths, in the order the specification and Google's docs use. */
36
+ const PROFILE_PATHS = ['/.well-known/ucp', '/.well-known/ucp.json'];
37
+ /** Capability names the specification defines, for reporting unknown ones. */
38
+ const KNOWN_CAPABILITY_PREFIX = 'dev.ucp.';
39
+ /**
40
+ * Evidence that this site has a storefront an agent could transact against.
41
+ *
42
+ * The distinction that matters is between selling and pricing. A SaaS landing
43
+ * page routinely carries a lone `Offer` describing its plans; that is a price
44
+ * statement, not a catalog, and telling such a site to publish a commerce
45
+ * profile would be wrong. So a bare `Offer` counts only alongside a second
46
+ * signal, while an unambiguous storefront type stands on its own.
47
+ */
48
+ export function hasCommerceSignals(html) {
49
+ const evidence = [];
50
+ let weakOffer = false;
51
+ for (const block of findJsonLdBlocks(html)) {
52
+ if (/"@type"\s*:\s*"(Product|AggregateOffer|OnlineStore|OnlineMarketplace|ItemList)"/i.test(block)) {
53
+ evidence.push('Product or storefront structured data');
54
+ break;
55
+ }
56
+ if (/"@type"\s*:\s*"Offer"/i.test(block))
57
+ weakOffer = true;
58
+ }
59
+ const hasCart = /<a\b[^>]+href\s*=\s*["'][^"']*\/(cart|checkout|basket|bag)\b/i.test(html);
60
+ if (hasCart)
61
+ evidence.push('links to a cart or checkout');
62
+ if (/<meta\b[^>]+property\s*=\s*["']product:price:amount["']/i.test(html)) {
63
+ evidence.push('product price Open Graph tags');
64
+ }
65
+ // A lone Offer is a plan price. Paired with a cart, it is a storefront.
66
+ if (weakOffer && evidence.length > 0)
67
+ evidence.push('Offer structured data');
68
+ return { found: evidence.length > 0, evidence };
69
+ }
70
+ export default async function check(ctx) {
71
+ const start = performance.now();
72
+ const findings = [];
73
+ let score = 100;
74
+ let profile = null;
75
+ for (const path of PROFILE_PATHS) {
76
+ const res = await ctx.fetch(`${ctx.url}${path}`);
77
+ if (res.ok && res.body.trim().length > 0 && !isHtmlDocument(res.body)) {
78
+ profile = { path, body: res.body, headers: res.headers };
79
+ break;
80
+ }
81
+ // A profile behind auth is a specification violation worth reporting, since
82
+ // an agent has no credentials at discovery time.
83
+ if (res.status === 401 || res.status === 403) {
84
+ findings.push({
85
+ status: 'fail',
86
+ message: `${path} requires authentication`,
87
+ detail: `HTTP ${res.status}`,
88
+ hint: 'The UCP profile must be publicly accessible with no authentication. An agent reads it before it has any credentials.',
89
+ learnMoreUrl: guideUrl(meta.id, 'profile-auth'),
90
+ });
91
+ return buildResult(meta, 0, findings, start);
92
+ }
93
+ }
94
+ if (profile === null) {
95
+ const commerce = hasCommerceSignals(ctx.html ?? '');
96
+ if (!commerce.found && !forcedBy(profileFrom(ctx), 'commerce')) {
97
+ findings.push({
98
+ status: 'pass',
99
+ message: 'No commerce surface — agentic-commerce discovery does not apply to this site',
100
+ detail: 'No Product or Offer structured data, cart links, or product price tags found.',
101
+ });
102
+ return notApplicable(meta, findings, start);
103
+ }
104
+ findings.push({
105
+ status: 'warn',
106
+ message: 'Site sells something but publishes no agent-readable commerce profile',
107
+ detail: `Commerce signals found: ${commerce.evidence.join(', ')}. Checked ${PROFILE_PATHS.join(', ')}.`,
108
+ hint: 'Publish a Universal Commerce Protocol profile at /.well-known/ucp so an agent can find your catalog, cart and ' +
109
+ 'checkout without a human. Note that the alternatives are not discoverable by design: the OpenAI and Stripe ' +
110
+ 'Agentic Commerce Protocol defines no manifest, and AP2 advertises itself through an A2A card extension.',
111
+ learnMoreUrl: guideUrl(meta.id, 'not-found'),
112
+ });
113
+ return buildResult(meta, 0, findings, start);
114
+ }
115
+ findings.push({
116
+ status: 'pass',
117
+ message: `UCP profile published at ${profile.path}`,
118
+ detail: standingNote(profile.path),
119
+ });
120
+ let data;
121
+ try {
122
+ data = JSON.parse(profile.body);
123
+ }
124
+ catch {
125
+ findings.push({
126
+ status: 'fail',
127
+ message: 'UCP profile is not valid JSON',
128
+ hint: 'Fix the JSON syntax. An agent cannot transact against a profile it cannot parse.',
129
+ learnMoreUrl: guideUrl(meta.id, 'invalid-json'),
130
+ });
131
+ return buildResult(meta, 10, findings, start);
132
+ }
133
+ const ucp = (data.ucp ?? {});
134
+ if (Object.keys(ucp).length === 0) {
135
+ findings.push({
136
+ status: 'fail',
137
+ message: 'UCP profile has no "ucp" object',
138
+ hint: 'The profile wraps everything in a top-level "ucp" object carrying version, services and payment_handlers.',
139
+ learnMoreUrl: guideUrl(meta.id, 'no-ucp-object'),
140
+ });
141
+ return buildResult(meta, 20, findings, start);
142
+ }
143
+ score = validateVersion(ucp, findings, score);
144
+ score = await validateServices(ctx, ucp, findings, score);
145
+ score = validatePayments(ucp, findings, score);
146
+ score = validateKeys(data, ucp, findings, score);
147
+ return buildResult(meta, score, findings, start);
148
+ }
149
+ /** The version is a spec date, and it tells a client which shape to expect. */
150
+ function validateVersion(ucp, findings, score) {
151
+ const version = typeof ucp.version === 'string' ? ucp.version : null;
152
+ if (version === null) {
153
+ findings.push({
154
+ status: 'fail',
155
+ message: 'UCP profile declares no version',
156
+ hint: 'Add "version" with the specification date you implement, for example "2026-08-25".',
157
+ learnMoreUrl: guideUrl(meta.id, 'no-version'),
158
+ });
159
+ return score - 20;
160
+ }
161
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(version)) {
162
+ findings.push({
163
+ status: 'warn',
164
+ message: `UCP version "${version}" is not a specification date`,
165
+ hint: 'UCP versions are dates, for example "2026-08-25". A semantic version here will not match any published revision.',
166
+ learnMoreUrl: guideUrl(meta.id, 'version-format'),
167
+ });
168
+ return score - 10;
169
+ }
170
+ findings.push({ status: 'pass', message: `UCP version ${version}` });
171
+ return score;
172
+ }
173
+ /** Services declare what an agent may do and where. Their schemas must resolve. */
174
+ async function validateServices(ctx, ucp, findings, score) {
175
+ const services = (ucp.services ?? {});
176
+ const names = Object.keys(services);
177
+ if (names.length === 0) {
178
+ findings.push({
179
+ status: 'fail',
180
+ message: 'UCP profile declares no services',
181
+ hint: 'Declare at least one service, for example dev.ucp.shopping, with its transports and schema URLs.',
182
+ learnMoreUrl: guideUrl(meta.id, 'no-services'),
183
+ });
184
+ return score - 25;
185
+ }
186
+ findings.push({ status: 'pass', message: `${names.length} commerce service(s) declared: ${names.join(', ')}` });
187
+ const unprefixed = names.filter((n) => !n.startsWith(KNOWN_CAPABILITY_PREFIX) && !n.includes('.'));
188
+ if (unprefixed.length > 0) {
189
+ findings.push({
190
+ status: 'warn',
191
+ message: 'Service name is not in reverse-DNS form',
192
+ detail: unprefixed.join(', '),
193
+ hint: 'Service names are reverse-DNS so vendors cannot collide, for example dev.ucp.shopping.',
194
+ learnMoreUrl: guideUrl(meta.id, 'service-name'),
195
+ });
196
+ score -= 5;
197
+ }
198
+ // Resolve the schema URLs the profile promises. A profile pointing at a
199
+ // missing schema is a transaction an agent starts and cannot finish.
200
+ const schemas = [];
201
+ for (const value of Object.values(services)) {
202
+ collectSchemaUrls(value, schemas);
203
+ }
204
+ if (schemas.length === 0) {
205
+ findings.push({
206
+ status: 'warn',
207
+ message: 'No service declares a schema URL',
208
+ hint: 'Each transport should point at the schema describing its operations, so an agent knows the request shapes.',
209
+ learnMoreUrl: guideUrl(meta.id, 'no-schema'),
210
+ });
211
+ return score - 10;
212
+ }
213
+ const dead = [];
214
+ for (const url of schemas.slice(0, 3)) {
215
+ const head = await ctx.fetch(url, { method: 'HEAD' });
216
+ const res = head.status === 405 || head.status === 501 ? await ctx.fetch(url) : head;
217
+ if (!res.ok)
218
+ dead.push(`${url} (HTTP ${res.status || 'network error'})`);
219
+ }
220
+ if (dead.length > 0) {
221
+ findings.push({
222
+ status: 'fail',
223
+ message: `${dead.length} declared schema URL(s) cannot be fetched`,
224
+ detail: dead.join('\n'),
225
+ hint: 'An agent reads the schema before it builds a request. A dead schema is a transaction it starts and cannot finish.',
226
+ learnMoreUrl: guideUrl(meta.id, 'dead-schema'),
227
+ });
228
+ score -= 20;
229
+ }
230
+ else {
231
+ findings.push({ status: 'pass', message: `${Math.min(schemas.length, 3)} declared schema URL(s) resolve` });
232
+ }
233
+ return score;
234
+ }
235
+ /** Walk a service definition for `schema` URLs, whatever transport shape it uses. */
236
+ function collectSchemaUrls(value, into) {
237
+ if (Array.isArray(value)) {
238
+ for (const item of value)
239
+ collectSchemaUrls(item, into);
240
+ return;
241
+ }
242
+ if (typeof value !== 'object' || value === null)
243
+ return;
244
+ for (const [key, child] of Object.entries(value)) {
245
+ if (key === 'schema' && typeof child === 'string' && /^https?:\/\//.test(child)) {
246
+ into.push(child);
247
+ continue;
248
+ }
249
+ collectSchemaUrls(child, into);
250
+ }
251
+ }
252
+ /** Without a payment handler, an agent can browse but not buy. */
253
+ function validatePayments(ucp, findings, score) {
254
+ const handlers = ucp.payment_handlers ?? ucp.payment?.handlers;
255
+ const list = Array.isArray(handlers) ? handlers : [];
256
+ if (list.length === 0) {
257
+ findings.push({
258
+ status: 'warn',
259
+ message: 'UCP profile declares no payment handlers',
260
+ hint: 'Without a payment handler an agent can read your catalog but cannot complete a purchase. Declare the handlers you accept.',
261
+ learnMoreUrl: guideUrl(meta.id, 'no-payment-handlers'),
262
+ });
263
+ return score - 15;
264
+ }
265
+ const named = list.map((h) => String(h.name ?? '(unnamed)'));
266
+ findings.push({ status: 'pass', message: `${list.length} payment handler(s): ${named.join(', ')}` });
267
+ const unnamed = list.filter((h) => h.name === undefined).length;
268
+ if (unnamed > 0) {
269
+ findings.push({
270
+ status: 'warn',
271
+ message: `${unnamed} payment handler(s) have no name`,
272
+ hint: 'Each handler needs a name so an agent can match it against the payment methods it holds.',
273
+ learnMoreUrl: guideUrl(meta.id, 'unnamed-handler'),
274
+ });
275
+ score -= 5;
276
+ }
277
+ return score;
278
+ }
279
+ /** Signing keys let an agent verify the profile belongs to the merchant. */
280
+ function validateKeys(data, ucp, findings, score) {
281
+ const keys = data.keys ?? data.signing_keys ?? ucp.keys ?? ucp.signing_keys;
282
+ const list = Array.isArray(keys) ? keys : [];
283
+ if (list.length === 0) {
284
+ findings.push({
285
+ status: 'warn',
286
+ message: 'UCP profile declares no signing keys',
287
+ hint: 'Publish the public keys an agent uses to verify your responses. Money is moving; identity should not rest on DNS alone.',
288
+ learnMoreUrl: guideUrl(meta.id, 'no-keys'),
289
+ });
290
+ return score - 10;
291
+ }
292
+ findings.push({ status: 'pass', message: `${list.length} signing key(s) published` });
293
+ return score;
294
+ }
295
+ //# sourceMappingURL=commerce-discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commerce-discovery.js","sourceRoot":"","sources":["../../src/checks/commerce-discovery.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"content-negotiation.d.ts","sourceRoot":"","sources":["../../src/checks/content-negotiation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAW,MAAM,aAAa,CAAC;AAIjF,eAAO,MAAM,IAAI,EAAE,SAKlB,CAAC;AAyBF,wBAA8B,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAuH3E"}
1
+ {"version":3,"file":"content-negotiation.d.ts","sourceRoot":"","sources":["../../src/checks/content-negotiation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAW,MAAM,aAAa,CAAC;AAKjF,eAAO,MAAM,IAAI,EAAE,SAKlB,CAAC;AAyCF,wBAA8B,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CA6G3E"}