@hyperscale0/udl 1.0.0-beta.1 → 1.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 (179) hide show
  1. package/CHANGELOG.md +78 -25
  2. package/README.md +37 -99
  3. package/conformance/README.md +44 -41
  4. package/conformance/evolution/action-contract.expected.json +10 -0
  5. package/conformance/evolution/action-contract.live.udl +44 -0
  6. package/conformance/evolution/action-contract.next.udl +45 -0
  7. package/conformance/evolution/product-identity.expected.json +10 -0
  8. package/conformance/evolution/product-identity.live.udl +55 -0
  9. package/conformance/evolution/product-identity.next.udl +55 -0
  10. package/conformance/evolution/version-required.expected.json +10 -0
  11. package/conformance/evolution/version-required.live.udl +55 -0
  12. package/conformance/evolution/version-required.next.udl +58 -0
  13. package/conformance/invalid/action-without-transition.expected.json +10 -0
  14. package/conformance/invalid/{verb-without-transition.udl → action-without-transition.udl} +7 -2
  15. package/conformance/invalid/agent-description-too-long.expected.json +10 -0
  16. package/conformance/invalid/agent-description-too-long.udl +57 -0
  17. package/conformance/invalid/blank-title.expected.json +1 -1
  18. package/conformance/invalid/blank-title.udl +6 -2
  19. package/conformance/invalid/composition-dial-duplicate-key.expected.json +10 -0
  20. package/conformance/invalid/composition-dial-duplicate-key.udl +73 -0
  21. package/conformance/invalid/depth-budget.expected.json +1 -1
  22. package/conformance/invalid/duplicate-subject.expected.json +10 -0
  23. package/conformance/invalid/duplicate-subject.udl +230 -0
  24. package/conformance/invalid/forged-effects.expected.json +10 -0
  25. package/conformance/invalid/forged-effects.udl +76 -0
  26. package/conformance/invalid/format-version.expected.json +1 -1
  27. package/conformance/invalid/format-version.udl +6 -2
  28. package/conformance/invalid/instrument-id-not-snake-case.expected.json +10 -0
  29. package/conformance/invalid/{noun-id-not-snake-case.udl → instrument-id-not-snake-case.udl} +6 -2
  30. package/conformance/invalid/invalid-aggregate-gate-shape.expected.json +10 -0
  31. package/conformance/invalid/invalid-aggregate-gate-shape.udl +1819 -0
  32. package/conformance/invalid/invalid-check-duration.expected.json +10 -0
  33. package/conformance/invalid/invalid-check-duration.udl +219 -0
  34. package/conformance/invalid/invalid-dial-anchor.expected.json +10 -0
  35. package/conformance/invalid/invalid-dial-anchor.udl +219 -0
  36. package/conformance/invalid/invalid-exception-parent-ref.expected.json +10 -0
  37. package/conformance/invalid/invalid-exception-parent-ref.udl +2487 -0
  38. package/conformance/invalid/invalid-exposure-shape.expected.json +10 -0
  39. package/conformance/invalid/invalid-exposure-shape.udl +1819 -0
  40. package/conformance/invalid/invalid-remainder.expected.json +10 -0
  41. package/conformance/invalid/invalid-remainder.udl +220 -0
  42. package/conformance/invalid/invalid-schema-keyword.expected.json +10 -0
  43. package/conformance/invalid/invalid-schema-keyword.udl +220 -0
  44. package/conformance/invalid/invalid-utf8.expected.json +1 -1
  45. package/conformance/invalid/malformed-json.expected.json +1 -1
  46. package/conformance/invalid/missing-create-action.expected.json +10 -0
  47. package/conformance/invalid/{missing-create-verb.udl → missing-create-action.udl} +5 -2
  48. package/conformance/invalid/missing-exception-amount-field.expected.json +10 -0
  49. package/conformance/invalid/missing-exception-amount-field.udl +2487 -0
  50. package/conformance/invalid/missing-exception-contract.expected.json +14 -0
  51. package/conformance/invalid/missing-exception-contract.udl +2523 -0
  52. package/conformance/invalid/missing-exception-reason-field.expected.json +10 -0
  53. package/conformance/invalid/missing-exception-reason-field.udl +2487 -0
  54. package/conformance/invalid/not-an-object.expected.json +1 -1
  55. package/conformance/invalid/payout-reconcile-not-a-bank-debit.expected.json +10 -0
  56. package/conformance/invalid/payout-reconcile-not-a-bank-debit.udl +259 -0
  57. package/conformance/invalid/quote-freeze-set-incomplete.expected.json +10 -0
  58. package/conformance/invalid/quote-freeze-set-incomplete.udl +261 -0
  59. package/conformance/invalid/quote-named-reference-gate.expected.json +10 -0
  60. package/conformance/invalid/quote-named-reference-gate.udl +50 -0
  61. package/conformance/invalid/reconcile-named-reference-gate.expected.json +10 -0
  62. package/conformance/invalid/reconcile-named-reference-gate.udl +50 -0
  63. package/conformance/invalid/unknown-key.expected.json +1 -1
  64. package/conformance/invalid/unknown-key.udl +6 -2
  65. package/conformance/invalid/unknown-reference-gate-field.expected.json +10 -0
  66. package/conformance/invalid/unknown-reference-gate-field.udl +1819 -0
  67. package/conformance/invalid/unknown-required-field.expected.json +10 -0
  68. package/conformance/invalid/unknown-required-field.udl +220 -0
  69. package/conformance/invalid/unreachable-state.expected.json +2 -2
  70. package/conformance/invalid/unreachable-state.udl +6 -2
  71. package/conformance/invalid/wrong-exception-amount-field.expected.json +10 -0
  72. package/conformance/invalid/wrong-exception-amount-field.udl +2487 -0
  73. package/conformance/invalid/wrong-exception-reason-field.expected.json +10 -0
  74. package/conformance/invalid/wrong-exception-reason-field.udl +2487 -0
  75. package/conformance/valid/agent-description.expected.json +6 -0
  76. package/conformance/valid/agent-description.udl +66 -0
  77. package/conformance/valid/cards.expected.json +1 -0
  78. package/conformance/valid/cards.udl +843 -356
  79. package/conformance/valid/commerce-escrow.expected.json +1 -0
  80. package/conformance/valid/commerce-escrow.udl +792 -291
  81. package/conformance/valid/compiled-crowdfunding.expected.json +6 -0
  82. package/conformance/valid/compiled-crowdfunding.udl +1843 -0
  83. package/conformance/valid/compiled-watch-club.expected.json +6 -0
  84. package/conformance/valid/compiled-watch-club.udl +2486 -0
  85. package/conformance/valid/complete-contract.expected.json +6 -0
  86. package/conformance/valid/complete-contract.udl +218 -0
  87. package/conformance/valid/effect-signatures.expected.json +6 -0
  88. package/conformance/valid/effect-signatures.udl +75 -0
  89. package/conformance/valid/hand-edited.expected.json +1 -0
  90. package/conformance/valid/hand-edited.udl +1 -1
  91. package/conformance/valid/insured-car-marketplace.expected.json +1 -0
  92. package/conformance/valid/insured-car-marketplace.udl +534 -315
  93. package/conformance/valid/insured-travel.expected.json +2 -1
  94. package/conformance/valid/insured-travel.udl +1489 -641
  95. package/conformance/valid/minimal.expected.json +1 -0
  96. package/conformance/valid/minimal.udl +18 -14
  97. package/conformance/valid/protection.expected.json +1 -0
  98. package/conformance/valid/protection.udl +719 -304
  99. package/conformance/valid/string-escaping.expected.json +6 -0
  100. package/conformance/valid/string-escaping.udl +54 -0
  101. package/dist/canonical.d.ts +2 -0
  102. package/dist/canonical.d.ts.map +1 -1
  103. package/dist/canonical.js +7 -0
  104. package/dist/canonical.js.map +1 -1
  105. package/dist/check-profiles.d.ts +57 -0
  106. package/dist/check-profiles.d.ts.map +1 -0
  107. package/dist/check-profiles.js +62 -0
  108. package/dist/check-profiles.js.map +1 -0
  109. package/dist/cli.js +48 -4
  110. package/dist/cli.js.map +1 -1
  111. package/dist/diagnostics.d.ts +168 -0
  112. package/dist/diagnostics.d.ts.map +1 -0
  113. package/dist/diagnostics.js +164 -0
  114. package/dist/diagnostics.js.map +1 -0
  115. package/dist/effects.d.ts +41 -0
  116. package/dist/effects.d.ts.map +1 -0
  117. package/dist/effects.js +110 -0
  118. package/dist/effects.js.map +1 -0
  119. package/dist/evolution.d.ts +51 -18
  120. package/dist/evolution.d.ts.map +1 -1
  121. package/dist/evolution.js +244 -102
  122. package/dist/evolution.js.map +1 -1
  123. package/dist/finance.d.ts +17 -13
  124. package/dist/finance.d.ts.map +1 -1
  125. package/dist/finance.js +165 -109
  126. package/dist/finance.js.map +1 -1
  127. package/dist/index.d.ts +12 -8
  128. package/dist/index.d.ts.map +1 -1
  129. package/dist/index.js +8 -5
  130. package/dist/index.js.map +1 -1
  131. package/dist/limits.d.ts +2 -2
  132. package/dist/limits.d.ts.map +1 -1
  133. package/dist/limits.js +4 -3
  134. package/dist/limits.js.map +1 -1
  135. package/dist/parser.d.ts.map +1 -1
  136. package/dist/parser.js +6 -16
  137. package/dist/parser.js.map +1 -1
  138. package/dist/schema.d.ts +2059 -135
  139. package/dist/schema.d.ts.map +1 -1
  140. package/dist/schema.js +759 -73
  141. package/dist/schema.js.map +1 -1
  142. package/dist/validation.d.ts +22 -9
  143. package/dist/validation.d.ts.map +1 -1
  144. package/dist/validation.js +1463 -457
  145. package/dist/validation.js.map +1 -1
  146. package/docs/README.md +14 -0
  147. package/docs/guide/01-a-document.md +37 -0
  148. package/docs/guide/02-money-steps.md +23 -0
  149. package/docs/guide/03-laws.md +18 -0
  150. package/docs/guide/04-fees-and-remainder.md +15 -0
  151. package/docs/guide/05-checks-updates-dials.md +7 -0
  152. package/docs/guide/06-effects.md +11 -0
  153. package/docs/guide/07-evolution.md +11 -0
  154. package/docs/guide/08-implementing.md +13 -0
  155. package/docs/llms-full.txt +1241 -0
  156. package/docs/llms.txt +14 -0
  157. package/docs/reference/canonical.md +16 -0
  158. package/docs/reference/clauses.md +986 -0
  159. package/docs/reference/cli.md +22 -0
  160. package/docs/reference/diagnostics.md +32 -0
  161. package/package.json +6 -2
  162. package/skills/udl/SKILL.md +28 -0
  163. package/spec/README.md +82 -51
  164. package/spec/udl.schema.json +1191 -119
  165. package/src/canonical.ts +11 -0
  166. package/src/check-profiles.ts +80 -0
  167. package/src/cli.ts +49 -3
  168. package/src/diagnostics.ts +221 -0
  169. package/src/effects.ts +163 -0
  170. package/src/evolution.ts +375 -125
  171. package/src/finance.ts +255 -160
  172. package/src/index.ts +50 -14
  173. package/src/limits.ts +4 -3
  174. package/src/parser.ts +15 -18
  175. package/src/schema.ts +855 -81
  176. package/src/validation.ts +2666 -560
  177. package/conformance/invalid/missing-create-verb.expected.json +0 -10
  178. package/conformance/invalid/noun-id-not-snake-case.expected.json +0 -10
  179. package/conformance/invalid/verb-without-transition.expected.json +0 -10
