@hyperscale0/hsx 1.0.125 → 1.0.130

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +2 -2
  2. package/dist/src/cli.js +1 -1
  3. package/dist/src/cli.js.map +1 -1
  4. package/dist/src/compile.d.ts.map +1 -1
  5. package/dist/src/compile.js +155 -21
  6. package/dist/src/compile.js.map +1 -1
  7. package/dist/src/examples-bundle.js +9 -9
  8. package/dist/src/examples-bundle.js.map +1 -1
  9. package/dist/src/headers.d.ts +1 -1
  10. package/dist/src/headers.d.ts.map +1 -1
  11. package/dist/src/headers.js +1 -0
  12. package/dist/src/headers.js.map +1 -1
  13. package/dist/src/parse.js +4 -1
  14. package/dist/src/parse.js.map +1 -1
  15. package/dist/src/std-bundle.d.ts.map +1 -1
  16. package/dist/src/std-bundle.js +8 -7
  17. package/dist/src/std-bundle.js.map +1 -1
  18. package/docs/README.md +102 -50
  19. package/examples/cards.hsx +4 -0
  20. package/examples/collections.hsx +5 -1
  21. package/examples/cost-table.json +80 -56
  22. package/examples/financing.hsx +1 -1
  23. package/examples/insurance.hsx +5 -4
  24. package/examples/lending.hsx +1 -1
  25. package/examples/library.hsx +1 -1
  26. package/examples/rental-deposit.hsx +1 -1
  27. package/examples/reporting.hsx +1 -1
  28. package/examples/serviced.hsx +1 -1
  29. package/package.json +4 -4
  30. package/src/cli.ts +1 -1
  31. package/src/compile.ts +223 -27
  32. package/src/examples-bundle.ts +9 -9
  33. package/src/headers.ts +1 -0
  34. package/src/parse.ts +4 -1
  35. package/src/std-bundle.ts +8 -7
  36. package/std/booking.hsx +75 -0
  37. package/std/cards.hsx +5 -3
  38. package/std/escrow.hsx +35 -9
  39. package/std/financing.hsx +158 -36
  40. package/std/insurance.hsx +9 -5
  41. package/std/marketplace.hsx +3 -3
  42. package/std/money.hsx +3 -3
  43. package/std/wallet.hsx +20 -9
@@ -1 +1 @@
1
- {"version":3,"file":"std-bundle.js","sourceRoot":"","sources":["../../src/std-bundle.ts"],"names":[],"mappings":"AAAA,oEAAoE;AAEpE,MAAM,CAAC,MAAM,iBAAiB,GAAgC,IAAI,GAAG,CAAiB;IACpF,CAAC,WAAW,EAAE,2oKAA2oK,CAAC;IAC1pK,CAAC,iBAAiB,EAAE,2sNAA2sN,CAAC;IAChuN,CAAC,YAAY,EAAE,+qHAA+qH,CAAC;IAC/rH,CAAC,eAAe,EAAE,6m+DAA6m+D,CAAC;IACho+D,CAAC,eAAe,EAAE,01KAA01K,CAAC;IAC72K,CAAC,aAAa,EAAE,qwTAAqwT,CAAC;IACtxT,CAAC,iBAAiB,EAAE,woTAAwoT,CAAC;IAC7pT,CAAC,WAAW,EAAE,u1VAAu1V,CAAC;IACt2V,CAAC,eAAe,EAAE,+q2BAA+q2B,CAAC;IACls2B,CAAC,aAAa,EAAE,85JAA85J,CAAC;IAC/6J,CAAC,YAAY,EAAE,2jGAA2jG,CAAC;CAC5kG,CAAC,CAAC"}
1
+ {"version":3,"file":"std-bundle.js","sourceRoot":"","sources":["../../src/std-bundle.ts"],"names":[],"mappings":"AAAA,oEAAoE;AAEpE,MAAM,CAAC,MAAM,iBAAiB,GAAgC,IAAI,GAAG,CAAiB;IACpF,CAAC,aAAa,EAAE,soLAAsoL,CAAC;IACvpL,CAAC,WAAW,EAAE,63KAA63K,CAAC;IAC54K,CAAC,iBAAiB,EAAE,2sNAA2sN,CAAC;IAChuN,CAAC,YAAY,EAAE,60LAA60L,CAAC;IAC71L,CAAC,eAAe,EAAE,8v2EAA8v2E,CAAC;IACjx2E,CAAC,eAAe,EAAE,uxLAAuxL,CAAC;IAC1yL,CAAC,aAAa,EAAE,qwTAAqwT,CAAC;IACtxT,CAAC,iBAAiB,EAAE,mpTAAmpT,CAAC;IACxqT,CAAC,WAAW,EAAE,+1VAA+1V,CAAC;IAC92V,CAAC,eAAe,EAAE,+q2BAA+q2B,CAAC;IACls2B,CAAC,aAAa,EAAE,85JAA85J,CAAC;IAC/6J,CAAC,YAAY,EAAE,s2HAAs2H,CAAC;CACv3H,CAAC,CAAC"}
package/docs/README.md CHANGED
@@ -82,11 +82,16 @@ the executor's current time when the action runs, not a caller-supplied return d
82
82
  A late `due` permits the operator action; it does not schedule that action.
