@agent-cards/checkout 0.18.0 → 0.21.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 (88) hide show
  1. package/README.md +6 -669
  2. package/cdp.d.ts +1 -0
  3. package/cdp.js +2 -0
  4. package/index.d.ts +1 -0
  5. package/index.js +2 -0
  6. package/package.json +33 -33
  7. package/playwright.d.ts +1 -0
  8. package/playwright.js +2 -0
  9. package/preflight.d.ts +1 -0
  10. package/preflight.js +2 -0
  11. package/CHANGELOG.md +0 -124
  12. package/PREFLIGHT.md +0 -308
  13. package/dist/adyen.generated.d.ts +0 -24
  14. package/dist/adyen.generated.js +0 -64
  15. package/dist/attachment.d.ts +0 -11
  16. package/dist/attachment.js +0 -50
  17. package/dist/braintree.d.ts +0 -2
  18. package/dist/braintree.generated.d.ts +0 -10
  19. package/dist/braintree.generated.js +0 -302
  20. package/dist/braintree.js +0 -2
  21. package/dist/builtin-registry.generated.d.ts +0 -2
  22. package/dist/builtin-registry.generated.js +0 -1
  23. package/dist/card-fields.generated.d.ts +0 -3
  24. package/dist/card-fields.generated.js +0 -46
  25. package/dist/cdp.d.ts +0 -189
  26. package/dist/cdp.js +0 -2194
  27. package/dist/checkout-com.generated.d.ts +0 -4
  28. package/dist/checkout-com.generated.js +0 -183
  29. package/dist/client.d.ts +0 -618
  30. package/dist/client.js +0 -1251
  31. package/dist/hosted-form.d.ts +0 -44
  32. package/dist/hosted-form.js +0 -78
  33. package/dist/index.d.ts +0 -13
  34. package/dist/index.js +0 -6
  35. package/dist/lifecycle.d.ts +0 -165
  36. package/dist/lifecycle.js +0 -370
  37. package/dist/mercado-checkout.d.ts +0 -20
  38. package/dist/mercado-checkout.generated.d.ts +0 -52
  39. package/dist/mercado-checkout.generated.js +0 -198
  40. package/dist/mercado-checkout.js +0 -108
  41. package/dist/owned-shop.generated.d.ts +0 -24
  42. package/dist/owned-shop.generated.js +0 -108
  43. package/dist/paysafe.generated.d.ts +0 -12
  44. package/dist/paysafe.generated.js +0 -87
  45. package/dist/playwright.d.ts +0 -3
  46. package/dist/playwright.js +0 -3
  47. package/dist/preflight-capabilities.generated.d.ts +0 -1253
  48. package/dist/preflight-capabilities.generated.js +0 -1929
  49. package/dist/preflight-catalog.json +0 -4595
  50. package/dist/preflight-playwright.d.ts +0 -34
  51. package/dist/preflight-playwright.js +0 -355
  52. package/dist/preflight-schemas.json +0 -1110
  53. package/dist/preflight.d.ts +0 -1
  54. package/dist/preflight.generated.d.ts +0 -1965
  55. package/dist/preflight.generated.js +0 -556
  56. package/dist/preflight.js +0 -2
  57. package/dist/preparation.d.ts +0 -31
  58. package/dist/preparation.js +0 -164
  59. package/dist/prepared-processor.d.ts +0 -10
  60. package/dist/prepared-processor.js +0 -122
  61. package/dist/recurly.generated.d.ts +0 -1
  62. package/dist/recurly.generated.js +0 -87
  63. package/dist/registry.d.ts +0 -76
  64. package/dist/registry.js +0 -296
  65. package/dist/spreedly.generated.d.ts +0 -10
  66. package/dist/spreedly.generated.js +0 -332
  67. package/dist/stripe-checkout.d.ts +0 -81
  68. package/dist/stripe-checkout.generated.d.ts +0 -82
  69. package/dist/stripe-checkout.generated.js +0 -1004
  70. package/dist/stripe-checkout.js +0 -140
  71. package/dist/substitute.d.ts +0 -38
  72. package/dist/substitute.js +0 -23
  73. package/dist/substitutions.generated.d.ts +0 -10
  74. package/dist/substitutions.generated.js +0 -66
  75. package/examples/existing-browser.mjs +0 -63
  76. package/examples/preflight/classify-direct.mjs +0 -21
  77. package/examples/preflight/classify-kernel.mjs +0 -30
  78. package/examples/preflight/inspect-browser.mjs +0 -44
  79. package/examples/preflight/kernel-native/README.md +0 -112
  80. package/examples/preflight/kernel-native/documented-adapters.json +0 -113
  81. package/examples/preflight/kernel-native/inventory.json +0 -233
  82. package/examples/preflight/kernel-native/qualification.mjs +0 -182
  83. package/examples/preflight/kernel-profile.empty.json +0 -11
  84. package/examples/preflight/mollie-hosted.observations.json +0 -23
  85. package/examples/preflight/mollie-hosted.result.json +0 -103
  86. package/examples/preflight/stripe-script.direct.result.json +0 -92
  87. package/examples/preflight/stripe-script.observations.json +0 -16
  88. package/examples/preflight/stripe-script.result.json +0 -87
