@hyperscale0/adl 1.0.0-alpha.2 → 1.0.0-beta.10

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 (43) hide show
  1. package/CHANGELOG.md +46 -2
  2. package/LICENSE.md +356 -0
  3. package/NOTICE.md +8 -0
  4. package/README.md +29 -140
  5. package/conformance/cases.json +50 -764
  6. package/conformance/subject-adapter.ts +31 -0
  7. package/dist/boundary-fixture.d.ts +24 -0
  8. package/dist/boundary-fixture.d.ts.map +1 -0
  9. package/dist/boundary-fixture.js +34 -0
  10. package/dist/boundary-fixture.js.map +1 -0
  11. package/dist/index.d.ts +68 -156
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +100 -77
  14. package/dist/index.js.map +1 -1
  15. package/dist/vocabulary.d.ts +3 -57
  16. package/dist/vocabulary.d.ts.map +1 -1
  17. package/dist/vocabulary.js +12 -84
  18. package/dist/vocabulary.js.map +1 -1
  19. package/docs/assets/adl.svg +11 -0
  20. package/docs/assets/brand/adl-horizontal-white.svg +1 -0
  21. package/docs/assets/brand/adl-horizontal.svg +1 -0
  22. package/docs/assets/brand/adl-stacked-white.svg +1 -0
  23. package/docs/assets/brand/adl-stacked.svg +1 -0
  24. package/docs/assets/brand/manifest.json +30 -0
  25. package/docs/authoring-guide.md +37 -416
  26. package/package.json +17 -12
  27. package/spec/manifest.schema.json +646 -439
  28. package/LICENSE +0 -661
  29. package/LICENSING.md +0 -51
  30. package/TRADEMARKS.md +0 -30
  31. package/dist/conformance.d.ts +0 -41
  32. package/dist/conformance.d.ts.map +0 -1
  33. package/dist/conformance.js +0 -486
  34. package/dist/conformance.js.map +0 -1
  35. package/examples/meridian-bank/README.md +0 -65
  36. package/examples/meridian-bank/example.spec.ts +0 -162
  37. package/examples/meridian-bank/fixtures/payout-status-replay.json +0 -19
  38. package/examples/meridian-bank/fixtures/payout-status-settled.json +0 -19
  39. package/examples/meridian-bank/fixtures/payout-submit-accepted.json +0 -26
  40. package/examples/meridian-bank/fixtures/payout-submit-declined.json +0 -25
  41. package/examples/meridian-bank/fixtures/statement-camt053.json +0 -45
  42. package/examples/meridian-bank/fixtures/webhook-payout-settled.json +0 -11
  43. package/examples/meridian-bank/index.ts +0 -262
@@ -1,431 +1,52 @@
1
1
  # Writing a provider adapter in ADL
2
2
 
3
- This is the whole job, in the order you do it. Everything here is checkable:
4
- each rule names the symbol that enforces it, and `examples/meridian-bank` is a
5
- complete adapter you can copy.
3
+ `ProviderAdapter` declares an adapter's identity, operation bindings and subject
4
+ requirements. `BoundaryAdapter` implements dispatch and observation. The runtime
5
+ owns instruction identity and money accounts.
6
6
 
7
- ## What an adapter is
7
+ ## Declare the binding
8
8
 
9
- An adapter is a **declaration**, not a client. It is a plain object saying
10
- what the provider does: which commands exist, how their responses classify,
11
- what the bank's status tokens mean, when statements can be fetched, which
12
- reference comes back on a debit. The runtime that executes it is generic and
13
- ships with the platform. Your adapter never opens a socket, never holds a
14
- credential, and never decides what a payment means.
9
+ Use `createProviderAdapterRegistry` to validate declarations. Each operation map
10
+ key must equal its binding's `operation`. Its `resourceKind` must appear in
11
+ `bindings`. Subject requirements describe required authored fields or attachments;
12
+ they never supply an account or choose a party.
15
13
 