83
83
 
84
84
  This sample binds a declared business named `renter` in Product configuration.
85
- It uses fixed parties because this compiler rejects parameterized instruments
86
- inside a program. Changing the renter binding is a Build configuration decision,
87
- not a different party ID on each request. Use header party parameters bound to
88
- `owner` or `actor` for per-object participants. Reusable custom headers require a
89
- host-supplied `StandardLibrary`; `use` cannot load a local file through this CLI.
85
+ The renter is one business for the whole Build, so the instrument takes no
86
+ parameters. Changing the renter binding is a Build configuration decision, not a
87
+ different party ID on each request. For per-object participants, give a program
88
+ instrument parameters as a header would, such as `instrument purse(holder: party)`,
89
+ and bind `holder: owner` or `holder: actor` in each `attach` block. A
90
+ parameterized program instrument exists only through its attachments. A `fee` on
91
+ a move of an action input, such as `moves input.amount from holder to self.held
92
+ fee { seller: 1% }`, is calculated when that action runs. Reusable custom headers
93
+ require a host-supplied `StandardLibrary`; `use` cannot load a local file through
94
+ this CLI.
90
95
 
91
96
  Inspect `objects` in the compiled UDL for the attachment and public names, then
92
97
  its instrument for fields, transitions, actors, requirements and ordered moves.
@@ -104,11 +109,19 @@ executor. Compilation cannot establish balances, permissions or provider readine
104
109
 
105
110
  Every attached party parameter binds to `owner`, `actor`, `operator`, a declared
106
111
  business, or a declared staff party with a supported role. Configure declared
107
- business participants per Build. Declared person parties cannot bind attachments.
112
+ business participants per Build. The host binds a declared business to an
113
+ organization customer of this company, and that business must be a customer with
114
+ an account before the Build that binds it is saved. It also needs an open balance
115
+ account in this Product before it takes part in a payment. Declared person
116
+ parties cannot bind attachments.
108
117
  `owner` is the object's resolved customer or business, `actor` is the authenticated
109
- caller, and `operator` is the program operator. A parameter with one of these
110
- names binds by name. Other party parameters use a same-named eligible declaration,
111
- a header default, or an explicit binding. Explicit bindings take precedence.
118
+ caller, or the customer a Product key or member names in `onBehalfOf`, and
119
+ `operator` is the program operator. `programOperator`, the default
120
+ of many std party parameters, is the same company: it resolves to the Product's
121
+ own company, and a Build binding for it is ignored. A parameter with one of these
122
+ names binds by name. Other required party parameters use a same-named eligible
123
+ declaration, a header default, or an explicit binding. An optional party parameter
124
+ stays unset unless the attachment binds it. Explicit bindings take precedence.
112
125
  Unbound parameters report `subject_party_unbound`. These bindings are frozen in
113
126
  UDL `objects[].attachments[].parties`; no caller supplies party IDs at creation.
114
127
 
@@ -119,7 +132,10 @@ compiler freezes the adapter identity, digest and requirements. An unavailable
119
132
  declaration leaves a null snapshot in compiled output. Product creation and
120
133
  recomposition reject unresolved or changed declarations during Build admission.
121
134
  Execution checks the frozen declaration too; later adapter unavailability can
122
- block actions on an already saved Build.
135
+ block actions on an already saved Build. A boundary adapter, such
136
+ as `conformance_boundary`, only binds its accounts and needs no evidence. Any
137
+ other adapter also needs a matching `requires evidence` rule on the action, or
138
+ preview and execution refuse with `subject_adapter_unbound`.
123
139
 
124
140
  An attachment can use `rename { price: salePrice }` to separate requirements with
125
141
  different meanings. Matching names must match types and constraints. The compiler
@@ -156,6 +172,8 @@ decimal places and percentages at most two. The compiler uses integer minor unit
156
172
  and basis points. Fee and tax calculations round down. Split percentages sum to
157
173
  100%; the last declared recipient receives the rounding remainder. Finite
158
174
  schedules use positions 1 through n and put the division remainder in position 1.
175
+ Amortizing financing is the exception: it rounds half up and puts the remainder in
176
+ the last instalment, as a standard amortization table does.
159
177
  Tax binds `programTax`. Fees default to `programOperator`. Fine, recovery and
160
178
  residual destinations are party tunables.
161
179
 
@@ -233,6 +251,13 @@ a literal. `requires unique "order" on [self.order]` fixes an identity namespace
233
251
  `requires count of { instrument: child, reference: "parent", anchor: self.id,
234
252
  states: [pending], limit: 12 } == 12` checks a typed selection; `sum "amount" of`
