@hyperscale0/hsx 1.0.0-beta.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. package/CHANGELOG.md +58 -9
  2. package/LICENSING.md +3 -3
  3. package/README.md +39 -149
  4. package/TRADEMARKS.md +4 -4
  5. package/bin/hsx.ts +2 -0
  6. package/dist/bin/hsx.js +2 -0
  7. package/dist/bin/hsx.js.map +1 -1
  8. package/dist/src/ast.d.ts +135 -10
  9. package/dist/src/ast.d.ts.map +1 -1
  10. package/dist/src/ast.js +24 -0
  11. package/dist/src/ast.js.map +1 -1
  12. package/dist/src/cli.d.ts +4 -1
  13. package/dist/src/cli.d.ts.map +1 -1
  14. package/dist/src/cli.js +172 -16
  15. package/dist/src/cli.js.map +1 -1
  16. package/dist/src/compile.d.ts +42 -7
  17. package/dist/src/compile.d.ts.map +1 -1
  18. package/dist/src/compile.js +82 -16
  19. package/dist/src/compile.js.map +1 -1
  20. package/dist/src/cost.d.ts +78 -0
  21. package/dist/src/cost.d.ts.map +1 -0
  22. package/dist/src/cost.js +369 -0
  23. package/dist/src/cost.js.map +1 -0
  24. package/dist/src/diagnostics.d.ts +11 -0
  25. package/dist/src/diagnostics.d.ts.map +1 -0
  26. package/dist/src/diagnostics.js +420 -0
  27. package/dist/src/diagnostics.js.map +1 -0
  28. package/dist/src/emit.d.ts +34 -0
  29. package/dist/src/emit.d.ts.map +1 -0
  30. package/dist/src/emit.js +137 -0
  31. package/dist/src/emit.js.map +1 -0
  32. package/dist/src/entry-overrides.d.ts +17 -3
  33. package/dist/src/entry-overrides.d.ts.map +1 -1
  34. package/dist/src/entry-overrides.js +180 -35
  35. package/dist/src/entry-overrides.js.map +1 -1
  36. package/dist/src/format.d.ts +10 -0
  37. package/dist/src/format.d.ts.map +1 -0
  38. package/dist/src/format.js +183 -0
  39. package/dist/src/format.js.map +1 -0
  40. package/dist/src/index.d.ts +11 -4
  41. package/dist/src/index.d.ts.map +1 -1
  42. package/dist/src/index.js +10 -3
  43. package/dist/src/index.js.map +1 -1
  44. package/dist/src/ir.d.ts +66 -0
  45. package/dist/src/ir.d.ts.map +1 -0
  46. package/dist/src/ir.js +15 -0
  47. package/dist/src/ir.js.map +1 -0
  48. package/dist/src/lex.d.ts +9 -1
  49. package/dist/src/lex.d.ts.map +1 -1
  50. package/dist/src/lex.js +50 -4
  51. package/dist/src/lex.js.map +1 -1
  52. package/dist/src/limits.d.ts +2 -3
  53. package/dist/src/limits.d.ts.map +1 -1
  54. package/dist/src/limits.js +2 -3
  55. package/dist/src/limits.js.map +1 -1
  56. package/dist/src/lsp/server.d.ts +32 -0
  57. package/dist/src/lsp/server.d.ts.map +1 -0
  58. package/dist/src/lsp/server.js +391 -0
  59. package/dist/src/lsp/server.js.map +1 -0
  60. package/dist/src/modules.d.ts +38 -0
  61. package/dist/src/modules.d.ts.map +1 -0
  62. package/dist/src/modules.js +368 -0
  63. package/dist/src/modules.js.map +1 -0
  64. package/dist/src/parse.d.ts.map +1 -1
  65. package/dist/src/parse.js +590 -17
  66. package/dist/src/parse.js.map +1 -1
  67. package/dist/src/std-bundle.d.ts +2 -0
  68. package/dist/src/std-bundle.d.ts.map +1 -0
  69. package/dist/src/std-bundle.js +88 -0
  70. package/dist/src/std-bundle.js.map +1 -0
  71. package/dist/src/std-library.d.ts +5 -0
  72. package/dist/src/std-library.d.ts.map +1 -0
  73. package/dist/src/std-library.js +9 -0
  74. package/dist/src/std-library.js.map +1 -0
  75. package/dist/src/typecheck.d.ts +8 -0
  76. package/dist/src/typecheck.d.ts.map +1 -0
  77. package/dist/src/typecheck.js +2958 -0
  78. package/dist/src/typecheck.js.map +1 -0
  79. package/dist/src/version.d.ts +4 -15
  80. package/dist/src/version.d.ts.map +1 -1
  81. package/dist/src/version.js +4 -15
  82. package/dist/src/version.js.map +1 -1
  83. package/docs/README.md +26 -0
  84. package/docs/guide/01-first-program.md +24 -0
  85. package/docs/guide/02-money.md +25 -0
  86. package/docs/guide/03-instruments.md +22 -0
  87. package/docs/guide/04-lifecycles.md +25 -0
  88. package/docs/guide/05-fees-and-splits.md +45 -0
  89. package/docs/guide/06-schedules.md +22 -0
  90. package/docs/guide/07-composition.md +46 -0
  91. package/docs/guide/08-writing-a-module.md +26 -0
  92. package/docs/guide/09-cost.md +24 -0
  93. package/docs/guide/10-diagnostics.md +27 -0
  94. package/docs/llms-full.txt +1739 -0
  95. package/docs/llms.txt +45 -0
  96. package/docs/playground.md +54 -0
  97. package/docs/reference/cli.md +35 -0
  98. package/docs/reference/diagnostics.md +619 -0
  99. package/docs/reference/grammar.md +39 -0
  100. package/docs/reference/std/advance.md +35 -0
  101. package/docs/reference/std/cancellable_booking.md +35 -0
  102. package/docs/reference/std/captured_payment.md +43 -0
  103. package/docs/reference/std/conditional_disbursement.md +33 -0
  104. package/docs/reference/std/credit_facility.md +35 -0
  105. package/docs/reference/std/held_payment.md +64 -0
  106. package/docs/reference/std/instant_transfer.md +30 -0
  107. package/docs/reference/std/metered.md +27 -0
  108. package/docs/reference/std/pooled_split.md +26 -0
  109. package/docs/reference/std/premium_forward.md +39 -0
  110. package/docs/reference/std/reconciled_payout.md +33 -0
  111. package/docs/reference/std/recurring_collection.md +25 -0
  112. package/docs/reference/std/rotating_pool.md +42 -0
  113. package/docs/reference/std/scheduled.md +51 -0
  114. package/docs/reference/std/security_deposit.md +46 -0
  115. package/docs/reference/std/settlement_batch.md +42 -0
  116. package/docs/reference/std/swap.md +46 -0
  117. package/docs/reference/std/threshold_pool.md +47 -0
  118. package/docs/reference/std/weighted_distribution.md +39 -0
  119. package/docs/reference/types.md +20 -0
  120. package/docs/reference/udl-output.md +13 -0
  121. package/docs/sessions/2026-09-02-two-instruments.hsx +21 -0
  122. package/docs/sessions/2026-09-02-two-instruments.md +41 -0
  123. package/examples/01-first-program/README.md +45 -0
  124. package/examples/01-first-program/tip-jar.hsx +17 -0
  125. package/examples/02-imports-and-archetypes/README.md +96 -0
  126. package/examples/02-imports-and-archetypes/photo-booth.hsx +37 -0
  127. package/examples/03-diagnostics/README.md +68 -0
  128. package/examples/03-diagnostics/corner-shop-fixed.hsx +22 -0
  129. package/examples/03-diagnostics/corner-shop.hsx +19 -0
  130. package/examples/04-complete-product/README.md +84 -0
  131. package/examples/04-complete-product/study-hall.hsx +67 -0
  132. package/examples/05-watch-club/README.md +9 -0
  133. package/examples/05-watch-club/watch-club.hsx +124 -0
  134. package/examples/README.md +18 -0
  135. package/examples/advance/README.md +3 -0
  136. package/examples/advance/advance.hsx +13 -0
  137. package/examples/advance/advance.udl +339 -0
  138. package/examples/cancellable_booking/README.md +3 -0
  139. package/examples/cancellable_booking/cancellable_booking.hsx +14 -0
  140. package/examples/cancellable_booking/cancellable_booking.udl +391 -0
  141. package/examples/captured_payment/README.md +3 -0
  142. package/examples/captured_payment/captured_payment.hsx +21 -0
  143. package/examples/captured_payment/captured_payment.udl +677 -0
  144. package/examples/conditional_disbursement/README.md +3 -0
  145. package/examples/conditional_disbursement/conditional_disbursement.hsx +17 -0
  146. package/examples/conditional_disbursement/conditional_disbursement.udl +412 -0
  147. package/examples/cost-table.json +386 -0
  148. package/examples/credit_facility/README.md +3 -0
  149. package/examples/credit_facility/credit_facility.hsx +27 -0
  150. package/examples/credit_facility/credit_facility.udl +1373 -0
  151. package/examples/held_payment/README.md +3 -0
  152. package/examples/held_payment/held_payment.hsx +13 -0
  153. package/examples/held_payment/held_payment.udl +507 -0
  154. package/examples/instant_transfer/README.md +3 -0
  155. package/examples/instant_transfer/instant_transfer.hsx +16 -0
  156. package/examples/instant_transfer/instant_transfer.udl +364 -0
  157. package/examples/metered/README.md +3 -0
  158. package/examples/metered/metered.hsx +13 -0
  159. package/examples/metered/metered.udl +247 -0
  160. package/examples/pooled_split/README.md +3 -0
  161. package/examples/pooled_split/pooled_split.hsx +15 -0
  162. package/examples/pooled_split/pooled_split.udl +425 -0
  163. package/examples/premium_forward/README.md +3 -0
  164. package/examples/premium_forward/premium_forward.hsx +19 -0
  165. package/examples/premium_forward/premium_forward.udl +594 -0
  166. package/examples/reconciled_payout/README.md +3 -0
  167. package/examples/reconciled_payout/reconciled_payout.hsx +13 -0
  168. package/examples/reconciled_payout/reconciled_payout.udl +303 -0
  169. package/examples/recurring_collection/README.md +3 -0
  170. package/examples/recurring_collection/recurring_collection.hsx +21 -0
  171. package/examples/recurring_collection/recurring_collection.udl +1130 -0
  172. package/examples/rotating_pool/README.md +3 -0
  173. package/examples/rotating_pool/rotating_pool.hsx +18 -0
  174. package/examples/rotating_pool/rotating_pool.udl +4352 -0
  175. package/examples/scheduled/README.md +3 -0
  176. package/examples/scheduled/scheduled.hsx +12 -0
  177. package/examples/scheduled/scheduled.udl +335 -0
  178. package/examples/security_deposit/README.md +3 -0
  179. package/examples/security_deposit/security_deposit.hsx +21 -0
  180. package/examples/security_deposit/security_deposit.udl +293 -0
  181. package/examples/settlement_batch/README.md +3 -0
  182. package/examples/settlement_batch/settlement_batch.hsx +19 -0
  183. package/examples/settlement_batch/settlement_batch.udl +753 -0
  184. package/examples/swap/README.md +3 -0
  185. package/examples/swap/swap.hsx +19 -0
  186. package/examples/swap/swap.udl +876 -0
  187. package/examples/threshold_pool/README.md +3 -0
  188. package/examples/threshold_pool/threshold_pool.hsx +16 -0
  189. package/examples/threshold_pool/threshold_pool.udl +667 -0
  190. package/examples/weighted_distribution/README.md +3 -0
  191. package/examples/weighted_distribution/weighted_distribution.hsx +20 -0
  192. package/examples/weighted_distribution/weighted_distribution.udl +337 -0
  193. package/package.json +27 -6
  194. package/skills/hsx/SKILL.md +483 -0
  195. package/src/ast.ts +193 -9
  196. package/src/cli.ts +191 -20
  197. package/src/compile.ts +160 -23
  198. package/src/cost.ts +579 -0
  199. package/src/diagnostics.ts +442 -0
  200. package/src/emit.ts +201 -0
  201. package/src/entry-overrides.ts +263 -48
  202. package/src/format.ts +261 -0
  203. package/src/index.ts +34 -4
  204. package/src/ir.ts +99 -0
  205. package/src/lex.ts +59 -4
  206. package/src/limits.ts +2 -3
  207. package/src/lsp/server.ts +460 -0
  208. package/src/modules.ts +446 -0
  209. package/src/parse.ts +655 -21
  210. package/src/std-bundle.ts +91 -0
  211. package/src/std-library.ts +12 -0
  212. package/src/typecheck.ts +3876 -0
  213. package/src/version.ts +4 -16
  214. package/std/SEMANTICS.md +130 -0
  215. package/std/settlements/advance.hsx +177 -0
  216. package/std/settlements/cancellable_booking.hsx +87 -0
  217. package/std/settlements/captured_payment.hsx +144 -0
  218. package/std/settlements/conditional_disbursement.hsx +185 -0
  219. package/std/settlements/credit_facility.hsx +167 -0
  220. package/std/settlements/held_payment.hsx +578 -0
  221. package/std/settlements/index.hsx +3 -0
  222. package/std/settlements/instant_transfer.hsx +190 -0
  223. package/std/settlements/metered.hsx +67 -0
  224. package/std/settlements/pooled_split.hsx +68 -0
  225. package/std/settlements/premium_forward.hsx +257 -0
  226. package/std/settlements/reconciled_payout.hsx +77 -0
  227. package/std/settlements/recurring_collection.hsx +27 -0
  228. package/std/settlements/rotating_pool.hsx +252 -0
  229. package/std/settlements/scheduled.hsx +641 -0
  230. package/std/settlements/security_deposit.hsx +166 -0
  231. package/std/settlements/settlement_batch.hsx +122 -0
  232. package/std/settlements/swap.hsx +1114 -0
  233. package/std/settlements/threshold_pool.hsx +221 -0
  234. package/std/settlements/weighted_distribution.hsx +141 -0
  235. package/dist/src/archetypes.d.ts +0 -17
  236. package/dist/src/archetypes.d.ts.map +0 -1
  237. package/dist/src/archetypes.js +0 -327
  238. package/dist/src/archetypes.js.map +0 -1
  239. package/dist/src/check.d.ts +0 -12
  240. package/dist/src/check.d.ts.map +0 -1
  241. package/dist/src/check.js +0 -1910
  242. package/dist/src/check.js.map +0 -1
  243. package/dist/src/lower.d.ts +0 -146
  244. package/dist/src/lower.d.ts.map +0 -1
  245. package/dist/src/lower.js +0 -4570
  246. package/dist/src/lower.js.map +0 -1
  247. package/dist/src/model.d.ts +0 -467
  248. package/dist/src/model.d.ts.map +0 -1
  249. package/dist/src/model.js +0 -15
  250. package/dist/src/model.js.map +0 -1
  251. package/spec/hsx-ir.schema.json +0 -920
  252. package/src/archetypes.ts +0 -340
  253. package/src/check.ts +0 -2938
  254. package/src/lower.ts +0 -5416
  255. package/src/model.ts +0 -519
