@hyperscale0/hsx 1.0.0-beta.1 → 1.0.0-rc.1

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 (234) hide show
  1. package/CHANGELOG.md +41 -9
  2. package/LICENSING.md +3 -3
  3. package/README.md +37 -149
  4. package/TRADEMARKS.md +4 -4
  5. package/dist/src/ast.d.ts +129 -10
  6. package/dist/src/ast.d.ts.map +1 -1
  7. package/dist/src/cli.d.ts +2 -1
  8. package/dist/src/cli.d.ts.map +1 -1
  9. package/dist/src/cli.js +148 -12
  10. package/dist/src/cli.js.map +1 -1
  11. package/dist/src/compile.d.ts +41 -4
  12. package/dist/src/compile.d.ts.map +1 -1
  13. package/dist/src/compile.js +82 -15
  14. package/dist/src/compile.js.map +1 -1
  15. package/dist/src/cost.d.ts +78 -0
  16. package/dist/src/cost.d.ts.map +1 -0
  17. package/dist/src/cost.js +369 -0
  18. package/dist/src/cost.js.map +1 -0
  19. package/dist/src/diagnostics.d.ts +11 -0
  20. package/dist/src/diagnostics.d.ts.map +1 -0
  21. package/dist/src/diagnostics.js +420 -0
  22. package/dist/src/diagnostics.js.map +1 -0
  23. package/dist/src/emit.d.ts +35 -0
  24. package/dist/src/emit.d.ts.map +1 -0
  25. package/dist/src/emit.js +359 -0
  26. package/dist/src/emit.js.map +1 -0
  27. package/dist/src/entry-overrides.d.ts +17 -3
  28. package/dist/src/entry-overrides.d.ts.map +1 -1
  29. package/dist/src/entry-overrides.js +180 -35
  30. package/dist/src/entry-overrides.js.map +1 -1
  31. package/dist/src/format.d.ts +10 -0
  32. package/dist/src/format.d.ts.map +1 -0
  33. package/dist/src/format.js +183 -0
  34. package/dist/src/format.js.map +1 -0
  35. package/dist/src/index.d.ts +10 -4
  36. package/dist/src/index.d.ts.map +1 -1
  37. package/dist/src/index.js +8 -3
  38. package/dist/src/index.js.map +1 -1
  39. package/dist/src/ir.d.ts +66 -0
  40. package/dist/src/ir.d.ts.map +1 -0
  41. package/dist/src/ir.js +15 -0
  42. package/dist/src/ir.js.map +1 -0
  43. package/dist/src/lex.d.ts +9 -1
  44. package/dist/src/lex.d.ts.map +1 -1
  45. package/dist/src/lex.js +50 -4
  46. package/dist/src/lex.js.map +1 -1
  47. package/dist/src/limits.d.ts +2 -3
  48. package/dist/src/limits.d.ts.map +1 -1
  49. package/dist/src/limits.js +2 -3
  50. package/dist/src/limits.js.map +1 -1
  51. package/dist/src/modules.d.ts +36 -0
  52. package/dist/src/modules.d.ts.map +1 -0
  53. package/dist/src/modules.js +372 -0
  54. package/dist/src/modules.js.map +1 -0
  55. package/dist/src/parse.d.ts.map +1 -1
  56. package/dist/src/parse.js +590 -17
  57. package/dist/src/parse.js.map +1 -1
  58. package/dist/src/typecheck.d.ts +8 -0
  59. package/dist/src/typecheck.d.ts.map +1 -0
  60. package/dist/src/typecheck.js +2958 -0
  61. package/dist/src/typecheck.js.map +1 -0
  62. package/dist/src/version.d.ts +4 -15
  63. package/dist/src/version.d.ts.map +1 -1
  64. package/dist/src/version.js +4 -15
  65. package/dist/src/version.js.map +1 -1
  66. package/docs/README.md +23 -0
  67. package/docs/guide/01-first-program.md +24 -0
  68. package/docs/guide/02-money.md +25 -0
  69. package/docs/guide/03-instruments.md +22 -0
  70. package/docs/guide/04-lifecycles.md +25 -0
  71. package/docs/guide/05-fees-and-splits.md +45 -0
  72. package/docs/guide/06-schedules.md +22 -0
  73. package/docs/guide/07-composition.md +46 -0
  74. package/docs/guide/08-writing-a-module.md +26 -0
  75. package/docs/guide/09-cost.md +24 -0
  76. package/docs/guide/10-diagnostics.md +27 -0
  77. package/docs/llms-full.txt +1738 -0
  78. package/docs/llms.txt +45 -0
  79. package/docs/reference/cli.md +33 -0
  80. package/docs/reference/diagnostics.md +619 -0
  81. package/docs/reference/grammar.md +39 -0
  82. package/docs/reference/std/advance.md +35 -0
  83. package/docs/reference/std/cancellable_booking.md +35 -0
  84. package/docs/reference/std/captured_payment.md +43 -0
  85. package/docs/reference/std/conditional_disbursement.md +33 -0
  86. package/docs/reference/std/credit_facility.md +35 -0
  87. package/docs/reference/std/held_payment.md +64 -0
  88. package/docs/reference/std/instant_transfer.md +30 -0
  89. package/docs/reference/std/metered.md +27 -0
  90. package/docs/reference/std/pooled_split.md +26 -0
  91. package/docs/reference/std/premium_forward.md +39 -0
  92. package/docs/reference/std/reconciled_payout.md +33 -0
  93. package/docs/reference/std/recurring_collection.md +25 -0
  94. package/docs/reference/std/rotating_pool.md +42 -0
  95. package/docs/reference/std/scheduled.md +51 -0
  96. package/docs/reference/std/security_deposit.md +46 -0
  97. package/docs/reference/std/settlement_batch.md +42 -0
  98. package/docs/reference/std/swap.md +46 -0
  99. package/docs/reference/std/threshold_pool.md +47 -0
  100. package/docs/reference/std/weighted_distribution.md +39 -0
  101. package/docs/reference/types.md +20 -0
  102. package/docs/reference/udl-output.md +14 -0
  103. package/docs/sessions/2026-09-02-two-instruments.hsx +21 -0
  104. package/docs/sessions/2026-09-02-two-instruments.md +41 -0
  105. package/examples/01-first-program/README.md +45 -0
  106. package/examples/01-first-program/tip-jar.hsx +17 -0
  107. package/examples/02-imports-and-archetypes/README.md +99 -0
  108. package/examples/02-imports-and-archetypes/photo-booth.hsx +37 -0
  109. package/examples/03-diagnostics/README.md +68 -0
  110. package/examples/03-diagnostics/corner-shop-fixed.hsx +22 -0
  111. package/examples/03-diagnostics/corner-shop.hsx +19 -0
  112. package/examples/04-complete-product/README.md +87 -0
  113. package/examples/04-complete-product/study-hall.hsx +67 -0
  114. package/examples/05-watch-club/README.md +9 -0
  115. package/examples/05-watch-club/watch-club.hsx +124 -0
  116. package/examples/README.md +18 -0
  117. package/examples/advance/README.md +3 -0
  118. package/examples/advance/advance.hsx +13 -0
  119. package/examples/advance/advance.udl +339 -0
  120. package/examples/cancellable_booking/README.md +3 -0
  121. package/examples/cancellable_booking/cancellable_booking.hsx +14 -0
  122. package/examples/cancellable_booking/cancellable_booking.udl +391 -0
  123. package/examples/captured_payment/README.md +3 -0
  124. package/examples/captured_payment/captured_payment.hsx +21 -0
  125. package/examples/captured_payment/captured_payment.udl +677 -0
  126. package/examples/conditional_disbursement/README.md +3 -0
  127. package/examples/conditional_disbursement/conditional_disbursement.hsx +17 -0
  128. package/examples/conditional_disbursement/conditional_disbursement.udl +412 -0
  129. package/examples/cost-table.json +386 -0
  130. package/examples/credit_facility/README.md +3 -0
  131. package/examples/credit_facility/credit_facility.hsx +27 -0
  132. package/examples/credit_facility/credit_facility.udl +1373 -0
  133. package/examples/held_payment/README.md +3 -0
  134. package/examples/held_payment/held_payment.hsx +13 -0
  135. package/examples/held_payment/held_payment.udl +507 -0
  136. package/examples/instant_transfer/README.md +3 -0
  137. package/examples/instant_transfer/instant_transfer.hsx +16 -0
  138. package/examples/instant_transfer/instant_transfer.udl +364 -0
  139. package/examples/metered/README.md +3 -0
  140. package/examples/metered/metered.hsx +13 -0
  141. package/examples/metered/metered.udl +247 -0
  142. package/examples/pooled_split/README.md +3 -0
  143. package/examples/pooled_split/pooled_split.hsx +15 -0
  144. package/examples/pooled_split/pooled_split.udl +425 -0
  145. package/examples/premium_forward/README.md +3 -0
  146. package/examples/premium_forward/premium_forward.hsx +19 -0
  147. package/examples/premium_forward/premium_forward.udl +594 -0
  148. package/examples/reconciled_payout/README.md +3 -0
  149. package/examples/reconciled_payout/reconciled_payout.hsx +13 -0
  150. package/examples/reconciled_payout/reconciled_payout.udl +303 -0
  151. package/examples/recurring_collection/README.md +3 -0
  152. package/examples/recurring_collection/recurring_collection.hsx +21 -0
  153. package/examples/recurring_collection/recurring_collection.udl +1130 -0
  154. package/examples/rotating_pool/README.md +3 -0
  155. package/examples/rotating_pool/rotating_pool.hsx +18 -0
  156. package/examples/rotating_pool/rotating_pool.udl +4352 -0
  157. package/examples/scheduled/README.md +3 -0
  158. package/examples/scheduled/scheduled.hsx +12 -0
  159. package/examples/scheduled/scheduled.udl +335 -0
  160. package/examples/security_deposit/README.md +3 -0
  161. package/examples/security_deposit/security_deposit.hsx +21 -0
  162. package/examples/security_deposit/security_deposit.udl +293 -0
  163. package/examples/settlement_batch/README.md +3 -0
  164. package/examples/settlement_batch/settlement_batch.hsx +19 -0
  165. package/examples/settlement_batch/settlement_batch.udl +753 -0
  166. package/examples/swap/README.md +3 -0
  167. package/examples/swap/swap.hsx +19 -0
  168. package/examples/swap/swap.udl +876 -0
  169. package/examples/threshold_pool/README.md +3 -0
  170. package/examples/threshold_pool/threshold_pool.hsx +16 -0
  171. package/examples/threshold_pool/threshold_pool.udl +667 -0
  172. package/examples/weighted_distribution/README.md +3 -0
  173. package/examples/weighted_distribution/weighted_distribution.hsx +20 -0
  174. package/examples/weighted_distribution/weighted_distribution.udl +337 -0
  175. package/package.json +19 -6
  176. package/skills/hsx/SKILL.md +483 -0
  177. package/src/ast.ts +163 -9
  178. package/src/cli.ts +164 -12
  179. package/src/compile.ts +160 -20
  180. package/src/cost.ts +579 -0
  181. package/src/diagnostics.ts +442 -0
  182. package/src/emit.ts +447 -0
  183. package/src/entry-overrides.ts +263 -48
  184. package/src/format.ts +261 -0
  185. package/src/index.ts +32 -4
  186. package/src/ir.ts +99 -0
  187. package/src/lex.ts +59 -4
  188. package/src/limits.ts +2 -3
  189. package/src/modules.ts +444 -0
  190. package/src/parse.ts +655 -21
  191. package/src/typecheck.ts +3876 -0
  192. package/src/version.ts +4 -16
  193. package/std/SEMANTICS.md +130 -0
  194. package/std/settlements/advance.hsx +177 -0
  195. package/std/settlements/cancellable_booking.hsx +87 -0
  196. package/std/settlements/captured_payment.hsx +144 -0
  197. package/std/settlements/conditional_disbursement.hsx +185 -0
  198. package/std/settlements/credit_facility.hsx +167 -0
  199. package/std/settlements/held_payment.hsx +578 -0
  200. package/std/settlements/index.hsx +3 -0
  201. package/std/settlements/instant_transfer.hsx +190 -0
  202. package/std/settlements/metered.hsx +67 -0
  203. package/std/settlements/pooled_split.hsx +68 -0
  204. package/std/settlements/premium_forward.hsx +257 -0
  205. package/std/settlements/reconciled_payout.hsx +77 -0
  206. package/std/settlements/recurring_collection.hsx +27 -0
  207. package/std/settlements/rotating_pool.hsx +252 -0
  208. package/std/settlements/scheduled.hsx +641 -0
  209. package/std/settlements/security_deposit.hsx +166 -0
  210. package/std/settlements/settlement_batch.hsx +122 -0
  211. package/std/settlements/swap.hsx +1114 -0
  212. package/std/settlements/threshold_pool.hsx +221 -0
  213. package/std/settlements/weighted_distribution.hsx +141 -0
  214. package/dist/src/archetypes.d.ts +0 -17
  215. package/dist/src/archetypes.d.ts.map +0 -1
  216. package/dist/src/archetypes.js +0 -327
  217. package/dist/src/archetypes.js.map +0 -1
  218. package/dist/src/check.d.ts +0 -12
  219. package/dist/src/check.d.ts.map +0 -1
  220. package/dist/src/check.js +0 -1910
  221. package/dist/src/check.js.map +0 -1
  222. package/dist/src/lower.d.ts +0 -146
  223. package/dist/src/lower.d.ts.map +0 -1
  224. package/dist/src/lower.js +0 -4570
  225. package/dist/src/lower.js.map +0 -1
  226. package/dist/src/model.d.ts +0 -467
  227. package/dist/src/model.d.ts.map +0 -1
  228. package/dist/src/model.js +0 -15
  229. package/dist/src/model.js.map +0 -1
  230. package/spec/hsx-ir.schema.json +0 -920
  231. package/src/archetypes.ts +0 -340
  232. package/src/check.ts +0 -2938
  233. package/src/lower.ts +0 -5416
  234. package/src/model.ts +0 -519