235
253
  uses the same selection syntax. `invariants` accepts these requirement expressions.
254
+ The reference is a `ref` field or a party account; `reference: "traveller",
255
+ anchor: self.traveller` selects every record of the same traveller. `overlaps:
256
+ { start: departure, end: returning, from: { field: self.departure }, until: {
257
+ field: self.returning } }` keeps rows whose own `[departure, returning)` period
258
+ meets the range, so a stay ending on the 8th and one starting on the 8th do not
259
+ overlap. `count of { instrument: current(), ..., overlaps: ... } <= 1` stops one
260
+ traveller holding two trips on the same dates.
236
261
  `requires hours self.now between 8 and 20 timezone "Asia/Riyadh"` checks local hours.
237
262
  `requires evidence self.payer family registry check ownership result verified
238
263
  maxAge 1d` requires a recent completed provider check.
@@ -261,20 +286,30 @@ and a correction. No artifact is returned with diagnostics.
261
286
 
262
287
  ## Financing policies
263
288
 
264
- `financing.installments` keeps principal and fixed flat profit as claims from
265
- activation. The company chooses where funding goes and when profit becomes earned.
266
- All choices use accounts, calculations and moves in the same two books.
267
-
268
- | Tunable | Default | Selected behavior |
269
- | ---------------------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
270
- | `disburse_to` | `funds` | `funds` pays down payment and principal into the hold and confirms it. `borrower` credits principal to the borrower's balance. |
271
- | `profit_earned` | `on_payment` | `on_payment` collects unearned profit on payment. `by_schedule` moves unearned claims to earned claims at each slice's date. `at_disbursement` makes that move at activation. Cash arrives only on payment. |
272
- | `apply` | `fines_profit_principal` | Visit each slice in position order; within that slice collect assessed fines by overdue date, evidenced costs, profit, then principal. `principal_profit` collects each slice in position order, principal before profit. `pro_rata` uses the slice's fixed principal:profit ratio, caps each side by its collectible balance, and assigns the remainder without stranding cash. |
273
- | `payoff_rebate` | `100%` | Reverse this share of unearned profit to borrower debt. Collect the remainder and all earned profit with outstanding principal. |
274
- | `late_charge.fines_to` | `programOperator` | Receive fine cash and fund its refunds. |
275
- | `late_charge.costs_to` | `programOperator` | Receive evidenced recovery cash and fund its refunds. |
276
- | `collections.case.fee` | `20%` | After payment succeeds, transfer this share of the payment amount from plan capital to the agency. |
277
- | `lending.distribution.residual_to` | `programOperator` | Receive the cash remainder and own the claim loss remainder after weighted distribution. |
289
+ `financing.installments` keeps principal and fixed profit as claims from
290
+ activation. The company chooses how profit is priced, where funding goes and when
291
+ profit becomes earned. All choices use accounts, calculations and moves in the same
292
+ two books.
293
+
294
+ `pricing` has no default, so every plan states it. `amortizing` reads
295
+ `profit_rate` as an annual rate on the declining balance: equal monthly
296
+ instalments from standard annuity maths, interest and instalment rounded half up,
297
+ the last instalment absorbing the rounding. 12,000 SAR at 18% over 12 months is
298
+ 11 instalments of 1,100.16 SAR and a last one of 1,100.19 SAR, 13,201.95 SAR in
299
+ total. `flat_total` reads `profit_rate` as one charge on principal for the whole
300
+ term, rounded down and split evenly with the remainder in position 1: murabaha and
301
+ fixed-fee pay-later. The same 12,000 SAR at 18% `flat_total` costs 14,160 SAR.
302
+
303
+ | Tunable | Default | Selected behavior |
304
+ | ---------------------------------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
305
+ | `disburse_to` | `funds` | `funds` pays down payment and principal into the hold and confirms it. `borrower` credits principal to the borrower's balance. `seller` pays principal to the `seller` party at activation; after capital refunds every paid payment, capital's `unwind` debits it back from the seller and cancels open slices. |
306
+ | `profit_earned` | `on_payment` | `on_payment` collects unearned profit on payment. `by_schedule` moves unearned claims to earned claims at each slice's date. `at_disbursement` makes that move at activation. Cash arrives only on payment. |
307
+ | `apply` | `fines_profit_principal` | Visit each slice in position order; within that slice collect assessed fines by overdue date, evidenced costs, profit, then principal. `principal_profit` collects each slice in position order, principal before profit. `pro_rata` uses the slice's fixed principal:profit ratio (its own principal and profit under `amortizing`), caps each side by its collectible balance, and assigns the remainder without stranding cash. |
308
+ | `payoff_rebate` | `100%` | Reverse this share of unearned profit to borrower debt. Collect the remainder and all earned profit with outstanding principal. |
309
+ | `late_charge.fines_to` | `programOperator` | Receive fine cash and fund its refunds. |
310
+ | `late_charge.costs_to` | `programOperator` | Receive evidenced recovery cash and fund its refunds. |
311
+ | `collections.case.fee` | `20%` | After payment succeeds, transfer this share of the payment amount from plan capital to the agency. |
312
+ | `lending.distribution.residual_to` | `programOperator` | Receive the cash remainder and own the claim loss remainder after weighted distribution. |
278
313
 