16
- That split is why the checks in ADL are declaration-level. Conformance
17
- does not call your bank. It proves the facts you declared are complete enough
18
- for a generic runtime to poll, classify, reconcile, and dedupe **without
19
- guessing**, because every guess a runtime makes about money is a bug you find
20
- in production.
14
+ The [generic fixture](../src/boundary-fixture.ts) declares one boundary
15
+ observation operation with no subject requirements. The
16
+ [subject fixture](../conformance/subject-adapter.ts) shows required subject fields.
21
17
 
22
- Two consequences worth internalizing before you write a line:
18
+ `adapterConformanceFindings` checks the declaration. The
19
+ [manifest schema](../spec/manifest.schema.json) expresses the same public shape
20
+ for non-TypeScript authors. Neither check contacts a provider.
23
21
 
24
- - **A fact you have not established is declared absent, never borrowed.** The
25
- fields that may be omitted (`charges`, `statementDebitReference`, `envelope`)
26
- exist so you can be honest during authoring. Conformance then refuses to
27
- certify while they are open. Absent is a finding; a wrong value is an
28
- outage.
29
- - **Poll-first.** A provider callback is a hint that a poll is due, never a
30
- fact to post from. `validatePartnerBankProfile` refuses a profile whose
31
- `notificationMechanisms` omits `poll`, whatever else it lists.
22
+ ## Dispatch an instruction
32
23
 
33
- ### Adapter Symmetry
24
+ `BoundaryInstruction` binds an immutable ID to the environment, tenant, Product,
25
+ retained Build, target, source and destination accounts, positive minor-unit
26
+ amount, currency and adapter. The runtime reserves the amount before dispatch.
27
+ An adapter receives that instruction unchanged.
34
28
 
35
- Hyperscale's own bank adapters are written against this package and nothing
36
- more. There is no private adapter API, no internal hook, no second interface
37
- for first-party code. When a first-party adapter needs a seam ADL lacks,
38
- the seam is added here, in public, or it is not added.
29
+ `BoundaryAdapter.dispatch` and `BoundaryAdapter.observe` return a
30
+ `BoundaryObservation` or `undefined`. The observation names the adapter,
31
+ instruction ID, stable external reference, explicit outcome and observation time.
32
+ Its outcome is `acknowledged`, `unknown`, `confirmed` or `rejected`.
39
33
 
40
- Practically: if the example in `examples/meridian-bank` can express your bank,
41
- so can we, and if it cannot, that is a gap in ADL worth an issue.
34
+ An acknowledgement or missing result leaves the reservation held. HTTP status
35
+ never supplies a terminal outcome. Only a matching `confirmed` observation can
36
+ authorize posting; an explicit `rejected` observation can authorize voiding.
37
+ The runtime records immutable observations and consumes settlement evidence once.
38
+ Recovery completes the same ledger intent without resending uncertain work.
42
39
 
43
- ## The four gates
40
+ ## Check the declaration
44
41
 
45
- An adapter passes through four gates. Know which one owns which failure, or
46
- you will fix the wrong thing.
42
+ From this package:
47
43
 