@@ -0,0 +1,230 @@
1
+ {
2
+ "instruments": [
3
+ {
4
+ "actionOrder": [
5
+ "create",
6
+ "revise",
7
+ "settle"
8
+ ],
9
+ "actions": {
10
+ "create": {
11
+ "moves": [],
12
+ "steps": [],
13
+ "summary": "Open the agreement"
14
+ },
15
+ "revise": {
16
+ "examples": [
17
+ {
18
+ "input": {
19
+ "agreementId": "agr_sandbox_agreement01",
20
+ "note": "Updated terms",
21
+ "tenantId": "ten_sandbox_example001"
22
+ },
23
+ "name": "revise_terms"
24
+ }
25
+ ],
26
+ "input": {
27
+ "additionalProperties": false,
28
+ "properties": {
29
+ "note": {
30
+ "type": "string"
31
+ }
32
+ },
33
+ "required": [
34
+ "note"
35
+ ],
36
+ "type": "object"
37
+ },
38
+ "moves": [],
39
+ "principal": "user_session",
40
+ "steps": [],
41
+ "summary": "Revise the note",
42
+ "updates": [
43
+ "note"
44
+ ]
45
+ },
46
+ "settle": {
47
+ "deadline": {
48
+ "field": "closesAt"
49
+ },
50
+ "moves": [
51
+ {
52
+ "bind": {
53
+ "amount": {
54
+ "from": "instance",
55
+ "path": "refs.remainingAmount"
56
+ },
57
+ "currency": {
58
+ "from": "instance",
59
+ "path": "fields.currency"
60
+ },
61
+ "destinationAccountId": {
62
+ "from": "instance",
63
+ "path": "fields.destinationAccountId"
64
+ },
65
+ "sourceAccountId": {
66
+ "from": "instance",
67
+ "path": "fields.sourceAccountId"
68
+ }
69
+ },
70
+ "key": "settlement",
71
+ "operation": "internal_transfer.create"
72
+ }
73
+ ],
74
+ "remainder": {
75
+ "amountRef": "remainingAmount",
76
+ "onZero": "refuse",
77
+ "totalPath": "fields.amount"
78
+ },
79
+ "requiresChecks": [
80
+ {
81
+ "checkKind": "identity_verification",
82
+ "family": "national_identity",
83
+ "maxAge": "P30D",
84
+ "statuses": [
85
+ "completed"
86
+ ],
87
+ "subjectField": "subjectId"
88
+ }
89
+ ],
90
+ "sandboxFailurePoint": "release",
91
+ "steps": [],
92
+ "summary": "Settle the agreement"
93
+ }
94
+ },
95
+ "callerParkedStates": {
96
+ "open": "The owner may revise or settle the agreement."
97
+ },
98
+ "dials": [
99
+ {
100
+ "field": "closesAt",
101
+ "key": "settlement_window",
102
+ "kind": "window",
103
+ "maxOffset": "P30D",
104
+ "minOffset": "PT0S",
105
+ "summary": "The settlement deadline offset.",
106
+ "title": "Settlement window"
107
+ }
108
+ ],
109
+ "fields": {
110
+ "amount": {
111
+ "pattern": "^[1-9][0-9]{0,17}$",
112
+ "type": "string"
113
+ },
114
+ "closesAt": {
115
+ "format": "hyperscale-date-time",
116
+ "type": "string"
117
+ },
118
+ "currency": {
119
+ "pattern": "^[A-Z]{3}$",
120
+ "type": "string"
121
+ },
122
+ "destinationAccountId": {
123
+ "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
124
+ "type": "string"
125
+ },
126
+ "note": {
127
+ "type": "string"
128
+ },
129
+ "sourceAccountId": {
130
+ "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
131
+ "type": "string"
132
+ },
133
+ "subjectId": {
134
+ "type": "string"
135
+ }
136
+ },
137
+ "id": "agreement",
138
+ "idPrefix": "agr",
139
+ "lifecycle": {
140
+ "initial": "open",
141
+ "states": [
142
+ "open",
143
+ "closed"
144
+ ],
145
+ "transitions": {
146
+ "revise": {
147
+ "from": [
148
+ "open"
149
+ ],
150
+ "to": "open"
151
+ },
152
+ "settle": {
153
+ "from": [
154
+ "open"
155
+ ],
156
+ "to": "closed"
157
+ }
158
+ }
159
+ },
160
+ "nav": [
161
+ "Agreements"
162
+ ],
163
+ "required": [
164
+ "amount",
165
+ "closesAt",
166
+ "currency",
167
+ "destinationAccountId",
168
+ "sourceAccountId",
169
+ "subjectId"
170
+ ],
171
+ "subject": {
172
+ "extensible": false,
173
+ "kinds": [
174
+ "asset"
175
+ ]
176
+ },
177
+ "summary": "One agreement with a computed final settlement.",
178
+ "surfaceVisibility": "public",
179
+ "templateId": "agreement",
180
+ "title": "Agreement",
181
+ "update": {
182
+ "examples": [
183
+ {
184
+ "input": {
185
+ "agreementId": "agr_sandbox_agreement01",
186
+ "note": "Updated terms",
187
+ "tenantId": "ten_sandbox_example001"
188
+ },
189
+ "name": "revise_terms"
190
+ }
191
+ ],
192
+ "fields": [
193
+ "note"
194
+ ],
195
+ "states": [
196
+ "open"
197
+ ]
198
+ }
199
+ }
200
+ ],
201
+ "product": "complete_contract",
202
+ "subjects": [
203
+ {
204
+ "declaredValue": "none",
205
+ "kind": "asset",
206
+ "schema": {
207
+ "additionalProperties": false,
208
+ "properties": {},
209
+ "type": "object"
210
+ },
211
+ "title": "Asset",
212
+ "version": 1
213
+ },
214
+ {
215
+ "declaredValue": "none",
216
+ "kind": "asset",
217
+ "schema": {
218
+ "additionalProperties": false,
219
+ "properties": {},
220
+ "type": "object"
221
+ },
222
+ "title": "Asset",
223
+ "version": 1
224
+ }
225
+ ],
226
+ "title": "Complete contract",
227
+ "udl": 1,
228
+ "version": 1
229
+ }
230
+
@@ -0,0 +1,10 @@
1
+ {
2
+ "issues": [
3
+ {
4
+ "code": "UDL2005",
5
+ "path": "$.instruments[0].actions.close.effects.decides"
6
+ }
7
+ ],
8
+ "summary": "Authored effects must equal the rows derived from clauses.",
9
+ "verdict": "invalid"
10
+ }
@@ -0,0 +1,76 @@
1
+ {
2
+ "instruments": [
3
+ {
4
+ "actionOrder": [
5
+ "create",
6
+ "close"
7
+ ],
8
+ "actions": {
9
+ "close": {
10
+ "decision": {
11
+ "capability": "identity_verification",
12
+ "deadlineMs": 15000,
13
+ "onTimeout": "decline"
14
+ },
15
+ "effects": {
16
+ "decides": [
17
+ {
18
+ "signature": "decides.forged",
19
+ "source": "decision"
20
+ }
21
+ ],
22
+ "notifies": [
23
+ {
24
+ "channel": "email",
25
+ "role": "beneficiary",
26
+ "signature": "notifies.email",
27
+ "source": "effects.notifies[0]"
28
+ }
29
+ ]
30
+ },
31
+ "moves": [],
32
+ "steps": [],
33
+ "summary": "Close the note."
34
+ },
35
+ "create": {
36
+ "moves": [],
37
+ "steps": [],
38
+ "summary": "File the note."
39
+ }
40
+ },
41
+ "fields": {
42
+ "reference": {
43
+ "type": "string"
44
+ }
45
+ },
46
+ "id": "note",
47
+ "idPrefix": "note",
48
+ "lifecycle": {
49
+ "initial": "open",
50
+ "states": [
51
+ "open",
52
+ "closed"
53
+ ],
54
+ "transitions": {
55
+ "close": {
56
+ "from": [
57
+ "open"
58
+ ],
59
+ "to": "closed"
60
+ }
61
+ }
62
+ },
63
+ "required": [
64
+ "reference"
65
+ ],
66
+ "summary": "A note a tenant files and later closes.",
67
+ "title": "Note"
68
+ }
69
+ ],
70
+ "product": "minimal",
71
+ "subjects": [],
72
+ "title": "Minimal",
73
+ "udl": 1,
74
+ "version": 1
75
+ }
76
+
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "issues": [
3
3
  {
4
- "code": "invalid_shape",
4
+ "code": "UDL1003",
5
5
  "path": "$.udl"
6
6
  }
7
7
  ],