279
314
  Each slice owns separate unearned and earned claim accounts. Scheduled recognition
280
315
  uses a dated child record so a partial payment cannot disable the maturity clock.
@@ -362,9 +397,9 @@ The compiler API is `compile(source)`. On success, `result.verdict` is `valid`
362
397
  and `result.artifacts` contains `document`, `costManifest` and `originMap`.
363
398
  On refusal, inspect `result.diagnostics`; no artifact is returned.
364
399
 
365
- `hsx headers` prints the instrument inventory from the declarations. The
400
+ `hsx headers --json` prints the instrument inventory from the declarations. The
366
401
  [object example](../examples/library.hsx) shows authenticated role bindings.
367
- The [playground](../playground/index.html) compiles locally in the browser.
402
+ The [playground](https://hyperscale0.ai/playground/) compiles locally in the browser.
368
403
 
369
404
  ## Standard-library behavior
370
405
 
@@ -372,24 +407,30 @@ Read the instrument's states, time gates and moves before promising a money
372
407
  outcome. A compiler pass does not prove that required actions are exposed,
373
408
  adapters are bound, participants have funds, or the flow can finish.
374
409
 
375
- | Instrument | Behavior |
376
- | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
377
- | `financing.installments` | `share` allocates collected profit to a cash payable owned by `capital`. It does not itself pay operator income. |
378
- | `financing.limits` | `per_borrower` caps outstanding principal. Both borrower and portfolio limits must be approved before disbursement; attaching them does not approve them. |
379
- | `lending.round` | The target is the linked plan's principal. Closing requires commitments and held funds to equal that amount. |
380
- | `lending.distribution` | Cash distribution needs an eligible recorded settlement, `prepare_cash`, one share record per funded commitment, then `distribute_cash`. Attaching it moves nothing. |
381
- | `insurance.cover.slice` | `collect` credits premium net of commission to the insurer account. The tenant retains commission. `refund` returns both portions; claims reserve insurer funds. External settlement uses the boundary protocol. |
382
- | `financing.installments`, `savings.circle` | Supply explicit date lists when creating agreements. A term count does not generate a monthly calendar. Savings supports at most 60 distinct member seats. |
383
- | `escrow.hold` | `fund` takes the whole price. Financing into pending escrow collects the remaining down payment and adds capital principal at disbursement; `fund` is not a down-payment checkout. |
384
- | `escrow.hold` | Acceptance timeout enters `disputed` without paying the seller. Delivery and return verification belong to `payee`; rebinding it also changes who receives accepted funds. |
385
- | `financing.late_charge` | `fine` is a fixed money amount, not a percentage of overdue principal. |
386
- | `cards.card` | `spend_limit` is a per-authorization ceiling, not a monthly aggregate. |
410
+ | Instrument | Behavior |
411
+ | ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
412
+ | `financing.installments` | `share` allocates collected profit to a cash payable owned by `capital`. It does not itself pay operator income. |
413
+ | `financing.limits` | `per_borrower` caps outstanding principal. Both borrower and portfolio limits must be approved before disbursement; attaching them does not approve them. |
414
+ | `lending.round` | The target is the linked plan's principal. Closing requires commitments and held funds to equal that amount. |
415
+ | `lending.distribution` | Cash distribution needs an eligible recorded settlement, `prepare_cash`, one share record per funded commitment, then `distribute_cash`. Attaching it moves nothing. |
416
+ | `insurance.cover.slice` | `collect` credits premium net of commission to the insurer account. The tenant retains commission. `refund` returns both portions; claims reserve insurer funds. External settlement uses the boundary protocol. |
417
+ | `financing.installments`, `savings.circle` | Supply explicit date lists when creating agreements. A term count does not generate a monthly calendar. Savings supports at most 60 distinct member seats. |
418
+ | `escrow.hold` | `fund` takes the whole price. Financing into pending escrow collects the remaining down payment and adds capital principal at disbursement; `fund` is not a down-payment checkout. |
419
+ | `escrow.hold` | Acceptance timeout enters `disputed` without paying the seller. Delivery and return verification belong to `payee`; rebinding it also changes who receives accepted funds. |
420
+ | `escrow.hold` | `deliver_within` (default `14d`) starts at funding. After it passes without delivery, an exposed `refund_undelivered` lets the payer take the whole held price back. Nothing runs it automatically. |
421
+ | `wallet.balance` | `topup_fee` (default `0%`) takes a floored percentage of each top-up for the Company. At `1%`, a 100.00 top-up credits 99.00 and earns 1.00. |
422
+ | `booking.reservation` | The balance is payable only from `deposit_paid`, so a cancelled booking never takes it. `middle_forfeit` and `late_forfeit` default to `0%`, so every cancellation returns all held money until the author sets them. At departure the clock completes a paid booking and lapses an unpaid one on `late_forfeit`. |
423
+ | `financing.late_charge` | `fine` is a fixed money amount, not a percentage of overdue principal. |
424
+ | `cards.card` | `spend_limit` is a per-authorization ceiling, not a monthly aggregate. |
387
425
 
388
426
  A seller-owned marketplace object can declare `entryActions: [create_order]`
389
427
  when `create_order` exposes an attachment's create action with its buyer bound
390
428
  to `actor`. This admits active enrolled customers to that action. The default
391
429
  is closed. A retained buyer can read the record and run its buyer actions;
392
430
  the seller remains owner. Entry never grants access to an existing escrow.
431
+ Without entry actions, the company runs a two-customer sale from its Product
432
+ key: create the record with `onBehalfOf` naming the seller, then run the buyer's
433
+ steps with `onBehalfOf` naming the buyer.
393
434
 
394
435
  `financing.limits` and `financing.portfolio_limit` declare `scope: product`.
395
436
  Create and approve the portfolio limit once per Product and the borrower limit
@@ -441,8 +482,9 @@ has no checkout collection action. The plan and escrow must agree on payer and
441
482
  price.
442
483
 
443
484
  Expose escrow `cancel` to return money credited before full funding. Plan `void`
444
- cancels the signed financing agreement but does not cancel its escrow. After
445
- funding and delivery, the default return path needs three separate aliases for
485
+ cancels the signed financing agreement but does not cancel its escrow. Between
486
+ funding and delivery, the payee's `refund` returns the full price. After
487
+ delivery, the default return path needs three separate aliases for
446
488
  `dispute`, `verify_return` and `refund`. The payee supplies return evidence and
447
489
  returns the full price to the payer. `accept` pays the payee instead.
448
490
  Marketplace order fulfillment alone does not execute any of these money actions.
@@ -456,15 +498,26 @@ cost assessment is a separate record.
456
498
 
457
499
  Bind `insurance.cover.broker` to the agency that receives commission. Collection
458
500
  pays the insurer's net premium and the broker's commission as two moves. Refunds
459
- reverse those same portions. The default broker is the program operator.
501
+ reverse those same portions. The default broker, `programOperator`, is the
502
+ Product's own company and needs no binding.
460
503
  `claim.deny` accepts only `submitted`; after approval, `pay` or expiry consumes
461
- the reservation.
504
+ the reservation. `claim_limit` is the sum insured, supplied per cover at creation:
505
+ approved and paid claims on one cover never total more. `adapter` names a
506
+ registered boundary adapter, `conformance_boundary` in sandbox. `covers` is
507
+ optional; the attached object is already the insured thing.
462
508
 
463
509
  A booking cancellation refunds only its own held cash. Expose `cover.cancel`
464
510
  separately for eligible premium refunds before the paid period starts. Active
465
511
  and expired premium periods are excluded. A card transaction needs a captured
466
512
  authorization and its own record before refund, but no authorization-expiry wait.
467
513
 
514
+ A booking runs two clock actions at departure. `complete` takes a `paid`
515
+ booking and pays the held money to `operator`. `lapse` takes a booking still
516
+ `reserved` or `deposit_paid` to `cancelled`: `operator` keeps `late_forfeit` of
517
+ the held money and the customer gets the rest back. An unpaid balance at
518
+ departure therefore costs the customer the same as `cancel_late`, and with the
519
+ default `0%` it costs nothing. Nothing stays held after departure.
520
+
468
521
  A savings membership becomes `received` after its pot payout. Its contribution
469
522
  records become `paid` independently. Future contributions can remain pending
470
523
  after the member receives the pot; paying a contribution does not advance their
@@ -497,8 +550,9 @@ instruments stay generic. New Builds carry the purpose; existing agreements
497
550
  and postings keep their retained Build and classification.
498
551
 
499
552
  Held customer funding and its unspent return are `principal`. A release for the
500
- company's sale is `earning`. A payment from company cash to another participant
501
- is `participant_payout`. Claims, waivers, write-offs and own-account allocations
553
+ company's sale is `earning`; its release to another participant is
554
+ `pass_through`, because the company never owned it. A payment from company cash
555
+ to another participant is `participant_payout`. Claims, waivers, write-offs and own-account allocations
502
556
  are `internal`; prepaid balance topups and returns are `prepaid_credit`. Tax is
503
557
  `pass_through`, excluded from earnings and costs. Unpaid claims count as neither.
504
558
  Refunds of paid profit, company charges and commission capture the original
@@ -511,16 +565,14 @@ product fees. Automatic platform fees keep their commercial classification.
511
565
 
512
566
  A move's economics block can select by a resolved party: `economics { recipient:
513
567
  recipient, company: { purpose: earning, sourceParty: payer }, participant:
514
- { purpose: participant_payout, sourceParty: programOperator } }`. The compiler
568
+ { purpose: pass_through, sourceParty: programOperator } }`. The compiler
515
569
  chooses `company` for `operator`, `programOperator`, or a declared party with the