@@ -0,0 +1,876 @@
1
+ {
2
+ "instruments": [
3
+ {
4
+ "actionOrder": [
5
+ "abandon",
6
+ "cancel",
7
+ "create",
8
+ "dispute",
9
+ "fund",
10
+ "post",
11
+ "release"
12
+ ],
13
+ "actions": {
14
+ "abandon": {
15
+ "agentDescription": "Walk away from a trade that never funded. Only a created trade abandons, and its escrow account must hold nothing, so there is nothing to refund. No money moves.",
16
+ "moves": [],
17
+ "publicAction": "abandonExchange",
18
+ "requiresDrainedAccount": {
19
+ "path": "refs.escrowAccountId"
20
+ },
21
+ "steps": [],
22
+ "summary": "Abandon the trade before its atomic funding batch"
23
+ },
24
+ "cancel": {
25
+ "agentDescription": "Unwind a funded trade before release. Both principals return from escrow to their own sides in one batch. The trade must be funded and not yet released. The service fees taken at funding stay with the platform.",
26
+ "effects": {
27
+ "moves": [
28
+ {
29
+ "signature": "moves.transfer.internal",
30
+ "source": "moves[0]"
31
+ },
32
+ {
33
+ "signature": "moves.transfer.internal",
34
+ "source": "moves[1]"
35
+ }
36
+ ]
37
+ },
38
+ "moves": [
39
+ {
40
+ "bind": {
41
+ "amount": {
42
+ "from": "instance",
43
+ "path": "fields.buyerAmount"
44
+ },
45
+ "currency": {
46
+ "from": "instance",
47
+ "path": "fields.currency"
48
+ },
49
+ "destinationAccountId": {
50
+ "from": "instance",
51
+ "path": "fields.buyerAccountId"
52
+ },
53
+ "metadata.instrumentId": {
54
+ "from": "const",
55
+ "value": "exchange"
56
+ },
57
+ "metadata.instrumentInstanceId": {
58
+ "from": "instance",
59
+ "path": "instrumentInstanceId"
60
+ },
61
+ "metadata.phase": {
62
+ "from": "const",
63
+ "value": "cancel"
64
+ },
65
+ "productId": {
66
+ "from": "instance",
67
+ "path": "productId"
68
+ },
69
+ "sourceAccountId": {
70
+ "from": "instance",
71
+ "path": "refs.escrowAccountId"
72
+ }
73
+ },
74
+ "capture": {
75
+ "cancelSideARefundTransferId": "transferId"
76
+ },
77
+ "key": "side_a_refund",
78
+ "operation": "internal_transfer.create"
79
+ },
80
+ {
81
+ "bind": {
82
+ "amount": {
83
+ "from": "instance",
84
+ "path": "fields.sellerAmount"
85
+ },
86
+ "currency": {
87
+ "from": "instance",
88
+ "path": "fields.currency"
89
+ },
90
+ "destinationAccountId": {
91
+ "from": "instance",
92
+ "path": "fields.sellerAccountId"
93
+ },
94
+ "metadata.instrumentId": {
95
+ "from": "const",
96
+ "value": "exchange"
97
+ },
98
+ "metadata.instrumentInstanceId": {
99
+ "from": "instance",
100
+ "path": "instrumentInstanceId"
101
+ },
102
+ "metadata.phase": {
103
+ "from": "const",
104
+ "value": "cancel"
105
+ },
106
+ "productId": {
107
+ "from": "instance",
108
+ "path": "productId"
109
+ },
110
+ "sourceAccountId": {
111
+ "from": "instance",
112
+ "path": "refs.escrowAccountId"
113
+ }
114
+ },
115
+ "capture": {
116
+ "cancelSideBRefundTransferId": "transferId"
117
+ },
118
+ "key": "side_b_refund",
119
+ "operation": "internal_transfer.create"
120
+ }
121
+ ],
122
+ "publicAction": "cancelExchange",
123
+ "steps": [],
124
+ "summary": "Cancel and return both trade principals atomically"
125
+ },
126
+ "create": {
127
+ "agentDescription": "Open a trade and provision its escrow account. No money moves. Both principals and both exact service fees are fixed here and cannot change afterwards.",
128
+ "moves": [],
129
+ "publicAction": "createExchange",
130
+ "steps": [
131
+ {
132
+ "bind": {
133
+ "currency": {
134
+ "from": "instance",
135
+ "path": "fields.currency"
136
+ },
137
+ "owner.id": {
138
+ "from": "instance",
139
+ "path": "productId"
140
+ },
141
+ "owner.type": {
142
+ "from": "const",
143
+ "value": "product"
144
+ },
145
+ "productId": {
146
+ "from": "instance",
147
+ "path": "productId"
148
+ },
149
+ "role": {
150
+ "from": "const",
151
+ "value": "product_escrow"
152
+ }
153
+ },
154
+ "capture": {
155
+ "escrowAccountId": "accountId"
156
+ },
157
+ "operation": "account.escrow.provision"
158
+ }
159
+ ],
160
+ "summary": "Create a exchange atomic trade"
161
+ },
162
+ "dispute": {
163
+ "agentDescription": "Claw back a released trade inside its dispute window. Both cross-payment reservations void and both principals return from escrow in one batch. The trade must be released and the clawback moment must not have passed. Either trading party may call it.",
164
+ "deadline": {
165
+ "field": "clawbackAt"
166
+ },
167
+ "effects": {
168
+ "decides": [
169
+ {
170
+ "signature": "decides.tenant_port",
171
+ "source": "port"
172
+ }
173
+ ],
174
+ "moves": [
175
+ {
176
+ "signature": "moves.transfer.internal",
177
+ "source": "moves[0]"
178
+ },
179
+ {
180
+ "signature": "moves.transfer.internal",
181
+ "source": "moves[1]"
182
+ },
183
+ {
184
+ "signature": "moves.transfer.internal",
185
+ "source": "moves[2]"
186
+ },
187
+ {
188
+ "signature": "moves.transfer.internal",
189
+ "source": "moves[3]"
190
+ }
191
+ ],
192
+ "schedules": [
193
+ {
194
+ "signature": "schedules.deadline",
195
+ "source": "deadline"
196
+ }
197
+ ]
198
+ },
199
+ "moves": [
200
+ {
201
+ "bind": {
202
+ "reason": {
203
+ "from": "const",
204
+ "value": "Whole trade disputed inside the clawback window"
205
+ },
206
+ "transferId": {
207
+ "from": "instance",
208
+ "path": "refs.releaseSideATransferId"
209
+ }
210
+ },
211
+ "key": "side_a_void",
212
+ "operation": "internal_transfer.void"
213
+ },
214
+ {
215
+ "bind": {
216
+ "reason": {
217
+ "from": "const",
218
+ "value": "Whole trade disputed inside the clawback window"
219
+ },
220
+ "transferId": {
221
+ "from": "instance",
222
+ "path": "refs.releaseSideBTransferId"
223
+ }
224
+ },
225
+ "key": "side_b_void",
226
+ "operation": "internal_transfer.void"
227
+ },
228
+ {
229
+ "bind": {
230
+ "amount": {
231
+ "from": "instance",
232
+ "path": "fields.buyerAmount"
233
+ },
234
+ "currency": {
235
+ "from": "instance",
236
+ "path": "fields.currency"
237
+ },
238
+ "destinationAccountId": {
239
+ "from": "instance",
240
+ "path": "fields.buyerAccountId"
241
+ },
242
+ "metadata.clawbackOfTransferId": {
243
+ "from": "instance",
244
+ "path": "refs.releaseSideATransferId"
245
+ },
246
+ "metadata.instrumentId": {
247
+ "from": "const",
248
+ "value": "exchange"
249
+ },
250
+ "metadata.instrumentInstanceId": {
251
+ "from": "instance",
252
+ "path": "instrumentInstanceId"
253
+ },
254
+ "metadata.phase": {
255
+ "from": "const",
256
+ "value": "dispute"
257
+ },
258
+ "productId": {
259
+ "from": "instance",
260
+ "path": "productId"
261
+ },
262
+ "sourceAccountId": {
263
+ "from": "instance",
264
+ "path": "refs.escrowAccountId"
265
+ }
266
+ },
267
+ "capture": {
268
+ "disputeSideARefundTransferId": "transferId"
269
+ },
270
+ "key": "side_a_refund",
271
+ "operation": "internal_transfer.create"
272
+ },
273
+ {
274
+ "bind": {
275
+ "amount": {
276
+ "from": "instance",
277
+ "path": "fields.sellerAmount"
278
+ },
279
+ "currency": {
280
+ "from": "instance",
281
+ "path": "fields.currency"
282
+ },
283
+ "destinationAccountId": {
284
+ "from": "instance",
285
+ "path": "fields.sellerAccountId"
286
+ },
287
+ "metadata.clawbackOfTransferId": {
288
+ "from": "instance",
289
+ "path": "refs.releaseSideBTransferId"
290
+ },
291
+ "metadata.instrumentId": {
292
+ "from": "const",
293
+ "value": "exchange"
294
+ },
295
+ "metadata.instrumentInstanceId": {
296
+ "from": "instance",
297
+ "path": "instrumentInstanceId"
298
+ },
299
+ "metadata.phase": {
300
+ "from": "const",
301
+ "value": "dispute"
302
+ },
303
+ "productId": {
304
+ "from": "instance",
305
+ "path": "productId"
306
+ },
307
+ "sourceAccountId": {
308
+ "from": "instance",
309
+ "path": "refs.escrowAccountId"
310
+ }
311
+ },
312
+ "capture": {
313
+ "disputeSideBRefundTransferId": "transferId"
314
+ },
315
+ "key": "side_b_refund",
316
+ "operation": "internal_transfer.create"
317
+ }
318
+ ],
319
+ "port": {
320
+ "allowedParties": [
321
+ "payer",
322
+ "beneficiary"
323
+ ]
324
+ },
325
+ "publicAction": "disputeExchange",
326
+ "steps": [],
327
+ "summary": "Void both reservations, then refund both principals atomically"
328
+ },
329
+ "fund": {
330
+ "agentDescription": "Fund both sides at once. Each side pays its principal into escrow and its service fee to the platform account, four transfers in one batch. The trade must be created and unfunded. This moves real money from both parties.",
331
+ "effects": {
332
+ "moves": [
333
+ {
334
+ "signature": "moves.collection.pay_in",
335
+ "source": "moves[0]"
336
+ },
337
+ {
338
+ "signature": "moves.collection.pay_in",
339
+ "source": "moves[1]"
340
+ },
341
+ {
342
+ "signature": "moves.transfer.internal",
343
+ "source": "moves[2]"
344
+ },
345
+ {
346
+ "signature": "moves.transfer.internal",
347
+ "source": "moves[3]"
348
+ }
349
+ ]
350
+ },
351
+ "moves": [
352
+ {
353
+ "bind": {
354
+ "amount": {
355
+ "from": "instance",
356
+ "path": "fields.buyerAmount"
357
+ },
358
+ "currency": {
359
+ "from": "instance",
360
+ "path": "fields.currency"
361
+ },
362
+ "destinationAccountId": {
363
+ "from": "instance",
364
+ "path": "refs.escrowAccountId"
365
+ },
366
+ "metadata.instrumentId": {
367
+ "from": "const",
368
+ "value": "exchange"
369
+ },
370
+ "metadata.instrumentInstanceId": {
371
+ "from": "instance",
372
+ "path": "instrumentInstanceId"
373
+ },
374
+ "metadata.phase": {
375
+ "from": "const",
376
+ "value": "fund"
377
+ },
378
+ "productId": {
379
+ "from": "instance",
380
+ "path": "productId"
381
+ },
382
+ "sourceAccountId": {
383
+ "from": "instance",
384
+ "path": "fields.buyerAccountId"
385
+ }
386
+ },
387
+ "capture": {
388
+ "fundSideAPrincipalTransferId": "transferId"
389
+ },
390
+ "key": "side_a_principal",
391
+ "operation": "internal_transfer.create"
392
+ },
393
+ {
394
+ "bind": {
395
+ "amount": {
396
+ "from": "instance",
397
+ "path": "fields.sellerAmount"
398
+ },
399
+ "currency": {
400
+ "from": "instance",
401
+ "path": "fields.currency"
402
+ },
403
+ "destinationAccountId": {
404
+ "from": "instance",
405
+ "path": "refs.escrowAccountId"
406
+ },
407
+ "metadata.instrumentId": {
408
+ "from": "const",
409
+ "value": "exchange"
410
+ },
411
+ "metadata.instrumentInstanceId": {
412
+ "from": "instance",
413
+ "path": "instrumentInstanceId"
414
+ },
415
+ "metadata.phase": {
416
+ "from": "const",
417
+ "value": "fund"
418
+ },
419
+ "productId": {
420
+ "from": "instance",
421
+ "path": "productId"
422
+ },
423
+ "sourceAccountId": {
424
+ "from": "instance",
425
+ "path": "fields.sellerAccountId"
426
+ }
427
+ },
428
+ "capture": {
429
+ "fundSideBPrincipalTransferId": "transferId"
430
+ },
431
+ "key": "side_b_principal",
432
+ "operation": "internal_transfer.create"
433
+ },
434
+ {
435
+ "bind": {
436
+ "amount": {
437
+ "from": "instance",
438
+ "path": "fields.buyerFee"
439
+ },
440
+ "currency": {
441
+ "from": "instance",
442
+ "path": "fields.currency"
443
+ },
444
+ "destinationAccountId": {
445
+ "from": "instance",
446
+ "path": "fields.platformAccountId"
447
+ },
448
+ "metadata.instrumentId": {
449
+ "from": "const",
450
+ "value": "exchange"
451
+ },
452
+ "metadata.instrumentInstanceId": {
453
+ "from": "instance",
454
+ "path": "instrumentInstanceId"
455
+ },
456
+ "metadata.phase": {
457
+ "from": "const",
458
+ "value": "fund"
459
+ },
460
+ "productId": {
461
+ "from": "instance",
462
+ "path": "productId"
463
+ },
464
+ "sourceAccountId": {
465
+ "from": "instance",
466
+ "path": "fields.buyerAccountId"
467
+ }
468
+ },
469
+ "capture": {
470
+ "fundSideAServiceFeeTransferId": "transferId"
471
+ },
472
+ "key": "side_a_service_fee",
473
+ "operation": "internal_transfer.create"
474
+ },
475
+ {
476
+ "bind": {
477
+ "amount": {
478
+ "from": "instance",
479
+ "path": "fields.sellerFee"
480
+ },
481
+ "currency": {
482
+ "from": "instance",
483
+ "path": "fields.currency"
484
+ },
485
+ "destinationAccountId": {
486
+ "from": "instance",
487
+ "path": "fields.platformAccountId"
488
+ },
489
+ "metadata.instrumentId": {
490
+ "from": "const",
491
+ "value": "exchange"
492
+ },
493
+ "metadata.instrumentInstanceId": {
494
+ "from": "instance",
495
+ "path": "instrumentInstanceId"
496
+ },
497
+ "metadata.phase": {
498
+ "from": "const",
499
+ "value": "fund"
500
+ },
501
+ "productId": {
502
+ "from": "instance",
503
+ "path": "productId"
504
+ },
505
+ "sourceAccountId": {
506
+ "from": "instance",
507
+ "path": "fields.sellerAccountId"
508
+ }
509
+ },
510
+ "capture": {
511
+ "fundSideBServiceFeeTransferId": "transferId"
512
+ },
513
+ "key": "side_b_service_fee",
514
+ "operation": "internal_transfer.create"
515
+ }
516
+ ],
517
+ "publicAction": "fundExchange",
518
+ "steps": [],
519
+ "summary": "Fund both trade sides and collect on-top fees atomically"
520
+ },
521
+ "post": {
522
+ "due": {
523
+ "field": "clawbackAt"
524
+ },
525
+ "effects": {
526
+ "moves": [
527
+ {
528
+ "signature": "moves.transfer.internal",
529
+ "source": "moves[0]"
530
+ },
531
+ {
532
+ "signature": "moves.transfer.internal",
533
+ "source": "moves[1]"
534
+ }
535
+ ],
536
+ "schedules": [
537
+ {
538
+ "signature": "schedules.due",
539
+ "source": "due"
540
+ }
541
+ ]
542
+ },
543
+ "moves": [
544
+ {
545
+ "bind": {
546
+ "transferId": {
547
+ "from": "instance",
548
+ "path": "refs.releaseSideATransferId"
549
+ }
550
+ },
551
+ "key": "side_a",
552
+ "operation": "internal_transfer.post"
553
+ },
554
+ {
555
+ "bind": {
556
+ "transferId": {
557
+ "from": "instance",
558
+ "path": "refs.releaseSideBTransferId"
559
+ }
560
+ },
561
+ "key": "side_b",
562
+ "operation": "internal_transfer.post"
563
+ }
564
+ ],
565
+ "steps": [],
566
+ "summary": "Post both trade reservations when the clawback window matures"
567
+ },
568
+ "release": {
569
+ "agentDescription": "Reserve each side's principal for the other side and start the dispute window. The trade must be funded. Money is reserved, not settled. It posts on its own when the window matures, and dispute unwinds it before then. Either trading party may call it.",
570
+ "effects": {
571
+ "decides": [
572
+ {
573
+ "signature": "decides.tenant_port",
574
+ "source": "port"
575
+ }
576
+ ],
577
+ "holds": [
578
+ {
579
+ "signature": "holds.reserve",
580
+ "source": "moves[0]"
581
+ },
582
+ {
583
+ "signature": "holds.reserve",
584
+ "source": "moves[1]"
585
+ }
586
+ ],
587
+ "moves": [
588
+ {
589
+ "signature": "moves.transfer.internal",
590
+ "source": "moves[0]"
591
+ },
592
+ {
593
+ "signature": "moves.transfer.internal",
594
+ "source": "moves[1]"
595
+ }
596
+ ]
597
+ },
598
+ "moves": [
599
+ {
600
+ "bind": {
601
+ "amount": {
602
+ "from": "instance",
603
+ "path": "fields.buyerAmount"
604
+ },
605
+ "currency": {
606
+ "from": "instance",
607
+ "path": "fields.currency"
608
+ },
609
+ "destinationAccountId": {
610
+ "from": "instance",
611
+ "path": "fields.sellerAccountId"
612
+ },
613
+ "metadata.clawbackAt": {
614
+ "from": "instance",
615
+ "path": "fields.clawbackAt"
616
+ },
617
+ "metadata.instrumentId": {
618
+ "from": "const",
619
+ "value": "exchange"
620
+ },
621
+ "metadata.instrumentInstanceId": {
622
+ "from": "instance",
623
+ "path": "instrumentInstanceId"
624
+ },
625
+ "metadata.phase": {
626
+ "from": "const",
627
+ "value": "release"
628
+ },
629
+ "productId": {
630
+ "from": "instance",
631
+ "path": "productId"
632
+ },
633
+ "sourceAccountId": {
634
+ "from": "instance",
635
+ "path": "refs.escrowAccountId"
636
+ }
637
+ },
638
+ "capture": {
639
+ "releaseSideATransferId": "transferId"
640
+ },
641
+ "key": "side_a",
642
+ "operation": "internal_transfer.reserve"
643
+ },
644
+ {
645
+ "bind": {
646
+ "amount": {
647
+ "from": "instance",
648
+ "path": "fields.sellerAmount"
649
+ },
650
+ "currency": {
651
+ "from": "instance",
652
+ "path": "fields.currency"
653
+ },
654
+ "destinationAccountId": {
655
+ "from": "instance",
656
+ "path": "fields.buyerAccountId"
657
+ },
658
+ "metadata.clawbackAt": {
659
+ "from": "instance",
660
+ "path": "fields.clawbackAt"
661
+ },
662
+ "metadata.instrumentId": {
663
+ "from": "const",
664
+ "value": "exchange"
665
+ },
666
+ "metadata.instrumentInstanceId": {
667
+ "from": "instance",
668
+ "path": "instrumentInstanceId"
669
+ },
670
+ "metadata.phase": {
671
+ "from": "const",
672
+ "value": "release"
673
+ },
674
+ "productId": {
675
+ "from": "instance",
676
+ "path": "productId"
677
+ },
678
+ "sourceAccountId": {
679
+ "from": "instance",
680
+ "path": "refs.escrowAccountId"
681
+ }
682
+ },
683
+ "capture": {
684
+ "releaseSideBTransferId": "transferId"
685
+ },
686
+ "key": "side_b",
687
+ "operation": "internal_transfer.reserve"
688
+ }
689
+ ],
690
+ "port": {
691
+ "allowedParties": [
692
+ "payer",
693
+ "beneficiary"
694
+ ]
695
+ },
696
+ "publicAction": "releaseExchange",
697
+ "setsAt": {
698
+ "field": "clawbackAt",
699
+ "offset": "P7D"
700
+ },
701
+ "steps": [],
702
+ "summary": "Reserve both cross-payments for the whole-trade clawback window"
703
+ }
704
+ },
705
+ "agentDescription": "Reach for swap when two named parties pay each other in one atomic trade and neither leg may settle alone. Both principals fund one escrow together, both cross-payments reserve together, and one dispute unwinds both. A single payer paying a single payee is instant transfer instead.",
706
+ "description": "Atomic swap between buyer and seller; half-funded and half-released states do not exist",
707
+ "distinctParties": true,
708
+ "feeRules": [
709
+ {
710
+ "amountField": "buyerFee",
711
+ "baseField": "buyerAmount",
712
+ "bearerField": "buyerAccountId",
713
+ "position": "on_top",
714
+ "rule": {
715
+ "currencyField": "currency",
716
+ "field": "buyerFee",
717
+ "kind": "exact"
718
+ }
719
+ },
720
+ {
721
+ "amountField": "sellerFee",
722
+ "baseField": "sellerAmount",
723
+ "bearerField": "sellerAccountId",
724
+ "position": "on_top",
725
+ "rule": {
726
+ "currencyField": "currency",
727
+ "field": "sellerFee",
728
+ "kind": "exact"
729
+ }
730
+ }
731
+ ],
732
+ "fields": {
733
+ "buyerAccountId": {
734
+ "description": "The buyer account",
735
+ "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
736
+ "type": "string",
737
+ "x-hyperscale-reference-filter": {
738
+ "column": "role",
739
+ "values": [
740
+ "customer_balance"
741
+ ]
742
+ }
743
+ },
744
+ "buyerAmount": {
745
+ "description": "Side A amount in SAR minor units, held against the whole trade",
746
+ "pattern": "^[1-9][0-9]{0,17}$",
747
+ "type": "string"
748
+ },
749
+ "buyerFee": {
750
+ "description": "Immutable exact buyer service fee in SAR minor units",
751
+ "pattern": "^[1-9][0-9]{0,17}$",
752
+ "type": "string"
753
+ },
754
+ "clawbackAt": {
755
+ "description": "Machine-owned end of the P7D whole-trade dispute window",
756
+ "format": "hyperscale-date-time",
757
+ "type": "string"
758
+ },
759
+ "currency": {
760
+ "description": "ISO 4217 currency code",
761
+ "maxLength": 3,
762
+ "minLength": 3,
763
+ "pattern": "^[A-Z]{3}$",
764
+ "type": "string"
765
+ },
766
+ "platformAccountId": {
767
+ "description": "The product fee collection account",
768
+ "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
769
+ "type": "string",
770
+ "x-hyperscale-fee-collection-port": true,
771
+ "x-hyperscale-reference-filter": {
772
+ "column": "role",
773
+ "values": [
774
+ "customer_balance",
775
+ "product_revenue"
776
+ ]
777
+ }
778
+ },
779
+ "sellerAccountId": {
780
+ "description": "The seller account",
781
+ "pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
782
+ "type": "string",
783
+ "x-hyperscale-reference-filter": {
784
+ "column": "role",
785
+ "values": [
786
+ "customer_balance"
787
+ ]
788
+ }
789
+ },
790
+ "sellerAmount": {
791
+ "description": "Side B amount in SAR minor units, held against the whole trade",
792
+ "pattern": "^[1-9][0-9]{0,17}$",
793
+ "type": "string"
794
+ },
795
+ "sellerFee": {
796
+ "description": "Immutable exact seller service fee in SAR minor units",
797
+ "pattern": "^[1-9][0-9]{0,17}$",
798
+ "type": "string"
799
+ }
800
+ },
801
+ "id": "exchange",
802
+ "idPrefix": "exch",
803
+ "lifecycle": {
804
+ "initial": "created",
805
+ "states": [
806
+ "created",
807
+ "abandoned",
808
+ "funded",
809
+ "cancelled",
810
+ "released",
811
+ "settled",
812
+ "clawed_back"
813
+ ],
814
+ "transitions": {
815
+ "abandon": {
816
+ "from": [
817
+ "created"
818
+ ],
819
+ "to": "abandoned"
820
+ },
821
+ "cancel": {
822
+ "from": [
823
+ "funded"
824
+ ],
825
+ "to": "cancelled"
826
+ },
827
+ "dispute": {
828
+ "from": [
829
+ "released"
830
+ ],
831
+ "to": "clawed_back"
832
+ },
833
+ "fund": {
834
+ "from": [
835
+ "created"
836
+ ],
837
+ "to": "funded"
838
+ },
839
+ "post": {
840
+ "from": [
841
+ "released"
842
+ ],
843
+ "to": "settled"
844
+ },
845
+ "release": {
846
+ "from": [
847
+ "funded"
848
+ ],
849
+ "to": "released"
850
+ }
851
+ }
852
+ },
853
+ "parties": {
854
+ "beneficiary": "sellerAccountId",
855
+ "payer": "buyerAccountId"
856
+ },
857
+ "required": [
858
+ "buyerAccountId",
859
+ "sellerAccountId",
860
+ "platformAccountId",
861
+ "buyerAmount",
862
+ "sellerAmount",
863
+ "buyerFee",
864
+ "sellerFee",
865
+ "currency"
866
+ ],
867
+ "summary": "Two-party atomic trade between buyer and seller",
868
+ "title": "Exchange"
869
+ }
870
+ ],
871
+ "product": "swap_example",
872
+ "subjects": [],
873
+ "title": "Swap example",
874
+ "udl": 1,
875
+ "version": 1
876
+ }