@@ -1,5 +1,5 @@
1
1
  {
2
- "nouns": [
2
+ "instruments": [
3
3
  {
4
4
  "fields": {
5
5
  "reference": {
@@ -28,7 +28,11 @@
28
28
  ],
29
29
  "summary": "A note a tenant files and later closes.",
30
30
  "title": "Note",
31
- "verbs": {
31
+ "actionOrder": [
32
+ "close",
33
+ "create"
34
+ ],
35
+ "actions": {
32
36
  "close": {
33
37
  "moves": [],
34
38
  "steps": [],
@@ -0,0 +1,10 @@
1
+ {
2
+ "issues": [
3
+ {
4
+ "code": "UDL1003",
5
+ "path": "$.instruments[0].id"
6
+ }
7
+ ],
8
+ "summary": "Naming law: instrument ids are snake_case, singular, plain business English.",
9
+ "verdict": "invalid"
10
+ }
@@ -1,5 +1,5 @@
1
1
  {
2
- "nouns": [
2
+ "instruments": [
3
3
  {
4
4
  "fields": {
5
5
  "reference": {
@@ -28,7 +28,11 @@
28
28
  ],
29
29
  "summary": "A note a tenant files and later closes.",
30
30
  "title": "Note",
31
- "verbs": {
31
+ "actionOrder": [
32
+ "close",
33
+ "create"
34
+ ],
35
+ "actions": {
32
36
  "close": {
33
37
  "moves": [],
34
38
  "steps": [],
@@ -0,0 +1,10 @@
1
+ {
2
+ "issues": [
3
+ {
4
+ "code": "UDL5004",
5
+ "path": "$.instruments[1].actions.complete.requiresAggregate[0].instrumentId"
6
+ }
7
+ ],
8
+ "summary": "Refuses Invalid input: expected string, received number.",
9
+ "verdict": "invalid"
10
+ }