516
570
  `program_operator` role; it chooses `participant` for other bound parties.
517
571
  Both branches must be supplied. A branch may be `unclassified` when no purpose
518
572
  is established. Outside financing-profit and recovery recipients refund directly
519
- to the customer, not the company that funded the payout; those refund branches
520
- remain unclassified because they cannot reverse that company payout. Std
521
- recovery charges use this rule to avoid counting company receipts as participant
522
- costs. Direct customer payments to
523
- outside recipients are pass-through; payments from held company cash are costs.
573
+ to the customer; those refund branches remain unclassified. Customer cash paid to
574
+ outside recipients is pass-through, whether paid direct or released from a hold
575
+ the customer funded as principal. Only company-owned cash paid out is a cost.
524
576
 
525
577
  Generic transfers and mixed principal/profit distributions remain unclassified
526
578
  when their structure does not establish a purpose. Adapter-owned premium and
@@ -1,6 +1,10 @@
1
1
  // A company issues expense cards to employees and reserves each supplier payment before capture.
2
2
  program team_expense_cards "Team expense cards"
3
3
  use cards
4
+ // supplier is a business this program declares, so plan needs {"partyBindings":{"supplier":"<partyId>"}}.
5
+ // That partyId is an organization customer's: create the Product from this source without the payment
6
+ // and receipt attachments, add the customer with customer.create, activate its access, open its
7
+ // customer_balance account, then compose this source with the binding.
4
8
  party supplier: business