@@ -0,0 +1,88 @@
1
+ // Generated by open/hsx/scripts/bundle-std.ts. Do not edit by hand.
2
+ export const BUNDLED_STD_FILES = new Map([
3
+ [
4
+ "SEMANTICS.md",
5
+ "# Settlement semantics frozen before legacy teardown\n\nThis note records the behavior that the former archetype branches emitted on\n2026-09-01. The 48 canonical documents under\n`test/fixtures/general-path-oracle/` are the byte-level authority. This note is\nthe human porting index.\n\n## Direct and held payments\n\n- `instant_transfer` stores the amount, currency, payer, and payee. Create pays\n through one or more ordered pieces and ends in `paid`. A payer fee is an\n `on_top` move. A payee fee is carved from the base amount. Exact, basis-point,\n and tiered rules produce fee fields and `feeRules`. The finest common\n refinement of all fee cuts produces piece fields and one partition. Floor\n rounding sends the remainder to the named non-fee recipient. A derived\n amount adds a floor percentage field, `derivedAmounts`, a platform party, and\n its own transfer piece.\n- `held_payment` reserves every refined piece before release. It posts release\n pieces, voids cancellation pieces, and keeps payer service fees outside the\n held principal. Release and cancellation fee sides share the finest common\n partition, so each stored piece has one release recipient and one cancel\n recipient. States track each funding, release, cancellation, and abandonment\n step. Abandonment refunds every still-held piece. A deadline release and a\n caller decision release carry the named date or port clause. Retention is the\n same form with one held piece, a release deadline, and cancellation back to\n the contractor. Whole-amount mode funds the principal and on-top fee in one\n action, then releases or cancels the principal whole. A condition and date\n can coexist, with separate early and scheduled release actions.\n- `captured_payment` stores authorization total, reserve and reversal dates,\n and both party accounts. It moves through `created`, `authorized`, optional\n `partially_captured`, `settled`, `voided`, `expired`, `corrected`, or\n `reversed`. Authorize reserves custody. Capture and capture-more consume the\n authorized balance according to the declared mode. Settle posts the captured\n amount. Void and expiry release the reserve. Correction and external reversal\n use their declared ports and windows. Derived fees use the same floor,\n partition, bearer, and position rules as direct payment.\n- `premium_forward` holds premium pieces, then forwards the net pieces after a\n bind decision. It can abandon unbound custody. Policy reference, renewal due,\n endorsement evidence, and lapse actions appear only when declared. Its fee\n partition and floor remainder rules match `held_payment`.\n\n## Decisions and credit\n\n- `conditional_disbursement` emits a submitted parent with cap, currency,\n source, destination, and the decision port. Denial terminates the parent. An\n approved-amount child stores a runtime-bounded amount and a parent reference.\n The child captures the port input, moves through `created`, `approved`, and\n `paid`, and refuses reopening. Recovery is a separate transfer.\n- `advance` has two forms. A carved advance references a held settlement and\n its recourse settlement, disburses once, and settles from the referenced\n release without minting new value. A scheduled advance stores advance,\n fee, repayable total, first due date, and one repayment field per fixed\n installment. It partitions repayments to the repayable total and advances\n before collecting each due installment.\n- `credit_facility` stores lender, borrower, draw destination, limit, currency,\n and expiry. The facility can freeze and close. Each draw is a generated child\n with amount, facility reference, and obligation reference. Draw admission\n checks the facility state and aggregate limit. Resolution waits for the\n referenced obligation state.\n\n## Schedules and usage\n\n- A finite `scheduled` transfer stores total, first due date, and one money\n field per installment. Floor division creates equal pieces and gives the\n final field the remainder. States and actions unroll in order. Each action\n carries its due rule and cumulative duration offset.\n- Scheduled obligation mode emits a parent plus one generated payment child per\n installment. The parent stores principal, delinquency dates, party accounts,\n partitions, and aggregate invariants. It supports draft approval, optional\n advance, fixed collection and delinquency actions, write-off, and completion.\n Each child binds parent fields, repays once, and can refund once.\n- `recurring_collection` with a finite count uses the scheduled construction.\n Open recurrence stores one amount and anchor, opens one period at a time,\n collects that period, and permits cancellation. It never unrolls an unbounded\n runtime loop.\n- `metered` stores one money field for each declared meter and a period end.\n Every charge moves directly from payer to payee. The instrument never accrues\n custody. Closing the period only changes state.\n\n## Collections and distributions\n\n- `pooled_split` stores the pool total, due date, and one share amount and\n account per recipient. Positive shares total exactly 10,000 basis points.\n Floor division assigns each share, and the named remainder recipient absorbs\n minor-unit residue. Funding and distribution actions unroll in roster order.\n- `weighted_distribution` emits an open parent and an entitlement child. The\n parent stores source, total, record date, and maximum recipient count. A port\n freezes the entitlement snapshot. Child rows store recipient, weight, source,\n currency, and parent reference. Largest-remainder distribution pays children\n once. Aggregate clauses cap and total the child set. Withholding is refused\n and correction creates a new distribution. Its `flat` form emits a single\n claim instead. The caller supplies typed pool, weight, and group references,\n their state gates, copy and match maps, and the pool amount path.\n- `threshold_pool` emits a pool parent and commitment child. The parent stores\n target, close date, maximum contributors, beneficiary, and currency. It moves\n through open, active, failed, or settled based on aggregate commitment gates.\n Each commitment can cancel before collection, collect into the round, or\n refund after failure. Its referenced-contribution form accepts a published\n contribution instrument, beneficiary account, and memo and emits no child.\n- `security_deposit` reserves the full amount. A claim port posts either the\n whole hold or a decided amount bounded by the hold. The explicit remainder\n returns to the payer. A return port voids the whole hold. The deadline form\n adds machine expiry and unfunded cancellation. Claim and return targets can\n name either party.\n\n## Composition and unwind\n\n- `swap` stores both side amounts, accounts, fees, currency, and optional\n clawback date. Funding is atomic across both sides. Release, settlement,\n cancellation, dispute, abandonment, and clawback preserve the two-sided\n conservation group. Side fees keep their declared bearer and position.\n `distinctParties` prevents self-dealing. Unwind refunds each side and applies\n the declared penalty tiers without changing the principal partition. Fixed\n side names, state order, action bindings, parked-state reasons, and ID prefix\n are general compile-time parameters.\n- `settlement_batch` emits a batch plus capture, credit-adjustment, and\n debit-adjustment children. The batch stores close time, settlement and payout\n accounts, beneficiary reference, and currency. Close freezes intake.\n Calculate signs capture, fee, and reversal entries. Approve rejects a negative\n position when configured. Instruct, acknowledge, and reconcile use the\n declared payout port. Child references and statuses define every aggregate\n and signed-sum input.\n- `rotating_pool` emits one parent plus one contribution child per fixed member.\n The parent unrolls active and ready states for every cycle and checks that each\n member row exists exactly once. Every child unrolls due, funded, defaulted,\n guaranteed, paid, and completed states for every cycle. Due offsets scale the\n fixed recurrence. A funded or guaranteed contribution pays the roster's fixed\n beneficiary for that cycle. The final close requires the escrow account to be\n drained. Its referenced-membership form delegates those member cycles to a\n published membership instrument and emits only the parent.\n",
6
+ ],
7
+ [
8
+ "settlements/advance.hsx",
9
+ 'module std.settlements.advance\n\nexport instrument advance<C>(\n funder: party,\n to: party,\n amount: money<C>,\n fee: optional<percent>,\n count: optional<integer>,\n every: optional<text>,\n first_due: optional<date>,\n against: optional<ref>,\n) {\n let(amount_path): concat("fields.", amount);\n let(currency_path): "fields.currency";\n let(funder_field): camel(concat(funder, "_account_id"));\n let(to_field): camel(concat(to, "_account_id"));\n\n agent_description: "Reach for advance when the {funder} pays the {to} up front and is repaid afterwards, either out of a carved hold release or over scheduled repayments. Pick deposit for a refundable reservation and instant transfer when nobody repays the payer.";\n title: sentence(instrument);\n id_prefix: prefix(instrument);\n parties {\n payer: funder;\n beneficiary: to;\n }\n\n when(against) {\n let(hold_name): owner(against);\n summary: "Advance to the {to} repaid by carving the {hold_name} release";\n description: "Advance: the {funder} disburses {amount} to the {to} and is repaid out of the {hold_name} release, which pays the {funder} in the {to}\'s place";\n fields {\n amount {\n type: money<C>;\n description: "The advanced amount in {C} minor units, disbursed to the {to} up front";\n }\n carve_hold_id {\n type: ref<hold_name>;\n description: "The {hold_name} bound to this advance";\n pattern: concat("^", prefix(hold_name), "_(sandbox|live)_[a-z0-9]{8,64}$");\n }\n carve_recourse_1_id {\n type: ref<recourse>;\n description: "The recourse bound to this advance";\n pattern: "^reco_(sandbox|live)_[a-z0-9]{8,64}$";\n }\n }\n required: [to_field, funder_field, amount, carveHoldId, carveRecourse1Id, currency];\n lifecycle {\n states created advanced repaid;\n initial created;\n on disburse: created -> advanced;\n on settle: advanced -> repaid;\n }\n action create {\n agent_description: "Open the advance row before any money moves. The caller supplies the {amount}, both party accounts, and the ids of the {hold_name} and the recourse that back repayment. Nothing is disbursed here.";\n summary: concat("Create a ", words(instrument));\n steps: [];\n moves: [];\n }\n action disburse {\n agent_description: "Pay the {amount} from the {funder} to the {to}. The advance must be created, the bound {hold_name} funded, and the recourse active, both matching this amount and currency. The transfer posts straight out and does not unwind.";\n summary: "Disburse the {amount} to the {to}";\n requires refs: [{\n field: carveHoldId;\n match: {\n [currency_path]: currency_path;\n [amount_path]: amount_path;\n };\n statuses: [funded];\n }, {\n field: carveRecourse1Id;\n match: {\n [currency_path]: currency_path;\n [amount_path]: amount_path;\n };\n statuses: [active];\n }];\n moves: [{ amount: amount; from: payer; to: beneficiary; key: transfer; operation: create; }];\n steps: [];\n }\n action settle {\n agent_description: "Close the advance once the {hold_name} has released to the {funder} in the {to}\'s place. The advance must already be disbursed. No money moves here, the release did the repaying.";\n summary: concat("Close the advance once the ", hold_name, " has released to the ", funder);\n steps: [];\n moves: [];\n }\n }\n\n when_not(against) {\n let(repayment_fields): names("repayment", count, "Amount");\n let(first_target): if_eq(count, 1, "repaid", "repaying_1");\n let(states_key): "states";\n let(first_due_field): camel(first_due);\n summary: concat("Advance to ", to, " repaid over ", count, " anchors");\n description: concat("Advance: the ", funder, " disburses ", amount, " to the ", to, ", repaid over ", count, " scheduled repayments plus the funder\'s discount");\n fields {\n amount {\n type: money<C>;\n description: "The advanced amount in {C} minor units, disbursed to the {to} up front";\n }\n fee_amount {\n type: money<C>;\n description: concat(fee, " of ", amount, ", the funder\'s discount repaid on top of the advance");\n }\n repayable_amount {\n type: money<C>;\n description: concat(amount, " + feeAmount: the total the repayment fields below partition exactly");\n }\n [first_due_field] {\n type: date;\n description: concat("Due date of the first repayment; repayment k falls ", every, " after its predecessor");\n }\n repayment_1_amount {\n type: money<C>;\n description: concat("Repayment 1 of ", count, " (carries the integer-division remainder): about 33.34% of repayableAmount, collected on its own stored-date anchor");\n }\n for repayment in sub(count, 1) {\n let(index): add(repayment, 1);\n repayment[index]Amount {\n type: money<C>;\n description: concat("Repayment ", index, " of ", count, ": about 33.33% of repayableAmount, collected on its own stored-date anchor");\n }\n }\n }\n lifecycle {\n states created advanced;\n [states_key]: [first_target];\n initial created;\n on disburse: created -> advanced;\n on collect_repayment_1: advanced -> [first_target];\n for repayment in sub(count, 1) {\n let(index): add(repayment, 1);\n let(previous): concat("repaying_", repayment);\n let(target): if_eq(index, count, "repaid", concat("repaying_", index));\n [states_key]: [target];\n on collect_repayment_[index]: [previous] -> [target];\n }\n }\n partitions: [{\n piece_fields: repayment_fields;\n total_field: repayableAmount;\n }, {\n piece_fields: [amount, feeAmount];\n total_field: repayableAmount;\n }];\n action create {\n agent_description: "Open the advance row before any money moves. The caller supplies the {amount}, the fee amount, the repayable total, and the first repayment date. The repayment fields must partition the repayable total exactly. Nothing is disbursed here.";\n summary: concat("Create a ", words(instrument));\n steps: [];\n moves: [];\n }\n action disburse {\n agent_description: "Pay the {amount} from the {funder} to the {to} and start the repayment schedule. The advance must be created. The transfer posts straight out and does not unwind. Each repayment is collected on its own stored date anchor.";\n summary: "Disburse the {amount} to the {to}";\n moves: [{ amount: amount; from: payer; to: beneficiary; key: transfer; operation: create; }];\n steps: [];\n }\n action collect_repayment_1 {\n summary: concat("Collect repayment 1 of ", count);\n due: { field: first_due_field; };\n moves: [{ amount: repayment1Amount; from: beneficiary; to: payer; key: transfer; operation: create; }];\n steps: [];\n }\n for repayment in sub(count, 1) {\n let(index): add(repayment, 1);\n let(repayment_field): concat("repayment", index, "Amount");\n action collect_repayment_[index] {\n summary: concat("Collect repayment ", index, " of ", count);\n due: {\n field: first_due_field;\n offset: scale_duration(every, sub(index, 1));\n };\n moves: [{ amount: repayment_field; from: beneficiary; to: payer; key: transfer; operation: create; }];\n steps: [];\n }\n }\n }\n}\n',
10
+ ],
11
+ [
12
+ "settlements/cancellable_booking.hsx",
13
+ 'module std.settlements.cancellable_booking\n\nexport instrument cancellable_booking<C>(\n guest: party,\n host: party,\n amount: money<C>,\n starts_at: date,\n late_penalty_bps: integer,\n late_within: text,\n early_penalty_bps: integer,\n offer_life: text,\n) {\n let(guest_account_field): camel(concat(guest, "_account_id"));\n let(host_account_field): camel(concat(host, "_account_id"));\n let(reference_filter_key): "x-hyperscale-reference-filter";\n let(owner_id_key): "owner.id";\n let(owner_type_key): "owner.type";\n fields {\n amount { type: money<C>; description: concat("Booking price in minor units, held away from both the ", words(guest), " and the ", words(host), " until the booking ends"); }\n currency { type: text; description: "ISO 4217 currency code"; minLength: 3; maxLength: 3; pattern: "^[A-Z]{3}$"; }\n starts_at { type: date; description: "When the booking starts; the cancellation penalty is priced against the time left before it"; }\n [guest_account_field] { type: account<C>; description: concat("The ", words(guest), " account the booking is taken from and the refund returns to"); pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; [reference_filter_key]: { column: role; values: [customer_balance]; }; }\n [host_account_field] { type: account<C>; description: concat("The ", words(host), " account the booking and any penalty end up in"); pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; [reference_filter_key]: { column: role; values: [customer_balance]; }; }\n }\n lifecycle {\n states created held cancellation_quoted canceled settled completed;\n initial created;\n on take: created -> held;\n on complete: held | cancellation_quoted -> completed;\n on cancel: held -> cancellation_quoted;\n on confirm: cancellation_quoted -> canceled;\n on retain: canceled -> settled;\n }\n parties { beneficiary: host_account_field; payer: guest_account_field; }\n required: [amount, currency, guest_account_field, host_account_field, starts_at];\n title: sentence(instrument);\n agent_description: concat("Reach for cancellable booking when the ", words(guest), " pays up front and can back out at a price they see before they agree to it. The money sits in a holding account, the penalty is priced against the time left before the start, and the quote is frozen until it expires. Pick held payment when there is no cancellation price to quote.");\n id_prefix: prefix(instrument);\n summary: concat("Booking the ", words(guest), " can cancel at a price they see before they agree to it");\n description: "A booking whose cancellation is quoted rather than argued: the penalty is priced against the time left before the start, frozen with the terms it was read from, and paid only if the guest confirms while the offer is still alive";\n action create {\n agent_description: concat("Open the booking and provision the holding account the price sits in. No money moves. The price, the currency, the start moment, and both party accounts are fixed here. Call take next to collect from the ", words(guest), ".");\n summary: concat("Open a ", words(instrument), " and its holding account");\n moves: [];\n steps: [{ operation: "account.escrow.provision"; bind: { currency: { from: instance; path: fields.currency; }; [owner_id_key]: { from: instance; path: productId; }; [owner_type_key]: { from: const; value: product; }; productId: { from: instance; path: productId; }; role: { from: const; value: product_escrow; }; }; capture: { bookingHoldingAccountId: accountId; }; }];\n }\n action take {\n agent_description: concat("Move the whole booking price out of the ", words(guest), " account into the holding account. This moves money. Only a created booking takes. Neither party can spend the money until the booking completes or a cancellation is confirmed.");\n summary: concat("Take the booking price from the ", words(guest), " into the holding account");\n moves: [{ key: booking; operation: internal_transfer.create; bind: { amount: { from: instance; path: concat("fields.", amount); }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: refs.bookingHoldingAccountId; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", guest_account_field); }; }; capture: { bookingTransferId: transferId; }; }];\n steps: [];\n }\n action complete {\n summary: concat("Release the whole booking to the ", words(host), " once the stay has started, even with a cancellation quote parked un-acted");\n due { field: starts_at; }\n moves: [{ key: release; operation: internal_transfer.create; bind: { amount: { from: instance; path: concat("fields.", amount); }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", host_account_field); }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.bookingHoldingAccountId; }; }; capture: { releaseTransferId: transferId; }; }];\n steps: [];\n }\n action cancel {\n agent_description: "Price the cancellation and freeze that price. No money moves. The penalty is computed from the time left before the start, and the quote expires on its own, after which a new cancel prices it again. Call confirm to spend the quote.";\n summary: "Price the cancellation and hold that price open";\n quote {\n anchorField: starts_at;\n baseField: amount;\n chargeRef: cancellationPenaltyAmount;\n charges: [{ bps: late_penalty_bps; withinOffset: late_within; }, { bps: early_penalty_bps; }];\n expires { offset: offer_life; }\n fixes: [amount, guest_account_field];\n netDestinationField: guest_account_field;\n netRef: cancellationRefundAmount;\n }\n moves: []; steps: [];\n }\n action confirm {\n agent_description: concat("Spend the frozen quote and return the net refund to the ", words(guest), ". This moves money and does not reverse. It requires an un-expired quote from cancel, and the penalty the refund left behind is paid to the ", words(host), " by retain.");\n summary: concat("Spend the quoted cancellation and return the net to the ", words(guest));\n commit: cancel;\n moves: [{ key: refund; operation: internal_transfer.create; bind: { amount: { from: instance; path: refs.cancellationRefundAmount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", guest_account_field); }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.bookingHoldingAccountId; }; }; capture: { cancellationTransferId: transferId; }; }];\n steps: [];\n }\n action retain {\n agent_description: concat("Pay the quoted cancellation penalty out of the holding account to the ", words(host), ". This moves money and does not reverse. The booking must already be canceled, so the penalty figure is the one the quote fixed.");\n summary: concat("Pay the quoted penalty that the refund left behind to the ", words(host));\n moves: [{ key: penalty; operation: internal_transfer.create; bind: { amount: { from: instance; path: refs.cancellationPenaltyAmount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", host_account_field); }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.bookingHoldingAccountId; }; }; capture: { penaltyTransferId: transferId; }; }];\n steps: [];\n }\n}\n',
14
+ ],
15
+ [
16
+ "settlements/captured_payment.hsx",
17
+ 'module std.settlements.captured_payment\n\nexport instrument captured_payment<C>(payer: party, payee: party, amount: money<C>, reserve_until: date, correction: condition, external_reversal: condition, capture_mode: text, correction_mode: text, negative_position: text, timeout: text, derived_amount: optional<block>) {\n let(correction_name): correction;\n let(reversal_name): external_reversal;\n let(reversal_window): external_reversal_within;\n let(instrument_words): words(instrument);\n when(derived_amount) {\n let(derived_field): get(derived_amount, "field");\n let(derived_source): get(derived_amount, "source");\n let(derived_rule): get(derived_amount, "rule");\n let(derived_bearer): get(derived_amount, "bearer");\n }\n agent_description: "Reach for captured payment when the {payee} reserves against the {payer} first and then takes the money in slices before {reserve_until}. Pick instant transfer when the whole amount moves at once, and deposit when the reservation is claimed or returned whole.";\n summary: "Capture reservation from {payer} to {payee}";\n title: sentence(instrument);\n description: "Payer reservation captured by the payee in slices within a fixed window";\n fields {\n when(derived_amount) {\n let(fee_collection_key): "x-hyperscale-fee-collection-port";\n let(reference_filter_key): "x-hyperscale-reference-filter";\n platformAccountId {\n type: account<C>;\n description: "The product fee collection account";\n pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$";\n [fee_collection_key]: true;\n [reference_filter_key]: { column: role; values: [customer_balance, product_revenue]; };\n }\n }\n amount { type: money<C>; description: "Maximum captured amount in {C} minor units"; }\n reserve_until { type: date; description: "Reservation expiry that releases any uncaptured remainder"; }\n reversalUntil { type: date; description: "Machine-owned external reversal cutoff anchored when settlement completes"; optional: true; }\n when(derived_amount) {\n [derived_field] { type: money<C>; description: "Machine-computed {derived_rule} of {derived_source}; callers never supply it"; pattern: "^[1-9][0-9]{0,17}$"; optional: true; }\n }\n }\n lifecycle {\n states created authorized partially_captured settled voided expired corrected reversed;\n initial created;\n on authorize: created -> authorized;\n on capture: authorized -> partially_captured;\n on capture_more: partially_captured -> partially_captured;\n on settle: authorized | partially_captured -> settled;\n on void: authorized -> voided;\n on expire: authorized -> expired;\n on settle_on_expiry: partially_captured -> settled;\n on [correction_name]: settled -> corrected;\n on [reversal_name]: settled -> reversed;\n }\n parties {\n payer: payer;\n beneficiary: payee;\n }\n when(derived_amount) {\n computes derived: { field: derived_field; source_field: derived_source; rounding: floor; rule: { kind: percentage_of; bps: derived_rule; }; };\n }\n action create {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: "Open the payment row before anything is reserved. The caller supplies the {amount}, the currency, and both party accounts. This reserves nothing, call authorize next.";\n summary: "Create a {instrument_words}";\n when(derived_amount) {\n moves: [{ key: "derived_amount"; operation: internal_transfer.create; bind: { amount: { from: instance; path: concat("fields.", derived_field); }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: fields.platformAccountId; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: create; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", camel(derived_bearer), "AccountId"); }; }; capture: { createDerivedAmountTransferId: transferId; }; }];\n }\n steps: [];\n }\n action authorize {\n agent_description: "Reserve the {amount} against the {payer} in the {payee}\'s favor until {reserve_until}. The payment must be created. The money is held, not paid: capture and settle post it, void and expiry release it.";\n summary: "Reserve the {amount} until {reserve_until}";\n moves: [{ key: reservation; amount: amount; from: payer; to: beneficiary; operation: reserve; }];\n steps: [];\n }\n action capture {\n agent_description: "Post the first capture slice out of the live reservation. The payment must be authorized and the caller passes captureAmount in minor units. The slice settles for good and void can no longer release the reservation. Call before {reserve_until}.";\n summary: "Post one strict partial capture slice";\n deadline { field: reserve_until; };\n input { type: object; additional_properties: false; properties: { captureAmount: { description: "Positive partial capture amount in minor units"; pattern: "^[1-9][0-9]{0,17}$"; type: string; }; }; required: [captureAmount]; }\n moves: [{ key: post; operation: internal_transfer.post; bind: { amount: { from: input; path: captureAmount; }; currency: { from: instance; path: fields.currency; }; postMode: { from: const; value: partial_only; }; transferId: { from: instance; path: refs.authorizeReservationTransferId; }; }; capture: { capturedAmount: postedAmount; }; }];\n steps: [];\n }\n action capture_more {\n agent_description: "Post another capture slice out of a partly captured reservation. Call this only after capture took the first slice. Each slice settles for good, and the uncaptured remainder still releases at {reserve_until}.";\n summary: "Post another strict partial capture slice";\n deadline { field: reserve_until; };\n input { type: object; additional_properties: false; properties: { captureAmount: { description: "Positive partial capture amount in minor units"; pattern: "^[1-9][0-9]{0,17}$"; type: string; }; }; required: [captureAmount]; }\n moves: [{ key: post; operation: internal_transfer.post; bind: { amount: { from: input; path: captureAmount; }; currency: { from: instance; path: fields.currency; }; postMode: { from: const; value: partial_only; }; transferId: { from: instance; path: refs.authorizeReservationTransferId; }; }; capture: { capturedAmount: postedAmount; }; }];\n steps: [];\n }\n action settle {\n agent_description: "Post the whole reserved remainder and finish the payment. The payment must be authorized or partly captured. The money settles and the external reversal window opens on reversalUntil.";\n summary: "Post the full reserved remainder and settle";\n deadline { field: reserve_until; };\n sets(at) { field: reversalUntil; offset: reversal_window; };\n moves: [{ key: post; operation: internal_transfer.post; bind: { transferId: { from: instance; path: refs.authorizeReservationTransferId; }; }; capture: { capturedAmount: postedAmount; }; }];\n steps: [];\n }\n action void {\n agent_description: "Release the reservation whole and cancel the payment. Only an authorized reservation with nothing captured can void. Once any slice is captured, settle it or let it expire instead.";\n summary: "Release an entirely uncaptured reservation";\n moves: [{ key: void; operation: internal_transfer.void; bind: { reason: { from: const; value: "Reservation voided before any capture"; }; transferId: { from: instance; path: refs.authorizeReservationTransferId; }; }; }];\n steps: [];\n }\n action expire {\n summary: "Release an uncaptured reservation at expiry";\n due { field: reserve_until; };\n moves: [{ key: void; operation: internal_transfer.void; bind: { reason: { from: const; value: "Uncaptured reservation expired"; }; transferId: { from: instance; path: refs.authorizeReservationTransferId; }; }; }];\n steps: [];\n }\n action settle_on_expiry {\n summary: "Release the uncaptured remainder and settle captured slices";\n due { field: reserve_until; };\n sets(at) { field: reversalUntil; offset: reversal_window; };\n moves: [{ key: void; operation: internal_transfer.void; bind: { reason: { from: const; value: "Uncaptured remainder released at expiry"; }; transferId: { from: instance; path: refs.authorizeReservationTransferId; }; }; }];\n steps: [];\n }\n action [correction_name] {\n let(metadata_clawback): "metadata.clawbackOfTransferId";\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n let(correction_capture): camel(concat(correction_name, "_transfer_transfer_id"));\n agent_description: "Return the whole captured amount to the {payer} after the payment settled. Only a settled payment corrects, and only the party the product authorized may call it. The money moves back and there is no undo.";\n summary: "Return the full captured amount on payee correction";\n port { allowed_parties: [if_eq(at(correction_allowed, 1), payee, "beneficiary", "payer")]; };\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: refs.capturedAmount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", payer, "AccountId"); }; [metadata_clawback]: { from: instance; path: refs.authorizeReservationTransferId; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: correction_name; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payee, "AccountId"); }; }; capture: { [correction_capture]: transferId; }; }];\n steps: [];\n }\n action [reversal_name] {\n let(metadata_clawback): "metadata.clawbackOfTransferId";\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n let(reversal_capture): camel(concat(reversal_name, "_transfer_transfer_id"));\n agent_description: "Return the whole captured amount to the {payer} on an external reversal. The payment must be settled and the call must land before reversalUntil. The caller passes externalReference, which stays in the receipt. There is no undo.";\n summary: "Return the full captured amount on an external reversal";\n capture(input) { externalReference: externalReference; };\n deadline { field: reversalUntil; };\n input { type: object; additional_properties: false; properties: { externalReference: { description: "Required decision reference retained in the operation receipt"; max_length: 180; min_length: 1; type: string; }; }; required: [externalReference]; }\n port { allowed_parties: [if_eq(at(external_reversal_allowed, 1), payee, "beneficiary", "payer")]; };\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: refs.capturedAmount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", payer, "AccountId"); }; [metadata_clawback]: { from: instance; path: refs.authorizeReservationTransferId; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: reversal_name; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payee, "AccountId"); }; }; capture: { [reversal_capture]: transferId; }; }];\n steps: [];\n }\n}\n',
18
+ ],
19
+ [
20
+ "settlements/conditional_disbursement.hsx",
21
+ 'module std.settlements.conditional_disbursement\n\nexport instrument conditional_disbursement<C>(\n source: party,\n destination: party,\n cap: money<C>,\n amount: money<C>,\n decision: condition,\n reopen_policy: text,\n recovery_policy: text,\n) {\n let(child_id): concat(instrument, "_approved_amount");\n let(child_amount): "amount";\n let(parent_field): camel(concat(instrument, "_id"));\n let(source_field): camel(concat(source, "_account_id"));\n let(destination_field): camel(concat(destination, "_account_id"));\n let(currency_path): "fields.currency";\n let(source_path): concat("fields.", source_field);\n let(destination_path): concat("fields.", destination_field);\n\n title: sentence(instrument);\n agent_description: "Reach for conditional disbursement when the {source} pays the {destination} only against stored external evidence and the payouts must stay under {cap}. Each approved amount is its own child row. Pick instant transfer when no evidence gates the payment.";\n summary: "Capped disbursement to {destination}";\n description: "Capped disbursement controlled by stored external evidence";\n id_prefix: prefix(instrument);\n fields {\n cap {\n type: money<C>;\n description: "Disbursement cap in {C} minor units";\n }\n }\n required: [destination_field, source_field, currency, cap];\n lifecycle {\n states submitted denied;\n initial submitted;\n on deny: submitted -> denied;\n }\n parties {\n beneficiary: destination;\n payer: source;\n }\n action create {\n agent_description: "Open the capped disbursement before any amount is approved. The caller supplies the {cap}, the currency, and the {source} and {destination} accounts. No money moves and nothing is approved yet.";\n summary: "Submit the capped disbursement";\n steps: [];\n moves: [];\n }\n action deny {\n agent_description: "Refuse the whole disbursement without moving money. Every child amount under it must still be unapproved, so call this before any approval lands. The caller passes evidenceReference, which stays in the receipt. Denial is final.";\n summary: "Record a denial without moving money";\n input: {\n additional_properties: false;\n properties: {\n evidence_reference: {\n description: "Required decision reference retained in the operation receipt";\n max_length: 180;\n min_length: 1;\n type: "string";\n };\n };\n required: [evidenceReference];\n type: "object";\n };\n capture_input: { decision_evidence_reference: evidenceReference; };\n port: { allowed_parties: [payer]; };\n requires aggregate: {\n check: { kind: all_in; };\n instrument_id: child_id;\n over: children;\n ref_field: parent_field;\n statuses: [created];\n };\n steps: [];\n moves: [];\n }\n\n instruments {\n instrument {\n id: child_id;\n generatedPrefix: true;\n title: concat(sentence(instrument), " Approved Amount");\n agent_description: concat("Reach for this child row to hold one evidence-gated amount under a ", words(instrument), ". The parent carries the {cap}, this row carries one approved amount and pays it once.");\n summary: "Approved amount under {instrument}";\n description: "One evidence-gated amount under {instrument}";\n fields {\n [child_amount] {\n type: money<C>;\n description: "Approved amount under the parent cap";\n }\n currency {\n type: text;\n description: "ISO 4217 currency code";\n max_length: 3;\n min_length: 3;\n pattern: "^[A-Z]{3}$";\n }\n [parent_field] {\n type: ref<instrument>;\n description: "The exact {instrument}";\n pattern: concat("^", prefix(instrument), "_(sandbox|live)_[a-z0-9]{8,64}$");\n }\n }\n required: [destination_field, source_field, child_amount, currency, parent_field];\n lifecycle {\n states created approved paid;\n initial created;\n on approve: created -> approved;\n on pay: approved -> paid;\n }\n parties {\n beneficiary: destination;\n payer: source;\n }\n action create {\n agent_description: concat("Create one candidate amount under the parent ", words(instrument), ". The parent must still be submitted and the currency and both accounts must match it. No money moves and the amount is not approved yet.");\n summary: "Create one candidate amount under the parent";\n requires refs: {\n bind: {\n currency: currency_path;\n [destination_field]: destination_path;\n [source_field]: source_path;\n };\n field: parent_field;\n statuses: [submitted];\n unique: true;\n };\n steps: [];\n moves: [];\n }\n action approve {\n agent_description: "Store one externally approved amount under the parent cap. The row must be created, the parent still submitted, and the already approved and paid amounts plus this one must stay within {cap}. The caller passes evidenceReference. No money moves yet.";\n summary: "Store one externally approved amount under the cap";\n input: {\n additional_properties: false;\n properties: {\n evidence_reference: {\n description: "Required decision reference retained in the operation receipt";\n max_length: 180;\n min_length: 1;\n type: "string";\n };\n };\n required: [evidenceReference];\n type: "object";\n };\n capture_input: { decision_evidence_reference: evidenceReference; };\n port: { allowed_parties: [payer]; };\n requires exposure: {\n amount_field: child_amount;\n anchor_field: parent_field;\n cap_field: cap;\n cap_on_anchor: true;\n child_instrument_id: child_id;\n statuses: [approved, paid];\n };\n requires refs: {\n field: parent_field;\n match: {\n [currency_path]: currency_path;\n [destination_path]: destination_path;\n [source_path]: source_path;\n };\n statuses: [submitted];\n };\n steps: [];\n moves: [];\n }\n action pay {\n agent_description: "Pay the stored approved amount to the {destination} once. The row must be approved and the parent still submitted. The transfer posts straight out of the {source} and does not unwind.";\n summary: "Pay the stored approved amount once";\n requires refs: {\n field: parent_field;\n match: {\n [currency_path]: currency_path;\n [destination_path]: destination_path;\n [source_path]: source_path;\n };\n statuses: [submitted];\n };\n moves: [{ amount: child_amount; from: payer; to: beneficiary; key: payout; operation: create; }];\n steps: [];\n }\n }\n }\n}\n',
22
+ ],
23
+ [
24
+ "settlements/credit_facility.hsx",
25
+ 'module std.settlements.credit_facility\n\nexport instrument credit_facility<C>(\n lender: party,\n borrower: party,\n draw_destination: party,\n limit: money<C>,\n expires_at: date,\n obligation: ref,\n availability_policy: text,\n expiry_policy: text,\n close_policy: text,\n) {\n let(draw_id): concat(instrument, "_draw");\n let(parent_field): camel(concat(instrument, "_id"));\n let(borrower_field): camel(concat(borrower, "_account_id"));\n let(lender_field): camel(concat(lender, "_account_id"));\n let(destination_field): camel(concat(draw_destination, "_account_id"));\n let(currency_path): "fields.currency";\n let(lender_path): concat("fields.", lender_field);\n let(destination_path): concat("fields.", destination_field);\n let(reference_filter): "x-hyperscale-reference-filter";\n let(obligation_name): owner(obligation);\n let(obligation_field): camel(concat(obligation_name, "_id"));\n\n title: sentence(instrument);\n agent_description: "Reach for credit facility when the {lender} gives the {borrower} reusable capacity up to {limit} and every draw is repaid through its own scheduled obligation. Capacity frees up as each obligation resolves. Pick advance for one up-front payment with no reusable limit.";\n summary: "Draw capacity for {borrower}";\n description: "Reusable capacity with repayment delegated to one scheduled obligation";\n id_prefix: prefix(instrument);\n fields {\n [borrower_field] {\n type: account<C>;\n description: "The {borrower} account";\n pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$";\n [reference_filter]: {\n column: role;\n values: [customer_balance];\n };\n }\n limit {\n type: money<C>;\n description: "Facility limit in {C} minor units";\n }\n expires_at {\n type: date;\n description: "Stored draw expiry";\n }\n }\n required: [borrower_field, destination_field, lender_field, currency, limit, expires_at];\n lifecycle {\n states active frozen closed;\n initial active;\n on freeze: active -> frozen;\n on close: active|frozen -> closed;\n }\n parties {\n beneficiary: draw_destination;\n payer: lender;\n }\n action create {\n agent_description: "Open the facility before any draw exists. The caller supplies the {limit}, the currency, the {borrower} and {lender} accounts, the draw destination account, and the stored expiry. No money moves.";\n summary: "Open the facility";\n steps: [];\n moves: [];\n }\n action freeze {\n summary: "Freeze new draws at expiry";\n due: { field: expires_at; };\n steps: [];\n moves: [];\n }\n action close {\n agent_description: "Close the facility for good. Every draw under it must already be resolved, so clear the outstanding obligations first. No money moves and a closed facility never lends again.";\n summary: "Close only when every admitted draw resolved";\n requires aggregate: {\n check: { kind: all_in; };\n instrument_id: draw_id;\n over: children;\n ref_field: parent_field;\n statuses: [resolved];\n };\n steps: [];\n moves: [];\n }\n\n instruments {\n instrument {\n id: draw_id;\n generatedPrefix: true;\n title: concat(sentence(instrument), " Draw");\n agent_description: concat("Reach for this child row to take one draw against a ", words(instrument), ". The parent carries the {limit}, this row carries one drawn amount and the single obligation that repays it.");\n summary: "Draw from {instrument}";\n description: "One capacity-capped draw linked to obligation";\n fields {\n amount {\n type: money<C>;\n description: "One draw amount";\n }\n currency {\n type: text;\n description: "ISO 4217 currency code";\n max_length: 3;\n min_length: 3;\n pattern: "^[A-Z]{3}$";\n }\n [parent_field] {\n type: ref<instrument>;\n description: "The exact {instrument}";\n pattern: concat("^", prefix(instrument), "_(sandbox|live)_[a-z0-9]{8,64}$");\n }\n [obligation_field] {\n type: ref<obligation_name>;\n description: "The sole repayment obligation";\n pattern: concat("^", prefix(obligation_name), "_(sandbox|live)_[a-z0-9]{8,64}$");\n }\n }\n required: [destination_field, lender_field, amount, currency, parent_field, obligation_field];\n lifecycle {\n states drawn resolved;\n initial drawn;\n on resolve: drawn -> resolved;\n }\n parties {\n beneficiary: draw_destination;\n payer: lender;\n }\n action create {\n agent_description: "Draw one amount out of the facility to the draw destination account. The facility must be active, the linked obligation active and bound to no other draw, and the drawn amounts plus this one must stay within {limit}. The money leaves the {lender} straight away.";\n summary: "Create one draw under the locked facility capacity";\n requires exposure: {\n amount_field: amount;\n anchor_field: parent_field;\n cap_field: limit;\n cap_on_anchor: true;\n child_instrument_id: draw_id;\n statuses: [drawn];\n };\n requires refs: [{\n bind: {\n currency: currency_path;\n [destination_field]: destination_path;\n [lender_field]: lender_path;\n };\n field: parent_field;\n statuses: [active];\n }, {\n field: obligation_field;\n statuses: [active];\n unique: true;\n }];\n moves: [{ amount: amount; from: payer; to: beneficiary; key: draw; operation: create; }];\n steps: [];\n }\n action resolve {\n agent_description: "Free the drawn capacity back to the facility. The linked obligation must already be repaid or written off. No money moves here, the obligation did the repaying.";\n summary: "Release revolving capacity only after the linked obligation resolves";\n requires refs: {\n field: obligation_field;\n statuses: [repaid, written_off];\n };\n steps: [];\n moves: [];\n }\n }\n }\n}\n',
26
+ ],
27
+ [
28
+ "settlements/held_payment.hsx",
29
+ 'module std.settlements.held_payment\n\nexport instrument held_payment<C>(payer: party, payee: party, amount: money<C>, release: condition, fees: optional<block>, on_cancel: optional<block>, derived_amount: optional<block>, release_to: optional<party>, whole_amount: optional<block>, release_action: optional<text>, whole_fee: optional<money<C>>, reference: optional<text>, upstream: optional<ref>, id_prefix_override: optional<text>) {\n let(release_name): release;\n let(release_actor): at(release_allowed, 1);\n let(release_actor_2): at(release_allowed, 2);\n let(release_multiple): lt(1, len(release_allowed));\n let(release_role): if_eq(release_actor, payer, "payer", "beneficiary");\n let(release_role_2): if_eq(release_actor_2, payer, "payer", "beneficiary");\n let(release_actor_text): if_eq(len(release_allowed), 2, concat(words(release_actor), " or ", words(release_actor_2)), words(release_actor));\n let(payer_account_field): camel(concat(payer, "_account_id"));\n let(payee_account_field): camel(concat(payee, "_account_id"));\n let(release_to_account_field): camel(concat(release_to, "_account_id"));\n let(payer_fee): get(fees, payer);\n let(payee_fee): get(fees, payee);\n let(payer_fee_kind): kind(payer_fee);\n let(payee_fee_kind): kind(payee_fee);\n when_eq(payee_fee_kind, binding) {\n when(on_cancel) {\n unsupported {\n code: HSX1110;\n message: "exact payee fees cannot combine with on_cancel yet";\n fix: "remove on_cancel or use a percentage payee fee";\n }\n }\n }\n let(payer_bps): basis_points(payer_fee);\n let(payee_bps): basis_points(payee_fee);\n let(net_bps): sub(10000, payee_fee);\n let(net_percent): percent_text(net_bps);\n let(cancel_payer): get(on_cancel, payer);\n let(cancel_payee): get(on_cancel, payee);\n let(cancel_payer_bps): basis_points(cancel_payer);\n let(cancel_payee_bps): basis_points(cancel_payee);\n let(cancel_splits): lt(1, len(on_cancel));\n let(piece1_bps): min(net_bps, cancel_payer_bps);\n let(piece3_bps): min(payee_bps, cancel_payee_bps);\n let(piece2_bps): sub(sub(10000, piece1_bps), piece3_bps);\n let(piece1_percent): percent_text(piece1_bps);\n let(piece2_percent): percent_text(piece2_bps);\n let(piece3_percent): percent_text(piece3_bps);\n let(carved_spans): lt(cancel_payee_bps, payee_bps);\n let(derived_field): get(derived_amount, "field");\n let(derived_source): get(derived_amount, "source");\n let(derived_rule): get(derived_amount, "rule");\n let(derived_bearer): get(derived_amount, "bearer");\n agent_description: concat("Reach for ", words(instrument), " when the ", words(payer), " must commit money up front and nobody is paid until ", release, " fires. Funding moves ", amount, " into this settlement\'s own escrow account, where it stays until a release or an unwind pays it out. A straight-through payment with no custody step is a different shape.");\n when_not(whole_amount) {\n summary: concat("Escrow-held payment from ", words(payer), " to ", words(payee));\n title: sentence(instrument);\n when_not(release_to) { description: concat("Held payment: the ", words(payer), " funds ", amount, " into this settlement\'s own escrow; ", release_actor_text, " confirms through ", release, " to release"); }\n when(release_to) { description: concat("Held payment: the ", words(payer), " funds ", amount, " into this settlement\'s own escrow; ", release_actor_text, " confirms through ", release, " to release to the ", words(release_to), ", whose advance the ", words(payee), " repays out of it"); }\n fields {\n let(fee_collection_key): "x-hyperscale-fee-collection-port";\n let(reference_filter_key): "x-hyperscale-reference-filter";\n when(release_to) {\n [release_to_account_field] { type: account<C>; description: concat("The ", words(release_to), " account"); pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; [reference_filter_key]: { column: role; values: [customer_balance]; }; }\n }\n platformAccountId {\n type: account<C>;\n description: "The product fee collection account";\n pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$";\n [fee_collection_key]: true;\n [reference_filter_key]: { column: role; values: [customer_balance, product_revenue]; };\n }\n when_not(payee_fee) {\n when_not(cancel_splits) { amount { type: money<C>; description: "The held amount in {C} minor units, funded and paid out whole"; } }\n when(cancel_splits) {\n amount { type: money<C>; description: "The gross held amount in {C} minor units; the piece fields below partition it exactly"; }\n piece1Amount { type: money<C>; description: concat(cancel_payer, " of ", amount, " (carries the integer-division remainder): released to the ", payee, "; on cancellation to the ", payer, ". Computed as floor(", amount, " * ", cancel_payer_bps, " / 10000) in ", C, " minor units"); pattern: "^[1-9][0-9]{0,17}$"; }\n piece2Amount { type: money<C>; description: concat(cancel_payee, " of ", amount, ": released to the ", payee, "; on cancellation to the ", payee, ". Computed as floor(", amount, " * ", cancel_payee_bps, " / 10000) in ", C, " minor units"); pattern: "^[1-9][0-9]{0,17}$"; }\n }\n }\n when(payee_fee) {\n amount { type: money<C>; description: "The gross held amount in {C} minor units; the piece fields below partition it exactly"; }\n when_not(on_cancel) {\n when_eq(payee_fee_kind, percent) {\n piece1Amount { type: money<C>; description: concat(net_percent, " of ", amount, " (carries the integer-division remainder): released to the ", payee, ". Computed as floor(", amount, " * ", net_bps, " / 10000) in ", C, " minor units"); pattern: "^[1-9][0-9]{0,17}$"; }\n piece2Amount { type: money<C>; description: concat(payee_fee, " of ", amount, ": released to the platform. Computed as floor(", amount, " * ", payee_bps, " / 10000) in ", C, " minor units"); pattern: "^[1-9][0-9]{0,17}$"; optional: true; }\n }\n when_eq(payee_fee_kind, binding) {\n piece1Amount { type: money<C>; description: concat("The remainder of ", amount, " after the exact ", payee_fee, " fee; released to the ", payee); pattern: "^[1-9][0-9]{0,17}$"; }\n [payee_fee] { type: payee_fee; description: concat("Immutable exact ", payee, " fee in ", C, " minor units; released to the platform"); pattern: "^[1-9][0-9]{0,17}$"; }\n }\n }\n when(on_cancel) {\n piece1Amount { type: money<C>; description: concat(piece1_percent, " of ", amount, " (carries the integer-division remainder): released to the ", payee, "; on cancellation to the ", payer, ". Computed as floor(", amount, " * ", piece1_bps, " / 10000) in ", C, " minor units"); pattern: "^[1-9][0-9]{0,17}$"; }\n when(carved_spans) {\n piece2Amount { type: money<C>; description: concat(piece2_percent, " of ", amount, ": released to the platform; on cancellation to the ", payer, ". Computed as floor(", amount, " * ", piece2_bps, " / 10000) in ", C, " minor units"); pattern: "^[1-9][0-9]{0,17}$"; }\n piece3Amount { type: money<C>; description: concat(piece3_percent, " of ", amount, ": released to the platform; on cancellation to the ", payee, ". Computed as floor(", amount, " * ", piece3_bps, " / 10000) in ", C, " minor units"); pattern: "^[1-9][0-9]{0,17}$"; }\n carvedFeeAmount { type: money<C>; description: "Machine-owned total of the 2 carved platform fee pieces"; pattern: "^[1-9][0-9]{0,17}$"; optional: true; }\n }\n when_not(carved_spans) {\n piece2Amount { type: money<C>; description: concat(piece2_percent, " of ", amount, ": released to the ", payee, "; on cancellation to the ", payee, ". Computed as floor(", amount, " * ", piece2_bps, " / 10000) in ", C, " minor units"); pattern: "^[1-9][0-9]{0,17}$"; }\n piece3Amount { type: money<C>; description: concat(piece3_percent, " of ", amount, ": released to the platform; on cancellation to the ", payee, ". Computed as floor(", amount, " * ", piece3_bps, " / 10000) in ", C, " minor units"); pattern: "^[1-9][0-9]{0,17}$"; optional: true; }\n }\n }\n }\n when_eq(payer_fee_kind, percent) { serviceFeeAmount { type: money<C>; description: concat("Machine-owned ", payer_fee, " service fee computed from ", amount, "; charged on top at funding"); pattern: "^[1-9][0-9]{0,17}$"; optional: true; } }\n when_eq(payer_fee_kind, binding) { [payer_fee] { type: payer_fee; description: concat("Immutable exact ", payer, " fee in ", C, " minor units; charged on top at funding"); pattern: "^[1-9][0-9]{0,17}$"; } }\n when(release_deadline) {\n when_not(release_to) { [release_deadline] { type: date; description: concat("The date an undecided hold releases to the ", words(payee), " on; ", release, " and cancellation decide only before it"); } }\n when(release_to) { [release_deadline] { type: date; description: concat("The date an undecided hold releases to the ", words(release_to), " on; ", release, " and cancellation decide only before it"); } }\n }\n when(derived_amount) { [derived_field] { type: money<C>; description: "Machine-computed {derived_rule} of {derived_source}; callers never supply it"; pattern: "^[1-9][0-9]{0,17}$"; optional: true; } }\n }\n lifecycle {\n when_not(payee_fee) {\n when_not(cancel_splits) {\n states created funded released;\n when(on_cancel) { states cancelled; }\n states abandoned;\n }\n when(cancel_splits) { states created funding_1 funded releasing_1 released cancelling_1 cancelled abandoned; }\n }\n when(payee_fee) {\n when_not(on_cancel) { states created funding_1 funded releasing_1 released abandoned; }\n when(on_cancel) {\n when_eq(payer_fee_kind, percent) { states created funding_1 funding_2 funding_3 funded releasing_1 releasing_2 released cancelling_1 cancelling_2 cancelled abandoning_1 abandoned abandoning_2; }\n when_eq(payer_fee_kind, none) { states created funding_1 funding_2 funded releasing_1 releasing_2 released cancelling_1 cancelling_2 cancelled abandoning_1 abandoned; }\n when_eq(payer_fee_kind, binding) { states created funding_1 funding_2 funded releasing_1 releasing_2 released cancelling_1 cancelling_2 cancelled abandoning_1 abandoned; }\n }\n }\n initial created;\n when_not(payee_fee) {\n when_not(cancel_splits) {\n on fund_piece_1: created -> funded;\n on [release_name]: funded -> released;\n when(release_deadline) { on release_on_deadline: funded -> released; }\n when(on_cancel) { on cancel: funded -> cancelled; }\n }\n when(cancel_splits) {\n on fund_piece_1: created -> funding_1;\n on fund_piece_2: funding_1 -> funded;\n on [release_name]: funded -> releasing_1;\n on release_piece_2: releasing_1 -> released;\n on cancel: funded -> cancelling_1;\n on refund_piece_2: cancelling_1 -> cancelled;\n on unfund_piece_1: funding_1 -> abandoned;\n }\n }\n when(payee_fee) {\n when_not(on_cancel) {\n on fund_piece_1: created -> funding_1;\n on fund_piece_2: funding_1 -> funded;\n on [release_name]: funded -> releasing_1;\n when(release_deadline) { on release_on_deadline: funded -> releasing_1; }\n on release_piece_2: releasing_1 -> released;\n on unfund_piece_1: funding_1 -> abandoned;\n }\n when(on_cancel) {\n on fund_piece_1: created -> funding_1;\n on fund_piece_2: funding_1 -> funding_2;\n when_eq(payer_fee_kind, percent) {\n on fund_piece_3: funding_2 -> funding_3;\n on collect_service_fee: funding_3 -> funded;\n }\n when_eq(payer_fee_kind, none) { on fund_piece_3: funding_2 -> funded; }\n when_eq(payer_fee_kind, binding) { on fund_piece_3: funding_2 -> funded; }\n on [release_name]: funded -> releasing_1;\n on release_piece_2: releasing_1 -> releasing_2;\n on release_piece_3: releasing_2 -> released;\n on cancel: funded -> cancelling_1;\n on refund_piece_2: cancelling_1 -> cancelling_2;\n on refund_piece_3: cancelling_2 -> cancelled;\n when_eq(payer_fee_kind, percent) {\n on unfund_piece_3: funding_3 -> abandoning_2;\n on unfund_piece_2: funding_2 | abandoning_2 -> abandoning_1;\n }\n when_eq(payer_fee_kind, none) { on unfund_piece_2: funding_2 -> abandoning_1; }\n when_eq(payer_fee_kind, binding) { on unfund_piece_2: funding_2 -> abandoning_1; }\n on unfund_piece_1: funding_1 | abandoning_1 -> abandoned;\n }\n }\n on abandon: created -> abandoned;\n }\n parties {\n payer: payer;\n beneficiary: payee;\n }\n when_eq(payer_fee_kind, percent) {\n computes fees: { amount_field: serviceFeeAmount; base_field: amount; bearer_field: payer_account_field; position: on_top; rule: { kind: bps; bps: payer_bps; }; };\n }\n when_eq(payer_fee_kind, binding) {\n computes fees: { amount_field: camel(payer_fee); base_field: amount; bearer_field: payer_account_field; position: on_top; rule: { kind: exact; field: camel(payer_fee); currency_field: currency; }; };\n }\n when(payee_fee) {\n when(on_cancel) {\n action fund_piece_2 {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: concat("Move piece 2 of the split amount from the ", words(payer), " into escrow. Piece 1 must be in escrow first. It debits the ", words(payer), " for real, and the hold is still short of funded until piece 3 lands.");\n summary: "Fund piece 2 of the held amount into escrow";\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece2Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: refs.escrowAccountId; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: fund_piece_2; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payer_account_field); }; }; capture: { fundPiece2TransferTransferId: transferId; }; }];\n steps: [];\n }\n action fund_piece_3 {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: concat("Move piece 3 of the split amount from the ", words(payer), " into escrow. Pieces 1 and 2 must be in escrow first. It debits the ", words(payer), " for real. Where the product charges a percentage payer fee, one more call collects that fee before the hold counts as funded.");\n summary: "Fund piece 3 of the held amount into escrow";\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece3Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: refs.escrowAccountId; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: fund_piece_3; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payer_account_field); }; }; capture: { fundPiece3TransferTransferId: transferId; }; }];\n steps: [];\n }\n when_eq(payer_fee_kind, percent) {\n action collect_service_fee {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: concat("Charge the ", words(payer), " the percentage service fee on top of the held amount and pay it to the platform account. All three funding pieces must be in escrow first. It debits the ", words(payer), " for real and it is the last step of funding.");\n summary: "Collect the payer-side service fee";\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.serviceFeeAmount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: fields.platformAccountId; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: collect_service_fee; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payer_account_field); }; }; capture: { collectServiceFeeTransferTransferId: transferId; }; }];\n steps: [];\n }\n }\n action release_piece_2 {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: concat("Pay piece 2 out of escrow once the release decision has run. Its destination follows the product fee split, either the platform account or the ", words(payee), ". Money leaves escrow on this call and does not come back.");\n summary: "Release piece 2 of the held amount";\n when(carved_spans) { let(release_piece_2_destination): "fields.platformAccountId"; }\n when_not(carved_spans) { let(release_piece_2_destination): concat("fields.", payee_account_field); }\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece2Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: release_piece_2_destination; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: release_piece_2; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { releasePiece2TransferTransferId: transferId; }; }];\n steps: [];\n }\n action release_piece_3 {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: concat("Pay piece 3 out of escrow to the platform account, which closes the release. Piece 2 must be released first. Money leaves escrow on this call and does not come back.");\n summary: "Release piece 3 of the held amount";\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece3Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: fields.platformAccountId; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: release_piece_3; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { releasePiece3TransferTransferId: transferId; }; }];\n steps: [];\n }\n action refund_piece_2 {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: concat("Return piece 2 out of escrow once cancel has run. Its destination follows the product fee split, either the ", words(payer), " or the ", words(payee), ". Money leaves escrow on this call and does not come back.");\n summary: "Return piece 2 on cancellation";\n when(carved_spans) { let(refund_piece_2_destination): concat("fields.", payer_account_field); }\n when_not(carved_spans) { let(refund_piece_2_destination): concat("fields.", payee_account_field); }\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece2Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: refund_piece_2_destination; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: refund_piece_2; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { refundPiece2TransferTransferId: transferId; }; }];\n steps: [];\n }\n action refund_piece_3 {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: concat("Return piece 3 out of escrow to the ", words(payee), ", which closes the cancellation. Piece 2 must be returned first. Money leaves escrow on this call and does not come back.");\n summary: "Return piece 3 on cancellation";\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece3Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", payee_account_field); }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: refund_piece_3; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { refundPiece3TransferTransferId: transferId; }; }];\n steps: [];\n }\n action unfund_piece_1 {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: concat("Return piece 1 from escrow to the ", words(payer), " and abandon the ", words(instrument), ". It runs when only piece 1 was ever funded, or after the later pieces have already gone back. The settlement ends abandoned.");\n summary: "Return piece 1 to the {payer} on abandonment";\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece1Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", payer_account_field); }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: unfund_piece_1; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { unfundPiece1TransferTransferId: transferId; }; }];\n steps: [];\n }\n action unfund_piece_2 {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: concat("Return piece 2 from escrow to the ", words(payer), " while abandoning a part-funded ", words(instrument), ". Funding must have stopped at piece 2, or piece 3 must already be back. Piece 1 still has to be returned after this.");\n summary: "Return piece 2 to the {payer} on abandonment";\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece2Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", payer_account_field); }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: unfund_piece_2; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { unfundPiece2TransferTransferId: transferId; }; }];\n steps: [];\n }\n when_eq(payer_fee_kind, percent) {\n action unfund_piece_3 {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: concat("Return piece 3 from escrow to the ", words(payer), " while abandoning a ", words(instrument), " funded as far as piece 3. Pieces 2 and 1 still have to be returned after this, in that order.");\n summary: "Return piece 3 to the {payer} on abandonment";\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece3Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", payer_account_field); }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: unfund_piece_3; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { unfundPiece3TransferTransferId: transferId; }; }];\n steps: [];\n }\n }\n }\n when_not(on_cancel) {\n when_eq(payee_fee_kind, percent) {\n computes fees: { amount_field: piece2Amount; base_field: amount; bearer_field: payee_account_field; position: carved; rule: { kind: bps; bps: payee_bps; }; };\n partitions: { total_field: amount; piece_fields: [piece1Amount, piece2Amount]; };\n }\n when_eq(payee_fee_kind, binding) {\n computes fees: { amount_field: camel(payee_fee); base_field: amount; bearer_field: payee_account_field; position: carved; rule: { kind: exact; field: camel(payee_fee); currency_field: currency; }; };\n partitions: { total_field: amount; piece_fields: [piece1Amount, camel(payee_fee)]; };\n }\n }\n when(on_cancel) {\n when_eq(payee_fee_kind, percent) {\n when(carved_spans) {\n computes fees: { amount_field: carvedFeeAmount; base_field: amount; bearer_field: payee_account_field; position: carved; rule: { kind: bps; bps: payee_bps; }; };\n }\n when_not(carved_spans) {\n computes fees: { amount_field: piece3Amount; base_field: amount; bearer_field: payee_account_field; position: carved; rule: { kind: bps; bps: payee_bps; }; };\n }\n }\n partitions: { total_field: amount; piece_fields: [piece1Amount, piece2Amount, piece3Amount]; };\n when(carved_spans) { partitions: { total_field: carvedFeeAmount; piece_fields: [piece2Amount, piece3Amount]; }; }\n }\n }\n when_not(payee_fee) {\n when(cancel_splits) { partitions: { total_field: amount; piece_fields: [piece1Amount, piece2Amount]; }; }\n }\n when(derived_amount) {\n computes derived: { field: derived_field; source_field: derived_source; rounding: floor; rule: { kind: percentage_of; bps: derived_rule; }; };\n }\n action create {\n let(owner_id): "owner.id";\n let(owner_type): "owner.type";\n agent_description: concat("Open the ", words(instrument), " and provision the escrow account that holds the funds. This is the first call, and every funding and release action moves money through that account. It does not move the held amount itself.");\n summary: concat("Create a ", words(instrument), " settlement");\n when_not(derived_amount) { moves: []; }\n when(derived_amount) {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n moves: [{ key: "derived_amount"; operation: internal_transfer.create; bind: { amount: { from: instance; path: concat("fields.", derived_field); }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: fields.platformAccountId; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: create; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", camel(derived_bearer), "AccountId"); }; }; capture: { createDerivedAmountTransferId: transferId; }; }];\n }\n steps: [{ operation: "account.escrow.provision"; bind: { currency: { from: instance; path: fields.currency; }; [owner_id]: { from: instance; path: productId; }; [owner_type]: { from: const; value: product; }; productId: { from: instance; path: productId; }; role: { from: const; value: product_escrow; }; }; capture: { escrowAccountId: accountId; }; }];\n }\n action fund_piece_1 {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: concat("Move the ", words(payer), "\'s money into this settlement\'s escrow. Call it after create and before any release. It debits the ", words(payer), " for real, and where the product charges a payer-side fee that fee is taken on top in the same call. Only a later release or unwind moves the money again.");\n summary: "Fund piece 1 of the held amount into escrow";\n when_not(payee_fee) {\n when_not(cancel_splits) { moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: concat("fields.", amount); }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: refs.escrowAccountId; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: fund_piece_1; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payer_account_field); }; }; capture: { fundPiece1TransferTransferId: transferId; }; }]; }\n when(cancel_splits) { moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece1Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: refs.escrowAccountId; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: fund_piece_1; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payer_account_field); }; }; capture: { fundPiece1TransferTransferId: transferId; }; }]; }\n }\n when(payee_fee) { moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece1Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: refs.escrowAccountId; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: fund_piece_1; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payer_account_field); }; }; capture: { fundPiece1TransferTransferId: transferId; }; }]; }\n when_eq(payer_fee_kind, percent) {\n when_not(payee_fee) { moves: [{ key: service_fee; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.serviceFeeAmount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: fields.platformAccountId; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: fund_piece_1; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payer_account_field); }; }; capture: { fundPiece1ServiceFeeTransferId: transferId; }; }]; }\n when(payee_fee) {\n when_not(on_cancel) { moves: [{ key: service_fee; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.serviceFeeAmount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: fields.platformAccountId; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: fund_piece_1; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payer_account_field); }; }; capture: { fundPiece1ServiceFeeTransferId: transferId; }; }]; }\n }\n }\n when_eq(payer_fee_kind, binding) { moves: [{ key: service_fee; operation: internal_transfer.create; bind: { amount: { from: instance; path: concat("fields.", payer_fee); }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: fields.platformAccountId; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: fund_piece_1; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payer_account_field); }; }; capture: { fundPiece1ServiceFeeTransferId: transferId; }; }]; }\n steps: [];\n }\n action [release_name] {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n let(release_capture): camel(concat(release_name, "_transfer_transfer_id"));\n agent_description: concat("Confirm ", release, " and start paying the held money out of escrow. The ", words(instrument), " must be funded first, and the caller must be ", release_actor_text, ". Where the product requires a decision reference, supply it here. Money leaves escrow on this call and does not come back.");\n summary: concat("Confirm through ", release, " and start the release payout");\n when(release_deadline) { deadline { field: release_deadline; }; }\n when(release_fields) {\n input {\n type: object;\n additional_properties: false;\n properties {\n for input_name in keys(release_fields) {\n [input_name] { type: string; description: "Required decision reference retained in the operation receipt"; max_length: 180; min_length: 1; }\n }\n }\n required: keys(release_fields);\n }\n }\n when_not(release_multiple) { port { allowed_parties: [release_role]; }; }\n when(release_multiple) { port { allowed_parties: [release_role, release_role_2]; }; }\n when_not(payee_fee) {\n when_not(cancel_splits) {\n when_not(release_to) { moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: concat("fields.", amount); }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", payee_account_field); }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: release_name; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { [release_capture]: transferId; }; }]; }\n when(release_to) { moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: concat("fields.", amount); }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", release_to_account_field); }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: release_name; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { [release_capture]: transferId; }; }]; }\n }\n when(cancel_splits) { moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece1Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", payee_account_field); }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: release_name; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { [release_capture]: transferId; }; }]; }\n }\n when(payee_fee) { moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece1Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", payee_account_field); }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: release_name; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { [release_capture]: transferId; }; }]; }\n steps: [];\n }\n when(release_deadline) {\n action release_on_deadline {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n when_not(release_to) { summary: "Release to the {payee} when {release_deadline} arrives undecided"; }\n when(release_to) { summary: "Release to the {release_to} when {release_deadline} arrives undecided"; }\n due { field: release_deadline; };\n when_not(payee_fee) {\n when_not(release_to) { moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: concat("fields.", amount); }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", payee_account_field); }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: release_on_deadline; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { releaseOnDeadlineTransferTransferId: transferId; }; }]; }\n when(release_to) { moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: concat("fields.", amount); }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", release_to_account_field); }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: release_on_deadline; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { releaseOnDeadlineTransferTransferId: transferId; }; }]; }\n }\n when(payee_fee) { moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece1Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", payee_account_field); }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: release_on_deadline; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { releaseOnDeadlineTransferTransferId: transferId; }; }]; }\n steps: [];\n }\n }\n when(on_cancel) {\n action cancel {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: concat("Cancel the ", words(instrument), " and start returning the held money to the ", words(payer), ". It must be funded and not yet released. Cancellation is final, and a cancelled settlement never releases. Where the product sets a release deadline, this call is refused once that date passes.");\n summary: "Cancel the settlement and start the unwind";\n when(release_deadline) { deadline { field: release_deadline; }; }\n when_not(payee_fee) {\n when_not(cancel_splits) { moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: concat("fields.", amount); }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", payer_account_field); }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: cancel; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { cancelTransferTransferId: transferId; }; }]; }\n when(cancel_splits) { moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece1Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", payer_account_field); }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: cancel; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { cancelTransferTransferId: transferId; }; }]; }\n }\n when(payee_fee) { moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece1Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", payer_account_field); }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: cancel; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { cancelTransferTransferId: transferId; }; }]; }\n steps: [];\n }\n }\n when(payee_fee) {\n when_not(on_cancel) {\n action fund_piece_2 {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: concat("Move the carved platform fee piece from the ", words(payer), " into escrow, which completes funding. Piece 1 must be in escrow first. It debits the ", words(payer), " for real, and the whole held amount then sits in escrow.");\n summary: "Fund piece 2 of the held amount into escrow";\n when_eq(payee_fee_kind, percent) { moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece2Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: refs.escrowAccountId; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: fund_piece_2; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payer_account_field); }; }; capture: { fundPiece2TransferTransferId: transferId; }; }]; }\n when_eq(payee_fee_kind, binding) { moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: concat("fields.", payee_fee); }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: refs.escrowAccountId; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: fund_piece_2; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payer_account_field); }; }; capture: { fundPiece2TransferTransferId: transferId; }; }]; }\n steps: [];\n }\n action release_piece_2 {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: concat("Pay the carved platform fee out of escrow to the platform account, which closes the release. The release decision must have run first. Money leaves escrow on this call and does not come back.");\n summary: "Release piece 2 of the held amount";\n when_eq(payee_fee_kind, percent) { moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece2Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: fields.platformAccountId; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: release_piece_2; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { releasePiece2TransferTransferId: transferId; }; }]; }\n when_eq(payee_fee_kind, binding) { moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: concat("fields.", payee_fee); }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: fields.platformAccountId; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: release_piece_2; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { releasePiece2TransferTransferId: transferId; }; }]; }\n steps: [];\n }\n action unfund_piece_1 {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: concat("Return piece 1 from escrow to the ", words(payer), " and abandon the ", words(instrument), ". It runs only while funding stopped after piece 1, before the release. The settlement ends abandoned.");\n summary: "Return piece 1 to the {payer} on abandonment";\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece1Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", payer_account_field); }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: unfund_piece_1; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { unfundPiece1TransferTransferId: transferId; }; }];\n steps: [];\n }\n }\n }\n when_not(payee_fee) {\n when(cancel_splits) {\n action fund_piece_2 {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: concat("Move piece 2 of the split amount from the ", words(payer), " into escrow, which completes funding. Piece 1 must be in escrow first. It debits the ", words(payer), " for real, and the whole held amount then sits in escrow.");\n summary: "Fund piece 2 of the held amount into escrow";\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece2Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: refs.escrowAccountId; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: fund_piece_2; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payer_account_field); }; }; capture: { fundPiece2TransferTransferId: transferId; }; }];\n steps: [];\n }\n action release_piece_2 {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: concat("Pay piece 2 out of escrow to the ", words(payee), ", which closes the release. The release decision must have run first. Money leaves escrow on this call and does not come back.");\n summary: "Release piece 2 of the held amount";\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece2Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", payee_account_field); }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: release_piece_2; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { releasePiece2TransferTransferId: transferId; }; }];\n steps: [];\n }\n action refund_piece_2 {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: concat("Return piece 2 out of escrow to the ", words(payee), ", which closes the cancellation. Cancel must have run first. Money leaves escrow on this call and does not come back.");\n summary: "Return piece 2 on cancellation";\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece2Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", payee_account_field); }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: refund_piece_2; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { refundPiece2TransferTransferId: transferId; }; }];\n steps: [];\n }\n action unfund_piece_1 {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: concat("Return piece 1 from escrow to the ", words(payer), " and abandon the ", words(instrument), ". It runs only while funding stopped after piece 1, before the release. The settlement ends abandoned.");\n summary: "Return piece 1 to the {payer} on abandonment";\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece1Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", payer_account_field); }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: unfund_piece_1; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { unfundPiece1TransferTransferId: transferId; }; }];\n steps: [];\n }\n }\n }\n action abandon {\n agent_description: concat("Close a ", words(instrument), " that was never funded. The escrow account must be empty, so this refuses once any piece is in it. It moves no money and the settlement ends here with no way back.");\n summary: "Abandon the settlement before any money is held";\n requires drained: { path: refs.escrowAccountId; };\n moves: [];\n steps: [];\n }\n }\n when(whole_amount) {\n let(fee_collection_key): "x-hyperscale-fee-collection-port";\n let(reference_filter_key): "x-hyperscale-reference-filter";\n let(whole_fee_field): camel(whole_fee);\n title: sentence(instrument);\n id_prefix: if_eq(id_prefix_override, false, prefix(instrument), id_prefix_override);\n summary: concat("Escrow-held payment from ", words(payer), " to ", words(payee));\n description: concat("Held payment: the ", words(payer), " funds ", amount, " into this settlement\'s own escrow; ", release_actor_text, " confirms through ", release, " to release");\n distinct_parties: true;\n caller_parked_states: { created: "The tenant either funds the hold or abandons it before any money moves."; };\n fields {\n currency { type: text; description: "One currency for the hold and its fee"; const: C; }\n amount { type: money<C>; description: "Amount held in custody, in {C} minor units"; }\n [payee]AccountId { type: account<C>; description: "Party the hold protects and pays on release"; pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; [reference_filter_key]: { column: role; values: [customer_balance]; }; }\n [payer]AccountId { type: account<C>; description: "Party whose money is held until the hold resolves"; pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; [reference_filter_key]: { column: role; values: [customer_balance]; }; }\n platformAccountId { type: account<C>; description: "Product revenue or customer balance account collecting the custody fee"; pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; [fee_collection_key]: true; [reference_filter_key]: { column: role; values: [customer_balance, product_revenue]; }; }\n when(reference) { reference { type: text; description: "The tenant\'s own identifier for what is held: invoice number, project code, contract reference"; optional: true; max_length: 180; min_length: 1; } }\n [release_deadline] { type: date; description: "Date the hold releases to the payee on its own; fixed at creation and the cutoff for both the release port and cancellation"; }\n whole_fee { type: money<C>; description: "Custody fee charged on top at funding and never placed in escrow"; }\n when(upstream) { upstream { type: ref<instrument>; description: "Hold this one is carved out of, when a chain of holds passes the same money down"; optional: true; pattern: concat("^", id_prefix_override, "_(sandbox|live)_[a-z0-9]{8,64}$"); } }\n }\n lifecycle {\n states created funded released cancelled abandoned;\n initial created;\n on abandon: created -> abandoned;\n on cancel: funded -> cancelled;\n on fund: created -> funded;\n on [release_action]: funded -> released;\n on release_on_deadline: funded -> released;\n }\n parties { beneficiary: payee_account_field; payer: payer_account_field; }\n required: [payer_account_field, payee_account_field, platformAccountId, amount, whole_fee_field, currency, release_deadline];\n action create {\n let(owner_id): "owner.id";\n let(owner_type): "owner.type";\n agent_description: concat("Open the ", words(instrument), " and provision the escrow account that holds the money. No money moves on this call. ", release_deadline, " is fixed here and never moves again, so one date governs the early release, the cancellation, and the automatic payout.");\n summary: concat("Create a ", words(instrument), " settlement");\n moves: [];\n steps: [{ operation: "account.escrow.provision"; bind: { currency: { from: instance; path: fields.currency; }; [owner_id]: { from: instance; path: productId; }; [owner_type]: { from: const; value: product; }; productId: { from: instance; path: productId; }; role: { from: const; value: product_escrow; }; }; capture: { escrowAccountId: accountId; }; }];\n }\n action fund {\n agent_description: concat("Move ", amount, " from the ", words(payer), " into escrow and charge ", whole_fee_field, " on top to the platform account, as one linked batch. This moves money and the ", words(payer), " pays both. Only a created hold funds. The fee never enters escrow, so it is non-refundable however the hold ends.");\n summary: "Fund the hold and collect the custody fee";\n moves: [\n { key: principal; operation: internal_transfer.create; bind: { amount: { from: instance; path: concat("fields.", amount); }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: refs.escrowAccountId; }; "metadata.instrumentId": { from: const; value: instrument; }; "metadata.instrumentInstanceId": { from: instance; path: instrumentInstanceId; }; "metadata.phase": { from: const; value: fund; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payer_account_field); }; }; capture: { fundingTransferId: transferId; }; },\n { key: service_fee; operation: internal_transfer.create; bind: { amount: { from: instance; path: concat("fields.", whole_fee_field); }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: fields.platformAccountId; }; "metadata.instrumentId": { from: const; value: instrument; }; "metadata.instrumentInstanceId": { from: instance; path: instrumentInstanceId; }; "metadata.phase": { from: const; value: service_fee; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payer_account_field); }; }; capture: { serviceFeeTransferId: transferId; }; }\n ];\n sandbox_failure_point: funding;\n steps: [];\n }\n action [release_action] {\n agent_description: concat("Pay the ", words(payee), " the whole ", amount, " out of escrow ahead of ", release_deadline, ". This moves money and does not reverse. Only a funded hold releases, the caller must act as the ", release_actor_text, ", and the call is refused once ", release_deadline, " passes. The custody fee stays posted.");\n summary: concat("Release the hold to the ", words(payee), " early");\n deadline: { field: release_deadline; };\n port: { allowed_parties: [release_role]; };\n moves: [{ key: release_action; operation: internal_transfer.create; bind: { amount: { from: instance; path: concat("fields.", amount); }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", payee_account_field); }; "metadata.instrumentId": { from: const; value: instrument; }; "metadata.instrumentInstanceId": { from: instance; path: instrumentInstanceId; }; "metadata.phase": { from: const; value: release_action; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { releaseTransferId: transferId; }; }];\n sandbox_failure_point: "release";\n steps: [];\n }\n action release_on_deadline {\n summary: concat("Release the hold to the ", words(payee), " on its release date");\n due: { field: release_deadline; };\n event_name: concat(instrument, ".released_on_deadline");\n moves: [{ key: release_action; operation: internal_transfer.create; bind: { amount: { from: instance; path: concat("fields.", amount); }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", payee_account_field); }; "metadata.instrumentId": { from: const; value: instrument; }; "metadata.instrumentInstanceId": { from: instance; path: instrumentInstanceId; }; "metadata.phase": { from: const; value: deadline_release; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { deadlineReleaseTransferId: transferId; }; }];\n steps: [];\n }\n action cancel {\n agent_description: concat("Return the whole ", amount, " from escrow to the ", words(payer), " and end the hold. This moves money and does not reverse. Only a funded hold cancels, and only before ", release_deadline, " passes. The custody fee stays posted because the custody it paid for was already provided.");\n summary: "Cancel the hold and return the held amount";\n deadline: { field: release_deadline; };\n event_name: concat(instrument, ".cancelled");\n moves: [{ key: refund; operation: internal_transfer.create; bind: { amount: { from: instance; path: concat("fields.", amount); }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", payer_account_field); }; "metadata.instrumentId": { from: const; value: instrument; }; "metadata.instrumentInstanceId": { from: instance; path: instrumentInstanceId; }; "metadata.phase": { from: const; value: cancel_refund; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: refs.escrowAccountId; }; }; capture: { cancelRefundTransferId: transferId; }; }];\n steps: [];\n }\n action abandon {\n agent_description: concat("Close a ", words(instrument), " that was opened and never funded. No money has moved and the escrow must be empty, so this is a lifecycle transition only. A funded hold refuses. Release it to the ", words(payee), " or cancel it back to the ", words(payer), " instead.");\n summary: "Abandon the hold before it is funded";\n moves: [];\n requires_drained: { path: refs.escrowAccountId; };\n steps: [];\n }\n }\n}\n',
30
+ ],
31
+ [
32
+ "settlements/index.hsx",
33
+ "module std.settlements\n\n// Settlement modules are imported by their full std.settlements.<name> path.\n",
34
+ ],
35
+ [
36
+ "settlements/instant_transfer.hsx",
37
+ 'module std.settlements.instant_transfer\n\nexport instrument instant_transfer<C>(payer: party, payee: party, amount: money<C>, fees: optional<block>, derived_amount: optional<block>) {\n let(payer_fee): get(fees, payer);\n let(payee_fee): get(fees, payee);\n let(payer_fee_kind): kind(payer_fee);\n let(payee_fee_kind): kind(payee_fee);\n let(payer_account_field): camel(concat(payer, "_account_id"));\n let(payee_account_field): camel(concat(payee, "_account_id"));\n let(net_bps): sub(10000, payee_fee);\n let(net_percent): percent_text(net_bps);\n let(payee_bps): basis_points(payee_fee);\n let(payee_tiers): values(payee_fee);\n let(first_tier): at(payee_tiers, 1);\n let(second_tier): at(payee_tiers, 2);\n let(second_tier_fee): get(second_tier, "fee");\n when(derived_amount) {\n let(derived_field): get(derived_amount, "field");\n let(derived_source): get(derived_amount, "source");\n let(derived_rule): get(derived_amount, "rule");\n let(derived_bearer): get(derived_amount, "bearer");\n }\n agent_description: concat("Reach for instant transfer when the ", words(payer), " pays the ", words(payee), " straight through with no custody step. The money leaves and lands in one call. Pick deposit when the money must be held first, and captured payment when the payee takes it in slices.");\n summary: concat("Instant payment from ", words(payer), " to ", words(payee));\n title: sentence(instrument);\n description: concat("Instant transfer: the ", words(payer), " pays ", amount, " straight through to the ", words(payee), ", no custody");\n fields {\n when_not(fees) {\n when(derived_amount) {\n let(fee_collection_key): "x-hyperscale-fee-collection-port";\n let(reference_filter_key): "x-hyperscale-reference-filter";\n platformAccountId {\n type: account<C>;\n description: "The product fee collection account";\n pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$";\n [fee_collection_key]: true;\n [reference_filter_key]: { column: role; values: [customer_balance, product_revenue]; };\n }\n }\n }\n when(fees) {\n let(fee_collection_key): "x-hyperscale-fee-collection-port";\n let(reference_filter_key): "x-hyperscale-reference-filter";\n platformAccountId {\n type: account<C>;\n description: "The product fee collection account";\n pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$";\n [fee_collection_key]: true;\n [reference_filter_key]: { column: role; values: [customer_balance, product_revenue]; };\n }\n }\n when_not(fees) {\n amount { type: money<C>; description: "The amount in {C} minor units, paid through whole"; }\n }\n when(fees) {\n amount { type: money<C>; description: "The gross amount in {C} minor units; the piece fields below partition it exactly"; }\n when_eq(payee_fee_kind, percent) {\n piece1Amount { type: money<C>; description: concat(net_percent, " of ", amount, " (carries the integer-division remainder): released to the ", payee, ". Computed as floor(", amount, " * ", net_bps, " / 10000) in ", C, " minor units"); pattern: "^[1-9][0-9]{0,17}$"; }\n piece2Amount { type: money<C>; description: concat(payee_fee, " of ", amount, ": released to the platform. Computed as floor(", amount, " * ", payee_bps, " / 10000) in ", C, " minor units"); pattern: "^[1-9][0-9]{0,17}$"; optional: true; }\n }\n when_eq(payee_fee_kind, block) {\n netOfCarvedFeeAmount { type: money<C>; description: "The remainder of {amount} after the carved platform fee"; pattern: "^[1-9][0-9]{0,17}$"; }\n carvedFeeAmount { type: money<C>; description: "The carved platform fee selected from {amount}"; pattern: "^[1-9][0-9]{0,17}$"; optional: true; }\n }\n when_eq(payer_fee_kind, percent) {\n serviceFeeAmount { type: money<C>; description: "Machine-owned {payer_fee} service fee computed from {amount}; charged on top"; pattern: "^[1-9][0-9]{0,17}$"; optional: true; }\n }\n when_eq(payer_fee_kind, binding) {\n [payer_fee] { type: payer_fee; description: "Immutable exact {payer} fee in {C} minor units"; pattern: "^[1-9][0-9]{0,17}$"; }\n }\n when_eq(payee_fee_kind, block) {\n [second_tier_fee] { type: second_tier_fee; description: "Immutable exact {payee} fee in {C} minor units"; pattern: "^[1-9][0-9]{0,17}$"; }\n }\n }\n when(derived_amount) {\n [derived_field] { type: money<C>; description: "Machine-computed {derived_rule} of {derived_source}; callers never supply it"; pattern: "^[1-9][0-9]{0,17}$"; optional: true; }\n }\n }\n lifecycle {\n when_not(fees) { states created paid; }\n when(fees) { states created paying_1 paying_2 paid; }\n initial created;\n when_not(fees) { on pay_piece_1: created -> paid; }\n when(fees) {\n on pay_piece_1: created -> paying_1;\n on pay_piece_2: paying_1 -> paying_2;\n on collect_service_fee: paying_2 -> paid;\n }\n }\n parties {\n payer: payer;\n beneficiary: payee;\n }\n when(derived_amount) {\n computes derived: { field: derived_field; source_field: derived_source; rounding: floor; rule: { kind: percentage_of; bps: derived_rule; }; };\n }\n when(fees) {\n when_eq(payer_fee_kind, percent) {\n computes fees: { amount_field: serviceFeeAmount; base_field: amount; bearer_field: payer_account_field; position: on_top; rule: { kind: bps; bps: payer_fee; }; };\n }\n when_eq(payer_fee_kind, binding) {\n computes fees: { amount_field: camel(payer_fee); base_field: amount; bearer_field: payer_account_field; position: on_top; rule: { kind: exact; field: camel(payer_fee); currency_field: currency; }; };\n }\n when_eq(payee_fee_kind, percent) {\n computes fees: { amount_field: piece2Amount; base_field: amount; bearer_field: payee_account_field; position: carved; rule: { kind: bps; bps: payee_fee; }; };\n partitions: { total_field: amount; piece_fields: [piece1Amount, piece2Amount]; };\n }\n when_eq(payee_fee_kind, block) {\n computes fees: { amount_field: carvedFeeAmount; base_field: amount; bearer_field: payee_account_field; position: carved; rule: { kind: tiered; tiers: [{ from_inclusive: concat("", get(first_tier, "from")); to_exclusive: concat("", get(first_tier, "to")); rule: { kind: bps; bps: get(first_tier, "fee"); }; }, { from_inclusive: concat("", get(second_tier, "from")); rule: { kind: exact; field: camel(second_tier_fee); currency_field: currency; }; }]; }; };\n partitions: { total_field: amount; piece_fields: [netOfCarvedFeeAmount, carvedFeeAmount]; };\n }\n }\n action create {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: "Open the payment row before anything moves. The caller supplies the {amount}, the currency, and both party accounts. Fee and derived pieces are computed from the {amount}, callers never supply them. Call pay piece 1 to move the money.";\n summary: concat("Create a ", words(instrument), " payment");\n when(derived_amount) {\n moves: [{\n key: "derived_amount";\n operation: internal_transfer.create;\n bind: {\n amount: { from: instance; path: concat("fields.", derived_field); };\n currency: { from: instance; path: fields.currency; };\n destinationAccountId: { from: instance; path: fields.platformAccountId; };\n [metadata_instrument]: { from: const; value: instrument; };\n [metadata_instance]: { from: instance; path: instrumentInstanceId; };\n [metadata_phase]: { from: const; value: create; };\n productId: { from: instance; path: productId; };\n sourceAccountId: { from: instance; path: concat("fields.", camel(derived_bearer), "AccountId"); };\n };\n capture: { createDerivedAmountTransferId: transferId; };\n }];\n }\n steps: [];\n }\n action pay_piece_1 {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: concat("Move the first piece from the ", words(payer), " to the ", words(payee), ". The payment must be created. This moves the whole amount unless the product carves a payee fee, in which case it moves the net share and pay piece 2 takes the fee.");\n summary: "Pay piece 1 of the amount through";\n when_not(fees) {\n moves: [{ key: transfer; amount: amount; from: payer; to: beneficiary; }];\n }\n when(fees) {\n when_eq(payee_fee_kind, none) {\n moves: [{ key: transfer; amount: amount; from: payer; to: beneficiary; }];\n }\n when_eq(payee_fee_kind, percent) {\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece1Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", payee_account_field); }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: pay_piece_1; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payer_account_field); }; }; capture: { payPiece1TransferTransferId: transferId; }; }];\n }\n when_eq(payee_fee_kind, block) {\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.netOfCarvedFeeAmount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", payee_account_field); }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: pay_piece_1; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payer_account_field); }; }; capture: { payPiece1TransferTransferId: transferId; }; }];\n }\n }\n steps: [];\n }\n when(fees) {\n action pay_piece_2 {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: concat("Move the carved platform fee out of the amount. Call this after pay piece 1. When the product carves no ", words(payee), " fee this only steps the payment forward and moves nothing.");\n summary: "Pay piece 2 of the amount through";\n when_eq(payee_fee_kind, percent) {\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.piece2Amount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: fields.platformAccountId; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: pay_piece_2; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payer_account_field); }; }; capture: { payPiece2TransferTransferId: transferId; }; }];\n }\n when_eq(payee_fee_kind, block) {\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.carvedFeeAmount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: fields.platformAccountId; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: pay_piece_2; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payer_account_field); }; }; capture: { payPiece2TransferTransferId: transferId; }; }];\n }\n steps: [];\n }\n action collect_service_fee {\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n agent_description: concat("Finish the payment and collect the service fee the ", words(payer), " owes on top of the amount. Both pieces must already be paid. When the product charges no payer fee this only closes the payment out.");\n summary: "Collect the payer-side service fee";\n when_eq(payer_fee_kind, percent) {\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: fields.serviceFeeAmount; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: fields.platformAccountId; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: collect_service_fee; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payer_account_field); }; }; capture: { collectServiceFeeTransferTransferId: transferId; }; }];\n }\n when_eq(payer_fee_kind, binding) {\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: concat("fields.", payer_fee); }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: fields.platformAccountId; }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: collect_service_fee; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payer_account_field); }; }; capture: { collectServiceFeeTransferTransferId: transferId; }; }];\n }\n steps: [];\n }\n }\n}\n',
38
+ ],
39
+ [
40
+ "settlements/metered.hsx",
41
+ 'module std.settlements.metered\n\nexport instrument metered(\n payer: party,\n payee: party,\n close_by: date,\n rates: unknown,\n) {\n let(instrument_words): words(instrument);\n title: sentence(instrument);\n agent_description: "Reach for metered when the {payer} is billed per unit at a rate card fixed when the period opens, and the period closes on {close_by}. Every charge is its own transfer. Pick recurring collection for a flat repeating amount and instant transfer for a one-off payment.";\n summary: "Metered charges from {payer} on a committed rate card";\n description: "Metered usage: the {payer} is charged per unit at the committed rate card until the period closes on its stored end date";\n\n fields {\n close_by: {\n type: date;\n description: "End of this metering period; the close makes further charges unreachable";\n }\n for item in keys(rates) {\n let(amount_binding): get(rates, item);\n let(rate_words): words(item);\n [amount_binding]: {\n type: amount_binding;\n description: "Per-unit price of {rate_words} in SAR minor units, committed at period open";\n }\n }\n }\n\n parties {\n payer: payer;\n beneficiary: payee;\n }\n\n lifecycle {\n states open closed;\n initial open;\n for item in keys(rates) {\n on charge_[item]: open -> open;\n }\n on close_period: open -> closed;\n }\n\n action create {\n agent_description: "Open the metering period with its committed rate card. The caller supplies the {close_by} anchor and every per-unit price. The prices are fixed here and no later charge can change them. No money moves.";\n summary: "Open a {instrument_words} period with its committed rate card";\n steps: [];\n }\n\n for item in keys(rates) {\n action charge_[item] {\n let(amount_binding): get(rates, item);\n let(amount_field): concat(amount_binding);\n let(rate_words): words(item);\n agent_description: "Charge one metered {rate_words} at the committed price. The period must still be open, so charge before {close_by}. The transfer posts from the {payer} to the {payee} at once and there is no reversal action.";\n summary: "Charge one metered {rate_words}; the emission is the transfer itself";\n moves: [{ amount: amount_field; from: payer; to: beneficiary; key: transfer; }];\n steps: [];\n }\n }\n\n action close_period {\n summary: "Close the metering period; no further usage can be charged";\n due: { field: close_by; };\n steps: [];\n }\n}\n',
42
+ ],
43
+ [
44
+ "settlements/pooled_split.hsx",
45
+ 'module std.settlements.pooled_split\n\nexport instrument pooled_split<C>(payer: party, amount: money<C>, payout_due: date, split: block) {\n let(recipients): keys_except(split, "remainder_to");\n let(recipient_count): len(recipients);\n let(remainder_recipient): get(split, "remainder_to");\n fields {\n currency { type: text; description: "ISO 4217 currency code"; minLength: 3; maxLength: 3; pattern: "^[A-Z]{3}$"; }\n [payer]AccountId { type: account<C>; description: concat("The ", words(payer), " account"); pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; "x-hyperscale-reference-filter": { column: role; values: [customer_balance]; }; }\n amount { type: money<C>; description: concat("The pooled period total in {C} minor units; the share fields below partition it exactly"); }\n payout_due { type: date; description: "The period\'s payout date; the pool distributes from it"; }\n for index in recipient_count {\n let(recipient): at(recipients, index);\n let(share_bps): get(split, recipient);\n [recipient]AccountId { type: account<C>; description: concat("The ", words(recipient), " account"); pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; "x-hyperscale-reference-filter": { column: role; values: [customer_balance]; }; }\n [recipient]ShareAmount {\n type: money<C>;\n description: concat(div_floor(basis_points(share_bps), 100), "% of ", amount, if_eq(recipient, remainder_recipient, " (carries the integer-division remainder): ", ": "), "the ", words(recipient), "\'s share. Computed as floor(", amount, " * ", basis_points(share_bps), " / 10000) in {C} minor units");\n }\n }\n }\n lifecycle {\n states created;\n initial created;\n for index in sub(recipient_count, 1) { states pooling_[index]; }\n states pooled;\n for index in sub(recipient_count, 1) { states distributing_[index]; }\n states distributed;\n for index in recipient_count {\n let(fund_from): if_eq(index, 1, "created", concat("pooling_", sub(index, 1)));\n let(fund_to): if_eq(index, recipient_count, "pooled", concat("pooling_", index));\n on fund_share_[index]: [fund_from] -> [fund_to];\n let(distribute_from): if_eq(index, 1, "pooled", concat("distributing_", sub(index, 1)));\n let(distribute_to): if_eq(index, recipient_count, "distributed", concat("distributing_", index));\n on distribute_share_[index]: [distribute_from] -> [distribute_to];\n }\n }\n parties { beneficiary: concat(camel(at(recipients, 1)), "AccountId"); payer: concat(camel(payer), "AccountId"); }\n required: concat_lists([concat(camel(payer), "AccountId")], suffix_each(recipients, "AccountId"), [concat("", amount), concat("", payout_due)], suffix_each(recipients, "ShareAmount"), ["currency"]);\n title: sentence(instrument);\n id_prefix: prefix(instrument);\n agent_description: concat("Reach for ", words(instrument), " when the ", words(payer), " funds one period total that is then split across ", recipient_count, " fixed recipients by stored share amounts. Callers fund the pool one share at a time. Each recipient\'s payout fires from the stored payout date, not from a call.");\n summary: concat("Period pool from ", words(payer), " split ", recipient_count, " ways");\n description: concat("Pooled split: the ", words(payer), " pools the period\'s ", amount, " share by share; the pool distributes to every recipient in full on the stored payout date");\n partitions { totalField: amount; pieceFields: suffix_each(recipients, "ShareAmount"); }\n action create {\n agent_description: concat("Open a ", words(instrument), " period and provision the escrow account the pool sits in. This is the first call on the period, and funding a share refuses until it lands. It moves no money.");\n summary: concat("Open a ", words(instrument), " period");\n moves: [];\n steps: [{ operation: "account.escrow.provision"; bind: { currency: { from: instance; path: "fields.currency"; }; "owner.id": { from: instance; path: productId; }; "owner.type": { from: const; value: product; }; productId: { from: instance; path: productId; }; role: { from: const; value: product_escrow; }; }; capture: { escrowAccountId: accountId; }; }];\n }\n for index in recipient_count {\n let(recipient): at(recipients, index);\n let(share_field): concat(camel(recipient), "ShareAmount");\n action fund_share_[index] {\n agent_description: concat("Move share ", index, " of the period total, the ", words(recipient), "\'s cut, from the ", words(payer), " into the pool escrow. Shares fund in order, so every earlier share must be in already. It debits the ", words(payer), " for real. The pool pays out from the stored payout date with no release call.");\n summary: concat("Pool share ", index, " of the period total");\n moves: [{ amount: share_field; from: payer; to: refs.escrowAccountId; key: transfer; }];\n steps: [];\n }\n action distribute_share_[index] {\n summary: concat("Distribute the ", words(recipient), "\'s share of the pool");\n due { field: payout_due; }\n moves: [{ amount: share_field; from: refs.escrowAccountId; to: recipient; key: transfer; }];\n steps: [];\n }\n }\n}\n',
46
+ ],
47
+ [
48
+ "settlements/premium_forward.hsx",
49
+ 'module std.settlements.premium_forward\n\nexport instrument premium_forward<C>(\n payer: party,\n carrier: party,\n amount: money<C>,\n bind: condition,\n commission: percent,\n policy_ref: optional<text>,\n renewal_due: optional<date>,\n endorsement: optional<condition>,\n) {\n let(instrument_words): words(instrument);\n let(bind_name): concat(bind);\n let(payer_field): camel(concat(payer, "_account_id"));\n let(carrier_field): camel(concat(carrier, "_account_id"));\n let(amount_field): concat(amount);\n let(net_bps): sub(10000, commission);\n let(fee_bps): add(commission, 0);\n let(net_percent): if_eq(net_bps, 9500, "95%", if_eq(net_bps, 9800, "98%", "87.5%"));\n let(fee_percent): if_eq(fee_bps, 500, "5%", if_eq(fee_bps, 200, "2%", "12.5%"));\n let(bind_roles): if_eq(len(bind_allowed), 2, ["payer", "beneficiary"], ["beneficiary"]);\n let(owner_id_key): "owner.id";\n let(owner_type_key): "owner.type";\n let(metadata_instrument_key): "metadata.instrumentId";\n let(metadata_instance_key): "metadata.instrumentInstanceId";\n let(metadata_phase_key): "metadata.phase";\n let(bind_capture_key): camel(concat(bind, "_transfer_transfer_id"));\n let(fee_port_key): "x-hyperscale-fee-collection-port";\n let(reference_filter_key): "x-hyperscale-reference-filter";\n\n title: sentence(instrument);\n agent_description: "Reach for {instrument_words} when the {payer} pays an insurance premium ahead of cover and the {carrier} must not be paid until the policy binds. The {amount_field} sits in this settlement\'s own escrow until {bind_name} fires. Binding then forwards {net_percent} to the {carrier} and {fee_percent} to the platform.";\n summary: "Premium held for the {carrier} until the policy binds";\n description: "Premium forward: the {payer} funds the {amount_field} into this settlement\'s own escrow; binding through {bind_name} forwards it to the {carrier} exactly once, minus the platform commission";\n partitions: { total_field: amount_field; piece_fields: [piece1Amount, piece2Amount]; };\n\n fields {\n platform_account_id: {\n type: account;\n description: "The product fee collection account";\n pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$";\n [fee_port_key]: true;\n [reference_filter_key]: { column: role; values: [customer_balance, product_revenue]; };\n }\n amount: {\n type: money<C>;\n description: "The gross held amount in {C} minor units; the piece fields below partition it exactly";\n }\n piece1_amount: {\n type: money<C>;\n description: "{net_percent} of {amount_field} (carries the integer-division remainder): released to the {carrier}. Computed as floor({amount_field} * {net_bps} / 10000) in {C} minor units";\n }\n piece2_amount: {\n type: money<C>;\n description: "{fee_percent} of {amount_field}: released to the platform. Computed as floor({amount_field} * {fee_bps} / 10000) in {C} minor units";\n }\n when(policy_ref) {\n policy_ref: {\n type: text;\n description: "Immutable external policy reference recorded with this forward";\n max_length: 180;\n min_length: 1;\n }\n }\n when(renewal_due) {\n renewal_due: {\n type: date;\n description: "Stored renewal due condition for the forwarded policy";\n }\n }\n }\n\n parties { payer: payer; beneficiary: carrier; }\n\n lifecycle {\n states created funding_1 funded releasing_1 released abandoned;\n when(endorsement) { states endorsed lapsed; }\n initial created;\n on fund_piece_1: created -> funding_1;\n on fund_piece_2: funding_1 -> funded;\n on [bind]: funded -> releasing_1;\n on forward_piece_2: releasing_1 -> released;\n on unfund_piece_1: funding_1 -> abandoned;\n on abandon: created -> abandoned;\n when(endorsement) {\n on [endorsement]: released -> endorsed;\n on lapse: released|endorsed -> lapsed;\n }\n }\n\n action create {\n agent_description: "Open the {instrument_words} and provision the escrow account that holds the funds. This is the first call on the settlement, and funding refuses until it lands. It moves no money.";\n summary: "Create a {instrument_words} settlement";\n steps: [{\n operation: "account.escrow.provision";\n bind: {\n currency: { from: instance; path: fields.currency; };\n [owner_id_key]: { from: instance; path: productId; };\n [owner_type_key]: { from: const; value: product; };\n product_id: { from: instance; path: productId; };\n role: { from: const; value: product_escrow; };\n };\n capture: { escrow_account_id: accountId; };\n }];\n }\n\n action fund_piece_1 {\n agent_description: "Move the {carrier}\'s share of the premium from the {payer} into escrow. The settlement must exist and be unfunded. It debits the {payer} for real, and piece 2 still has to fund before the policy can bind.";\n summary: "Fund piece 1 of the held amount into escrow";\n moves: [{\n key: transfer; operation: "internal_transfer.create";\n bind: {\n amount: { from: instance; path: fields.piece1Amount; };\n currency: { from: instance; path: fields.currency; };\n destination_account_id: { from: instance; path: refs.escrowAccountId; };\n source_account_id: { from: instance; path: concat("fields.", payer_field); };\n [metadata_instrument_key]: { from: const; value: instrument; };\n [metadata_instance_key]: { from: instance; path: instrumentInstanceId; };\n [metadata_phase_key]: { from: const; value: fund_piece_1; };\n product_id: { from: instance; path: productId; };\n };\n capture: { fund_piece_1_transfer_transfer_id: transferId; };\n }];\n steps: [];\n }\n\n action fund_piece_2 {\n agent_description: "Move the platform commission piece from the {payer} into escrow, which completes funding. Piece 1 must be in escrow first. It debits the {payer} for real, and the premium is then held whole.";\n summary: "Fund piece 2 of the held amount into escrow";\n moves: [{\n key: transfer; operation: "internal_transfer.create";\n bind: {\n amount: { from: instance; path: fields.piece2Amount; };\n currency: { from: instance; path: fields.currency; };\n destination_account_id: { from: instance; path: refs.escrowAccountId; };\n source_account_id: { from: instance; path: concat("fields.", payer_field); };\n [metadata_instrument_key]: { from: const; value: instrument; };\n [metadata_instance_key]: { from: instance; path: instrumentInstanceId; };\n [metadata_phase_key]: { from: const; value: fund_piece_2; };\n product_id: { from: instance; path: productId; };\n };\n capture: { fund_piece_2_transfer_transfer_id: transferId; };\n }];\n steps: [];\n }\n\n action [bind] {\n agent_description: "Bind the policy through {bind_name} and forward the {carrier}\'s share out of escrow. The premium must be fully funded first, and the call carries the decision reference the product asks for. Money leaves escrow here and does not come back.";\n summary: "Confirm through {bind_name} and start the forward payout";\n input: {\n additional_properties: false;\n properties: {\n for item in keys(bind_fields) {\n [item]: {\n description: "Required decision reference retained in the operation receipt";\n max_length: 180; min_length: 1; type: string;\n }\n }\n };\n required: keys(bind_fields);\n type: object;\n };\n port: { allowed_parties: bind_roles; };\n moves: [{\n key: transfer; operation: "internal_transfer.create";\n bind: {\n amount: { from: instance; path: fields.piece1Amount; };\n currency: { from: instance; path: fields.currency; };\n destination_account_id: { from: instance; path: concat("fields.", carrier_field); };\n source_account_id: { from: instance; path: refs.escrowAccountId; };\n [metadata_instrument_key]: { from: const; value: instrument; };\n [metadata_instance_key]: { from: instance; path: instrumentInstanceId; };\n [metadata_phase_key]: { from: const; value: bind; };\n product_id: { from: instance; path: productId; };\n };\n capture: { [bind_capture_key]: transferId; };\n }];\n steps: [];\n }\n\n action forward_piece_2 {\n agent_description: "Pay the platform commission out of escrow to the fee collection account, which closes the forward. {bind_name} must have run first. Money leaves escrow here and does not come back.";\n summary: "Forward piece 2 of the held amount";\n moves: [{\n key: transfer; operation: "internal_transfer.create";\n bind: {\n amount: { from: instance; path: fields.piece2Amount; };\n currency: { from: instance; path: fields.currency; };\n destination_account_id: { from: instance; path: fields.platformAccountId; };\n source_account_id: { from: instance; path: refs.escrowAccountId; };\n [metadata_instrument_key]: { from: const; value: instrument; };\n [metadata_instance_key]: { from: instance; path: instrumentInstanceId; };\n [metadata_phase_key]: { from: const; value: forward_piece_2; };\n product_id: { from: instance; path: productId; };\n };\n capture: { forward_piece_2_transfer_transfer_id: transferId; };\n }];\n steps: [];\n }\n\n action unfund_piece_1 {\n agent_description: "Return the {carrier}\'s share from escrow to the {payer} and abandon the forward. It runs only while funding stopped after piece 1, before the policy binds. The settlement ends abandoned.";\n summary: "Return piece 1 to the {payer} on abandonment";\n moves: [{\n key: transfer; operation: "internal_transfer.create";\n bind: {\n amount: { from: instance; path: fields.piece1Amount; };\n currency: { from: instance; path: fields.currency; };\n destination_account_id: { from: instance; path: concat("fields.", payer_field); };\n source_account_id: { from: instance; path: refs.escrowAccountId; };\n [metadata_instrument_key]: { from: const; value: instrument; };\n [metadata_instance_key]: { from: instance; path: instrumentInstanceId; };\n [metadata_phase_key]: { from: const; value: unfund_piece_1; };\n product_id: { from: instance; path: productId; };\n };\n capture: { unfund_piece_1_transfer_transfer_id: transferId; };\n }];\n steps: [];\n }\n\n action abandon {\n agent_description: "Close a {instrument_words} that was never funded. The escrow account must be empty, so this refuses once any piece is in it. It moves no money and the settlement ends here.";\n summary: "Abandon the settlement before any money is held";\n requires drained: { path: refs.escrowAccountId; };\n steps: [];\n }\n\n when(endorsement) {\n action [endorsement] {\n agent_description: "Record one endorsement against a policy that already forwarded, from evidence the caller supplies. The forward must be released first, and only the {carrier} may call it. It moves no money and it does not change the premium.";\n summary: "Record one non-money endorsement from external evidence";\n input: {\n additional_properties: false;\n properties: {\n for item in keys(endorsement_fields) {\n [item]: {\n description: "Required decision reference retained in the operation receipt";\n max_length: 180; min_length: 1; type: string;\n }\n }\n };\n required: keys(endorsement_fields);\n type: object;\n };\n capture_input: { endorsement_evidence_reference: evidenceReference; };\n port: { allowed_parties: [beneficiary]; };\n steps: [];\n }\n action lapse {\n summary: "Mark the forwarded policy lapsed at its stored renewal due condition";\n due: { field: renewal_due; };\n requires drained: { path: refs.escrowAccountId; };\n steps: [];\n }\n }\n}\n',
50
+ ],
51
+ [
52
+ "settlements/reconciled_payout.hsx",
53
+ 'module std.settlements.reconciled_payout\n\nexport instrument reconciled_payout<C>(\n payer: party,\n beneficiary: party,\n amount: money<C>,\n beneficiary_ref: text,\n settle_by: date,\n matched_within: integer,\n matched_ceiling: integer,\n) {\n let(payer_account_field): camel(concat(payer, "_account_id"));\n let(beneficiary_account_field): camel(concat(beneficiary, "_account_id"));\n let(reference_filter_key): "x-hyperscale-reference-filter";\n fields {\n amount { type: money<C>; description: concat("Amount instructed to the ", words(beneficiary), " in minor units"); }\n currency { type: text; description: "ISO 4217 currency code"; minLength: 3; maxLength: 3; pattern: "^[A-Z]{3}$"; }\n settle_by { type: date; description: "Instant the expectation stops waiting and the unmatched amount becomes a break"; }\n beneficiary_ref { type: text; description: "Beneficiary ID for the payout instruction"; pattern: "^ben_(sandbox|live)_[a-z0-9]{8,64}$"; }\n [beneficiary_account_field] { type: account<C>; description: concat("The ", words(beneficiary), " account"); pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; [reference_filter_key]: { column: role; values: [customer_balance]; }; }\n [payer_account_field] { type: account<C>; description: concat("The ", words(payer), " account the payout leaves"); pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; [reference_filter_key]: { column: role; values: [customer_balance]; }; }\n }\n lifecycle {\n states created instructed settled;\n initial created;\n on instruct: created -> instructed;\n on settle: instructed -> settled;\n }\n parties { beneficiary: beneficiary_account_field; payer: payer_account_field; }\n required: [amount, beneficiary_account_field, beneficiary_ref, currency, payer_account_field, settle_by];\n title: sentence(instrument);\n agent_description: concat("Reach for reconciled payout when a payment to the ", words(beneficiary), " is not finished until the bank confirms the debit. The instruction goes out, the expectation waits for a matching statement line, and anything still unmatched at the settle date becomes a break row instead of disappearing. Pick instant transfer when no bank confirmation is involved.");\n id_prefix: prefix(instrument);\n summary: concat("Payout from ", words(payer), " to ", words(beneficiary), " that is not done until the bank agrees");\n description: "A payout the instrument owns end to end: one instruction, one expectation about the debit it will produce, and one break when the debit never matches";\n dials: [{ key: settlement_tolerance; kind: reconcile_tolerance; maxMinorUnits: matched_ceiling; summary: "Largest difference between the instructed amount and the settled debit that still counts as matched."; title: "Settlement tolerance"; }];\n action create { summary: concat("Create a ", words(instrument)); agent_description: concat("Open the payout row with the ", words(payer), " and ", words(beneficiary), " accounts, the amount, the beneficiary reference, and the settle date. No money moves and no instruction goes out yet. Call instruct next."); moves: []; steps: []; }\n action instruct {\n agent_description: concat("Send the payout instruction and start the expectation clock. This commits the amount to the ", words(beneficiary), " and the payout is not reversible from here. The bank debit is matched later by settle, which runs on its own at the settle date.");\n summary: concat("Instruct the payout to the ", words(beneficiary));\n payout { amount: concat("fields.", amount); beneficiaryField: beneficiary_ref; beneficiaryPartyField: beneficiary_account_field; capture: payoutId; currencyField: currency; sourceAccountField: payer_account_field; speed: standard; }\n moves: []; steps: [];\n }\n action settle {\n summary: "Match the bank\'s debit against what the instruction promised";\n due { field: settle_by; }\n reconcile {\n amount: concat("fields.", amount); capture: settlementEvidenceId; counterpartyRef: payoutId;\n currencyField: currency; direction: debit; evidence: statement_line;\n exception { amountField: unmatchedAmount; childInstrumentId: concat(instrument, "_break"); maxOpen: 1; reasonField: breakReason; refField: concat(camel(instrument), "Id"); }\n match { law: tolerance; dial: settlement_tolerance; minorUnits: matched_within; }\n within { field: settle_by; }\n }\n moves: []; steps: [];\n }\n instruments {\n instrument {\n let(parent_name): instrument;\n id: concat(parent_name, "_break");\n id_prefix: concat(prefix(parent_name), "bk");\n fields {\n unmatchedAmount { type: money<C>; description: "Difference between the instructed amount and the evidence, in minor units"; }\n currency { type: text; description: "ISO 4217 currency code"; minLength: 3; maxLength: 3; pattern: "^[A-Z]{3}$"; }\n breakReason { type: text; description: "Why the expectation went unmatched"; minLength: 1; maxLength: 180; }\n [parent_name]Id { type: ref<parent_name>; description: "Payout whose expectation broke"; pattern: concat("^", prefix(parent_name), "_(sandbox|live)_[a-z0-9]{8,64}$"); }\n }\n lifecycle { states created carried; initial created; on carry: created -> carried; }\n required: [breakReason, currency, unmatchedAmount, concat(camel(parent_name), "Id")];\n title: concat(sentence(parent_name), " Break");\n agent_description: concat("Reach for this child row when a ", words(parent_name), " expectation reached its window with no matching bank debit. The break carries the unmatched amount and the reason so the difference is owned by someone rather than silently dropped.");\n summary: "Unmatched settlement expectation carried as its own row";\n description: "One break raised when a payout expectation reached its window with no matching debit; it is carried, never silently dropped";\n action create { summary: "Raise a break against an instructed payout"; agent_description: "Raise a break against an instructed payout, recording the unmatched amount and why the expectation went unmatched. No money moves. The payout must still be instructed, and only one open break exists per payout."; requires refs { field: concat(camel(parent_name), "Id"); statuses: [instructed]; match: { "fields.currency": "fields.currency"; }; } moves: []; steps: []; }\n action carry { summary: "Carry the break to whoever owns it"; agent_description: "Hand the break to whoever owns resolving it. No money moves. The payout must still be instructed. This is the only exit from a raised break, so a break is never closed by dropping it."; requires refs { field: concat(camel(parent_name), "Id"); statuses: [instructed]; match: { "fields.currency": "fields.currency"; }; } moves: []; steps: []; }\n }\n }\n}\n',
54
+ ],
55
+ [
56
+ "settlements/recurring_collection.hsx",
57
+ 'module std.settlements.recurring_collection\n\nexport instrument recurring_collection(marker: optional<text>) {\n agent_description: concat("Reach for ", words(instrument), " to track a bounded run of scheduled collections, one call per recorded installment. It carries no amount and no account, and every action only advances its own state. A settlement that debits an account on a schedule is a different shape.");\n fields {}\n lifecycle {\n states active ended;\n initial active;\n on collect: active -> active;\n on end: active -> ended;\n }\n action create {\n agent_description: "Open the collection so installments can be recorded against it. This is the first call and the collection starts active. It moves no money.";\n summary: "Create a bounded recurring collection";\n steps: [];\n }\n action collect {\n agent_description: "Record one due installment as collected. The collection must still be active, and it stays active afterwards so the next installment can follow. It moves no money.";\n summary: "Collect one due installment";\n steps: [];\n }\n action end {\n agent_description: "Close the collection so no further installment can be recorded. Only an active collection can end, and ended is final. It moves no money.";\n summary: "End future collections";\n steps: [];\n }\n}\n',
58
+ ],
59
+ [
60
+ "settlements/rotating_pool.hsx",
61
+ 'module std.settlements.rotating_pool\n\nexport instrument rotating_pool<C>(members: optional<list<party>>, contribution: money<C>, count: integer, every: optional<text>, first_due: date, payout_order: optional<list<party>>, default_policy: optional<text>, guarantee_policy: optional<text>, guarantor: optional<party>, exit_policy: optional<text>, memo: optional<text>, membership: optional<block>) {\n when_not(membership) {\n let(member_fields): suffix_each(members, "AccountId");\n let(guarantor_field): concat(camel(guarantor), "AccountId");\n let(contribution_field): camel(contribution);\n let(first_due_field): camel(first_due);\n let(parent_ref_field): concat(camel(instrument), "Id");\n let(reference_filter): "x-hyperscale-reference-filter";\n fields {\n for member in members { [member]AccountId { type: account<C>; description: concat("The ", words(member), " account"); pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; [reference_filter]: { column: role; values: [customer_balance]; }; } }\n [guarantor_field] { type: account<C>; description: concat("The ", words(guarantor), " account"); pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; [reference_filter]: { column: role; values: [customer_balance]; }; }\n [contribution_field] { type: money<C>; description: "Exact contribution in {C} minor units"; }\n currency { type: text; description: "ISO 4217 currency code"; minLength: 3; maxLength: 3; pattern: "^[A-Z]{3}$"; }\n [first_due_field] { type: date; description: "Stored first contribution due date"; }\n one { type: integer; description: "Exact fixed member-row count"; const: 1; }\n }\n lifecycle {\n states forming cancelled;\n for cycle in count {\n let(active_state): concat("active_cycle_", cycle);\n let(ready_state): concat("cycle_", cycle, "_ready");\n let(states_key): "states";\n [states_key]: [active_state, ready_state];\n }\n states completed;\n initial forming;\n on cancel: forming -> cancelled;\n on activate: forming -> active_cycle_1;\n for cycle in count {\n let(active_state): concat("active_cycle_", cycle);\n let(ready_state): concat("cycle_", cycle, "_ready");\n on ready_cycle_[cycle]: active_state -> ready_state;\n let(next_state): if_eq(cycle, count, "completed", concat("active_cycle_", add(cycle, 1)));\n on advance_cycle_[cycle]: ready_state -> next_state;\n }\n }\n parties { payer: guarantor_field; }\n required: concat_lists(member_fields, [guarantor_field, "currency", contribution_field, first_due_field, "one"]);\n title: sentence(instrument);\n id_prefix: prefix(instrument);\n agent_description: "Reach for rotating pool when a fixed group pays the same contribution every cycle and one member takes the whole pot each cycle, in a declared order. The roster freezes at creation, one contribution row per member, and the pot rotates until every member has been paid. Scheduled is the one payer, one payee shape on a calendar.";\n summary: concat(count, "-member rotating pool");\n description: "Fixed rotating contribution and payout order";\n action create { agent_description: "Create the pool with its frozen roster, cycle count, contribution amount, and payout order. No money moves. Each member\'s contribution row is created separately, and the pool cannot activate until every row exists."; summary: "Create the fixed roster before activation"; moves: []; steps: []; }\n action cancel { agent_description: "Cancel the pool before it activates. Only a forming pool cancels, no money has moved yet, and there is nothing to refund. Once the pool activates this exit is gone."; summary: "Cancel before activation without moving money"; moves: []; steps: []; }\n action activate {\n agent_description: "Start cycle one. Refused unless every member on the roster has exactly one contribution row waiting at the first cycle, so a pool can never run a member short. No money moves.";\n summary: "Activate only after every fixed member row exists once";\n for member in members { requires aggregate { instrumentId: concat(instrument, "_", member, "_contribution"); over: children; refField: parent_ref_field; statuses: [cycle_1_due]; check: { kind: count_equals_field; field: one; }; } }\n moves: [];\n steps: [];\n }\n for cycle in count {\n action ready_cycle_[cycle] {\n agent_description: concat("Lock cycle ", cycle, " once every member row is funded or covered by the guarantor. Refused while any row is still due or defaulted. No money moves here. Locking the cycle is what lets its payouts run.");\n summary: concat("Lock cycle ", cycle, " only after every member row is funded or guaranteed");\n let(funded_state): concat("cycle_", cycle, "_funded");\n let(guaranteed_state): concat("cycle_", cycle, "_guaranteed");\n for member in members { requires aggregate { instrumentId: concat(instrument, "_", member, "_contribution"); over: children; refField: parent_ref_field; statuses: [funded_state, guaranteed_state]; check: { kind: all_in; }; } }\n moves: [];\n steps: [];\n }\n action advance_cycle_[cycle] {\n let(target_status): if_eq(cycle, count, "completed", concat("cycle_", add(cycle, 1), "_due"));\n agent_description: concat("Close cycle ", cycle, " once every member row has paid into that cycle pot, moving the pool to the next cycle or to completed on the last one. Refused while any row is unpaid. No money moves here. The money moved on the member rows.");\n summary: if_eq(cycle, count, "Complete after the final shared pot pays", concat("Advance after every cycle ", cycle, " contribution pays"));\n for member in members { requires aggregate { instrumentId: concat(instrument, "_", member, "_contribution"); over: children; refField: parent_ref_field; statuses: [target_status]; check: { kind: all_in; }; } }\n moves: [];\n steps: [];\n }\n }\n instruments {\n for member in members {\n instrument {\n let(parent_name): instrument;\n let(child_id): concat(parent_name, "_", member, "_contribution");\n id: child_id;\n generatedPrefix: true;\n title: concat(sentence(parent_name), " ", sentence(member), " Contribution");\n agent_description: concat("One seat in the pool. The ", words(member), " pays the same contribution every cycle and takes the whole pot on their turn. Every contribution, default, guarantee, and payout for that member happens on this row, never on the pool itself.");\n summary: concat(words(member), " contribution row");\n description: concat("Fixed contribution row for ", words(member));\n fields {\n for roster_member in payout_order { [roster_member]AccountId { type: account<C>; description: concat("The ", words(roster_member), " account"); pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; [reference_filter]: { column: role; values: [customer_balance]; }; } }\n [guarantor_field] { type: account<C>; description: concat("The ", words(guarantor), " account"); pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; [reference_filter]: { column: role; values: [customer_balance]; }; }\n [contribution_field] { type: money<C>; description: "Exact contribution amount shared by every cycle"; }\n currency { type: text; description: "ISO 4217 currency code"; minLength: 3; maxLength: 3; pattern: "^[A-Z]{3}$"; }\n [first_due_field] { type: date; description: "First due anchor derived from the pool"; }\n [parent_ref_field] { type: ref<parent_name>; description: concat("The exact ", parent_name); pattern: concat("^", prefix(parent_name), "_(sandbox|live)_[a-z0-9]{8,64}$"); }\n }\n lifecycle {\n for cycle in count {\n let(states_key): "states";\n let(due_state): concat("cycle_", cycle, "_due");\n let(funded_state): concat("cycle_", cycle, "_funded");\n let(defaulted_state): concat("cycle_", cycle, "_defaulted");\n let(guaranteed_state): concat("cycle_", cycle, "_guaranteed");\n [states_key]: [due_state, funded_state, defaulted_state, guaranteed_state];\n }\n states final_paid completed;\n initial cycle_1_due;\n for cycle in count {\n let(due_state): concat("cycle_", cycle, "_due");\n let(funded_state): concat("cycle_", cycle, "_funded");\n let(defaulted_state): concat("cycle_", cycle, "_defaulted");\n let(guaranteed_state): concat("cycle_", cycle, "_guaranteed");\n on contribute_cycle_[cycle]: due_state -> funded_state;\n on mark_default_cycle_[cycle]: due_state -> defaulted_state;\n on guarantee_cycle_[cycle]: defaulted_state -> guaranteed_state;\n let(next_state): if_eq(cycle, count, "final_paid", concat("cycle_", add(cycle, 1), "_due"));\n on pay_cycle_[cycle]: funded_state -> next_state;\n on pay_guaranteed_cycle_[cycle]: guaranteed_state -> next_state;\n }\n on close: final_paid -> completed;\n }\n parties { beneficiary: concat(camel(member), "AccountId"); payer: guarantor_field; }\n action create {\n agent_description: concat("Create the contribution row for the ", words(member), " and provision its escrow account. The pool must still be forming, and every member needs exactly one row before the pool can activate. No money moves.");\n summary: concat("Create the fixed contribution row for ", words(member));\n requires refs { field: parent_ref_field; statuses: [forming]; unique: true; bind: { [contribution_field]: concat("fields.", contribution_field); currency: "fields.currency"; [first_due_field]: concat("fields.", first_due_field); [guarantor_field]: concat("fields.", guarantor_field); for roster_member in members { let(roster_field): concat(camel(roster_member), "AccountId"); [roster_field]: concat("fields.", roster_field); } }; }\n moves: [];\n steps: [{ operation: "account.escrow.provision"; bind: { currency: { from: instance; path: "fields.currency"; }; "owner.id": { from: instance; path: productId; }; "owner.type": { from: const; value: product; }; productId: { from: instance; path: productId; }; role: { from: const; value: product_escrow; }; }; capture: { escrowAccountId: accountId; }; }];\n }\n for cycle in count {\n let(active_state): concat("active_cycle_", cycle);\n let(ready_state): concat("cycle_", cycle, "_ready");\n let(due_offset): scale_duration(every, sub(cycle, 1));\n let(contribute_name): concat("contribute_cycle_", cycle);\n let(guarantee_name): concat("guarantee_cycle_", cycle);\n let(pay_name): concat("pay_cycle_", cycle);\n let(pay_guaranteed_name): concat("pay_guaranteed_cycle_", cycle);\n let(contribute_capture): concat("contributeCycle", cycle, "ContributionTransferId");\n let(guarantee_capture): concat("guaranteeCycle", cycle, "GuaranteeTransferId");\n let(pay_capture): concat("payCycle", cycle, "PayoutTransferId");\n let(pay_guaranteed_capture): concat("payGuaranteedCycle", cycle, "PayoutTransferId");\n let(payout_member): at(payout_order, cycle);\n let(payout_field): concat(camel(payout_member), "AccountId");\n action contribute_cycle_[cycle] {\n summary: concat("Fund ", words(member), "\'s cycle ", cycle, " contribution");\n let(first): if_eq(cycle, 1, true, false);\n when(first) { due: { field: first_due_field; }; }\n when_not(first) { due: { field: first_due_field; offset: due_offset; }; }\n requires refs { field: parent_ref_field; statuses: [active_state]; }\n moves: [{ key: "contribution"; operation: internal_transfer.create; bind: { amount: { from: instance; path: concat("fields.", contribution_field); }; currency: { from: instance; path: "fields.currency"; }; destinationAccountId: { from: instance; path: "refs.escrowAccountId"; }; "metadata.instrumentId": { from: const; value: child_id; }; "metadata.instrumentInstanceId": { from: instance; path: instrumentInstanceId; }; "metadata.phase": { from: const; value: contribute_name; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", camel(member), "AccountId"); }; }; capture: { [contribute_capture]: transferId; }; }];\n steps: [];\n }\n action mark_default_cycle_[cycle] {\n summary: concat("Mark the stored cycle ", cycle, " due condition");\n let(first): if_eq(cycle, 1, true, false);\n when(first) { due: { field: first_due_field; }; }\n when_not(first) { due: { field: first_due_field; offset: due_offset; }; }\n requires refs { field: parent_ref_field; statuses: [active_state]; }\n moves: [];\n steps: [];\n }\n action guarantee_cycle_[cycle] {\n agent_description: concat("Have the guarantor fund cycle ", cycle, " for this member after the row defaulted. The row must be marked defaulted for that cycle. This moves the guarantor\'s money into the row escrow so the pot still pays in full.");\n summary: concat("Fund the defaulted cycle ", cycle, " amount before payout");\n requires refs { field: parent_ref_field; statuses: [active_state]; }\n moves: [{ key: guarantee; operation: internal_transfer.create; bind: { amount: { from: instance; path: concat("fields.", contribution_field); }; currency: { from: instance; path: "fields.currency"; }; destinationAccountId: { from: instance; path: "refs.escrowAccountId"; }; "metadata.instrumentId": { from: const; value: child_id; }; "metadata.instrumentInstanceId": { from: instance; path: instrumentInstanceId; }; "metadata.phase": { from: const; value: guarantee_name; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", guarantor_field); }; }; capture: { [guarantee_capture]: transferId; }; }];\n steps: [];\n }\n action pay_cycle_[cycle] {\n agent_description: concat("Pay this row\'s funded cycle ", cycle, " contribution out of escrow to whoever holds the pot that cycle. The cycle must be locked first and the row must be funded rather than guaranteed. This moves money and does not reverse.");\n summary: concat("Pay this member\'s stored contribution into cycle ", cycle, "\'s shared pot recipient");\n requires refs { field: parent_ref_field; statuses: [ready_state]; }\n moves: [{ key: payout; operation: internal_transfer.create; bind: { amount: { from: instance; path: concat("fields.", contribution_field); }; currency: { from: instance; path: "fields.currency"; }; destinationAccountId: { from: instance; path: concat("fields.", payout_field); }; "metadata.instrumentId": { from: const; value: child_id; }; "metadata.instrumentInstanceId": { from: instance; path: instrumentInstanceId; }; "metadata.phase": { from: const; value: pay_name; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: "refs.escrowAccountId"; }; }; capture: { [pay_capture]: transferId; }; }];\n steps: [];\n }\n action pay_guaranteed_cycle_[cycle] {\n agent_description: concat("Pay this row\'s guarantor-funded cycle ", cycle, " contribution out of escrow to whoever holds the pot that cycle. The cycle must be locked first and the row must be guaranteed rather than funded. This moves money and does not reverse.");\n summary: concat("Pay the funded default into cycle ", cycle, "\'s stored recipient");\n requires refs { field: parent_ref_field; statuses: [ready_state]; }\n moves: [{ key: payout; operation: internal_transfer.create; bind: { amount: { from: instance; path: concat("fields.", contribution_field); }; currency: { from: instance; path: "fields.currency"; }; destinationAccountId: { from: instance; path: concat("fields.", payout_field); }; "metadata.instrumentId": { from: const; value: child_id; }; "metadata.instrumentInstanceId": { from: instance; path: instrumentInstanceId; }; "metadata.phase": { from: const; value: pay_guaranteed_name; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: "refs.escrowAccountId"; }; }; capture: { [pay_guaranteed_capture]: transferId; }; }];\n steps: [];\n }\n }\n action close { agent_description: "Retire this member row after its final payout. Refused while the row escrow account still holds anything, so a row can never close over stranded money. No money moves."; summary: "Complete after the final payout drains this member custody"; requires drained: { path: "refs.escrowAccountId"; }; moves: []; steps: []; }\n }\n }\n }\n }\n\n when(membership) {\n let(membership_instrument): get(membership, "instrument");\n let(membership_ref_field): get(membership, "ref_field");\n let(joined_status): get(membership, "joined_status");\n let(active_status): get(membership, "active_status");\n let(paid_status): get(membership, "paid_status");\n let(custody_ref): get(membership, "custody_ref");\n let(instrument_id_prefix): get(membership, "id_prefix");\n let(active_parked): get(membership, "active_parked");\n let(min_members): get(membership, "min_members");\n let(max_members): get(membership, "max_members");\n let(contribution_description): get(membership, "contribution_description");\n let(currency_description): get(membership, "currency_description");\n let(create_examples): get(membership, "create_examples");\n let(activate_examples): get(membership, "activate_examples");\n let(disband_examples): get(membership, "disband_examples");\n let(close_examples): get(membership, "close_examples");\n let(contribution_field): camel(contribution);\n let(count_field): camel(count);\n let(first_due_field): camel(first_due);\n\n fields {\n [contribution_field] { type: money<C>; description: contribution_description; }\n currency { type: text; description: currency_description; maxLength: 3; minLength: 3; pattern: "^[A-Z]{3}$"; }\n [count_field] { type: integer; maximum: max_members; minimum: min_members; }\n when(memo) { [memo] { type: text; optional: true; maxLength: 180; minLength: 1; } }\n [first_due_field] { type: date; }\n }\n lifecycle {\n states forming active completed disbanded;\n initial forming;\n on activate: forming -> active;\n on close: active -> completed;\n on disband: forming -> disbanded;\n }\n required: [count_field, contribution_field, currency, first_due_field];\n aggregate_invariants { childInstrumentId: membership_instrument; childRefField: membership_ref_field; childStatuses: [joined_status, active_status, paid_status]; count: true; parentField: count_field; }\n caller_parked_states { active: active_parked; }\n agent_description: concat("Reach for ", words(instrument), " when a fixed group pays the same contribution every cycle and one member takes the whole pot each cycle, and the product publishes its own membership rows. This shape owns the pot account and the seat count. Every contribution and payout happens on the membership row that references it, never here.");\n id_prefix: instrument_id_prefix;\n action create {\n public: none;\n agent_description: concat("Open the ", words(instrument), " and provision the pot account every contribution lands in. No money moves. The roster is still empty, so the pool stays forming until one membership row exists per seat.");\n examples: create_examples;\n moves: [];\n steps: [{ operation: "account.escrow.provision"; bind: { currency: { from: instance; path: "fields.currency"; }; "owner.id": { from: instance; path: productId; }; "owner.type": { from: const; value: product; }; productId: { from: instance; path: productId; }; role: { from: const; value: product_escrow; }; }; capture: { [custody_ref]: accountId; }; }];\n }\n action activate {\n public: none;\n due { field: first_due_field; }\n examples: activate_examples;\n requires aggregate { instrumentId: membership_instrument; over: children; refField: membership_ref_field; statuses: [joined_status]; check: { kind: count_equals_field; field: count_field; }; }\n moves: [];\n steps: [];\n }\n action disband { public: none; agent_description: concat("Close a ", words(instrument), " that never filled its roster. Only a forming pool disbands, no money has moved, and there is nothing to refund. Once the pool activates this exit is gone."); examples: disband_examples; moves: []; steps: []; }\n action close {\n public: none;\n agent_description: concat("Retire the ", words(instrument), " after every membership row has been paid. Refused while any row is unpaid or while the pot account still holds anything, so a pool can never close over stranded money. No money moves.");\n examples: close_examples;\n requires aggregate { instrumentId: membership_instrument; over: children; refField: membership_ref_field; statuses: [paid_status]; check: { kind: all_in; }; }\n requires drained { path: concat("refs.", custody_ref); }\n moves: [];\n steps: [];\n }\n }\n}\n',
62
+ ],
63
+ [
64
+ "settlements/scheduled.hsx",
65
+ 'module std.settlements.scheduled\n\nexport instrument scheduled<C>(\n payer: party,\n payee: party,\n amount: money<C>,\n count: optional<integer>,\n every: text,\n first_due: date,\n mode: optional<text>,\n debtor: optional<party>,\n advance_to: optional<party>,\n until: optional<condition>,\n month_end: optional<text>,\n period_liability: optional<text>,\n termination_drain: optional<text>,\n mandate: optional<condition>,\n derived_amount: optional<unknown>\n) {\n agent_description: "Reach for scheduled when one payer owes one payee on a calendar. It covers a plan of fixed installments partitioning one total, an obligation whose installments are paid through child payment records and can go delinquent, and an open period charge that repeats until a cancel port fires. Rotating pool is for a group taking turns.";\n when_not(mode) {\n let(instrument_words): words(instrument);\n let(first_percent): if_eq(count, 3, "33.34%", if_eq(count, 2, "50%", "25%"));\n let(other_percent): if_eq(count, 3, "33.33%", if_eq(count, 2, "50%", "25%"));\n\n title: sentence(instrument);\n summary: "{count}-installment schedule from {payer} to {payee}";\n description: "Scheduled payment: the {payer} pays {amount} to the {payee} in {count} installments, one every {every}";\n partitions: { totalField: amount; pieceFields: names("installment", count, "Amount"); };\n\n fields {\n amount: {\n type: money<C>;\n description: "The total scheduled amount in {C} minor units; the installment fields below partition it exactly";\n }\n first_due: {\n type: date;\n description: "Due date of the first installment; installment k falls {every} after its predecessor";\n }\n for i in count {\n let(piece_percent): if_eq(i, 1, first_percent, other_percent);\n let(remainder_words): if_eq(i, 1, " (carries the integer-division remainder)", "");\n installment[i]Amount: {\n type: money<C>;\n description: "Installment {i} of {count}{remainder_words}: about {piece_percent} of {amount}, collected on its own stored-date anchor";\n }\n }\n }\n\n parties {\n payer: payer;\n beneficiary: payee;\n }\n\n lifecycle {\n states active;\n for i in sub(count, 1) { states collecting_[i]; }\n states settled;\n initial active;\n for i in count {\n let(from_state): if_eq(i, 1, "active", concat("collecting_", sub(i, 1)));\n let(to_state): if_eq(i, count, "settled", concat("collecting_", i));\n on pay_installment_[i]: from_state -> to_state;\n }\n }\n\n action create {\n agent_description: "Create the installment plan. No money moves. The total and its per-installment amounts are fixed here, and each installment collects on its own stored due date from then on.";\n summary: "Create a {instrument_words} plan";\n steps: [];\n }\n\n for i in count {\n action pay_installment_[i] {\n let(first): if_eq(i, 1, true, false);\n let(offset): scale_duration(every, sub(i, 1));\n let(installment_field): concat("installment", i, "Amount");\n summary: "Collect installment {i} of {count}";\n when(first) { due: { field: first_due; }; }\n when_not(first) { due: { field: first_due; offset: offset; }; }\n moves: [{ amount: installment_field; from: payer; to: beneficiary; key: transfer; }];\n steps: [];\n }\n }\n }\n\n when_eq(mode, obligation) {\n when(count) {\n let(instrument_words): words(instrument);\n let(amount_field): concat(amount);\n let(first_due_field): concat(first_due);\n let(payer_field): camel(concat(payer, "_account_id"));\n let(payer_words): words(payer);\n let(payee_field): camel(concat(payee, "_account_id"));\n let(payee_words): words(payee);\n let(debtor_field): camel(concat(debtor, "_account_id"));\n let(debtor_words): words(debtor);\n let(advance_field): camel(concat(advance_to, "_account_id"));\n let(advance_words): words(advance_to);\n let(parent_ref_field): camel(concat(instrument, "_id"));\n let(has_advance): advance_to;\n let(same_debtor): if_eq(payer, debtor, true, false);\n let(parent_statuses): if_eq(count, 2,\n ["active", "installment_1_delinquent", "installment_2_delinquent"],\n if_eq(count, 3,\n ["active", "installment_1_delinquent", "installment_2_delinquent", "installment_3_delinquent"],\n ["active", "installment_1_delinquent", "installment_2_delinquent", "installment_3_delinquent", "installment_4_delinquent"]\n )\n );\n let(delinquent_statuses): names("installment_", count, "_delinquent");\n let(last_offset): scale_duration(every, sub(count, 1));\n let(reference_filter_key): "x-hyperscale-reference-filter";\n let(fee_port_key): "x-hyperscale-fee-collection-port";\n let(derived_field): concat(get(derived_amount, "field"));\n let(derived_source): concat(get(derived_amount, "source"));\n let(derived_rule): get(derived_amount, "rule");\n let(derived_bps): add(derived_rule, 0);\n let(derived_percent): concat(derived_rule);\n let(derived_bearer): get(derived_amount, "bearer");\n let(derived_bearer_field): camel(concat(derived_bearer, "_account_id"));\n let(metadata_instrument_key): "metadata.instrumentId";\n let(metadata_instance_key): "metadata.instrumentInstanceId";\n let(metadata_phase_key): "metadata.phase";\n\n title: sentence(instrument);\n summary: "{count}-anchor obligation for {debtor_words}";\n description: "Installment obligation for {debtor_words}; {payer_words} pays {payee_words} against exact stored anchors";\n partitions: { total_field: amount_field; piece_fields: names("installment", count, "Amount"); };\n when(derived_amount) {\n computes derived: {\n field: derived_field;\n source_field: derived_source;\n rule: { kind: percentage_of; bps: derived_bps; };\n rounding: floor;\n };\n }\n for i in count {\n aggregate_invariants: {\n child_field: "amount";\n child_instrument_id: concat(instrument, "_installment_", i, "_payment");\n child_ref_field: parent_ref_field;\n child_statuses: [paid];\n parent_field: concat("installment", i, "Amount");\n };\n }\n when(has_advance) {\n when_not(same_debtor) {\n required: if_eq(count, 2,\n [advance_field, payee_field, payer_field, debtor_field, "currency", amount_field, first_due_field, "installment1Amount", "installment2Amount"],\n if_eq(count, 3,\n [advance_field, payee_field, payer_field, debtor_field, "currency", amount_field, first_due_field, "installment1Amount", "installment2Amount", "installment3Amount"],\n [advance_field, payee_field, payer_field, debtor_field, "currency", amount_field, first_due_field, "installment1Amount", "installment2Amount", "installment3Amount", "installment4Amount"]\n )\n );\n }\n when(same_debtor) {\n when_not(derived_amount) {\n required: if_eq(count, 3,\n [advance_field, payee_field, payer_field, "currency", amount_field, first_due_field, "installment1Amount", "installment2Amount", "installment3Amount"],\n [advance_field, payee_field, payer_field, "currency", amount_field, first_due_field, "installment1Amount", "installment2Amount", "installment3Amount", "installment4Amount"]\n );\n }\n when(derived_amount) {\n required: if_eq(count, 2,\n [advance_field, payee_field, payer_field, "platformAccountId", "currency", amount_field, first_due_field, "installment1Amount", "installment2Amount"],\n [advance_field, payee_field, payer_field, "platformAccountId", "currency", amount_field, first_due_field, "installment1Amount", "installment2Amount", "installment3Amount", "installment4Amount"]\n );\n }\n }\n }\n when_not(has_advance) {\n when_not(same_debtor) {\n required: if_eq(count, 2,\n [payee_field, payer_field, debtor_field, "currency", amount_field, first_due_field, "installment1Amount", "installment2Amount"],\n if_eq(count, 3,\n [payee_field, payer_field, debtor_field, "currency", amount_field, first_due_field, "installment1Amount", "installment2Amount", "installment3Amount"],\n [payee_field, payer_field, debtor_field, "currency", amount_field, first_due_field, "installment1Amount", "installment2Amount", "installment3Amount", "installment4Amount"]\n )\n );\n }\n when(same_debtor) {\n required: if_eq(count, 2,\n [payee_field, payer_field, "currency", amount_field, first_due_field, "installment1Amount", "installment2Amount"],\n if_eq(count, 3,\n [payee_field, payer_field, "currency", amount_field, first_due_field, "installment1Amount", "installment2Amount", "installment3Amount"],\n [payee_field, payer_field, "currency", amount_field, first_due_field, "installment1Amount", "installment2Amount", "installment3Amount", "installment4Amount"]\n )\n );\n }\n }\n\n fields {\n when(has_advance) {\n [payee_field]: {\n type: account;\n description: "The {payee_words} account";\n pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$";\n [reference_filter_key]: { column: role; values: [customer_balance]; };\n }\n }\n when(same_debtor) {\n [payer_field]: {\n type: account;\n description: "The {payer_words} account";\n pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$";\n [reference_filter_key]: { column: role; values: [customer_balance]; };\n }\n }\n when_not(same_debtor) {\n [debtor_field]: {\n type: account;\n description: "The {debtor_words} account";\n pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$";\n [reference_filter_key]: { column: role; values: [customer_balance]; };\n }\n }\n when(derived_amount) {\n platform_account_id: {\n type: account;\n description: "The product fee collection account";\n pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$";\n [fee_port_key]: true;\n [reference_filter_key]: { column: role; values: [customer_balance, product_revenue]; };\n }\n }\n currency: {\n type: text;\n description: "ISO 4217 currency code";\n max_length: 3;\n min_length: 3;\n pattern: "^[A-Z]{3}$";\n }\n amount: {\n type: money<C>;\n description: "The principal in {C} minor units; the stored installment anchors partition it exactly";\n }\n first_due: {\n type: date;\n description: "Due date of the first installment; later anchors use fixed offsets of {every}";\n }\n when(derived_amount) {\n [derived_field]: {\n type: money<C>;\n optional: true;\n pattern: "^[1-9][0-9]{0,17}$";\n description: "Machine-computed {derived_percent} of {derived_source}; callers never supply it";\n }\n }\n for i in count {\n let(remainder_words): if_eq(i, 1, " (carries the integer-division remainder)", "");\n installment[i]Amount: {\n type: money<C>;\n description: "Stored amount for installment {i} of {count}{remainder_words}";\n }\n installment[i]DelinquentAfter: {\n type: date;\n optional: true;\n description: "Machine-set marker proving installment {i} reached its stored due date while unpaid";\n }\n }\n }\n\n parties {\n when(has_advance) { beneficiary: advance_to; }\n when_not(has_advance) { beneficiary: payee; }\n when_not(same_debtor) { payer: payer; }\n }\n\n let(count_is_2): if_eq(count, 2, true, false);\n let(count_is_3): if_eq(count, 3, true, false);\n let(count_is_4): if_eq(count, 4, true, false);\n when(count_is_2) {\n lifecycle {\n states draft;\n when(has_advance) { states approved; }\n states active installment_1_delinquent installment_2_delinquent written_off repaid;\n initial draft;\n when(has_advance) { on approve: draft -> approved; }\n when_not(has_advance) { on approve: draft -> active; }\n when(has_advance) { on advance: approved -> active; }\n on collect_installment_1: installment_1_delinquent|installment_2_delinquent -> active;\n on collect_installment_2: installment_1_delinquent|installment_2_delinquent -> active;\n on mark_installment_1_delinquent: active|installment_2_delinquent -> installment_1_delinquent;\n on mark_installment_2_delinquent: active|installment_1_delinquent -> installment_2_delinquent;\n on complete: active|installment_1_delinquent|installment_2_delinquent -> repaid;\n when(has_advance) { on write_off: draft|approved|active|installment_1_delinquent|installment_2_delinquent -> written_off; }\n when_not(has_advance) { on write_off: draft|active|installment_1_delinquent|installment_2_delinquent -> written_off; }\n }\n }\n when(count_is_3) {\n lifecycle {\n states draft;\n when(has_advance) { states approved; }\n states active installment_1_delinquent installment_2_delinquent installment_3_delinquent written_off repaid;\n initial draft;\n when(has_advance) { on approve: draft -> approved; }\n when_not(has_advance) { on approve: draft -> active; }\n when(has_advance) { on advance: approved -> active; }\n on collect_installment_1: installment_1_delinquent|installment_2_delinquent|installment_3_delinquent -> active;\n on collect_installment_2: installment_1_delinquent|installment_2_delinquent|installment_3_delinquent -> active;\n on collect_installment_3: installment_1_delinquent|installment_2_delinquent|installment_3_delinquent -> active;\n on mark_installment_1_delinquent: active|installment_2_delinquent|installment_3_delinquent -> installment_1_delinquent;\n on mark_installment_2_delinquent: active|installment_1_delinquent|installment_3_delinquent -> installment_2_delinquent;\n on mark_installment_3_delinquent: active|installment_1_delinquent|installment_2_delinquent -> installment_3_delinquent;\n on complete: active|installment_1_delinquent|installment_2_delinquent|installment_3_delinquent -> repaid;\n when(has_advance) { on write_off: draft|approved|active|installment_1_delinquent|installment_2_delinquent|installment_3_delinquent -> written_off; }\n when_not(has_advance) { on write_off: draft|active|installment_1_delinquent|installment_2_delinquent|installment_3_delinquent -> written_off; }\n }\n }\n when(count_is_4) {\n lifecycle {\n states draft;\n when(has_advance) { states approved; }\n states active installment_1_delinquent installment_2_delinquent installment_3_delinquent installment_4_delinquent written_off repaid;\n initial draft;\n when(has_advance) { on approve: draft -> approved; }\n when_not(has_advance) { on approve: draft -> active; }\n when(has_advance) { on advance: approved -> active; }\n on collect_installment_1: installment_1_delinquent|installment_2_delinquent|installment_3_delinquent|installment_4_delinquent -> active;\n on collect_installment_2: installment_1_delinquent|installment_2_delinquent|installment_3_delinquent|installment_4_delinquent -> active;\n on collect_installment_3: installment_1_delinquent|installment_2_delinquent|installment_3_delinquent|installment_4_delinquent -> active;\n on collect_installment_4: installment_1_delinquent|installment_2_delinquent|installment_3_delinquent|installment_4_delinquent -> active;\n on mark_installment_1_delinquent: active|installment_2_delinquent|installment_3_delinquent|installment_4_delinquent -> installment_1_delinquent;\n on mark_installment_2_delinquent: active|installment_1_delinquent|installment_3_delinquent|installment_4_delinquent -> installment_2_delinquent;\n on mark_installment_3_delinquent: active|installment_1_delinquent|installment_2_delinquent|installment_4_delinquent -> installment_3_delinquent;\n on mark_installment_4_delinquent: active|installment_1_delinquent|installment_2_delinquent|installment_3_delinquent -> installment_4_delinquent;\n on complete: active|installment_1_delinquent|installment_2_delinquent|installment_3_delinquent|installment_4_delinquent -> repaid;\n when(has_advance) { on write_off: draft|approved|active|installment_1_delinquent|installment_2_delinquent|installment_3_delinquent|installment_4_delinquent -> written_off; }\n when_not(has_advance) { on write_off: draft|active|installment_1_delinquent|installment_2_delinquent|installment_3_delinquent|installment_4_delinquent -> written_off; }\n }\n }\n\n action create {\n agent_description: "Create the obligation in draft with its principal split across stored installment anchors. Approve is the next call. Where the product declares a derived fee, creating the obligation also moves that fee from its bearer to the platform account.";\n summary: "Create a {instrument_words} obligation";\n when(derived_amount) {\n moves: [{\n key: "derived_amount";\n operation: "internal_transfer.create";\n bind: {\n amount: { from: instance; path: concat("fields.", derived_field); };\n currency: { from: instance; path: fields.currency; };\n destination_account_id: { from: instance; path: fields.platformAccountId; };\n source_account_id: { from: instance; path: concat("fields.", derived_bearer_field); };\n [metadata_instrument_key]: { from: const; value: instrument; };\n [metadata_instance_key]: { from: instance; path: instrumentInstanceId; };\n [metadata_phase_key]: { from: const; value: create; };\n product_id: { from: instance; path: productId; };\n };\n capture: { create_derived_amount_transfer_id: transferId; };\n }];\n }\n steps: [];\n }\n action approve {\n agent_description: "Approve the draft obligation and freeze its principal partition and due anchors. The obligation must be in draft. No money moves. Where the product advances funds, approve is what makes advance available.";\n summary: "Approve the immutable principal partition and stored anchors";\n steps: [];\n }\n when(has_advance) {\n action advance {\n agent_description: "Pay the principal out to the advance recipient and put the obligation into repayment. The obligation must be approved. This moves the whole principal and does not reverse, so approve is the last point to stop.";\n summary: "Advance the principal to the {advance_words}; the internal ledger receipt is the confirmation";\n moves: [{ amount: amount_field; from: payee; to: beneficiary; key: advance; }];\n steps: [];\n }\n }\n for i in count {\n let(child_id): concat(instrument, "_installment_", i, "_payment");\n let(target_field): concat("installment", i, "Amount");\n let(marker_field): concat("installment", i, "DelinquentAfter");\n let(delinquent_action): concat("mark_installment_", i, "_delinquent");\n let(offset): scale_duration(every, sub(i, 1));\n action collect_installment_[i] {\n let(first): if_eq(i, 1, true, false);\n summary: "Close delinquent installment {i} after linked payments reach its stored amount";\n when(first) { due: { field: first_due_field; }; }\n when_not(first) { due: { field: first_due_field; offset: offset; }; }\n requires aggregate: {\n check: { amount_field: "amount"; kind: sum_exactly; target_field: target_field; };\n instrument_id: child_id;\n over: children;\n ref_field: parent_ref_field;\n statuses: [paid];\n };\n steps: [];\n }\n action [delinquent_action] {\n let(first): if_eq(i, 1, true, false);\n summary: "Mark installment {i} delinquent only when its due anchor is unmet";\n when(first) { due: { field: first_due_field; }; }\n when_not(first) { due: { field: first_due_field; offset: offset; }; }\n requires aggregate: {\n check: { amount_field: "amount"; kind: sum_below; target_field: target_field; };\n instrument_id: child_id;\n over: children;\n ref_field: parent_ref_field;\n statuses: [paid];\n };\n sets_at: { field: marker_field; marker: true; offset: PT1S; };\n steps: [];\n }\n }\n action complete {\n summary: "Close the obligation only after every stored anchor is paid exactly";\n due: { field: first_due_field; offset: last_offset; };\n for i in count {\n requires aggregate: {\n check: { amount_field: "amount"; kind: sum_exactly; target_field: concat("installment", i, "Amount"); };\n instrument_id: concat(instrument, "_installment_", i, "_payment");\n over: children;\n ref_field: parent_ref_field;\n statuses: [paid];\n };\n }\n steps: [];\n }\n action write_off {\n agent_description: "Write off the remaining exposure and stop the obligation. No money moves and nothing is refunded. This is the bookkeeping exit for debt that will not be collected. A written-off obligation never returns to repayment.";\n summary: "Write off the remaining exposure without moving money";\n steps: [];\n }\n\n instruments {\n for i in count {\n instrument {\n let(has_mandate): mandate;\n id: concat(instrument, "_installment_", i, "_payment");\n generatedPrefix: true;\n title: concat(sentence(instrument), " Installment ", i, " Payment");\n agent_description: concat("One payment against installment ", i, " of the obligation. Payments can be partial, so create a record, repay it, and the parent installment closes once its paid records sum to the stored anchor amount.");\n summary: concat("Anchor-bound payment for installment ", i);\n description: concat("One partial or full payment bound to installment ", i, " of ", instrument, "; the operation name fixes the anchor and ", parent_ref_field, " fixes the obligation");\n fields {\n amount: {\n type: money<C>;\n description: concat("Positive payment amount capped with its paid siblings at installment", i, "Amount");\n }\n currency: {\n type: text;\n description: "ISO 4217 currency code";\n max_length: 3;\n min_length: 3;\n pattern: "^[A-Z]{3}$";\n }\n [parent_ref_field]: {\n type: ref<instrument>;\n description: "The exact {instrument_words} this payment belongs to";\n pattern: concat("^", prefix(instrument), "_(sandbox|live)_[a-z0-9]{8,64}$");\n }\n }\n parties { beneficiary: payee; payer: payer; }\n lifecycle {\n states created paid refunded;\n initial created;\n on repay: created -> paid;\n on refund: paid -> refunded;\n }\n action create {\n agent_description: concat("Open a payment record against installment ", i, ". The parent obligation must be live. No money moves yet. Repay is what pays.");\n summary: concat("Create a payment record for installment ", i);\n requires refs: {\n field: parent_ref_field;\n statuses: parent_statuses;\n bind: {\n currency: fields.currency;\n [payer_field]: concat("fields.", payer_field);\n [payee_field]: concat("fields.", payee_field);\n };\n };\n steps: [];\n }\n action repay {\n agent_description: concat("Pay this record\'s amount toward installment ", i, ". The record must be created and its obligation live. Refused when this amount plus the records already paid against that installment would pass the stored amount. This moves the payer\'s money. Where a mandate applies, only the payer may call it and an evidence reference is required.");\n summary: concat("Pay a partial or full amount against installment ", i);\n when(has_mandate) {\n input: {\n additional_properties: false;\n properties: {\n evidence_reference: {\n description: "Required decision reference retained in the operation receipt";\n max_length: 180;\n min_length: 1;\n type: string;\n };\n };\n required: [evidenceReference];\n type: object;\n };\n capture_input: { mandate_evidence_reference: evidenceReference; };\n port: { allowed_parties: ["payer"]; };\n }\n requires refs: {\n field: parent_ref_field;\n statuses: parent_statuses;\n match: {\n let(payer_match): concat("fields.", payer_field);\n let(payee_match): concat("fields.", payee_field);\n let(currency_match): "fields.currency";\n [payer_match]: payer_match;\n [payee_match]: payee_match;\n [currency_match]: currency_match;\n };\n };\n requires exposure: {\n amount_field: "amount";\n anchor_field: parent_ref_field;\n cap_field: concat("installment", i, "Amount");\n cap_on_anchor: true;\n child_instrument_id: concat(instrument, "_installment_", i, "_payment");\n statuses: [paid];\n };\n moves: [{ amount: "amount"; from: payer; to: beneficiary; key: repayment; }];\n steps: [];\n }\n action refund {\n agent_description: concat("Return one whole installment ", i, " payment to the payer. The record must be paid, and the refund is always its full amount, so split a payment across records when a partial refund could be needed. This moves money back.");\n summary: concat("Refund this one stored installment ", i, " payment whole");\n requires refs: {\n field: parent_ref_field;\n statuses: parent_statuses;\n match: {\n let(payer_match): concat("fields.", payer_field);\n let(payee_match): concat("fields.", payee_field);\n let(currency_match): "fields.currency";\n [payer_match]: payer_match;\n [payee_match]: payee_match;\n [currency_match]: currency_match;\n };\n };\n moves: [{ amount: "amount"; from: beneficiary; to: payer; key: refund; }];\n steps: [];\n }\n }\n }\n }\n }\n\n when_not(count) {\n let(amount_field): concat(amount);\n let(until_name): concat(until);\n title: sentence(instrument);\n summary: "Open {every} obligation for {payer}";\n description: "Open monthly obligation for {payer}; one period liability at a time";\n\n fields {\n amount: {\n type: money<C>;\n description: "Exact charge for one {every} period in {C} minor units";\n }\n currency: {\n type: text;\n const: C;\n description: "ISO 4217 currency code";\n }\n first_due: {\n type: date;\n description: "First period anchor; missing Gregorian month days clamp to the target month\'s final day";\n }\n }\n\n parties { payer: payer; beneficiary: payee; }\n\n lifecycle {\n states active period_open canceled;\n initial active;\n on open_period: active -> period_open;\n on collect_period: period_open -> active;\n on [until]: active|period_open -> canceled;\n }\n\n action create {\n agent_description: "Create the open obligation before its first period anchor. No money moves. The charge for one period and the first anchor are fixed here, and periods then open on their own.";\n summary: "Create the open obligation before its first anchor";\n steps: [];\n }\n\n action open_period {\n summary: "Open exactly one period liability without moving money";\n due: {\n field: first_due;\n every: {\n period: { calendar: gregorian; month_end: month_end; months: 1; };\n until_action: until_name;\n liability: period_liability;\n delinquency: parent_policy;\n drain_action: termination_drain;\n };\n };\n steps: [];\n }\n\n action collect_period {\n agent_description: "Collect one open period charge from the payer, with the mandate evidence reference kept in the receipt. A period must be open. Only the payer may call it. This moves the period amount and does not reverse.";\n summary: "Collect one authored period charge with mandate evidence";\n input: {\n additional_properties: false;\n properties: {\n evidence_reference: {\n description: "Required decision reference retained in the operation receipt";\n max_length: 180;\n min_length: 1;\n type: string;\n };\n };\n required: [evidenceReference];\n type: object;\n };\n capture_input: { mandate_evidence_reference: evidenceReference; };\n port: { allowed_parties: ["payer"]; };\n moves: [{ amount: amount_field; from: payer; to: beneficiary; key: period_collection; }];\n steps: [];\n }\n\n action [until] {\n agent_description: "Cancel the open schedule for good and drain any period liability still standing. Only the payer may call it, and the reference fields the port declares are required. No further period opens and there is no reactivation.";\n summary: "Cancel the open schedule and drain any period liability";\n input: {\n additional_properties: false;\n properties: {\n for item in keys(until_fields) {\n [item]: {\n description: "Required decision reference retained in the operation receipt";\n max_length: 180;\n min_length: 1;\n type: string;\n }\n }\n };\n required: keys(until_fields);\n type: object;\n };\n capture_input: {\n for item in keys(until_fields) { [item]: item; }\n };\n port: { allowed_parties: ["payer"]; };\n steps: [];\n }\n }\n }\n}\n',
66
+ ],
67
+ [
68
+ "settlements/security_deposit.hsx",
69
+ 'module std.settlements.security_deposit\n\nexport instrument security_deposit<C>(payer: party, holder: party, amount: money<C>, claim: optional<condition>, return: optional<condition>, claim_amount: optional<block>, deadline: optional<date>, claim_to: optional<party>, return_to: optional<party>, memo: optional<text>, claim_input: optional<block>, claim_capture: optional<block>, fund_failure_point: optional<text>, id_prefix_override: optional<text>) {\n let(claim_name): claim;\n let(return_name): return;\n let(payer_account_field): camel(concat(payer, "_account_id"));\n let(holder_account_field): camel(concat(holder, "_account_id"));\n let(claim_actor): at(claim_allowed, 1);\n let(claim_role): if_eq(claim_actor, payer, "payer", "beneficiary");\n let(claim_field): get(claim_amount, "field");\n let(claim_bound): get(claim_amount, "bound");\n let(claim_remainder): get(claim_amount, "remainder");\n let(deadline_field): concat(deadline);\n let(memo_field): concat(memo);\n let(claim_to_role): if_eq(claim_to, payer, "payer", "beneficiary");\n let(return_to_role): if_eq(return_to, payer, "payer", "beneficiary");\n agent_description: "Reach for security deposit when money is reserved against the {payer} in the {holder}\'s favor and later claimed or returned. The funds stay reserved and move only on the claim. Pick captured payment when the holder takes the money in slices, and instant transfer when nothing is held.";\n summary: "Refundable deposit from {payer} held for {holder}";\n title: sentence(instrument);\n when(id_prefix_override) { id_prefix: id_prefix_override; }\n when_not(deadline) {\n when_not(claim_amount) {\n description: concat("Deposit: the ", amount, " is reserved against the ", payer, "\'s account in the ", holder, "\'s favor, then claimed or returned in full");\n }\n when(claim_amount) {\n description: concat("Deposit: the ", amount, " is reserved against the ", payer, "\'s account in the ", holder, "\'s favor, then ", claim_field, " is claimed and the exact remainder returned, or the deposit is returned in full");\n }\n }\n fields {\n when_not(deadline) {\n amount { type: money<C>; description: "The deposit amount in {C} minor units, reserved in full and fully accounted on claim or return"; }\n }\n when(deadline) {\n let(reference_filter_key): "x-hyperscale-reference-filter";\n amount { type: money<C>; description: "Positive minor-unit integer amount serialized as a string (at most 18 digits)"; }\n [deadline_field] { type: date; }\n [holder_account_field] { type: account<C>; description: "Hyperscale account ID"; pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; [reference_filter_key]: { column: role; values: [customer_balance]; }; }\n [payer_account_field] { type: account<C>; description: "Hyperscale account ID"; pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; [reference_filter_key]: { column: role; values: [customer_balance]; }; }\n when(memo) { [memo_field] { type: text; max_length: 180; min_length: 1; optional: true; } }\n }\n }\n lifecycle {\n when_not(deadline) {\n states created held claimed returned;\n initial created;\n on place_deposit: created -> held;\n on [claim_name]: held -> claimed;\n on [return_name]: held -> returned;\n }\n when(deadline) {\n states created held claimed returned expired canceled;\n initial created;\n on cancel: created -> canceled;\n on claim: held -> claimed;\n on expire: held -> expired;\n on fund: created -> held;\n on return: held -> returned;\n }\n }\n parties {\n payer: payer;\n beneficiary: holder;\n }\n when_not(deadline) {\n action create {\n agent_description: "Open the deposit row before anything is reserved. The caller supplies the {amount}, the currency, and the {payer} and {holder} accounts. Nothing is reserved yet, call place deposit next.";\n summary: concat("Create a ", words(instrument));\n moves: [];\n steps: [];\n }\n action place_deposit {\n agent_description: "Reserve the {amount} against the {payer}\'s account in the {holder}\'s favor. The deposit must be created. The money is held, not paid: the claim posts it to the {holder} and the return releases it back.";\n let(metadata_instrument): "metadata.instrumentId";\n let(metadata_instance): "metadata.instrumentInstanceId";\n let(metadata_phase): "metadata.phase";\n summary: "Reserve the {amount} against the {payer}\'s account";\n moves: [{ key: reservation; operation: internal_transfer.reserve; bind: { amount: { from: instance; path: concat("fields.", amount); }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", holder_account_field); }; [metadata_instrument]: { from: const; value: instrument; }; [metadata_instance]: { from: instance; path: instrumentInstanceId; }; [metadata_phase]: { from: const; value: place_deposit; }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payer_account_field); }; }; capture: { placeDepositReservationTransferId: transferId; }; }];\n steps: [];\n }\n action [claim_name] {\n agent_description: "Claim the held deposit for the {holder}. The deposit must be in held. The reservation settles here, whole or up to the decided amount with the exact remainder released back to the {payer}. There is no return afterwards.";\n summary: "Claim the deposit for the {holder} through {claim}";\n when_not(claim_amount) {\n moves: [{ key: post; operation: internal_transfer.post; bind: { transferId: { from: instance; path: refs.placeDepositReservationTransferId; }; }; }];\n }\n when(claim_amount) {\n let(decided_clause): "decided amount";\n input {\n type: object;\n additional_properties: false;\n properties {\n for input_name in keys(claim_fields) {\n [input_name] { type: string; description: "Required decision reference retained in the operation receipt"; max_length: 180; min_length: 1; }\n }\n [claim_field] { type: string; description: "Caller-decided amount in minor units"; pattern: "^(0|[1-9][0-9]{0,17})$"; }\n }\n required: keys(claim_fields);\n }\n [decided_clause]: { field: claim_field; bound_field: claim_bound; remainder_action: return_name; };\n port { allowed_parties: [claim_role]; };\n moves: [{ key: post; operation: internal_transfer.post; bind: { amount: { from: input; path: claim_field; }; currency: { from: instance; path: fields.currency; }; postMode: { from: const; value: partial_only; }; transferId: { from: instance; path: refs.placeDepositReservationTransferId; }; }; }, { key: remainder; operation: internal_transfer.void; bind: { reason: { from: const; value: "Return the unclaimed deposit remainder"; }; transferId: { from: instance; path: refs.placeDepositReservationTransferId; }; }; }];\n }\n steps: [];\n }\n action [return_name] {\n agent_description: "Return the held deposit to the {payer}. The deposit must be in held and unclaimed. This releases the reservation whole and the {holder} receives nothing.";\n summary: "Return the deposit to the {payer} through {return}";\n moves: [{ key: void; operation: internal_transfer.void; bind: { reason: { from: const; value: "Deposit returned in full"; }; transferId: { from: instance; path: refs.placeDepositReservationTransferId; }; }; }];\n steps: [];\n }\n }\n when(deadline) {\n required: [payer_account_field, holder_account_field, amount, currency, deadline_field];\n caller_parked_states: { created: "funding or canceling an unfunded hold is the payer\'s decision"; };\n distinct_parties: true;\n dials: [{ field: deadline_field; key: holding_window; kind: window; maxOffset: "P90D"; summary: "Maximum time before the machine returns an unclaimed hold."; title: "Holding window"; }];\n action create {\n agent_description: "Open the hold by recording the {payer}, the {holder}, the {amount}, and the deadline. No money moves here, so a created hold costs the {payer} nothing until fund runs. The deadline is when the machine returns anything still unclaimed.";\n deadline: { field: deadline_field; };\n summary: concat("Create a ", words(instrument));\n moves: [];\n steps: [];\n }\n action fund {\n agent_description: "Reserve the whole {amount} out of the {payer}\'s balance for the {holder}. This moves money and the {payer} can no longer spend it. Only a created hold funds. The reservation carries no expiry of its own, so the hold\'s deadline governs when it comes back.";\n deadline: { field: deadline_field; };\n moves: [{ key: reservation; operation: internal_transfer.reserve; bind: { amount: { from: instance; path: concat("fields.", amount); }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", holder_account_field); }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", payer_account_field); }; }; capture: { holdTransferId: transferId; }; }];\n when(fund_failure_point) { sandbox_failure_point: fund_failure_point; }\n steps: [];\n summary: "Fund the security deposit";\n }\n action claim {\n agent_description: "Post the {holder}\'s decided amount out of the reservation and void the remainder back to the {payer} in one linked group. This moves money and does not reverse. Only a funded hold claims, and the claimed amount cannot exceed the held {amount}.";\n deadline: { field: deadline_field; };\n when(claim_capture) { capture_input: claim_capture; }\n when(claim_amount) {\n decided_amount: { field: claim_field; bound_field: claim_bound; remainder_action: claim_remainder; };\n }\n when(claim_input) { input: claim_input; }\n when(claim_to) { port { allowed_parties: [claim_to_role]; }; }\n moves: [{ key: "claim"; operation: internal_transfer.post; bind: { amount: { from: input; path: claim_field; }; currency: { from: instance; path: fields.currency; }; postMode: { from: const; value: partial_only; }; transferId: { from: instance; path: refs.holdTransferId; }; }; }, { key: remainder; operation: internal_transfer.void; bind: { reason: { from: const; value: "Return unclaimed deposit remainder"; }; transferId: { from: instance; path: refs.holdTransferId; }; }; }];\n steps: [];\n summary: "Claim the security deposit";\n }\n action return {\n agent_description: "Void the whole reservation so the {payer} gets every unit back. Use this when the {holder} decides to keep nothing. This moves money and does not reverse. Only a funded hold returns.";\n deadline: { field: deadline_field; };\n when(return_to) { port { allowed_parties: [return_to_role]; }; }\n moves: [{ key: "return"; operation: internal_transfer.void; bind: { reason: { from: const; value: "Deposit returned in full"; }; transferId: { from: instance; path: refs.holdTransferId; }; }; }];\n steps: [];\n summary: "Return the security deposit";\n }\n action expire {\n due: { field: deadline_field; };\n moves: [{ key: expire; operation: internal_transfer.void; bind: { reason: { from: const; value: "Deposit hold expired"; }; transferId: { from: instance; path: refs.holdTransferId; }; }; }];\n steps: [];\n summary: "Expire the security deposit";\n }\n action cancel {\n agent_description: "Close a hold before anyone funds it. No money has moved, so this is a lifecycle transition only. Only a created hold cancels. A funded hold refuses, because its money is already reserved. Claim it or return it instead.";\n moves: [];\n steps: [];\n summary: "Cancel the security deposit";\n }\n }\n}\n',
70
+ ],
71
+ [
72
+ "settlements/settlement_batch.hsx",
73
+ 'module std.settlements.settlement_batch\n\nexport instrument settlement_batch<C>(\n settlement_account: party,\n source_capture_refs: text,\n fee_entries: text,\n external_reversal_offsets: text,\n close_trigger: date,\n payout_destination: party,\n negative_position: text,\n payout_acknowledgement: condition,\n payout_beneficiary_ref: text,\n) {\n fields {\n close_trigger { type: date; description: "Date the open batch freezes against later entries"; }\n currency { type: text; description: "ISO 4217 currency code"; minLength: 3; maxLength: 3; pattern: "^[A-Z]{3}$"; }\n payout_beneficiary_ref { type: text; description: "Beneficiary ID for the payout instruction"; pattern: "^ben_(sandbox|live)_[a-z0-9]{8,64}$"; }\n [payout_destination]AccountId { type: account<C>; description: concat("The ", words(payout_destination), " account"); pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; "x-hyperscale-reference-filter": { column: role; values: [customer_balance]; }; }\n [settlement_account]AccountId { type: account<C>; description: concat("The ", words(settlement_account), " account"); pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; "x-hyperscale-reference-filter": { column: role; values: [customer_balance]; }; }\n }\n lifecycle {\n states open closed calculated approved instructed acknowledged reconciled;\n initial open;\n on close: open -> closed;\n on calculate: closed -> calculated;\n on approve: calculated -> approved;\n on instruct: approved -> instructed;\n on [payout_acknowledgement]: instructed -> acknowledged;\n on reconcile: instructed|acknowledged -> reconciled;\n }\n parties { beneficiary: concat(camel(payout_destination), "AccountId"); payer: concat(camel(settlement_account), "AccountId"); }\n required: [concat(camel(payout_destination), "AccountId"), concat(camel(settlement_account), "AccountId"), close_trigger, currency, payout_beneficiary_ref];\n title: sentence(instrument);\n id_prefix: prefix(instrument);\n agent_description: "Reach for settlement batch when many charges over a period roll up into one payout. Capture entries and adjustments accrue against an open batch, the batch freezes on its close date, calculate proves one signed net payable, and instruct sends a single external payout. Weighted distribution goes the other way, one amount out to many recipients.";\n summary: concat("Payout batch from ", words(settlement_account), " to ", words(payout_destination));\n description: "Immutable batch of capture lineage and signed adjustments that creates one payout";\n action create { agent_description: "Open a batch that capture entries and adjustments can accrue into. No money moves. The batch keeps taking entries until its close date freezes it."; summary: concat("Open a ", words(instrument)); moves: []; steps: []; }\n action close { summary: "Freeze the batch and stop all new entries"; due { field: close_trigger; } moves: []; steps: []; }\n action calculate {\n agent_description: "Prove and freeze the one net payable from gross captures plus credit adjustments minus debit adjustments. The batch must be closed first. A zero or negative net is refused, so a batch in deficit never reaches a payout. No money moves.";\n summary: "Prove and freeze the one signed net payable amount";\n computes signed_sum {\n amountRef: netPayable; onNegative: refuse; onZero: refuse;\n sources: [\n { amountField: amount; instrumentId: concat(instrument, "_capture_entry"); refField: concat(camel(instrument), "Id"); sign: add; statuses: [accrued]; subtotalRef: grossCaptureAmount; },\n { amountField: amount; instrumentId: concat(instrument, "_credit_adjustment"); refField: concat(camel(instrument), "Id"); sign: add; statuses: [applied]; subtotalRef: creditAdjustmentAmount; },\n { amountField: amount; instrumentId: concat(instrument, "_debit_adjustment"); refField: concat(camel(instrument), "Id"); sign: subtract; statuses: [applied]; subtotalRef: debitAdjustmentAmount; },\n ];\n }\n moves: []; steps: [];\n }\n action approve { agent_description: "Sign off on the frozen net payable. The batch must already be calculated. Nothing is recomputed and no money moves. This is the gate instruct waits on."; summary: "Approve the frozen payable without recomputing it"; moves: []; steps: []; }\n action instruct {\n agent_description: "Create one external payout for the frozen net payable, drawn on the settlement account and sent to the stored beneficiary. The batch must be approved. This moves money off the platform and is idempotent, so a retry never pays twice.";\n summary: "Create one idempotent payout from the frozen net payable";\n payout { amount: "refs.netPayable"; beneficiaryField: payout_beneficiary_ref; beneficiaryPartyField: concat(camel(payout_destination), "AccountId"); capture: payoutId; currencyField: currency; sourceAccountField: concat(camel(settlement_account), "AccountId"); speed: standard; }\n moves: []; steps: [];\n }\n action [payout_acknowledgement] {\n agent_description: "Record the beneficiary confirmation that the payout landed, with the reference kept in the receipt. The batch must already be instructed. Only the payout destination may call it. No money moves.";\n summary: "Record the tenant\'s payout acknowledgement in the receipt";\n port { allowedParties: [beneficiary]; }\n input { type: object; properties: { acknowledgementReference: { type: string; description: "Required decision reference retained in the operation receipt"; minLength: 1; maxLength: 180; }; }; required: [acknowledgementReference]; additionalProperties: false; }\n capture_input { acknowledgementReference: acknowledgementReference; }\n moves: []; steps: [];\n }\n action reconcile {\n summary: "Match durable evidence that the payout settled";\n due { field: close_trigger; offset: "P30D"; }\n reconcile {\n amount: "refs.netPayable"; capture: settlementEvidenceId; counterpartyRef: payoutId;\n currencyField: currency; direction: debit; evidence: statement_line;\n exception { amountField: amount; childInstrumentId: concat(instrument, "_debit_adjustment"); maxOpen: 1; reasonField: adjustmentReference; refField: concat(camel(instrument), "Id"); }\n match { law: exact; }\n within { offset: "P30D"; }\n }\n moves: []; steps: [];\n }\n instruments {\n instrument {\n let(parent_name): instrument;\n id: concat(parent_name, "_capture_entry");\n id_prefix: concat(prefix(parent_name), "ce");\n fields {\n amount { type: money<C>; description: "Gross captured amount in minor units"; }\n [source_capture_refs] { type: text; description: "Immutable source capture reference"; minLength: 1; maxLength: 180; }\n currency { type: text; description: "ISO 4217 currency code"; minLength: 3; maxLength: 3; pattern: "^[A-Z]{3}$"; }\n [parent_name]Id { type: ref<parent_name>; description: "Open batch this capture entry accrues into"; pattern: concat("^", prefix(parent_name), "_(sandbox|live)_[a-z0-9]{8,64}$"); }\n }\n lifecycle { states created accrued; initial created; on accrue: created -> accrued; }\n required: [amount, currency, concat(camel(parent_name), "Id"), source_capture_refs];\n agent_description: "One gross capture that belongs to an open batch. Record one per source capture so the net payable keeps its lineage back to the original charge.";\n title: concat(sentence(parent_name), " Capture Entry"); summary: "Gross capture lineage entry"; description: "One gross capture entry linked to an open payout batch";\n action create { agent_description: "Record one capture with its source reference against an open batch. The batch must be open and share the currency. No money moves, and the entry counts toward the net payable only once it accrues."; summary: "Create a capture lineage entry on an open batch"; requires refs { field: concat(camel(parent_name), "Id"); statuses: [open]; match: { "fields.currency": "fields.currency"; }; } moves: []; steps: []; }\n action accrue { agent_description: "Count this capture toward the batch gross total. The entry must be created and its batch still open, because a closed batch admits nothing new. No money moves."; summary: "Accrue the capture entry into the open batch"; requires refs { field: concat(camel(parent_name), "Id"); statuses: [open]; match: { "fields.currency": "fields.currency"; }; } moves: []; steps: []; }\n }\n for adjustment_kind in [credit, debit] {\n instrument {\n let(parent_name): instrument;\n id: concat(parent_name, "_", adjustment_kind, "_adjustment");\n id_prefix: concat(prefix(parent_name), if_eq(adjustment_kind, "credit", "ca", "da"));\n fields {\n adjustmentReference { type: text; description: "Immutable explicit adjustment reference"; minLength: 1; maxLength: 180; }\n amount { type: money<C>; description: concat(title(adjustment_kind), " adjustment amount in minor units"); }\n [source_capture_refs] { type: text; description: "Original capture reference that this adjustment corrects"; minLength: 1; maxLength: 180; }\n currency { type: text; description: "ISO 4217 currency code"; minLength: 3; maxLength: 3; pattern: "^[A-Z]{3}$"; }\n [external_reversal_offsets] { type: text; description: "Optional externally decided reversal reference"; minLength: 1; maxLength: 180; optional: true; }\n [fee_entries] { type: text; description: "Optional fee entry reference"; minLength: 1; maxLength: 180; optional: true; }\n [parent_name]Id { type: ref<parent_name>; description: "Open batch this adjustment applies to"; pattern: concat("^", prefix(parent_name), "_(sandbox|live)_[a-z0-9]{8,64}$"); }\n }\n lifecycle { states created applied; initial created; on adjust: created -> applied; on correct: created -> applied; }\n required: [amount, currency, adjustmentReference, concat(camel(parent_name), "Id"), source_capture_refs];\n agent_description: concat("One ", adjustment_kind, " adjustment against an open batch, carrying the capture reference it corrects. Credit adjustments add to the net payable and debit adjustments subtract from it, so a late correction lands on the current open batch instead of reopening a closed one.");\n title: concat(sentence(parent_name), " ", title(adjustment_kind), " Adjustment"); summary: concat(title(adjustment_kind), " adjustment with capture lineage"); description: concat("One ", adjustment_kind, " adjustment linked to an open payout batch; closed batches stay unchanged");\n action create { agent_description: concat("Record a ", adjustment_kind, " adjustment on an open batch, naming the capture reference it corrects. The batch must be open and share the currency. No money moves, and the adjustment counts only once it is applied."); summary: concat("Create a ", adjustment_kind, " adjustment on an open batch"); requires refs { field: concat(camel(parent_name), "Id"); statuses: [open]; match: { "fields.currency": "fields.currency"; }; } moves: []; steps: []; }\n action adjust { agent_description: concat("Apply the ", adjustment_kind, " adjustment so calculate counts it. The adjustment must be created and its batch still open. No money moves. The effect shows up in the batch net payable."); summary: concat("Apply the ", adjustment_kind, " adjustment to the open batch"); requires refs { field: concat(camel(parent_name), "Id"); statuses: [open]; match: { "fields.currency": "fields.currency"; }; } moves: []; steps: []; }\n action correct { agent_description: "Apply this adjustment as a correction on the open batch it names. Use it when the batch carrying the original entry has already closed, because a closed batch never changes. The adjustment must be created and no money moves."; summary: "Record a later correction on this open batch instead of changing the closed source batch"; requires refs { field: concat(camel(parent_name), "Id"); statuses: [open]; match: { "fields.currency": "fields.currency"; }; } moves: []; steps: []; }\n }\n }\n }\n}\n',
74
+ ],
75
+ [
76
+ "settlements/swap.hsx",
77
+ 'module std.settlements.swap;\nexport instrument swap<C>(between: list<party>, amounts: block, fees: block, release: condition, dispute: condition, side_names: optional<block>, lifecycle_state_order: optional<list<text>>, action_bindings: optional<block>, parked_states: optional<block>, fixed_prefix: optional<text>) {\n let(side_a): at(between, 1);\n let(side_b): at(between, 2);\n let(side_a_amount): get(amounts, side_a);\n let(side_b_amount): get(amounts, side_b);\n let(side_a_fee): get(fees, side_a);\n let(side_b_fee): get(fees, side_b);\n when(side_names) {\n let(side_a_name): get(side_names, "first");\n let(side_b_name): get(side_names, "second");\n }\n when_not(side_names) {\n let(side_a_name): side_a;\n let(side_b_name): side_b;\n }\n let(side_a_account): concat(camel(side_a_name), "AccountId");\n let(side_b_account): concat(camel(side_b_name), "AccountId");\n agent_description: "Reach for swap when two named parties pay each other in one atomic trade and neither leg may settle alone. Both principals fund one escrow together, both cross-payments reserve together, and one dispute unwinds both. A single payer paying a single payee is instant transfer instead.";\n title: sentence(instrument);\n when(fixed_prefix) {\n id_prefix: fixed_prefix;\n }\n when_not(fixed_prefix) {\n id_prefix: prefix(instrument);\n }\n summary: concat("Two-party atomic trade between ", words(side_a), " and ", words(side_b));\n description: concat("Atomic swap between ", words(side_a), " and ", words(side_b), "; half-funded and half-released states do not exist");\n distinct_parties: true;\n when(side_names) {\n parties {\n payer: side_a_account;\n beneficiary: side_b_account;\n }\n }\n when_not(side_names) {\n parties {\n payer: side_a;\n beneficiary: side_b;\n }\n }\n required: [side_a_account, side_b_account, platformAccountId, concat(side_a_amount), concat(side_b_amount), concat(side_a_fee), concat(side_b_fee), currency];\n when_not(side_names) {\n computes fees {\n amountField: concat(side_a_fee);\n baseField: concat(side_a_amount);\n bearerField: side_a_account;\n position: on_top;\n rule {\n currencyField: currency;\n field: concat(side_a_fee);\n kind: exact;\n }\n }\n computes fees {\n amountField: concat(side_b_fee);\n baseField: concat(side_b_amount);\n bearerField: side_b_account;\n position: on_top;\n rule {\n currencyField: currency;\n field: concat(side_b_fee);\n kind: exact;\n }\n }\n }\n when(parked_states) {\n caller_parked_states: parked_states;\n }\n fields {\n when(side_names) {\n clawbackAt {\n type: date;\n description: "Machine-owned absolute end of the release clawback window";\n optional: true;\n }\n currency {\n type: text;\n description: "One currency for both trade legs and both fees";\n const: C;\n }\n "[side_a_account]" {\n type: account<C>;\n description: "First trade party and funder";\n pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$";\n "x-hyperscale-reference-filter" {\n column: role;\n values: [customer_balance];\n }\n }\n "[side_a_amount]" {\n type: get(amounts, side_a);\n description: concat("Amount side A holds against the whole exchange, in ", C, " minor units");\n }\n "[side_a_fee]" {\n type: get(fees, side_a);\n description: "Side A custody fee charged on top and never placed in escrow";\n }\n "[side_b_account]" {\n type: account<C>;\n description: "Second trade party and funder";\n pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$";\n "x-hyperscale-reference-filter" {\n column: role;\n values: [customer_balance];\n }\n }\n "[side_b_amount]" {\n type: get(amounts, side_b);\n description: concat("Amount side B holds against the whole exchange, in ", C, " minor units");\n }\n "[side_b_fee]" {\n type: get(fees, side_b);\n description: "Side B custody fee charged on top and never placed in escrow";\n }\n }\n when_not(side_names) {\n clawbackAt {\n type: date;\n description: concat("Machine-owned end of the ", dispute_within, " whole-trade dispute window");\n }\n "[side_a_amount]" {\n type: get(amounts, side_a);\n description: "Side A amount in SAR minor units, held against the whole trade";\n }\n "[side_b_amount]" {\n type: get(amounts, side_b);\n description: "Side B amount in SAR minor units, held against the whole trade";\n }\n "[side_a_fee]" {\n type: get(fees, side_a);\n description: concat("Immutable exact ", words(side_a), " service fee in SAR minor units");\n }\n "[side_b_fee]" {\n type: get(fees, side_b);\n description: concat("Immutable exact ", words(side_b), " service fee in SAR minor units");\n }\n }\n platformAccountId {\n type: account<C>;\n when(side_names) {\n description: "Product revenue or customer balance account collecting trade service fees";\n }\n when_not(side_names) {\n description: "The product fee collection account";\n }\n pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$";\n "x-hyperscale-fee-collection-port": true;\n "x-hyperscale-reference-filter" {\n column: role;\n values: [customer_balance, product_revenue];\n }\n }\n }\n when(lifecycle_state_order) {\n let(states_key): "states";\n lifecycle {\n "[states_key]": lifecycle_state_order;\n initial created;\n on abandon: created -> abandoned;\n on cancel: funded -> cancelled;\n on dispute: released -> clawed_back;\n on fund: created -> funded;\n on post: released -> settled;\n on release: funded -> released;\n }\n }\n when_not(lifecycle_state_order) {\n lifecycle {\n states created abandoned funded cancelled released settled clawed_back;\n initial created;\n on abandon: created -> abandoned;\n on cancel: funded -> cancelled;\n on dispute: released -> clawed_back;\n on fund: created -> funded;\n on post: released -> settled;\n on release: funded -> released;\n }\n }\n when_not(action_bindings) {\n action abandon {\n agent_description: "Walk away from a trade that never funded. Only a created trade abandons, and its escrow account must hold nothing, so there is nothing to refund. No money moves.";\n summary: "Abandon the trade before its atomic funding batch";\n public_action: concat("abandon", title(camel(instrument)));\n requires drained {\n path: "refs.escrowAccountId";\n }\n moves: [];\n steps: [];\n }\n action cancel {\n agent_description: "Unwind a funded trade before release. Both principals return from escrow to their own sides in one batch. The trade must be funded and not yet released. The service fees taken at funding stay with the platform.";\n summary: "Cancel and return both trade principals atomically";\n public_action: concat("cancel", title(camel(instrument)));\n moves: [{\n amount: concat(side_a_amount);\n from: "refs.escrowAccountId";\n to: side_a;\n key: side_a_refund;\n }, {\n amount: concat(side_b_amount);\n from: "refs.escrowAccountId";\n to: side_b;\n key: side_b_refund;\n }];\n steps: [];\n }\n action create {\n agent_description: "Open a trade and provision its escrow account. No money moves. Both principals and both exact service fees are fixed here and cannot change afterwards.";\n summary: concat("Create a ", words(instrument), " atomic trade");\n public_action: concat("create", title(camel(instrument)));\n moves: [];\n steps: [{\n operation: "account.escrow.provision";\n bind {\n currency {\n from: instance;\n path: "fields.currency";\n }\n "owner.id" {\n from: instance;\n path: productId;\n }\n "owner.type" {\n from: const;\n value: product;\n }\n productId {\n from: instance;\n path: productId;\n }\n role {\n from: const;\n value: product_escrow;\n }\n }\n capture {\n escrowAccountId: accountId;\n }\n }];\n }\n action dispute {\n agent_description: "Claw back a released trade inside its dispute window. Both cross-payment reservations void and both principals return from escrow in one batch. The trade must be released and the clawback moment must not have passed. Either trading party may call it.";\n summary: "Void both reservations, then refund both principals atomically";\n public_action: concat("dispute", title(camel(instrument)));\n deadline {\n field: clawbackAt;\n }\n port {\n allowedParties: [payer, beneficiary];\n }\n moves: [{\n bind {\n reason {\n from: const;\n value: "Whole trade disputed inside the clawback window";\n }\n transferId {\n from: instance;\n path: "refs.releaseSideATransferId";\n }\n }\n key: side_a_void;\n operation: "internal_transfer.void";\n }, {\n bind {\n reason {\n from: const;\n value: "Whole trade disputed inside the clawback window";\n }\n transferId {\n from: instance;\n path: "refs.releaseSideBTransferId";\n }\n }\n key: side_b_void;\n operation: "internal_transfer.void";\n }, {\n bind {\n amount {\n from: instance;\n path: concat("fields.", side_a_amount);\n }\n currency {\n from: instance;\n path: "fields.currency";\n }\n destinationAccountId {\n from: instance;\n path: concat("fields.", side_a_account);\n }\n "metadata.clawbackOfTransferId" {\n from: instance;\n path: "refs.releaseSideATransferId";\n }\n "metadata.instrumentId" {\n from: const;\n value: instrument;\n }\n "metadata.instrumentInstanceId" {\n from: instance;\n path: instrumentInstanceId;\n }\n "metadata.phase" {\n from: const;\n value: "dispute";\n }\n productId {\n from: instance;\n path: productId;\n }\n sourceAccountId {\n from: instance;\n path: "refs.escrowAccountId";\n }\n }\n capture {\n disputeSideARefundTransferId: transferId;\n }\n key: side_a_refund;\n operation: "internal_transfer.create";\n }, {\n bind {\n amount {\n from: instance;\n path: concat("fields.", side_b_amount);\n }\n currency {\n from: instance;\n path: "fields.currency";\n }\n destinationAccountId {\n from: instance;\n path: concat("fields.", side_b_account);\n }\n "metadata.clawbackOfTransferId" {\n from: instance;\n path: "refs.releaseSideBTransferId";\n }\n "metadata.instrumentId" {\n from: const;\n value: instrument;\n }\n "metadata.instrumentInstanceId" {\n from: instance;\n path: instrumentInstanceId;\n }\n "metadata.phase" {\n from: const;\n value: "dispute";\n }\n productId {\n from: instance;\n path: productId;\n }\n sourceAccountId {\n from: instance;\n path: "refs.escrowAccountId";\n }\n }\n capture {\n disputeSideBRefundTransferId: transferId;\n }\n key: side_b_refund;\n operation: "internal_transfer.create";\n }];\n steps: [];\n }\n action fund {\n agent_description: "Fund both sides at once. Each side pays its principal into escrow and its service fee to the platform account, four transfers in one batch. The trade must be created and unfunded. This moves real money from both parties.";\n summary: "Fund both trade sides and collect on-top fees atomically";\n public_action: concat("fund", title(camel(instrument)));\n moves: [{\n amount: concat(side_a_amount);\n from: side_a;\n to: "refs.escrowAccountId";\n key: side_a_principal;\n }, {\n amount: concat(side_b_amount);\n from: side_b;\n to: "refs.escrowAccountId";\n key: side_b_principal;\n }, {\n amount: concat(side_a_fee);\n from: side_a;\n to: platformAccountId;\n key: side_a_service_fee;\n }, {\n amount: concat(side_b_fee);\n from: side_b;\n to: platformAccountId;\n key: side_b_service_fee;\n }];\n steps: [];\n }\n action post {\n summary: "Post both trade reservations when the clawback window matures";\n due {\n field: clawbackAt;\n }\n moves: [{\n bind {\n transferId {\n from: instance;\n path: "refs.releaseSideATransferId";\n }\n }\n key: "side_a";\n operation: "internal_transfer.post";\n }, {\n bind {\n transferId {\n from: instance;\n path: "refs.releaseSideBTransferId";\n }\n }\n key: "side_b";\n operation: "internal_transfer.post";\n }];\n steps: [];\n }\n action release {\n agent_description: "Reserve each side\'s principal for the other side and start the dispute window. The trade must be funded. Money is reserved, not settled. It posts on its own when the window matures, and dispute unwinds it before then. Either trading party may call it.";\n summary: "Reserve both cross-payments for the whole-trade clawback window";\n public_action: concat("release", title(camel(instrument)));\n port {\n allowedParties: [payer, beneficiary];\n }\n sets_at {\n field: clawbackAt;\n offset: dispute_within;\n }\n moves: [{\n bind {\n amount {\n from: instance;\n path: concat("fields.", side_a_amount);\n }\n currency {\n from: instance;\n path: "fields.currency";\n }\n destinationAccountId {\n from: instance;\n path: concat("fields.", side_b_account);\n }\n "metadata.clawbackAt" {\n from: instance;\n path: "fields.clawbackAt";\n }\n "metadata.instrumentId" {\n from: const;\n value: instrument;\n }\n "metadata.instrumentInstanceId" {\n from: instance;\n path: instrumentInstanceId;\n }\n "metadata.phase" {\n from: const;\n value: "release";\n }\n productId {\n from: instance;\n path: productId;\n }\n sourceAccountId {\n from: instance;\n path: "refs.escrowAccountId";\n }\n }\n capture {\n releaseSideATransferId: transferId;\n }\n key: "side_a";\n operation: "internal_transfer.reserve";\n }, {\n bind {\n amount {\n from: instance;\n path: concat("fields.", side_b_amount);\n }\n currency {\n from: instance;\n path: "fields.currency";\n }\n destinationAccountId {\n from: instance;\n path: concat("fields.", side_a_account);\n }\n "metadata.clawbackAt" {\n from: instance;\n path: "fields.clawbackAt";\n }\n "metadata.instrumentId" {\n from: const;\n value: instrument;\n }\n "metadata.instrumentInstanceId" {\n from: instance;\n path: instrumentInstanceId;\n }\n "metadata.phase" {\n from: const;\n value: "release";\n }\n productId {\n from: instance;\n path: productId;\n }\n sourceAccountId {\n from: instance;\n path: "refs.escrowAccountId";\n }\n }\n capture {\n releaseSideBTransferId: transferId;\n }\n key: "side_b";\n operation: "internal_transfer.reserve";\n }];\n steps: [];\n }\n }\n when(action_bindings) {\n let(event_prefix): get(action_bindings, "event_prefix");\n let(fund_principal_capture): get(action_bindings, "fund_principal_capture");\n let(fund_fee_capture): get(action_bindings, "fund_fee_capture");\n let(fund_principal_phase): get(action_bindings, "fund_principal_phase");\n let(fund_fee_phase): get(action_bindings, "fund_fee_phase");\n let(release_capture): get(action_bindings, "release_capture");\n let(release_phase): get(action_bindings, "release_phase");\n let(release_key): get(action_bindings, "release_key");\n let(post_key): get(action_bindings, "post_key");\n let(dispute_capture): get(action_bindings, "dispute_capture");\n let(dispute_phase): get(action_bindings, "dispute_phase");\n let(dispute_reason): get(action_bindings, "dispute_reason");\n let(cancel_capture): get(action_bindings, "cancel_capture");\n let(cancel_phase): get(action_bindings, "cancel_phase");\n let(side_a_fund_capture): camel(concat(side_a_name, "_", fund_principal_capture, "_transfer_id"));\n let(side_b_fund_capture): camel(concat(side_b_name, "_", fund_principal_capture, "_transfer_id"));\n let(side_a_fee_capture): camel(concat(side_a_name, "_", fund_fee_capture, "_transfer_id"));\n let(side_b_fee_capture): camel(concat(side_b_name, "_", fund_fee_capture, "_transfer_id"));\n let(side_a_release_capture): camel(concat(side_a_name, "_", release_capture, "_id"));\n let(side_b_release_capture): camel(concat(side_b_name, "_", release_capture, "_id"));\n let(side_a_release_ref): concat("refs.", side_a_release_capture);\n let(side_b_release_ref): concat("refs.", side_b_release_capture);\n let(side_a_dispute_capture): camel(concat(side_a_name, "_", dispute_capture, "_transfer_id"));\n let(side_b_dispute_capture): camel(concat(side_b_name, "_", dispute_capture, "_transfer_id"));\n let(side_a_cancel_capture): camel(concat(side_a_name, "_", cancel_capture, "_transfer_id"));\n let(side_b_cancel_capture): camel(concat(side_b_name, "_", cancel_capture, "_transfer_id"));\n action create {\n agent_description: "Open a trade and provision its escrow account. No money moves. Both principals and both exact service fees are fixed here and cannot change afterwards.";\n summary: concat("Create a ", words(instrument), " atomic trade");\n public_action: concat("create", title(camel(instrument)));\n moves: [];\n steps: [{\n operation: "account.escrow.provision";\n bind {\n currency {\n from: instance;\n path: "fields.currency";\n }\n "owner.id" {\n from: instance;\n path: productId;\n }\n "owner.type" {\n from: const;\n value: product;\n }\n productId {\n from: instance;\n path: productId;\n }\n role {\n from: const;\n value: product_escrow;\n }\n }\n capture {\n escrowAccountId: accountId;\n }\n }];\n }\n action fund {\n agent_description: "Fund both sides at once. Each side pays its principal into escrow and its service fee to the platform account, four transfers in one batch. The trade must be created and unfunded. This moves real money from both parties.";\n summary: "Fund both trade sides and collect on-top fees atomically";\n public_action: concat("fund", title(camel(instrument)));\n event_name: concat(event_prefix, ".funded");\n sandbox_failure_point: "funding";\n moves: [{\n bind {\n amount {\n from: instance;\n path: concat("fields.", side_a_amount);\n }\n currency {\n from: instance;\n path: "fields.currency";\n }\n destinationAccountId {\n from: instance;\n path: "refs.escrowAccountId";\n }\n "metadata.instrumentId" {\n from: const;\n value: instrument;\n }\n "metadata.instrumentInstanceId" {\n from: instance;\n path: instrumentInstanceId;\n }\n "metadata.phase" {\n from: const;\n value: fund_principal_phase;\n }\n productId {\n from: instance;\n path: productId;\n }\n sourceAccountId {\n from: instance;\n path: concat("fields.", side_a_account);\n }\n }\n capture {\n "[side_a_fund_capture]": transferId;\n }\n key: side_a_principal;\n operation: "internal_transfer.create";\n }, {\n bind {\n amount {\n from: instance;\n path: concat("fields.", side_b_amount);\n }\n currency {\n from: instance;\n path: "fields.currency";\n }\n destinationAccountId {\n from: instance;\n path: "refs.escrowAccountId";\n }\n "metadata.instrumentId" {\n from: const;\n value: instrument;\n }\n "metadata.instrumentInstanceId" {\n from: instance;\n path: instrumentInstanceId;\n }\n "metadata.phase" {\n from: const;\n value: fund_principal_phase;\n }\n productId {\n from: instance;\n path: productId;\n }\n sourceAccountId {\n from: instance;\n path: concat("fields.", side_b_account);\n }\n }\n capture {\n "[side_b_fund_capture]": transferId;\n }\n key: side_b_principal;\n operation: "internal_transfer.create";\n }, {\n bind {\n amount {\n from: instance;\n path: concat("fields.", side_a_fee);\n }\n currency {\n from: instance;\n path: "fields.currency";\n }\n destinationAccountId {\n from: instance;\n path: "fields.platformAccountId";\n }\n "metadata.instrumentId" {\n from: const;\n value: instrument;\n }\n "metadata.instrumentInstanceId" {\n from: instance;\n path: instrumentInstanceId;\n }\n "metadata.phase" {\n from: const;\n value: fund_fee_phase;\n }\n productId {\n from: instance;\n path: productId;\n }\n sourceAccountId {\n from: instance;\n path: concat("fields.", side_a_account);\n }\n }\n capture {\n "[side_a_fee_capture]": transferId;\n }\n key: side_a_service_fee;\n operation: "internal_transfer.create";\n }, {\n bind {\n amount {\n from: instance;\n path: concat("fields.", side_b_fee);\n }\n currency {\n from: instance;\n path: "fields.currency";\n }\n destinationAccountId {\n from: instance;\n path: "fields.platformAccountId";\n }\n "metadata.instrumentId" {\n from: const;\n value: instrument;\n }\n "metadata.instrumentInstanceId" {\n from: instance;\n path: instrumentInstanceId;\n }\n "metadata.phase" {\n from: const;\n value: fund_fee_phase;\n }\n productId {\n from: instance;\n path: productId;\n }\n sourceAccountId {\n from: instance;\n path: concat("fields.", side_b_account);\n }\n }\n capture {\n "[side_b_fee_capture]": transferId;\n }\n key: side_b_service_fee;\n operation: "internal_transfer.create";\n }];\n steps: [];\n }\n action release {\n agent_description: "Reserve each side\'s principal for the other side and start the dispute window. The trade must be funded. Money is reserved, not settled. It posts on its own when the window matures, and dispute unwinds it before then. Either trading party may call it.";\n summary: "Reserve both cross-payments for the whole-trade clawback window";\n public_action: concat("release", title(camel(instrument)));\n event_name: concat(event_prefix, ".released");\n port {\n allowedParties: [payer, beneficiary];\n }\n sandbox_failure_point: "release";\n sets_at {\n field: clawbackAt;\n offset: dispute_within;\n }\n moves: [{\n bind {\n amount {\n from: instance;\n path: concat("fields.", side_a_amount);\n }\n currency {\n from: instance;\n path: "fields.currency";\n }\n destinationAccountId {\n from: instance;\n path: concat("fields.", side_b_account);\n }\n "metadata.clawbackAt" {\n from: instance;\n path: "fields.clawbackAt";\n }\n "metadata.instrumentId" {\n from: const;\n value: instrument;\n }\n "metadata.instrumentInstanceId" {\n from: instance;\n path: instrumentInstanceId;\n }\n "metadata.phase" {\n from: const;\n value: release_phase;\n }\n productId {\n from: instance;\n path: productId;\n }\n sourceAccountId {\n from: instance;\n path: "refs.escrowAccountId";\n }\n }\n capture {\n "[side_a_release_capture]": transferId;\n }\n key: concat("side_a_", release_key);\n operation: "internal_transfer.reserve";\n }, {\n bind {\n amount {\n from: instance;\n path: concat("fields.", side_b_amount);\n }\n currency {\n from: instance;\n path: "fields.currency";\n }\n destinationAccountId {\n from: instance;\n path: concat("fields.", side_a_account);\n }\n "metadata.clawbackAt" {\n from: instance;\n path: "fields.clawbackAt";\n }\n "metadata.instrumentId" {\n from: const;\n value: instrument;\n }\n "metadata.instrumentInstanceId" {\n from: instance;\n path: instrumentInstanceId;\n }\n "metadata.phase" {\n from: const;\n value: release_phase;\n }\n productId {\n from: instance;\n path: productId;\n }\n sourceAccountId {\n from: instance;\n path: "refs.escrowAccountId";\n }\n }\n capture {\n "[side_b_release_capture]": transferId;\n }\n key: concat("side_b_", release_key);\n operation: "internal_transfer.reserve";\n }];\n steps: [];\n }\n action post {\n summary: "Post both trade reservations when the clawback window matures";\n event_name: concat(event_prefix, ".posted");\n due {\n field: clawbackAt;\n }\n moves: [{\n bind {\n transferId {\n from: instance;\n path: side_a_release_ref;\n }\n }\n key: concat("side_a_", post_key);\n operation: "internal_transfer.post";\n }, {\n bind {\n transferId {\n from: instance;\n path: side_b_release_ref;\n }\n }\n key: concat("side_b_", post_key);\n operation: "internal_transfer.post";\n }];\n steps: [];\n }\n action dispute {\n agent_description: "Claw back a released trade inside its dispute window. Both cross-payment reservations void and both principals return from escrow in one batch. The trade must be released and the clawback moment must not have passed. Either trading party may call it.";\n summary: "Void both reservations, then refund both principals atomically";\n public_action: concat("dispute", title(camel(instrument)));\n event_name: concat(event_prefix, ".clawed_back");\n deadline {\n field: clawbackAt;\n }\n port {\n allowedParties: [payer, beneficiary];\n }\n moves: [{\n bind {\n reason {\n from: const;\n value: dispute_reason;\n }\n transferId {\n from: instance;\n path: side_a_release_ref;\n }\n }\n key: side_a_void;\n operation: "internal_transfer.void";\n }, {\n bind {\n reason {\n from: const;\n value: dispute_reason;\n }\n transferId {\n from: instance;\n path: side_b_release_ref;\n }\n }\n key: side_b_void;\n operation: "internal_transfer.void";\n }, {\n bind {\n amount {\n from: instance;\n path: concat("fields.", side_a_amount);\n }\n currency {\n from: instance;\n path: "fields.currency";\n }\n destinationAccountId {\n from: instance;\n path: concat("fields.", side_a_account);\n }\n "metadata.clawbackOfTransferId" {\n from: instance;\n path: side_a_release_ref;\n }\n "metadata.instrumentId" {\n from: const;\n value: instrument;\n }\n "metadata.instrumentInstanceId" {\n from: instance;\n path: instrumentInstanceId;\n }\n "metadata.phase" {\n from: const;\n value: dispute_phase;\n }\n productId {\n from: instance;\n path: productId;\n }\n sourceAccountId {\n from: instance;\n path: "refs.escrowAccountId";\n }\n }\n capture {\n "[side_a_dispute_capture]": transferId;\n }\n key: side_a_refund;\n operation: "internal_transfer.create";\n }, {\n bind {\n amount {\n from: instance;\n path: concat("fields.", side_b_amount);\n }\n currency {\n from: instance;\n path: "fields.currency";\n }\n destinationAccountId {\n from: instance;\n path: concat("fields.", side_b_account);\n }\n "metadata.clawbackOfTransferId" {\n from: instance;\n path: side_b_release_ref;\n }\n "metadata.instrumentId" {\n from: const;\n value: instrument;\n }\n "metadata.instrumentInstanceId" {\n from: instance;\n path: instrumentInstanceId;\n }\n "metadata.phase" {\n from: const;\n value: dispute_phase;\n }\n productId {\n from: instance;\n path: productId;\n }\n sourceAccountId {\n from: instance;\n path: "refs.escrowAccountId";\n }\n }\n capture {\n "[side_b_dispute_capture]": transferId;\n }\n key: side_b_refund;\n operation: "internal_transfer.create";\n }];\n steps: [];\n }\n action cancel {\n agent_description: "Unwind a funded trade before release. Both principals return from escrow to their own sides in one batch. The trade must be funded and not yet released. The service fees taken at funding stay with the platform.";\n summary: "Cancel and return both trade principals atomically";\n public_action: concat("cancel", title(camel(instrument)));\n event_name: concat(event_prefix, ".cancelled");\n moves: [{\n bind {\n amount {\n from: instance;\n path: concat("fields.", side_a_amount);\n }\n currency {\n from: instance;\n path: "fields.currency";\n }\n destinationAccountId {\n from: instance;\n path: concat("fields.", side_a_account);\n }\n "metadata.instrumentId" {\n from: const;\n value: instrument;\n }\n "metadata.instrumentInstanceId" {\n from: instance;\n path: instrumentInstanceId;\n }\n "metadata.phase" {\n from: const;\n value: cancel_phase;\n }\n productId {\n from: instance;\n path: productId;\n }\n sourceAccountId {\n from: instance;\n path: "refs.escrowAccountId";\n }\n }\n capture {\n "[side_a_cancel_capture]": transferId;\n }\n key: side_a_refund;\n operation: "internal_transfer.create";\n }, {\n bind {\n amount {\n from: instance;\n path: concat("fields.", side_b_amount);\n }\n currency {\n from: instance;\n path: "fields.currency";\n }\n destinationAccountId {\n from: instance;\n path: concat("fields.", side_b_account);\n }\n "metadata.instrumentId" {\n from: const;\n value: instrument;\n }\n "metadata.instrumentInstanceId" {\n from: instance;\n path: instrumentInstanceId;\n }\n "metadata.phase" {\n from: const;\n value: cancel_phase;\n }\n productId {\n from: instance;\n path: productId;\n }\n sourceAccountId {\n from: instance;\n path: "refs.escrowAccountId";\n }\n }\n capture {\n "[side_b_cancel_capture]": transferId;\n }\n key: side_b_refund;\n operation: "internal_transfer.create";\n }];\n steps: [];\n }\n action abandon {\n agent_description: "Walk away from a trade that never funded. Only a created trade abandons, and its escrow account must hold nothing, so there is nothing to refund. No money moves.";\n summary: "Abandon the trade before its atomic funding batch";\n public_action: concat("abandon", title(camel(instrument)));\n event_name: concat(event_prefix, ".abandoned");\n requires drained {\n path: "refs.escrowAccountId";\n }\n moves: [];\n steps: [];\n }\n }\n}\n',
78
+ ],
79
+ [
80
+ "settlements/threshold_pool.hsx",
81
+ 'module std.settlements.threshold_pool\n\nexport instrument threshold_pool<C>(\n contributor: optional<party>,\n beneficiary: optional<party>,\n target: money<C>,\n commitment: money<C>,\n max_contributors: optional<integer>,\n close_by: date,\n close_policy: optional<text>,\n overfund_policy: optional<text>,\n cancel_policy: optional<text>,\n fail_policy: optional<text>,\n beneficiary_account: optional<account<C>>,\n memo: optional<text>,\n contribution_instrument: optional<block>,\n wording: optional<block>,\n) {\n when(wording) {\n let(wording_unknown_keys): keys_except(wording, "pool_summary", "pool_description", "create_summary", "commitment_create_summary", "commitment_cancel_summary", "commitment_refund_summary");\n when(wording_unknown_keys) {\n unsupported {\n code: HSX1407;\n message: "threshold_pool wording contains an unknown key";\n fix: "use only the six declared threshold_pool wording keys";\n }\n }\n }\n agent_description: "Reach for threshold pool when many contributors commit toward one target and nothing is collected unless the pool reaches it by the close date. Commitments sit in escrow until the pool activates or fails. Pick weighted distribution to pay a pool out and instant transfer for a single payment.";\n when_not(contribution_instrument) {\n fields {\n [beneficiary]AccountId { type: account<C>; description: concat("The ", words(beneficiary), " account"); pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; "x-hyperscale-reference-filter": { column: role; values: [customer_balance]; }; }\n close_by { type: date; description: "Stored close anchor"; }\n currency { type: text; description: "ISO 4217 currency code"; minLength: 3; maxLength: 3; pattern: "^[A-Z]{3}$"; }\n maxContributors { type: integer; description: concat("Exactly ", max_contributors, " admitted contributors"); const: max_contributors; }\n target { type: money<C>; description: "Funding target in {C} minor units"; }\n }\n lifecycle {\n states open active failed settled;\n initial open;\n on activate: open -> active;\n on fail: open -> failed;\n on close: active -> settled;\n }\n parties { beneficiary: concat(camel(beneficiary), "AccountId"); }\n required: [concat(camel(beneficiary), "AccountId"), currency, target, close_by, maxContributors];\n title: sentence(instrument);\n id_prefix: prefix(instrument);\n let(pool_summary): get(wording, "pool_summary");\n when_not(pool_summary) { summary: concat("Threshold contribution pool for ", words(beneficiary)); }\n when(pool_summary) { summary: pool_summary; }\n let(pool_description): get(wording, "pool_description");\n when_not(pool_description) { description: "All-or-nothing aggregate contribution threshold"; }\n when(pool_description) { description: pool_description; }\n aggregate_invariants { childField: amount; childInstrumentId: concat(instrument, "_commitment"); childRefField: concat(camel(instrument), "Id"); childStatuses: [committed]; parentField: target; }\n aggregate_invariants { childInstrumentId: concat(instrument, "_commitment"); childRefField: concat(camel(instrument), "Id"); childStatuses: [committed]; count: true; parentField: maxContributors; }\n action create {\n agent_description: "Open the pool before any commitment exists. The caller supplies the target, the currency, the beneficiary account, the close anchor, and the pinned contributor count. No money moves and the pool opens for commitments.";\n let(create_summary): get(wording, "create_summary");\n when_not(create_summary) { summary: "Open the contribution pool"; }\n when(create_summary) { summary: create_summary; }\n moves: [];\n steps: [];\n }\n action activate {\n summary: "Activate when commitments meet the target";\n due { field: close_by; }\n requires aggregate { instrumentId: concat(instrument, "_commitment"); over: children; refField: concat(camel(instrument), "Id"); statuses: [committed]; check: { kind: sum_at_least; amountField: amount; targetField: target; }; }\n moves: [];\n steps: [];\n }\n action fail {\n summary: "Fail when commitments remain below target";\n due { field: close_by; }\n requires aggregate { instrumentId: concat(instrument, "_commitment"); over: children; refField: concat(camel(instrument), "Id"); statuses: [committed]; check: { kind: sum_below; amountField: amount; targetField: target; }; }\n moves: [];\n steps: [];\n }\n action close {\n agent_description: "Settle the pool once every admitted commitment is collected or was cancelled before activation. The pool must be active. No money moves here, collect already paid the beneficiary.";\n summary: "Settle after every admitted row is collected or was cancelled before activation";\n requires aggregate { instrumentId: concat(instrument, "_commitment"); over: children; refField: concat(camel(instrument), "Id"); statuses: [cancelled, collected]; check: { kind: all_in; }; }\n moves: [];\n steps: [];\n }\n instruments {\n instrument {\n let(parent_name): instrument;\n id: concat(parent_name, "_commitment");\n generatedPrefix: true;\n fields {\n amount { type: money<C>; description: "One whole commitment amount"; }\n [beneficiary]AccountId { type: account<C>; description: concat("The ", words(beneficiary), " account"); pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; "x-hyperscale-reference-filter": { column: role; values: [customer_balance]; }; }\n [parent_name]Id { type: ref<parent_name>; description: concat("The exact ", parent_name); pattern: concat("^", prefix(parent_name), "_(sandbox|live)_[a-z0-9]{8,64}$"); }\n [contributor]AccountId { type: account<C>; description: concat("The ", words(contributor), " account"); pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; "x-hyperscale-reference-filter": { column: role; values: [customer_balance]; }; }\n currency { type: text; description: "ISO 4217 currency code"; minLength: 3; maxLength: 3; pattern: "^[A-Z]{3}$"; }\n }\n lifecycle {\n states committed cancelled collected refunded;\n initial committed;\n on cancel: committed -> cancelled;\n on collect: committed -> collected;\n on refund: committed -> refunded;\n }\n parties { beneficiary: concat(camel(beneficiary), "AccountId"); payer: concat(camel(contributor), "AccountId"); }\n required: [concat(camel(beneficiary), "AccountId"), concat(camel(contributor), "AccountId"), amount, currency, concat(camel(parent_name), "Id")];\n title: concat(sentence(parent_name), " Commitment");\n agent_description: concat("Reach for this child row to record one whole commitment into a ", words(parent_name), ". Each contributor commits once, the money sits in the product escrow, and whether it is collected or refunded depends on the pool reaching its target.");\n summary: concat("Whole commitment to ", parent_name);\n description: concat("One whole commitment linked to ", parent_name);\n action create {\n agent_description: "Commit one whole amount into the pool escrow. The pool must still be open, the currency and beneficiary account must match it, and the committed total plus this amount must stay within the target. The money leaves the contributor now.";\n let(commitment_create_summary): get(wording, "commitment_create_summary");\n when_not(commitment_create_summary) { summary: "Store one whole commitment without exceeding the pool target"; }\n when(commitment_create_summary) { summary: commitment_create_summary; }\n requires refs { field: concat(camel(parent_name), "Id"); statuses: [open]; bind: { [beneficiary]AccountId: concat("fields.", camel(beneficiary), "AccountId"); currency: "fields.currency"; }; }\n requires exposure { amountField: amount; anchorField: concat(camel(parent_name), "Id"); capField: target; capOnAnchor: true; childInstrumentId: concat(parent_name, "_commitment"); statuses: [committed]; }\n moves: [{ amount: amount; from: payer; to: refs.escrowAccountId; key: commit; }];\n steps: [{ operation: "account.escrow.provision"; bind: { currency: { from: instance; path: "fields.currency"; }; "owner.id": { from: instance; path: productId; }; "owner.type": { from: const; value: product; }; productId: { from: instance; path: productId; }; role: { from: const; value: product_escrow; }; }; capture: { escrowAccountId: accountId; }; }];\n }\n action cancel {\n agent_description: "Pull one commitment back out of escrow to the contributor. The pool must still be open, so this is unavailable once the pool activates or fails. The money returns and the commitment is closed.";\n let(commitment_cancel_summary): get(wording, "commitment_cancel_summary");\n when_not(commitment_cancel_summary) { summary: "Cancel one commitment while the pool is open"; }\n when(commitment_cancel_summary) { summary: commitment_cancel_summary; }\n requires refs { field: concat(camel(parent_name), "Id"); statuses: [open]; match: { "fields.[beneficiary]AccountId": concat("fields.", camel(beneficiary), "AccountId"); "fields.currency": "fields.currency"; }; }\n moves: [{ amount: amount; from: refs.escrowAccountId; to: payer; key: cancel; }];\n steps: [];\n }\n action collect {\n agent_description: "Release one commitment out of escrow to the beneficiary. The pool must be active, which happens only once commitments meet the target. The money moves for good.";\n summary: "Collect one successful commitment whole";\n requires refs { field: concat(camel(parent_name), "Id"); statuses: [active]; match: { "fields.[beneficiary]AccountId": concat("fields.", camel(beneficiary), "AccountId"); "fields.currency": "fields.currency"; }; }\n moves: [{ amount: amount; from: refs.escrowAccountId; to: beneficiary; key: collect; }];\n steps: [];\n }\n action refund {\n agent_description: "Return one commitment out of escrow to the contributor after the pool failed to reach its target. The pool must be in failed. The money returns and the commitment is closed.";\n let(commitment_refund_summary): get(wording, "commitment_refund_summary");\n when_not(commitment_refund_summary) { summary: "Refund one failed-pool commitment whole"; }\n when(commitment_refund_summary) { summary: commitment_refund_summary; }\n requires refs { field: concat(camel(parent_name), "Id"); statuses: [failed]; match: { "fields.[beneficiary]AccountId": concat("fields.", camel(beneficiary), "AccountId"); "fields.currency": "fields.currency"; }; }\n moves: [{ amount: amount; from: refs.escrowAccountId; to: payer; key: refund; }];\n steps: [];\n }\n }\n }\n }\n\n when(contribution_instrument) {\n let(contribution_id): get(contribution_instrument, "instrument");\n let(contribution_ref_field): get(contribution_instrument, "ref_field");\n let(contribution_amount_field): get(contribution_instrument, "amount_field");\n let(committed_status): get(contribution_instrument, "committed_status");\n let(collected_status): get(contribution_instrument, "collected_status");\n let(instrument_id_prefix): get(contribution_instrument, "id_prefix");\n let(active_parked): get(contribution_instrument, "active_parked");\n let(custody_ref): get(contribution_instrument, "custody_ref");\n let(beneficiary_account_description): get(contribution_instrument, "beneficiary_account_description");\n let(target_description): get(contribution_instrument, "target_description");\n let(currency_description): get(contribution_instrument, "currency_description");\n let(create_examples): get(contribution_instrument, "create_examples");\n let(activate_examples): get(contribution_instrument, "activate_examples");\n let(fail_examples): get(contribution_instrument, "fail_examples");\n let(close_examples): get(contribution_instrument, "close_examples");\n let(beneficiary_account_field): camel(beneficiary_account);\n let(target_field): camel(target);\n let(close_field): camel(close_by);\n\n fields {\n [beneficiary_account_field] { type: account<C>; description: beneficiary_account_description; pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; "x-hyperscale-reference-filter": { column: role; values: [customer_balance]; }; }\n [close_field] { type: date; }\n currency { type: text; description: currency_description; maxLength: 3; minLength: 3; pattern: "^[A-Z]{3}$"; }\n when(memo) { [memo] { type: text; optional: true; maxLength: 180; minLength: 1; } }\n [target_field] { type: money<C>; description: target_description; }\n }\n lifecycle {\n states open active failed settled;\n initial open;\n on activate: open -> active;\n on close: active -> settled;\n on fail: open -> failed;\n }\n parties { beneficiary: beneficiary_account_field; }\n required: [beneficiary_account_field, target_field, currency, close_field];\n aggregate_invariants { childField: contribution_amount_field; childInstrumentId: contribution_id; childRefField: contribution_ref_field; childStatuses: [committed_status, collected_status]; parentField: target_field; }\n caller_parked_states { active: active_parked; }\n id_prefix: instrument_id_prefix;\n action create {\n public: none;\n agent_description: "Open the pool before any contribution exists. The caller supplies the target, the currency, the beneficiary account, and the close anchor, and the pool provisions its escrow account. No money moves.";\n examples: create_examples;\n moves: [];\n steps: [{ operation: "account.escrow.provision"; bind: { currency: { from: instance; path: "fields.currency"; }; "owner.id": { from: instance; path: productId; }; "owner.type": { from: const; value: product; }; productId: { from: instance; path: productId; }; role: { from: const; value: product_escrow; }; }; capture: { [custody_ref]: accountId; }; }];\n }\n action activate {\n public: none;\n due { field: close_field; }\n examples: activate_examples;\n requires aggregate { instrumentId: contribution_id; over: children; refField: contribution_ref_field; statuses: [committed_status]; check: { kind: sum_at_least; amountField: contribution_amount_field; targetField: target_field; }; }\n moves: [];\n steps: [];\n }\n action fail {\n public: none;\n due { field: close_field; }\n examples: fail_examples;\n requires aggregate { instrumentId: contribution_id; over: children; refField: contribution_ref_field; statuses: [committed_status]; check: { kind: sum_below; amountField: contribution_amount_field; targetField: target_field; }; }\n moves: [];\n steps: [];\n }\n action close {\n public: none;\n agent_description: "Settle the pool once every contribution has been collected into the beneficiary account. No money moves. Refused while any contribution is still uncollected, so wait for the per-contribution collections to run rather than retrying.";\n examples: close_examples;\n requires aggregate { instrumentId: contribution_id; over: children; refField: contribution_ref_field; statuses: [collected_status]; check: { kind: all_in; }; }\n moves: [];\n steps: [];\n }\n }\n}\n',
82
+ ],
83
+ [
84
+ "settlements/weighted_distribution.hsx",
85
+ 'module std.settlements.weighted_distribution\n\nexport instrument weighted_distribution<C>(\n source: party,\n recipient: party,\n amount: money<C>,\n record_at: date,\n weight: optional<money<C>>,\n max_recipients: optional<integer>,\n snapshot: optional<condition>,\n rounding_policy: optional<text>,\n withholding_policy: optional<text>,\n correction_policy: optional<text>,\n flat: optional<block>,\n id_prefix_override: optional<text>,\n) {\n when_not(flat) {\n fields {\n currency { type: text; description: "ISO 4217 currency code"; minLength: 3; maxLength: 3; pattern: "^[A-Z]{3}$"; }\n amount { type: money<C>; description: "Distribution pool in {C} minor units"; }\n [source]AccountId { type: account<C>; description: concat("The ", words(source), " account"); pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; "x-hyperscale-reference-filter": { column: role; values: [customer_balance]; }; }\n maxRecipients { type: integer; description: concat("Exactly ", max_recipients, " frozen entitlement rows"); const: max_recipients; }\n record_at { type: date; description: "Stored record date"; }\n }\n lifecycle { states open snapshotted; initial open; on [snapshot]: open -> snapshotted; }\n parties { payer: concat(camel(source), "AccountId"); }\n required: [concat(camel(source), "AccountId"), currency, amount, record_at, maxRecipients];\n title: sentence(instrument);\n id_prefix: prefix(instrument);\n agent_description: "Reach for weighted distribution when one pool splits across many recipients by declared weights. Record one entitlement per recipient, freeze the set with the snapshot port, then each entitlement pays its own largest-remainder share, so the shares add back to the pool exactly. Settlement batch goes the other way, many charges into one payout.";\n summary: "Frozen largest-remainder distribution";\n description: "Evidence-frozen weighted distribution";\n aggregate_invariants { childInstrumentId: concat(instrument, "_entitlement"); childRefField: concat(camel(instrument), "Id"); childStatuses: [recorded, paid]; count: true; parentField: maxRecipients; }\n action create { agent_description: "Open a distribution and start recording entitlements. No money moves. The pool amount, the record date, and the exact recipient count are fixed here."; summary: "Open entitlement recording"; moves: []; steps: []; }\n action [snapshot] {\n agent_description: "Freeze the entitlement set against a stated evidence reference. The distribution must still be open and its recorded entitlements must match the declared recipient count. Nothing can be recorded afterwards and there is no unfreeze. No money moves.";\n summary: "Freeze the entitlement set from stored evidence";\n port { allowedParties: [payer]; }\n input { type: object; properties: { evidenceReference: { type: string; description: "Required decision reference retained in the operation receipt"; minLength: 1; maxLength: 180; }; }; required: [evidenceReference]; additionalProperties: false; }\n capture_input { snapshotEvidenceReference: evidenceReference; }\n moves: [];\n steps: [];\n }\n instruments {\n instrument {\n let(parent_name): instrument;\n id: concat(parent_name, "_entitlement");\n generatedPrefix: true;\n fields {\n currency { type: text; description: "ISO 4217 currency code"; minLength: 3; maxLength: 3; pattern: "^[A-Z]{3}$"; }\n [source]AccountId { type: account<C>; description: concat("The ", words(source), " account"); pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; "x-hyperscale-reference-filter": { column: role; values: [customer_balance]; }; }\n [weight] { type: money<C>; description: "Stored non-negative entitlement weight"; }\n [parent_name]Id { type: ref<parent_name>; description: concat("The exact ", parent_name); pattern: concat("^", prefix(parent_name), "_(sandbox|live)_[a-z0-9]{8,64}$"); }\n [recipient]AccountId { type: account<C>; description: concat("The ", words(recipient), " account"); pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; "x-hyperscale-reference-filter": { column: role; values: [customer_balance]; }; }\n }\n lifecycle { states recorded paid; initial recorded; on payout: recorded -> paid; }\n parties { beneficiary: concat(camel(recipient), "AccountId"); payer: concat(camel(source), "AccountId"); }\n required: [concat(camel(recipient), "AccountId"), concat(camel(source), "AccountId"), currency, concat(camel(parent_name), "Id"), weight];\n title: concat(sentence(parent_name), " Entitlement");\n agent_description: concat("One recipient weighted claim on ", parent_name, ". Record one per recipient before the snapshot. Its share is derived from its weight against the frozen set, never supplied by the caller.");\n summary: concat("Frozen entitlement in ", parent_name);\n description: concat("One frozen weighted entitlement in ", parent_name);\n action create {\n agent_description: "Record one recipient weight against an open distribution. The parent distribution must still be open, and the currency and source account are copied from it. No money moves. Do not supply a share. It is derived later from the frozen set.";\n summary: "Record one entitlement before snapshot";\n requires refs { field: concat(camel(parent_name), "Id"); statuses: [open]; bind: { currency: "fields.currency"; [source]AccountId: concat("fields.", camel(source), "AccountId"); }; }\n moves: [];\n steps: [];\n }\n action payout {\n agent_description: "Pay this recipient their largest-remainder share of the pool. The parent distribution must already be snapshotted. The amount is computed from the recorded weights, not supplied by the caller, and a zero share moves nothing. This moves money and does not reverse.";\n summary: "Pay the deterministic largest-remainder share once";\n requires refs { field: concat(camel(parent_name), "Id"); statuses: [snapshotted]; match: { "fields.currency": "fields.currency"; "fields.[source]AccountId": concat("fields.", camel(source), "AccountId"); }; }\n computes distribute { amountRef: payoutShare; onZero: skip_steps; pool: { from: parent; path: concat("fields.", amount); }; refField: concat(camel(parent_name), "Id"); statuses: [recorded, paid]; weightField: weight; }\n moves: [{ amount: refs.payoutShare; from: payer; to: beneficiary; key: payout; }];\n steps: [];\n }\n }\n }\n }\n when(flat) {\n let(pool): get(flat, "pool");\n let(pool_ref): get(pool, "field");\n let(pool_ref_field): camel(pool_ref);\n let(pool_instrument): get(pool, "instrument");\n let(pool_create_statuses): get(pool, "create_statuses");\n let(pool_payout_statuses): get(pool, "payout_statuses");\n let(pool_bind): get(pool, "bind");\n let(pool_match): get(pool, "match");\n let(pool_amount_path): get(pool, "amount_path");\n let(weight_source): get(flat, "weight_source");\n let(weight_ref): get(weight_source, "field");\n let(weight_ref_field): camel(weight_ref);\n let(weight_statuses): get(weight_source, "statuses");\n let(weight_bind): get(weight_source, "bind");\n let(weight_match): get(weight_source, "match");\n let(unique_weight_source): get(weight_source, "unique");\n let(group): get(flat, "group");\n let(group_ref): get(group, "field");\n let(source_account_field): camel(concat(source, "_account_id"));\n let(recipient_account_field): camel(concat(recipient, "_account_id"));\n fields {\n [amount] { type: money<C>; description: get(flat, "amount_description"); }\n [record_at] { type: date; }\n [pool_ref] { type: pool_ref; description: get(pool, "description"); pattern: get(pool, "pattern"); }\n currency { type: text; description: "ISO 4217 currency code"; minLength: 3; maxLength: 3; pattern: "^[A-Z]{3}$"; }\n [weight_ref] { type: weight_ref; description: get(weight_source, "description"); pattern: get(weight_source, "pattern"); }\n [group_ref] { type: group_ref; description: get(group, "description"); pattern: get(group, "pattern"); }\n [recipient]AccountId { type: account<C>; description: get(flat, "recipient_account_description"); pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; "x-hyperscale-reference-filter": { column: role; values: [customer_balance]; }; }\n [source]AccountId { type: account<C>; description: get(flat, "source_account_description"); pattern: "^acct_(sandbox|live)_[a-z0-9]{8,64}$"; "x-hyperscale-reference-filter": { column: role; values: [customer_balance]; }; }\n }\n lifecycle { states claimed paid; initial claimed; on payout: claimed -> paid; }\n parties { beneficiary: recipient_account_field; }\n required: get(flat, "required");\n title: sentence(instrument);\n id_prefix: if_eq(id_prefix_override, false, prefix(instrument), id_prefix_override);\n agent_description: concat("One weighted claim on a distribution pool that another instrument owns. Record one claim per recipient before the pool settles. Its share is derived from its weight against the settled pool, never supplied by the caller, and the shares add back to the pool exactly.");\n summary: "Flat largest-remainder distribution claim";\n description: "One weighted claim on a settled distribution pool";\n action create {\n public: none;\n agent_description: concat("Record one recipient weight against a pool that is still open. Both the pool and the weight source must be in an accepting state, and the same weight source cannot be claimed twice. No money moves. Do not supply a share. It is derived at payout from the settled pool.");\n summary: "Open one weighted distribution claim";\n requires_refs: [\n { field: pool_ref_field; statuses: pool_create_statuses; bind: pool_bind; match: pool_match; },\n { field: weight_ref_field; statuses: weight_statuses; bind: weight_bind; match: weight_match; unique: unique_weight_source; }\n ];\n moves: [];\n steps: [];\n }\n action payout {\n public: none;\n summary: "Pay one largest-remainder share from the settled pool";\n due { field: record_at; whenParentStatus: { instrumentId: pool_instrument; refField: pool_ref_field; statuses: pool_payout_statuses; }; }\n requires refs { field: pool_ref_field; statuses: pool_payout_statuses; }\n computes distribute { amountRef: payoutShare; onZero: skip_steps; pool: { from: parent; path: pool_amount_path; }; refField: pool_ref_field; statuses: [claimed, paid]; weightField: amount; }\n moves: [{ key: transfer; operation: internal_transfer.create; bind: { amount: { from: instance; path: refs.payoutShare; }; currency: { from: instance; path: fields.currency; }; destinationAccountId: { from: instance; path: concat("fields.", recipient_account_field); }; productId: { from: instance; path: productId; }; sourceAccountId: { from: instance; path: concat("fields.", source_account_field); }; }; capture: { payoutTransferId: transferId; }; }];\n steps: [];\n }\n }\n}\n',
86
+ ],
87
+ ]);
88
+ //# sourceMappingURL=std-bundle.js.map