@@ -1,113 +0,0 @@
1
- {
2
- "schema_version": 1,
3
- "baseline_version": "kernel-native-docs-2026-09-11.1",
4
- "reviewed_at": "2026-09-11",
5
- "evidence_level": "documentation_only",
6
- "native_build": null,
7
- "sources": [
8
- {
9
- "id": "kernel-payments-overview",
10
- "repository": "kernel/docs",
11
- "commit": "fd81f0d8c7ff33e81d6feae2dd314347b6ebb355",
12
- "path": "integrations/payments/overview.mdx",
13
- "url": "https://github.com/kernel/docs/blob/fd81f0d8c7ff33e81d6feae2dd314347b6ebb355/integrations/payments/overview.mdx",
14
- "sha256": "a6c3633ef6aa8cb09deb210d5a36cccb2f3561cffa470ccb5cf2f7de5e7b4ab9"
15
- },
16
- {
17
- "id": "kernel-agentcard-guide",
18
- "repository": "kernel/docs",
19
- "commit": "fd81f0d8c7ff33e81d6feae2dd314347b6ebb355",
20
- "path": "integrations/payments/agentcard.mdx",
21
- "url": "https://github.com/kernel/docs/blob/fd81f0d8c7ff33e81d6feae2dd314347b6ebb355/integrations/payments/agentcard.mdx",
22
- "sha256": "0075bd44e45fe43147f63348a01bf6e9bb6dbdd6eb7c33eea46f09fcfc778a7b"
23
- }
24
- ],
25
- "documented_adapters": [
26
- {
27
- "psp": "stripe",
28
- "method": "POST",
29
- "scheme": "https",
30
- "body_encoding": "form",
31
- "url_patterns": [
32
- "https://api.stripe.com/v1/payment_methods",
33
- "https://api.stripe.com/v1/tokens",
34
- "https://api.stripe.com/v1/payment_intents/{id}/confirm",
35
- "https://api.stripe.com/v1/payment_pages/{id}/confirm"
36
- ],
37
- "source_id": "kernel-payments-overview",
38
- "limitations": [
39
- "Other layouts, payment scenarios, and authentication flows are unqualified."
40
- ]
41
- },
42
- {
43
- "psp": "shopify",
44
- "method": "POST",
45
- "scheme": "https",
46
- "body_encoding": "json",
47
- "url_patterns": [
48
- "https://checkout.pci.shopifyinc.com/sessions",
49
- "https://deposit.<region>.shopifycs.com/sessions"
50
- ],
51
- "source_id": "kernel-payments-overview",
52
- "limitations": [
53
- "Card sessions only; this list does not qualify native checkout GraphQL.",
54
- "Allowed regions are not enumerated."
55
- ]
56
- },
57
- {
58
- "psp": "square",
59
- "method": "POST",
60
- "scheme": "https",
61
- "body_encoding": "json",
62
- "url_patterns": [
63
- "https://pci-connect.squareup.com/v2/card-nonce",
64
- "https://pci-connect.squareupsandbox.com/v2/card-nonce"
65
- ],
66
- "source_id": "kernel-payments-overview",
67
- "limitations": [
68
- "A listed sandbox hostname does not establish sandbox card-item availability.",
69
- "CORS, preparation, and replay timing remain unqualified."
70
- ]
71
- },
72
- {
73
- "psp": "recurly",
74
- "method": "POST",
75
- "scheme": "https",
76
- "body_encoding": "form",
77
- "url_patterns": [
78
- "https://api.recurly.com/js/v1/token",
79
- "https://api.eu.recurly.com/js/v1/token"
80
- ],
81
- "source_id": "kernel-payments-overview",
82
- "limitations": [
83
- "Form POST only; JSONP, saved-card use, and subscriptions remain unqualified."
84
- ]
85
- },
86
- {
87
- "psp": "razorpay",
88
- "method": "POST",
89
- "scheme": "https",
90
- "body_encoding": "form",
91
- "url_patterns": [
92
- "https://api.razorpay.com/v1/payments/create/ajax",
93
- "https://api.razorpay.com/v1/standard_checkout/payments/create/ajax"
94
- ],
95
- "source_id": "kernel-payments-overview",
96
- "limitations": [
97
- "Tokenization-only layouts and authentication continuation remain unqualified."
98
- ]
99
- }
100
- ],
101
- "limitations": [
102
- "Documentation claims only; this baseline is neither runtime-test evidence nor a deployable capability profile.",
103
- "Kernel lists these five adapters for Link and Agentcard. Unlisted processors remain unestablished, not explicitly unsupported.",
104
- "Recognition requires every alias and the expected HTTPS method, destination, content type, and card-field layout. Complete body schemas are unavailable.",
105
- "Kernel says non-Stripe coverage needs further tests with actual SDKs and hosted checkouts.",
106
- "Encrypted, differently structured, or unrecognized requests bypass native handoff.",
107
- "Patterns describe the documentation; they grant no payment admission or native execution capability.",
108
- "Agentcard begins authorization after recognition; no separate authorize operation is advertised.",
109
- "Ready item state, approval, and replay results do not confirm a paid merchant order.",
110
- "No adapter build identity or conformance results accompany this table. Client SDK and CLI versions identify different artifacts.",
111
- "Direct SDK tests cannot qualify Kernel native support. Release requires evidence for the actual native build."
112
- ]
113
- }
@@ -1,233 +0,0 @@
1
- {
2
- "schema_version": 1,
3
- "catalog_version": "2026-09-15.1",
4
- "catalog_sha256": "c605e3f370a2560e15d695e9ce80248f117076e4556f8dc7912ba1e54fb92315",
5
- "baseline_version": "kernel-native-docs-2026-09-11.1",
6
- "baseline_sha256": "d86722f49633d8223fccae54cd3d485df4375aee06aa156a273cc689b7c8507c",
7
- "native_build": null,
8
- "processors": [
9
- {
10
- "psp": "spreedly",
11
- "mode": "token",
12
- "documentation": "not_documented",
13
- "status": "unknown",
14
- "limitations": [
15
- "No adapter declaration was found in the pinned documentation. Native runtime evidence is missing."
16
- ]
17
- },
18
- {
19
- "psp": "shopify",
20
- "mode": "token",
21
- "documentation": "documented",
22
- "status": "unknown",
23
- "limitations": [
24
- "Card sessions only; this list does not qualify native checkout GraphQL.",
25
- "Allowed regions are not enumerated.",
26
- "Native runtime evidence is missing."
27
- ]
28
- },
29
- {
30
- "psp": "stripe",
31
- "mode": "token",
32
- "documentation": "documented",
33
- "status": "unknown",
34
- "limitations": [
35
- "Other layouts, payment scenarios, and authentication flows are unqualified.",
36
- "Native runtime evidence is missing."
37
- ]
38
- },
39
- {
40
- "psp": "braintree",
41
- "mode": "token",
42
- "documentation": "not_documented",
43
- "status": "unknown",
44
- "limitations": [
45
- "No adapter declaration was found in the pinned documentation. Native runtime evidence is missing."
46
- ]
47
- },
48
- {
49
- "psp": "checkout_com",
50
- "mode": "token",
51
- "documentation": "not_documented",
52
- "status": "unknown",
53
- "limitations": [
54
- "No adapter declaration was found in the pinned documentation. Native runtime evidence is missing."
55
- ]
56
- },
57
- {
58
- "psp": "adyen",
59
- "mode": "cse",
60
- "documentation": "not_documented",
61
- "status": "unknown",
62
- "limitations": [
63
- "No adapter declaration was found in the pinned documentation. Native runtime evidence is missing."
64
- ]
65
- },
66
- {
67
- "psp": "tranzila",
68
- "mode": "hosted_form",
69
- "documentation": "not_documented",
70
- "status": "unknown",
71
- "limitations": [
72
- "No adapter declaration was found in the pinned documentation. Native runtime evidence is missing."
73
- ]
74
- },
75
- {
76
- "psp": "square",
77
- "mode": "token",
78
- "documentation": "documented",
79
- "status": "unknown",
80
- "limitations": [
81
- "A listed sandbox hostname does not establish sandbox card-item availability.",
82
- "CORS, preparation, and replay timing remain unqualified.",
83
- "Native runtime evidence is missing."
84
- ]
85
- },
86
- {
87
- "psp": "authorize_net",
88
- "mode": "token",
89
- "documentation": "not_documented",
90
- "status": "unknown",
91
- "limitations": [
92
- "No adapter declaration was found in the pinned documentation. Native runtime evidence is missing."
93
- ]
94
- },
95
- {
96
- "psp": "worldpay",
97
- "mode": "token",
98
- "documentation": "not_documented",
99
- "status": "unknown",
100
- "limitations": [
101
- "No adapter declaration was found in the pinned documentation. Native runtime evidence is missing."
102
- ]
103
- },
104
- {
105
- "psp": "nuvei",
106
- "mode": "token",
107
- "documentation": "not_documented",
108
- "status": "unknown",
109
- "limitations": [
110
- "No adapter declaration was found in the pinned documentation. Native runtime evidence is missing."
111
- ]
112
- },
113
- {
114
- "psp": "airwallex",
115
- "mode": "token",
116
- "documentation": "not_documented",
117
- "status": "unknown",
118
- "limitations": [
119
- "No adapter declaration was found in the pinned documentation. Native runtime evidence is missing."
120
- ]
121
- },
122
- {
123
- "psp": "rapyd",
124
- "mode": "token",
125
- "documentation": "not_documented",
126
- "status": "unknown",
127
- "limitations": [
128
- "No adapter declaration was found in the pinned documentation. Native runtime evidence is missing."
129
- ]
130
- },
131
- {
132
- "psp": "dlocal",
133
- "mode": "token",
134
- "documentation": "not_documented",
135
- "status": "unknown",
136
- "limitations": [
137
- "No adapter declaration was found in the pinned documentation. Native runtime evidence is missing."
138
- ]
139
- },
140
- {
141
- "psp": "ebanx",
142
- "mode": "token",
143
- "documentation": "not_documented",
144
- "status": "unknown",
145
- "limitations": [
146
- "No adapter declaration was found in the pinned documentation. Native runtime evidence is missing."
147
- ]
148
- },
149
- {
150
- "psp": "mercado_pago",
151
- "mode": "token",
152
- "documentation": "not_documented",
153
- "status": "unknown",
154
- "limitations": [
155
- "No adapter declaration was found in the pinned documentation. Native runtime evidence is missing."
156
- ]
157
- },
158
- {
159
- "psp": "payu",
160
- "mode": "token",
161
- "documentation": "not_documented",
162
- "status": "unknown",
163
- "limitations": [
164
- "No adapter declaration was found in the pinned documentation. Native runtime evidence is missing."
165
- ]
166
- },
167
- {
168
- "psp": "razorpay",
169
- "mode": "token",
170
- "documentation": "documented",
171
- "status": "unknown",
172
- "limitations": [
173
- "Tokenization-only layouts and authentication continuation remain unqualified.",
174
- "Native runtime evidence is missing."
175
- ]
176
- },
177
- {
178
- "psp": "mollie",
179
- "mode": "token",
180
- "documentation": "not_documented",
181
- "status": "unknown",
182
- "limitations": [
183
- "No adapter declaration was found in the pinned documentation. Native runtime evidence is missing."
184
- ]
185
- },
186
- {
187
- "psp": "paysafe",
188
- "mode": "token",
189
- "documentation": "not_documented",
190
- "status": "unknown",
191
- "limitations": [
192
- "No adapter declaration was found in the pinned documentation. Native runtime evidence is missing."
193
- ]
194
- },
195
- {
196
- "psp": "recurly",
197
- "mode": "token",
198
- "documentation": "documented",
199
- "status": "unknown",
200
- "limitations": [
201
- "Form POST only; JSONP, saved-card use, and subscriptions remain unqualified.",
202
- "Native runtime evidence is missing."
203
- ]
204
- },
205
- {
206
- "psp": "moneris",
207
- "mode": "token",
208
- "documentation": "not_documented",
209
- "status": "unknown",
210
- "limitations": [
211
- "No adapter declaration was found in the pinned documentation. Native runtime evidence is missing."
212
- ]
213
- },
214
- {
215
- "psp": "bambora",
216
- "mode": "token",
217
- "documentation": "not_documented",
218
- "status": "unknown",
219
- "limitations": [
220
- "No adapter declaration was found in the pinned documentation. Native runtime evidence is missing."
221
- ]
222
- },
223
- {
224
- "psp": "global_payments",
225
- "mode": "token",
226
- "documentation": "not_documented",
227
- "status": "unknown",
228
- "limitations": [
229
- "No adapter declaration was found in the pinned documentation. Native runtime evidence is missing."
230
- ]
231
- }
232
- ]
233
- }
@@ -1,182 +0,0 @@
1
- // Maintainer tooling. Reports are trusted review inputs, never merchant-page inputs.
2
- import { createHash } from 'node:crypto';
3
- import { readFile, realpath } from 'node:fs/promises';
4
- import { isAbsolute, relative, resolve, sep } from 'node:path';
5
- import { pathToFileURL } from 'node:url';
6
- import { BUILTIN_REGISTRY } from '@agent-cards/checkout';
7
- import { assessCheckoutSupport, getCheckoutPreflightCatalog } from '@agent-cards/checkout/preflight';
8
-
9
- export const SUPPORTED_CHECKS = Object.freeze([
10
- 'native_recognition', 'approval_pause_resume', 'processor_replay',
11
- 'merchant_confirmation', 'unrecognized_request_passthrough', 'decline_or_error',
12
- 'no_duplicate_submission', 'authentication_or_explicit_exclusion',
13
- ]);
14
- const SCENARIOS = ['one_time', 'save_card', 'subscription_initial', 'subscription_renewal'];
15
- const sha256 = bytes => createHash('sha256').update(bytes).digest('hex');
16
- const canonical = value => Array.isArray(value) ? value.map(canonical)
17
- : value !== null && typeof value === 'object'
18
- ? Object.fromEntries(Object.keys(value).sort().map(key => [key, canonical(value[key])])) : value;
19
- export const digest = value => sha256(JSON.stringify(canonical(value)));
20
- const fail = message => { throw new Error(message); };
21
- const requireThat = (condition, message) => { if (!condition) fail(message); };
22
- const record = value => value !== null && typeof value === 'object' && !Array.isArray(value);
23
- const id = value => typeof value === 'string' && /^[A-Za-z0-9][A-Za-z0-9._+-]{0,119}$/.test(value);
24
- const hash = value => typeof value === 'string' && /^[a-f0-9]{64}$/.test(value);
25
- const text = value => typeof value === 'string' && value.trim().length > 0 && value.length <= 256 && !/[\x00-\x1f]/.test(value);
26
- const keys = (value, required, optional = []) => record(value)
27
- && required.every(key => Object.hasOwn(value, key))
28
- && Object.keys(value).every(key => [...required, ...optional].includes(key));
29
-
30
- function requireCompleteCatalog(catalog) {
31
- requireThat(record(catalog) && catalog.schema_version === 1 && Array.isArray(catalog.processors), 'Invalid catalog.');
32
- // This projection comes from request recognition, independently of preflight's
33
- // capability projection. Regenerating a reduced inventory cannot hide a PSP.
34
- const expected = new Map(BUILTIN_REGISTRY.map(({ psp, mode = 'token' }) => [psp, mode]));
35
- const seen = new Set();
36
- for (const processor of catalog.processors) {
37
- requireThat(record(processor) && !seen.has(processor.psp) && expected.has(processor.psp)
38
- && expected.get(processor.psp) === processor.mode, 'Canonical processor membership or mode mismatch.');
39
- seen.add(processor.psp);
40
- }
41
- requireThat(seen.size === expected.size, 'The catalog omits a canonical processor.');
42
- }
43
-
44
- export function buildInventory(catalog, baseline) {
45
- requireCompleteCatalog(catalog);
46
- requireThat(baseline.evidence_level === 'documentation_only' && baseline.native_build === null
47
- && Array.isArray(baseline.documented_adapters), 'Expected a documentation-only baseline.');
48
- const documented = new Map(baseline.documented_adapters.map(adapter => [adapter.psp, adapter]));
49
- requireThat(documented.size === baseline.documented_adapters.length
50
- && [...documented.keys()].every(psp => catalog.processors.some(processor => processor.psp === psp)), 'Baseline processor drift.');
51
- return {
52
- schema_version: 1, catalog_version: catalog.catalog_version, catalog_sha256: digest(catalog),
53
- baseline_version: baseline.baseline_version, baseline_sha256: digest(baseline), native_build: null,
54
- processors: catalog.processors.map(({ psp, mode }) => ({
55
- psp, mode, documentation: documented.has(psp) ? 'documented' : 'not_documented', status: 'unknown',
56
- limitations: documented.has(psp) ? [...documented.get(psp).limitations, 'Native runtime evidence is missing.']
57
- : ['No adapter declaration was found in the pinned documentation. Native runtime evidence is missing.'],
58
- })),
59
- };
60
- }
61
-
62
- function profileClaims(catalog, profile, now) {
63
- requireThat(keys(profile, ['schema_version', 'profile_version', 'catalog_version', 'integration', 'entries'], ['processor_entries', 'expires_at'])
64
- && profile.schema_version === 1 && id(profile.profile_version)
65
- && keys(profile.integration, ['id', 'version']) && profile.integration.id === 'kernel_native'
66
- && id(profile.integration.version), 'Invalid native profile.');
67
- requireThat(profile.catalog_version === catalog.catalog_version, 'Profile catalog mismatch.');
68
- // Ask the installed classifier to validate its own contract, including dates.
69
- // Empty observations exercise profile validation without claiming a checkout.
70
- const assessment = assessCheckoutSupport({ schema_version: 1, catalog_version: catalog.catalog_version,
71
- signals: [], observation: { complete: true, truncated: false, reasons: [] } },
72
- { integration: profile.integration, profile, now });
73
- requireThat(assessment.reason_codes.every(code => ['psp_not_detected', 'checkout_flow_unidentified'].includes(code)),
74
- 'The installed classifier rejected the profile, catalog, or current time.');
75
- requireThat(Array.isArray(profile.entries) && profile.entries.length <= 256
76
- && (profile.processor_entries === undefined || (Array.isArray(profile.processor_entries) && profile.processor_entries.length <= 256)), 'Invalid profile declarations.');
77
- const claims = new Map();
78
- const add = (entry, kind) => {
79
- const isFlow = kind === 'flow';
80
- const required = isFlow ? ['flow', 'operation', 'operation_version', 'mode', 'scenario', 'status', 'limitations']
81
- : ['psp', 'mode', 'scenario', 'status', 'limitations'];
82
- requireThat(keys(entry, required) && SCENARIOS.includes(entry.scenario)
83
- && ['supported', 'unsupported'].includes(entry.status)
84
- && Array.isArray(entry.limitations) && entry.limitations.length > 0 && entry.limitations.length <= 16
85
- && entry.limitations.every(text), 'Each declaration needs a valid status, scenario, and explicit limitations.');
86
- const definition = isFlow ? catalog.flows.find(flow => flow.id === entry.flow)
87
- : catalog.processors.find(processor => processor.psp === entry.psp);
88
- requireThat(definition && definition.mode === entry.mode
89
- && (!isFlow || (definition.operation === entry.operation && definition.operation_version === entry.operation_version)), 'Unknown declaration or operation/mode mismatch.');
90
- if (entry.status === 'supported') {
91
- requireThat(definition.server_constraint !== 'unsupported' && entry.scenario !== 'subscription_renewal'
92
- && !(entry.mode === 'hosted_form' && entry.scenario !== 'one_time'), 'Shared Vault exclusion cannot be overridden.');
93
- }
94
- const key = isFlow ? `flow:${entry.flow}:${entry.operation}:${entry.operation_version}:${entry.mode}:${entry.scenario}`
95
- : `processor:${entry.psp}:${entry.mode}:${entry.scenario}`;
96
- requireThat(!claims.has(key), 'Duplicate profile declaration.');
97
- const checks = entry.status === 'supported' ? [...SUPPORTED_CHECKS] : ['native_exclusion'];
98
- if (entry.status === 'supported' && ['save_card', 'subscription_initial'].includes(entry.scenario)) {
99
- checks.push('stored_card_consent', entry.scenario === 'save_card' ? 'merchant_card_saved' : 'merchant_subscription_confirmation');
100
- }
101
- claims.set(key, checks);
102
- };
103
- profile.entries.forEach(entry => add(entry, 'flow'));
104
- (profile.processor_entries ?? []).forEach(entry => add(entry, 'processor'));
105
- requireThat(claims.size > 0, 'An empty profile is an integration draft, not a qualified release.');
106
- return claims;
107
- }
108
-
109
- async function verifyEvidence(evidence, directory) {
110
- requireThat(keys(evidence, ['path', 'sha256']) && typeof evidence.path === 'string'
111
- && evidence.path.length > 0 && evidence.path.length <= 1024 && !/[\x00-\x1f\\]/.test(evidence.path)
112
- && !isAbsolute(evidence.path) && !evidence.path.split('/').includes('..') && hash(evidence.sha256), 'Invalid evidence path or digest.');
113
- const actual = await realpath(resolve(directory, evidence.path));
114
- const inside = relative(directory, actual);
115
- requireThat(inside !== '' && inside !== '..' && !inside.startsWith(`..${sep}`) && !isAbsolute(inside), 'Evidence escapes its directory.');
116
- requireThat(sha256(await readFile(actual)) === evidence.sha256, 'Evidence digest mismatch.');
117
- }
118
-
119
- /** Validates a trusted attestation and its retained files, not the truth of a test run. */
120
- export async function verifyRelease({ catalog, profile, report, runtime, evidenceDirectory, now = new Date().toISOString() }) {
121
- requireCompleteCatalog(catalog);
122
- const claims = profileClaims(catalog, profile, now);
123
- requireThat(keys(runtime, ['version', 'artifact_sha256']) && id(runtime.version) && hash(runtime.artifact_sha256), 'Actual native build identity is required.');
124
- requireThat(keys(report, ['schema_version', 'execution', 'adapter', 'catalog_sha256', 'profile_sha256', 'harness_commit', 'reviewed_by', 'claims'])
125
- && report.schema_version === 1 && report.execution === 'kernel_native'
126
- && keys(report.adapter, ['version', 'artifact_sha256'])
127
- && typeof report.harness_commit === 'string' && /^[a-f0-9]{40}$/.test(report.harness_commit)
128
- && text(report.reviewed_by) && Array.isArray(report.claims), 'A reviewed native execution report is required.');
129
- requireThat(report.adapter.version === runtime.version && report.adapter.artifact_sha256 === runtime.artifact_sha256
130
- && profile.integration.version === runtime.version, 'Native build mismatch.');
131
- requireThat(report.catalog_sha256 === digest(catalog), 'Catalog evidence drift. Requalify this catalog.');
132
- requireThat(report.profile_sha256 === digest(profile), 'Profile evidence drift. Requalify these declarations.');
133
- requireThat(report.claims.length === claims.size, 'Evidence must cover exactly the declared claims.');
134
- const directory = await realpath(evidenceDirectory);
135
- const seen = new Set();
136
- for (const claim of report.claims) {
137
- requireThat(keys(claim, ['key', 'checks']) && claims.has(claim.key) && !seen.has(claim.key)
138
- && Array.isArray(claim.checks), 'Unknown or duplicate evidence claim.');
139
- seen.add(claim.key);
140
- const expected = claims.get(claim.key);
141
- requireThat(claim.checks.length === expected.length, 'Missing or extra native checks.');
142
- const checks = new Set();
143
- for (const check of claim.checks) {
144
- requireThat(keys(check, ['id', 'outcome', 'evidence']) && expected.includes(check.id)
145
- && !checks.has(check.id) && check.outcome === 'passed', 'Missing, failed, or duplicate native check.');
146
- checks.add(check.id);
147
- await verifyEvidence(check.evidence, directory);
148
- }
149
- }
150
- return { status: 'qualified', integration: profile.integration, profile_sha256: digest(profile) };
151
- }
152
-
153
- async function main(args) {
154
- const catalog = getCheckoutPreflightCatalog();
155
- const readJSON = async path => JSON.parse(await readFile(path, 'utf8'));
156
- if (args[0] === 'inventory' && (args.length === 1 || (args.length === 2 && args[1] === '--check'))) {
157
- const inventory = buildInventory(catalog, await readJSON(new URL('./documented-adapters.json', import.meta.url)));
158
- if (args[1] === '--check') {
159
- requireThat(digest(inventory) === digest(await readJSON(new URL('./inventory.json', import.meta.url))), 'Inventory drift. Review the catalog and documentation before updating inventory.json.');
160
- console.log('Native inventory matches the reviewed catalog and documentation. Runtime support remains unknown.');
161
- } else console.log(JSON.stringify(inventory, null, 2));
162
- return;
163
- }
164
- const flags = ['--profile', '--report', '--runtime', '--evidence-dir'];
165
- requireThat(args[0] === 'release' && args.length === 9, 'Use inventory [--check] or release --profile JSON --report JSON --runtime JSON --evidence-dir DIRECTORY.');
166
- const values = {};
167
- for (let index = 1; index < args.length; index += 2) {
168
- requireThat(flags.includes(args[index]) && !Object.hasOwn(values, args[index]) && args[index + 1], 'Invalid or duplicate release option.');
169
- values[args[index]] = args[index + 1];
170
- }
171
- const result = await verifyRelease({ catalog, profile: await readJSON(values['--profile']), report: await readJSON(values['--report']),
172
- runtime: await readJSON(values['--runtime']), evidenceDirectory: values['--evidence-dir'] });
173
- console.log(JSON.stringify(result, null, 2));
174
- }
175
-
176
- if (process.argv[1] && pathToFileURL(resolve(process.argv[1])).href === import.meta.url) {
177
- main(process.argv.slice(2)).catch(() => {
178
- // Paths/reports may contain private deployment metadata. Keep failures out of CLI logs.
179
- console.error('Native qualification failed. Check the arguments, catalog, build identity, profile, and retained evidence against README.md.');
180
- process.exitCode = 1;
181
- });
182
- }
@@ -1,11 +0,0 @@
1
- {
2
- "schema_version": 1,
3
- "profile_version": "kernel-template-1",
4
- "catalog_version": "2026-09-15.1",
5
- "integration": {
6
- "id": "kernel_native",
7
- "version": "example-native-adapter"
8
- },
9
- "entries": [],
10
- "processor_entries": []
11
- }
@@ -1,23 +0,0 @@
1
- {
2
- "signals": [
3
- {
4
- "kind": "document",
5
- "url": "https://www.mollie.com/checkout/credit-card/session/synthetic-example",
6
- "frame_id": 0,
7
- "parent_frame_id": null,
8
- "visible": true
9
- },
10
- {
11
- "kind": "script",
12
- "url": "https://js.mollie.com/v2/mollie.js",
13
- "frame_id": 0,
14
- "parent_frame_id": null,
15
- "visible": null
16
- }
17
- ],
18
- "observation": {
19
- "complete": true,
20
- "truncated": false,
21
- "reasons": []
22
- }
23
- }
@@ -1,103 +0,0 @@
1
- {
2
- "snapshot": {
3
- "schema_version": 1,
4
- "catalog_version": "2026-09-15.1",
5
- "signals": [
6
- {
7
- "rule_id": "mollie-hosted-credit-card",
8
- "kind": "document",
9
- "frame_id": 0,
10
- "parent_frame_id": null,
11
- "visible": true
12
- },
13
- {
14
- "rule_id": "mollie-components-script",
15
- "kind": "script",
16
- "frame_id": 0,
17
- "parent_frame_id": null,
18
- "visible": null
19
- },
20
- {
21
- "rule_id": "mollie-components-v2",
22
- "kind": "script",
23
- "frame_id": 0,
24
- "parent_frame_id": null,
25
- "visible": null
26
- }
27
- ],
28
- "observation": {
29
- "complete": true,
30
- "truncated": false,
31
- "reasons": []
32
- }
33
- },
34
- "result": {
35
- "schema_version": 1,
36
- "catalog_version": "2026-09-15.1",
37
- "integration": {
38
- "id": "kernel_native",
39
- "version": "example-native-adapter"
40
- },
41
- "scenario": "one_time",
42
- "scenario_defaulted": false,
43
- "psp": "mollie",
44
- "flow": "mollie.hosted_components",
45
- "mode": "token",
46
- "status": "unknown",
47
- "support_scope": null,
48
- "checkout_flow_status": "identified",
49
- "candidates": [
50
- {
51
- "psp": "mollie",
52
- "relevance": "active",
53
- "evidence": [
54
- {
55
- "rule_id": "mollie-hosted-credit-card",
56
- "kind": "document",
57
- "frame_id": 0,
58
- "parent_frame_id": null,
59
- "visible": true,
60
- "origin": "https://www.mollie.com",
61
- "path_pattern": "/checkout/credit-card/session/:session"
62
- },
63
- {
64
- "rule_id": "mollie-components-script",
65
- "kind": "script",
66
- "frame_id": 0,
67
- "parent_frame_id": null,
68
- "visible": null,
69
- "origin": "https://js.mollie.com",
70
- "path_pattern": "/v2/mollie.js"
71
- },
72
- {
73
- "rule_id": "mollie-components-v2",
74
- "kind": "script",
75
- "frame_id": 0,
76
- "parent_frame_id": null,
77
- "visible": null,
78
- "origin": "https://js.mollie.com",
79
- "path_pattern": "^/v2/mollie\\.js$"
80
- }
81
- ]
82
- }
83
- ],
84
- "reason_codes": [
85
- "integration_flow_undeclared"
86
- ],
87
- "limitations": [
88
- "The payment request must match the supported Mollie Components card-token format.",
89
- "Authentication and merchant confirmation must finish in the merchant browser.",
90
- "Merchant configuration, card eligibility and processor approval still determine whether the purchase succeeds."
91
- ],
92
- "missing_evidence": [
93
- "integration_flow_capability"
94
- ],
95
- "observation": {
96
- "complete": true,
97
- "truncated": false,
98
- "reasons": []
99
- },
100
- "scope": "preflight_hint",
101
- "merchant_confirmation_required": true
102
- }
103
- }