5
9
 
6
10
  object employee "Employee card" {
@@ -2,6 +2,10 @@
2
2
  program business_collections "Small business collections"
3
3
  use collections
4
4
  use financing
5
+ // agency is a business this program declares, so plan needs {"partyBindings":{"agency":"<partyId>"}}.
6
+ // That partyId is an organization customer's: create the Product from this source without the recovery
7
+ // and contact attachments, add the customer with customer.create, activate its access, open its
8
+ // customer_balance account, then compose this source with the binding.
5
9
  party agency: business
6
10
 
7
11
  object facility "Business loan" {
@@ -12,7 +16,7 @@ object facility "Business loan" {
12
16
  attach loan = financing.installments {
13
17
  expose create as create_loan
14
18
  borrower: owner, capital: operator
15
- months: 12, profit: 6%, disburse_to: borrower
19
+ months: 12, pricing: amortizing, profit_rate: 6%, disburse_to: borrower
16
20
  limits: allowance, portfolio: budget
17
21
  expose sign as sign_loan
18
22
  expose disburse as release_loan
@@ -4,15 +4,14 @@
4
4
  "declaredMeters": [
5
5
  "account.active_month",
6
6
  "instrument.event.count",
7
- "transfer.internal.count",
8
- "transfer.internal.volume_sar"
7
+ "transfer.internal.count"
9
8
  ],
10
- "effectiveTableDigest": "2d53121d200de2cb7567113ebf5bc0ce9377e7089fd4697f4b694bd557e32063",
9
+ "effectiveTableDigest": "e58f5c33766a44254880f328f1f9fb886b63d510bf3dfa0f9fb529a0638d74c6",
11
10
  "fixed": {
12
11
  "activationBaseMinor": "500000",
13
- "activationPerPointMinor": "100000",
12
+ "activationPerPointMinor": "10000",
14
13
  "monthlyBaseMinor": "100000",
15
- "monthlyPerPointMinor": "20000",
14
+ "monthlyPerPointMinor": "2000",
16
15
  "weights": {
17
16
  "aggregate_invariant": 2,
18
17
  "flow": 1,
@@ -69,7 +68,7 @@
69
68
  "bps": 0,
70
69
  "meter": "account.active_month",
71
70
  "payer": "product",
72
- "perEventMinor": "27500",
71
+ "perEventMinor": "500",
73
72
  "settlement": "invoice",
74
73
  "signature": "meters.account.active_month"
75
74
  },
@@ -77,18 +76,25 @@
77
76
  "bps": 0,
78
77
  "meter": "instrument.event.count",
79
78
  "payer": "product",
80
- "perEventMinor": "150",
79
+ "perEventMinor": "25",
81
80
  "settlement": "invoice",
82
81
  "signature": "meters.instrument.event.count"
83
82
  },
84
83
  {
85
- "bps": 6,
84
+ "bps": 0,
86
85
  "meter": "transfer.internal.count",
87
- "payer": "end_customer",
88
- "perEventMinor": "75",
89
- "settlement": "per_event",
90
- "signature": "moves.transfer.internal",
91
- "volumeMeter": "transfer.internal.volume_sar"
86
+ "payer": "product",
87
+ "perEventMinor": "25",
88
+ "settlement": "invoice",
89
+ "signature": "meters.transfer.internal.count"
90
+ },
91
+ {
92
+ "bps": 0,
93
+ "meter": "instrument.event.count",
94
+ "payer": "product",
95
+ "perEventMinor": "0",
96
+ "settlement": "invoice",
97
+ "signature": "moves.transfer.internal"
92
98
  },
93
99
  {
94
100
  "bps": 0,
@@ -155,22 +161,21 @@
155
161
  "signature": "unwinds.void"
156
162
  }
157
163
  ],
158
- "version": "2026-09-02.1"
164
+ "version": "2026-09-27.1"
159
165
  },
160
166
  {
161
167
  "currency": "USD",
162
168
  "declaredMeters": [
163
169
  "account.active_month",
164
170
  "instrument.event.count",
165
- "transfer.internal.count",
166
- "transfer.internal.volume_usd"
171
+ "transfer.internal.count"
167
172
  ],
168
- "effectiveTableDigest": "44fa81226359fcafa8bd66b70c2311ee999c9bae66ff59c85ccb14d7d68126a9",
173
+ "effectiveTableDigest": "f2845819ad077745ed5d0af924b33f34210b20da703522e78aa2629d9be5040e",
169
174
  "fixed": {
170
175
  "activationBaseMinor": "133300",
171
- "activationPerPointMinor": "26700",
176
+ "activationPerPointMinor": "2700",
172
177
  "monthlyBaseMinor": "26700",
173
- "monthlyPerPointMinor": "5300",
178
+ "monthlyPerPointMinor": "500",
174
179
  "weights": {
175
180
  "aggregate_invariant": 2,
176
181
  "flow": 1,
@@ -227,7 +232,7 @@
227
232
  "bps": 0,
228
233
  "meter": "account.active_month",
229
234
  "payer": "product",
230
- "perEventMinor": "7333",
235
+ "perEventMinor": "133",
231
236
  "settlement": "invoice",
232
237
  "signature": "meters.account.active_month"
233
238
  },
@@ -235,18 +240,25 @@
235
240
  "bps": 0,
236
241
  "meter": "instrument.event.count",
237
242
  "payer": "product",
238
- "perEventMinor": "40",
243
+ "perEventMinor": "7",
239
244
  "settlement": "invoice",
240
245
  "signature": "meters.instrument.event.count"
241
246
  },
242
247
  {
243
- "bps": 6,
248
+ "bps": 0,
244
249
  "meter": "transfer.internal.count",
245
- "payer": "end_customer",
246
- "perEventMinor": "20",
247
- "settlement": "per_event",
248
- "signature": "moves.transfer.internal",
249
- "volumeMeter": "transfer.internal.volume_usd"
250
+ "payer": "product",
251
+ "perEventMinor": "7",
252
+ "settlement": "invoice",
253
+ "signature": "meters.transfer.internal.count"
254
+ },
255
+ {
256
+ "bps": 0,
257
+ "meter": "instrument.event.count",
258
+ "payer": "product",
259
+ "perEventMinor": "0",
260
+ "settlement": "invoice",
261
+ "signature": "moves.transfer.internal"
250
262
  },
251
263
  {
252
264
  "bps": 0,
@@ -313,22 +325,21 @@
313
325
  "signature": "unwinds.void"
314
326
  }
315
327
  ],
316
- "version": "2026-09-02.1"
328
+ "version": "2026-09-27.1"
317
329
  },
318
330
  {
319
331
  "currency": "EUR",
320
332
  "declaredMeters": [
321
333
  "account.active_month",
322
334
  "instrument.event.count",
323
- "transfer.internal.count",
324
- "transfer.internal.volume_eur"
335
+ "transfer.internal.count"
325
336
  ],
326
- "effectiveTableDigest": "613d900e38f98a6bf3934e7940ff4d06c76f1dddc695c79ee3b5ee1ad45b8636",
337
+ "effectiveTableDigest": "f741132e1aa38a860d855a83f20f12c0ec8a7ec5379117c407799e2012e63335",
327
338
  "fixed": {
328
339
  "activationBaseMinor": "125000",
329
- "activationPerPointMinor": "25000",
340
+ "activationPerPointMinor": "2500",
330
341
  "monthlyBaseMinor": "25000",
331
- "monthlyPerPointMinor": "5000",
342
+ "monthlyPerPointMinor": "500",
332
343
  "weights": {
333
344
  "aggregate_invariant": 2,
334
345
  "flow": 1,
@@ -385,7 +396,7 @@
385
396
  "bps": 0,
386
397
  "meter": "account.active_month",
387
398
  "payer": "product",
388
- "perEventMinor": "6875",
399
+ "perEventMinor": "125",
389
400
  "settlement": "invoice",
390
401
  "signature": "meters.account.active_month"
391
402
  },
@@ -393,18 +404,25 @@
393
404
  "bps": 0,
394
405
  "meter": "instrument.event.count",
395
406
  "payer": "product",
396
- "perEventMinor": "38",
407
+ "perEventMinor": "6",
397
408
  "settlement": "invoice",
398
409
  "signature": "meters.instrument.event.count"
399
410
  },
400
411
  {
401
- "bps": 6,
412
+ "bps": 0,
402
413
  "meter": "transfer.internal.count",
403
- "payer": "end_customer",
404
- "perEventMinor": "19",
405
- "settlement": "per_event",
406
- "signature": "moves.transfer.internal",
407
- "volumeMeter": "transfer.internal.volume_eur"
414
+ "payer": "product",
415
+ "perEventMinor": "6",
416
+ "settlement": "invoice",
417
+ "signature": "meters.transfer.internal.count"
418
+ },
419
+ {
420
+ "bps": 0,
421
+ "meter": "instrument.event.count",
422
+ "payer": "product",
423
+ "perEventMinor": "0",
424
+ "settlement": "invoice",
425
+ "signature": "moves.transfer.internal"
408
426
  },
409
427
  {
410
428
  "bps": 0,
@@ -471,22 +489,21 @@
471
489
  "signature": "unwinds.void"
472
490
  }
473
491
  ],
474
- "version": "2026-09-02.1"
492
+ "version": "2026-09-27.1"
475
493
  },
