@hyperscale0/hsx 2.4.0 → 3.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 (249) hide show
  1. package/CHANGELOG.md +2 -400
  2. package/README.md +3 -92
  3. package/dist/src/ast.d.ts +99 -310
  4. package/dist/src/ast.d.ts.map +1 -1
  5. package/dist/src/ast.js +16 -69
  6. package/dist/src/ast.js.map +1 -1
  7. package/dist/src/cli.d.ts +6 -19
  8. package/dist/src/cli.d.ts.map +1 -1
  9. package/dist/src/cli.js +76 -315
  10. package/dist/src/cli.js.map +1 -1
  11. package/dist/src/compile.d.ts +23 -73
  12. package/dist/src/compile.d.ts.map +1 -1
  13. package/dist/src/compile.js +1113 -148
  14. package/dist/src/compile.js.map +1 -1
  15. package/dist/src/cost.d.ts +8 -77
  16. package/dist/src/cost.d.ts.map +1 -1
  17. package/dist/src/cost.js +13 -422
  18. package/dist/src/cost.js.map +1 -1
  19. package/dist/src/format.d.ts +8 -7
  20. package/dist/src/format.d.ts.map +1 -1
  21. package/dist/src/format.js +9 -175
  22. package/dist/src/format.js.map +1 -1
  23. package/dist/src/headers.d.ts +35 -0
  24. package/dist/src/headers.d.ts.map +1 -0
  25. package/dist/src/headers.js +108 -0
  26. package/dist/src/headers.js.map +1 -0
  27. package/dist/src/index.d.ts +6 -12
  28. package/dist/src/index.d.ts.map +1 -1
  29. package/dist/src/index.js +4 -9
  30. package/dist/src/index.js.map +1 -1
  31. package/dist/src/lex.d.ts +8 -28
  32. package/dist/src/lex.d.ts.map +1 -1
  33. package/dist/src/lex.js +88 -146
  34. package/dist/src/lex.js.map +1 -1
  35. package/dist/src/parse.d.ts +4 -17
  36. package/dist/src/parse.d.ts.map +1 -1
  37. package/dist/src/parse.js +402 -1040
  38. package/dist/src/parse.js.map +1 -1
  39. package/dist/src/std-bundle.d.ts.map +1 -1
  40. package/dist/src/std-bundle.js +12 -20
  41. package/dist/src/std-bundle.js.map +1 -1
  42. package/dist/src/std-library.d.ts +1 -1
  43. package/dist/src/std-library.d.ts.map +1 -1
  44. package/dist/src/std-library.js +1 -5
  45. package/dist/src/std-library.js.map +1 -1
  46. package/dist/src/tunables.d.ts +7 -0
  47. package/dist/src/tunables.d.ts.map +1 -0
  48. package/dist/src/tunables.js +26 -0
  49. package/dist/src/tunables.js.map +1 -0
  50. package/dist/src/version.d.ts +2 -4
  51. package/dist/src/version.d.ts.map +1 -1
  52. package/dist/src/version.js +2 -4
  53. package/dist/src/version.js.map +1 -1
  54. package/docs/README.md +179 -41
  55. package/docs/headers.md +44 -0
  56. package/examples/cost-table.json +99 -751
  57. package/examples/library.hsx +59 -0
  58. package/package.json +9 -17
  59. package/src/ast.ts +82 -441
  60. package/src/cli.ts +77 -362
  61. package/src/compile.ts +1535 -247
  62. package/src/cost.ts +28 -671
  63. package/src/format.ts +12 -256
  64. package/src/headers.ts +126 -0
  65. package/src/index.ts +7 -39
  66. package/src/lex.ts +99 -195
  67. package/src/parse.ts +403 -1209
  68. package/src/std-bundle.ts +12 -20
  69. package/src/std-library.ts +2 -7
  70. package/src/tunables.ts +31 -0
  71. package/src/version.ts +2 -5
  72. package/std/approvals.hsx +17 -0
  73. package/std/cards.hsx +63 -0
  74. package/std/collections.hsx +31 -0
  75. package/std/escrow.hsx +43 -0
  76. package/std/financing.hsx +372 -0
  77. package/std/insurance.hsx +59 -0
  78. package/std/lending.hsx +115 -0
  79. package/std/marketplace.hsx +24 -0
  80. package/std/money.hsx +195 -0
  81. package/std/savings.hsx +44 -0
  82. package/std/travel.hsx +98 -0
  83. package/std/wallet.hsx +41 -0
  84. package/dist/src/diagnostics.d.ts +0 -13
  85. package/dist/src/diagnostics.d.ts.map +0 -1
  86. package/dist/src/diagnostics.js +0 -587
  87. package/dist/src/diagnostics.js.map +0 -1
  88. package/dist/src/emit.d.ts +0 -51
  89. package/dist/src/emit.d.ts.map +0 -1
  90. package/dist/src/emit.js +0 -192
  91. package/dist/src/emit.js.map +0 -1
  92. package/dist/src/entry-overrides.d.ts +0 -58
  93. package/dist/src/entry-overrides.d.ts.map +0 -1
  94. package/dist/src/entry-overrides.js +0 -284
  95. package/dist/src/entry-overrides.js.map +0 -1
  96. package/dist/src/ir.d.ts +0 -73
  97. package/dist/src/ir.d.ts.map +0 -1
  98. package/dist/src/ir.js +0 -15
  99. package/dist/src/ir.js.map +0 -1
  100. package/dist/src/limits.d.ts +0 -23
  101. package/dist/src/limits.d.ts.map +0 -1
  102. package/dist/src/limits.js +0 -23
  103. package/dist/src/limits.js.map +0 -1
  104. package/dist/src/lsp/server.d.ts +0 -32
  105. package/dist/src/lsp/server.d.ts.map +0 -1
  106. package/dist/src/lsp/server.js +0 -391
  107. package/dist/src/lsp/server.js.map +0 -1
  108. package/dist/src/modules.d.ts +0 -38
  109. package/dist/src/modules.d.ts.map +0 -1
  110. package/dist/src/modules.js +0 -372
  111. package/dist/src/modules.js.map +0 -1
  112. package/dist/src/typecheck.d.ts +0 -8
  113. package/dist/src/typecheck.d.ts.map +0 -1
  114. package/dist/src/typecheck.js +0 -4131
  115. package/dist/src/typecheck.js.map +0 -1
  116. package/docs/guide/01-first-program.md +0 -24
  117. package/docs/guide/02-money.md +0 -25
  118. package/docs/guide/03-instruments.md +0 -93
  119. package/docs/guide/04-lifecycles.md +0 -40
  120. package/docs/guide/05-fees-and-splits.md +0 -45
  121. package/docs/guide/06-schedules.md +0 -26
  122. package/docs/guide/07-composition.md +0 -52
  123. package/docs/guide/08-writing-a-module.md +0 -85
  124. package/docs/guide/09-cost.md +0 -24
  125. package/docs/guide/10-diagnostics.md +0 -27
  126. package/docs/llms-full.txt +0 -3684
  127. package/docs/llms.txt +0 -44
  128. package/docs/piece-plans.md +0 -120
  129. package/docs/playground.md +0 -55
  130. package/docs/reference/cli.md +0 -36
  131. package/docs/reference/diagnostics.md +0 -901
  132. package/docs/reference/grammar.md +0 -38
  133. package/docs/reference/std/advance.md +0 -112
  134. package/docs/reference/std/cancellable_booking.md +0 -159
  135. package/docs/reference/std/captured_payment.md +0 -115
  136. package/docs/reference/std/conditional_disbursement.md +0 -101
  137. package/docs/reference/std/credit_facility.md +0 -108
  138. package/docs/reference/std/held_payment.md +0 -173
  139. package/docs/reference/std/instant_transfer.md +0 -97
  140. package/docs/reference/std/metered.md +0 -89
  141. package/docs/reference/std/pooled_split.md +0 -95
  142. package/docs/reference/std/premium_forward.md +0 -119
  143. package/docs/reference/std/reconciled_payout.md +0 -103
  144. package/docs/reference/std/rotating_pool.md +0 -130
  145. package/docs/reference/std/scheduled.md +0 -136
  146. package/docs/reference/std/security_deposit.md +0 -138
  147. package/docs/reference/std/settlement_batch.md +0 -123
  148. package/docs/reference/std/swap.md +0 -133
  149. package/docs/reference/std/threshold_pool.md +0 -138
  150. package/docs/reference/std/weighted_distribution.md +0 -135
  151. package/docs/reference/types.md +0 -61
  152. package/docs/reference/udl-output.md +0 -13
  153. package/examples/01-first-program/README.md +0 -45
  154. package/examples/01-first-program/tip-jar.hsx +0 -17
  155. package/examples/02-imports-and-modules/README.md +0 -96
  156. package/examples/02-imports-and-modules/photo-booth.hsx +0 -37
  157. package/examples/03-diagnostics/README.md +0 -68
  158. package/examples/03-diagnostics/corner-shop-fixed.hsx +0 -22
  159. package/examples/03-diagnostics/corner-shop.hsx +0 -19
  160. package/examples/04-complete-product/README.md +0 -84
  161. package/examples/04-complete-product/study-hall.hsx +0 -67
  162. package/examples/05-authored-instrument/README.md +0 -5
  163. package/examples/05-authored-instrument/payment.hsx +0 -37
  164. package/examples/05-watch-club/README.md +0 -6
  165. package/examples/05-watch-club/watch-club.hsx +0 -123
  166. package/examples/README.md +0 -48
  167. package/examples/advance/README.md +0 -3
  168. package/examples/advance/advance.hsx +0 -13
  169. package/examples/advance/advance.udl +0 -367
  170. package/examples/cancellable_booking/README.md +0 -3
  171. package/examples/cancellable_booking/cancellable_booking.hsx +0 -14
  172. package/examples/cancellable_booking/cancellable_booking.udl +0 -413
  173. package/examples/captured_payment/README.md +0 -3
  174. package/examples/captured_payment/captured_payment.hsx +0 -17
  175. package/examples/captured_payment/captured_payment.udl +0 -686
  176. package/examples/conditional_disbursement/README.md +0 -3
  177. package/examples/conditional_disbursement/conditional_disbursement.hsx +0 -15
  178. package/examples/conditional_disbursement/conditional_disbursement.udl +0 -418
  179. package/examples/credit_facility/README.md +0 -3
  180. package/examples/credit_facility/credit_facility.hsx +0 -24
  181. package/examples/credit_facility/credit_facility.udl +0 -1396
  182. package/examples/held_payment/README.md +0 -3
  183. package/examples/held_payment/held_payment.hsx +0 -13
  184. package/examples/held_payment/held_payment.udl +0 -569
  185. package/examples/instant_transfer/README.md +0 -3
  186. package/examples/instant_transfer/instant_transfer.hsx +0 -16
  187. package/examples/instant_transfer/instant_transfer.udl +0 -376
  188. package/examples/metered/README.md +0 -3
  189. package/examples/metered/metered.hsx +0 -13
  190. package/examples/metered/metered.udl +0 -253
  191. package/examples/pooled_split/README.md +0 -3
  192. package/examples/pooled_split/pooled_split.hsx +0 -15
  193. package/examples/pooled_split/pooled_split.udl +0 -432
  194. package/examples/premium_forward/README.md +0 -3
  195. package/examples/premium_forward/premium_forward.hsx +0 -19
  196. package/examples/premium_forward/premium_forward.udl +0 -604
  197. package/examples/reconciled_payout/README.md +0 -3
  198. package/examples/reconciled_payout/reconciled_payout.hsx +0 -13
  199. package/examples/reconciled_payout/reconciled_payout.udl +0 -312
  200. package/examples/rotating_pool/README.md +0 -3
  201. package/examples/rotating_pool/rotating_pool.hsx +0 -18
  202. package/examples/rotating_pool/rotating_pool.udl +0 -4370
  203. package/examples/scheduled/README.md +0 -3
  204. package/examples/scheduled/scheduled.hsx +0 -12
  205. package/examples/scheduled/scheduled.udl +0 -355
  206. package/examples/security_deposit/README.md +0 -3
  207. package/examples/security_deposit/security_deposit.hsx +0 -21
  208. package/examples/security_deposit/security_deposit.udl +0 -320
  209. package/examples/settlement_batch/README.md +0 -3
  210. package/examples/settlement_batch/settlement_batch.hsx +0 -19
  211. package/examples/settlement_batch/settlement_batch.udl +0 -757
  212. package/examples/swap/README.md +0 -3
  213. package/examples/swap/swap.hsx +0 -19
  214. package/examples/swap/swap.udl +0 -892
  215. package/examples/threshold_pool/README.md +0 -3
  216. package/examples/threshold_pool/threshold_pool.hsx +0 -16
  217. package/examples/threshold_pool/threshold_pool.udl +0 -680
  218. package/examples/weighted_distribution/README.md +0 -3
  219. package/examples/weighted_distribution/weighted_distribution.hsx +0 -20
  220. package/examples/weighted_distribution/weighted_distribution.udl +0 -348
  221. package/skills/hsx/SKILL.md +0 -449
  222. package/src/diagnostics.ts +0 -620
  223. package/src/emit.ts +0 -282
  224. package/src/entry-overrides.ts +0 -428
  225. package/src/ir.ts +0 -113
  226. package/src/limits.ts +0 -22
  227. package/src/lsp/server.ts +0 -460
  228. package/src/modules.ts +0 -452
  229. package/src/typecheck.ts +0 -5381
  230. package/std/SEMANTICS.md +0 -44
  231. package/std/money_flows/advance.hsx +0 -235
  232. package/std/money_flows/cancellable_booking.hsx +0 -402
  233. package/std/money_flows/captured_payment.hsx +0 -220
  234. package/std/money_flows/conditional_disbursement.hsx +0 -226
  235. package/std/money_flows/credit_facility.hsx +0 -214
  236. package/std/money_flows/held_payment.hsx +0 -812
  237. package/std/money_flows/index.hsx +0 -4
  238. package/std/money_flows/instant_transfer.hsx +0 -231
  239. package/std/money_flows/metered.hsx +0 -104
  240. package/std/money_flows/pooled_split.hsx +0 -109
  241. package/std/money_flows/premium_forward.hsx +0 -307
  242. package/std/money_flows/reconciled_payout.hsx +0 -119
  243. package/std/money_flows/rotating_pool.hsx +0 -305
  244. package/std/money_flows/scheduled.hsx +0 -599
  245. package/std/money_flows/security_deposit.hsx +0 -248
  246. package/std/money_flows/settlement_batch.hsx +0 -173
  247. package/std/money_flows/swap.hsx +0 -1192
  248. package/std/money_flows/threshold_pool.hsx +0 -307
  249. package/std/money_flows/weighted_distribution.hsx +0 -237