48
- | Gate | Symbol | Catches |
49
- | --------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
50
- | Type check | `ProviderAdapter<Vocabulary>` | Names outside your closed vocabulary, wrong shapes, missing required fields. |
51
- | Registry load | `createProviderAdapterRegistry` | Cross-field structure at import time: key drift, blank locators, an unreadable clock, a duplicate identity. Throws. |
52
- | Conformance | `partnerBankConformanceFindings`, `certifyPartnerBankAdapter` | Operational completeness. Returns findings, or throws with all of them listed. |
53
- | Manifest schema | `spec/manifest.schema.json` | The same structure for authors who are not writing TypeScript. |
54
-
55
- `conformance/cases.json` records, for every rule, which gates see it. Read it
56
- when you want the exact division of labor.
57
-
58
- ## 1. Declare your vocabulary
59
-
60
- Start by naming the closed unions your product uses. `ProviderAdapterVocabulary`
61
- is nine string fields, and you narrow every one of them:
62
-
63
- ```ts
64
- import type { ProviderAdapterVocabulary } from "@hyperscale0/adl";
65
-
66
- interface MeridianVocabulary extends ProviderAdapterVocabulary {
67
- readonly capability: "payout_execution" | "bank_credit";
68
- readonly domain: "payouts" | "deposits";
69
- readonly meter: "external_payout";
70
- readonly obligation: "payout_submission" | "bank_credit";
71
- readonly operation: "payout.submit" | "deposit.record";
72
- readonly resource: "payout" | "deposit";
73
- readonly webhookOperation: "payout.complete";
74
- readonly webhookResource: "payout";
75
- readonly webhookResourceId: "payoutId";
76
- }
77
- ```
78
-
79
- The names come from the published operation catalog for the product you are
80
- integrating with, not from your provider's documentation. Your provider calls
81
- it `POST /v2/payments`; the platform calls it `payout.submit`. Translating
82
- between the two is the adapter's whole reason to exist.
83
-
84
- Then bind the vocabulary once and keep the returned function:
85
-
86
- ```ts
87
- const defineMeridianAdapters =
88
- createProviderAdapterRegistry<MeridianVocabulary>();
89
- ```
90
-
91
- `createProviderAdapterRegistry` returns a validator that preserves your exact
92
- literal types (`const Adapters extends readonly ProviderAdapter<Vocabulary>[]`),
93
- so downstream code sees the operations you actually declared, not `string`.
94
-
95
- ## 2. Declare the operations
96
-
97
- `operationMap` is keyed by operation name, and the key must equal the binding's
98
- `operation` field. Drift throws at load:
99
- `operationMap key submit must match operation payout.submit`.
100
-
101
- Each `ProviderOperationBinding` carries:
102
-
103
- | Field | Contract |
104
- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
105
- | `operation` | The platform operation this binding serves. Equal to its map key. |
106
- | `direction` | `tenant_initiated` when the runtime sends the provider a command and reads an answer. `system_settlement` when the operation records something observation already saw. This single field decides which rules apply below. |
107
- | `obligationKind` | Which obligation the operation discharges. Your product's vocabulary. |
108
- | `resourceKind` | The platform resource the provider's answer commits onto. Must appear in `bindings`. |
109
- | `resourceIdPath` | Where the resource id is read from. Non-blank, checked at load. |
110
- | `meter` | Optional. The usage meter this operation feeds. |
111
- | `envelope` | How **this** operation's response carries its outcome. Required on a live command, see below. |
112
- | `statusEnquiry` | The authoritative read-after-write. Required on a REST command, see below. |
113
-
114
- ### The envelope class, per operation
115
-
116
- `ProviderResponseEnvelope` has three inhabitants:
117
-
118
- - `http_200_body_status` -- every response is HTTP 200 and the outcome is a
119
- status token in the body. A rejection arrives inside a success.
120
- - `http_status_error_body` -- the HTTP status carries the outcome and a failure
121
- body is prose.
122
- - `unconfirmed_until_live` -- the provider publishes no error sample, so the
123
- class is honestly unknown.
124
-
125
- Declare it **per operation**, never per provider. Real providers answer in more
126
- than one shape across their own endpoints, and inheriting a class from a
127
- sibling endpoint is how a rejection gets read as a success.
128
-
129
- Conformance requires the class on any binding where the runtime sends a command
130
- and reads an answer, meaning `direction: "tenant_initiated"` on an `egress` of
131
- `rest` or `sync_clearance`. Missing it is `response_envelope_unclassified`; a
132
- declared `unconfirmed_until_live` is `response_envelope_unconfirmed`, because
133
- certification is the licence to serve live and the class must be established
134
- first. A `system_settlement` binding carries no response of its own, so it owes
135
- no envelope, and declaring one there would be a borrowed fact.
136
-
137
- ### Status enquiry, the read-after-write
138
-
139
- A REST command's response can be lost after the provider has already acted on
140
- it. Without an authoritative way to re-read the outcome, the runtime's only
141
- options are guessing and resubmitting, and resubmitting pays twice.
142
-
143
- ```ts
144
- statusEnquiry: {
145
- keys: "provider_reference",
146
- pathTemplate: "/v2/payments/{providerReference}",
147
- }
148
- ```
149
-
150
- `keys` says which reference the enquiry is keyed by, and the template must
151
- contain the matching placeholder, checked at load:
152
- `{instructionId}` for `instruction_id`, `{providerReference}` for
153
- `provider_reference`.
154
-
155
- Presence is a readiness commitment, not a hint. Runtimes must never infer
156
- enquiry support from a command URL, so:
157
-
158
- - a `tenant_initiated` binding on `egress: "rest"` without one is
159
- `status_enquiry_missing`;
160
- - an enquiry declared on an adapter whose `egress` is not `rest` is
161
- `status_enquiry_without_rest_egress`, because there is no transport to run it;
162
- - `sync_clearance` is exempt: the answer arrives in the same exchange.
163
-
164
- ### Egress and direction have to agree
165
-
166
- `ProviderEgressMode` is how this adapter reaches the provider at all:
167
-
168
- - `none` -- the capability is learned entirely by observation;
169
- - `rest` -- per-command HTTP;
170
- - `batch_reconcile` -- files, reconciled after the fact;
171
- - `sync_clearance` -- one synchronous exchange that carries its own truth.
172
-
173
- A `tenant_initiated` binding on `none` or `batch_reconcile` promises an
174
- outbound call the egress mode cannot make: `egress_direction_incoherent`.
175
-
176
- ## 3. Declare the webhook plans
177
-
178
- `webhookMap` is keyed by event kind, and the key must equal `eventKind` (load
179
- throws on drift, same as operations). A `ProviderWebhookTransitionPlan` says
180
- what a callback must contain before the runtime will treat it as a reason to
181
- poll: `requiredPayloadFields`, `optionalPayloadFields`,
182
- `requiredFieldGroups` (each inner array is a set where at least one member is
183
- required), `resourceIdField`, `resourceKind`, and `timestampField` from the
184
- `ProviderTimestampField` vocabulary.
185
-
186
- An adapter with no callbacks declares `webhookMap: {}`. That is complete, not
187
- missing: polling is the fact.
188
-
189
- ## 4. Declare the bindings
190
-
191
- `bindings` maps each resource kind this adapter settles to a
192
- `ProviderResourceBinding`:
193
-
194
- - `strict` -- the provider's fact must match the platform's row exactly;
195
- - `claim` -- the provider's fact claims an existing row;
196
- - `confirmation_only` -- the provider only confirms what the platform already
197
- decided;
198
- - `evidence_only` -- the fact is recorded as evidence, and settles nothing.
199
-
200
- Every `resourceKind` named by an operation binding or a webhook plan needs an
201
- entry, or conformance reports `resource_binding_missing`: a provider fact with
202
- no declared match mode has no lawful way to commit.
203
-
204
- ## 5. Declare the config
205
-
206
- ```ts
207
- config: {
208
- baseUrl: "https://api.meridian-bank.example/v2",
209
- credentialRef: { source: "environment", name: "MERIDIAN_BANK_CREDENTIALS" },
210
- }
211
- ```
212
-
213
- `ProviderCredentialReference` is a **locator**: an environment variable name,
214
- or a keychain service and account. There is no field a secret can be written
215
- into, and `validateConfig` refuses a blank locator or a relative `baseUrl`.
216
- Never put a token, certificate, or password in an adapter. The declaration is
217
- committed to a repository; the credential is not.
218
-
219
- ## 6. Declare the partner-bank profile
220
-
221
- `PartnerBankAdapterProfile` is the bank as fact. It is the longest part of the
222
- job and the part that repays care, because every field is something a runtime
223
- would otherwise guess.
224
-
225
- ### Auth and wire
226
-
227
- `wireCodec` (`rest_json`, `iso20022_xml`, `swift_mt`) and `auth`
228
- (`ProviderAuthEnvelope` plus a signing scheme). Declaring a grant the bank will
229
- not accept fails on the first live call, so read the bank's token service, do
230
- not assume client credentials.
231
-
232
- ### The idempotency spine
233
-
234
- ```ts
235
- idempotencySpine: {
236
- dedupeKeys: ["instructionId", "paymentReference"],
237
- instructionId: { maxLength: 32 },
238
- endToEndId: { maxLength: 32 },
239
- paymentReference: { maxLength: 20 },
240
- }
44
+ ```sh
45
+ bun run conformance -- ./src/boundary-fixture.ts
46
+ bun run spec:emit
241
47
  ```
242
48
 
243
- `dedupeKeys` names which references the bank grades a duplicate against. It
244
- must be non-empty and free of duplicates (both checked at load). The three
245
- length facts are what stops the runtime minting a reference the bank will
246
- truncate, which is how two payments end up sharing an identity.
247
-
248
- ### The lifecycle vocabulary
249
-
250
- The bank's own status spellings, mapped onto canonical states:
251
-
252
- ```ts
253
- lifecycleVocabulary: {
254
- QUEUED: "received",
255
- AUTHORISED: "accepted",
256
- SETTLED: "processed",
257
- DECLINED: "failed",
258
- RECALLED: "returned",
259
- REPLAY_SETTLED: "duplicate_original_succeeded",
260
- REPLAY_DECLINED: "duplicate_original_rejected",
261
- }
262
- ```
263
-
264
- Runtimes match after trimming and upper-casing, so `ok`, `OK ` and `OK` are one
265
- entry. Four rules apply:
266
-
267
- - the vocabulary must spell `processed`, `failed`, and `returned`, or a payment
268
- ending there is unclassifiable and polls forever
269
- (`lifecycle_terminals_incomplete`);
270
- - it must spell `received` or `accepted`, because an acknowledgement proves the
271
- bank took the instruction, never that money moved
272
- (`lifecycle_intake_missing`);
273
- - a spelling that trims to nothing can never match (`lifecycle_spelling_blank`);
274
- - two spellings that normalize to the same token must agree on the canonical
275
- state, or classification becomes order-dependent
276
- (`lifecycle_spelling_conflict`).
277
-
278
- And the one authors forget: both duplicate verdicts must be spellable
279
- (`duplicate_verdicts_unmapped`). The dedupe spine means a crash-recovery
280
- resubmission comes back graded against the original's outcome. Unclassified,
281
- your own recovery reads as a fresh failure.
282
-
283
- ### Statements
284
-
285
- `statementFormats` lists what the bank can hand you (`mt940`, `mt942`,
286
- `camt_052`, `camt_053`, `obie_json`), and `windows.statements` gives each one a
287
- fetch window:
288
-
289
- - `availability: "T-1"` pages over history, so it needs positive `lookbackDays`
290
- and `statementDaysPerRequest`;
291
- - `availability: "today_only"` is intraday and owes no paging facts.
292
-
293
- A declared format with no window is `statement_window_missing`; a T-1 window
294
- without paging facts is `statement_window_incomplete`. No formats at all is
295
- `statement_formats_empty`: statements are bank truth, and reconciliation has
296
- nothing to prove the ledger against without one.
297
-
298
- `statementDebitReference` says which of the two references on a debit line
299
- names the instruction behind it: the bank's own entry reference
300
- (`bank_reference`) or the reference you sent (`customer_reference`). Banks
301
- disagree, and the wrong choice makes every payout you instructed look like an
302
- unexplained debit. Leaving it unestablished is
303
- `statement_debit_reference_unestablished`.
304
-
305
- ### Charges
306
-
307
- ```ts
308
- charges: {
309
- narratives: { charge: ["MERIDIAN FEE"], vat: ["MERIDIAN TAX"] },
310
- posting: "post_hoc",
311
- vat: "separate_line",
312
- }
313
- ```
314
-
315
- `posting` says whether the bank debits its fee separately after the payment or
316
- nets it out of the instructed amount; `vat` says whether tax arrives as its own
317
- line. Post-hoc charges and separate VAT lines are bank-initiated debits
318
- recognizable only by their wording, so each mode in play needs at least one
319
- narrative prefix (`charge_narrative_unestablished`,
320
- `vat_narrative_unestablished`). Omitting `charges` entirely is honest during
321
- authoring and refused at certification (`charges_unestablished`): the bank's own
322
- debits would land as unexplained statement lines.
323
-
324
- ### Windows
325
-
326
- ```ts
327
- paymentCutoff: {
328
- time: "16:30",
329
- timeZone: "Europe/Dublin",
330
- beforeCutoffValueDate: "D+0",
331
- afterCutoffValueDate: "D+1",
332
- }
333
- ```
334
-
335
- The cutoff is read on the **bank's** clock, so `timeZone` is an IANA name and
336
- both gates resolve it through `Intl.DateTimeFormat`. Absence is not tolerated:
337
- an undefined zone silently means the host's clock
338
- (`cutoff_clock_invalid`).
339
-
340
- Value dates are `D+<whole days>`. Missing a cutoff can only push value later,
341
- so an after-cutoff date earlier than the before-cutoff one is a
342
- `cutoff_window_regression`, and so is a `valueDateMaxDaysAhead` that cannot
343
- reach the after-cutoff date. A malformed offset is
344
- `value_date_offset_invalid` rather than a NaN that slides through every
345
- comparison after it.
346
-
347
- ### The rest
348
-
349
- `executedReadBack` (whether the executed read-back may name another rail, and
350
- when an FX rate is final), `limitFacts` (what the bank exposes about limits),
351
- `financialAddressProvisioning` (how virtual addresses are issued, priced, and
352
- quota'd), and `notificationMechanisms` (which must include `poll`).
353
-
354
- ## 7. Run conformance
355
-
356
- ```bash
357
- bun run conformance -- ./examples/meridian-bank
358
- ```
359
-
360
- ```
361
- ok meridian_bank:payout_execution
362
- ok meridian_bank:bank_credit
363
- 2 adapter(s) checked, 0 finding(s) reported
364
- ```
365
-
366
- The runner exits 1 when anything reports, so it drops straight into CI. It
367
- takes a module path or a directory, and certifies every adapter the module
368
- exports.
369
-
370
- In your own repository, call the function directly and skip the runner:
371
-
372
- ```ts
373
- import { certifyPartnerBankAdapter } from "@hyperscale0/adl";
374
-
375
- import { myAdapters } from "./src/index.js";
376
-
377
- for (const adapter of myAdapters) certifyPartnerBankAdapter(adapter);
378
- ```
379
-
380
- `partnerBankConformanceFindings` returns every finding as
381
- `{ code, path, message }`, where `path` is the dotted location inside your
382
- declaration. `certifyPartnerBankAdapter` throws with all of them listed at
383
- once, so you fix a declaration in one pass rather than one throw at a time.
384
- The codes are append-only: a released code is never renamed or removed, so you
385
- can switch on `PartnerBankConformanceCode` without a stale fallback arm.
386
-
387
- An empty result is the certification. Nothing else is.
388
-
389
- ## 8. Write the manifest without TypeScript
390
-
391
- `spec/manifest.schema.json` is JSON Schema 2020-12 for one adapter
392
- declaration, generated from `src/vocabulary.ts` by `scripts/emit-spec.ts` and
393
- drift-checked by `bun run spec:check`. Generate types, validate a
394
- hand-written manifest, or feed it to an editor.
395
-
396
- The schema is structural. Rules that compare two fields, resolve a time zone,
397
- or match a property key against a value inside it cannot be expressed in JSON
398
- Schema and stay in the validator and the conformance suite.
399
- `conformance/cases.json` says which gate owns each rule, in the `note` field of
400
- every case where they differ.
401
-
402
- ## 9. Hand it over
403
-
404
- An adapter is handed over as source, never as a running service:
405
-
406
- 1. `bun run conformance` reports zero findings.
407
- 2. Your own tests read captured provider bytes and prove the declaration
408
- matches them. `examples/meridian-bank/example.spec.ts` is the pattern:
409
- every status token in a fixture is spelled in the lifecycle vocabulary, the
410
- envelope class is how the fixtures actually read, and the declared charge
411
- narratives match the statement lines.
412
- 3. Open an issue on this repository with the certified declaration and the
413
- conformance output. Credentials are never part of a submission; the
414
- declaration names locators, and the operator fills them in.
415
-
416
- ## Stability
417
-
418
- The package is `1.0.0-alpha.1` and the surface can still change on a minor
419
- version until it is `1.0.0`. Two promises hold from now:
420
-
421
- - conformance codes are append-only;
422
- - a value removed from a vocabulary in `src/vocabulary.ts` is a breaking change
423
- and appears in `CHANGELOG.md`.
424
-
425
- ## What is not here
426
-
427
- The declaration carries no timeouts, no retry policy, and no rate limits.
428
- Those belong to the runtime that executes adapters, not to the facts about the
429
- provider, and no field in `ProviderAdapter` accepts them. If your provider's
430
- limits are a fact the runtime must know, open an issue: under Adapter Symmetry
431
- the seam gets added here, publicly, or not at all.
49
+ The conformance command exits 1 when it reports a finding. The schema emitter
50
+ writes the declaration schema and the `BoundaryInstruction` and
51
+ `BoundaryObservation` definitions. Add a case in `conformance/cases.json` when a
52
+ new declaration rule prevents a concrete failure.
package/package.json CHANGED
@@ -1,14 +1,12 @@
1
1
  {
2
2
  "name": "@hyperscale0/adl",
3
- "version": "1.0.0-alpha.2",
4
- "description": "The Adapter Declaration Language: provider adapter interfaces, registry validation, and the partner-bank conformance suite.",
3
+ "version": "1.0.0-beta.10",
4
+ "description": "The Adapter Declaration Language: generic evidence, provider declarations and conformance.",
5
5
  "keywords": [
6
6
  "adl",
7
7
  "adapter",
8
- "banking",
9
8
  "conformance",
10
9
  "fintech",
11
- "iso20022",
12
10
  "json-schema",
13
11
  "payments",
14
12
  "provider"
@@ -21,7 +19,7 @@
21
19
  "type": "git",
22
20
  "url": "git+https://github.com/hyperscale0/hyperscale-adl.git"
23
21
  },
24
- "license": "AGPL-3.0-only",
22
+ "license": "SEE LICENSE IN LICENSE.md",
25
23
  "type": "module",
26
24
  "sideEffects": false,
27
25
  "main": "./dist/index.js",
@@ -32,21 +30,23 @@
32
30
  "types": "./dist/index.d.ts",
33
31
  "default": "./dist/index.js"
34
32
  },
33
+ "./boundary-fixture": {
34
+ "types": "./dist/boundary-fixture.d.ts",
35
+ "default": "./dist/boundary-fixture.js"
36
+ },
35
37
  "./spec/manifest.schema.json": "./spec/manifest.schema.json",
36
38
  "./package.json": "./package.json"
37
39
  },
38
40
  "files": [
41
+ "LICENSE.md",
42
+ "NOTICE.md",
39
43
  "AUTHORS",
40
44
  "CHANGELOG.md",
41
- "LICENSE",
42
- "LICENSING.md",
43
45
  "README.md",
44
46
  "SECURITY.md",
45
- "TRADEMARKS.md",
46
47
  "conformance",
47
48
  "dist",
48
49
  "docs",
49
- "examples",
50
50
  "spec"
51
51
  ],
52
52
  "engines": {
@@ -66,14 +66,19 @@
66
66
  "test": "bun test",
67
67
  "typecheck": "tsc -p tsconfig.json"
68
68
  },
69
+ "dependencies": {
70
+ "@hyperscale0/udl": "4.7.0",
71
+ "zod": "4.6.5"
72
+ },
69
73
  "devDependencies": {
70
- "@types/bun": "1.4.0",
71
- "typescript": "6.0.3"
74
+ "bun-types": "1.4.2",
75
+ "typescript": "7.0.2"
72
76
  },
73
77
  "author": "Hyperscale LLC",
74
78
  "contributors": [
75
79
  "Meshael AlBakaawi",
76
80
  "Amir Ayub",
77
81
  "Sara AlBakaawi"
78
- ]
82
+ ],
83
+ "gitHead": "a238da0dbb6ed4e454852cf7f8dbdf1015520d18"
79
84
  }