476
494
  {
477
495
  "currency": "GBP",
478
496
  "declaredMeters": [
479
497
  "account.active_month",
480
498
  "instrument.event.count",
481
- "transfer.internal.count",
482
- "transfer.internal.volume_gbp"
499
+ "transfer.internal.count"
483
500
  ],
484
- "effectiveTableDigest": "11ff399b5078ba8ba544a518d5483fced9da63da9c7b1cc2124fea1f17a5b01c",
501
+ "effectiveTableDigest": "12ed3fa44010e80ae20c114d7dd94f277686225c040576a8bb96d12a0fe5333a",
485
502
  "fixed": {
486
503
  "activationBaseMinor": "104200",
487
- "activationPerPointMinor": "20800",
504
+ "activationPerPointMinor": "2100",
488
505
  "monthlyBaseMinor": "20800",
489
- "monthlyPerPointMinor": "4200",
506
+ "monthlyPerPointMinor": "400",
490
507
  "weights": {
491
508
  "aggregate_invariant": 2,
492
509
  "flow": 1,
@@ -543,7 +560,7 @@
543
560
  "bps": 0,
544
561
  "meter": "account.active_month",
545
562
  "payer": "product",
546
- "perEventMinor": "5729",
563
+ "perEventMinor": "104",
547
564
  "settlement": "invoice",
548
565
  "signature": "meters.account.active_month"
549
566
  },
@@ -551,18 +568,25 @@
551
568
  "bps": 0,
552
569
  "meter": "instrument.event.count",
553
570
  "payer": "product",
554
- "perEventMinor": "31",
571
+ "perEventMinor": "5",
555
572
  "settlement": "invoice",
556
573
  "signature": "meters.instrument.event.count"
557
574
  },
558
575
  {
559
- "bps": 6,
576
+ "bps": 0,
560
577
  "meter": "transfer.internal.count",
561
- "payer": "end_customer",
562
- "perEventMinor": "16",
563
- "settlement": "per_event",
564
- "signature": "moves.transfer.internal",
565
- "volumeMeter": "transfer.internal.volume_gbp"
578
+ "payer": "product",
579
+ "perEventMinor": "5",
580
+ "settlement": "invoice",
581
+ "signature": "meters.transfer.internal.count"
582
+ },
583
+ {
584
+ "bps": 0,
585
+ "meter": "instrument.event.count",
586
+ "payer": "product",
587
+ "perEventMinor": "0",
588
+ "settlement": "invoice",
589
+ "signature": "moves.transfer.internal"
566
590
  },
567
591
  {
568
592
  "bps": 0,
@@ -629,6 +653,6 @@
629
653
  "signature": "unwinds.void"
630
654
  }
631
655
  ],
632
- "version": "2026-09-02.1"
656
+ "version": "2026-09-27.1"
633
657
  }
634
658
  ]
@@ -18,7 +18,7 @@ object enrolment "Enrolment" {
18
18
  attach tuition = financing.installments {
19
19
  expose create as create_tuition
20
20
  borrower: owner, capital: operator
21
- months: 3, profit: 0%, disburse_to: borrower
21
+ months: 3, pricing: flat_total, profit_rate: 0%, disburse_to: borrower
22
22
  limits: allowance, portfolio: budget
23
23
  expose sign as sign_tuition_plan
24
24
  expose disburse as fund_tuition