@@ -1,3684 +0,0 @@
1
- <!-- Generated by scripts/docs/build.ts for HSX 2.4.0. Do not edit. -->
2
-
3
- # HSX full documentation
4
-
5
- # Your first program
6
-
7
- An HSX file declares one program, the parties that take part, and the instruments that define its money rules. A settlement applies a standard-library instrument. The compiler checks the application and emits canonical UDL with an origin map and a cost manifest.
8
-
9
- This program sends a tip from a listener to a host:
10
-
11
- ```hsx
12
- program tip_jar "Tip jar"
13
- import { instant_transfer } from "std/money_flows"
14
- party listener: person
15
- party host: business
16
- settlement tip = instant_transfer {
17
- payer: listener
18
- payee: host
19
- amount: tipAmount: money(SAR)
20
- fees { listener: 1% }
21
- }
22
- ```
23
-
24
- `tipAmount` is an input field measured in SAR minor units. The settlement becomes an instrument named `tip` in the UDL document.
25
-
26
- A port declares a decision that an external caller may supply. The port names the parties allowed to answer and may define a typed input shape. Use a port only when the selected instrument accepts a condition parameter.
27
-
28
- After package installation, run `npx @hyperscale0/hsx check product.hsx` while editing and `npx @hyperscale0/hsx build product.hsx --out product.udl.json` when the program passes. In the full repository checkout, run `bun install` once from the repository root, then use `bun open/hsx/bin/hsx.ts check product.hsx` and `bun open/hsx/bin/hsx.ts build product.hsx --out product.udl.json`. In the standalone HSX package checkout, the entrypoint is `bin/hsx.ts`.
29
-
30
- # Money
31
-
32
- HSX indexes money by currency. `money<SAR>` is the field type inside a general instrument. `amount: total: money(SAR)` binds a settlement parameter to a new SAR money field. Values use integer minor units, so `1250` means SAR 12.50. The emitted UDL field keeps the currency as `x-hyperscale-currency`, which is how the platform learns a program's ledger currency.
33
-
34
- Money of different currencies never unifies. Percent literals use basis-point precision: `2%` is 200 basis points and `2.5%` is 250 basis points. The compiler floors percentage-derived minor units and assigns any declared remainder according to the selected instrument.
35
-
36
- Money is linear. A computed amount must be consumed exactly once. This invalid general-form program uses `rest` twice, so the compiler reports `HSX1201`:
37
-
38
- ```hsx expect=HSX1201
39
- program duplicated_money "Duplicated money"
40
- party buyer: person
41
- instrument invoice {
42
- fields { amount: money<SAR>; }
43
- lifecycle { states created paid; initial created; on pay: created -> paid; }
44
- parties { payer: buyer; }
45
- action create { steps: []; }
46
- action pay {
47
- computes remainder rest { amount_ref: total; on_zero: refuse; total_path: fields.amount; }
48
- moves: [{ amount: rest; }, { amount: rest; }]
49
- steps: []
50
- }
51
- }
52
- ```
53
-
54
- Do not use free arithmetic to repair a linearity refusal. Choose a standard-library split, fee, or derived-amount form that states where every minor unit goes.
55
-
56
- # Instruments
57
-
58
- Start with the money flows library (open/hsx/std). Import a money flow by export name from `std/money_flows`, then apply it under a local settlement name. The local name becomes the emitted instrument id.
59
-
60
- ```hsx
61
- program equipment_hire "Equipment hire"
62
- import { scheduled } from "std/money_flows"
63
- party renter: person
64
- party owner: business
65
- settlement installments = scheduled {
66
- payer: renter
67
- payee: owner
68
- amount: hirePrice: money(SAR)
69
- count: 2
70
- every: P30D
71
- first_due: firstPaymentAt
72
- }
73
- ```
74
-
75
- Required parameters state the instrument's core contract. Optional parameters add bounded behavior such as a deadline, cancellation allocation, fee, or policy. Omit an optional block when the product does not need it. Do not pass an empty block as a substitute unless the module documents that form.
76
-
77
- The generated money flows reference lists every module, parameter, action, port, and emitted clause. Read that page before choosing a module. Prefer one module that already states the required lifecycle over a custom instrument with copied mechanics.
78
-
79
- ## Account fields
80
-
81
- When declaring fields of type `account<C>`, the HSX compiler automatically lowers the field schema with the UDL2002 account pattern (`^acct_(sandbox|live)_[a-z0-9]{8,64}$`). Authors do not need to write an explicit `pattern` clause on account fields.
82
-
83
- ```hsx
84
- fields {
85
- customerAccountId {
86
- type: account<SAR>;
87
- "x-hyperscale-reference-filter": { column: role; values: [customer_balance]; };
88
- }
89
- amount: money<SAR>;
90
- }
91
- ```
92
-
93
- The account type pins the currency and identifier shape. The reference filter
94
- pins the allowed ledger roles. Product admission requires every account field
95
- to declare a non-empty role list. Choose roles that match the accounts the
96
- program will use; `customer_balance` is the role in this example.
97
-
98
- Use the quoted `"x-hyperscale-reference-filter"` key inside the field block,
99
- with `column: role` and `values: [...]`. There is no shorter role annotation.
100
- A bare `customerAccountId: account<SAR>;` compiles as HSX but does not satisfy
101
- the host's account-role admission law.
102
-
103
- ## Money fields
104
-
105
- A `money<C>` field admits a minor-unit integer string and refuses zero: it lowers to the pattern `^[1-9][0-9]{0,17}$`. Marking the field `optional: true` lets a caller omit it; it does not let a caller send `"0"`. When zero is a real value for the field, opt in with `allow_zero: true`, which lowers to `^(0|[1-9][0-9]{0,17})$`:
106
-
107
- ```hsx
108
- fields {
109
- amount: money<SAR>;
110
- discount { type: money<SAR>; optional: true; allow_zero: true; }
111
- }
112
- ```
113
-
114
- `allow_zero` on any other type is HSX1105. Decision port shapes set it on their money fields, because a decided amount may be zero.
115
-
116
- ## Date fields
117
-
118
- A `date` field lowers to the UDL `hyperscale-date-time` format. Callers may send any RFC 3339 offset, such as `2026-10-03T09:00:00+03:00`; the host admits it and stores the UTC instant, `2026-10-03T06:00:00.000Z`. A value already in `Z` is stored byte for byte. A local date-time without an offset is refused.
119
-
120
- ## Port declarations and action clauses
121
-
122
- HSX supports two distinct port syntaxes depending on scope:
123
-
124
- 1. **Top-level port declarations** declare a named port at program scope using `allowed: [...]`.
125
- 2. **Action-level port clauses** define caller permissions directly inside an instrument action using `allowed_parties: [...]`.
126
-
127
- Top-level port declaration:
128
-
129
- ```hsx
130
- port confirm_delivery {
131
- allowed: [buyer];
132
- }
133
- ```
134
-
135
- Action-level port clause:
136
-
137
- ```hsx
138
- action release {
139
- agent_description: "Release escrowed funds to the payee."
140
- steps: [];
141
- moves: [];
142
- port {
143
- allowed_parties: [payer];
144
- }
145
- }
146
- ```
147
-
148
- Writing `allowed:` inside an action-level `port` clause triggers diagnostic `HSX1508`. Use `allowed_parties: [...]` inside action clauses, and reserve `allowed: [...]` for top-level port declarations.
149
-
150
- # Lifecycles
151
-
152
- A lifecycle lists every state, names one initial state, and declares action transitions. Every reachable nonterminal state must have a bounded exit or be explicitly parked for a caller action. Actions hold the money moves and other typed clauses that occur on a transition.
153
-
154
- ```hsx
155
- program approvals "Approvals"
156
- instrument approval {
157
- agent_description: "Manage a bounded approval decision across pending, approved, and rejected states."
158
- title: "Approval"
159
- summary: "A bounded approval decision"
160
- fields {}
161
- lifecycle {
162
- states pending approved rejected;
163
- initial pending;
164
- on approve: pending -> approved;
165
- on reject: pending -> rejected;
166
- }
167
- action create {
168
- agent_description: "Create an approval record in pending state."
169
- steps: [];
170
- moves: [];
171
- }
172
- action approve {
173
- agent_description: "Approve the pending decision."
174
- steps: [];
175
- moves: [];
176
- }
177
- action reject {
178
- agent_description: "Reject the pending decision."
179
- steps: [];
180
- moves: [];
181
- }
182
- }
183
- ```
184
-
185
- Every callable custom instrument action becomes an agent tool and requires an `agent_description` string. Instruments that declare callable actions also require an `agent_description` string. Actions that declare a `due` clause are exempt system actions that run on a schedule instead of an agent call. The compiler emits `HSX1509` when an author omits `agent_description` on an instrument or callable action.
186
-
187
- Standard-library instruments bind ports to caller decisions. A deadline appears as stored date data and a `due` clause on the action that may run at that date. An unwind states how a failed or cancelled path drains held value. The compiler refuses a reachable exit that strands money.
188
-
189
- Keep lifecycle changes additive after composition. Add a new action or state when old instances can still obey the previous contract. Do not rename a state or tighten an active transition in place.
190
-
191
- # Fees and splits
192
-
193
- Standard-library payment modules accept bounded fee forms. A payer fee sits on top of the principal. A payee fee is carved from the payout. A fee may be an exact percentage, an immutable money field, or a finite tier table when the module accepts it.
194
-
195
- ```hsx
196
- program lesson_market "Lesson market"
197
- import { instant_transfer, pooled_split } from "std/money_flows"
198
- party student: person
199
- party tutor: business
200
- party assistant: business
201
- party school: business
202
- settlement lesson = instant_transfer {
203
- payer: student
204
- payee: tutor
205
- amount: lessonFee: money(SAR)
206
- fees { student: 1%, tutor: 8% }
207
- }
208
- settlement payout = pooled_split {
209
- payer: school
210
- amount: weeklyPool: money(SAR)
211
- payout_due: payoutAt
212
- split { tutor: 60%, assistant: 40%, remainder_to: tutor }
213
- }
214
- ```
215
-
216
- Every percentage partition must total 100 percent. `pooled_split` distributes a pool among named recipients and sends integer-division residue to `remainder_to`. `security_deposit` can bind a decided claim amount and return the unused remainder. `weighted_distribution` records bounded entitlement rows before it snapshots a distribution.
217
-
218
- `cancellable_booking` uses `quote` and `commit` when a fee must be shown before it can move money. Its `cancel` action prices a penalty from the time left before `starts_at`, freezes the price and the fields named by `fixes`, and gives the offer a bounded life. Its `confirm` action commits that exact quote. Expiry or a changed frozen field refuses the commit instead of repricing it silently.
219
-
220
- ```hsx
221
- program studio_booking "Studio booking"
222
- import { cancellable_booking } from "std/money_flows"
223
- party guest: person
224
- party studio: business
225
- settlement session = cancellable_booking {
226
- guest: guest
227
- host: studio
228
- amount: sessionPrice: money(SAR)
229
- starts_at: startsAt
230
- late_penalty_bps: 5000
231
- late_within: P2D
232
- early_penalty_bps: 1000
233
- offer_life: PT30M
234
- }
235
- ```
236
-
237
- # Schedules
238
-
239
- HSX schedules are finite. A literal `count`, an interval, and a first due date let the compiler expand installments at compile time. The monthly obligation form can instead use a caller-controlled end condition, but it must name the drain action that ends future liability.
240
-
241
- ```hsx
242
- program installments "Installments"
243
- import { scheduled } from "std/money_flows"
244
- party buyer: person
245
- party seller: business
246
- settlement plan = scheduled {
247
- payer: buyer
248
- payee: seller
249
- amount: totalAmount: money(SAR)
250
- count: 3
251
- every: P30D
252
- first_due: firstDueAt
253
- }
254
- ```
255
-
256
- `scheduled` handles finite installments and obligation schedules. `rotating_pool` expands a fixed roster and cycle count. `settlement_batch` closes on a stored date before calculation, approval, instruction, acknowledgement, and reconciliation actions.
257
-
258
- General modules may use a comprehension over a compile-time integer or finite list. Runtime-dependent bounds are refused. An expansion may contain at most 256 generated rows.
259
-
260
- Finite obligation counts expand the same lifecycle for each slice. A lifecycle source may be a finite list; `without(states, state)` removes one state before expansion. This preserves rejection of a repeated delinquency marker for its current slice.
261
-
262
- Use `advance` with `dated: true` when each repayment has a signed date. `repayment_source` separates the borrower from the capital recipient; `profit_to` sends computed profit to a separate account. The caller partitions the principal and profit across stored repayments. These partitions do not enforce equal slices or ordered dates.
263
-
264
- # Composition
265
-
266
- One program can apply several instruments. Each instrument keeps its own lifecycle and fields. References connect them through typed ids instead of shared mutable state.
267
-
268
- ```hsx
269
- program studio_sales "Studio sales"
270
- import { instant_transfer, scheduled } from "std/money_flows"
271
- party buyer: person
272
- party studio: business
273
- settlement purchase = instant_transfer {
274
- payer: buyer
275
- payee: studio
276
- amount: purchasePrice: money(SAR)
277
- fees { buyer: 1% }
278
- }
279
- settlement installments = scheduled {
280
- payer: buyer
281
- payee: studio
282
- amount: servicePrice: money(SAR)
283
- count: 2
284
- every: P30D
285
- first_due: firstPaymentAt
286
- }
287
- ```
288
-
289
- A general instrument declares a `ref<target>` field when an instance must point to another instrument. Cross-instrument clauses bind against the target's declared fields, actions, and lifecycle states after the full module graph resolves. A missing target or incompatible field reports a typed diagnostic before UDL emission.
290
-
291
- Keep each money route in one instrument. Connect instruments with evidence and references. Do not move an amount through an untyped text field.
292
-
293
- `reconciled_payout` composes a payout instruction with one explicit expectation about the bank debit that follows. Its `reconcile` clause binds the expected amount, currency, direction, payout reference, evidence source, match law, and deadline. A match settles the payout. A missed or mismatched expectation creates the declared break child, so the composition retains the exception as contract data.
294
-
295
- ```hsx
296
- program supplier_payment "Supplier payment"
297
- import { reconciled_payout } from "std/money_flows"
298
- party treasury: business
299
- party supplier: business
300
- settlement payout = reconciled_payout {
301
- payer: treasury
302
- beneficiary: supplier
303
- amount: netPayable: money(SAR)
304
- beneficiary_ref: supplierBeneficiaryId
305
- settle_by: settleBy
306
- matched_within: 100
307
- matched_ceiling: 500
308
- }
309
- ```
310
-
311
- ## Recomposition and exposed actions
312
-
313
- When evolving an existing Product with new instruments or flows, the composer plans the candidate program against the active Product Build.
314
-
315
- Public action exposures preserve stable semantic identities across builds. Unchanged authored instruments and catalog instruments retain their exposures without false removal and re-addition churn. Only genuinely new, removed, or rebound action aliases appear in the exposure delta.
316
-
317
- # Writing a module
318
-
319
- A module is ordinary HSX source. It declares a dotted module name and exports templates, types, constants, subjects, or applications. The compiler does not branch on a standard-library module name.
320
-
321
- ```hsx
322
- program approval_example "Approval example"
323
- instrument approval() {
324
- agent_description: "Reusable approval lifecycle template."
325
- title: "Approval"
326
- summary: "A reusable approval lifecycle"
327
- fields {}
328
- lifecycle {
329
- states pending approved;
330
- initial pending;
331
- on approve: pending -> approved;
332
- }
333
- action create {
334
- agent_description: "Create a pending approval record."
335
- steps: [];
336
- moves: [];
337
- }
338
- action approve {
339
- agent_description: "Approve the pending decision."
340
- steps: [];
341
- moves: [];
342
- }
343
- }
344
- instrument review = approval()
345
- ```
346
-
347
- Custom instruments and callable actions require `agent_description: "..."`. An agent uses these descriptions as tool instructions when invoking actions on an instance. Actions that declare a `due` clause run without an agent call and remain exempt from this requirement. Omitting `agent_description` on callable actions or their containing instruments triggers `HSX1509`.
348
-
349
- A parameter list makes an instrument a template, including an empty list. A concrete instrument without a parameter list emits directly when its file compiles. Export only the declarations that callers need.
350
-
351
- Imported exports carry the local declarations they reference. Identical declarations unify. Conflicting declarations report `HSX1009`. Keep module parameters typed, keep loops finite, and use UDL clause vocabulary for instrument and action mechanics.
352
-
353
- Publish a module only after compiling it directly and through an importing program. Compare the canonical UDL bytes from both paths when the exported application should be identical.
354
-
355
- ## An authored action that moves money
356
-
357
- Declare each cash movement in `moves` with a unique `key`, an `operation`, and `bind` operands. This complete program comes from [payment.hsx](../../examples/05-authored-instrument/payment.hsx). The docs builder requires the snippet to match that file and compiles it with the packaged cost table.
358
-
359
- ```hsx source=examples/05-authored-instrument/payment.hsx
360
- program authored_payment "Authored payment"
361
-
362
- instrument payment {
363
- agent_description: "Collect a stored payment once from its payer."
364
- title: "Payment"
365
- summary: "A payment with fixed payer and payee accounts"
366
- fields {
367
- payerAccountId: account<SAR>;
368
- payeeAccountId: account<SAR>;
369
- amount: money<SAR>;
370
- }
371
- parties { payer: payerAccountId; beneficiary: payeeAccountId; }
372
- lifecycle {
373
- states pending paid;
374
- initial pending;
375
- on pay: pending -> paid;
376
- }
377
- action create {
378
- agent_description: "Open a pending payment without moving money."
379
- steps: [];
380
- moves: [];
381
- }
382
- action pay {
383
- agent_description: "Move the stored amount from payer to payee."
384
- steps: [];
385
- moves: [{
386
- bind: {
387
- amount: { from: "instance", path: "fields.amount" }
388
- currency: { from: "const", value: "SAR" }
389
- sourceAccountId: { from: "instance", path: "fields.payerAccountId" }
390
- destinationAccountId: { from: "instance", path: "fields.payeeAccountId" }
391
- }
392
- key: "payment_transfer"
393
- operation: "internal_transfer.create"
394
- }];
395
- }
396
- }
397
- ```
398
-
399
- `from: "instance"` reads an immutable stored field. `from: "const"` supplies the literal currency. The four bindings supply the transfer's amount, currency, source account and destination account. `internal_transfer.create` names the transfer operation; `payment_transfer` identifies this move within the action. Account IDs come from account creation or discovery before creating the payment. They are never invented by the program.
400
-
401
- `create` opens a pending record without cash movement. `pay` moves the stored amount and transitions to `paid`; the lifecycle refuses a second payment under a new action request. The compiler emits these bindings into UDL. Execution still requires an engine that admits the operation and accounts.
402
-
403
- # Cost
404
-
405
- Compilation emits a deterministic cost manifest beside the UDL document. The manifest pins the cost-table version and effective digest. It records fixed structural cost, action effect rows, payer, settlement policy, meters, per-event prices, and any basis-point volume price.
406
-
407
- ```hsx
408
- program direct_sale "Direct sale"
409
- import { instant_transfer } from "std/money_flows"
410
- party buyer: person
411
- party seller: business
412
- settlement sale = instant_transfer {
413
- payer: buyer
414
- payee: seller
415
- amount: saleAmount: money(SAR)
416
- fees { buyer: 1% }
417
- }
418
- ```
419
-
420
- Read an action line as `instrument.action`, followed by the effect signature and its count. The payer tells whether the product or end customer bears the row. `perEventMinor` prices one occurrence in the cost table's billing currency. A row with `bps` also names a volume meter.
421
-
422
- The monthly estimate is an expression over declared meter variables. Billing supplies observed readings to that frozen expression. Recomposition emits a new manifest for the next commercial snapshot. It does not rewrite a prior manifest. During recomposition planning, compose plan calculates the candidate program's proposed estimate and reconciles it against the current Build's frozen pricing quote. The existing Product retains its frozen quote until the recomposition is applied.
423
-
424
- An effect without a price row reports `HSX1301`. An invalid price reports `HSX1302`. A missing cost table also reports `HSX1301`. `examples/cost-table.json` ships one rate card per priced billing currency; the compiler picks the card whose currency the program's money fields move. Money in a currency no card prices reports `HSX1304`, and money in two currencies reports `HSX1305`: a program bills in one ledger currency. A move of a `money<SAR>` field moves SAR whatever the caller wrote in the instance currency field: the compiler pins the move's currency binding to the constant, and a binding it cannot pin reports `HSX1306`. Do not create another table for documentation.
425
-
426
- Do not confuse an action `quote` with the commercial cost manifest. `cancellable_booking.cancel` quotes a customer-visible cancellation penalty and `confirm` commits it. The compiler counts an instrument that carries a quote as unwind work because an expired or abandoned offer still needs bounded cleanup. The cost manifest prices that runtime work from the shipped rate card. It does not replace, spend, or alter the quoted financial amount.
427
-
428
- # Diagnostics
429
-
430
- An HSX diagnostic carries a stable code, severity, stage, source line and column, message, and fix. Match automation on the code. Treat the message as explanation rather than a stable interface.
431
-
432
- The stages locate the refusal:
433
-
434
- - `parse` means the source did not form valid declarations or expressions.
435
- - `bind` means an import, name, port, or reference did not resolve.
436
- - `typecheck` and `check` mean the program formed but violated a type or language law.
437
- - `lower` means the typed program could not emit valid UDL.
438
-
439
- Use one loop: compile, find the first error code in the diagnostics reference, apply its stated fix, and compile again. Do not suppress the diagnostic or alter generated UDL by hand.
440
-
441
- ```hsx
442
- program repaired_transfer "Repaired transfer"
443
- import { instant_transfer } from "std/money_flows"
444
- party sender: person
445
- party recipient: business
446
- settlement transfer = instant_transfer {
447
- payer: sender
448
- payee: recipient
449
- amount: transferAmount: money(SAR)
450
- fees { sender: 1% }
451
- }
452
- ```
453
-
454
- Exit code `0` means the command accepted the program. Exit code `1` means compilation refused it. Exit code `2` means the invocation or file operation failed. `hsx explain HSX1201` prints the catalog entry for one code.
455
-
456
- # CLI
457
-
458
- ```text
459
- hsx 2.4.0, the HSX compiler
460
-
461
- Usage:
462
- hsx check <file.hsx> [--catalog <catalog.udl>] [--strict]
463
- hsx build <file.hsx> [--catalog <catalog.udl>] [--out <file.json>] [--strict]
464
- hsx cost <file.hsx> [--catalog <catalog.udl>] [--json] [--out <file.json>] [--strict]
465
- hsx explain <HSX####>
466
- hsx format <file.hsx>
467
- hsx lsp
468
- hsx --version
469
- hsx --help
470
-
471
- Commands:
472
- check Compile and report diagnostics. Prints nothing when the program is clean.
473
- build Compile and write canonical UDL as JSON.
474
- cost Compile and print the version-pinned cost manifest as a table or JSON.
475
- explain Print one diagnostic title, fix, and source example.
476
- format Print the source in the one canonical HSX style.
477
- lsp Run the language server over stdin and stdout.
478
-
479
- Options:
480
- --catalog <file> Read the published instrument catalogue as canonical UDL JSON.
481
- --json Print the cost manifest as JSON instead of a table.
482
- --out <file> Write build or cost JSON to this path instead of stdout.
483
- --strict Treat warning-severity diagnostics as failures.
484
-
485
- Exit codes:
486
- 0 the program compiled (verdict valid, or warning without --strict)
487
- 1 the program was refused (verdict invalid, or warning with --strict)
488
- 2 the command line or the input file could not be used
489
- ```
490
-
491
- # Diagnostics
492
-
493
- Use `hsx explain HSX####` for the same catalog entry.
494
-
495
- ## HSX1000: Missing file declaration
496
-
497
- Stage: `typecheck`
498
-
499
- Fix: Add one program header or module declaration.
500
-
501
- No source-only witness exists. The compiler host or lowering input must supply the invalid value.
502
-
503
- ## HSX1001: Unbound name
504
-
505
- Stage: `bind`
506
-
507
- Fix: Declare or import the name before using it.
508
-
509
- ```hsx expect=HSX1001
510
- program catalog_probe "Catalog probe"
511
- instrument probe = missing()
512
- ```
513
-
514
- ## HSX1002: Duplicate program declaration
515
-
516
- Stage: `typecheck`
517
-
518
- Fix: Keep exactly one program declaration.
519
-
520
- ```hsx expect=HSX1002
521
- program catalog_probe "Catalog probe"
522
- instrument probe {
523
- agent_description: "Probe instrument for catalog diagnostics.";
524
- fields { }
525
- lifecycle { states created; initial created; }
526
- action create {
527
- agent_description: "Create a probe instance.";
528
- steps: [];
529
- }
530
-
531
- }
532
- program second "Second"
533
- ```
534
-
535
- ## HSX1003: Invalid declaration name
536
-
537
- Stage: `typecheck`
538
-
539
- Fix: Use lowercase snake_case for program and instrument names.
540
-
541
- ```hsx expect=HSX1003
542
- program NotSnake "Catalog probe"
543
- ```
544
-
545
- ## HSX1004: Duplicate declaration
546
-
547
- Stage: `typecheck`
548
-
549
- Fix: Keep one declaration or give each declaration a distinct name.
550
-
551
- ```hsx expect=HSX1004
552
- program catalog_probe "Catalog probe"
553
- instrument probe {
554
- agent_description: "Probe instrument for catalog diagnostics.";
555
- fields { }
556
- lifecycle { states created; initial created; }
557
- action create {
558
- agent_description: "Create a probe instance.";
559
- steps: [];
560
- }
561
-
562
- }
563
- instrument probe { fields {}; lifecycle { states created; initial created; }; action create { steps: []; }; }
564
- ```
565
-
566
- ## HSX1005: Invalid field name
567
-
568
- Stage: `typecheck`
569
-
570
- Fix: Rename the field in lower camelCase.
571
-
572
- No source-only witness exists. The parser normalizes every accepted field spelling before typechecking.
573
-
574
- ## HSX1006: Invalid module import
575
-
576
- Stage: `bind`
577
-
578
- Fix: Resolve one module that exports each imported name exactly once.
579
-
580
- No source-only witness exists. This refusal requires a compiler-host module resolver result.
581
-
582
- ## HSX1007: Invalid cross-instrument reference
583
-
584
- Stage: `typecheck`
585
-
586
- Fix: Name an existing target instrument in the ref type.
587
-
588
- ```hsx expect=HSX1007
589
- program catalog_probe "Catalog probe"
590
- instrument probe {
591
- fields { parentId { type: ref; description: "Parent"; } }
592
- lifecycle { states created; initial created; }
593
- action create { steps: []; }
594
- }
595
- ```
596
-
597
- ## HSX1008: Invalid subject or decision port
598
-
599
- Stage: `typecheck`
600
-
601
- Fix: Complete the declaration and bind every referenced decision port.
602
-
603
- ```hsx expect=HSX1008
604
- program catalog_probe "Catalog probe"
605
- instrument probe {
606
- agent_description: "Probe instrument for catalog diagnostics.";
607
- fields { }
608
- lifecycle { states created; initial created; }
609
- action create {
610
- agent_description: "Create a probe instance.";
611
- steps: [];
612
- }
613
-
614
- }
615
- subject vehicle { title: "Vehicle"; }
616
- ```
617
-
618
- ## HSX1009: Imported declaration collision
619
-
620
- Stage: `bind`
621
-
622
- Fix: Rename the importer-owned declaration or the module-local declaration.
623
-
624
- No source-only witness exists. This refusal requires declarations returned by a compiler-host module resolver.
625
-
626
- ## HSX1010: Wrong type-argument count
627
-
628
- Stage: `typecheck`
629
-
630
- Fix: Supply exactly the type arguments declared by the instrument function.
631
-
632
- ```hsx expect=HSX1010
633
- program catalog_probe "Catalog probe"
634
- export instrument template<C>() { fields {}; lifecycle { states created; initial created; }; action create { steps: []; }; }
635
- instrument probe = template<SAR, USD>()
636
- ```
637
-
638
- ## HSX1011: Missing required argument
639
-
640
- Stage: `typecheck`
641
-
642
- Fix: Pass every required instrument-function argument.
643
-
644
- ```hsx expect=HSX1011
645
- program catalog_probe "Catalog probe"
646
- export instrument template(value: text) { fields {}; lifecycle { states created; initial created; }; action create { steps: []; }; }
647
- instrument probe = template()
648
- ```
649
-
650
- ## HSX1012: Unknown named argument
651
-
652
- Stage: `typecheck`
653
-
654
- Fix: Remove the argument or use a parameter declared by the instrument function.
655
-
656
- ```hsx expect=HSX1012
657
- program catalog_probe "Catalog probe"
658
- export instrument template() { fields {}; lifecycle { states created; initial created; }; action create { steps: []; }; }
659
- instrument probe = template(typo: true)
660
- ```
661
-
662
- ## HSX1013: Duplicate named argument
663
-
664
- Stage: `typecheck`
665
-
666
- Fix: Pass each named argument once.
667
-
668
- ```hsx expect=HSX1013
669
- program catalog_probe "Catalog probe"
670
- export instrument template(value: text) { fields {}; lifecycle { states created; initial created; }; action create { steps: []; }; }
671
- instrument probe = template(value: "one", value: "two")
672
- ```
673
-
674
- ## HSX1014: JSON supplied as HSX
675
-
676
- Stage: `parse`
677
-
678
- Fix: Replace the JSON object with HSX declarations.
679
-
680
- ```hsx expect=HSX1014
681
- { "hsx": 1 }
682
- ```
683
-
684
- ## HSX1015: Invalid composed program identity
685
-
686
- Stage: `typecheck`
687
-
688
- Fix: Give the composed program a bounded product id and title.
689
-
690
- No source-only witness exists. This refusal requires a compiler-host published catalog.
691
-
692
- ## HSX1016: Empty published composition
693
-
694
- Stage: `typecheck`
695
-
696
- Fix: Select at least one published instrument with use.
697
-
698
- No source-only witness exists. This refusal requires a compiler-host published catalog.
699
-
700
- ## HSX1017: Duplicate published instrument
701
-
702
- Stage: `typecheck`
703
-
704
- Fix: Keep one use declaration for each published instrument.
705
-
706
- No source-only witness exists. This refusal requires a compiler-host published catalog.
707
-
708
- ## HSX1018: Unavailable published instrument
709
-
710
- Stage: `typecheck`
711
-
712
- Fix: Use an instrument id from the supplied published catalog.
713
-
714
- ```hsx expect=HSX1018
715
- program catalog_probe "Catalog probe"
716
- use missing
717
- ```
718
-
719
- ## HSX1020: Invalid public action name
720
-
721
- Stage: `typecheck`
722
-
723
- Fix: Expose each action once under a distinct lower camelCase name.
724
-
725
- No source-only witness exists. This refusal requires a compiler-host published catalog.
726
-
727
- ## HSX1021: Invalid exposed action
728
-
729
- Stage: `typecheck`
730
-
731
- Fix: Expose an action on an explicitly used published instrument.
732
-
733
- No source-only witness exists. This refusal requires a compiler-host published catalog.
734
-
735
- ## HSX1022: Authored instrument collides with published catalog
736
-
737
- Stage: `typecheck`
738
-
739
- Fix: Rename the authored instrument to avoid colliding with published catalog instruments.
740
-
741
- No source-only witness exists. This refusal requires a compiler-host published catalog.
742
-
743
- ## HSX1023: Invalid required-field list
744
-
745
- Stage: `typecheck`
746
-
747
- Fix: List declared, non-optional field names once each.
748
-
749
- ```hsx expect=HSX1023
750
- program catalog_probe "Catalog probe"
751
- instrument probe {
752
- agent_description: "Probe instrument for catalog diagnostics.";
753
- fields { }
754
- lifecycle { states created; initial created; }
755
- action create {
756
- agent_description: "Create a probe instance.";
757
- steps: [];
758
- }
759
- required: missing;
760
- }
761
- ```
762
-
763
- ## HSX1024: Decision party has no matching account binding
764
-
765
- Stage: `typecheck`
766
-
767
- Fix: Bind the allowed party to an account field and use that binding in the decision action.
768
-
769
- ```hsx expect=HSX1024
770
- program decision_binding "Decision binding"
771
- party buyer: person
772
- party seller: business
773
- port approve { allowed: [buyer] }
774
- instrument gated(decision: condition) {
775
- fields {}
776
- parties { payer: seller }
777
- lifecycle { states created done; initial created; on approve: created -> done; }
778
- action create { steps: []; }
779
- action [decision] { steps: []; port { allowed_parties: [payer]; } }
780
- }
781
- instrument gate = gated(decision: port approve)
782
- ```
783
-
784
- ## HSX1025: Unknown decision port shape type
785
-
786
- Stage: `typecheck`
787
-
788
- Fix: Declare the shape field as text, money(CUR), date, integer, boolean, account(CUR), ref<instrument_id>, id(instrument_id), bps, or percent.
789
-
790
- ```hsx expect=HSX1025
791
- program catalog_probe "Catalog probe"
792
- import { security_deposit } from "std/money_flows"
793
- party buyer: person
794
- party seller: business
795
- settlement hold = security_deposit {
796
- payer: buyer
797
- holder: seller
798
- amount: depositAmount: money(SAR)
799
- claim: port report_damage
800
- claim_amount: { field: damageAmount, bound: depositAmount, remainder: return }
801
- return: port pass_inspection
802
- }
803
- port report_damage { allowed: [seller] shape { damageAmount: money(SAR) } }
804
- port pass_inspection { allowed: [seller] shape { invalidField: mystery_type } }
805
- ```
806
-
807
- ## HSX1026: Decision port input type mismatch with instrument capture field
808
-
809
- Stage: `typecheck`
810
-
811
- Fix: Declare the decision port input field with the type expected by the instrument capture field.
812
-
813
- No source-only witness exists. This refusal requires a compiler-host published catalog.
814
-
815
- ## HSX1101: Currency mismatch
816
-
817
- Stage: `typecheck`
818
-
819
- Fix: Use the declared currency because money values never coerce.
820
-
821
- ```hsx expect=HSX1101
822
- program catalog_probe "Catalog probe"
823
- instrument probe {
824
- agent_description: "Probe instrument for catalog diagnostics.";
825
- fields { }
826
- lifecycle { states created; initial created; }
827
- action create {
828
- agent_description: "Create a probe instance.";
829
- steps: [];
830
- }
831
-
832
- }
833
- const fee: money<SAR> = USD 1.00
834
- ```
835
-
836
- ## HSX1102: Money precision exceeds minor units
837
-
838
- Stage: `typecheck`
839
-
840
- Fix: Round the literal to the currency's minor-unit precision.
841
-
842
- ```hsx expect=HSX1102
843
- program catalog_probe "Catalog probe"
844
- instrument probe {
845
- agent_description: "Probe instrument for catalog diagnostics.";
846
- fields { }
847
- lifecycle { states created; initial created; }
848
- action create {
849
- agent_description: "Create a probe instance.";
850
- steps: [];
851
- }
852
-
853
- }
854
- const fee: money<SAR> = SAR 1.001
855
- ```
856
-
857
- ## HSX1103: Invalid numeric value
858
-
859
- Stage: `typecheck`
860
-
861
- Fix: Use an integer, percent, bps, or valid fixed-money binding.
862
-
863
- ```hsx expect=HSX1103
864
- program catalog_probe "Catalog probe"
865
- instrument probe {
866
- agent_description: "Probe instrument for catalog diagnostics.";
867
- fields { }
868
- lifecycle { states created; initial created; }
869
- action create {
870
- agent_description: "Create a probe instance.";
871
- steps: [];
872
- }
873
- summary: 1.5;
874
- }
875
- ```
876
-
877
- ## HSX1104: Value has the wrong type
878
-
879
- Stage: `typecheck`
880
-
881
- Fix: Pass the type declared by the parameter or UDL slot.
882
-
883
- ```hsx expect=HSX1104
884
- program catalog_probe "Catalog probe"
885
- instrument probe {
886
- agent_description: "Probe instrument for catalog diagnostics.";
887
- fields { }
888
- lifecycle { states created; initial created; }
889
- action create {
890
- agent_description: "Create a probe instance.";
891
- steps: [];
892
- }
893
- summary: money(SAR, 2500);
894
- }
895
- ```
896
-
897
- ## HSX1105: allow_zero needs a money field
898
-
899
- Stage: `typecheck`
900
-
901
- Fix: Put allow_zero: true on a money field, or remove it; amounts are strictly positive unless a money field opts in.
902
-
903
- ```hsx expect=HSX1105
904
- program catalog_probe "Catalog probe"
905
- instrument probe {
906
- agent_description: "Probe instrument for catalog diagnostics.";
907
- fields { memo { type: text; allow_zero: true; } }
908
- lifecycle { states created; initial created; }
909
- action create {
910
- agent_description: "Create a probe instance.";
911
- steps: [];
912
- }
913
-
914
- }
915
- ```
916
-
917
- ## HSX1110: Unsupported parameter combination
918
-
919
- Stage: `typecheck`
920
-
921
- Fix: Choose a supported compile-time parameter combination.
922
-
923
- ```hsx expect=HSX1110
924
- program catalog_probe "Catalog probe"
925
- export instrument template() {
926
- unsupported { message: "Not supported"; fix: "Choose another form"; }
927
- fields {}
928
- lifecycle { states created; initial created; }
929
- action create { steps: []; }
930
- }
931
- instrument probe = template()
932
- ```
933
-
934
- ## HSX1201: Linear money consumed more than once
935
-
936
- Stage: `typecheck`
937
-
938
- Fix: Leave exactly one sink for each produced money value.
939
-
940
- ```hsx expect=HSX1201
941
- program catalog_probe "Catalog probe"
942
- instrument probe {
943
- agent_description: "Probe instrument for catalog diagnostics.";
944
- fields { }
945
- lifecycle { states created; initial created; }
946
- action create {
947
- agent_description: "Create a probe instance.";
948
- steps: [];
949
- }
950
- fields { amount: money<SAR>; }
951
- action pay { computes remainder rest { amount_ref: total; on_zero: refuse; total_path: fields.amount; }; moves: [{ amount: rest; }, { amount: rest; }]; }
952
- }
953
- ```
954
-
955
- ## HSX1202: Linear money is unconsumed
956
-
957
- Stage: `typecheck`
958
-
959
- Fix: Route each produced money value to one explicit sink.
960
-
961
- ```hsx expect=HSX1202
962
- program catalog_probe "Catalog probe"
963
- instrument probe {
964
- agent_description: "Probe instrument for catalog diagnostics.";
965
- fields { }
966
- lifecycle { states created; initial created; }
967
- action create {
968
- agent_description: "Create a probe instance.";
969
- steps: [];
970
- }
971
- fields { amount: money<SAR>; }
972
- action pay { computes remainder rest { amount_ref: total; on_zero: refuse; total_path: fields.amount; }; }
973
- }
974
- ```
975
-
976
- ## HSX1301: Missing cost-table price
977
-
978
- Stage: `typecheck`
979
-
980
- Fix: Supply a versioned cost table with a row for every emitted effect.
981
-
982
- ```hsx expect=HSX1301
983
- program catalog_probe "Catalog probe"
984
- instrument probe {
985
- agent_description: "Probe instrument for catalog diagnostics.";
986
- fields { }
987
- lifecycle { states created; initial created; }
988
- action create {
989
- agent_description: "Create a probe instance.";
990
- steps: [];
991
- }
992
-
993
- }
994
- ```
995
-
996
- ## HSX1302: Invalid cost-table row
997
-
998
- Stage: `typecheck`
999
-
1000
- Fix: Use non-negative integer prices and a supported settlement timing.
1001
-
1002
- No source-only witness exists. This refusal requires a malformed compiler-host cost table.
1003
-
1004
- ## HSX1303: Invalid cost-table currency
1005
-
1006
- Stage: `typecheck`
1007
-
1008
- Fix: Use the supported uppercase cost-table currency.
1009
-
1010
- No source-only witness exists. This refusal requires an invalid compiler-host cost-table currency.
1011
-
1012
- ## HSX1304: Unpriced ledger currency
1013
-
1014
- Stage: `typecheck`
1015
-
1016
- Fix: Move money in a currency the shipped cost tables price.
1017
-
1018
- ```hsx expect=HSX1304
1019
- program catalog_probe "Catalog probe"
1020
- instrument probe {
1021
- agent_description: "Probe instrument for catalog diagnostics.";
1022
- fields { amount: money<JPY>; }
1023
- lifecycle { states created; initial created; }
1024
- action create {
1025
- agent_description: "Create a probe instance.";
1026
- steps: [];
1027
- }
1028
-
1029
- }
1030
- ```
1031
-
1032
- ## HSX1305: More than one ledger currency
1033
-
1034
- Stage: `typecheck`
1035
-
1036
- Fix: Move all money in one currency; a program bills in one ledger currency.
1037
-
1038
- ```hsx expect=HSX1305
1039
- program catalog_probe "Catalog probe"
1040
- instrument probe {
1041
- agent_description: "Probe instrument for catalog diagnostics.";
1042
- fields { amount: money<SAR>; fee: money<USD>; }
1043
- lifecycle { states created; initial created; }
1044
- action create {
1045
- agent_description: "Create a probe instance.";
1046
- steps: [];
1047
- }
1048
-
1049
- }
1050
- ```
1051
-
1052
- ## HSX1306: Fixed-currency amount moved in another currency
1053
-
1054
- Stage: `typecheck`
1055
-
1056
- Fix: Bind the currency of a money<CUR> move or account step as the constant CUR; the compiler pins a binding that reads the instrument's currency field.
1057
-
1058
- ```hsx expect=HSX1306
1059
- program catalog_probe "Catalog probe"
1060
- instrument probe {
1061
- agent_description: "Probe instrument for catalog diagnostics.";
1062
- fields { amount: money<SAR>; payeeAccountId: account<SAR>; payerAccountId: account<SAR>; }
1063
- lifecycle { states created; initial created; }
1064
- action create {
1065
- agent_description: "Create a probe instance.";
1066
- steps: [];
1067
- }
1068
- action pay { agent_description: "Pay the amount."; moves: [{ "bind": { "amount": { "from": "instance"; "path": "fields.amount"; }; "currency": { "from": "const"; "value": "USD"; }; "destinationAccountId": { "from": "instance"; "path": "fields.payeeAccountId"; }; "sourceAccountId": { "from": "instance"; "path": "fields.payerAccountId"; }; }; "key": "transfer"; "operation": "internal_transfer.create"; }]; steps: []; }
1069
- }
1070
- ```
1071
-
1072
- ## HSX1401: Unbounded action
1073
-
1074
- Stage: `typecheck`
1075
-
1076
- Fix: Replace runtime iteration with a bounded compile-time comprehension.
1077
-
1078
- ```hsx expect=HSX1401
1079
- program catalog_probe "Catalog probe"
1080
- instrument probe {
1081
- agent_description: "Probe instrument for catalog diagnostics.";
1082
- fields { }
1083
- lifecycle { states created; initial created; }
1084
- action create {
1085
- agent_description: "Create a probe instance.";
1086
- steps: [];
1087
- }
1088
- action run { while { condition: true; }; }
1089
- }
1090
- ```
1091
-
1092
- ## HSX1402: Missing lifecycle
1093
-
1094
- Stage: `typecheck`
1095
-
1096
- Fix: Declare lifecycle states and an initial state.
1097
-
1098
- ```hsx expect=HSX1402
1099
- program catalog_probe "Catalog probe"
1100
- instrument probe { fields {}; action create { steps: []; }; }
1101
- ```
1102
-
1103
- ## HSX1403: Runtime comprehension bound
1104
-
1105
- Stage: `typecheck`
1106
-
1107
- Fix: Use an integer literal or literal finite list as the bound.
1108
-
1109
- ```hsx expect=HSX1403
1110
- program catalog_probe "Catalog probe"
1111
- export instrument template(count: integer) {
1112
- fields {}
1113
- lifecycle { states created; initial created; }
1114
- action create { steps: []; }
1115
- for item in count { action run_[item] { steps: []; } }
1116
- }
1117
- instrument probe = template(count: runtimeCount: integer)
1118
- ```
1119
-
1120
- ## HSX1404: Comprehension expansion limit
1121
-
1122
- Stage: `typecheck`
1123
-
1124
- Fix: Reduce the fixed expansion to the compiler limit.
1125
-
1126
- ```hsx expect=HSX1404
1127
- program catalog_probe "Catalog probe"
1128
- instrument probe {
1129
- agent_description: "Probe instrument for catalog diagnostics.";
1130
- fields { }
1131
- lifecycle { states created; initial created; }
1132
- action create {
1133
- agent_description: "Create a probe instance.";
1134
- steps: [];
1135
- }
1136
- for item in 257 { action run_[item] { steps: []; } }
1137
- }
1138
- ```
1139
-
1140
- ## HSX1405: Invalid compile-time selection
1141
-
1142
- Stage: `typecheck`
1143
-
1144
- Fix: Give compile-time conditions and unsupported branches fixed blocks.
1145
-
1146
- ```hsx expect=HSX1405
1147
- program catalog_probe "Catalog probe"
1148
- export instrument template() { unsupported: true; fields {}; lifecycle { states created; initial created; }; action create { steps: []; }; }
1149
- instrument probe = template()
1150
- ```
1151
-
1152
- ## HSX1406: Invalid companion instrument
1153
-
1154
- Stage: `typecheck`
1155
-
1156
- Fix: Construct each companion with a compile-time id.
1157
-
1158
- ```hsx expect=HSX1406
1159
- program catalog_probe "Catalog probe"
1160
- export instrument template() {
1161
- fields {}
1162
- lifecycle { states created; initial created; }
1163
- action create { steps: []; }
1164
- instruments { invalid: true; }
1165
- }
1166
- instrument probe = template()
1167
- ```
1168
-
1169
- ## HSX1501: Unknown UDL clause
1170
-
1171
- Stage: `typecheck`
1172
-
1173
- Fix: Use a clause exported by the targeted UDL vocabulary.
1174
-
1175
- ```hsx expect=HSX1501
1176
- program catalog_probe "Catalog probe"
1177
- instrument probe {
1178
- agent_description: "Probe instrument for catalog diagnostics.";
1179
- fields { }
1180
- lifecycle { states created; initial created; }
1181
- action create {
1182
- agent_description: "Create a probe instance.";
1183
- steps: [];
1184
- }
1185
- unknown_clause: true;
1186
- }
1187
- ```
1188
-
1189
- ## HSX1502: Program emits no instruments
1190
-
1191
- Stage: `typecheck`
1192
-
1193
- Fix: Declare or instantiate at least one instrument.
1194
-
1195
- ```hsx expect=HSX1502
1196
- program catalog_probe "Catalog probe"
1197
- ```
1198
-
1199
- ## HSX1503: Missing fields block
1200
-
1201
- Stage: `typecheck`
1202
-
1203
- Fix: Add a fields block, even when it is empty.
1204
-
1205
- ```hsx expect=HSX1503
1206
- program catalog_probe "Catalog probe"
1207
- instrument probe { lifecycle { states created; initial created; }; action create { steps: []; }; }
1208
- ```
1209
-
1210
- ## HSX1504: Missing create action
1211
-
1212
- Stage: `typecheck`
1213
-
1214
- Fix: Add an action create block.
1215
-
1216
- ```hsx expect=HSX1504
1217
- program catalog_probe "Catalog probe"
1218
- instrument probe { fields {}; lifecycle { states created; initial created; }; }
1219
- ```
1220
-
1221
- ## HSX1505: Repeated single-valued clause
1222
-
1223
- Stage: `typecheck`
1224
-
1225
- Fix: Keep one occurrence of the clause.
1226
-
1227
- ```hsx expect=HSX1505
1228
- program catalog_probe "Catalog probe"
1229
- instrument probe {
1230
- agent_description: "Probe instrument for catalog diagnostics.";
1231
- fields { }
1232
- lifecycle { states created; initial created; }
1233
- action create {
1234
- agent_description: "Create a probe instance.";
1235
- steps: [];
1236
- }
1237
- title: "First"; title: "Second";
1238
- }
1239
- ```
1240
-
1241
- ## HSX1506: Conflicting public action settings
1242
-
1243
- Stage: `typecheck`
1244
-
1245
- Fix: Keep either public: none or a public action name.
1246
-
1247
- ```hsx expect=HSX1506
1248
- program catalog_probe "Catalog probe"
1249
- instrument probe {
1250
- agent_description: "Probe instrument for catalog diagnostics.";
1251
- fields { }
1252
- lifecycle { states created; initial created; }
1253
- action create {
1254
- agent_description: "Create a probe instance.";
1255
- steps: [];
1256
- }
1257
- action finish { public: none; public_action: finishProbe; steps: []; }
1258
- }
1259
- ```
1260
-
1261
- ## HSX1507: Invalid application metadata
1262
-
1263
- Stage: `typecheck`
1264
-
1265
- Fix: Keep contract mechanics in the parameterized instrument.
1266
-
1267
- ```hsx expect=HSX1507
1268
- program catalog_probe "Catalog probe"
1269
- export instrument template() { fields {}; lifecycle { states created; initial created; }; action create { steps: []; }; }
1270
- instrument probe = template() { fields: {}; }
1271
- ```
1272
-
1273
- ## HSX1508: Invalid action-level port syntax
1274
-
1275
- Stage: `typecheck`
1276
-
1277
- Fix: Use allowed_parties: [...] inside an action-level port clause; allowed: is for top-level port declarations.
1278
-
1279
- ```hsx expect=HSX1508
1280
- program catalog_probe "Catalog probe"
1281
- party approver: person
1282
- instrument probe {
1283
- fields {}
1284
- lifecycle { states created; initial created; }
1285
- action create {
1286
- steps: [];
1287
- port { allowed: [approver]; }
1288
- }
1289
- }
1290
- ```
1291
-
1292
- ## HSX1509: Callable action without an agent description
1293
-
1294
- Stage: `typecheck`
1295
-
1296
- Fix: Add agent_description: "..." to the instrument and to every action a caller can reach; composer.check refuses the program without them.
1297
-
1298
- ```hsx expect=HSX1509
1299
- program catalog_probe "Catalog probe"
1300
- instrument probe {
1301
- fields {}
1302
- lifecycle { states created; initial created; }
1303
- action create { steps: []; }
1304
- }
1305
- ```
1306
-
1307
- ## HSX1601: Invalid UDL shape
1308
-
1309
- Stage: `lower`
1310
-
1311
- Fix: Correct the named clause so it matches the targeted UDL definition.
1312
-
1313
- No source-only witness exists. Typed source cannot bypass the checker to emit an invalid UDL shape.
1314
-
1315
- ## HSX1602: Invalid UDL semantics
1316
-
1317
- Stage: `lower`
1318
-
1319
- Fix: Correct the named clause so it satisfies the targeted UDL law.
1320
-
1321
- No source-only witness exists. Typed source cannot bypass the checker to emit invalid UDL semantics.
1322
-
1323
- ## HSX1603: Unresolved compiler marker
1324
-
1325
- Stage: `lower`
1326
-
1327
- Fix: Correct compile-time block keys or parameter bindings.
1328
-
1329
- ```hsx expect=HSX1603
1330
- program catalog_probe "Catalog probe"
1331
- instrument probe {
1332
- agent_description: "Probe instrument for catalog diagnostics.";
1333
- fields { }
1334
- lifecycle { states created; initial created; }
1335
- action create {
1336
- agent_description: "Create a probe instance.";
1337
- steps: [];
1338
- }
1339
- title: "__hsx_none__";
1340
- }
1341
- ```
1342
-
1343
- ## HSX1610: Invalid piece partition
1344
-
1345
- Stage: `typecheck`
1346
-
1347
- Fix: Bind immutable money and account fields to one declared partition.
1348
-
1349
- No source-only witness exists. The shared UDL action-plan validator supplies the code and source path.
1350
-
1351
- ## HSX1611: Invalid piece stage
1352
-
1353
- Stage: `typecheck`
1354
-
1355
- Fix: Use a declared piece stage and let the compiler derive pieceId.
1356
-
1357
- No source-only witness exists. The shared UDL action-plan validator supplies the code and source path.
1358
-
1359
- ## HSX1612: Invalid action graph
1360
-
1361
- Stage: `typecheck`
1362
-
1363
- Fix: Declare an acyclic action graph within the expansion bound.
1364
-
1365
- No source-only witness exists. The shared UDL action-plan validator supplies the code and source path.
1366
-
1367
- ## HSX1613: Invalid static call binding
1368
-
1369
- Stage: `typecheck`
1370
-
1371
- Fix: Bind declared typed targets with unique captures and money consumption.
1372
-
1373
- No source-only witness exists. The shared UDL action-plan validator supplies the code and source path.
1374
-
1375
- ## HSX1614: Incompatible action boundary
1376
-
1377
- Stage: `typecheck`
1378
-
1379
- Fix: Keep the parent principal, approval and recovery boundary.
1380
-
1381
- No source-only witness exists. The shared UDL action-plan validator supplies the code and source path.
1382
-
1383
- ## HSX1615: Invalid leaf evidence or effects
1384
-
1385
- Stage: `typecheck`
1386
-
1387
- Fix: Declare evidence and the exact effects of each expanded leaf.
1388
-
1389
- No source-only witness exists. The shared UDL action-plan validator supplies the code and source path.
1390
-
1391
- # Grammar vocabulary
1392
-
1393
- The parser is hand-written. This page records the exported lexer vocabulary, the UDL clause vocabulary it binds, and the current standard-library module names.
1394
-
1395
- ## Keywords
1396
-
1397
- `action`, `as`, `asset`, `commit`, `const`, `expect`, `expose`, `expires`, `export`, `from`, `import`, `instrument`, `module`, `party`, `port`, `program`, `quote`, `rate`, `reconcile`, `settlement`, `subject`, `type`, `use`
1398
-
1399
- ## Punctuation
1400
-
1401
- `{`, `}`, `(`, `)`, `[`, `]`, `:`, `,`, `;`, `=`, `|`, `.`, `<`, `>`, `?` and `->`
1402
-
1403
- ## Typed clause spellings
1404
-
1405
- `funding`, `receipt distribution`, `requires allocation`, `allocation`, `contributions`, `allocate`, `contribution stage`, `date order`, `unique`, `transitions refs`, `cascade`, `action library`, `agent description`, `calls`, `requires input`, `engine owned`, `capture engine`, `capture input`, `commit`, `quote`, `decided amount`, `deadline`, `decision`, `computes distribute`, `description`, `due`, `earnable`, `event name`, `examples`, `input`, `moves`, `payout`, `piece plan`, `piece stage`, `port`, `principal`, `public action`, `reconcile`, `computes remainder`, `requires aggregate`, `requires checks`, `requires drained`, `requires exposure`, `requires refs`, `sandbox failure point`, `sets at`, `computes signed_sum`, `steps`, `summary`, `updates`, `notify`, `agent description`, `aggregate invariants`, `caller parked states`, `description`, `dials`, `distinct parties`, `computes derived`, `computes fees`, `id prefix`, `nav`, `partitions`, `subject`, `summary`, `surface visibility`, `template binding`, `template id`, `title`, `update`, `request authority`
1406
-
1407
- ## Standard-library modules
1408
-
1409
- - `advance`
1410
- - `cancellable_booking`
1411
- - `captured_payment`
1412
- - `conditional_disbursement`
1413
- - `credit_facility`
1414
- - `held_payment`
1415
- - `instant_transfer`
1416
- - `metered`
1417
- - `pooled_split`
1418
- - `premium_forward`
1419
- - `reconciled_payout`
1420
- - `rotating_pool`
1421
- - `scheduled`
1422
- - `security_deposit`
1423
- - `settlement_batch`
1424
- - `swap`
1425
- - `threshold_pool`
1426
- - `weighted_distribution`
1427
-
1428
- # advance
1429
-
1430
- Source: [`std/money_flows/advance.hsx`](../../../std/money_flows/advance.hsx)
1431
-
1432
- ## Export
1433
-
1434
- `advance<C>`
1435
-
1436
- ## Parameters
1437
-
1438
- | Parameter | Type | Required | Meaning |
1439
- | --- | --- | --- | --- |
1440
- | `funder` | `party` | Yes | The party providing the upfront capital. |
1441
- | `to` | `party` | Yes | The party receiving the advance and responsible for repayment. |
1442
- | `amount` | `money<C>` | Yes | Total advanced principal in minor units of currency `C`. |
1443
- | `fee` | `optional<percent>` | No | Optional markup percentage fee charged on the advance (basis points precision). |
1444
- | `count` | `optional<integer>` | No | Optional number of scheduled installment repayments. |
1445
- | `every` | `optional<text>` | No | Optional recurrence duration between installments (e.g. `"P30D"`). |
1446
- | `first_due` | `optional<date>` | No | Optional date for the first installment repayment. |
1447
- | `against` | `optional<ref>` | No | Optional reference to a hold instrument whose release will be carved to repay the advance. |
1448
- | `repayment_source` | `optional<party>` | No | Optional party repaying when distinct from the capital recipient. |
1449
- | `profit_to` | `optional<party>` | No | Optional recipient of profit, separated from principal repayments. |
1450
- | `dated` | `optional<boolean>` | No | Require an explicit signed date for each repayment instead of duration offsets. |
1451
-
1452
- Required means required by the template signature. A selected mode may also need parameters marked optional; the guidance below describes those combinations.
1453
-
1454
- ## Module guidance
1455
-
1456
- Upfront capital disbursement repaid by carving future held payment releases or over scheduled installments.
1457
-
1458
- ### Purpose
1459
-
1460
- `advance` provides working capital, merchant cash advances, or contractor pre-funding from a funder to a recipient.
1461
- Repayment occurs either automatically by intercepting (carving) releases from a linked escrow hold (`against`),
1462
- or over calendar-anchored installment repayments (`count`, `every`, `first_due`).
1463
-
1464
- ### Selection guidance
1465
-
1466
- - vs `credit_facility`: `advance` disburses a single upfront lump-sum principal that is repaid over time.
1467
- `credit_facility` establishes a reusable revolving credit line with multiple draws up to a limit,
1468
- where repayments restore available borrowing capacity.
1469
- - vs `conditional_disbursement`: `advance` expects repayment of the advanced principal plus optional fees.
1470
- `conditional_disbursement` disburses non-repayable grants, claims, or milestone payments against external evidence.
1471
- - vs `held_payment`: `held_payment` holds customer funds in escrow until delivery. An `advance` can carve repayments
1472
- directly out of a `held_payment`'s release using `against`.
1473
-
1474
- ### Parameters
1475
-
1476
- - `funder`: The party providing the upfront capital.
1477
- - `to`: The party receiving the advance and responsible for repayment.
1478
- - `amount`: Total advanced principal in minor units of currency `C`.
1479
- - `fee`: Optional markup percentage fee charged on the advance (basis points precision).
1480
- - `count`: Optional number of scheduled installment repayments.
1481
- - `every`: Optional recurrence duration between installments (e.g. `"P30D"`).
1482
- - `first_due`: Optional date for the first installment repayment.
1483
- - `repayment_source`: Optional party repaying when distinct from the capital recipient.
1484
- - `profit_to`: Optional recipient of profit, separated from principal repayments.
1485
- - `dated`: Require an explicit signed date for each repayment instead of duration offsets.
1486
- - `against`: Optional reference to a hold instrument whose release will be carved to repay the advance.
1487
-
1488
- ### Decision ports
1489
-
1490
- None. Repayment is driven by linked hold releases or scheduled calendar dates.
1491
-
1492
- ### Example
1493
-
1494
- ```hsx
1495
- program advance_example "Advance example"
1496
- import { advance } from "std/money_flows"
1497
- party funder: business
1498
- party recipient: business
1499
- settlement advance_payment = advance {
1500
- funder: funder
1501
- to: recipient
1502
- amount: principal: money(SAR)
1503
- fee: 2.5%
1504
- count: 2
1505
- every: P30D
1506
- first_due: firstDueAt
1507
- }
1508
- ```
1509
-
1510
- ## Declared clauses
1511
-
1512
- - `agent description`
1513
- - `description`
1514
- - `due`
1515
- - `id prefix`
1516
- - `moves`
1517
- - `partitions`
1518
- - `steps`
1519
- - `summary`
1520
- - `title`
1521
-
1522
- This inventory covers all branches and nested instruments in the module. The selected parameters determine which clauses and actions the compiler emits. Indexed action names expand over the declared finite list.
1523
-
1524
- ## Decision ports
1525
-
1526
- None.
1527
-
1528
- ## Actions and clauses
1529
-
1530
- | Action | Clauses lowered |
1531
- | --- | --- |
1532
- | `create` | `agent description`, `moves`, `steps`, `summary` |
1533
- | `disburse` | `agent description`, `moves`, `steps`, `summary` |
1534
- | `settle` | `agent description`, `moves`, `steps`, `summary` |
1535
- | `create` | `agent description`, `moves`, `steps`, `summary` |
1536
- | `disburse` | `agent description`, `moves`, `steps`, `summary` |
1537
- | `collect_repayment_[i]` | `agent description`, `due`, `moves`, `steps`, `summary` |
1538
-
1539
- # cancellable_booking
1540
-
1541
- Source: [`std/money_flows/cancellable_booking.hsx`](../../../std/money_flows/cancellable_booking.hsx)
1542
-
1543
- ## Export
1544
-
1545
- `cancellable_booking<C>`
1546
-
1547
- ## Parameters
1548
-
1549
- | Parameter | Type | Required | Meaning |
1550
- | --- | --- | --- | --- |
1551
- | `guest` | `optional<party>` | No | The booking customer paying the fee and receiving refunds. |
1552
- | `host` | `optional<party>` | No | The service provider receiving the payout or retained cancellation penalty. |
1553
- | `amount` | `optional<money<C>>` | No | Total booking price in minor units of currency `C`. |
1554
- | `starts_at` | `optional<date>` | No | Stored ISO 8601 date when the booking begins. |
1555
- | `late_penalty_bps` | `optional<integer>` | No | Penalty in basis points applied when cancelling within the late window. |
1556
- | `late_within` | `optional<text>` | No | ISO 8601 duration defining the late window before `starts_at` (e.g. `"P2D"` for 2 days). |
1557
- | `early_penalty_bps` | `optional<integer>` | No | Penalty in basis points applied when cancelling before the late window. |
1558
- | `offer_life` | `optional<text>` | No | ISO 8601 duration defining how long a quoted cancellation offer remains valid (e.g. `"PT30M"`). |
1559
- | `cancel_bands` | `optional<list<block>>` | No | Supply cancel_bands to select deposit/balance custody instead of quoted cancellation. |
1560
- | `price_value` | `optional<text>` | No | price_value and supplier_cost fix the price; deposit_bps derives the deposit. |
1561
- | `supplier_cost` | `optional<text>` | No | price_value and supplier_cost fix the price; deposit_bps derives the deposit. |
1562
- | `departure` | `optional<text>` | No | balance_before and confirmation_window are positive fixed durations relative to departure. |
1563
- | `balance_before` | `optional<text>` | No | balance_before and confirmation_window are positive fixed durations relative to departure. |
1564
- | `confirmation_window` | `optional<text>` | No | balance_before and confirmation_window are positive fixed durations relative to departure. |
1565
- | `unpaid_band` | `optional<integer>` | No | The unpaid_band index selects a retained deposit policy. |
1566
- | `acceptance` | `optional<block>` | No | acceptance optionally supplies an aggregate gate. |
1567
- | `deposit_bps` | `optional<integer>` | No | price_value and supplier_cost fix the price; deposit_bps derives the deposit. |
1568
- | `tax_bps` | `optional<integer>` | No | tax_bps applies to margin after the supplier share. |
1569
- | `authority_type` | `optional<text>` | No | authority_type and supplier_role bind release to a consumed confirmation decision. |
1570
- | `supplier_role` | `optional<text>` | No | authority_type and supplier_role bind release to a consumed confirmation decision. |
1571
- | `collects` | `optional<json>` | No | collects optionally cascades named actions to linked instruments on deposit. |
1572
-
1573
- Required means required by the template signature. A selected mode may also need parameters marked optional; the guidance below describes those combinations.
1574
-
1575
- ## Module guidance
1576
-
1577
- Time-anchored reservation holding booking funds in escrow with dynamically quoted cancellation penalties.
1578
-
1579
- ### Purpose
1580
-
1581
- `cancellable_booking` holds booking fees in escrow from a guest for a host until a scheduled start date.
1582
- It fits hospitality, travel reservations, studio rentals, event tickets, and appointments where guests
1583
- can cancel prior to start, but cancellation penalties depend on how close to the start date cancellation occurs.
1584
-
1585
- ### Selection guidance
1586
-
1587
- - vs `held_payment`: Both hold money in escrow and both quote a cancellation before it is spent.
1588
- `cancellable_booking` prices the penalty against the time left before `starts_at`, so the charge moves
1589
- as the start approaches; `held_payment` has no start date and quotes one flat charge.
1590
- Choose `cancellable_booking` whenever cancellation fees are time-sensitive.
1591
- - vs `security_deposit`: `security_deposit` holds funds to cover damages claimed by the holder.
1592
- `cancellable_booking` holds the service fee itself and releases to the host upon `starts_at` or refunds net of penalty.
1593
-
1594
- ### Parameters
1595
-
1596
- - `guest`: The booking customer paying the fee and receiving refunds.
1597
- - `host`: The service provider receiving the payout or retained cancellation penalty.
1598
- - `amount`: Total booking price in minor units of currency `C`.
1599
- - `starts_at`: Stored ISO 8601 date when the booking begins.
1600
- - `late_penalty_bps`: Penalty in basis points applied when cancelling within the late window.
1601
- - `late_within`: ISO 8601 duration defining the late window before `starts_at` (e.g. `"P2D"` for 2 days).
1602
- - `early_penalty_bps`: Penalty in basis points applied when cancelling before the late window.
1603
- - `offer_life`: ISO 8601 duration defining how long a quoted cancellation offer remains valid (e.g. `"PT30M"`).
1604
-
1605
- ### Decision ports
1606
-
1607
- None. Action transitions are driven by guest API calls (`take`, `cancel`, `confirm`) and scheduled completion (`complete` due at `starts_at`).
1608
-
1609
- ### Example
1610
-
1611
- ```hsx
1612
- program studio_booking "Studio booking"
1613
- import { cancellable_booking } from "std/money_flows"
1614
- party guest: person
1615
- party studio: business
1616
- settlement studio_session = cancellable_booking {
1617
- guest: guest
1618
- host: studio
1619
- amount: sessionPrice: money(SAR)
1620
- starts_at: startsAt
1621
- late_penalty_bps: 5000
1622
- late_within: "P2D"
1623
- early_penalty_bps: 1000
1624
- offer_life: "PT30M"
1625
- }
1626
- ```
1627
-
1628
- ### Finite cancellation bands
1629
-
1630
- Supply cancel_bands to select deposit/balance custody instead of quoted cancellation.
1631
- Each band has name, refund (full, balance or none), starts_at after the first band,
1632
- and supplier_bps when money is retained. The unpaid_band index selects a retained
1633
- deposit policy. Omit it to return the deposit; a full-refund band also returns it. price_value and supplier_cost fix the price; deposit_bps derives
1634
- the deposit. balance_before and confirmation_window are positive fixed durations
1635
- relative to departure. tax_bps applies to margin after the supplier share.
1636
- authority_type and supplier_role bind release to a consumed confirmation decision.
1637
- collects optionally cascades named actions to linked instruments on deposit.
1638
- acceptance optionally supplies an aggregate gate. All actions are private until
1639
- expose selects them. Ordered band starts and deadlines prevent a late sweep from
1640
- extending an earlier band's cancellation rights. Full timeout refund returns price.
1641
- Seven derivations suffice for three bands; larger finite policies use up to the
1642
- UDL bound of 64 derived amounts. shift_date(date, duration, "before") subtracts a
1643
- fixed duration; omitting the direction adds it. Invalid dates or durations refuse.
1644
-
1645
- ## Declared clauses
1646
-
1647
- - `agent description`
1648
- - `caller parked states`
1649
- - `cascade`
1650
- - `commit`
1651
- - `deadline`
1652
- - `description`
1653
- - `distinct parties`
1654
- - `due`
1655
- - `id prefix`
1656
- - `input`
1657
- - `moves`
1658
- - `partitions`
1659
- - `port`
1660
- - `quote`
1661
- - `requires drained`
1662
- - `sandbox failure point`
1663
- - `steps`
1664
- - `summary`
1665
- - `title`
1666
- - `unique`
1667
- - `updates`
1668
-
1669
- This inventory covers all branches and nested instruments in the module. The selected parameters determine which clauses and actions the compiler emits. Indexed action names expand over the declared finite list.
1670
-
1671
- ## Decision ports
1672
-
1673
- None.
1674
-
1675
- ## Actions and clauses
1676
-
1677
- | Action | Clauses lowered |
1678
- | --- | --- |
1679
- | `create` | `agent description`, `moves`, `steps`, `summary` |
1680
- | `take` | `agent description`, `moves`, `sandbox failure point`, `steps`, `summary` |
1681
- | `complete` | `due`, `moves`, `steps`, `summary` |
1682
- | `cancel` | `agent description`, `moves`, `quote`, `steps`, `summary` |
1683
- | `confirm` | `agent description`, `commit`, `moves`, `steps`, `summary` |
1684
- | `retain` | `agent description`, `moves`, `steps`, `summary` |
1685
- | `create` | `agent description`, `deadline`, `steps`, `unique` |
1686
- | `deposit` | `agent description`, `cascade`, `deadline`, `moves`, `port`, `steps` |
1687
- | `expire` | `agent description`, `due`, `requires drained`, `steps` |
1688
- | `[balance_action]` | `agent description`, `deadline`, `moves`, `port`, `steps` |
1689
- | `[open_action]` | `agent description`, `due`, `steps` |
1690
- | `[cancel_action]` | `agent description`, `deadline`, `moves`, `port`, `steps` |
1691
- | `cancel_unpaid` | `agent description`, `due`, `moves`, `steps` |
1692
- | `await_confirmation` | `agent description`, `due`, `steps` |
1693
- | `confirm` | `agent description`, `deadline`, `input`, `steps`, `updates` |
1694
- | `release` | `agent description`, `moves`, `steps` |
1695
- | `refund_unconfirmed` | `agent description`, `due`, `moves`, `steps` |
1696
-
1697
- # captured_payment
1698
-
1699
- Source: [`std/money_flows/captured_payment.hsx`](../../../std/money_flows/captured_payment.hsx)
1700
-
1701
- ## Export
1702
-
1703
- `captured_payment<C>`
1704
-
1705
- ## Parameters
1706
-
1707
- | Parameter | Type | Required | Meaning |
1708
- | --- | --- | --- | --- |
1709
- | `payer` | `party` | Yes | Party whose account balance is reserved during authorization. |
1710
- | `payee` | `party` | Yes | Beneficiary party capturing authorized funds. |
1711
- | `amount` | `money<C>` | Yes | Maximum authorized reservation in minor units of currency `C`. |
1712
- | `reserve_until` | `date` | Yes | Expiration date for the authorization hold. |
1713
- | `correction` | `condition` | Yes | Condition port allowing post-settlement amount corrections. |
1714
- | `external_reversal` | `condition` | Yes | Condition port allowing external processor chargebacks/reversals. |
1715
- | `derived_amount` | `optional<block>` | No | Optional block declaring percentage fee calculation. |
1716
-
1717
- Required means required by the template signature. A selected mode may also need parameters marked optional; the guidance below describes those combinations.
1718
-
1719
- ## Module guidance
1720
-
1721
- Two-phase authorization and capture payment flow for card and merchant processing.
1722
-
1723
- ### Purpose
1724
-
1725
- `captured_payment` reserves funds against a payer's account and allows the payee to capture the authorized
1726
- balance in one or multiple slices before a reservation expiry date (`reserve_until`). It fits ecommerce checkouts,
1727
- card processing, hotel authorizations, and pay-at-pump fuel payments where final amounts vary or settle later.
1728
-
1729
- ### Selection guidance
1730
-
1731
- - vs `instant_transfer`: `instant_transfer` immediately transfers money from payer to payee in a single irreversible
1732
- step without reservation or settlement delays. `captured_payment` separates authorization from capture, allowing
1733
- incremental captures, voids, amount corrections via the `correction` port, and external network reversals via `external_reversal`.
1734
- - vs `held_payment`: `held_payment` holds the full amount in third-party escrow pending release. `captured_payment`
1735
- reserves funds directly on payer balance and settles incrementally directly to payee.
1736
-
1737
- ### Parameters
1738
-
1739
- - `payer`: Party whose account balance is reserved during authorization.
1740
- - `payee`: Beneficiary party capturing authorized funds.
1741
- - `amount`: Maximum authorized reservation in minor units of currency `C`.
1742
- - `reserve_until`: Expiration date for the authorization hold.
1743
- - `correction`: Condition port allowing post-settlement amount corrections.
1744
- - `external_reversal`: Condition port allowing external processor chargebacks/reversals.
1745
- - `derived_amount`: Optional block declaring percentage fee calculation.
1746
-
1747
- ### Decision ports
1748
-
1749
- - `correction`: Condition allowing payee or processor to submit an amount correction after settlement.
1750
- - `external_reversal`: Condition allowing bank or card network to execute an external reversal.
1751
-
1752
- ### Example
1753
-
1754
- ```hsx
1755
- program captured_payment_example "Captured payment example"
1756
- import { captured_payment } from "std/money_flows"
1757
- party payer: person
1758
- party payee: business
1759
- settlement card_payment = captured_payment {
1760
- payer: payer
1761
- payee: payee
1762
- amount: authorizedAmount: money(SAR)
1763
- reserve_until: reserveUntil
1764
- correction: port correct_capture
1765
- external_reversal: port reverse_capture within P14D
1766
- }
1767
- port correct_capture { allowed: [payee] }
1768
- port reverse_capture {
1769
- allowed: [payee]
1770
- shape: { externalReference: text }
1771
- }
1772
- ```
1773
-
1774
- ## Declared clauses
1775
-
1776
- - `agent description`
1777
- - `capture input`
1778
- - `deadline`
1779
- - `description`
1780
- - `due`
1781
- - `input`
1782
- - `moves`
1783
- - `port`
1784
- - `sandbox failure point`
1785
- - `steps`
1786
- - `summary`
1787
- - `title`
1788
-
1789
- This inventory covers all branches and nested instruments in the module. The selected parameters determine which clauses and actions the compiler emits. Indexed action names expand over the declared finite list.
1790
-
1791
- ## Decision ports
1792
-
1793
- - `correction`
1794
- - `external_reversal`
1795
-
1796
- ## Actions and clauses
1797
-
1798
- | Action | Clauses lowered |
1799
- | --- | --- |
1800
- | `create` | `agent description`, `moves`, `steps`, `summary` |
1801
- | `authorize` | `agent description`, `moves`, `sandbox failure point`, `steps`, `summary` |
1802
- | `capture` | `agent description`, `deadline`, `description`, `input`, `moves`, `sandbox failure point`, `steps`, `summary` |
1803
- | `capture_more` | `agent description`, `deadline`, `description`, `input`, `moves`, `steps`, `summary` |
1804
- | `settle` | `agent description`, `deadline`, `moves`, `steps`, `summary` |
1805
- | `void` | `agent description`, `moves`, `steps`, `summary` |
1806
- | `expire` | `due`, `moves`, `steps`, `summary` |
1807
- | `settle_on_expiry` | `due`, `moves`, `steps`, `summary` |
1808
- | `[correction_name]` | `agent description`, `capture input`, `input`, `moves`, `port`, `steps`, `summary` |
1809
- | `[reversal_name]` | `agent description`, `capture input`, `deadline`, `input`, `moves`, `port`, `steps`, `summary` |
1810
-
1811
- # conditional_disbursement
1812
-
1813
- Source: [`std/money_flows/conditional_disbursement.hsx`](../../../std/money_flows/conditional_disbursement.hsx)
1814
-
1815
- ## Export
1816
-
1817
- `conditional_disbursement<C>`
1818
-
1819
- ## Parameters
1820
-
1821
- | Parameter | Type | Required | Meaning |
1822
- | --- | --- | --- | --- |
1823
- | `source` | `party` | Yes | The funding party providing the money. |
1824
- | `destination` | `party` | Yes | The beneficiary party receiving approved disbursements. |
1825
- | `cap` | `money<C>` | Yes | Maximum total amount that can be disbursed across all child approvals in minor units of currency `C`. |
1826
- | `amount` | `money<C>` | Yes | Binding name for child approval amount values. |
1827
- | `decision` | `condition` | Yes | Port conditioning approval, requiring evidence reference. |
1828
-
1829
- Required means required by the template signature. A selected mode may also need parameters marked optional; the guidance below describes those combinations.
1830
-
1831
- ## Module guidance
1832
-
1833
- Capped disbursement from a source party to a destination party gated on stored external decision evidence.
1834
-
1835
- ### Purpose
1836
-
1837
- `conditional_disbursement` manages evidence-contingent payouts subject to a cumulative cap.
1838
- It fits insurance claim settlements, grant tranches, subsidy distributions, and escrow milestones
1839
- where each approved payment requires explicit external evidence and the total paid must not exceed `cap`.
1840
-
1841
- ### Selection guidance
1842
-
1843
- - vs `advance`: `conditional_disbursement` disburses non-repayable funds against external evidence
1844
- up to a declared cap. `advance` pays money up front with the expectation of repayment through carved
1845
- hold releases or scheduled installments.
1846
- - vs `instant_transfer`: `instant_transfer` moves money immediately with no evidence gate or cap.
1847
- `conditional_disbursement` requires an external decision port and evidence reference before any child amount moves.
1848
-
1849
- ### Parameters
1850
-
1851
- - `source`: The funding party providing the money.
1852
- - `destination`: The beneficiary party receiving approved disbursements.
1853
- - `cap`: Maximum total amount that can be disbursed across all child approvals in minor units of currency `C`.
1854
- - `amount`: Binding name for child approval amount values.
1855
- - `decision`: Port conditioning approval, requiring evidence reference.
1856
-
1857
- ### Decision ports
1858
-
1859
- - `decision`: External port providing decision evidence required to approve child disbursement amounts.
1860
-
1861
- ### Example
1862
-
1863
- ```hsx
1864
- program conditional_disbursement_example "Conditional disbursement example"
1865
- import { conditional_disbursement } from "std/money_flows"
1866
- party source: business
1867
- party claimant: person
1868
- settlement claim_payment = conditional_disbursement {
1869
- source: source
1870
- destination: claimant
1871
- cap: policyLimit: money(SAR)
1872
- amount: approvedAmount: money(SAR)
1873
- decision: port approve_claim
1874
- }
1875
- port approve_claim {
1876
- allowed: [source]
1877
- shape: { evidenceReference: text }
1878
- }
1879
- ```
1880
-
1881
- ## Declared clauses
1882
-
1883
- - `agent description`
1884
- - `capture input`
1885
- - `description`
1886
- - `id prefix`
1887
- - `input`
1888
- - `moves`
1889
- - `port`
1890
- - `steps`
1891
- - `summary`
1892
- - `title`
1893
- - `unique`
1894
-
1895
- This inventory covers all branches and nested instruments in the module. The selected parameters determine which clauses and actions the compiler emits. Indexed action names expand over the declared finite list.
1896
-
1897
- ## Decision ports
1898
-
1899
- - `decision`
1900
-
1901
- ## Actions and clauses
1902
-
1903
- | Action | Clauses lowered |
1904
- | --- | --- |
1905
- | `create` | `agent description`, `moves`, `steps`, `summary` |
1906
- | `deny` | `agent description`, `capture input`, `input`, `moves`, `port`, `steps`, `summary` |
1907
- | `create` | `agent description`, `moves`, `steps`, `summary`, `unique` |
1908
- | `approve` | `agent description`, `capture input`, `description`, `input`, `moves`, `port`, `steps`, `summary` |
1909
- | `pay` | `agent description`, `moves`, `steps`, `summary` |
1910
-
1911
- # credit_facility
1912
-
1913
- Source: [`std/money_flows/credit_facility.hsx`](../../../std/money_flows/credit_facility.hsx)
1914
-
1915
- ## Export
1916
-
1917
- `credit_facility<C>`
1918
-
1919
- ## Parameters
1920
-
1921
- | Parameter | Type | Required | Meaning |
1922
- | --- | --- | --- | --- |
1923
- | `lender` | `party` | Yes | The financing institution or party providing the credit capacity. |
1924
- | `borrower` | `party` | Yes | The borrowing party authorized to draw against the facility limit. |
1925
- | `draw_destination` | `party` | Yes | Account or party receiving disbursed draw proceeds. |
1926
- | `limit` | `money<C>` | Yes | Total revolving borrowing limit in minor units of currency `C`. |
1927
- | `expires_at` | `date` | Yes | Expiration date after which new draws cannot be opened. |
1928
- | `obligation` | `ref` | Yes | Reference to a scheduled obligation instrument handling draw repayments. |
1929
-
1930
- Required means required by the template signature. A selected mode may also need parameters marked optional; the guidance below describes those combinations.
1931
-
1932
- ## Module guidance
1933
-
1934
- Revolving credit line providing reusable borrowing capacity up to a limit backed by scheduled obligations.
1935
-
1936
- ### Purpose
1937
-
1938
- `credit_facility` manages revolving commercial credit, inventory financing, and overdraft facilities.
1939
- A borrower can draw funds multiple times up to `limit` into `draw_destination`. Each draw creates a child
1940
- record linked to a scheduled `obligation`. Repayments restore available borrowing capacity until `expires_at`.
1941
-
1942
- ### Selection guidance
1943
-
1944
- - vs `advance`: `credit_facility` provides revolving, reusable credit lines where multiple draws can occur
1945
- and repayments restore capacity. `advance` is a single upfront lump-sum disbursement with a fixed repayment plan.
1946
- - vs `scheduled`: `scheduled` defines repayment installments or recurring transfers. `credit_facility` delegates
1947
- draw repayments to a `scheduled` obligation while tracking total facility utilization and limit compliance.
1948
-
1949
- ### Parameters
1950
-
1951
- - `lender`: The financing institution or party providing the credit capacity.
1952
- - `borrower`: The borrowing party authorized to draw against the facility limit.
1953
- - `draw_destination`: Account or party receiving disbursed draw proceeds.
1954
- - `limit`: Total revolving borrowing limit in minor units of currency `C`.
1955
- - `expires_at`: Expiration date after which new draws cannot be opened.
1956
- - `obligation`: Reference to a scheduled obligation instrument handling draw repayments.
1957
-
1958
- ### Decision ports
1959
-
1960
- None on the facility itself. Mandates and decision ports are declared on the linked `obligation` instrument.
1961
-
1962
- ### Example
1963
-
1964
- ```hsx
1965
- program credit_facility_example "Credit facility example"
1966
- import { credit_facility, scheduled } from "std/money_flows"
1967
- party lender: business
1968
- party borrower: business
1969
- party draw_destination: business
1970
- party repayment_source: business
1971
- settlement repayment = scheduled {
1972
- mode: obligation
1973
- payer: repayment_source
1974
- payee: lender
1975
- debtor: borrower
1976
- amount: principal: money(SAR)
1977
- count: 2
1978
- every: P30D
1979
- first_due: firstDueAt
1980
- }
1981
- settlement facility = credit_facility {
1982
- lender: lender
1983
- borrower: borrower
1984
- draw_destination: draw_destination
1985
- limit: facilityLimit: money(SAR)
1986
- expires_at: expiresAt
1987
- obligation: repayment.obligation
1988
- }
1989
- ```
1990
-
1991
- ## Declared clauses
1992
-
1993
- - `agent description`
1994
- - `description`
1995
- - `due`
1996
- - `id prefix`
1997
- - `moves`
1998
- - `steps`
1999
- - `summary`
2000
- - `title`
2001
-
2002
- This inventory covers all branches and nested instruments in the module. The selected parameters determine which clauses and actions the compiler emits. Indexed action names expand over the declared finite list.
2003
-
2004
- ## Decision ports
2005
-
2006
- None.
2007
-
2008
- ## Actions and clauses
2009
-
2010
- | Action | Clauses lowered |
2011
- | --- | --- |
2012
- | `create` | `agent description`, `moves`, `steps`, `summary` |
2013
- | `freeze` | `due`, `moves`, `steps`, `summary` |
2014
- | `close` | `agent description`, `moves`, `steps`, `summary` |
2015
- | `create` | `agent description`, `moves`, `steps`, `summary` |
2016
- | `resolve` | `agent description`, `moves`, `steps`, `summary` |
2017
-
2018
- # held_payment
2019
-
2020
- Source: [`std/money_flows/held_payment.hsx`](../../../std/money_flows/held_payment.hsx)
2021
-
2022
- ## Export
2023
-
2024
- `held_payment<C>`
2025
-
2026
- ## Parameters
2027
-
2028
- | Parameter | Type | Required | Meaning |
2029
- | --- | --- | --- | --- |
2030
- | `payer` | `party` | Yes | The funding party providing the money. |
2031
- | `payee` | `party` | Yes | The beneficiary party receiving the released funds. |
2032
- | `amount` | `money<C>` | Yes | Total amount in minor units of currency `C`. |
2033
- | `release` | `condition` | Yes | Condition required to release funds. Supports decision ports (`port <name>`), date deadlines (`at(<date>)`), or disjunctions (`port <name> &#124; at(<date>)`). |
2034
- | `fees` | `optional<block>` | No | Optional block declaring percentage or fixed fee cuts, e.g. `{ buyer: 1%, seller: 2% }`. |
2035
- | `on_cancel` | `optional<block>` | No | Optional block defining refund splits if cancelled while funded, e.g. `(funded) { buyer: 90%, seller: 10% }`. |
2036
- | `derived_amount` | `optional<block>` | No | Optional block declaring machine-derived fees calculated as a percentage of another field. |
2037
- | `release_to` | `optional<party>` | No | Optional third-party destination for release. |
2038
- | `whole_amount` | `optional<block>` | No | Optional block enabling single-action funding and release of principal plus on-top fee. |
2039
- | `release_action` | `optional<text>` | No | Optional custom name for the release action. |
2040
- | `whole_fee` | `optional<money<C>>` | No | Optional money amount for the whole-amount fee. |
2041
- | `reference` | `optional<text>` | No | Optional string reference stored on the instance. |
2042
- | `upstream` | `optional<ref>` | No | Optional reference to a parent instrument. |
2043
- | `id_prefix_override` | `optional<text>` | No | Optional custom prefix for generated instrument IDs. |
2044
- | `cancel_charge_bps` | `optional<integer>` | No | Optional cancellation charge in basis points. Declaring it gives the settlement a quoted cancellation: `quote_cancellation` prices the charge and the refund and freezes both, `cancel` pays the refund to the payer, and `retain_cancellation_charge` pays the charge to the payee. A zero charge keeps the flow with a zero fee. |
2045
- | `cancel_offer_life` | `optional<text>` | No | ISO 8601 duration a cancellation quote stays open, required with `cancel_charge_bps`. |
2046
- | `private_actions` | `optional<boolean>` | No | Suppress automatic aliases. Publish chosen actions with `expose`. |
2047
-
2048
- Required means required by the template signature. A selected mode may also need parameters marked optional; the guidance below describes those combinations.
2049
-
2050
- ## Module guidance
2051
-
2052
- Escrow settlement holding funds from a payer before releasing to a payee upon a verified condition or deadline.
2053
-
2054
- ### Purpose
2055
-
2056
- `held_payment` holds customer funds in a dedicated product escrow account away from both payer and payee.
2057
- It fits milestone-gated commerce, vehicle escrow, contractor holdbacks, and goods purchases where funds
2058
- must remain reserved until delivery confirmation or inspection.
2059
-
2060
- ### Selection guidance
2061
-
2062
- - vs `cancellable_booking`: Both hold funds in custody and both can quote a cancellation before it is
2063
- spent. `held_payment` quotes one flat charge declared by `cancel_charge_bps`, because it has no scheduled
2064
- start to price against, and `on_cancel` remains the way to unwind it on static splits instead.
2065
- Choose `cancellable_booking` when the charge must follow the time left before a scheduled start date.
2066
- - vs `security_deposit`: `held_payment` releases or cancels the principal according to predefined splits.
2067
- Choose `security_deposit` when the holder must assess damages and claim an arbitrary partial amount
2068
- via a `decided amount` clause while returning the unspent remainder to the payer.
2069
- - vs `swap`: `held_payment` is a one-way transfer from payer to payee. Choose `swap` for bilateral or
2070
- multi-party atomic exchanges where all parties must fund their legs into escrow before simultaneous release.
2071
- - vs `premium_forward`: Choose `premium_forward` for insurance premium collection requiring carrier policy
2072
- binding conditions, broker commission retention, policy endorsements, and lapse schedules.
2073
-
2074
- ### Parameters
2075
-
2076
- - `payer`: The funding party providing the money.
2077
- - `payee`: The beneficiary party receiving the released funds.
2078
- - `amount`: Total amount in minor units of currency `C`.
2079
- - `release`: Condition required to release funds. Supports decision ports (`port <name>`), date deadlines
2080
- (`at(<date>)`), or disjunctions (`port <name> | at(<date>)`).
2081
- - `fees`: Optional block declaring percentage or fixed fee cuts, e.g. `{ buyer: 1%, seller: 2% }`.
2082
- - `on_cancel`: Optional block defining refund splits if cancelled while funded, e.g. `(funded) { buyer: 90%, seller: 10% }`.
2083
- - `derived_amount`: Optional block declaring machine-derived fees calculated as a percentage of another field.
2084
- - `release_to`: Optional third-party destination for release.
2085
- - `whole_amount`: Optional block enabling single-action funding and release of principal plus on-top fee.
2086
- - `release_action`: Optional custom name for the release action.
2087
- - `whole_fee`: Optional money amount for the whole-amount fee.
2088
- - `reference`: Optional string reference stored on the instance.
2089
- - `upstream`: Optional reference to a parent instrument.
2090
- - `id_prefix_override`: Optional custom prefix for generated instrument IDs.
2091
- - `cancel_charge_bps`: Optional cancellation charge in basis points. Declaring it gives the settlement a
2092
- quoted cancellation: `quote_cancellation` prices the charge and the refund and freezes both,
2093
- `cancel` pays the refund to the payer, and `retain_cancellation_charge` pays the charge to the payee.
2094
- A zero charge keeps the flow with a zero fee.
2095
- - `cancel_offer_life`: ISO 8601 duration a cancellation quote stays open, required with `cancel_charge_bps`.
2096
-
2097
- - `private_actions`: Suppress automatic aliases. Publish chosen actions with `expose`.
2098
-
2099
- ### Decision ports
2100
-
2101
- - `release`: Port deciding release authorization, answered by allowed parties declared in the port.
2102
-
2103
- ### Example
2104
-
2105
- ```hsx
2106
- program held_payment_example "Held payment example"
2107
- import { held_payment } from "std/money_flows"
2108
- party buyer: person
2109
- party seller: business
2110
- settlement sale = held_payment {
2111
- payer: buyer
2112
- payee: seller
2113
- amount: price: money(SAR)
2114
- fees { buyer: 1% }
2115
- on_cancel(funded) { buyer: 100% }
2116
- release: port confirm_delivery | at(releaseDueAt)
2117
- }
2118
- port confirm_delivery { allowed: [buyer] }
2119
- ```
2120
-
2121
- ## Declared clauses
2122
-
2123
- - `agent description`
2124
- - `caller parked states`
2125
- - `commit`
2126
- - `deadline`
2127
- - `description`
2128
- - `distinct parties`
2129
- - `due`
2130
- - `event name`
2131
- - `id prefix`
2132
- - `input`
2133
- - `moves`
2134
- - `partitions`
2135
- - `port`
2136
- - `quote`
2137
- - `requires drained`
2138
- - `sandbox failure point`
2139
- - `steps`
2140
- - `summary`
2141
- - `title`
2142
-
2143
- This inventory covers all branches and nested instruments in the module. The selected parameters determine which clauses and actions the compiler emits. Indexed action names expand over the declared finite list.
2144
-
2145
- ## Decision ports
2146
-
2147
- - `release`
2148
-
2149
- ## Actions and clauses
2150
-
2151
- | Action | Clauses lowered |
2152
- | --- | --- |
2153
- | `fund_piece_2` | `agent description`, `moves`, `sandbox failure point`, `steps`, `summary` |
2154
- | `fund_piece_3` | `agent description`, `moves`, `sandbox failure point`, `steps`, `summary` |
2155
- | `collect_service_fee` | `agent description`, `moves`, `steps`, `summary` |
2156
- | `release_piece_2` | `agent description`, `moves`, `steps`, `summary` |
2157
- | `release_piece_3` | `agent description`, `moves`, `steps`, `summary` |
2158
- | `refund_piece_2` | `agent description`, `moves`, `steps`, `summary` |
2159
- | `refund_piece_3` | `agent description`, `moves`, `steps`, `summary` |
2160
- | `unfund_piece_1` | `agent description`, `moves`, `steps`, `summary` |
2161
- | `unfund_piece_2` | `agent description`, `moves`, `steps`, `summary` |
2162
- | `unfund_piece_3` | `agent description`, `moves`, `steps`, `summary` |
2163
- | `create` | `agent description`, `moves`, `steps`, `summary` |
2164
- | `fund_piece_1` | `agent description`, `moves`, `sandbox failure point`, `steps`, `summary` |
2165
- | `[release_name]` | `agent description`, `deadline`, `input`, `moves`, `port`, `sandbox failure point`, `steps`, `summary` |
2166
- | `release_on_deadline` | `due`, `moves`, `steps`, `summary` |
2167
- | `cancel` | `agent description`, `deadline`, `moves`, `steps`, `summary` |
2168
- | `quote_cancellation` | `agent description`, `deadline`, `moves`, `quote`, `steps`, `summary` |
2169
- | `cancel` | `agent description`, `commit`, `deadline`, `moves`, `steps`, `summary` |
2170
- | `retain_cancellation_charge` | `agent description`, `moves`, `steps`, `summary` |
2171
- | `fund_piece_2` | `agent description`, `moves`, `sandbox failure point`, `steps`, `summary` |
2172
- | `release_piece_2` | `agent description`, `moves`, `steps`, `summary` |
2173
- | `unfund_piece_1` | `agent description`, `moves`, `steps`, `summary` |
2174
- | `fund_piece_2` | `agent description`, `moves`, `sandbox failure point`, `steps`, `summary` |
2175
- | `release_piece_2` | `agent description`, `moves`, `steps`, `summary` |
2176
- | `refund_piece_2` | `agent description`, `moves`, `steps`, `summary` |
2177
- | `unfund_piece_1` | `agent description`, `moves`, `steps`, `summary` |
2178
- | `abandon` | `agent description`, `moves`, `steps`, `summary` |
2179
- | `dispute` | `agent description`, `deadline`, `description`, `moves`, `steps`, `summary` |
2180
- | `resume` | `agent description`, `description`, `moves`, `steps`, `summary` |
2181
- | `create` | `agent description`, `moves`, `steps`, `summary` |
2182
- | `fund` | `agent description`, `moves`, `sandbox failure point`, `steps`, `summary` |
2183
- | `[release_action]` | `agent description`, `deadline`, `moves`, `port`, `sandbox failure point`, `steps`, `summary` |
2184
- | `release_on_deadline` | `due`, `event name`, `moves`, `steps`, `summary` |
2185
- | `cancel` | `agent description`, `deadline`, `event name`, `moves`, `steps`, `summary` |
2186
- | `abandon` | `agent description`, `moves`, `requires drained`, `steps`, `summary` |
2187
- | `dispute` | `agent description`, `deadline`, `description`, `moves`, `steps`, `summary` |
2188
- | `resume` | `agent description`, `description`, `moves`, `steps`, `summary` |
2189
-
2190
- # instant_transfer
2191
-
2192
- Source: [`std/money_flows/instant_transfer.hsx`](../../../std/money_flows/instant_transfer.hsx)
2193
-
2194
- ## Export
2195
-
2196
- `instant_transfer<C>`
2197
-
2198
- ## Parameters
2199
-
2200
- | Parameter | Type | Required | Meaning |
2201
- | --- | --- | --- | --- |
2202
- | `payer` | `party` | Yes | Funding party whose account is debited. |
2203
- | `payee` | `party` | Yes | Recipient party whose account is credited. |
2204
- | `amount` | `money<C>` | Yes | Transfer amount in minor units of currency `C`. |
2205
- | `fees` | `optional<block>` | No | Optional fee configuration block specifying flat fees, percentage fees, or bracketed fee tiers for payer and/or payee. |
2206
- | `derived_amount` | `optional<block>` | No | Optional block declaring derived platform fees calculated from the transfer amount. |
2207
-
2208
- Required means required by the template signature. A selected mode may also need parameters marked optional; the guidance below describes those combinations.
2209
-
2210
- ## Module guidance
2211
-
2212
- Direct, single-step push transfer from payer to payee with optional tiered or percentage fees.
2213
-
2214
- ### Purpose
2215
-
2216
- `instant_transfer` debits a payer and credits a payee immediately in a single execution step.
2217
- It fits peer-to-peer transfers, direct disbursements, instant payouts, wallet reloads, and simple point-of-sale payments.
2218
-
2219
- ### Selection guidance
2220
-
2221
- - vs `captured_payment`: `instant_transfer` moves money in one atomic step without prior authorization holds,
2222
- incremental captures, voids, or post-settlement correction ports. Use `captured_payment` when authorization must precede capture.
2223
- - vs `conditional_disbursement`: `instant_transfer` executes immediately without external decision evidence
2224
- or cumulative cap tracking. Use `conditional_disbursement` when payments require evidence submission or aggregate milestone caps.
2225
- - vs `held_payment`: `instant_transfer` never holds funds in an intermediary escrow account.
2226
-
2227
- ### Parameters
2228
-
2229
- - `payer`: Funding party whose account is debited.
2230
- - `payee`: Recipient party whose account is credited.
2231
- - `amount`: Transfer amount in minor units of currency `C`.
2232
- - `fees`: Optional fee configuration block specifying flat fees, percentage fees, or bracketed fee tiers for payer and/or payee.
2233
- - `derived_amount`: Optional block declaring derived platform fees calculated from the transfer amount.
2234
-
2235
- ### Decision ports
2236
-
2237
- None. Transfers execute immediately upon invocation.
2238
-
2239
- ### Example
2240
-
2241
- ```hsx
2242
- program instant_transfer_example "Instant transfer example"
2243
- import { instant_transfer } from "std/money_flows"
2244
- party customer: person
2245
- party merchant: business
2246
- settlement transfer = instant_transfer {
2247
- payer: customer
2248
- payee: merchant
2249
- amount: transferAmount: money(SAR)
2250
- fees {
2251
- customer: checkoutFee: money(SAR)
2252
- merchant {
2253
- tier { from: 0, to: 10000, fee: 1% }
2254
- tier { from: 10000, fee: highValueFee: money(SAR) }
2255
- }
2256
- }
2257
- }
2258
- ```
2259
-
2260
- ## Declared clauses
2261
-
2262
- - `agent description`
2263
- - `description`
2264
- - `moves`
2265
- - `partitions`
2266
- - `sandbox failure point`
2267
- - `steps`
2268
- - `summary`
2269
- - `title`
2270
-
2271
- This inventory covers all branches and nested instruments in the module. The selected parameters determine which clauses and actions the compiler emits. Indexed action names expand over the declared finite list.
2272
-
2273
- ## Decision ports
2274
-
2275
- None.
2276
-
2277
- ## Actions and clauses
2278
-
2279
- | Action | Clauses lowered |
2280
- | --- | --- |
2281
- | `create` | `agent description`, `moves`, `steps`, `summary` |
2282
- | `pay_piece_1` | `agent description`, `moves`, `sandbox failure point`, `steps`, `summary` |
2283
- | `pay_piece_2` | `agent description`, `moves`, `steps`, `summary` |
2284
- | `collect_service_fee` | `agent description`, `moves`, `steps`, `summary` |
2285
-
2286
- # metered
2287
-
2288
- Source: [`std/money_flows/metered.hsx`](../../../std/money_flows/metered.hsx)
2289
-
2290
- ## Export
2291
-
2292
- `metered`
2293
-
2294
- ## Parameters
2295
-
2296
- | Parameter | Type | Required | Meaning |
2297
- | --- | --- | --- | --- |
2298
- | `payer` | `party` | Yes | The customer being billed for usage. |
2299
- | `payee` | `party` | Yes | The service provider receiving usage revenue. |
2300
- | `close_by` | `date` | Yes | Date when the metering period closes, preventing further usage charges. |
2301
- | `rates` | `unknown` | Yes | Block mapping rate metric names to their per-unit money prices committed at period open. |
2302
-
2303
- Required means required by the template signature. A selected mode may also need parameters marked optional; the guidance below describes those combinations.
2304
-
2305
- ## Module guidance
2306
-
2307
- Usage-based billing against a committed rate card over an open period until a stored close date.
2308
-
2309
- ### Purpose
2310
-
2311
- `metered` bills customers for variable resource consumption such as API requests, compute hours,
2312
- storage gigabytes, or utility consumption. The rate card is fixed when the period opens, and individual
2313
- usage events are charged incrementally until the billing period closes on `close_by`.
2314
-
2315
- ### Selection guidance
2316
-
2317
- - vs `scheduled`: `metered` charges variable amounts per event calculated from consumed units and committed
2318
- rate card prices. `scheduled` executes transfers on fixed calendar recurrence intervals (`every`, `first_due`)
2319
- with predetermined amounts or installments.
2320
-
2321
- ### Parameters
2322
-
2323
- - `payer`: The customer being billed for usage.
2324
- - `payee`: The service provider receiving usage revenue.
2325
- - `close_by`: Date when the metering period closes, preventing further usage charges.
2326
- - `rates`: Block mapping rate metric names to their per-unit money prices committed at period open.
2327
-
2328
- ### Decision ports
2329
-
2330
- None. Charges are driven by caller billing actions and period closure.
2331
-
2332
- ### Example
2333
-
2334
- ```hsx
2335
- program metered_example "Metered example"
2336
- import { metered } from "std/money_flows"
2337
- party customer: business
2338
- party provider: business
2339
- settlement usage = metered {
2340
- payer: customer
2341
- payee: provider
2342
- close_by: periodEnd
2343
- rates {
2344
- api_call: callRate: money(SAR)
2345
- storage_gib: storageRate: money(SAR)
2346
- }
2347
- }
2348
- ```
2349
-
2350
- ## Declared clauses
2351
-
2352
- - `agent description`
2353
- - `description`
2354
- - `due`
2355
- - `moves`
2356
- - `steps`
2357
- - `summary`
2358
- - `title`
2359
-
2360
- This inventory covers all branches and nested instruments in the module. The selected parameters determine which clauses and actions the compiler emits. Indexed action names expand over the declared finite list.
2361
-
2362
- ## Decision ports
2363
-
2364
- None.
2365
-
2366
- ## Actions and clauses
2367
-
2368
- | Action | Clauses lowered |
2369
- | --- | --- |
2370
- | `create` | `agent description`, `steps`, `summary` |
2371
- | `charge_[item]` | `agent description`, `moves`, `steps`, `summary` |
2372
- | `close_period` | `due`, `steps`, `summary` |
2373
-
2374
- # pooled_split
2375
-
2376
- Source: [`std/money_flows/pooled_split.hsx`](../../../std/money_flows/pooled_split.hsx)
2377
-
2378
- ## Export
2379
-
2380
- `pooled_split<C>`
2381
-
2382
- ## Parameters
2383
-
2384
- | Parameter | Type | Required | Meaning |
2385
- | --- | --- | --- | --- |
2386
- | `payer` | `party` | Yes | The funding party providing the pooled amount. |
2387
- | `amount` | `money<C>` | Yes | Total pooled amount in minor units of currency `C`. |
2388
- | `payout_due` | `date` | Yes | Stored payout date when the pool distributes to all recipients. |
2389
- | `split` | `block` | Yes | Block declaring each recipient's percentage share and `remainder_to` recipient for rounding remainders. |
2390
-
2391
- Required means required by the template signature. A selected mode may also need parameters marked optional; the guidance below describes those combinations.
2392
-
2393
- ## Module guidance
2394
-
2395
- Fixed multi-recipient revenue or period pool funded share-by-share and released automatically on a due date.
2396
-
2397
- ### Purpose
2398
-
2399
- `pooled_split` pools a period total from one payer and splits it across a fixed roster of recipients
2400
- according to predetermined percentage shares (with integer division remainder assigned to `remainder_to`).
2401
- Callers fund the pool share-by-share, and payouts disburse automatically to each recipient on `payout_due`.
2402
-
2403
- ### Selection guidance
2404
-
2405
- - vs `weighted_distribution`: `pooled_split` hardcodes a fixed set of recipients and static percentage shares
2406
- directly in the contract. `weighted_distribution` handles dynamic recipient counts where arbitrary weights
2407
- are recorded as child records and frozen via a snapshot port before distribution.
2408
- - vs `settlement_batch`: `settlement_batch` aggregates multiple payments from many sources into one net payout.
2409
- `pooled_split` takes one period total from one payer and partitions it out to multiple recipients.
2410
-
2411
- ### Parameters
2412
-
2413
- - `payer`: The funding party providing the pooled amount.
2414
- - `amount`: Total pooled amount in minor units of currency `C`.
2415
- - `payout_due`: Stored payout date when the pool distributes to all recipients.
2416
- - `split`: Block declaring each recipient's percentage share and `remainder_to` recipient for rounding remainders.
2417
-
2418
- ### Decision ports
2419
-
2420
- None. Payout distribution triggers automatically from the stored `payout_due` date.
2421
-
2422
- ### Example
2423
-
2424
- ```hsx
2425
- program pooled_split_example "Pooled split example"
2426
- import { pooled_split } from "std/money_flows"
2427
- party payer: business
2428
- party first_recipient: business
2429
- party second_recipient: business
2430
- settlement pool = pooled_split {
2431
- payer: payer
2432
- amount: poolAmount: money(SAR)
2433
- payout_due: payoutDueAt
2434
- split {
2435
- first_recipient: 60%
2436
- second_recipient: 40%
2437
- remainder_to: first_recipient
2438
- }
2439
- }
2440
- ```
2441
-
2442
- ## Declared clauses
2443
-
2444
- - `agent description`
2445
- - `description`
2446
- - `due`
2447
- - `id prefix`
2448
- - `moves`
2449
- - `partitions`
2450
- - `steps`
2451
- - `summary`
2452
- - `title`
2453
-
2454
- This inventory covers all branches and nested instruments in the module. The selected parameters determine which clauses and actions the compiler emits. Indexed action names expand over the declared finite list.
2455
-
2456
- ## Decision ports
2457
-
2458
- None.
2459
-
2460
- ## Actions and clauses
2461
-
2462
- | Action | Clauses lowered |
2463
- | --- | --- |
2464
- | `create` | `agent description`, `moves`, `steps`, `summary` |
2465
- | `fund_share_[index]` | `agent description`, `moves`, `steps`, `summary` |
2466
- | `distribute_share_[index]` | `due`, `moves`, `steps`, `summary` |
2467
-
2468
- # premium_forward
2469
-
2470
- Source: [`std/money_flows/premium_forward.hsx`](../../../std/money_flows/premium_forward.hsx)
2471
-
2472
- ## Export
2473
-
2474
- `premium_forward<C>`
2475
-
2476
- ## Parameters
2477
-
2478
- | Parameter | Type | Required | Meaning |
2479
- | --- | --- | --- | --- |
2480
- | `payer` | `party` | Yes | The policyholder paying the insurance premium. |
2481
- | `carrier` | `party` | Yes | The insurance carrier underwriting the policy. |
2482
- | `amount` | `money<C>` | Yes | Total gross premium in minor units of currency `C`. |
2483
- | `bind` | `condition` | Yes | Condition port triggering policy binding and premium forwarding. |
2484
- | `commission` | `percent` | Yes | Platform commission percentage retained from the gross premium. |
2485
- | `policy_ref` | `optional<text>` | No | Optional policy identifier string. |
2486
- | `renewal_due` | `optional<date>` | No | Optional date anchor when the policy is due for renewal. |
2487
- | `endorsement` | `optional<condition>` | No | Optional condition port for recording policy endorsements. |
2488
-
2489
- Required means required by the template signature. A selected mode may also need parameters marked optional; the guidance below describes those combinations.
2490
-
2491
- ## Module guidance
2492
-
2493
- Insurance premium escrow holding customer funds until policy binding, then partitioning net carrier premium and commission.
2494
-
2495
- ### Purpose
2496
-
2497
- `premium_forward` manages insurance premium collection, broker commission retention, and carrier remittance.
2498
- A policyholder funds the premium into dedicated escrow. The funds remain held until the policy binds via the `bind` port.
2499
- Upon binding, the gross premium is automatically partitioned: the platform fee/commission is retained, and the net
2500
- balance forwards to the carrier. It also supports policy endorsements and renewal schedules.
2501
-
2502
- ### Selection guidance
2503
-
2504
- - vs `held_payment`: `premium_forward` is tailored for insurance lifecycles, featuring automatic commission splits
2505
- upon binding and policy endorsement tracking. `held_payment` is general commercial escrow without insurance
2506
- underwriting binding semantics or gross-to-net fee partitioning.
2507
- - vs `conditional_disbursement`: `premium_forward` collects and forwards inbound policy premiums to carriers.
2508
- `conditional_disbursement` pays outbound claim settlements to claimants against stored evidence.
2509
-
2510
- ### Parameters
2511
-
2512
- - `payer`: The policyholder paying the insurance premium.
2513
- - `carrier`: The insurance carrier underwriting the policy.
2514
- - `amount`: Total gross premium in minor units of currency `C`.
2515
- - `bind`: Condition port triggering policy binding and premium forwarding.
2516
- - `commission`: Platform commission percentage retained from the gross premium.
2517
- - `policy_ref`: Optional policy identifier string.
2518
- - `renewal_due`: Optional date anchor when the policy is due for renewal.
2519
- - `endorsement`: Optional condition port for recording policy endorsements.
2520
-
2521
- ### Decision ports
2522
-
2523
- - `bind`: Port authorizing policy binding, triggering carrier payout and commission retention.
2524
- - `endorsement`: Port allowing carrier endorsement evidence to be recorded.
2525
-
2526
- ### Example
2527
-
2528
- ```hsx
2529
- program premium_forward_example "Premium forward example"
2530
- import { premium_forward } from "std/money_flows"
2531
- party policyholder: person
2532
- party carrier: business
2533
- settlement premium = premium_forward {
2534
- payer: policyholder
2535
- carrier: carrier
2536
- amount: premiumAmount: money(SAR)
2537
- commission: 2%
2538
- bind: port bind_policy
2539
- policy_ref: policyReference
2540
- renewal_due: renewalDueAt
2541
- endorsement: port record_endorsement
2542
- }
2543
- port bind_policy { allowed: [policyholder, carrier] }
2544
- port record_endorsement {
2545
- allowed: [carrier]
2546
- shape: { evidenceReference: text }
2547
- }
2548
- ```
2549
-
2550
- ## Declared clauses
2551
-
2552
- - `agent description`
2553
- - `capture input`
2554
- - `description`
2555
- - `due`
2556
- - `input`
2557
- - `moves`
2558
- - `partitions`
2559
- - `port`
2560
- - `sandbox failure point`
2561
- - `steps`
2562
- - `summary`
2563
- - `title`
2564
-
2565
- This inventory covers all branches and nested instruments in the module. The selected parameters determine which clauses and actions the compiler emits. Indexed action names expand over the declared finite list.
2566
-
2567
- ## Decision ports
2568
-
2569
- - `bind`
2570
- - `endorsement`
2571
-
2572
- ## Actions and clauses
2573
-
2574
- | Action | Clauses lowered |
2575
- | --- | --- |
2576
- | `create` | `agent description`, `steps`, `summary` |
2577
- | `fund_piece_1` | `agent description`, `moves`, `sandbox failure point`, `steps`, `summary` |
2578
- | `fund_piece_2` | `agent description`, `moves`, `sandbox failure point`, `steps`, `summary` |
2579
- | `[bind]` | `agent description`, `input`, `moves`, `port`, `sandbox failure point`, `steps`, `summary` |
2580
- | `forward_piece_2` | `agent description`, `moves`, `steps`, `summary` |
2581
- | `unfund_piece_1` | `agent description`, `moves`, `steps`, `summary` |
2582
- | `abandon` | `agent description`, `steps`, `summary` |
2583
- | `[endorsement]` | `agent description`, `capture input`, `input`, `port`, `steps`, `summary` |
2584
- | `lapse` | `due`, `steps`, `summary` |
2585
-
2586
- # reconciled_payout
2587
-
2588
- Source: [`std/money_flows/reconciled_payout.hsx`](../../../std/money_flows/reconciled_payout.hsx)
2589
-
2590
- ## Export
2591
-
2592
- `reconciled_payout<C>`
2593
-
2594
- ## Parameters
2595
-
2596
- | Parameter | Type | Required | Meaning |
2597
- | --- | --- | --- | --- |
2598
- | `payer` | `party` | Yes | The funding party providing the payout. |
2599
- | `beneficiary` | `party` | Yes | The beneficiary party receiving the external payout. |
2600
- | `amount` | `money<C>` | Yes | Instructed payout amount in minor units of currency `C`. |
2601
- | `beneficiary_ref` | `text` | Yes | Registered external beneficiary ID for bank routing. |
2602
- | `settle_by` | `date` | Yes | Cut-off date when unmatched expectation amounts become formal break records. |
2603
- | `matched_within` | `integer` | Yes | Match tolerance window in basis points or minor units. |
2604
- | `matched_ceiling` | `integer` | Yes | Maximum acceptable tolerance ceiling between instructed amount and settled debit. |
2605
-
2606
- Required means required by the template signature. A selected mode may also need parameters marked optional; the guidance below describes those combinations.
2607
-
2608
- ## Module guidance
2609
-
2610
- Outbound bank payout instruction with end-to-end reconciliation against external bank statement feeds.
2611
-
2612
- ### Purpose
2613
-
2614
- `reconciled_payout` manages high-assurance payouts to external suppliers, partners, or customers where payment
2615
- is not complete until confirmed by bank statement data. An instruction is dispatched to the beneficiary and an expectation
2616
- record is opened. Incoming statement debit lines match against the expectation within configurable tolerance thresholds
2617
- (`matched_within`, `matched_ceiling`). If the statement debit does not match before `settle_by`, a formal break row is raised.
2618
-
2619
- ### Selection guidance
2620
-
2621
- - vs `settlement_batch`: `reconciled_payout` executes and reconciles an individual bank payout instruction.
2622
- `settlement_batch` aggregates periodic captures, fees, and signed adjustments to calculate a net payable batch.
2623
- - vs `instant_transfer`: `instant_transfer` executes an immediate internal ledger transfer between platform accounts.
2624
- `reconciled_payout` dispatches funds across external banking rails with reconciliation tolerances and break tracking.
2625
-
2626
- ### Parameters
2627
-
2628
- - `payer`: The funding party providing the payout.
2629
- - `beneficiary`: The beneficiary party receiving the external payout.
2630
- - `amount`: Instructed payout amount in minor units of currency `C`.
2631
- - `beneficiary_ref`: Registered external beneficiary ID for bank routing.
2632
- - `settle_by`: Cut-off date when unmatched expectation amounts become formal break records.
2633
- - `matched_within`: Match tolerance window in basis points or minor units.
2634
- - `matched_ceiling`: Maximum acceptable tolerance ceiling between instructed amount and settled debit.
2635
-
2636
- ### Decision ports
2637
-
2638
- None. Payout dispatch and settlement matching follow the declared schedule, bank statement lines, and tolerance rules.
2639
-
2640
- ### Example
2641
-
2642
- ```hsx
2643
- program reconciled_payout_example "Reconciled payout example"
2644
- import { reconciled_payout } from "std/money_flows"
2645
- party treasury: business
2646
- party supplier: business
2647
- settlement supplier_payout = reconciled_payout {
2648
- payer: treasury
2649
- beneficiary: supplier
2650
- amount: netPayable: money(SAR)
2651
- beneficiary_ref: supplierBeneficiaryId
2652
- settle_by: settleBy
2653
- matched_within: 100
2654
- matched_ceiling: 500
2655
- }
2656
- ```
2657
-
2658
- ## Declared clauses
2659
-
2660
- - `agent description`
2661
- - `description`
2662
- - `dials`
2663
- - `due`
2664
- - `id prefix`
2665
- - `moves`
2666
- - `payout`
2667
- - `reconcile`
2668
- - `steps`
2669
- - `summary`
2670
- - `title`
2671
-
2672
- This inventory covers all branches and nested instruments in the module. The selected parameters determine which clauses and actions the compiler emits. Indexed action names expand over the declared finite list.
2673
-
2674
- ## Decision ports
2675
-
2676
- None.
2677
-
2678
- ## Actions and clauses
2679
-
2680
- | Action | Clauses lowered |
2681
- | --- | --- |
2682
- | `create` | `agent description`, `moves`, `steps`, `summary` |
2683
- | `instruct` | `agent description`, `moves`, `payout`, `steps`, `summary` |
2684
- | `settle` | `due`, `moves`, `reconcile`, `steps`, `summary` |
2685
- | `create` | `agent description`, `moves`, `steps`, `summary` |
2686
- | `carry` | `agent description`, `moves`, `steps`, `summary` |
2687
-
2688
- # rotating_pool
2689
-
2690
- Source: [`std/money_flows/rotating_pool.hsx`](../../../std/money_flows/rotating_pool.hsx)
2691
-
2692
- ## Export
2693
-
2694
- `rotating_pool<C>`
2695
-
2696
- ## Parameters
2697
-
2698
- | Parameter | Type | Required | Meaning |
2699
- | --- | --- | --- | --- |
2700
- | `members` | `optional<list<party>>` | No | List of parties belonging to the rotating group. |
2701
- | `contribution` | `money<C>` | Yes | Fixed contribution amount required from each member per cycle in minor units of currency `C`. |
2702
- | `count` | `integer` | Yes | Total number of cycles in the rotation (matching the member count). |
2703
- | `every` | `optional<text>` | No | Recurrence interval between contribution cycles (e.g. `"P30D"`). |
2704
- | `first_due` | `date` | Yes | Due date for the first cycle's contribution. |
2705
- | `payout_order` | `optional<list<party>>` | No | Ordered list of member parties defining the cycle payout sequence. |
2706
- | `default_policy` | `optional<text>` | No | Policy for handling missed contributions (`due_condition`). |
2707
- | `guarantee_policy` | `optional<text>` | No | Policy for backing defaulted contributions (`funded_only`). |
2708
- | `guarantor` | `optional<party>` | No | Optional guarantor party covering member defaults. |
2709
- | `exit_policy` | `optional<text>` | No | Policy governing member departures (`before_activation_only`). |
2710
- | `memo` | `optional<text>` | No | Optional memo text stored on the pool. |
2711
- | `membership` | `optional<block>` | No | Optional custom membership configuration block. |
2712
-
2713
- Required means required by the template signature. A selected mode may also need parameters marked optional; the guidance below describes those combinations.
2714
-
2715
- ## Module guidance
2716
-
2717
- Rotating savings and credit association (ROSCA) pool where members contribute fixed amounts and take turns receiving the pot.
2718
-
2719
- ### Purpose
2720
-
2721
- `rotating_pool` coordinates peer savings circles, chit funds, tandas, and committee savings groups.
2722
- A fixed group of members contributes an identical contribution amount each cycle. In each cycle, one designated member
2723
- receives the entire pooled pot according to a predefined `payout_order` until all members have taken their turn.
2724
-
2725
- ### Selection guidance
2726
-
2727
- - vs `threshold_pool`: `rotating_pool` coordinates recurring multi-party peer savings with rotating payouts.
2728
- `threshold_pool` is all-or-nothing capital accumulation toward a single threshold for one beneficiary.
2729
- - vs `scheduled`: `scheduled` coordinates a single payer to a single payee. `rotating_pool` orchestrates
2730
- a closed circular group of members taking sequential turns.
2731
-
2732
- ### Parameters
2733
-
2734
- - `members`: List of parties belonging to the rotating group.
2735
- - `contribution`: Fixed contribution amount required from each member per cycle in minor units of currency `C`.
2736
- - `count`: Total number of cycles in the rotation (matching the member count).
2737
- - `every`: Recurrence interval between contribution cycles (e.g. `"P30D"`).
2738
- - `first_due`: Due date for the first cycle's contribution.
2739
- - `payout_order`: Ordered list of member parties defining the cycle payout sequence.
2740
- - `default_policy`: Policy for handling missed contributions (`due_condition`).
2741
- - `guarantee_policy`: Policy for backing defaulted contributions (`funded_only`).
2742
- - `guarantor`: Optional guarantor party covering member defaults.
2743
- - `exit_policy`: Policy governing member departures (`before_activation_only`).
2744
- - `memo`: Optional memo text stored on the pool.
2745
- - `membership`: Optional custom membership configuration block.
2746
-
2747
- ### Decision ports
2748
-
2749
- None. Cycle advancement and pot payouts follow the declared schedule and membership actions.
2750
-
2751
- ### Example
2752
-
2753
- ```hsx
2754
- program rotating_pool_example "Rotating pool example"
2755
- import { rotating_pool } from "std/money_flows"
2756
- party member_a: person
2757
- party member_b: person
2758
- party member_c: person
2759
- party guarantor: business
2760
- settlement pool = rotating_pool {
2761
- members: [member_a, member_b, member_c]
2762
- contribution: contributionAmount: money(SAR)
2763
- count: 3
2764
- every: P30D
2765
- first_due: firstContributionAt
2766
- payout_order: [member_b, member_c, member_a]
2767
- default_policy: due_condition
2768
- guarantee_policy: funded_only
2769
- guarantor: guarantor
2770
- exit_policy: before_activation_only
2771
- }
2772
- ```
2773
-
2774
- ## Declared clauses
2775
-
2776
- - `agent description`
2777
- - `aggregate invariants`
2778
- - `caller parked states`
2779
- - `description`
2780
- - `due`
2781
- - `examples`
2782
- - `id prefix`
2783
- - `moves`
2784
- - `sandbox failure point`
2785
- - `steps`
2786
- - `summary`
2787
- - `title`
2788
- - `unique`
2789
-
2790
- This inventory covers all branches and nested instruments in the module. The selected parameters determine which clauses and actions the compiler emits. Indexed action names expand over the declared finite list.
2791
-
2792
- ## Decision ports
2793
-
2794
- None.
2795
-
2796
- ## Actions and clauses
2797
-
2798
- | Action | Clauses lowered |
2799
- | --- | --- |
2800
- | `create` | `agent description`, `moves`, `steps`, `summary` |
2801
- | `cancel` | `agent description`, `moves`, `steps`, `summary` |
2802
- | `activate` | `agent description`, `moves`, `steps`, `summary` |
2803
- | `ready_cycle_[cycle]` | `agent description`, `moves`, `steps`, `summary` |
2804
- | `advance_cycle_[cycle]` | `agent description`, `moves`, `steps`, `summary` |
2805
- | `create` | `agent description`, `moves`, `steps`, `summary`, `unique` |
2806
- | `contribute_cycle_[cycle]` | `due`, `moves`, `sandbox failure point`, `steps`, `summary` |
2807
- | `mark_default_cycle_[cycle]` | `due`, `moves`, `steps`, `summary` |
2808
- | `guarantee_cycle_[cycle]` | `agent description`, `moves`, `steps`, `summary` |
2809
- | `pay_cycle_[cycle]` | `agent description`, `moves`, `sandbox failure point`, `steps`, `summary` |
2810
- | `pay_guaranteed_cycle_[cycle]` | `agent description`, `moves`, `steps`, `summary` |
2811
- | `close` | `agent description`, `moves`, `steps`, `summary` |
2812
- | `create` | `agent description`, `examples`, `moves`, `steps` |
2813
- | `activate` | `due`, `examples`, `moves`, `steps` |
2814
- | `disband` | `agent description`, `examples`, `moves`, `steps` |
2815
- | `close` | `agent description`, `examples`, `moves`, `steps` |
2816
-
2817
- # scheduled
2818
-
2819
- Source: [`std/money_flows/scheduled.hsx`](../../../std/money_flows/scheduled.hsx)
2820
-
2821
- ## Export
2822
-
2823
- `scheduled<C>`
2824
-
2825
- ## Parameters
2826
-
2827
- | Parameter | Type | Required | Meaning |
2828
- | --- | --- | --- | --- |
2829
- | `payer` | `party` | Yes | The paying party (or repayment source). |
2830
- | `payee` | `party` | Yes | The beneficiary party receiving installment funds. |
2831
- | `amount` | `money<C>` | Yes | Total amount to partition into installments or recurring charge amount in minor units of currency `C`. |
2832
- | `count` | `optional<integer>` | No | Optional number of installments for installment or obligation modes. |
2833
- | `every` | `text` | Yes | Recurrence cadence duration string (e.g. `"P30D"`, `"P1M"`). |
2834
- | `first_due` | `date` | Yes | Stored date anchor for the first installment or charge. |
2835
- | `mode` | `optional<text>` | No | Optional mode selector (`obligation`). Omit for standard installment plans. |
2836
- | `debtor` | `optional<party>` | No | Optional debtor party when distinct from the payment source in obligation mode. |
2837
- | `advance_to` | `optional<party>` | No | Optional third-party receiving upfront advance disbursements in obligation mode. |
2838
- | `until` | `optional<condition>` | No | Optional condition port triggering cancellation of recurring subscription runs. |
2839
- | `month_end` | `optional<text>` | No | Optional handling policy for calendar month-end adjustments. |
2840
- | `period_liability` | `optional<text>` | No | Optional liability policy for billing periods. |
2841
- | `termination_drain` | `optional<text>` | No | Optional policy for draining balances on early termination. |
2842
- | `mandate` | `optional<condition>` | No | Optional condition port supplying formal debit mandate evidence. |
2843
- | `derived_amount` | `optional<unknown>` | No | Optional calculated markup or fee rules. |
2844
-
2845
- Required means required by the template signature. A selected mode may also need parameters marked optional; the guidance below describes those combinations.
2846
-
2847
- ## Module guidance
2848
-
2849
- Calendar-anchored payments supporting fixed installment plans, recurring subscriptions, or debt obligations.
2850
-
2851
- ### Purpose
2852
-
2853
- `scheduled` automates time-anchored payment series between one payer and one payee.
2854
- It supports three modes:
2855
-
2856
- 1. Installment plan: Partitions a fixed total amount into `count` installments, each collected on its own stored date.
2857
- 2. Open recurring subscription: Charges a recurring amount on an interval `every` until an `until` port fires.
2858
- 3. Debt obligation: Manages legally binding multi-installment debt with delinquency tracking, mandate evidence, and child payment records.
2859
-
2860
- ### Selection guidance
2861
-
2862
- - vs `metered`: `scheduled` executes calendar-based recurring charges or fixed installment plans.
2863
- `metered` bills variable usage per event based on a committed rate card.
2864
- - vs `rotating_pool`: `scheduled` coordinates one payer to one payee on a calendar.
2865
- `rotating_pool` coordinates a multi-party peer circle where members rotate turns receiving the entire pot.
2866
-
2867
- ### Parameters
2868
-
2869
- - `payer`: The paying party (or repayment source).
2870
- - `payee`: The beneficiary party receiving installment funds.
2871
- - `amount`: Total amount to partition into installments or recurring charge amount in minor units of currency `C`.
2872
- - `count`: Optional number of installments for installment or obligation modes.
2873
- - `every`: Recurrence cadence duration string (e.g. `"P30D"`, `"P1M"`).
2874
- - `first_due`: Stored date anchor for the first installment or charge.
2875
- - `mode`: Optional mode selector (`obligation`). Omit for standard installment plans.
2876
- - `debtor`: Optional debtor party when distinct from the payment source in obligation mode.
2877
- - `advance_to`: Optional third-party receiving upfront advance disbursements in obligation mode.
2878
- - `until`: Optional condition port triggering cancellation of recurring subscription runs.
2879
- - `month_end`: Optional handling policy for calendar month-end adjustments.
2880
- - `period_liability`: Optional liability policy for billing periods.
2881
- - `termination_drain`: Optional policy for draining balances on early termination.
2882
- - `mandate`: Optional condition port supplying formal debit mandate evidence.
2883
- - `derived_amount`: Optional calculated markup or fee rules.
2884
-
2885
- ### Decision ports
2886
-
2887
- - `until`: Port terminating recurring subscriptions.
2888
- - `mandate`: Port supplying mandate verification evidence for direct debit obligations.
2889
-
2890
- ### Example
2891
-
2892
- ```hsx
2893
- program scheduled_example "Scheduled example"
2894
- import { scheduled } from "std/money_flows"
2895
- party payer: business
2896
- party payee: business
2897
- settlement installments = scheduled {
2898
- payer: payer
2899
- payee: payee
2900
- amount: totalAmount: money(SAR)
2901
- count: 3
2902
- every: P30D
2903
- first_due: firstDueAt
2904
- }
2905
- ```
2906
-
2907
- ## Declared clauses
2908
-
2909
- - `agent description`
2910
- - `aggregate invariants`
2911
- - `capture input`
2912
- - `description`
2913
- - `due`
2914
- - `input`
2915
- - `moves`
2916
- - `partitions`
2917
- - `port`
2918
- - `sandbox failure point`
2919
- - `sets at`
2920
- - `steps`
2921
- - `summary`
2922
- - `title`
2923
-
2924
- This inventory covers all branches and nested instruments in the module. The selected parameters determine which clauses and actions the compiler emits. Indexed action names expand over the declared finite list.
2925
-
2926
- ## Decision ports
2927
-
2928
- - `until`
2929
- - `mandate`
2930
-
2931
- ## Actions and clauses
2932
-
2933
- | Action | Clauses lowered |
2934
- | --- | --- |
2935
- | `create` | `agent description`, `steps`, `summary` |
2936
- | `pay_installment_[i]` | `due`, `moves`, `sandbox failure point`, `steps`, `summary` |
2937
- | `create` | `agent description`, `moves`, `steps`, `summary` |
2938
- | `approve` | `agent description`, `steps`, `summary` |
2939
- | `advance` | `agent description`, `moves`, `steps`, `summary` |
2940
- | `collect_installment_[i]` | `due`, `steps`, `summary` |
2941
- | `[delinquent_action]` | `due`, `sets at`, `steps`, `summary` |
2942
- | `complete` | `due`, `steps`, `summary` |
2943
- | `write_off` | `agent description`, `steps`, `summary` |
2944
- | `create` | `agent description`, `steps`, `summary` |
2945
- | `repay` | `agent description`, `capture input`, `description`, `input`, `moves`, `port`, `steps`, `summary` |
2946
- | `refund` | `agent description`, `moves`, `steps`, `summary` |
2947
- | `create` | `agent description`, `steps`, `summary` |
2948
- | `open_period` | `due`, `steps`, `summary` |
2949
- | `collect_period` | `agent description`, `capture input`, `description`, `input`, `moves`, `port`, `sandbox failure point`, `steps`, `summary` |
2950
- | `[until]` | `agent description`, `capture input`, `input`, `port`, `steps`, `summary` |
2951
-
2952
- # security_deposit
2953
-
2954
- Source: [`std/money_flows/security_deposit.hsx`](../../../std/money_flows/security_deposit.hsx)
2955
-
2956
- ## Export
2957
-
2958
- `security_deposit<C>`
2959
-
2960
- ## Parameters
2961
-
2962
- | Parameter | Type | Required | Meaning |
2963
- | --- | --- | --- | --- |
2964
- | `payer` | `party` | Yes | The customer providing the deposit collateral. |
2965
- | `holder` | `party` | Yes | The merchant or owner holding the deposit rights. |
2966
- | `amount` | `money<C>` | Yes | Total reserved deposit amount in minor units of currency `C`. |
2967
- | `claim` | `optional<condition>` | No | Optional condition port triggering a damage claim. |
2968
- | `return` | `optional<condition>` | No | Optional condition port triggering full return of the deposit. |
2969
- | `claim_amount` | `optional<block>` | No | Optional block defining partial claim logic (`field`, `bound`, `remainder`). |
2970
- | `deadline` | `optional<date>` | No | Optional stored date anchor for automatic deposit release or expiry. |
2971
- | `claim_to` | `optional<party>` | No | Optional alternate destination for claimed funds. |
2972
- | `return_to` | `optional<party>` | No | Optional alternate destination for returned funds. |
2973
- | `memo` | `optional<text>` | No | Optional memo text stored on the deposit record. |
2974
- | `claim_input` | `optional<block>` | No | Optional custom input schema for the claim action. |
2975
- | `claim_capture` | `optional<block>` | No | Optional capture mappings for claim evidence. |
2976
- | `fund_failure_point` | `optional<text>` | No | Optional configuration for deposit funding failure. |
2977
- | `id_prefix_override` | `optional<text>` | No | Optional custom prefix for generated instrument IDs. |
2978
-
2979
- Required means required by the template signature. A selected mode may also need parameters marked optional; the guidance below describes those combinations.
2980
-
2981
- ## Module guidance
2982
-
2983
- Collateral deposit reserved against a payer's account in favor of a holder, returned in full or claimed against damages.
2984
-
2985
- ### Purpose
2986
-
2987
- `security_deposit` reserves collateral funds for vehicle rentals, property leasing, equipment hire, and security bonds.
2988
- Funds remain held until the rental or lease concludes. The holder can either return the deposit in full
2989
- or assess damages, claim a decided partial amount, and return the exact unspent remainder.
2990
-
2991
- ### Selection guidance
2992
-
2993
- - vs `held_payment`: `security_deposit` holds collateral where the standard outcome is returning 100% of the funds
2994
- to the payer, and claims are partial damage assessments. `held_payment` holds payment consideration where the
2995
- standard outcome is releasing 100% of the funds to the payee upon delivery.
2996
- - vs `cancellable_booking`: `cancellable_booking` holds booking fees and applies time-based cancellation penalties.
2997
- `security_deposit` holds damage collateral and supports arbitrary damage claims with remainder refund.
2998
-
2999
- ### Parameters
3000
-
3001
- - `payer`: The customer providing the deposit collateral.
3002
- - `holder`: The merchant or owner holding the deposit rights.
3003
- - `amount`: Total reserved deposit amount in minor units of currency `C`.
3004
- - `claim`: Optional condition port triggering a damage claim.
3005
- - `return`: Optional condition port triggering full return of the deposit.
3006
- - `claim_amount`: Optional block defining partial claim logic (`field`, `bound`, `remainder`).
3007
- - `deadline`: Optional stored date anchor for automatic deposit release or expiry.
3008
- - `claim_to`: Optional alternate destination for claimed funds.
3009
- - `return_to`: Optional alternate destination for returned funds.
3010
- - `memo`: Optional memo text stored on the deposit record.
3011
- - `claim_input`: Optional custom input schema for the claim action.
3012
- - `claim_capture`: Optional capture mappings for claim evidence.
3013
- - `fund_failure_point`: Optional configuration for deposit funding failure.
3014
- - `id_prefix_override`: Optional custom prefix for generated instrument IDs.
3015
-
3016
- ### Decision ports
3017
-
3018
- - `claim`: Port permitting the holder to submit a damage claim.
3019
- - `return`: Port permitting the holder to return the deposit to the payer.
3020
-
3021
- ### Example
3022
-
3023
- ```hsx
3024
- program deposit_example "Deposit example"
3025
- import { security_deposit } from "std/money_flows"
3026
- party renter: person
3027
- party owner: business
3028
- settlement security_deposit = security_deposit {
3029
- payer: renter
3030
- holder: owner
3031
- amount: depositAmount: money(SAR)
3032
- claim: port assess_damage
3033
- claim_amount: decided {
3034
- field: damageAmount
3035
- bound: depositAmount
3036
- remainder: return
3037
- }
3038
- return: port return_deposit
3039
- }
3040
- port assess_damage {
3041
- allowed: [owner]
3042
- shape: { damageAmount: money(SAR), evidence: text }
3043
- }
3044
- port return_deposit { allowed: [owner] }
3045
- ```
3046
-
3047
- ## Declared clauses
3048
-
3049
- - `agent description`
3050
- - `caller parked states`
3051
- - `capture input`
3052
- - `deadline`
3053
- - `decided amount`
3054
- - `description`
3055
- - `dials`
3056
- - `distinct parties`
3057
- - `due`
3058
- - `id prefix`
3059
- - `input`
3060
- - `moves`
3061
- - `port`
3062
- - `sandbox failure point`
3063
- - `steps`
3064
- - `summary`
3065
- - `title`
3066
-
3067
- This inventory covers all branches and nested instruments in the module. The selected parameters determine which clauses and actions the compiler emits. Indexed action names expand over the declared finite list.
3068
-
3069
- ## Decision ports
3070
-
3071
- - `claim`
3072
- - `return`
3073
-
3074
- ## Actions and clauses
3075
-
3076
- | Action | Clauses lowered |
3077
- | --- | --- |
3078
- | `create` | `agent description`, `moves`, `steps`, `summary` |
3079
- | `place_deposit` | `agent description`, `moves`, `sandbox failure point`, `steps`, `summary` |
3080
- | `[claim_name]` | `agent description`, `input`, `moves`, `port`, `steps`, `summary` |
3081
- | `[return_name]` | `agent description`, `capture input`, `input`, `moves`, `port`, `steps`, `summary` |
3082
- | `create` | `agent description`, `deadline`, `moves`, `steps`, `summary` |
3083
- | `fund` | `agent description`, `deadline`, `moves`, `sandbox failure point`, `steps`, `summary` |
3084
- | `claim` | `agent description`, `capture input`, `deadline`, `decided amount`, `input`, `moves`, `port`, `sandbox failure point`, `steps`, `summary` |
3085
- | `return` | `agent description`, `deadline`, `moves`, `port`, `steps`, `summary` |
3086
- | `expire` | `due`, `moves`, `steps`, `summary` |
3087
- | `cancel` | `agent description`, `moves`, `steps`, `summary` |
3088
-
3089
- # settlement_batch
3090
-
3091
- Source: [`std/money_flows/settlement_batch.hsx`](../../../std/money_flows/settlement_batch.hsx)
3092
-
3093
- ## Export
3094
-
3095
- `settlement_batch<C>`
3096
-
3097
- ## Parameters
3098
-
3099
- | Parameter | Type | Required | Meaning |
3100
- | --- | --- | --- | --- |
3101
- | `settlement_account` | `party` | Yes | The source clearing account holding captured funds and paying the batch. |
3102
- | `source_capture_refs` | `text` | Yes | Binding name for gross capture references included in the batch. |
3103
- | `fee_entries` | `text` | Yes | Binding name for fee deductions applied to the batch. |
3104
- | `external_reversal_offsets` | `text` | Yes | Binding name for reversal adjustments applied to the batch. |
3105
- | `close_trigger` | `date` | Yes | Date when the batch closes and ceases accepting new transaction entries. |
3106
- | `payout_destination` | `party` | Yes | The merchant or partner account receiving the net payout. |
3107
- | `negative_position` | `text` | Yes | Policy when calculated net payable is zero or negative (`reject`). |
3108
- | `payout_acknowledgement` | `condition` | Yes | Condition port confirming bank receipt of the payout. |
3109
- | `payout_beneficiary_ref` | `text` | Yes | Beneficiary identifier for external bank dispatch. |
3110
-
3111
- Required means required by the template signature. A selected mode may also need parameters marked optional; the guidance below describes those combinations.
3112
-
3113
- ## Module guidance
3114
-
3115
- Periodic aggregation of capture lineage, fee entries, and adjustments into a single net calculated payout.
3116
-
3117
- ### Purpose
3118
-
3119
- `settlement_batch` settles merchant balances, marketplace vendor earnings, and partner clearing accounts.
3120
- Individual payment captures, platform fees, and reversal adjustments accumulate into an open batch over a period.
3121
- On `close_trigger`, the batch freezes. The platform calculates the signed net payable from gross captures plus credit
3122
- adjustments minus debit adjustments. If positive, an outbound bank payout is instructed and acknowledged.
3123
-
3124
- ### Selection guidance
3125
-
3126
- - vs `reconciled_payout`: `settlement_batch` aggregates multiple transactions and adjustments over a billing cycle
3127
- to compute a single net payable. `reconciled_payout` manages bank instruction dispatch and statement line reconciliation
3128
- for an individual payout amount.
3129
- - vs `weighted_distribution`: `settlement_batch` consolidates many inbound transactions into one net outbound payout.
3130
- `weighted_distribution` splits one funding pool into many recipient payouts.
3131
-
3132
- ### Parameters
3133
-
3134
- - `settlement_account`: The source clearing account holding captured funds and paying the batch.
3135
- - `source_capture_refs`: Binding name for gross capture references included in the batch.
3136
- - `fee_entries`: Binding name for fee deductions applied to the batch.
3137
- - `external_reversal_offsets`: Binding name for reversal adjustments applied to the batch.
3138
- - `close_trigger`: Date when the batch closes and ceases accepting new transaction entries.
3139
- - `payout_destination`: The merchant or partner account receiving the net payout.
3140
- - `negative_position`: Policy when calculated net payable is zero or negative (`reject`).
3141
- - `payout_acknowledgement`: Condition port confirming bank receipt of the payout.
3142
- - `payout_beneficiary_ref`: Beneficiary identifier for external bank dispatch.
3143
-
3144
- ### Decision ports
3145
-
3146
- - `payout_acknowledgement`: Port recording external bank or partner receipt confirmation.
3147
-
3148
- ### Example
3149
-
3150
- ```hsx
3151
- program settlement_batch_example "Settlement batch example"
3152
- import { settlement_batch } from "std/money_flows"
3153
- party settlement_account: business
3154
- party payout_destination: business
3155
- settlement batch = settlement_batch {
3156
- settlement_account: settlement_account
3157
- source_capture_refs: captureReference
3158
- fee_entries: feeReference
3159
- external_reversal_offsets: reversalReference
3160
- close_trigger: closeAt
3161
- payout_destination: payout_destination
3162
- negative_position: reject
3163
- payout_acknowledgement: port acknowledge_payout
3164
- payout_beneficiary_ref: payoutBeneficiaryId
3165
- }
3166
- port acknowledge_payout {
3167
- allowed: [payout_destination]
3168
- shape: { acknowledgementReference: text }
3169
- }
3170
- ```
3171
-
3172
- ## Declared clauses
3173
-
3174
- - `agent description`
3175
- - `capture input`
3176
- - `description`
3177
- - `due`
3178
- - `id prefix`
3179
- - `input`
3180
- - `moves`
3181
- - `payout`
3182
- - `port`
3183
- - `reconcile`
3184
- - `steps`
3185
- - `summary`
3186
- - `title`
3187
-
3188
- This inventory covers all branches and nested instruments in the module. The selected parameters determine which clauses and actions the compiler emits. Indexed action names expand over the declared finite list.
3189
-
3190
- ## Decision ports
3191
-
3192
- - `payout_acknowledgement`
3193
-
3194
- ## Actions and clauses
3195
-
3196
- | Action | Clauses lowered |
3197
- | --- | --- |
3198
- | `create` | `agent description`, `moves`, `steps`, `summary` |
3199
- | `close` | `due`, `moves`, `steps`, `summary` |
3200
- | `calculate` | `agent description`, `moves`, `steps`, `summary` |
3201
- | `approve` | `agent description`, `moves`, `steps`, `summary` |
3202
- | `instruct` | `agent description`, `moves`, `payout`, `steps`, `summary` |
3203
- | `[payout_acknowledgement]` | `agent description`, `capture input`, `description`, `input`, `moves`, `port`, `steps`, `summary` |
3204
- | `reconcile` | `due`, `moves`, `reconcile`, `steps`, `summary` |
3205
- | `create` | `agent description`, `moves`, `steps`, `summary` |
3206
- | `accrue` | `agent description`, `moves`, `steps`, `summary` |
3207
- | `create` | `agent description`, `moves`, `steps`, `summary` |
3208
- | `adjust` | `agent description`, `moves`, `steps`, `summary` |
3209
- | `correct` | `agent description`, `moves`, `steps`, `summary` |
3210
-
3211
- # swap
3212
-
3213
- Source: [`std/money_flows/swap.hsx`](../../../std/money_flows/swap.hsx)
3214
-
3215
- ## Export
3216
-
3217
- `swap<C>`
3218
-
3219
- ## Parameters
3220
-
3221
- | Parameter | Type | Required | Meaning |
3222
- | --- | --- | --- | --- |
3223
- | `between` | `list<party>` | Yes | List containing exactly two trade participant parties (`[side_a, side_b]`). |
3224
- | `amounts` | `block` | Yes | Block declaring the principal money amounts for each party. |
3225
- | `fees` | `block` | Yes | Block declaring the platform fee money amounts for each party. |
3226
- | `release` | `condition` | Yes | Condition port required to execute the atomic swap release. |
3227
- | `dispute` | `condition` | Yes | Condition port triggering unwinding and refunding of both trade legs. |
3228
- | `side_names` | `optional<block>` | No | Optional custom naming block for the two sides (`first`, `second`). |
3229
- | `lifecycle_state_order` | `optional<list<text>>` | No | Optional custom ordering for lifecycle states. |
3230
- | `action_bindings` | `optional<block>` | No | Optional custom action names. |
3231
- | `parked_states` | `optional<block>` | No | Optional configuration for parked states. |
3232
- | `fixed_prefix` | `optional<text>` | No | Optional custom prefix for generated instrument IDs. |
3233
-
3234
- Required means required by the template signature. A selected mode may also need parameters marked optional; the guidance below describes those combinations.
3235
-
3236
- ## Module guidance
3237
-
3238
- Atomic two-sided trade between two parties where neither leg settles alone.
3239
-
3240
- ### Purpose
3241
-
3242
- `swap` executes atomic delivery-versus-payment (DvP) or payment-versus-payment (PvP) exchanges between two named parties.
3243
- Both sides fund their declared principal amounts and platform fees into a shared escrow. The exchange settles atomically
3244
- upon triggering the `release` condition port, paying each party the other's funded amount. If a `dispute` occurs,
3245
- both legs unwind and refund simultaneously. Half-funded or half-released states cannot occur.
3246
-
3247
- ### Selection guidance
3248
-
3249
- - vs `held_payment`: `swap` is a bilateral trade where both sides must deposit funds into escrow and receive each other's
3250
- disbursements simultaneously. `held_payment` is unilateral escrow where a single payer funds a payment held for a payee.
3251
- - vs `instant_transfer`: `instant_transfer` executes an immediate one-way transfer. `swap` coordinates two reciprocal transfers
3252
- held atomically in escrow until release confirmation.
3253
-
3254
- ### Parameters
3255
-
3256
- - `between`: List containing exactly two trade participant parties (`[side_a, side_b]`).
3257
- - `amounts`: Block declaring the principal money amounts for each party.
3258
- - `fees`: Block declaring the platform fee money amounts for each party.
3259
- - `release`: Condition port required to execute the atomic swap release.
3260
- - `dispute`: Condition port triggering unwinding and refunding of both trade legs.
3261
- - `side_names`: Optional custom naming block for the two sides (`first`, `second`).
3262
- - `lifecycle_state_order`: Optional custom ordering for lifecycle states.
3263
- - `action_bindings`: Optional custom action names.
3264
- - `parked_states`: Optional configuration for parked states.
3265
- - `fixed_prefix`: Optional custom prefix for generated instrument IDs.
3266
-
3267
- ### Decision ports
3268
-
3269
- - `release`: Port authorizing atomic settlement of both trade legs.
3270
- - `dispute`: Port triggering atomic cancellation and refund of both parties.
3271
-
3272
- ### Example
3273
-
3274
- ```hsx
3275
- program swap_example "Swap example"
3276
- import { swap } from "std/money_flows"
3277
- party buyer: business
3278
- party seller: business
3279
- settlement exchange = swap {
3280
- between: [buyer, seller]
3281
- amounts {
3282
- buyer: buyerAmount: money(SAR)
3283
- seller: sellerAmount: money(SAR)
3284
- }
3285
- fees {
3286
- buyer: buyerFee: money(SAR)
3287
- seller: sellerFee: money(SAR)
3288
- }
3289
- release: port release_exchange
3290
- dispute: port dispute_exchange within P7D
3291
- }
3292
- port release_exchange { allowed: [buyer, seller] }
3293
- port dispute_exchange { allowed: [buyer, seller] }
3294
- ```
3295
-
3296
- ## Declared clauses
3297
-
3298
- - `agent description`
3299
- - `caller parked states`
3300
- - `capture input`
3301
- - `deadline`
3302
- - `description`
3303
- - `distinct parties`
3304
- - `due`
3305
- - `event name`
3306
- - `id prefix`
3307
- - `input`
3308
- - `moves`
3309
- - `port`
3310
- - `public action`
3311
- - `sandbox failure point`
3312
- - `sets at`
3313
- - `steps`
3314
- - `summary`
3315
- - `title`
3316
-
3317
- This inventory covers all branches and nested instruments in the module. The selected parameters determine which clauses and actions the compiler emits. Indexed action names expand over the declared finite list.
3318
-
3319
- ## Decision ports
3320
-
3321
- - `release`
3322
- - `dispute`
3323
-
3324
- ## Actions and clauses
3325
-
3326
- | Action | Clauses lowered |
3327
- | --- | --- |
3328
- | `abandon` | `agent description`, `moves`, `public action`, `steps`, `summary` |
3329
- | `cancel` | `agent description`, `moves`, `public action`, `steps`, `summary` |
3330
- | `create` | `agent description`, `moves`, `public action`, `steps`, `summary` |
3331
- | `dispute` | `agent description`, `capture input`, `deadline`, `input`, `moves`, `port`, `public action`, `steps`, `summary` |
3332
- | `fund` | `agent description`, `moves`, `public action`, `sandbox failure point`, `steps`, `summary` |
3333
- | `post` | `due`, `moves`, `steps`, `summary` |
3334
- | `release` | `agent description`, `moves`, `port`, `public action`, `sandbox failure point`, `sets at`, `steps`, `summary` |
3335
- | `create` | `agent description`, `moves`, `public action`, `steps`, `summary` |
3336
- | `fund` | `agent description`, `event name`, `moves`, `public action`, `sandbox failure point`, `steps`, `summary` |
3337
- | `release` | `agent description`, `event name`, `moves`, `port`, `public action`, `sandbox failure point`, `sets at`, `steps`, `summary` |
3338
- | `post` | `due`, `event name`, `moves`, `steps`, `summary` |
3339
- | `dispute` | `agent description`, `capture input`, `deadline`, `event name`, `input`, `moves`, `port`, `public action`, `steps`, `summary` |
3340
- | `cancel` | `agent description`, `event name`, `moves`, `public action`, `steps`, `summary` |
3341
- | `abandon` | `agent description`, `event name`, `moves`, `public action`, `steps`, `summary` |
3342
-
3343
- # threshold_pool
3344
-
3345
- Source: [`std/money_flows/threshold_pool.hsx`](../../../std/money_flows/threshold_pool.hsx)
3346
-
3347
- ## Export
3348
-
3349
- `threshold_pool<C>`
3350
-
3351
- ## Parameters
3352
-
3353
- | Parameter | Type | Required | Meaning |
3354
- | --- | --- | --- | --- |
3355
- | `contributor` | `optional<party>` | No | The party representing individual contributors. |
3356
- | `beneficiary` | `optional<party>` | No | The beneficiary party receiving the settled pool if the target is met. |
3357
- | `target` | `money<C>` | Yes | Total target funding threshold in minor units of currency `C`. |
3358
- | `commitment` | `money<C>` | Yes | Binding name for individual contributor commitment amounts. |
3359
- | `max_contributors` | `optional<integer>` | No | Optional maximum count of admitted contributors. |
3360
- | `close_by` | `date` | Yes | Stored date deadline by which the target must be met. |
3361
- | `close_policy` | `optional<text>` | No | Policy determining pool close behavior (`threshold`). |
3362
- | `overfund_policy` | `optional<text>` | No | Policy on commitments exceeding the target (`reject`). |
3363
- | `cancel_policy` | `optional<text>` | No | Contributor withdrawal policy before close (`before_close`). |
3364
- | `fail_policy` | `optional<text>` | No | Refund policy if the pool fails to hit target (`whole_commitment_refund`). |
3365
- | `beneficiary_account` | `optional<account<C>>` | No | Optional direct account reference for the beneficiary. |
3366
- | `memo` | `optional<text>` | No | Optional memo text stored on the pool. |
3367
- | `contribution_instrument` | `optional<block>` | No | Optional custom contribution child instrument block. |
3368
- | `wording` | `optional<block>` | No | Optional custom UI wording block. |
3369
- | `funding_join` | `optional<block>` | No | funding_join configures the flat contribution-instrument mode for a priced obligation. |
3370
-
3371
- Required means required by the template signature. A selected mode may also need parameters marked optional; the guidance below describes those combinations.
3372
-
3373
- ## Module guidance
3374
-
3375
- All-or-nothing capital accumulation pool collecting commitments toward a target amount before a close deadline.
3376
-
3377
- ### Purpose
3378
-
3379
- `threshold_pool` powers all-or-nothing crowdfunding, capital calls, collective purchasing, and consortium rounds.
3380
- Multiple contributors pledge commitments toward a monetary `target`. Commitments sit in escrow until the pool
3381
- reaches the target before `close_by` (activating and settling funds to the beneficiary), or fails (triggering full refunds).
3382
-
3383
- ### Selection guidance
3384
-
3385
- - vs `rotating_pool`: `threshold_pool` is all-or-nothing fundraising where many contributors fund a single beneficiary.
3386
- `rotating_pool` is a peer savings circle where members contribute identically in each cycle and rotate who receives the pot.
3387
- - vs `weighted_distribution`: `threshold_pool` pools funds inward from many contributors to one beneficiary.
3388
- `weighted_distribution` pays funds outward from one source pool to many weighted recipients.
3389
-
3390
- ### Parameters
3391
-
3392
- - `contributor`: The party representing individual contributors.
3393
- - `beneficiary`: The beneficiary party receiving the settled pool if the target is met.
3394
- - `target`: Total target funding threshold in minor units of currency `C`.
3395
- - `commitment`: Binding name for individual contributor commitment amounts.
3396
- - `max_contributors`: Optional maximum count of admitted contributors.
3397
- - `close_by`: Stored date deadline by which the target must be met.
3398
- - `close_policy`: Policy determining pool close behavior (`threshold`).
3399
- - `overfund_policy`: Policy on commitments exceeding the target (`reject`).
3400
- - `cancel_policy`: Contributor withdrawal policy before close (`before_close`).
3401
- - `fail_policy`: Refund policy if the pool fails to hit target (`whole_commitment_refund`).
3402
- - `beneficiary_account`: Optional direct account reference for the beneficiary.
3403
- - `memo`: Optional memo text stored on the pool.
3404
- - `contribution_instrument`: Optional custom contribution child instrument block.
3405
- - `wording`: Optional custom UI wording block.
3406
-
3407
- ### Decision ports
3408
-
3409
- None. Lifecycle transitions (`activate`, `fail`, `close`) are driven by target threshold evaluation and the `close_by` date.
3410
-
3411
- ### Example
3412
-
3413
- ```hsx
3414
- program capital_pool_example "Capital pool example"
3415
- import { threshold_pool } from "std/money_flows"
3416
- party contributor: person
3417
- party company: business
3418
- settlement round = threshold_pool {
3419
- contributor: contributor
3420
- beneficiary: company
3421
- target: targetAmount: money(SAR)
3422
- commitment: commitmentAmount: money(SAR)
3423
- max_contributors: 100
3424
- close_by: closeBy
3425
- close_policy: threshold
3426
- overfund_policy: reject
3427
- cancel_policy: before_close
3428
- fail_policy: whole_commitment_refund
3429
- }
3430
- ```
3431
-
3432
- ### Funding join
3433
-
3434
- funding_join configures the flat contribution-instrument mode for a priced
3435
- obligation. Opening freezes minimum ticket, investor cap, profit and schedule
3436
- terms. Closing binds the obligation, freezes committed ticket identities and
3437
- moves the principal once into its funding account. A ticket's engine-owned
3438
- collection action has no independent payment or clock trigger.
3439
-
3440
- ## Declared clauses
3441
-
3442
- - `agent description`
3443
- - `aggregate invariants`
3444
- - `caller parked states`
3445
- - `description`
3446
- - `due`
3447
- - `examples`
3448
- - `funding`
3449
- - `id prefix`
3450
- - `input`
3451
- - `moves`
3452
- - `steps`
3453
- - `summary`
3454
- - `title`
3455
- - `updates`
3456
-
3457
- This inventory covers all branches and nested instruments in the module. The selected parameters determine which clauses and actions the compiler emits. Indexed action names expand over the declared finite list.
3458
-
3459
- ## Decision ports
3460
-
3461
- None.
3462
-
3463
- ## Actions and clauses
3464
-
3465
- | Action | Clauses lowered |
3466
- | --- | --- |
3467
- | `create` | `agent description`, `moves`, `steps`, `summary` |
3468
- | `activate` | `due`, `moves`, `steps`, `summary` |
3469
- | `fail` | `due`, `moves`, `steps`, `summary` |
3470
- | `close` | `agent description`, `moves`, `steps`, `summary` |
3471
- | `create` | `agent description`, `moves`, `steps`, `summary` |
3472
- | `cancel` | `agent description`, `moves`, `steps`, `summary` |
3473
- | `collect` | `agent description`, `moves`, `steps`, `summary` |
3474
- | `refund` | `agent description`, `moves`, `steps`, `summary` |
3475
- | `create` | `agent description`, `examples`, `moves`, `steps` |
3476
- | `activate` | `due`, `examples`, `moves`, `steps` |
3477
- | `fail` | `due`, `examples`, `moves`, `steps` |
3478
- | `close` | `agent description`, `examples`, `funding`, `input`, `moves`, `steps`, `updates` |
3479
-
3480
- # weighted_distribution
3481
-
3482
- Source: [`std/money_flows/weighted_distribution.hsx`](../../../std/money_flows/weighted_distribution.hsx)
3483
-
3484
- ## Export
3485
-
3486
- `weighted_distribution<C>`
3487
-
3488
- ## Parameters
3489
-
3490
- | Parameter | Type | Required | Meaning |
3491
- | --- | --- | --- | --- |
3492
- | `source` | `optional<party>` | No | The funding party providing the distribution pool. |
3493
- | `recipient` | `optional<party>` | No | The party representing entitled recipients. |
3494
- | `amount` | `optional<money<C>>` | No | Total distribution pool in minor units of currency `C`. |
3495
- | `record_at` | `optional<date>` | No | Date when entitlement eligibility is established. |
3496
- | `weight` | `optional<money<C>>` | No | Binding name for individual recipient weight amounts. |
3497
- | `max_recipients` | `optional<integer>` | No | Exact number of entitlement rows required before snapshotting. |
3498
- | `snapshot` | `optional<condition>` | No | Port freezing the entitlement set against stored decision evidence. |
3499
- | `rounding_policy` | `optional<text>` | No | Mathematical rounding policy (`largest_remainder`). |
3500
- | `withholding_policy` | `optional<text>` | No | Tax or withholding policy (`refuse`). |
3501
- | `correction_policy` | `optional<text>` | No | Error correction policy (`new_distribution`). |
3502
- | `flat` | `optional<block>` | No | Optional flat distribution configuration block. |
3503
- | `receipts` | `optional<block>` | No | receipts selects repeated distributions from immutable allocation receipts. |
3504
- | `id_prefix_override` | `optional<text>` | No | Optional custom prefix for generated instrument IDs. |
3505
-
3506
- Required means required by the template signature. A selected mode may also need parameters marked optional; the guidance below describes those combinations.
3507
-
3508
- ## Module guidance
3509
-
3510
- Frozen largest-remainder distribution splitting one pool across dynamic recipients by recorded weights.
3511
-
3512
- ### Purpose
3513
-
3514
- `weighted_distribution` distributes dividend pools, creator royalties, liquidation proceeds, and investment returns.
3515
- Child entitlement rows are recorded for each recipient with their respective weight. Once all recipients are recorded,
3516
- an evidence-backed snapshot freezes the entitlement set. Each recipient is then paid their exact largest-remainder
3517
- share such that all payouts sum exactly to `amount` without rounding leaks.
3518
-
3519
- ### Selection guidance
3520
-
3521
- - vs `pooled_split`: `weighted_distribution` handles dynamic recipient rosters recorded as child rows and frozen
3522
- via snapshot. `pooled_split` hardcodes a fixed set of recipients and static percentages at definition time.
3523
- - vs `settlement_batch`: `weighted_distribution` splits one funding pool out to many recipients.
3524
- `settlement_batch` aggregates many inbound charges and adjustments into a single net payout.
3525
-
3526
- ### Parameters
3527
-
3528
- - `source`: The funding party providing the distribution pool.
3529
- - `recipient`: The party representing entitled recipients.
3530
- - `amount`: Total distribution pool in minor units of currency `C`.
3531
- - `record_at`: Date when entitlement eligibility is established.
3532
- - `weight`: Binding name for individual recipient weight amounts.
3533
- - `max_recipients`: Exact number of entitlement rows required before snapshotting.
3534
- - `snapshot`: Port freezing the entitlement set against stored decision evidence.
3535
- - `rounding_policy`: Mathematical rounding policy (`largest_remainder`).
3536
- - `withholding_policy`: Tax or withholding policy (`refuse`).
3537
- - `correction_policy`: Error correction policy (`new_distribution`).
3538
- - `flat`: Optional flat distribution configuration block.
3539
- - `id_prefix_override`: Optional custom prefix for generated instrument IDs.
3540
-
3541
- ### Decision ports
3542
-
3543
- - `snapshot`: Port freezing the entitlement set with an evidence reference, preventing further entries.
3544
-
3545
- ### Example
3546
-
3547
- ```hsx
3548
- program weighted_distribution_example "Weighted distribution example"
3549
- import { weighted_distribution } from "std/money_flows"
3550
- party distribution_source: business
3551
- party recipient: business
3552
- settlement proceeds = weighted_distribution {
3553
- source: distribution_source
3554
- recipient: recipient
3555
- amount: distributableAmount: money(SAR)
3556
- weight: entitlementWeight: money(SAR)
3557
- max_recipients: 12
3558
- record_at: recordAt
3559
- snapshot: port snapshot_entitlements
3560
- rounding_policy: largest_remainder
3561
- withholding_policy: refuse
3562
- correction_policy: new_distribution
3563
- }
3564
- port snapshot_entitlements {
3565
- allowed: [distribution_source]
3566
- shape: { evidenceReference: text }
3567
- }
3568
- ```
3569
-
3570
- ### Receipt-backed distributions
3571
-
3572
- receipts selects repeated distributions from immutable allocation receipts.
3573
- It names round, receipt, path, mode (cash or loss), fee_bps and vat_bps.
3574
- The funding snapshot owns ticket weights and original wallet destinations.
3575
- Cash floors each ratio after fee and fee VAT; a named account receives residual.
3576
- Loss assigns principal by largest remainder without cash, fee or VAT.
3577
- Each receipt is consumed once; a new receipt may fund a new distribution record.
3578
- This mode does not use caller-entered weights or a once-only settled principal pool.
3579
-
3580
- ## Declared clauses
3581
-
3582
- - `agent description`
3583
- - `aggregate invariants`
3584
- - `capture input`
3585
- - `description`
3586
- - `due`
3587
- - `id prefix`
3588
- - `input`
3589
- - `moves`
3590
- - `port`
3591
- - `requires refs`
3592
- - `steps`
3593
- - `summary`
3594
- - `title`
3595
-
3596
- This inventory covers all branches and nested instruments in the module. The selected parameters determine which clauses and actions the compiler emits. Indexed action names expand over the declared finite list.
3597
-
3598
- ## Decision ports
3599
-
3600
- - `snapshot`
3601
-
3602
- ## Actions and clauses
3603
-
3604
- | Action | Clauses lowered |
3605
- | --- | --- |
3606
- | `create` | `agent description`, `moves`, `steps`, `summary` |
3607
- | `[snapshot]` | `agent description`, `capture input`, `description`, `input`, `moves`, `port`, `steps`, `summary` |
3608
- | `create` | `agent description`, `moves`, `steps`, `summary` |
3609
- | `payout` | `agent description`, `moves`, `steps`, `summary` |
3610
- | `create` | `agent description`, `moves`, `requires refs`, `steps`, `summary` |
3611
- | `payout` | `due`, `moves`, `steps`, `summary` |
3612
- | `create` | `agent description`, `steps` |
3613
-
3614
- # Types
3615
-
3616
- HSX checks types before it emits UDL. Money and account values carry a currency parameter, and no implicit currency conversion exists.
3617
-
3618
- | Kind | Meaning |
3619
- | --- | --- |
3620
- | `account` | A currency-indexed ledger account reference. |
3621
- | `boolean` | A compile-time or stored true or false value. |
3622
- | `bps` | An integer basis-point value. |
3623
- | `condition` | A declared decision port. |
3624
- | `date` | A stored date-time string checked by UDL. |
3625
- | `integer` | A bounded whole number. |
3626
- | `money` | A currency-indexed minor-unit amount. |
3627
- | `party` | A declared program party. |
3628
- | `percent` | An exact percentage with basis-point precision. |
3629
- | `ref` | A typed reference to another instrument. |
3630
- | `text` | A finite string value. |
3631
- | `unknown` | An internal checker result that source must resolve before lowering. |
3632
-
3633
- ## Account fields
3634
-
3635
- When declaring fields of type `account<C>`, the HSX compiler automatically lowers the field schema with the UDL2002 account pattern (`^acct_(sandbox|live)_[a-z0-9]{8,64}$`). Authors do not need to write an explicit `pattern` clause on account fields.
3636
-
3637
- ```hsx
3638
- fields {
3639
- customerAccountId {
3640
- type: account<SAR>;
3641
- "x-hyperscale-reference-filter": { column: role; values: [customer_balance]; };
3642
- }
3643
- amount: money<SAR>;
3644
- }
3645
- ```
3646
-
3647
- The account type pins the currency and identifier shape. The reference filter
3648
- pins the allowed ledger roles. Product admission requires every account field
3649
- to declare a non-empty role list. Choose roles that match the accounts the
3650
- program will use; `customer_balance` is the role in this example.
3651
-
3652
- Use the quoted `"x-hyperscale-reference-filter"` key inside the field block,
3653
- with `column: role` and `values: [...]`. There is no shorter role annotation.
3654
- A bare `customerAccountId: account<SAR>;` compiles as HSX but does not satisfy
3655
- the host's account-role admission law.
3656
-
3657
- ## Money fields
3658
-
3659
- A `money<C>` field admits a minor-unit integer string and refuses zero: it lowers to the pattern `^[1-9][0-9]{0,17}$`. Marking the field `optional: true` lets a caller omit it; it does not let a caller send `"0"`. When zero is a real value for the field, opt in with `allow_zero: true`, which lowers to `^(0|[1-9][0-9]{0,17})$`:
3660
-
3661
- ```hsx
3662
- fields {
3663
- amount: money<SAR>;
3664
- discount { type: money<SAR>; optional: true; allow_zero: true; }
3665
- }
3666
- ```
3667
-
3668
- `allow_zero` on any other type is HSX1105. Decision port shapes set it on their money fields, because a decided amount may be zero.
3669
-
3670
- ## Date fields
3671
-
3672
- A `date` field lowers to the UDL `hyperscale-date-time` format. Callers may send any RFC 3339 offset, such as `2026-10-03T09:00:00+03:00`; the host admits it and stores the UTC instant, `2026-10-03T06:00:00.000Z`. A value already in `Z` is stored byte for byte. A local date-time without an offset is refused.
3673
-
3674
- # UDL output
3675
-
3676
- An accepted compile returns three artifacts.
3677
-
3678
- | Artifact | Contents |
3679
- | --- | --- |
3680
- | `document` | The canonical UDL object. Serialize it with `serializeUdl` from `@hyperscale0/udl`. |
3681
- | `originMap` | Canonical UDL paths mapped to authored HSX spans. |
3682
- | `costManifest` | The deterministic manifest pinned to the supplied rate card. |
3683
-
3684
- Canonical UDL sorts object keys, preserves array order, uses two-space JSON indentation, and ends with one line feed.