@hyperscale0/hsx 3.2.0 → 3.3.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.
@@ -2,15 +2,17 @@
2
2
  export const BUNDLED_STD_FILES = new Map([
3
3
  ["approvals.hsx", "header approvals\n\ninstrument decision(for: ref, approved_by: party, action: text = \"approve\") {\n summary: \"One authenticated decision bound to an immutable target and expiry.\"\n fields { target: ref<for>, expiresAt: date }\n lifecycle { states: [pending, approved, declined, expired], initial: pending }\n action create {}\n action approve {\n from: pending, to: approved, actor: { party: approved_by }, deadline: { at: self.expiresAt }\n approval: { target: self.target, action: action, party: approved_by, expires: self.expiresAt, input: \"material\", decision: \"approved\" }\n }\n action decline {\n from: pending, to: declined, actor: { party: approved_by }, deadline: { at: self.expiresAt }\n approval: { target: self.target, action: action, party: approved_by, expires: self.expiresAt, input: \"material\", decision: \"declined\" }\n }\n action expire { from: pending, to: expired, actor: clock, due: { at: self.expiresAt } }\n}\n"],
4
4
  ["cards.hsx", "header cards\n\ninstrument cardholder(holder: party) {\n fields { holder: account of holder }\n lifecycle { states: [pending, active, suspended, closed], initial: pending }\n action create {}\n action activate { from: pending, to: active }\n action suspend { from: active, to: suspended }\n action resume { from: suspended, to: active }\n action close { from: [active, suspended], to: closed }\n}\n\ninstrument card(holder: ref<cards.cardholder>, spend_limit: money) {\n fields { holder: ref<holder>, spendLimit: money = spend_limit }\n lifecycle { states: [issued, active, frozen, cancelled], initial: issued }\n action create { requires self.holder in [active] }\n action activate { from: issued, to: active, requires self.holder in [active] }\n action freeze { from: active, to: frozen }\n action unfreeze { from: frozen, to: active, requires self.holder in [active] }\n action cancel { from: [issued, active, frozen], to: cancelled }\n}\n\ninstrument authorization(card: ref<cards.card>, merchant: party, approval: approval) {\n fields { card: ref<card>, merchant: account of merchant, amount: money, expiresAt: date, reservation: text? }\n lifecycle { states: [pending, approved, captured, declined, reversed, expired], initial: pending }\n action create {\n requires self.card in [active]\n requires self.amount <= self.card.spendLimit\n }\n action approve {\n from: pending, to: approved, deadline: { at: self.expiresAt }\n requires approval by approval; requires self.card in [active]\n moves reserve self.amount from self.card.holder.holder to merchant capture \"reservation\"\n }\n action capture { from: approved, to: captured, deadline: { at: self.expiresAt }, moves post self.reservation }\n action reverse { from: approved, to: reversed, moves void self.reservation }\n action decline { from: pending, to: declined, requires approval by approval for \"approve\" is \"declined\" }\n action expire { from: approved, to: expired, actor: clock, due: { at: self.expiresAt }, moves void self.reservation }\n action abandon { from: pending, to: expired, actor: clock, due: { at: self.expiresAt } }\n}\n\ninstrument transaction(authorization: ref<cards.authorization>) {\n fields { authorization: ref<authorization>, amount: money = self.authorization.amount }\n lifecycle { states: [posted, refunded], initial: posted }\n action create { requires self.authorization in [captured]; requires unique \"captured_authorization\" on [self.authorization] }\n action refund {\n from: posted, to: refunded, input { reason: text }\n moves self.amount from self.authorization.merchant to self.authorization.card.holder.holder\n }\n}\n\ninstrument dispute(transaction: ref<cards.transaction>, approved_by: approval, within: duration = 90d) {\n fields { transaction: ref<transaction>, evidence: text, expiresAt: date = after(self.createdAt, within) }\n lifecycle { states: [filed, reviewing, won, lost], initial: filed }\n action create { requires self.transaction in [posted]; requires unique \"disputed_transaction\" on [self.transaction] }\n action review { from: filed, to: reviewing }\n action win {\n from: reviewing, to: won, deadline: { at: self.expiresAt }\n requires approval by approved_by\n invoke: [{ reference: self.transaction, action: refund, input: { reason: { field: self.evidence } } }]\n }\n action lose { from: [filed, reviewing], to: lost, actor: clock, due: { at: self.expiresAt } }\n}\n"],
5
- ["collections.hsx", "header collections\n\ninstrument case(on: ref<financing.installments>[], agency: approval, overdue: duration = 3d, fee: percent = 20%) {\n summary: \"Refer an overdue installment without creating another debt.\"\n fields { plan: ref<on>, slice: ref<on.slice>, payment: ref<on.payment>, eligibleAt: date = after(self.slice.dueAt, overdue), agencyFee: money = rate(self.payment.amount, fee) }\n lifecycle { states: [opened, assigned, recovered, recalled, returned_uncollected], initial: opened }\n action create {\n due: { at: self.eligibleAt }\n requires self.plan == self.slice.plan\n requires self.slice.principalReceivable.balance > \"0\"\n requires unique \"overdue_referral\" on [self.slice]\n }\n action assign { from: opened, to: assigned, requires approval by agency }\n action recover { from: assigned, to: recovered, actor: { party: agency }, requires self.payment.plan == self.plan, invoke: [{ reference: self.payment, action: pay, input: {} }, { reference: self.id, action: pay_fee, input: {} }] }\n action pay_fee { from: recovered, to: recovered, actor: { parent: current() }, moves self.agencyFee from self.plan.capital to agency }\n action recall { from: [opened, assigned], to: recalled }\n action return_uncollected { from: assigned, to: returned_uncollected, actor: { party: agency } }\n}\n\ninstrument contact(case: ref<collections.case>[], agency: party, max_contacts: integer = 10, window: duration = 30d, contact_from: integer(0, 23) = 8, contact_until: integer(1, 23) = 20, timezone: text = \"Asia/Riyadh\") {\n constraints { contact_from: less_than(contact_until) }\n summary: \"An agency contact admitted against the locked rolling count and local hours.\"\n fields { case: ref<case>, attemptedAt: date?, evidence: text, maximum: integer = max_contacts }\n lifecycle { states: [recorded], initial: recorded }\n invariants count of { instrument: current(), reference: \"case\", anchor: self.case, states: [recorded], limit: 366, window: { field: attemptedAt, milliseconds: window } } <= self.maximum\n action create {\n actor: { party: agency }\n set: { attemptedAt: { field: self.now } }\n requires self.case in [assigned]; requires hours self.now between contact_from and contact_until timezone timezone\n }\n}\n"],
6
- ["escrow.hsx", "header escrow\n\ninstrument hold(payer: party, payee: party, for: ref<marketplace.order>, accept_within: duration = 48h, fee: fee = { seller: 0%, tax: 0% }, dispute: policy = { refund_after: return_verified }) {\n summary: \"Hold an order's price through delivery, acceptance and verified return.\"\n fields { payer: account of payer, payee: account of payee, order: ref<for>, price: money, held: account of self, deliveredAt: date? }\n lifecycle { states: [pending, funded, delivered, disputed, return_verified, released, refunded, cancelled], initial: pending }\n action create {\n requires self.payer == self.order.buyer; requires self.payee == self.order.listing.seller; requires self.price == self.order.price\n }\n action fund {\n from: pending, to: funded, actor: { party: payer }\n requires self.order in [placed]\n moves self.price from payer to self.held\n }\n action confirm {\n from: pending, to: funded\n requires self.held.balance == self.price\n }\n action deliver {\n from: funded, to: delivered, actor: { party: payee }\n set: { deliveredAt: { field: self.now } }\n }\n action accept {\n from: delivered, to: released, actor: { party: payer }\n input { acceptanceReference: text, titleReference: text, coverReference: text }\n deadline: { at: self.deliveredAt, offset: accept_within }\n moves self.price from self.held to payee fee fee\n }\n action expire_acceptance {\n from: delivered, to: disputed, actor: clock\n due: { at: self.deliveredAt, offset: accept_within }\n }\n action dispute {\n from: delivered, to: disputed, actor: { party: payer }\n deadline: { at: self.deliveredAt, offset: accept_within }\n }\n action verify_return { from: disputed, to: return_verified, input { returnReference: text } }\n action refund {\n from: dispute.refund_after, to: refunded\n moves self.price from self.held to payer\n }\n action cancel { from: pending, to: cancelled }\n}\n"],
7
- ["financing.hsx", "header financing\n\ninstrument installments(months: integer(1, 366), profit: percent, disburse_to: enum(funds, borrower) = funds, profit_earned: enum(on_payment, by_schedule, at_disbursement) = on_payment, apply: enum(fines_profit_principal, principal_profit, pro_rata) = fines_profit_principal, payoff_rebate: percent = 100%, down_payment: percent = 0%, funds: ref, approval: approval, borrower: party = party(person), capital: party = programOperator, profit_to: party = programOperator, limits: ref<financing.limits> = object(financing.limits)) {\n summary: \"Funding, profit recognition and payment order chosen by the program.\"\n fields {\n funds: ref<funds>, borrower: account of borrower, settlementIdentity: text, borrowerLimit: ref<limits>, portfolioLimit: ref<limits.portfolio>\n months: integer = months, dates: list(date, months)\n capital: account(capital, cash, \"capital\"), profitIncome: account(profit_to, cash, \"profitIncome\"), loss: account(capital, claim, \"loss\")\n principalReturned: money?, profitReturned: money?, lossRecorded: money?\n price: money = self.funds.price\n downPayment: money = rate(self.price, down_payment)\n principal: money = subtract(self.price, self.downPayment)\n profit: money = rate(self.principal, profit)\n total: money = sum(self.principal, self.profit)\n }\n lifecycle { states: [quoted, signed, active, paid, written_off, cancelled], initial: quoted }\n invariants count of { instrument: all(financing.installments), reference: \"borrowerLimit\", anchor: self.borrowerLimit, states: [active], limit: 366 } <= self.borrowerLimit.activePlans\n invariants sum \"principalReceivable.balance\" of { instrument: all(financing.installments.slice), reference: \"borrowerLimit\", anchor: self.borrowerLimit, states: [pending, due, paid], limit: 366 } <= self.borrowerLimit.limit\n invariants sum \"principalReceivable.balance\" of { instrument: all(financing.installments.slice), reference: \"portfolioLimit\", anchor: self.portfolioLimit, states: [pending, due, paid], limit: 366 } <= self.portfolioLimit.limit\n action create { requires self.borrower == self.funds.payer; requires self.borrowerLimit.borrower == self.funds.payer }\n action sign {\n from: quoted, to: signed, input { signedOffer: text, affordabilityReference: text }\n requires count of { instrument: slice, reference: \"plan\", anchor: self.id, states: [draft], limit: 366 } == self.months\n }\n action disburse {\n from: signed, to: active\n requires approval by approval\n requires self.borrowerLimit in [approved]\n requires self.portfolioLimit in [approved]\n when disburse_to is funds {\n requires self.funds in [pending]\n moves self.downPayment from self.funds.payer to self.funds.held\n moves self.principal from self.capital to self.funds.held\n }\n when disburse_to is borrower { moves self.principal from self.capital to self.borrower }\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [draft], limit: 366, order: [position] }, action: activate, input: {} }]\n when disburse_to is funds { invoke: [{ reference: self.funds, action: confirm, input: {} }] }\n }\n action complete {\n from: active, to: paid\n requires count of { instrument: slice, reference: \"plan\", anchor: self.id, states: [pending, due], limit: 366 } == 0\n }\n action restore { from: [active, paid], to: active, actor: { parent: payment } }\n action payoff {\n from: active, to: paid\n calculate: [\n { target: \"principalReturned\", op: \"aggregate\", selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [pending, due], limit: 366 }, measure: { sum: \"principalReceivable.balance\" } }\n ]\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [pending, due], limit: 366, order: [position] }, action: payoff, input: { identity: { field: self.settlementIdentity } } }, { reference: self.id, action: record_payoff, input: {} }]\n }\n action record_payoff {\n from: paid, to: paid, actor: { parent: current() }\n calculate: [{ target: profitReturned, op: aggregate, selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [paid], limit: 366, where: { payoffIdentity: { field: self.settlementIdentity } } }, measure: { sum: \"payoffProfit\" } }]\n invoke: [{ instrument: settlement, action: create, input: { plan: { field: self.id }, identity: { field: self.settlementIdentity }, principal: { field: self.principalReturned }, profit: { field: self.profitReturned }, loss: { literal: \"0\" }, kind: { literal: \"cash\" } } }]\n }\n action write_off {\n from: active, to: written_off\n input { overdueSlice: ref<slice> }\n calculate: [{ target: \"lossRecorded\", op: \"aggregate\", selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [pending, due], limit: 366 }, measure: { sum: \"principalReceivable.balance\" } }]\n due: { at: input.overdueSlice.lossEligibleAt }\n requires approval by approval; requires input.overdueSlice.plan == self.id; requires input.overdueSlice.principalReceivable.balance > \"0\"\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [pending, due], limit: 366, order: [position] }, action: write_off, input: {} }, { instrument: settlement, action: create, input: { plan: { field: self.id }, identity: { field: self.settlementIdentity }, principal: { literal: \"0\" }, profit: { literal: \"0\" }, loss: { field: self.lossRecorded }, kind: { literal: \"loss\" } } }]\n }\n action record_payment {\n from: active, to: active, actor: { parent: payment }\n input { identity: text, principal: money, profit: money }\n invoke: [{ instrument: settlement, action: create, input: { plan: { field: self.id }, identity: { field: input.identity }, principal: { field: input.principal }, profit: { field: input.profit }, loss: { literal: \"0\" }, kind: { literal: \"cash\" } } }]\n }\n action cancel { from: quoted, to: cancelled }\n records {\n settlement: {\n fields { plan: ref<parent>, identity: text, principal: money, profit: money, loss: money, kind: enum(cash, loss)\n capital: account(capital, cash, \"capital\"), profitIncome: account(profit_to, cash, \"profitIncome\"), lossAccount: account(capital, claim, \"loss\") }\n lifecycle { states: [recorded], initial: recorded }\n action create {\n actor: { parent: parent }\n input { plan: ref<parent>, identity: text, principal: money, profit: money, loss: money, kind: enum(cash, loss) }\n requires unique \"settlement_identity\" on [self.plan, self.identity]\n }\n }\n slice: {\n fields {\n plan: ref<parent>, borrowerLimit: ref<limits>, portfolioLimit: ref<limits.portfolio>, position: integer(1, months)\n dueAt: date = at(self.plan.dates, self.position), lossEligibleAt: date = after(self.dueAt, 90d)\n principalBase: money = divide(self.plan.principal, months)\n principalAllocated: money = multiply(self.principalBase, months)\n principalRemainder: money = subtract(self.plan.principal, self.principalAllocated)\n profitBase: money = divide(self.plan.profit, months)\n profitAllocated: money = multiply(self.profitBase, months)\n profitRemainder: money = subtract(self.plan.profit, self.profitAllocated)\n first: integer = divide(1, self.position)\n principalAdjustment: money = multiply(self.principalRemainder, self.first)\n profitAdjustment: money = multiply(self.profitRemainder, self.first)\n principal: money = sum(self.principalBase, self.principalAdjustment)\n profit: money = sum(self.profitBase, self.profitAdjustment)\n principalReceivable: account(self, claim), profitReceivable: account(self, claim), profitEarned: account(self, claim)\n payoffIdentity: text?, payoffRebate: money?, payoffProfitTotal: money?, payoffProfit: money?\n paymentBudget: money?, principalPayment: money?, principalBasePayment: money?, principalRatio: money?, profitPayment: money?, profitBudget: money?, collectibleProfit: money?, collectibleTotal: money?, ratioDenominator: integer = sum(10000, profit)\n debt: account(borrower, claim, contra, \"debt\"), loss: account(capital, claim, \"loss\")\n }\n lifecycle { states: [draft, pending, due, paid, written_off], initial: draft }\n action create {\n requires self.plan in [quoted]; requires unique \"signed_position\" on [self.plan, self.position]; requires self.borrowerLimit == self.plan.borrowerLimit; requires self.portfolioLimit == self.plan.portfolioLimit\n }\n action activate {\n from: draft, to: pending, actor: { parent: parent }\n moves self.principal from self.debt to self.principalReceivable\n moves self.profit from self.debt to self.profitReceivable\n when profit_earned is at_disbursement { moves self.profit from self.profitReceivable to self.profitEarned }\n when profit_earned is by_schedule { invoke: [{ instrument: recognition, action: create, input: { slice: { field: self.id } } }] }\n }\n action mature {\n from: pending, to: due, actor: clock, due: { at: self.dueAt }\n }\n action collect {\n from: [pending, due], to: due, actor: { parent: payment }\n input { payment: ref<payment> }\n requires input.payment.plan == self.plan\n when profit_earned is on_payment { calculate: [{ target: collectibleProfit, op: sum, values: [{ field: self.profitReceivable.balance }] }] }\n when profit_earned is by_schedule { calculate: [{ target: collectibleProfit, op: sum, values: [{ field: self.profitEarned.balance }] }] }\n when profit_earned is at_disbursement { calculate: [{ target: collectibleProfit, op: sum, values: [{ field: self.profitEarned.balance }] }] }\n when apply is fines_profit_principal {\n invoke: [{ instrument: profit_piece, action: create, input: { slice: { field: self.id }, payment: { field: input.payment }, limit: { field: self.collectibleProfit } } }, { instrument: principal_piece, action: create, input: { slice: { field: self.id }, payment: { field: input.payment }, limit: { field: self.principalReceivable.balance } } }]\n }\n when apply is principal_profit {\n invoke: [{ instrument: principal_piece, action: create, input: { slice: { field: self.id }, payment: { field: input.payment }, limit: { field: self.principalReceivable.balance } } }, { instrument: profit_piece, action: create, input: { slice: { field: self.id }, payment: { field: input.payment }, limit: { field: self.collectibleProfit } } }]\n }\n }\n action collect_pro_rata {\n from: [pending, due], to: due, actor: { parent: payment }, input { payment: ref<payment> }\n requires input.payment.plan == self.plan\n when profit_earned is on_payment { calculate: [{ target: collectibleProfit, op: sum, values: [{ field: self.profitReceivable.balance }] }] }\n when profit_earned is by_schedule { calculate: [{ target: collectibleProfit, op: sum, values: [{ field: self.profitEarned.balance }] }] }\n when profit_earned is at_disbursement { calculate: [{ target: collectibleProfit, op: sum, values: [{ field: self.profitEarned.balance }] }] }\n calculate: [\n { target: collectibleTotal, op: sum, values: [{ field: self.principalReceivable.balance }, { field: self.collectibleProfit }] }\n { target: paymentBudget, op: minimum, values: [{ field: input.payment.held.balance }, { field: self.collectibleTotal }] }\n { target: principalRatio, op: ratio, amount: { field: self.paymentBudget }, numerator: { literal: 10000 }, denominator: { field: self.ratioDenominator }, rounding: floor }\n { target: principalBasePayment, op: minimum, values: [{ field: self.principalRatio }, { field: self.principalReceivable.balance }] }\n { target: profitBudget, op: subtract, base: { field: self.paymentBudget }, subtract: [{ field: self.principalBasePayment }] }\n { target: profitPayment, op: minimum, values: [{ field: self.profitBudget }, { field: self.collectibleProfit }] }\n { target: principalPayment, op: subtract, base: { field: self.paymentBudget }, subtract: [{ field: self.profitPayment }] }\n ]\n invoke: [{ instrument: principal_piece, action: create, input: { slice: { field: self.id }, payment: { field: input.payment }, limit: { field: self.principalPayment } } }, { instrument: profit_piece, action: create, input: { slice: { field: self.id }, payment: { field: input.payment }, limit: { field: self.profitPayment } } }]\n }\n action complete {\n from: [pending, due], to: paid\n requires self.principalReceivable.balance == \"0\"; requires self.profitReceivable.balance == \"0\"; requires self.profitEarned.balance == \"0\"\n }\n action restore { from: [pending, due, paid], to: due, actor: { parent: payment } }\n action payoff {\n from: [pending, due], to: paid, actor: { parent: parent }, input { identity: text }\n set: { payoffIdentity: { field: input.identity } }\n calculate: [{ target: payoffRebate, op: rate, base: { field: self.profitReceivable.balance }, bps: { literal: payoff_rebate }, rounding: floor }, { target: payoffProfitTotal, op: sum, values: [{ field: self.profitReceivable.balance }, { field: self.profitEarned.balance }] }, { target: payoffProfit, op: subtract, base: { field: self.payoffProfitTotal }, subtract: [{ field: self.payoffRebate }] }]\n moves self.principalReceivable.balance from self.plan.borrower to self.plan.capital\n moves self.payoffProfit from self.plan.borrower to self.plan.profitIncome\n moves self.principalReceivable.balance from self.principalReceivable to self.debt\n moves self.profitReceivable.balance from self.profitReceivable to self.debt\n moves self.profitEarned.balance from self.profitEarned to self.debt\n }\n action write_off {\n from: [pending, due], to: written_off, actor: { parent: parent }\n moves self.principalReceivable.balance from self.principalReceivable to self.loss; moves self.profitReceivable.balance from self.profitReceivable to self.debt; moves self.profitEarned.balance from self.profitEarned to self.loss\n }\n }\n recognition: {\n fields { slice: ref<slice>, dueAt: date = after(self.slice.dueAt, 0) }\n lifecycle { states: [pending, recognised], initial: pending }\n action create { actor: { parent: slice }, input { slice: ref<slice> }, requires unique \"profit_recognition\" on [self.slice] }\n action mature { from: pending, to: recognised, actor: clock, due: { at: self.dueAt }, moves self.slice.profitReceivable.balance from self.slice.profitReceivable to self.slice.profitEarned }\n }\n payment: {\n fields { plan: ref<parent>, amount: money, paymentIdentity: text, held: account of self\n capital: account(capital, cash, \"capital\"), profitIncome: account(profit_to, cash, \"profitIncome\"), loss: account(capital, claim, \"loss\")\n outstandingPrincipal: money?, outstandingProfit: money?, outstandingFines: money?, outstandingCosts: money?, outstandingTotal: money?, principalReturned: money?, profitReturned: money?, lossRecorded: money? }\n\n lifecycle { states: [pending, paid, refunded], initial: pending }\n action create { input { plan: ref<parent>, amount: money, paymentIdentity: text } requires self.plan in [active]; requires unique \"payment_identity\" on [self.plan, self.paymentIdentity] }\n action pay {\n from: pending, to: paid\n calculate: [{ target: outstandingPrincipal, op: aggregate, selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending, due, paid], limit: 366, order: [position] }, measure: { sum: \"principalReceivable.balance\" } }]\n when profit_earned is on_payment { calculate: [{ target: outstandingProfit, op: aggregate, selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending, due, paid], limit: 366, order: [position] }, measure: { sum: \"profitReceivable.balance\" } }] }\n when profit_earned is by_schedule { calculate: [{ target: outstandingProfit, op: aggregate, selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending, due, paid], limit: 366, order: [position] }, measure: { sum: \"profitEarned.balance\" } }] }\n when profit_earned is at_disbursement { calculate: [{ target: outstandingProfit, op: aggregate, selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending, due, paid], limit: 366, order: [position] }, measure: { sum: \"profitEarned.balance\" } }] }\n when apply is fines_profit_principal {\n calculate: [{ target: outstandingFines, op: aggregate, selection: { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.plan, states: [assessed, collected], limit: 366, order: [overdueAt] }, measure: { sum: \"receivable.balance\" } }, { target: outstandingCosts, op: aggregate, selection: { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.plan, states: [assessed, collected], limit: 366, order: [overdueAt] }, measure: { sum: \"receivable.balance\" } }, { target: outstandingTotal, op: sum, values: [{ field: self.outstandingPrincipal }, { field: self.outstandingProfit }, { field: self.outstandingFines }, { field: self.outstandingCosts }] }]\n }\n when apply is principal_profit { calculate: [{ target: outstandingTotal, op: sum, values: [{ field: self.outstandingPrincipal }, { field: self.outstandingProfit }] }] }\n when apply is pro_rata { calculate: [{ target: outstandingTotal, op: sum, values: [{ field: self.outstandingPrincipal }, { field: self.outstandingProfit }] }] }\n requires self.plan in [active]; requires self.amount <= self.outstandingTotal\n moves self.amount from self.plan.borrower to self.held\n when apply is principal_profit {\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending, due], limit: 366, order: [position] }, action: collect, input: { payment: { field: self.id } } }]\n }\n when apply is fines_profit_principal {\n invoke: [{ selection: { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.plan, states: [assessed, collected], limit: 366, order: [overdueAt] }, action: collect, input: { payment: { field: self.id } } }, { selection: { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.plan, states: [assessed, collected], limit: 366, order: [overdueAt] }, action: collect, input: { payment: { field: self.id } } }]\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending, due], limit: 366, order: [position] }, action: collect, input: { payment: { field: self.id } } }]\n }\n when apply is pro_rata {\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending, due], limit: 366, order: [position] }, action: collect_pro_rata, input: { payment: { field: self.id } } }]\n }\n invoke: [{ reference: self.id, action: record, input: {} }]\n }\n action record {\n from: paid, to: paid, actor: { parent: current() }\n requires self.held.balance == \"0\"\n calculate: [{ target: principalReturned, op: aggregate, selection: { instrument: principal_piece, reference: \"payment\", anchor: self.id, states: [paid], limit: 366 }, measure: { sum: \"amount\" } }, { target: profitReturned, op: aggregate, selection: { instrument: profit_piece, reference: \"payment\", anchor: self.id, states: [paid], limit: 366 }, measure: { sum: \"amount\" } }]\n invoke: [{ reference: self.plan, action: record_payment, input: { identity: { field: self.paymentIdentity }, principal: { field: self.principalReturned }, profit: { field: self.profitReturned } } }]\n }\n action refund {\n from: paid, to: refunded\n requires unique \"settlement_consumption\" on [self.plan, self.paymentIdentity]; requires self.plan in [active, paid]\n when apply is fines_profit_principal {\n invoke: [{ selection: { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.plan, states: [assessed, collected], limit: 366, order: [overdueAt] }, action: refund, input: { payment: { field: self.id } } }, { selection: { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.plan, states: [assessed, collected], limit: 366, order: [overdueAt] }, action: refund, input: { payment: { field: self.id } } }]\n }\n invoke: [{ reference: self.plan, action: restore, input: {} }, { selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending, due, paid], limit: 366 }, action: restore, input: {} }, { selection: { instrument: principal_piece, reference: \"payment\", anchor: self.id, states: [paid], limit: 366 }, action: refund, input: {} }, { selection: { instrument: profit_piece, reference: \"payment\", anchor: self.id, states: [paid], limit: 366 }, action: refund, input: {} }]\n }\n }\n principal_piece: {\n fields { slice: ref<slice>, payment: ref<payment>, limit: money, amount: money = minimum(self.payment.held.balance, self.slice.principalReceivable.balance, self.limit) }\n lifecycle { states: [paid, refunded], initial: paid }\n action create {\n actor: { parent: slice }\n input { slice: ref<slice>, payment: ref<payment>, limit: money }\n requires unique \"principal_receipt\" on [self.slice, self.payment]\n moves self.amount from self.payment.held to self.slice.plan.capital; moves self.amount from self.slice.principalReceivable to self.slice.debt\n }\n action refund {\n from: paid, to: refunded, actor: { parent: payment }\n moves self.amount from self.slice.plan.capital to self.slice.plan.funds.payer; moves self.amount from self.slice.debt to self.slice.principalReceivable\n }\n }\n profit_piece: {\n fields { slice: ref<slice>, payment: ref<payment>, limit: money, amount: money = minimum(self.payment.held.balance, self.limit) }\n lifecycle { states: [paid, refunded], initial: paid }\n action create {\n actor: { parent: slice }\n input { slice: ref<slice>, payment: ref<payment>, limit: money }\n requires unique \"profit_receipt\" on [self.slice, self.payment]\n moves self.amount from self.payment.held to self.slice.plan.profitIncome\n when profit_earned is on_payment { moves self.amount from self.slice.profitReceivable to self.slice.debt }\n when profit_earned is by_schedule { moves self.amount from self.slice.profitEarned to self.slice.debt }\n when profit_earned is at_disbursement { moves self.amount from self.slice.profitEarned to self.slice.debt }\n }\n action refund {\n from: paid, to: refunded, actor: { parent: payment }\n moves self.amount from self.slice.plan.profitIncome to self.slice.plan.borrower\n when profit_earned is on_payment { moves self.amount from self.slice.debt to self.slice.profitReceivable }\n when profit_earned is by_schedule { moves self.amount from self.slice.debt to self.slice.profitEarned }\n when profit_earned is at_disbursement { moves self.amount from self.slice.debt to self.slice.profitEarned }\n }\n }\n }\n}\n\ninstrument late_charge(on: ref<financing.installments>[], grace: duration = 3d, fine: money = 50 SAR, cap: money = 25 SAR, fines_to: party = programOperator, costs_to: party = programOperator, approval: approval = programOperator, borrower: party = party(person)) {\n summary: \"Separate approved fine and evidenced recovery claims on an overdue installment.\"\n fields {\n plan: ref<on>, slice: ref<on.slice>, borrower: account of borrower, fine: money = fine, overdueAt: date = after(self.slice.dueAt, grace)\n receivable: account(self, claim), debt: account(borrower, claim, contra, \"debt\")\n }\n lifecycle { states: [proposed, assessed, collected, waived, refunded], initial: proposed }\n action create { requires unique \"late_assessment\" on [self.slice]; requires self.borrower == self.slice.plan.borrower; requires self.plan == self.slice.plan }\n action assess {\n from: proposed, to: assessed, due: { at: self.overdueAt }\n requires self.slice.principalReceivable.balance > \"0\"; requires approval by approval\n moves self.fine from self.debt to self.receivable\n }\n action collect {\n from: [assessed, collected], to: assessed, input { payment: ref<on.payment> }\n requires input.payment in [paid]\n requires input.payment.plan == self.plan\n invoke: [{ instrument: receipt, action: create, input: { assessment: { field: self.id }, payment: { field: input.payment } } }, { selection: { instrument: current(), reference: \"plan\", anchor: self.plan, states: [assessed], limit: 1, where: { id: { field: self.id }, receivable.balance: { literal: \"0\" } } }, action: finish, input: {} }]\n }\n action finish { from: assessed, to: collected, actor: { parent: current() }, requires self.receivable.balance == \"0\" }\n action cancel { from: proposed, to: waived }\n action waive { from: assessed, to: waived, moves self.receivable.balance from self.receivable to self.debt }\n action refund {\n from: [assessed, collected], to: assessed, input { payment: ref<on.payment> }\n requires input.payment in [paid, refunded]\n requires input.payment.plan == self.plan\n invoke: [{ selection: { instrument: receipt, reference: \"payment\", anchor: input.payment, states: [paid], limit: 1, where: { assessment: { field: self.id } } }, action: refund, input: {} }, { selection: { instrument: current(), reference: \"plan\", anchor: self.plan, states: [assessed], limit: 1, where: { id: { field: self.id }, receivable.balance: { literal: \"0\" } } }, action: finish, input: {} }]\n }\n records {\n receipt: {\n fields { assessment: ref<parent>, payment: ref<on.payment>, amount: money = minimum(self.payment.held.balance, self.assessment.receivable.balance) }\n lifecycle { states: [paid, refunded], initial: paid }\n action create { actor: { parent: parent }, input { assessment: ref<parent>, payment: ref<on.payment> }, requires input.payment.plan == self.assessment.plan; requires unique \"fine_receipt\" on [self.assessment, self.payment]; moves self.amount from self.payment.held to fines_to; moves self.amount from self.assessment.receivable to self.assessment.debt }\n action refund { from: paid, to: refunded, actor: { parent: parent }, moves self.amount from fines_to to self.payment.plan.borrower; moves self.amount from self.assessment.debt to self.assessment.receivable }\n }\n\n cost: {\n fields {\n plan: ref<on>, assessment: ref<parent>, overdueAt: date = after(self.assessment.slice.dueAt, grace), evidence: text, evidencedCost: money, amount: money = minimum(self.evidencedCost, cap)\n receivable: account(self, claim), debt: account(borrower, claim, contra, \"debt\")\n }\n lifecycle { states: [proposed, assessed, collected, waived, refunded], initial: proposed }\n action create { requires unique \"recovery_assessment\" on [self.assessment]; requires self.plan == self.assessment.plan }\n action assess {\n from: proposed, to: assessed, due: { at: self.assessment.overdueAt }\n requires self.assessment.slice.principalReceivable.balance > \"0\"; requires approval by approval\n moves self.amount from self.debt to self.receivable\n }\n action collect {\n from: [assessed, collected], to: assessed, input { payment: ref<on.payment> }\n requires input.payment in [paid]\n requires input.payment.plan == self.plan\n invoke: [{ instrument: receipt, action: create, input: { assessment: { field: self.id }, payment: { field: input.payment } } }, { selection: { instrument: current(), reference: \"plan\", anchor: self.plan, states: [assessed], limit: 1, where: { id: { field: self.id }, receivable.balance: { literal: \"0\" } } }, action: finish, input: {} }]\n }\n action finish { from: assessed, to: collected, actor: { parent: current() }, requires self.receivable.balance == \"0\" }\n action cancel { from: proposed, to: waived }\n action waive { from: assessed, to: waived, moves self.receivable.balance from self.receivable to self.debt }\n action refund {\n from: [assessed, collected], to: assessed, input { payment: ref<on.payment> }\n requires input.payment in [paid, refunded]\n requires input.payment.plan == self.plan\n invoke: [{ selection: { instrument: receipt, reference: \"payment\", anchor: input.payment, states: [paid], limit: 1, where: { assessment: { field: self.id } } }, action: refund, input: {} }, { selection: { instrument: current(), reference: \"plan\", anchor: self.plan, states: [assessed], limit: 1, where: { id: { field: self.id }, receivable.balance: { literal: \"0\" } } }, action: finish, input: {} }]\n }\n records {\n receipt: {\n fields { assessment: ref<parent>, payment: ref<on.payment>, amount: money = minimum(self.payment.held.balance, self.assessment.receivable.balance) }\n lifecycle { states: [paid, refunded], initial: paid }\n action create { actor: { parent: parent }, input { assessment: ref<parent>, payment: ref<on.payment> }, requires input.payment.plan == self.assessment.plan; requires unique \"cost_receipt\" on [self.assessment, self.payment]; moves self.amount from self.payment.held to costs_to; moves self.amount from self.assessment.receivable to self.assessment.debt }\n action refund { from: paid, to: refunded, actor: { parent: parent }, moves self.amount from costs_to to self.payment.plan.borrower; moves self.amount from self.assessment.debt to self.assessment.receivable }\n }\n }\n }\n }\n}\n\ninstrument limits(per_borrower: money, portfolio: money, borrower: party = party(person), active_plans: integer = 1) {\n summary: \"One borrower ceiling and one shared portfolio ceiling.\"\n fields { borrower: account of borrower, limit: money = per_borrower, activePlans: integer = active_plans }\n lifecycle { states: [pending, approved], initial: pending }\n action create { requires unique \"borrower_limit\" on [self.borrower] }\n action approve { from: pending, to: approved }\n records {\n portfolio: {\n fields { key: text = \"portfolio\", limit: money = portfolio }\n lifecycle { states: [pending, approved], initial: pending }\n action create { requires unique \"portfolio_limit\" on [self.key] }\n action approve { from: pending, to: approved }\n }\n }\n}\n\ninstrument credit_line(borrower: party, lender: party, limit: money, expires: date) {\n summary: \"A revolving facility; each draw is a separate immutable advance.\"\n fields { borrower: account of borrower, lender: account of lender, debt: account(borrower, claim, contra, \"debt\"), limit: money = limit, expiresAt: date = expires }\n lifecycle { states: [pending, active, suspended, closed], initial: pending }\n action create {}\n action activate { from: pending, to: active, actor: { party: lender } }\n action suspend { from: active, to: suspended, actor: { party: lender } }\n action resume { from: suspended, to: active, actor: { party: lender } }\n action close { from: [active, suspended], to: closed, due: { at: self.expiresAt }, requires count of { instrument: all(financing.advance), reference: \"line\", anchor: self.id, states: [drawn], limit: 366 } == 0 }\n}\n\ninstrument advance(line: ref<financing.credit_line>, amount: money = runtime) {\n summary: \"A single facility draw with an immutable principal and full repayment.\"\n fields { line: ref<line>, amount: money = amount, principalReceivable: account(self, claim) }\n lifecycle { states: [pending, drawn, repaid, cancelled], initial: pending }\n action create { requires self.amount <= self.line.limit }\n invariants sum \"principalReceivable.balance\" of { instrument: all(financing.advance), reference: \"line\", anchor: self.line, states: [drawn], limit: 366 } <= self.line.limit\n action draw {\n from: pending, to: drawn\n requires self.line in [active]\n deadline: { at: self.line.expiresAt }\n moves self.amount from self.line.lender to self.line.borrower; moves self.amount from self.line.debt to self.principalReceivable\n }\n action repay { from: drawn, to: repaid, moves self.amount from self.line.borrower to self.line.lender; moves self.amount from self.principalReceivable to self.line.debt }\n action cancel { from: pending, to: cancelled }\n}\n"],
5
+ ["collections.hsx", "header collections\n\ninstrument case(on: ref<financing.installments>[], agency: approval, overdue: duration = 3d, fee: percent = 20%) {\n revisioned: true\n summary: \"Refer an overdue installment without creating another debt.\"\n fields { assignedAgency: account of agency, plan: ref<on>, slice: ref<on.slice>, payment: ref<on.payment>, eligibleAt: date = after(self.slice.dueAt, overdue), agencyFee: money = rate(self.payment.amount, fee) }\n lifecycle { states: [opened, assigned, recovered, recalled, returned_uncollected], initial: opened }\n action create {\n due: { at: self.eligibleAt }\n requires self.plan == self.slice.plan\n requires self.slice.principalReceivable.balance > \"0\"\n requires unique \"overdue_referral\" on [self.slice]\n }\n action assign { from: opened, to: assigned, requires approval by agency }\n action recover { expansionLimit: 8192, from: assigned, to: recovered, actor: { party: agency }, requires self.payment.plan == self.plan, invoke: [{ reference: self.payment, action: pay, input: {} }, { reference: self.id, action: pay_fee, input: {} }] }\n action pay_fee { from: recovered, to: recovered, actor: { parent: current() }, moves self.agencyFee from self.plan.capital to agency }\n action recall { from: [opened, assigned], to: recalled }\n action return_uncollected { from: assigned, to: returned_uncollected, actor: { party: agency } }\n}\n\ninstrument contact(case: ref<collections.case>[], agency: party, max_contacts: integer = 10, window: duration = 30d, contact_from: integer(0, 23) = 8, contact_until: integer(1, 23) = 20, timezone: text = \"Asia/Riyadh\") {\n constraints { contact_from: less_than(contact_until) }\n summary: \"An agency contact admitted against the locked rolling count and local hours.\"\n fields { agency: account of agency, case: ref<case>, attemptedAt: date?, evidence: text, maximum: integer = max_contacts }\n lifecycle { states: [recorded], initial: recorded }\n invariants count of { instrument: current(), reference: \"case\", anchor: self.case, states: [recorded], limit: 366, window: { field: attemptedAt, milliseconds: window } } <= self.maximum\n action create {\n actor: { party: agency }\n set: { attemptedAt: { field: self.now } }\n requires self.agency == self.case.assignedAgency; requires self.case in [assigned]; requires hours self.now between contact_from and contact_until timezone timezone\n }\n records {\n outcome: {\n fields { contact: ref<parent>, agency: account of agency, outcome: enum(reached, no_answer, promise_to_pay, disputed, wrong_contact, refused), evidence: text, recordedAt: date? }\n lifecycle { states: [recorded], initial: recorded }\n action create {\n actor: { party: agency }\n requires self.agency == self.contact.case.assignedAgency\n set: { recordedAt: { field: self.now } }\n }\n }\n }\n}\n\n\ninstrument reminder(on: ref<financing.installments>[], operator: party = programOperator, before_days: integer(0, 366) = 3, overdue_days: integer(1, 366) = 1, max_per_day: integer(1, 10) = 1, send_from: integer(0, 23) = 8, send_until: integer(1, 24) = 20, timezone: text = \"Asia/Riyadh\") {\n constraints { send_from: less_than(send_until) }\n summary: \"Send an email to the installment borrower's stored contact address.\"\n fields { slice: ref<on.slice> }\n lifecycle { states: [ready], initial: ready }\n action create { requires unique \"installment_reminder\" on [self.slice] }\n action dispatch {\n from: ready, to: ready, actor: { party: operator }\n invoke: [{ reference: self.id, action: send, input: {} }]\n }\n action before_due {\n from: ready, to: ready, actor: clock\n due: { at: self.slice.dueAt, localDay: { days: before_days, direction: \"before\", hour: send_from, timezone: timezone } }\n invoke: [{ selection: { instrument: current(), reference: \"slice\", anchor: self.slice, states: [ready], limit: 1, where: { slice.plan.status: { literal: \"active\" } } }, action: send, guard: { kind: compare, left: { field: self.slice.principalReceivable.balance }, operator: \">\", right: { literal: \"0\" } }, input: {} }]\n }\n action overdue {\n from: ready, to: ready, actor: clock\n due: { at: self.slice.dueAt, localDay: { days: overdue_days, direction: \"after\", hour: send_from, timezone: timezone } }\n invoke: [{ selection: { instrument: current(), reference: \"slice\", anchor: self.slice, states: [ready], limit: 1, where: { slice.plan.status: { literal: \"active\" } } }, action: send, guard: { kind: compare, left: { field: self.slice.principalReceivable.balance }, operator: \">\", right: { literal: \"0\" } }, input: {} }]\n }\n action send {\n from: ready, to: ready, actor: { parent: current() }\n requires self.slice.plan in [active]\n requires self.slice.principalReceivable.balance > \"0\"\n reminder: { installment: self.slice, recipient: self.slice.plan.borrower, dueAt: self.slice.dueAt, channel: \"email\", template: \"payment_reminder\", beforeDays: before_days, overdueDays: overdue_days, maxPerDay: max_per_day, startHour: send_from, endHour: send_until, timezone: timezone }\n }\n}\n"],
6
+ ["escrow.hsx", "header escrow\n\ninstrument hold(payer: party, payee: party, for: ref<marketplace.order>, accept_within: duration = 48h, fee: fee = { seller: 0%, tax: 0% }, dispute: policy = { refund_after: return_verified }) {\n revisioned: true\n summary: \"Hold an order's price through delivery, acceptance and verified return.\"\n fields { payer: account of payer, payee: account of payee, order: ref<for>, price: money, held: account of self, deliveredAt: date?, buyerTopUp: money? }\n lifecycle { states: [pending, funded, delivered, disputed, return_verified, released, refunded, cancelled], initial: pending }\n action create {\n requires self.payer == self.order.buyer; requires self.payee == self.order.listing.seller; requires self.price == self.order.price\n }\n action fund {\n from: pending, to: funded, actor: { party: payer }\n requires self.order in [quoted, placed]\n invoke: [{ reference: self.order, action: commit, input: {} }, { selection: { instrument: all(marketplace.reservation), reference: \"listing\", anchor: self.order.listing, states: [active], limit: 1, where: { buyer: { field: self.payer } } }, action: credit, input: { funds: { field: self.id }, contribution: { field: self.price } } }, { reference: self.id, action: fund_remainder, input: {} }]\n }\n action fund_remainder {\n from: funded, to: funded, actor: { parent: current() }\n calculate: [{ target: buyerTopUp, op: subtract, base: { field: self.price }, subtract: [{ field: self.held.balance }] }]\n moves self.buyerTopUp from payer to self.held\n }\n action confirm {\n from: pending, to: funded\n requires self.held.balance == self.price\n invoke: [{ reference: self.order, action: commit, input: {} }]\n }\n action deliver {\n from: funded, to: delivered, actor: { party: payee }\n set: { deliveredAt: { field: self.now } }\n }\n action accept {\n from: delivered, to: released, actor: { party: payer }\n input { acceptanceReference: text, titleReference: text, coverReference: text }\n deadline: { at: self.deliveredAt, offset: accept_within }\n moves self.price from self.held to payee fee fee\n }\n action expire_acceptance {\n from: delivered, to: disputed, actor: clock\n due: { at: self.deliveredAt, offset: accept_within }\n }\n action dispute {\n from: delivered, to: disputed, actor: { party: payer }\n deadline: { at: self.deliveredAt, offset: accept_within }\n }\n action verify_return { from: disputed, to: return_verified, input { returnReference: text } }\n action refund {\n from: dispute.refund_after, to: refunded\n moves self.price from self.held to payer\n }\n action cancel { from: pending, to: cancelled }\n}\n"],
7
+ ["financing.hsx", "header financing\n\ninstrument installments(months: integer(1, 366), charge_limit: integer(1, 3) = 3, profit: percent, disburse_to: enum(funds, borrower) = funds, profit_earned: enum(on_payment, by_schedule, at_disbursement) = on_payment, apply: enum(fines_profit_principal, principal_profit, pro_rata) = fines_profit_principal, payoff_rebate: percent = 100%, write_off_after: duration = 90d, max_extension: duration = 90d, max_amendments: integer(0, 366) = 2, waiver_limit: percent = 100%, amendment_expiry: duration = 7d, payoff_quote_expiry: duration = 1h, allow_overdue: enum(allowed, blocked) = allowed, assessed_fines: enum(carry, require_waiver) = carry, down_payment: percent = 0%, funds: ref, approval: approval, borrower: party = party(person), capital: party = programOperator, profit_to: party = programOperator, limits: ref<financing.limits> = object(financing.limits)) {\n revisioned: true\n summary: \"Funding, profit recognition and payment order chosen by the program.\"\n fields {\n funds: ref<funds>, borrower: account of borrower, settlementIdentity: text, borrowerLimit: ref<limits>, portfolioLimit: ref<limits.portfolio>\n months: integer = months, dates: list(date, months)\n capital: account(capital, cash, \"capital\"), profitIncome: account(profit_to, cash, \"profitIncome\"), loss: account(capital, claim, \"loss\")\n downPaymentRemaining: money?, downPaymentCredit: money?, principalReturned: money?, profitReturned: money?, lossRecorded: money?\n price: money = self.funds.price\n downPayment: money = rate(self.price, down_payment)\n principal: money = subtract(self.price, self.downPayment)\n profit: money = rate(self.principal, profit)\n total: money = sum(self.principal, self.profit)\n }\n lifecycle { states: [quoted, signed, active, paid, written_off, cancelled], initial: quoted }\n invariants count of { instrument: all(financing.installments), reference: \"borrowerLimit\", anchor: self.borrowerLimit, states: [active], limit: 366 } <= self.borrowerLimit.activePlans\n invariants sum \"principalReceivable.balance\" of { instrument: all(financing.installments.slice), reference: \"borrowerLimit\", anchor: self.borrowerLimit, states: [pending, due, paid], limit: 366 } <= self.borrowerLimit.limit\n invariants sum \"principalReceivable.balance\" of { instrument: all(financing.installments.slice), reference: \"portfolioLimit\", anchor: self.portfolioLimit, states: [pending, due, paid], limit: 366 } <= self.portfolioLimit.limit\n action create {\n requires self.borrower == self.funds.payer; requires self.borrowerLimit.borrower == self.funds.payer\n invoke: [{ range: { count: { literal: months }, maximum: months, bind: position }, instrument: slice, action: create, input: { plan: { field: self.id }, borrowerLimit: { field: self.borrowerLimit }, portfolioLimit: { field: self.portfolioLimit }, position: { field: position } } }]\n }\n action sign {\n from: quoted, to: signed, actor: { party: borrower }, input { signedOffer: text, affordabilityReference: text }\n requires count of { instrument: slice, reference: \"plan\", anchor: self.id, states: [draft], limit: 366 } == self.months\n when funds has order { invoke: [{ reference: self.funds.order, action: commit, input: {} }] }\n }\n action disburse {\n from: signed, to: active\n requires approval by approval\n requires self.borrowerLimit in [approved]\n requires self.portfolioLimit in [approved]\n when disburse_to is funds {\n requires self.funds in [pending]\n when funds has order { invoke: [{ selection: { instrument: all(marketplace.reservation), reference: \"listing\", anchor: self.funds.order.listing, states: [active], limit: 1, where: { buyer: { field: self.borrower } } }, action: credit, input: { funds: { field: self.funds }, contribution: { field: self.downPayment } } }] }\n invoke: [{ reference: self.id, action: fund_down_payment, input: {} }]\n }\n when disburse_to is borrower { moves self.principal from self.capital to self.borrower }\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [draft], limit: 366, order: [position] }, action: activate, input: {} }]\n when disburse_to is funds { invoke: [{ reference: self.funds, action: confirm, input: {} }] }\n }\n action fund_down_payment {\n from: active, to: active, actor: { parent: current() }\n calculate: [{ target: downPaymentCredit, op: minimum, values: [{ field: self.funds.held.balance }, { field: self.downPayment }] }, { target: downPaymentRemaining, op: subtract, base: { field: self.downPayment }, subtract: [{ field: self.downPaymentCredit }] }]\n moves self.downPaymentRemaining from self.funds.payer to self.funds.held\n moves self.principal from self.capital to self.funds.held\n }\n action complete {\n from: active, to: paid\n requires count of { instrument: slice, reference: \"plan\", anchor: self.id, states: [pending, due], limit: 366 } == 0\n requires sum \"receivable.balance\" of { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.id, states: [assessed, collected], limit: 366 } == \"0\"\n requires sum \"receivable.balance\" of { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.id, states: [assessed, collected], limit: 366 } == \"0\"\n }\n action restore { from: [active, paid], to: active, actor: { parent: payment } }\n action payoff {\n from: active, to: paid, actor: { party: borrower }\n input { quote: ref<payoff_quote> }\n requires input.quote.plan == self.id; requires input.quote.revision == self.productRevision\n deadline: { at: input.quote.expiresAt }\n calculate: [\n { target: \"principalReturned\", op: \"aggregate\", selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [pending, due], limit: 366 }, measure: { sum: \"principalReceivable.balance\" } }\n ]\n invoke: [{ selection: { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.id, states: [assessed, collected], limit: 366, order: [overdueAt] }, action: payoff, input: {} }, { selection: { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.id, states: [assessed, collected], limit: 366, order: [overdueAt] }, action: payoff, input: {} }]\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [pending, due], limit: 366, order: [position] }, action: payoff, input: { identity: { field: self.settlementIdentity } } }, { reference: self.id, action: record_payoff, input: {} }]\n }\n action record_payoff {\n from: paid, to: paid, actor: { parent: current() }\n calculate: [{ target: profitReturned, op: aggregate, selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [paid], limit: 366, where: { payoffIdentity: { field: self.settlementIdentity } } }, measure: { sum: \"payoffProfit\" } }]\n invoke: [{ instrument: settlement, action: create, input: { plan: { field: self.id }, identity: { field: self.settlementIdentity }, principal: { field: self.principalReturned }, profit: { field: self.profitReturned }, loss: { literal: \"0\" }, kind: { literal: \"cash\" } } }]\n }\n action write_off {\n from: active, to: written_off\n input { overdueSlice: ref<slice> }\n calculate: [{ target: \"lossRecorded\", op: \"aggregate\", selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [pending, due], limit: 366 }, measure: { sum: \"principalReceivable.balance\" } }]\n due: { at: input.overdueSlice.lossEligibleAt }\n requires approval by approval; requires input.overdueSlice.plan == self.id; requires input.overdueSlice.principalReceivable.balance > \"0\"\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [pending, due], limit: 366, order: [position] }, action: write_off, input: {} }, { instrument: settlement, action: create, input: { plan: { field: self.id }, identity: { field: self.settlementIdentity }, principal: { literal: \"0\" }, profit: { literal: \"0\" }, loss: { field: self.lossRecorded }, kind: { literal: \"loss\" } } }]\n }\n action record_payment {\n from: active, to: active, actor: { parent: payment }\n input { identity: text, principal: money, profit: money }\n invoke: [{ instrument: settlement, action: create, input: { plan: { field: self.id }, identity: { field: input.identity }, principal: { field: input.principal }, profit: { field: input.profit }, loss: { literal: \"0\" }, kind: { literal: \"cash\" } } }]\n }\n action cancel { from: quoted, to: cancelled }\n action void { from: signed, to: cancelled, actor: { party: borrower } }\n records {\n payoff_quote: {\n fields {\n plan: ref<parent>, revision: text?, effectiveAt: date?, expiresAt: date = after(self.createdAt, payoff_quote_expiry)\n principal: money?, earnedProfit: money?, unearnedProfit: money?, rebate: money?, fines: money?, costs: money?, gross: money?, amount: money?\n }\n lifecycle { states: [quoted], initial: quoted }\n action create {\n requires self.plan in [active]\n set: { revision: { field: self.productRevision }, effectiveAt: { field: self.now } }\n invoke: [\n { selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending], limit: 366 }, action: quote_pending, input: { quote: { field: self.id } } }\n { selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [due], limit: 366 }, action: quote_due, input: { quote: { field: self.id } } }\n { reference: self.id, action: record, input: {} }\n ]\n }\n action record {\n from: quoted, to: quoted, actor: { parent: current() }\n calculate: [\n { target: principal, op: aggregate, selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending, due, paid], limit: 366 }, measure: { sum: \"principalReceivable.balance\" } }\n { target: earnedProfit, op: aggregate, selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending, due, paid], limit: 366 }, measure: { sum: \"profitEarned.balance\" } }\n { target: unearnedProfit, op: aggregate, selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending, due, paid], limit: 366 }, measure: { sum: \"profitReceivable.balance\" } }\n { target: rebate, op: aggregate, selection: { instrument: quote_piece, reference: \"quote\", anchor: self.id, states: [recorded], limit: 366 }, measure: { sum: \"rebate\" } }\n { target: fines, op: aggregate, selection: { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.plan, states: [assessed, collected], limit: 366 }, measure: { sum: \"receivable.balance\" } }\n { target: costs, op: aggregate, selection: { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.plan, states: [assessed, collected], limit: 366 }, measure: { sum: \"receivable.balance\" } }\n { target: gross, op: sum, values: [{ field: self.principal }, { field: self.earnedProfit }, { field: self.unearnedProfit }, { field: self.fines }, { field: self.costs }] }\n { target: amount, op: subtract, base: { field: self.gross }, subtract: [{ field: self.rebate }] }\n ]\n }\n }\n quote_piece: {\n fields { quote: ref<payoff_quote>, slice: ref<slice>, rebate: money = rate(self.slice.profitReceivable.balance, payoff_rebate) }\n lifecycle { states: [recorded], initial: recorded }\n action create { actor: { parent: slice }, input { quote: ref<payoff_quote>, slice: ref<slice> }, requires unique \"payoff_slice_quote\" on [self.quote, self.slice] }\n }\n amendment: {\n fields {\n plan: ref<parent>, dates: list(date, months), agreement: text, waiverPercent: percent, waiverEvidence: text, maximumWaiver: percent = waiver_limit\n revision: text?, acceptedAt: date?, staleReason: text?, expiresAt: date = after(self.createdAt, amendment_expiry)\n fineDisposition: enum(carry, require_waiver) = assessed_fines, addedProfit: money = 0 SAR\n principalSnapshot: money?, earnedProfitSnapshot: money?, unearnedProfitSnapshot: money?, finesSnapshot: money?, costsSnapshot: money?\n extension: duration = max_extension, maximum: integer = max_amendments\n }\n lifecycle { states: [proposed, applied, declined, withdrawn, expired, superseded], initial: proposed }\n action create {\n actor: { party: borrower }\n requires self.plan in [active]; requires self.waiverPercent <= self.maximumWaiver\n set: { revision: { field: self.productRevision } }\n calculate: [\n { target: principalSnapshot, op: aggregate, selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending, due, paid], limit: 366 }, measure: { sum: \"principalReceivable.balance\" } }\n { target: earnedProfitSnapshot, op: aggregate, selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending, due, paid], limit: 366 }, measure: { sum: \"profitEarned.balance\" } }\n { target: unearnedProfitSnapshot, op: aggregate, selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending, due, paid], limit: 366 }, measure: { sum: \"profitReceivable.balance\" } }\n { target: finesSnapshot, op: aggregate, selection: { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.plan, states: [assessed, collected], limit: 366 }, measure: { sum: \"receivable.balance\" } }\n { target: costsSnapshot, op: aggregate, selection: { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.plan, states: [assessed, collected], limit: 366 }, measure: { sum: \"receivable.balance\" } }\n ]\n requires count of { instrument: current(), reference: \"plan\", anchor: self.plan, states: [applied], limit: 366 } < self.maximum\n invoke: [{ range: { count: { literal: months }, maximum: months, bind: position }, instrument: proposed_date, action: create, input: { amendment: { field: self.id }, position: { field: position } } }, { selection: { instrument: proposed_date, reference: \"amendment\", anchor: self.id, states: [recorded], limit: 366, where: { first: { literal: 0 } } }, action: check_order, input: {} }]\n }\n action accept {\n from: proposed, to: applied, actor: { party: borrower }, deadline: { at: self.expiresAt }\n requires self.plan in [active]; requires self.revision == self.productRevision\n requires approval by approval\n requires count of { instrument: current(), reference: \"plan\", anchor: self.plan, states: [applied], limit: 366 } < self.maximum\n set: { acceptedAt: { field: self.now } }\n when assessed_fines is require_waiver { requires self.waiverPercent == 10000 }\n invoke: [{ selection: { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.plan, states: [assessed, collected], limit: 366 }, action: waive_for_amendment, input: { amendment: { field: self.id } } }, { selection: { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.plan, states: [assessed, collected], limit: 366 }, action: waive_for_amendment, input: { amendment: { field: self.id } } }]\n invoke: [{ selection: { instrument: all(collections.case), reference: \"plan\", anchor: self.plan, states: [opened, assigned], limit: 366 }, action: recall, input: {} }, { selection: { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.plan, states: [proposed], limit: 366 }, action: cancel, input: {} }, { selection: { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.plan, states: [proposed], limit: 366 }, action: cancel, input: {} }]\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending, due], limit: 366, order: [position] }, action: amend, input: { amendment: { field: self.id } } }]\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [paid], limit: 366 }, action: verify_fixed_date, input: { amendment: { field: self.id } } }]\n }\n action withdraw { from: proposed, to: withdrawn, actor: { party: borrower } }\n action decline { from: proposed, to: declined, actor: { party: approval } }\n action expire { from: proposed, to: expired, actor: clock, due: { at: self.expiresAt } }\n action supersede { from: proposed, to: superseded, requires self.revision != self.productRevision, set: { staleReason: { literal: \"economic_revision_changed\" } } }\n }\n proposed_date: {\n fields { amendment: ref<amendment>, position: integer(1, months), date: date = at(self.amendment.dates, self.position), first: integer = divide(1, self.position), prior: integer = subtract(self.position, 1), previousPosition: integer = sum(self.prior, self.first), previous: date = at(self.amendment.dates, self.previousPosition) }\n lifecycle { states: [recorded], initial: recorded }\n action create { actor: { parent: amendment }, input { amendment: ref<amendment>, position: integer(1, months) }, requires self.date >= self.previous }\n action check_order { from: recorded, to: recorded, actor: { parent: amendment }, requires self.date > self.previous }\n }\n date_change: {\n fields { amendment: ref<amendment>, slice: ref<slice>, oldDate: date, newDate: date }\n lifecycle { states: [recorded], initial: recorded }\n action create { actor: { parent: slice }, input { amendment: ref<amendment>, slice: ref<slice>, oldDate: date, newDate: date }, requires unique \"amended_slice\" on [self.amendment, self.slice] }\n }\n settlement: {\n fields { plan: ref<parent>, identity: text, principal: money, profit: money, loss: money, kind: enum(cash, loss)\n capital: account(capital, cash, \"capital\"), profitIncome: account(profit_to, cash, \"profitIncome\"), lossAccount: account(capital, claim, \"loss\") }\n lifecycle { states: [recorded], initial: recorded }\n action create {\n actor: { parent: parent }\n input { plan: ref<parent>, identity: text, principal: money, profit: money, loss: money, kind: enum(cash, loss) }\n requires unique \"settlement_identity\" on [self.plan, self.identity]\n }\n }\n slice: {\n revisioned: true\n fields {\n plan: ref<parent>, borrowerLimit: ref<limits>, portfolioLimit: ref<limits.portfolio>, position: integer(1, months)\n originalDueAt: date = at(self.plan.dates, self.position), dueAt: date?, nextDueAt: date?, previousDueAt: date?, previousPosition: integer?, previousDate: date?, extensionLimit: date = after(self.originalDueAt, max_extension), lossEligibleAt: date?\n principalBase: money = divide(self.plan.principal, months)\n principalAllocated: money = multiply(self.principalBase, months)\n principalRemainder: money = subtract(self.plan.principal, self.principalAllocated)\n profitBase: money = divide(self.plan.profit, months)\n profitAllocated: money = multiply(self.profitBase, months)\n profitRemainder: money = subtract(self.plan.profit, self.profitAllocated)\n first: integer = divide(1, self.position)\n principalAdjustment: money = multiply(self.principalRemainder, self.first)\n profitAdjustment: money = multiply(self.profitRemainder, self.first)\n principal: money = sum(self.principalBase, self.principalAdjustment)\n profit: money = sum(self.profitBase, self.profitAdjustment)\n principalReceivable: account(self, claim), profitReceivable: account(self, claim), profitEarned: account(self, claim)\n payoffIdentity: text?, payoffRebate: money?, payoffProfitTotal: money?, payoffProfit: money?\n paymentBudget: money?, principalPayment: money?, principalBasePayment: money?, principalRatio: money?, profitPayment: money?, profitBudget: money?, collectibleProfit: money?, collectibleTotal: money?, ratioDenominator: integer = sum(10000, profit)\n debt: account(borrower, claim, contra, \"debt\"), loss: account(capital, claim, \"loss\")\n }\n lifecycle { states: [draft, pending, due, paid, written_off], initial: draft }\n action create {\n actor: { parent: parent }\n input { plan: ref<parent>, borrowerLimit: ref<limits>, portfolioLimit: ref<limits.portfolio>, position: integer(1, months) }\n set: { dueAt: { field: self.originalDueAt } }\n invoke: [{ reference: self.id, action: refresh_loss_date, input: {} }]\n requires self.plan in [quoted]; requires unique \"signed_position\" on [self.plan, self.position]; requires self.borrowerLimit == self.plan.borrowerLimit; requires self.portfolioLimit == self.plan.portfolioLimit\n }\n action quote_pending {\n from: pending, to: pending, actor: { parent: payoff_quote }, input { quote: ref<payoff_quote> }\n requires input.quote.plan == self.plan\n invoke: [{ instrument: quote_piece, action: create, input: { quote: { field: input.quote }, slice: { field: self.id } } }]\n }\n action quote_due {\n from: due, to: due, actor: { parent: payoff_quote }, input { quote: ref<payoff_quote> }\n requires input.quote.plan == self.plan\n invoke: [{ instrument: quote_piece, action: create, input: { quote: { field: input.quote }, slice: { field: self.id } } }]\n }\n action refresh_loss_date {\n from: [draft, pending, due], to: draft, actor: { parent: current() }\n calculate: [{ target: lossEligibleAt, op: shift, date: { field: self.dueAt }, milliseconds: { literal: write_off_after }, direction: after }]\n }\n action amend {\n from: [pending, due], to: pending, actor: { parent: amendment }, input { amendment: ref<amendment> }\n requires input.amendment.plan == self.plan\n when allow_overdue is blocked { requires self.dueAt > self.now }\n calculate: [\n { target: nextDueAt, op: at, list: input.amendment.dates, position: { field: self.position } }\n { target: lossEligibleAt, op: shift, date: { field: self.nextDueAt }, milliseconds: { literal: write_off_after }, direction: after }\n ]\n requires self.nextDueAt > self.now; requires self.nextDueAt >= self.dueAt; requires self.nextDueAt <= self.extensionLimit\n set: { previousDueAt: { field: self.dueAt }, dueAt: { field: self.nextDueAt } }\n invoke: [{ instrument: date_change, action: create, input: { amendment: { field: input.amendment }, slice: { field: self.id }, oldDate: { field: self.previousDueAt }, newDate: { field: self.nextDueAt } } }]\n when profit_earned is by_schedule { invoke: [{ selection: { instrument: recognition, reference: \"slice\", anchor: self.id, states: [pending], limit: 1 }, action: reschedule, input: {} }] }\n }\n action verify_fixed_date {\n from: paid, to: paid, actor: { parent: amendment }, input { amendment: ref<amendment> }\n calculate: [{ target: nextDueAt, op: at, list: input.amendment.dates, position: { field: self.position } }]\n requires self.nextDueAt == self.dueAt\n }\n action activate {\n from: draft, to: pending, actor: { parent: parent }\n moves self.principal from self.debt to self.principalReceivable\n moves self.profit from self.debt to self.profitReceivable\n when profit_earned is at_disbursement { moves self.profit from self.profitReceivable to self.profitEarned }\n when profit_earned is by_schedule { invoke: [{ instrument: recognition, action: create, input: { slice: { field: self.id } } }] }\n }\n action mature {\n from: pending, to: due, actor: clock, due: { at: self.dueAt }\n }\n action collect {\n from: [pending, due], to: preserve, actor: { parent: payment }\n input { payment: ref<payment> }\n requires input.payment.plan == self.plan\n when profit_earned is on_payment { calculate: [{ target: collectibleProfit, op: sum, values: [{ field: self.profitReceivable.balance }] }] }\n when profit_earned is by_schedule { calculate: [{ target: collectibleProfit, op: sum, values: [{ field: self.profitEarned.balance }] }] }\n when profit_earned is at_disbursement { calculate: [{ target: collectibleProfit, op: sum, values: [{ field: self.profitEarned.balance }] }] }\n when apply is principal_profit {\n invoke: [\n { instrument: principal_piece, action: create, input: { slice: { field: self.id }, payment: { field: input.payment }, limit: { field: self.principalReceivable.balance } } }\n { instrument: profit_piece, action: create, input: { slice: { field: self.id }, payment: { field: input.payment }, limit: { field: self.collectibleProfit } } }\n { selection: { instrument: current(), reference: \"plan\", anchor: self.plan, states: [pending, due], limit: 1, where: { id: { field: self.id }, principalReceivable.balance: { literal: \"0\" }, profitReceivable.balance: { literal: \"0\" }, profitEarned.balance: { literal: \"0\" } } }, action: complete, input: {} }\n ]\n }\n }\n action collect_waterfall {\n from: [pending, due], to: preserve, actor: { parent: payment }, input { payment: ref<payment> }\n requires input.payment.plan == self.plan\n when profit_earned is on_payment { calculate: [{ target: collectibleProfit, op: sum, values: [{ field: self.profitReceivable.balance }] }] }\n when profit_earned is by_schedule { calculate: [{ target: collectibleProfit, op: sum, values: [{ field: self.profitEarned.balance }] }] }\n when profit_earned is at_disbursement { calculate: [{ target: collectibleProfit, op: sum, values: [{ field: self.profitEarned.balance }] }] }\n invoke: [\n { selection: { instrument: all(financing.late_charge), reference: \"slice\", anchor: self.id, states: [assessed], limit: charge_limit, order: [overdueAt] }, action: collect, input: { payment: { field: input.payment } } }\n { selection: { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.plan, states: [assessed], limit: charge_limit, order: [overdueAt], where: { assessment.slice: { field: self.id } } }, action: collect, input: { payment: { field: input.payment } } }\n { instrument: profit_piece, action: create, input: { slice: { field: self.id }, payment: { field: input.payment }, limit: { field: self.collectibleProfit } } }\n { instrument: principal_piece, action: create, input: { slice: { field: self.id }, payment: { field: input.payment }, limit: { field: self.principalReceivable.balance } } }\n { selection: { instrument: current(), reference: \"plan\", anchor: self.plan, states: [pending, due], limit: 1, where: { id: { field: self.id }, principalReceivable.balance: { literal: \"0\" }, profitReceivable.balance: { literal: \"0\" }, profitEarned.balance: { literal: \"0\" } } }, action: complete, input: {} }\n ]\n }\n action collect_pro_rata {\n from: [pending, due], to: preserve, actor: { parent: payment }, input { payment: ref<payment> }\n requires input.payment.plan == self.plan\n when profit_earned is on_payment { calculate: [{ target: collectibleProfit, op: sum, values: [{ field: self.profitReceivable.balance }] }] }\n when profit_earned is by_schedule { calculate: [{ target: collectibleProfit, op: sum, values: [{ field: self.profitEarned.balance }] }] }\n when profit_earned is at_disbursement { calculate: [{ target: collectibleProfit, op: sum, values: [{ field: self.profitEarned.balance }] }] }\n calculate: [\n { target: collectibleTotal, op: sum, values: [{ field: self.principalReceivable.balance }, { field: self.collectibleProfit }] }\n { target: paymentBudget, op: minimum, values: [{ field: input.payment.held.balance }, { field: self.collectibleTotal }] }\n { target: principalRatio, op: ratio, amount: { field: self.paymentBudget }, numerator: { literal: 10000 }, denominator: { field: self.ratioDenominator }, rounding: floor }\n { target: principalBasePayment, op: minimum, values: [{ field: self.principalRatio }, { field: self.principalReceivable.balance }] }\n { target: profitBudget, op: subtract, base: { field: self.paymentBudget }, subtract: [{ field: self.principalBasePayment }] }\n { target: profitPayment, op: minimum, values: [{ field: self.profitBudget }, { field: self.collectibleProfit }] }\n { target: principalPayment, op: subtract, base: { field: self.paymentBudget }, subtract: [{ field: self.profitPayment }] }\n ]\n invoke: [\n { instrument: principal_piece, action: create, input: { slice: { field: self.id }, payment: { field: input.payment }, limit: { field: self.principalPayment } } }\n { instrument: profit_piece, action: create, input: { slice: { field: self.id }, payment: { field: input.payment }, limit: { field: self.profitPayment } } }\n { selection: { instrument: current(), reference: \"plan\", anchor: self.plan, states: [pending, due], limit: 1, where: { id: { field: self.id }, principalReceivable.balance: { literal: \"0\" }, profitReceivable.balance: { literal: \"0\" }, profitEarned.balance: { literal: \"0\" } } }, action: complete, input: {} }\n ]\n }\n action complete {\n from: [pending, due], to: paid\n requires self.principalReceivable.balance == \"0\"; requires self.profitReceivable.balance == \"0\"; requires self.profitEarned.balance == \"0\"\n }\n action restore { from: [pending, due, paid], to: pending, actor: { parent: payment } }\n action payoff {\n from: [pending, due], to: paid, actor: { parent: parent }, input { identity: text }\n set: { payoffIdentity: { field: input.identity } }\n calculate: [{ target: payoffRebate, op: rate, base: { field: self.profitReceivable.balance }, bps: { literal: payoff_rebate }, rounding: floor }, { target: payoffProfitTotal, op: sum, values: [{ field: self.profitReceivable.balance }, { field: self.profitEarned.balance }] }, { target: payoffProfit, op: subtract, base: { field: self.payoffProfitTotal }, subtract: [{ field: self.payoffRebate }] }]\n moves self.principalReceivable.balance from self.plan.borrower to self.plan.capital\n moves self.payoffProfit from self.plan.borrower to self.plan.profitIncome\n moves self.principalReceivable.balance from self.principalReceivable to self.debt\n moves self.profitReceivable.balance from self.profitReceivable to self.debt\n moves self.profitEarned.balance from self.profitEarned to self.debt\n }\n action write_off {\n from: [pending, due], to: written_off, actor: { parent: parent }\n moves self.principalReceivable.balance from self.principalReceivable to self.loss; moves self.profitReceivable.balance from self.profitReceivable to self.debt; moves self.profitEarned.balance from self.profitEarned to self.loss\n }\n }\n recognition: {\n fields { slice: ref<slice>, dueAt: date = after(self.slice.dueAt, 0) }\n lifecycle { states: [pending, recognised], initial: pending }\n action create { actor: { parent: slice }, input { slice: ref<slice> }, requires unique \"profit_recognition\" on [self.slice] }\n action reschedule { from: pending, to: pending, actor: { parent: slice } }\n action mature { from: pending, to: recognised, actor: clock, due: { at: self.dueAt }, moves self.slice.profitReceivable.balance from self.slice.profitReceivable to self.slice.profitEarned }\n }\n payment: {\n revisioned: true\n fields { plan: ref<parent>, amount: money, paymentIdentity: text, held: account of self\n capital: account(capital, cash, \"capital\"), profitIncome: account(profit_to, cash, \"profitIncome\"), loss: account(capital, claim, \"loss\")\n outstandingPrincipal: money?, outstandingProfit: money?, outstandingFines: money?, outstandingCosts: money?, outstandingTotal: money?, principalReturned: money?, profitReturned: money?, lossRecorded: money? }\n\n lifecycle { states: [pending, paid, refunded], initial: pending }\n action create { input { plan: ref<parent>, amount: money, paymentIdentity: text } requires self.plan in [active]; requires unique \"payment_identity\" on [self.plan, self.paymentIdentity] }\n // 366 slices * (1 + 3 fines * 3 + 3 costs * 3 + 2 pieces + 1 completion), plus recording.\n action pay {\n expansionLimit: 8192\n from: pending, to: paid\n calculate: [{ target: outstandingPrincipal, op: aggregate, selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending, due, paid], limit: 366, order: [position] }, measure: { sum: \"principalReceivable.balance\" } }]\n when profit_earned is on_payment { calculate: [{ target: outstandingProfit, op: aggregate, selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending, due, paid], limit: 366, order: [position] }, measure: { sum: \"profitReceivable.balance\" } }] }\n when profit_earned is by_schedule { calculate: [{ target: outstandingProfit, op: aggregate, selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending, due, paid], limit: 366, order: [position] }, measure: { sum: \"profitEarned.balance\" } }] }\n when profit_earned is at_disbursement { calculate: [{ target: outstandingProfit, op: aggregate, selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending, due, paid], limit: 366, order: [position] }, measure: { sum: \"profitEarned.balance\" } }] }\n when apply is fines_profit_principal {\n calculate: [{ target: outstandingFines, op: aggregate, selection: { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.plan, states: [assessed, collected], limit: 366, order: [overdueAt] }, measure: { sum: \"receivable.balance\" } }, { target: outstandingCosts, op: aggregate, selection: { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.plan, states: [assessed, collected], limit: 366, order: [overdueAt] }, measure: { sum: \"receivable.balance\" } }, { target: outstandingTotal, op: sum, values: [{ field: self.outstandingPrincipal }, { field: self.outstandingProfit }, { field: self.outstandingFines }, { field: self.outstandingCosts }] }]\n }\n when apply is principal_profit { calculate: [{ target: outstandingTotal, op: sum, values: [{ field: self.outstandingPrincipal }, { field: self.outstandingProfit }] }] }\n when apply is pro_rata { calculate: [{ target: outstandingTotal, op: sum, values: [{ field: self.outstandingPrincipal }, { field: self.outstandingProfit }] }] }\n requires self.plan in [active]; requires self.amount <= self.outstandingTotal\n moves self.amount from self.plan.borrower to self.held\n when apply is principal_profit {\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending, due], limit: 366, order: [position] }, action: collect, guard: { kind: compare, left: { field: self.held.balance }, operator: \">\", right: { literal: \"0\" } }, input: { payment: { field: self.id } } }]\n }\n when apply is fines_profit_principal {\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending, due], limit: 366, order: [position] }, action: collect_waterfall, guard: { kind: compare, left: { field: self.held.balance }, operator: \">\", right: { literal: \"0\" } }, input: { payment: { field: self.id } } }]\n }\n when apply is pro_rata {\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending, due], limit: 366, order: [position] }, action: collect_pro_rata, guard: { kind: compare, left: { field: self.held.balance }, operator: \">\", right: { literal: \"0\" } }, input: { payment: { field: self.id } } }]\n }\n invoke: [{ reference: self.id, action: record, input: {} }]\n }\n action record {\n from: paid, to: paid, actor: { parent: current() }\n requires self.held.balance == \"0\"\n calculate: [{ target: principalReturned, op: aggregate, selection: { instrument: principal_piece, reference: \"payment\", anchor: self.id, states: [paid], limit: 366 }, measure: { sum: \"amount\" } }, { target: profitReturned, op: aggregate, selection: { instrument: profit_piece, reference: \"payment\", anchor: self.id, states: [paid], limit: 366 }, measure: { sum: \"amount\" } }]\n invoke: [{ reference: self.plan, action: record_payment, input: { identity: { field: self.paymentIdentity }, principal: { field: self.principalReturned }, profit: { field: self.profitReturned } } }]\n }\n action refund {\n from: paid, to: refunded\n requires unique \"settlement_consumption\" on [self.plan, self.paymentIdentity]; requires self.plan in [active, paid]\n when apply is fines_profit_principal {\n invoke: [{ selection: { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.plan, states: [assessed, collected], limit: 366, order: [overdueAt] }, action: refund, input: { payment: { field: self.id } } }, { selection: { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.plan, states: [assessed, collected], limit: 366, order: [overdueAt] }, action: refund, input: { payment: { field: self.id } } }]\n }\n invoke: [{ reference: self.plan, action: restore, input: {} }, { selection: { instrument: slice, reference: \"plan\", anchor: self.plan, states: [pending, due, paid], limit: 366 }, action: restore, input: {} }, { selection: { instrument: principal_piece, reference: \"payment\", anchor: self.id, states: [paid], limit: 366 }, action: refund, input: {} }, { selection: { instrument: profit_piece, reference: \"payment\", anchor: self.id, states: [paid], limit: 366 }, action: refund, input: {} }]\n }\n }\n principal_piece: {\n fields { slice: ref<slice>, payment: ref<payment>, limit: money, amount: money? }\n lifecycle { states: [paid, refunded], initial: paid }\n action create {\n calculate: [{ target: amount, op: minimum, values: [{ field: self.payment.held.balance }, { field: self.slice.principalReceivable.balance }, { field: self.limit }] }]\n actor: { parent: slice }\n input { slice: ref<slice>, payment: ref<payment>, limit: money }\n requires unique \"principal_receipt\" on [self.slice, self.payment]\n moves self.amount from self.payment.held to self.slice.plan.capital; moves self.amount from self.slice.principalReceivable to self.slice.debt\n }\n action refund {\n from: paid, to: refunded, actor: { parent: payment }\n moves self.amount from self.slice.plan.capital to self.slice.plan.funds.payer; moves self.amount from self.slice.debt to self.slice.principalReceivable\n }\n }\n profit_piece: {\n fields { slice: ref<slice>, payment: ref<payment>, limit: money, amount: money? }\n lifecycle { states: [paid, refunded], initial: paid }\n action create {\n calculate: [{ target: amount, op: minimum, values: [{ field: self.payment.held.balance }, { field: self.limit }] }]\n actor: { parent: slice }\n input { slice: ref<slice>, payment: ref<payment>, limit: money }\n requires unique \"profit_receipt\" on [self.slice, self.payment]\n moves self.amount from self.payment.held to self.slice.plan.profitIncome\n when profit_earned is on_payment { moves self.amount from self.slice.profitReceivable to self.slice.debt }\n when profit_earned is by_schedule { moves self.amount from self.slice.profitEarned to self.slice.debt }\n when profit_earned is at_disbursement { moves self.amount from self.slice.profitEarned to self.slice.debt }\n }\n action refund {\n from: paid, to: refunded, actor: { parent: payment }\n moves self.amount from self.slice.plan.profitIncome to self.slice.plan.borrower\n when profit_earned is on_payment { moves self.amount from self.slice.debt to self.slice.profitReceivable }\n when profit_earned is by_schedule { moves self.amount from self.slice.debt to self.slice.profitEarned }\n when profit_earned is at_disbursement { moves self.amount from self.slice.debt to self.slice.profitEarned }\n }\n }\n }\n}\n\ninstrument late_charge(on: ref<financing.installments>[], grace: duration = 3d, fine: money = 50 SAR, cap: money = 25 SAR, fines_to: party = programOperator, costs_to: party = programOperator, approval: approval = programOperator, borrower: party = party(person)) {\n revisioned: true\n summary: \"Separate approved fine and evidenced recovery claims on an overdue installment.\"\n fields {\n plan: ref<on>, slice: ref<on.slice>, borrower: account of borrower, fine: money = fine, overdueAt: date?\n receivable: account(self, claim), debt: account(borrower, claim, contra, \"debt\")\n }\n lifecycle { states: [proposed, assessed, collected, waived, refunded], initial: proposed }\n action create { calculate: [{ target: overdueAt, op: shift, date: { field: self.slice.dueAt }, milliseconds: { literal: grace }, direction: after }], requires unique \"late_assessment\" on [self.slice, self.overdueAt]; requires self.borrower == self.slice.plan.borrower; requires self.plan == self.slice.plan }\n action assess {\n from: proposed, to: assessed, due: { at: self.overdueAt }\n requires self.slice.principalReceivable.balance > \"0\"; requires approval by approval\n moves self.fine from self.debt to self.receivable\n }\n action collect {\n from: [assessed, collected], to: assessed, input { payment: ref<on.payment> }\n requires input.payment in [paid]\n requires input.payment.plan == self.plan\n invoke: [{ instrument: receipt, action: create, input: { assessment: { field: self.id }, payment: { field: input.payment } } }, { selection: { instrument: current(), reference: \"plan\", anchor: self.plan, states: [assessed], limit: 1, where: { id: { field: self.id }, receivable.balance: { literal: \"0\" } } }, action: finish, input: {} }]\n }\n action payoff {\n from: [assessed, collected], to: collected\n requires self.plan in [paid]\n moves self.receivable.balance from self.plan.borrower to fines_to\n moves self.receivable.balance from self.receivable to self.debt\n }\n action finish { from: assessed, to: collected, actor: { parent: current() }, requires self.receivable.balance == \"0\" }\n action cancel { from: proposed, to: waived }\n action waive_for_amendment {\n from: [assessed, collected], to: assessed, actor: { parent: child(on, amendment) }, input { amendment: ref<on.amendment> }\n requires input.amendment.plan == self.plan; requires input.amendment in [applied]\n invoke: [{ instrument: waiver, action: create, input: { assessment: { field: self.id }, amendment: { field: input.amendment } } }]\n }\n action waive { from: [assessed, collected], to: waived, input { reason: text, evidence: text }, requires approval by approval, moves self.receivable.balance from self.receivable to self.debt }\n action refund {\n from: [assessed, collected], to: assessed, input { payment: ref<on.payment> }\n requires input.payment in [paid, refunded]\n requires input.payment.plan == self.plan\n invoke: [{ selection: { instrument: receipt, reference: \"payment\", anchor: input.payment, states: [paid], limit: 1, where: { assessment: { field: self.id } } }, action: refund, input: {} }, { selection: { instrument: current(), reference: \"plan\", anchor: self.plan, states: [assessed], limit: 1, where: { id: { field: self.id }, receivable.balance: { literal: \"0\" } } }, action: finish, input: {} }]\n }\n records {\n waiver: {\n fields { assessment: ref<parent>, amendment: ref<on.amendment>, amount: money? }\n lifecycle { states: [recorded], initial: recorded }\n action create {\n actor: { parent: parent }, input { assessment: ref<parent>, amendment: ref<on.amendment> }\n calculate: [{ target: amount, op: rate, base: { field: self.assessment.receivable.balance }, bps: { field: self.amendment.waiverPercent }, rounding: floor }]\n requires unique \"amendment_waiver\" on [self.assessment, self.amendment]\n moves self.amount from self.assessment.receivable to self.assessment.debt\n }\n }\n receipt: {\n fields { assessment: ref<parent>, payment: ref<on.payment>, amount: money? }\n lifecycle { states: [paid, refunded], initial: paid }\n action create { calculate: [{ target: amount, op: minimum, values: [{ field: self.payment.held.balance }, { field: self.assessment.receivable.balance }] }], actor: { parent: parent }, input { assessment: ref<parent>, payment: ref<on.payment> }, requires input.payment.plan == self.assessment.plan; requires unique \"fine_receipt\" on [self.assessment, self.payment]; moves self.amount from self.payment.held to fines_to; moves self.amount from self.assessment.receivable to self.assessment.debt }\n action refund { from: paid, to: refunded, actor: { parent: parent }, moves self.amount from fines_to to self.payment.plan.borrower; moves self.amount from self.assessment.debt to self.assessment.receivable }\n }\n\n cost: {\n revisioned: true\n fields {\n plan: ref<on>, assessment: ref<parent>, overdueAt: date?, evidence: text, evidencedCost: money, amount: money = minimum(self.evidencedCost, cap)\n receivable: account(self, claim), debt: account(borrower, claim, contra, \"debt\")\n }\n lifecycle { states: [proposed, assessed, collected, waived, refunded], initial: proposed }\n action create { calculate: [{ target: overdueAt, op: shift, date: { field: self.assessment.overdueAt }, milliseconds: { literal: 0 }, direction: after }], requires unique \"recovery_assessment\" on [self.assessment]; requires self.plan == self.assessment.plan }\n action assess {\n from: proposed, to: assessed, due: { at: self.assessment.overdueAt }\n requires self.assessment.slice.principalReceivable.balance > \"0\"; requires approval by approval\n moves self.amount from self.debt to self.receivable\n }\n action collect {\n from: [assessed, collected], to: assessed, input { payment: ref<on.payment> }\n requires input.payment in [paid]\n requires input.payment.plan == self.plan\n invoke: [{ instrument: receipt, action: create, input: { assessment: { field: self.id }, payment: { field: input.payment } } }, { selection: { instrument: current(), reference: \"plan\", anchor: self.plan, states: [assessed], limit: 1, where: { id: { field: self.id }, receivable.balance: { literal: \"0\" } } }, action: finish, input: {} }]\n }\n action payoff {\n from: [assessed, collected], to: collected\n requires self.plan in [paid]\n moves self.receivable.balance from self.plan.borrower to costs_to\n moves self.receivable.balance from self.receivable to self.debt\n }\n action finish { from: assessed, to: collected, actor: { parent: current() }, requires self.receivable.balance == \"0\" }\n action cancel { from: proposed, to: waived }\n action waive_for_amendment {\n from: [assessed, collected], to: assessed, actor: { parent: child(on, amendment) }, input { amendment: ref<on.amendment> }\n requires input.amendment.plan == self.plan; requires input.amendment in [applied]\n invoke: [{ instrument: waiver, action: create, input: { assessment: { field: self.id }, amendment: { field: input.amendment } } }]\n }\n action waive { from: [assessed, collected], to: waived, input { reason: text, evidence: text }, requires approval by approval, moves self.receivable.balance from self.receivable to self.debt }\n action refund {\n from: [assessed, collected], to: assessed, input { payment: ref<on.payment> }\n requires input.payment in [paid, refunded]\n requires input.payment.plan == self.plan\n invoke: [{ selection: { instrument: receipt, reference: \"payment\", anchor: input.payment, states: [paid], limit: 1, where: { assessment: { field: self.id } } }, action: refund, input: {} }, { selection: { instrument: current(), reference: \"plan\", anchor: self.plan, states: [assessed], limit: 1, where: { id: { field: self.id }, receivable.balance: { literal: \"0\" } } }, action: finish, input: {} }]\n }\n records {\n waiver: {\n fields { assessment: ref<parent>, amendment: ref<on.amendment>, amount: money? }\n lifecycle { states: [recorded], initial: recorded }\n action create {\n actor: { parent: parent }, input { assessment: ref<parent>, amendment: ref<on.amendment> }\n calculate: [{ target: amount, op: rate, base: { field: self.assessment.receivable.balance }, bps: { field: self.amendment.waiverPercent }, rounding: floor }]\n requires unique \"amendment_waiver\" on [self.assessment, self.amendment]\n moves self.amount from self.assessment.receivable to self.assessment.debt\n }\n }\n receipt: {\n fields { assessment: ref<parent>, payment: ref<on.payment>, amount: money? }\n lifecycle { states: [paid, refunded], initial: paid }\n action create { calculate: [{ target: amount, op: minimum, values: [{ field: self.payment.held.balance }, { field: self.assessment.receivable.balance }] }], actor: { parent: parent }, input { assessment: ref<parent>, payment: ref<on.payment> }, requires input.payment.plan == self.assessment.plan; requires unique \"cost_receipt\" on [self.assessment, self.payment]; moves self.amount from self.payment.held to costs_to; moves self.amount from self.assessment.receivable to self.assessment.debt }\n action refund { from: paid, to: refunded, actor: { parent: parent }, moves self.amount from costs_to to self.payment.plan.borrower; moves self.amount from self.assessment.debt to self.assessment.receivable }\n }\n }\n }\n }\n}\n\ninstrument limits(per_borrower: money, portfolio: money, borrower: party = party(person), active_plans: integer = 1) {\n summary: \"One borrower ceiling and one shared portfolio ceiling.\"\n fields { borrower: account of borrower, limit: money = per_borrower, activePlans: integer = active_plans }\n lifecycle { states: [pending, approved], initial: pending }\n action create { requires unique \"borrower_limit\" on [self.borrower] }\n action approve { from: pending, to: approved }\n records {\n portfolio: {\n fields { key: text = \"portfolio\", limit: money = portfolio }\n lifecycle { states: [pending, approved], initial: pending }\n action create { requires unique \"portfolio_limit\" on [self.key] }\n action approve { from: pending, to: approved }\n }\n }\n}\n\ninstrument credit_line(borrower: party, lender: party, limit: money, expires: date) {\n summary: \"A revolving facility; each draw is a separate immutable advance.\"\n fields { borrower: account of borrower, lender: account of lender, debt: account(borrower, claim, contra, \"debt\"), limit: money = limit, expiresAt: date = expires }\n lifecycle { states: [pending, active, suspended, closed], initial: pending }\n action create {}\n action activate { from: pending, to: active, actor: { party: lender } }\n action suspend { from: active, to: suspended, actor: { party: lender } }\n action resume { from: suspended, to: active, actor: { party: lender } }\n action close { from: [active, suspended], to: closed, due: { at: self.expiresAt }, requires count of { instrument: all(financing.advance), reference: \"line\", anchor: self.id, states: [drawn], limit: 366 } == 0 }\n}\n\ninstrument advance(line: ref<financing.credit_line>, amount: money = runtime) {\n summary: \"A single facility draw with an immutable principal and full repayment.\"\n fields { line: ref<line>, amount: money = amount, principalReceivable: account(self, claim) }\n lifecycle { states: [pending, drawn, repaid, cancelled], initial: pending }\n action create { requires self.amount <= self.line.limit }\n invariants sum \"principalReceivable.balance\" of { instrument: all(financing.advance), reference: \"line\", anchor: self.line, states: [drawn], limit: 366 } <= self.line.limit\n action draw {\n from: pending, to: drawn\n requires self.line in [active]\n deadline: { at: self.line.expiresAt }\n moves self.amount from self.line.lender to self.line.borrower; moves self.amount from self.line.debt to self.principalReceivable\n }\n action repay { from: drawn, to: repaid, moves self.amount from self.line.borrower to self.line.lender; moves self.amount from self.principalReceivable to self.line.debt }\n action cancel { from: pending, to: cancelled }\n}\n"],
8
8
  ["insurance.hsx", "header insurance\n\ninstrument cover(holder: party, insurer: party, commission: percent = 0%, covers: ref, premium: money = runtime) {\n summary: \"Recurring cover with separate premium slices and commission clawback.\"\n fields { covers: ref<covers>, holder: account of holder, insurer: account of insurer, expiresAt: date }\n lifecycle { states: [pending, active, cancelled, expired], initial: pending }\n action create {}\n action activate { from: pending, to: active, actor: { party: insurer } }\n action cancel {\n from: active, to: cancelled\n invoke: [{ selection: { instrument: slice, reference: \"cover\", anchor: self.id, states: [paid], limit: 366 }, action: refund, input: {} }]\n }\n action expire { from: active, to: expired, actor: clock, due: { at: self.expiresAt } }\n records {\n slice: {\n summary: \"A whole premium period, collected once and refundable only before it starts.\"\n fields {\n cover: ref<parent>, covers: ref<covers>, premium: money = premium, startsAt: date, endsAt: date\n commission: money = rate(self.premium, commission)\n carrierNet: money = subtract(self.premium, self.commission)\n }\n lifecycle { states: [pending, paid, active, expired, refunded], initial: pending }\n action create {\n requires self.covers == self.cover.covers\n requires self.startsAt < self.endsAt\n requires unique \"premium_period\" on [self.cover, self.startsAt, self.endsAt]\n }\n action collect {\n from: pending, to: paid\n requires self.cover in [active]\n moves self.premium from holder to insurer\n moves self.commission from insurer to programOperator\n }\n action start { from: paid, to: active, actor: clock, due: { at: self.startsAt } }\n action expire { from: active, to: expired, actor: clock, due: { at: self.endsAt } }\n action refund {\n from: paid, to: refunded, deadline: { at: self.startsAt }\n moves self.commission from programOperator to insurer\n moves self.premium from insurer to holder\n }\n }\n }\n}\n\ninstrument claim(cover: ref<insurance.cover>, approved_by: approval) {\n summary: \"A carrier decision reserves one claim payment before settlement.\"\n fields { cover: ref<cover>, amount: money, expiresAt: date, evidence: text, reservation: text? }\n lifecycle { states: [submitted, approved, paid, denied, expired], initial: submitted }\n action create { requires self.cover in [active] }\n action approve {\n from: submitted, to: approved, actor: { party: approved_by }\n requires approval by approved_by\n deadline: { at: self.expiresAt }\n moves reserve self.amount from self.cover.insurer to self.cover.holder capture \"reservation\"\n }\n action pay { from: approved, to: paid, deadline: { at: self.expiresAt }, moves post self.reservation }\n action deny { from: submitted, to: denied, requires approval by approved_by for approve is \"declined\" }\n action expire { from: approved, to: expired, actor: clock, due: { at: self.expiresAt }, moves void self.reservation }\n}\n"],
9
9
  ["lending.hsx", "header lending\n\ninstrument round(borrower: party, capital: party, plan: ref<financing.installments> = object(financing.installments), months: integer(1, 366) = 3, profit: percent = 3%, minimum_ticket: money = 100 SAR, investor_cap: percent = 20%, commitments: ref<lending.commitment> = object(lending.commitment)) {\n summary: \"A threshold funding round; failed rounds return each original wallet contribution.\"\n fields {\n borrower: account of borrower, capital: account(capital, cash, \"capital\"), plan: ref<plan>, price: money, closesAt: date\n months: integer = months, profit: money = rate(self.price, profit)\n minimumTicket: money = minimum_ticket, maximumTicket: money = rate(self.price, investor_cap)\n held: account of self\n }\n lifecycle { states: [open, funded, failed], initial: open }\n action create { requires unique \"funding_plan\" on [self.plan]; requires self.months == self.plan.months; requires self.profit == self.plan.profit; requires self.price == self.plan.principal; requires self.borrower == self.plan.funds.payer }\n action close {\n from: open, to: funded\n requires sum \"amount\" of { instrument: commitments, reference: \"round\", anchor: self.id, states: [committed], limit: 366 } == self.price\n requires self.held.balance == self.price\n moves self.price from self.held to self.plan.capital\n invoke: [{ selection: { instrument: commitments, reference: \"round\", anchor: self.id, states: [committed], limit: 366 }, action: fund, input: {} }]\n }\n action fail {\n from: open, to: failed, actor: clock, due: { at: self.closesAt }\n requires self.held.balance < self.price\n invoke: [{ selection: { instrument: commitments, reference: \"round\", anchor: self.id, states: [committed], limit: 366 }, action: refund, input: {} }]\n }\n}\n\ninstrument commitment(round: ref<lending.round>, wallet: ref<wallet.balance>, investor: party = party(person)) {\n summary: \"One investor's original-wallet contribution, capped cumulatively within the round.\"\n fields { round: ref<round>, wallet: ref<wallet>, amount: money, loss: account(investor, claim, \"loss\") }\n lifecycle { states: [committed, funded, withdrawn, refunded], initial: committed }\n invariants sum \"amount\" of { instrument: all(lending.commitment), reference: \"round\", anchor: self.round, states: [committed, funded], limit: 366, where: { wallet: { field: self.wallet } } } <= self.round.maximumTicket\n invariants sum \"amount\" of { instrument: all(lending.commitment), reference: \"round\", anchor: self.round, states: [committed, funded], limit: 366 } <= self.round.price\n action create {\n requires self.round in [open]\n requires self.wallet in [active]\n requires self.amount >= self.round.minimumTicket\n deadline: { at: self.round.closesAt }\n moves self.amount from self.wallet.held to self.round.held\n }\n action fund { from: committed, to: funded, actor: { parent: round } }\n action withdraw {\n from: committed, to: withdrawn\n requires self.round in [open]\n deadline: { at: self.round.closesAt }\n moves self.amount from self.round.held to self.wallet.held\n }\n action refund {\n from: committed, to: refunded, actor: { parent: round }\n moves self.amount from self.round.held to self.wallet.held\n }\n}\n\ninstrument distribution(round: ref<lending.round>, receipt: ref, commitments: ref<lending.commitment> = object(lending.commitment), mode: enum(cash, loss) = cash, residual_to: party = programOperator, fee: percent = 1%, tax: percent = 15%) {\n summary: \"Frozen weighted shares, floored once, with residual assigned to the chosen party.\"\n fields {\n round: ref<round>, source: ref<receipt>, mode: enum(cash, loss) = mode\n principal: money?, profit: money?, grossTotal: money?, charge: money?, vat: money?, net: money?\n held: account of self, losses: account(self, claim), residualLoss: account(residual_to, claim, \"loss\")\n }\n lifecycle { states: [pending, cash_ready, loss_ready, distributed], initial: pending }\n action create { requires self.round in [funded]; requires self.source.plan == self.round.plan; requires unique \"settlement_consumption\" on [self.source.plan, self.source.identity] }\n action prepare_cash {\n from: pending, to: cash_ready\n requires self.mode == \"cash\"; requires self.source.kind == \"cash\"\n calculate: [\n { target: \"principal\", op: \"sum\", values: [{ field: self.source.principal }] }\n { target: \"profit\", op: \"sum\", values: [{ field: self.source.profit }] }\n { target: \"charge\", op: \"rate\", base: { field: self.profit }, bps: { literal: fee }, rounding: \"floor\" }\n { target: \"vat\", op: \"rate\", base: { field: self.charge }, bps: { literal: tax }, rounding: \"floor\" }\n { target: \"grossTotal\", op: \"sum\", values: [{ field: self.principal }, { field: self.profit }] }\n { target: \"net\", op: \"subtract\", base: { field: self.grossTotal }, subtract: [{ field: self.charge }, { field: self.vat }] }\n ]\n }\n action prepare_loss {\n from: pending, to: loss_ready\n requires self.mode == \"loss\"; requires self.source.kind == \"loss\"\n calculate: [{ target: \"net\", op: \"sum\", values: [{ field: self.source.loss }] }]\n }\n action distribute_cash {\n from: cash_ready, to: distributed\n requires sum \"weight\" of { instrument: share, reference: \"distribution\", anchor: self.id, states: [pending], limit: 366 } == self.round.price\n moves self.principal from self.source.capital to self.held; moves self.profit from self.source.profitIncome to self.held; moves self.charge from self.held to programOperator; moves self.vat from self.held to programTax\n invoke: [{ selection: { instrument: share, reference: \"distribution\", anchor: self.id, states: [pending], limit: 366 }, action: cash, input: {} }, { reference: self.id, action: residual_cash, input: {} }]\n }\n action residual_cash {\n from: distributed, to: distributed, actor: { parent: current() }\n moves self.held.balance from self.held to residual_to\n }\n action distribute_loss {\n from: loss_ready, to: distributed\n requires sum \"weight\" of { instrument: share, reference: \"distribution\", anchor: self.id, states: [pending], limit: 366 } == self.round.price\n moves self.net from self.source.lossAccount to self.losses\n invoke: [{ selection: { instrument: share, reference: \"distribution\", anchor: self.id, states: [pending], limit: 366 }, action: loss, input: {} }, { reference: self.id, action: residual_loss, input: {} }]\n }\n action residual_loss {\n from: distributed, to: distributed, actor: { parent: current() }\n moves self.losses.balance from self.losses to self.residualLoss\n }\n records {\n share: {\n fields {\n distribution: ref<parent>, commitment: ref<commitments>\n weight: money = self.commitment.amount\n gross: money = ratio(self.distribution.net, self.weight, self.distribution.round.price)\n }\n lifecycle { states: [pending, paid], initial: pending }\n action create { requires self.distribution in [cash_ready, loss_ready]; requires self.commitment in [funded]; requires unique \"distribution_weight\" on [self.distribution, self.commitment]; requires self.commitment.round == self.distribution.round }\n action cash {\n from: pending, to: paid, actor: { parent: parent }\n moves self.gross from self.distribution.held to self.commitment.wallet.held\n }\n action loss { from: pending, to: paid, actor: { parent: parent }, moves self.gross from self.distribution.losses to self.commitment.loss }\n }\n }\n}\n"],
10
- ["marketplace.hsx", "header marketplace\n\ninstrument listing(seller: party) {\n summary: \"A seller's offer and its asking price.\"\n fields { seller: account of seller, title: text, price: money }\n lifecycle { states: [draft, active, withdrawn, sold], initial: draft }\n action create { actor: { party: seller } }\n action publish { from: draft, to: active, actor: { party: seller } }\n action withdraw { from: active, to: withdrawn, actor: { party: seller } }\n action sell { from: active, to: sold, actor: { party: seller } }\n}\n\ninstrument order(listing: ref<marketplace.listing>, buyer: party) {\n summary: \"A buyer's order for one listing at its declared price.\"\n fields { listing: ref<listing>, buyer: account of buyer, price: money }\n lifecycle { states: [placed, fulfilled, cancelled], initial: placed }\n action create {\n actor: { party: buyer }\n requires self.listing in [active]\n requires self.price == self.listing.price\n }\n action fulfill { from: placed, to: fulfilled }\n action cancel { from: placed, to: cancelled, actor: { party: buyer } }\n}\n"],
11
- ["money.hsx", "header money\n\ninstrument transfer(payer: party, payee: party, amount: money = runtime) {\n summary: \"One transfer between the bound parties.\"\n fields { amount: money = amount }\n lifecycle { states: [pending, paid, cancelled], initial: pending }\n action create { actor: { party: payer } }\n action pay {\n from: pending, to: paid, actor: { party: payer }\n moves self.amount from payer to payee\n }\n action cancel { from: pending, to: cancelled, actor: { party: payer } }\n}\n\ninstrument hold(payer: party, payee: party, amount: money = runtime) {\n summary: \"Hold the declared amount until release or refund.\"\n fields { payer: account of payer, payee: account of payee, amount: money = amount, price: money = self.amount, held: account of self }\n lifecycle { states: [pending, funded, released, refunded, cancelled], initial: pending }\n action create { }\n action fund {\n from: pending, to: funded, actor: { party: payer }\n moves self.amount from payer to self.held\n }\n action confirm {\n from: pending, to: funded\n requires self.held.balance == self.amount\n }\n action release {\n from: funded, to: released\n moves self.amount from self.held to payee\n }\n action refund {\n from: funded, to: refunded\n moves self.amount from self.held to payer\n }\n action cancel { from: pending, to: cancelled }\n}\n\ninstrument split(payer: party, amount: money = runtime, shares: split = { programOperator: 100% }) {\n summary: \"Split one amount; the last declared recipient receives the rounding remainder.\"\n fields { amount: money = amount }\n lifecycle { states: [pending, paid, cancelled], initial: pending }\n action create {}\n action pay { from: pending, to: paid, moves self.amount from payer shares shares }\n action cancel { from: pending, to: cancelled }\n}\n\ninstrument schedule(payer: party, payee: party, amount: money = runtime, count: integer(1, 366) = 12) {\n summary: \"A finite schedule whose dated pieces sum exactly to the declared total.\"\n fields { amount: money = amount, count: integer = count, dates: list(date, count) }\n lifecycle { states: [draft, active, complete, cancelled], initial: draft }\n action create {}\n action activate {\n from: draft, to: active\n requires count of { instrument: occurrence, reference: \"schedule\", anchor: self.id, states: [pending], limit: 366 } == self.count\n }\n action complete {\n from: active, to: complete\n requires count of { instrument: occurrence, reference: \"schedule\", anchor: self.id, states: [pending], limit: 366 } == 0\n }\n action cancel { from: [draft, active], to: cancelled }\n records {\n occurrence: {\n fields {\n schedule: ref<parent>, position: integer(1, count), dueAt: date = at(self.schedule.dates, self.position)\n base: money = divide(self.schedule.amount, count)\n allocated: money = multiply(self.base, count)\n remainder: money = subtract(self.schedule.amount, self.allocated)\n first: integer = divide(1, self.position)\n adjustment: money = multiply(self.remainder, self.first)\n amount: money = sum(self.base, self.adjustment)\n }\n lifecycle { states: [pending, paid, cancelled], initial: pending }\n action create { requires self.schedule in [draft]; requires unique \"scheduled_position\" on [self.schedule, self.position] }\n action pay { from: pending, to: paid, actor: clock, due: { at: self.dueAt }, requires self.schedule in [active], moves self.amount from payer to payee }\n action cancel { from: pending, to: cancelled, requires self.schedule in [cancelled] }\n }\n }\n}\n\ninstrument pool(payer: party, payee: party, target: money, closes: date) {\n summary: \"Contributions fund one threshold or return to their original contributor.\"\n fields { target: money = target, closesAt: date = closes, held: account of self }\n lifecycle { states: [open, paid, failed], initial: open }\n action create { }\n action pay {\n from: open, to: paid\n requires self.held.balance == self.target\n moves self.target from self.held to payee\n }\n action fail {\n from: open, to: failed, actor: clock, due: { at: self.closesAt }\n requires self.held.balance < self.target\n invoke: [{ selection: { instrument: contribution, reference: \"pool\", anchor: self.id, states: [paid], limit: 366 }, action: refund, input: {} }]\n }\n records {\n contribution: {\n fields { pool: ref<parent>, payer: account of payer, amount: money }\n lifecycle { states: [pending, paid, refunded], initial: pending }\n action create { requires self.pool in [open] }\n action pay { from: pending, to: paid, deadline: { at: self.pool.closesAt }, requires self.pool in [open], moves self.amount from self.payer to self.pool.held }\n action refund { from: paid, to: refunded, actor: { parent: parent }, moves self.amount from self.pool.held to self.payer }\n }\n }\n}\n\ninstrument swap(first: party, second: party, first_amount: money, second_amount: money, expires: date) {\n summary: \"Two reservations settle together or both return.\"\n fields { firstAmount: money = first_amount, secondAmount: money = second_amount, expiresAt: date = expires, firstReceipt: text?, secondReceipt: text? }\n lifecycle { states: [pending, first_ready, second_ready, both_ready, exchanged, cancelled], initial: pending }\n action create {}\n action fund_first { from: pending, to: first_ready, actor: { party: first }, deadline: { at: self.expiresAt }, moves reserve self.firstAmount from first to second capture \"firstReceipt\" }\n action fund_second { from: first_ready, to: both_ready, actor: { party: second }, deadline: { at: self.expiresAt }, moves reserve self.secondAmount from second to first capture \"secondReceipt\" }\n action start_second { from: pending, to: second_ready, actor: { party: second }, deadline: { at: self.expiresAt }, moves reserve self.secondAmount from second to first capture \"secondReceipt\" }\n action finish_first { from: second_ready, to: both_ready, actor: { party: first }, deadline: { at: self.expiresAt }, moves reserve self.firstAmount from first to second capture \"firstReceipt\" }\n action expire_second { from: second_ready, to: cancelled, actor: clock, due: { at: self.expiresAt }, moves void self.secondReceipt }\n action exchange { from: both_ready, to: exchanged, moves post self.firstReceipt; moves post self.secondReceipt }\n action cancel { from: pending, to: cancelled }\n action expire_first { from: first_ready, to: cancelled, actor: clock, due: { at: self.expiresAt }, moves void self.firstReceipt }\n action expire_both { from: both_ready, to: cancelled, actor: clock, due: { at: self.expiresAt }, moves void self.firstReceipt; moves void self.secondReceipt }\n}\n\ninstrument deposit(payer: party, payee: party, amount: money, expires: date, approval: approval) {\n fields { amount: money = amount, expiresAt: date = expires, reservation: text? }\n lifecycle { states: [pending, held, claimed, returned, cancelled], initial: pending }\n action create {}\n action fund { from: pending, to: held, actor: { party: payer }, moves reserve self.amount from payer to payee capture \"reservation\" }\n action claim { from: held, to: claimed, deadline: { at: self.expiresAt }, requires approval by approval, moves post self.reservation }\n action return { from: held, to: returned, actor: clock, due: { at: self.expiresAt }, moves void self.reservation }\n action cancel { from: pending, to: cancelled }\n}\n\ninstrument payout(payer: party, payee: party, amount: money = runtime, reconcile_within: duration = 3d) {\n summary: \"A bank-linked transfer with confirmation bound to its captured identity.\"\n fields { amount: money = amount, bank: account(payee, cash, external, \"bank\"), receipt: text?, expectedAt: date = after(self.createdAt, reconcile_within) }\n lifecycle { states: [pending, instructed, settled, exception, reversed], initial: pending }\n action create {}\n action instruct { from: pending, to: instructed, actor: { party: payer }, moves self.amount from payer to self.bank capture \"receipt\" }\n action confirm {\n from: [instructed, exception], to: settled\n requires self.receipt.status == \"settled\"\n }\n action expire {\n from: instructed, to: exception, actor: clock, due: { at: self.expectedAt }\n requires self.receipt.status != \"settled\"\n }\n action reverse {\n from: [instructed, exception], to: reversed\n requires self.receipt.status == \"reversed\"\n }\n}\n\ninstrument metered(payer: party, payee: party, unit_price: money, units: integer = 1, fee: fee = { seller: 0% }) {\n summary: \"A unique usage event priced once at the fixed unit price.\"\n fields { usageIdentity: text, unitPrice: money = unit_price, units: integer = units, amount: money = multiply(self.unitPrice, self.units) }\n lifecycle { states: [recorded, billed, cancelled], initial: recorded }\n action create { requires unique \"usage_event\" on [self.usageIdentity] }\n action bill { from: recorded, to: billed, moves self.amount from payer to payee fee fee }\n action cancel { from: recorded, to: cancelled }\n}\n\ninstrument batch(payer: party, payee: party, closes: date, approval: approval, reconcile_within: duration = 3d) {\n summary: \"A frozen positive net of credit and debit entries, paid once.\"\n fields { closesAt: date = closes, credits: money, debits: money, amount: money = subtract(self.credits, self.debits), bank: account(payee, cash, external, \"bank\"), receipt: text?, instructedAt: date?, expectedAt: date? }\n lifecycle { states: [open, closed, approved, instructed, exception, paid, reversed], initial: open }\n action create {}\n action close {\n from: open, to: closed, actor: clock, due: { at: self.closesAt }\n requires sum \"amount\" of { instrument: credit, reference: \"batch\", anchor: self.id, states: [recorded], limit: 366 } == self.credits\n requires sum \"amount\" of { instrument: debit, reference: \"batch\", anchor: self.id, states: [recorded], limit: 366 } == self.debits\n requires self.amount > \"0\"\n }\n action approve { from: closed, to: approved, requires approval by approval }\n action pay {\n from: approved, to: instructed\n set: { instructedAt: { field: self.now } }\n calculate: [{ target: \"expectedAt\", op: \"shift\", date: { field: self.now }, milliseconds: { literal: reconcile_within }, direction: \"after\" }]\n moves self.amount from payer to self.bank capture \"receipt\"\n }\n action confirm { from: [instructed, exception], to: paid, requires self.receipt.status == \"settled\" }\n action expire { from: instructed, to: exception, actor: clock, due: { at: self.expectedAt }, requires self.receipt.status != \"settled\" }\n action reverse { from: [instructed, exception], to: reversed, requires self.receipt.status == \"reversed\" }\n records {\n credit: {\n fields { batch: ref<parent>, identity: text, amount: money }\n lifecycle { states: [recorded], initial: recorded }\n action create { requires self.batch in [open]; requires unique \"batch_credit\" on [self.identity] }\n }\n debit: {\n fields { batch: ref<parent>, identity: text, amount: money }\n lifecycle { states: [recorded], initial: recorded }\n action create { requires self.batch in [open]; requires unique \"batch_debit\" on [self.identity] }\n }\n }\n}\n"],
10
+ ["marketplace.hsx", "header marketplace\n\ninstrument listing(seller: party, vehicle_facts: enum(optional, required) = optional) {\n revisioned: true\n summary: \"A seller's offer and its asking price.\"\n fields { seller: account of seller, title: text, price: money }\n lifecycle { states: [draft, active, withdrawn, sold], initial: draft }\n action create { actor: { party: seller } }\n action publish {\n from: draft, to: active, actor: { party: seller }\n when vehicle_facts is required { requires count of { instrument: all(vehicles.vehicle), reference: \"listing\", anchor: self.id, states: [draft], limit: 1 } == 1 }\n invoke: [{ selection: { instrument: all(vehicles.vehicle), reference: \"listing\", anchor: self.id, states: [draft], limit: 1 }, action: publish, input: {} }]\n }\n action withdraw { from: active, to: withdrawn, actor: { party: seller }, requires count of { instrument: all(marketplace.reservation), reference: \"listing\", anchor: self.id, states: [active], limit: 366 } == 0 }\n action sell { from: active, to: sold, actor: { party: seller }, requires count of { instrument: all(marketplace.reservation), reference: \"listing\", anchor: self.id, states: [active], limit: 366 } == 0 }\n}\n\ninstrument order(listing: ref<marketplace.listing>, buyer: party) {\n revisioned: true\n summary: \"A buyer's order for one listing at its declared price.\"\n fields { listing: ref<listing>, buyer: account of buyer, price: money, reservations: integer?, ownReservations: integer?, blockingQuotes: integer?, ownBlockingQuotes: integer? }\n lifecycle { states: [quoted, placed, fulfilled, cancelled], initial: quoted }\n action create {\n actor: { party: buyer }\n requires self.listing in [active]\n calculate: [\n { target: blockingQuotes, op: aggregate, selection: { instrument: all(marketplace.reservation), reference: \"listing\", anchor: self.listing, states: [active], limit: 366, where: { quotePolicy: { literal: \"blocked\" } } }, measure: count }\n { target: ownBlockingQuotes, op: aggregate, selection: { instrument: all(marketplace.reservation), reference: \"listing\", anchor: self.listing, states: [active], limit: 366, where: { quotePolicy: { literal: \"blocked\" }, buyer: { field: self.buyer } } }, measure: count }\n ]\n requires self.blockingQuotes == self.ownBlockingQuotes\n requires self.price == self.listing.price\n }\n action commit {\n from: [quoted, placed], to: placed\n requires self.listing in [active]\n calculate: [\n { target: reservations, op: aggregate, selection: { instrument: all(marketplace.reservation), reference: \"listing\", anchor: self.listing, states: [active], limit: 366 }, measure: count }\n { target: ownReservations, op: aggregate, selection: { instrument: all(marketplace.reservation), reference: \"listing\", anchor: self.listing, states: [active], limit: 366, where: { buyer: { field: self.buyer } } }, measure: count }\n ]\n requires self.reservations == self.ownReservations\n requires count of { instrument: current(), reference: \"listing\", anchor: self.listing, states: [placed, fulfilled], limit: 366 } <= 1\n }\n invariants count of { instrument: current(), reference: \"listing\", anchor: self.listing, states: [placed, fulfilled], limit: 366 } <= 1\n action fulfill { from: placed, to: fulfilled }\n action cancel { from: [quoted, placed], to: cancelled, actor: { party: buyer } }\n}\n\ninstrument reservation(listing: ref<marketplace.listing>, funds: ref<escrow.hold>, plans: ref<financing.installments>[], converters: ref[], buyer: party, seller: party, expires_after: duration = 48h, deposit: money = 1000 SAR, cancellation_refund: percent = 100%, expiry_refund: percent = 100%, retained_to: party = programOperator, operator: party = programOperator, competing_quotes: enum(allowed, blocked) = allowed) {\n revisioned: true\n summary: \"Exclusive timed listing hold with explicit deposit credit and refund.\"\n fields {\n listing: ref<listing>, funds: ref<funds>, buyer: account of buyer, seller: account of seller, price: money, terms: text\n held: account of self, quotePolicy: enum(allowed, blocked) = competing_quotes, deposit: money = deposit, proposalExpiresAt: date = after(self.createdAt, expires_after), expiresAt: date?\n credit: money?, refund: money?, retained: money?, dispositionAt: date?, reason: text?\n }\n lifecycle { states: [proposed, active, converted, cancelled, expired], initial: proposed }\n invariants count of { instrument: current(), reference: \"listing\", anchor: self.listing, states: [active], limit: 366 } <= 1\n action create { actor: { party: buyer }, requires self.listing in [active]; requires self.seller == self.listing.seller; requires self.price == self.listing.price }\n action activate {\n from: proposed, to: active, actor: { party: buyer }, deadline: { at: self.proposalExpiresAt }\n calculate: [{ target: expiresAt, op: shift, date: { field: self.now }, milliseconds: { literal: expires_after }, direction: after }]\n requires self.listing in [active]; requires self.price == self.listing.price\n requires count of { instrument: all(marketplace.order), reference: \"listing\", anchor: self.listing, states: [placed, fulfilled], limit: 366 } == 0\n moves self.deposit from self.buyer to self.held\n }\n action convert_financed {\n from: active, to: active, actor: { party: buyer }, deadline: { at: self.expiresAt }\n input { plan: ref<plans> }\n requires input.plan.funds == self.funds; requires input.plan.borrower == self.buyer\n invoke: [{ reference: input.plan, action: disburse, input: {} }]\n }\n action convert_cash {\n from: active, to: active, actor: { party: buyer }, deadline: { at: self.expiresAt }\n invoke: [{ reference: self.funds, action: fund, input: {} }]\n }\n action credit {\n from: active, to: converted, actor: { parent: converters }, deadline: { at: self.expiresAt }\n input { funds: ref<funds>, contribution: money }\n requires input.funds == self.funds; requires input.funds in [pending, funded]; requires input.funds.order.listing == self.listing; requires input.funds.payer == self.buyer; requires input.funds.price == self.price\n requires input.contribution <= self.price\n calculate: [{ target: credit, op: minimum, values: [{ field: self.held.balance }, { field: input.contribution }] }, { target: refund, op: subtract, base: { field: self.held.balance }, subtract: [{ field: self.credit }] }]\n set: { dispositionAt: { field: self.now } }\n moves self.credit from self.held to input.funds.held\n moves self.refund from self.held to self.buyer\n invoke: [{ reference: input.funds.order, action: commit, input: {} }]\n }\n action cancel {\n from: active, to: cancelled, actor: { party: buyer }, input { reason: text }\n calculate: [{ target: refund, op: rate, base: { field: self.held.balance }, bps: { literal: cancellation_refund }, rounding: floor }, { target: retained, op: subtract, base: { field: self.held.balance }, subtract: [{ field: self.refund }] }]\n set: { reason: { field: input.reason }, dispositionAt: { field: self.now } }\n moves self.refund from self.held to self.buyer; moves self.retained from self.held to retained_to\n }\n action seller_cancel {\n from: active, to: cancelled, actor: { party: seller }, input { reason: text }\n set: { reason: { field: input.reason }, dispositionAt: { field: self.now } }\n moves self.held.balance from self.held to self.buyer\n }\n action operator_cancel {\n from: active, to: cancelled, actor: { party: operator }, input { reason: text }\n set: { reason: { field: input.reason }, dispositionAt: { field: self.now } }\n moves self.held.balance from self.held to self.buyer\n }\n action withdraw { from: proposed, to: cancelled, actor: { party: buyer } }\n action expire {\n from: active, to: expired, actor: clock, due: { at: self.expiresAt }\n calculate: [{ target: refund, op: rate, base: { field: self.held.balance }, bps: { literal: expiry_refund }, rounding: floor }, { target: retained, op: subtract, base: { field: self.held.balance }, subtract: [{ field: self.refund }] }]\n set: { dispositionAt: { field: self.now } }\n moves self.refund from self.held to self.buyer; moves self.retained from self.held to retained_to\n }\n action expire_proposal { from: proposed, to: expired, actor: clock, due: { at: self.proposalExpiresAt } }\n}\n"],
11
+ ["money.hsx", "header money\n\ninstrument transfer(payer: party, payee: party, amount: money = runtime) {\n summary: \"One transfer between the bound parties.\"\n fields { amount: money = amount }\n lifecycle { states: [pending, paid, cancelled], initial: pending }\n action create { actor: { party: payer } }\n action pay {\n from: pending, to: paid, actor: { party: payer }\n moves self.amount from payer to payee\n }\n action cancel { from: pending, to: cancelled, actor: { party: payer } }\n}\n\ninstrument hold(payer: party, payee: party, amount: money = runtime) {\n summary: \"Hold the declared amount until release or refund.\"\n fields { payer: account of payer, payee: account of payee, amount: money = amount, price: money = self.amount, held: account of self }\n lifecycle { states: [pending, funded, released, refunded, cancelled], initial: pending }\n action create { }\n action fund {\n from: pending, to: funded, actor: { party: payer }\n moves self.amount from payer to self.held\n }\n action confirm {\n from: pending, to: funded\n requires self.held.balance == self.amount\n }\n action release {\n from: funded, to: released\n moves self.amount from self.held to payee\n }\n action refund {\n from: funded, to: refunded\n moves self.amount from self.held to payer\n }\n action cancel { from: pending, to: cancelled }\n}\n\ninstrument split(payer: party, amount: money = runtime, shares: split = { programOperator: 100% }) {\n summary: \"Split one amount; the last declared recipient receives the rounding remainder.\"\n fields { amount: money = amount }\n lifecycle { states: [pending, paid, cancelled], initial: pending }\n action create {}\n action pay { from: pending, to: paid, moves self.amount from payer shares shares }\n action cancel { from: pending, to: cancelled }\n}\n\ninstrument schedule(payer: party, payee: party, amount: money = runtime, count: integer(1, 366) = 12) {\n summary: \"A finite schedule whose dated pieces sum exactly to the declared total.\"\n fields { amount: money = amount, count: integer = count, dates: list(date, count) }\n lifecycle { states: [draft, active, complete, cancelled], initial: draft }\n action create {}\n action activate {\n from: draft, to: active\n requires count of { instrument: occurrence, reference: \"schedule\", anchor: self.id, states: [pending], limit: 366 } == self.count\n }\n action complete {\n from: active, to: complete\n requires count of { instrument: occurrence, reference: \"schedule\", anchor: self.id, states: [pending], limit: 366 } == 0\n }\n action cancel { from: [draft, active], to: cancelled }\n records {\n occurrence: {\n fields {\n schedule: ref<parent>, position: integer(1, count), dueAt: date = at(self.schedule.dates, self.position)\n base: money = divide(self.schedule.amount, count)\n allocated: money = multiply(self.base, count)\n remainder: money = subtract(self.schedule.amount, self.allocated)\n first: integer = divide(1, self.position)\n adjustment: money = multiply(self.remainder, self.first)\n amount: money = sum(self.base, self.adjustment)\n }\n lifecycle { states: [pending, paid, cancelled], initial: pending }\n action create { requires self.schedule in [draft]; requires unique \"scheduled_position\" on [self.schedule, self.position] }\n action pay { from: pending, to: paid, actor: clock, due: { at: self.dueAt }, requires self.schedule in [active], moves self.amount from payer to payee }\n action cancel { from: pending, to: cancelled, requires self.schedule in [cancelled] }\n }\n }\n}\n\ninstrument pool(payer: party, payee: party, target: money, closes: date) {\n summary: \"Contributions fund one threshold or return to their original contributor.\"\n fields { target: money = target, closesAt: date = closes, held: account of self }\n lifecycle { states: [open, paid, failed], initial: open }\n action create { }\n action pay {\n from: open, to: paid\n requires self.held.balance == self.target\n moves self.target from self.held to payee\n }\n action fail {\n from: open, to: failed, actor: clock, due: { at: self.closesAt }\n requires self.held.balance < self.target\n invoke: [{ selection: { instrument: contribution, reference: \"pool\", anchor: self.id, states: [paid], limit: 366 }, action: refund, input: {} }]\n }\n records {\n contribution: {\n fields { pool: ref<parent>, payer: account of payer, amount: money }\n lifecycle { states: [pending, paid, refunded], initial: pending }\n action create { requires self.pool in [open] }\n action pay { from: pending, to: paid, deadline: { at: self.pool.closesAt }, requires self.pool in [open], moves self.amount from self.payer to self.pool.held }\n action refund { from: paid, to: refunded, actor: { parent: parent }, moves self.amount from self.pool.held to self.payer }\n }\n }\n}\n\ninstrument swap(first: party, second: party, first_amount: money, second_amount: money, expires: date) {\n summary: \"Two reservations settle together or both return.\"\n fields { firstAmount: money = first_amount, secondAmount: money = second_amount, expiresAt: date = expires, firstReceipt: text?, secondReceipt: text? }\n lifecycle { states: [pending, first_ready, second_ready, both_ready, exchanged, cancelled], initial: pending }\n action create {}\n action fund_first { from: pending, to: first_ready, actor: { party: first }, deadline: { at: self.expiresAt }, moves reserve self.firstAmount from first to second capture \"firstReceipt\" }\n action fund_second { from: first_ready, to: both_ready, actor: { party: second }, deadline: { at: self.expiresAt }, moves reserve self.secondAmount from second to first capture \"secondReceipt\" }\n action start_second { from: pending, to: second_ready, actor: { party: second }, deadline: { at: self.expiresAt }, moves reserve self.secondAmount from second to first capture \"secondReceipt\" }\n action finish_first { from: second_ready, to: both_ready, actor: { party: first }, deadline: { at: self.expiresAt }, moves reserve self.firstAmount from first to second capture \"firstReceipt\" }\n action expire_second { from: second_ready, to: cancelled, actor: clock, due: { at: self.expiresAt }, moves void self.secondReceipt }\n action exchange { from: both_ready, to: exchanged, moves post self.firstReceipt; moves post self.secondReceipt }\n action cancel { from: pending, to: cancelled }\n action expire_first { from: first_ready, to: cancelled, actor: clock, due: { at: self.expiresAt }, moves void self.firstReceipt }\n action expire_both { from: both_ready, to: cancelled, actor: clock, due: { at: self.expiresAt }, moves void self.firstReceipt; moves void self.secondReceipt }\n}\n\ninstrument deposit(payer: party, payee: party, amount: money, expires: date, approval: approval) {\n fields { amount: money = amount, expiresAt: date = expires, reservation: text? }\n lifecycle { states: [pending, held, claimed, returned, cancelled], initial: pending }\n action create {}\n action fund { from: pending, to: held, actor: { party: payer }, moves reserve self.amount from payer to payee capture \"reservation\" }\n action claim { from: held, to: claimed, deadline: { at: self.expiresAt }, requires approval by approval, moves post self.reservation }\n action return { from: held, to: returned, actor: clock, due: { at: self.expiresAt }, moves void self.reservation }\n action cancel { from: pending, to: cancelled }\n}\n\ninstrument payout(payer: party, payee: party, amount: money = runtime, reconcile_within: duration = 3d) {\n summary: \"A bank-linked transfer with confirmation bound to its captured identity.\"\n fields { amount: money = amount, bank: account(payee, cash, external, \"bank\"), receipt: text?, expectedAt: date = after(self.createdAt, reconcile_within) }\n lifecycle { states: [pending, instructed, settled, exception, reversed], initial: pending }\n action create {}\n action instruct { from: pending, to: instructed, actor: { party: payer }, humanApproval: \"distinct_member\", moves self.amount from payer to self.bank capture \"receipt\" }\n action confirm {\n from: [instructed, exception], to: settled\n requires self.receipt.status == \"settled\"\n }\n action expire {\n from: instructed, to: exception, actor: clock, due: { at: self.expectedAt }\n requires self.receipt.status != \"settled\"\n }\n action reverse {\n from: [instructed, exception], to: reversed\n requires self.receipt.status == \"reversed\"\n }\n}\n\ninstrument metered(payer: party, payee: party, unit_price: money, units: integer = 1, fee: fee = { seller: 0% }) {\n summary: \"A unique usage event priced once at the fixed unit price.\"\n fields { usageIdentity: text, unitPrice: money = unit_price, units: integer = units, amount: money = multiply(self.unitPrice, self.units) }\n lifecycle { states: [recorded, billed, cancelled], initial: recorded }\n action create { requires unique \"usage_event\" on [self.usageIdentity] }\n action bill { from: recorded, to: billed, moves self.amount from payer to payee fee fee }\n action cancel { from: recorded, to: cancelled }\n}\n\ninstrument batch(payer: party, payee: party, closes: date, approval: approval, reconcile_within: duration = 3d) {\n summary: \"A frozen positive net of credit and debit entries, paid once.\"\n fields { closesAt: date = closes, credits: money, debits: money, amount: money = subtract(self.credits, self.debits), bank: account(payee, cash, external, \"bank\"), receipt: text?, instructedAt: date?, expectedAt: date? }\n lifecycle { states: [open, closed, approved, instructed, exception, paid, reversed], initial: open }\n action create {}\n action close {\n from: open, to: closed, actor: clock, due: { at: self.closesAt }\n requires sum \"amount\" of { instrument: credit, reference: \"batch\", anchor: self.id, states: [recorded], limit: 366 } == self.credits\n requires sum \"amount\" of { instrument: debit, reference: \"batch\", anchor: self.id, states: [recorded], limit: 366 } == self.debits\n requires self.amount > \"0\"\n }\n action approve { from: closed, to: approved, requires approval by approval }\n action pay {\n from: approved, to: instructed\n set: { instructedAt: { field: self.now } }\n calculate: [{ target: \"expectedAt\", op: \"shift\", date: { field: self.now }, milliseconds: { literal: reconcile_within }, direction: \"after\" }]\n moves self.amount from payer to self.bank capture \"receipt\"\n }\n action confirm { from: [instructed, exception], to: paid, requires self.receipt.status == \"settled\" }\n action expire { from: instructed, to: exception, actor: clock, due: { at: self.expectedAt }, requires self.receipt.status != \"settled\" }\n action reverse { from: [instructed, exception], to: reversed, requires self.receipt.status == \"reversed\" }\n records {\n credit: {\n fields { batch: ref<parent>, identity: text, amount: money }\n lifecycle { states: [recorded], initial: recorded }\n action create { requires self.batch in [open]; requires unique \"batch_credit\" on [self.identity] }\n }\n debit: {\n fields { batch: ref<parent>, identity: text, amount: money }\n lifecycle { states: [recorded], initial: recorded }\n action create { requires self.batch in [open]; requires unique \"batch_debit\" on [self.identity] }\n }\n }\n}\n"],
12
+ ["reporting.hsx", "header reporting\n\ninstrument portfolio(on: ref<financing.installments>[], default_days: integer(1, 3650) = 90, retention_years: integer(1, 100) = 10, aging_first_days: integer(1, 3650) = 30, aging_second_days: integer(1, 3650) = 60, aging_third_days: integer(1, 3650) = 90, ratio_scale: integer(1, 1000000) = 10000, ratio_rounding: enum(floor, halfUp) = floor, lock_wait_ms: integer(1, 2000) = 2000, capture_ms: integer(1, 10000) = 10000, max_rows: integer(1, 100000) = 10000, max_join_rows: integer(1, 1000000) = 100000, max_bytes: integer(1024, 16777216) = 8388608) {\n summary: \"Declared financing reports evaluated over frozen Product facts.\"\n fields {}\n lifecycle { states: [declared], initial: declared }\n action create {}\n constraints { aging_first_days: less_than(aging_second_days), aging_second_days: less_than(aging_third_days) }\n reports: [\n {\n identity: { id: \"portfolio_aging\", version: 1, description: \"Period-end outstanding principal by oldest unpaid installment. Remaining scheduled profit is distinct from accrued profit. Restructuring evidence is unavailable.\" },\n scope: { kind: \"product\", classification: \"internal\", currency: \"SAR\" },\n datasets: [\n {\n id: \"facilities\",\n source: \"instrument\",\n instruments: on,\n rowKey: \"facilityId\",\n columns: [\n {\n name: \"facilityId\",\n field: \"id\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"borrowerAccount\",\n field: \"borrower\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"state\",\n field: \"status\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"originalPrincipal\",\n field: \"principal\",\n type: { kind: \"money\", currency: \"SAR\" },\n required: true\n },\n {\n name: \"scheduleCount\",\n field: \"months\",\n type: { kind: \"integer\" },\n required: true\n },\n {\n name: \"recordedCreation\",\n field: \"createdAt\",\n type: { kind: \"date\" },\n required: true\n }\n ],\n expressions: [\n {\n id: \"activeState\",\n op: \"literal\",\n type: { kind: \"text\" },\n value: \"active\"\n },\n {\n id: \"paidState\",\n op: \"literal\",\n type: { kind: \"text\" },\n value: \"paid\"\n },\n {\n id: \"writtenState\",\n op: \"literal\",\n type: { kind: \"text\" },\n value: \"written_off\"\n },\n { id: \"active\", op: \"equal\", left: \"state\", right: \"activeState\" },\n { id: \"paid\", op: \"equal\", left: \"state\", right: \"paidState\" },\n { id: \"writtenOff\", op: \"equal\", left: \"state\", right: \"writtenState\" },\n { id: \"activeOrPaid\", op: \"or\", left: \"active\", right: \"paid\" },\n { id: \"financed\", op: \"or\", left: \"active\", right: \"writtenOff\" }\n ],\n selection: \"active\"\n },\n {\n id: \"schedule\",\n source: \"instrument\",\n instruments: child(on, slice),\n rowKey: \"sliceId\",\n columns: [\n {\n name: \"sliceId\",\n field: \"id\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"planId\",\n field: \"plan\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"due\",\n field: \"dueAt\",\n type: { kind: \"date\" },\n required: true\n },\n {\n name: \"principal\",\n field: \"principalReceivable.balance\",\n type: { kind: \"money\", currency: \"SAR\" },\n required: true\n },\n {\n name: \"profit\",\n field: \"profitReceivable.balance\",\n type: { kind: \"money\", currency: \"SAR\" },\n required: true\n },\n {\n name: \"scheduledPrincipal\",\n field: \"principal\",\n type: { kind: \"money\", currency: \"SAR\" },\n required: true\n }\n ],\n expressions: [\n {\n id: \"zeroMoney\",\n op: \"literal\",\n type: { kind: \"money\", currency: \"SAR\" },\n value: \"0\"\n },\n {\n id: \"zeroDays\",\n op: \"literal\",\n type: { kind: \"integer\" },\n value: 0\n },\n { id: \"observed\", op: \"parameter\", name: \"observationAt\" },\n { id: \"scheduledOutstanding\", op: \"sum\", left: \"principal\", right: \"profit\" },\n { id: \"unpaid\", op: \"less\", left: \"zeroMoney\", right: \"scheduledOutstanding\" },\n { id: \"elapsed\", op: \"daysBetween\", left: \"due\", right: \"observed\" },\n { id: \"nonnegativeDays\", op: \"maximum\", left: \"elapsed\", right: \"zeroDays\" },\n { id: \"daysPastDue\", op: \"choose\", condition: \"unpaid\", yes: \"nonnegativeDays\", no: \"zeroDays\" }\n ]\n },\n {\n id: \"borrowerAccounts\",\n source: \"account\",\n instruments: [ ],\n rowKey: \"accountId\",\n columns: [\n {\n name: \"accountId\",\n field: \"id\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"participant\",\n field: \"ownerParticipantId\",\n type: { kind: \"text\" },\n required: false\n }\n ],\n expressions: [ ]\n },\n {\n id: \"borrowers\",\n source: \"identity\",\n instruments: [ ],\n rowKey: \"customerId\",\n columns: [\n {\n name: \"customerId\",\n field: \"id\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"participantId\",\n field: \"participantId\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"entityId\",\n field: \"entityId\",\n type: { kind: \"text\" },\n required: true\n }\n ],\n expressions: [ ]\n }\n ],\n time: { timezone: \"Asia/Riyadh\", boundary: \"startInclusiveEndExclusive\", observation: \"periodEnd\", history: \"retainedOnly\" },\n selection: { dataset: \"facilities\" },\n calculation: {\n joins: [\n {\n dataset: \"schedule\",\n local: \"facilityId\",\n foreign: \"planId\",\n cardinality: \"many\",\n missing: \"refuse\",\n aggregates: [\n { name: \"outstandingPrincipal\", op: \"sum\", value: \"principal\" },\n { name: \"remainingScheduledProfit\", op: \"sum\", value: \"profit\" },\n { name: \"scheduledPrincipalTotal\", op: \"sum\", value: \"scheduledPrincipal\" },\n { name: \"capturedScheduleCount\", op: \"count\" },\n { name: \"oldestUnpaidDays\", op: \"maximum\", value: \"daysPastDue\" }\n ]\n },\n {\n dataset: \"borrowerAccounts\",\n local: \"borrowerAccount\",\n foreign: \"accountId\",\n cardinality: \"one\",\n missing: \"refuse\",\n aggregates: [\n { name: \"borrowerParticipant\", op: \"minimum\", value: \"participant\" }\n ]\n },\n {\n dataset: \"borrowers\",\n local: \"borrowerParticipant\",\n foreign: \"participantId\",\n cardinality: \"one\",\n missing: \"refuse\",\n aggregates: [\n { name: \"borrowerEntity\", op: \"minimum\", value: \"entityId\" }\n ]\n }\n ],\n expressions: [\n {\n id: \"day0\",\n op: \"literal\",\n type: { kind: \"integer\" },\n value: 0\n },\n {\n id: \"day30\",\n op: \"literal\",\n type: { kind: \"integer\" },\n value: aging_first_days\n },\n {\n id: \"day60\",\n op: \"literal\",\n type: { kind: \"integer\" },\n value: aging_second_days\n },\n {\n id: \"day90\",\n op: \"literal\",\n type: { kind: \"integer\" },\n value: aging_third_days\n },\n {\n id: \"band0\",\n op: \"literal\",\n type: { kind: \"text\" },\n value: \"current\"\n },\n {\n id: \"band30\",\n op: \"literal\",\n type: { kind: \"text\" },\n value: \"first\"\n },\n {\n id: \"band60\",\n op: \"literal\",\n type: { kind: \"text\" },\n value: \"second\"\n },\n {\n id: \"band90\",\n op: \"literal\",\n type: { kind: \"text\" },\n value: \"third\"\n },\n {\n id: \"bandLate\",\n op: \"literal\",\n type: { kind: \"text\" },\n value: \"later\"\n },\n { id: \"current\", op: \"atMost\", left: \"oldestUnpaidDays\", right: \"day0\" },\n { id: \"first\", op: \"atMost\", left: \"oldestUnpaidDays\", right: \"day30\" },\n { id: \"second\", op: \"atMost\", left: \"oldestUnpaidDays\", right: \"day60\" },\n { id: \"third\", op: \"atMost\", left: \"oldestUnpaidDays\", right: \"day90\" },\n { id: \"lateBand\", op: \"choose\", condition: \"third\", yes: \"band90\", no: \"bandLate\" },\n { id: \"secondBand\", op: \"choose\", condition: \"second\", yes: \"band60\", no: \"lateBand\" },\n { id: \"firstBand\", op: \"choose\", condition: \"first\", yes: \"band30\", no: \"secondBand\" },\n { id: \"agingBand\", op: \"choose\", condition: \"current\", yes: \"band0\", no: \"firstBand\" }\n ],\n groupBy: [ \"agingBand\" ],\n aggregates: [\n { name: \"facilities\", op: \"count\" },\n { name: \"principalMinor\", op: \"sum\", value: \"outstandingPrincipal\" },\n { name: \"scheduledProfitMinor\", op: \"sum\", value: \"remainingScheduledProfit\" }\n ],\n resultExpressions: [ ]\n },\n validation: {\n empty: \"noEligibleFacilities\",\n required: [ \"borrowerEntity\" ],\n reconcile: [ ],\n rowReconcile: [\n { left: \"originalPrincipal\", right: \"scheduledPrincipalTotal\" },\n { left: \"scheduleCount\", right: \"capturedScheduleCount\" }\n ],\n unavailableFacts: [ ],\n lockTimeoutMs: lock_wait_ms,\n captureTimeoutMs: capture_ms,\n maxRows: max_rows,\n maxJoinRows: max_join_rows,\n maxBytes: max_bytes\n },\n output: {\n profile: \"internal.v1\",\n formats: [ \"json\", \"csv\" ],\n columns: [\n {\n name: \"agingBand\",\n label: \"agingBand\",\n type: { kind: \"text\" }\n },\n {\n name: \"facilities\",\n label: \"facilities\",\n type: { kind: \"integer\" }\n },\n {\n name: \"principalMinor\",\n label: \"principalMinor\",\n type: { kind: \"money\", currency: \"SAR\" }\n },\n {\n name: \"scheduledProfitMinor\",\n label: \"scheduledProfitMinor\",\n type: { kind: \"money\", currency: \"SAR\" }\n }\n ],\n sort: [ \"agingBand\" ]\n },\n authority: {\n request: [ \"owner\", \"finance\" ],\n read: [ \"owner\", \"admin\", \"operations\", \"finance\", \"viewer\" ],\n release: [ ],\n independentApproval: true,\n retention: { policy: \"report_replay\", years: retention_years }\n }\n },\n {\n identity: { id: \"origination_cohorts\", version: 1, description: \"Origination cohort performance. Refuses until business-effective origination dates and dated repayment allocation are retained; record creation time is not origination.\" },\n scope: { kind: \"product\", classification: \"internal\", currency: \"SAR\" },\n datasets: [\n {\n id: \"facilities\",\n source: \"instrument\",\n instruments: on,\n rowKey: \"facilityId\",\n columns: [\n {\n name: \"facilityId\",\n field: \"id\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"borrowerAccount\",\n field: \"borrower\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"state\",\n field: \"status\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"originalPrincipal\",\n field: \"principal\",\n type: { kind: \"money\", currency: \"SAR\" },\n required: true\n },\n {\n name: \"scheduleCount\",\n field: \"months\",\n type: { kind: \"integer\" },\n required: true\n },\n {\n name: \"recordedCreation\",\n field: \"createdAt\",\n type: { kind: \"date\" },\n required: true\n }\n ],\n expressions: [\n {\n id: \"activeState\",\n op: \"literal\",\n type: { kind: \"text\" },\n value: \"active\"\n },\n {\n id: \"paidState\",\n op: \"literal\",\n type: { kind: \"text\" },\n value: \"paid\"\n },\n {\n id: \"writtenState\",\n op: \"literal\",\n type: { kind: \"text\" },\n value: \"written_off\"\n },\n { id: \"active\", op: \"equal\", left: \"state\", right: \"activeState\" },\n { id: \"paid\", op: \"equal\", left: \"state\", right: \"paidState\" },\n { id: \"writtenOff\", op: \"equal\", left: \"state\", right: \"writtenState\" },\n { id: \"activeOrPaid\", op: \"or\", left: \"active\", right: \"paid\" },\n { id: \"financed\", op: \"or\", left: \"active\", right: \"writtenOff\" }\n ],\n selection: \"financed\"\n },\n {\n id: \"schedule\",\n source: \"instrument\",\n instruments: child(on, slice),\n rowKey: \"sliceId\",\n columns: [\n {\n name: \"sliceId\",\n field: \"id\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"planId\",\n field: \"plan\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"due\",\n field: \"dueAt\",\n type: { kind: \"date\" },\n required: true\n },\n {\n name: \"principal\",\n field: \"principalReceivable.balance\",\n type: { kind: \"money\", currency: \"SAR\" },\n required: true\n },\n {\n name: \"profit\",\n field: \"profitReceivable.balance\",\n type: { kind: \"money\", currency: \"SAR\" },\n required: true\n },\n {\n name: \"scheduledPrincipal\",\n field: \"principal\",\n type: { kind: \"money\", currency: \"SAR\" },\n required: true\n }\n ],\n expressions: [\n {\n id: \"zeroMoney\",\n op: \"literal\",\n type: { kind: \"money\", currency: \"SAR\" },\n value: \"0\"\n },\n {\n id: \"zeroDays\",\n op: \"literal\",\n type: { kind: \"integer\" },\n value: 0\n },\n { id: \"observed\", op: \"parameter\", name: \"observationAt\" },\n { id: \"scheduledOutstanding\", op: \"sum\", left: \"principal\", right: \"profit\" },\n { id: \"unpaid\", op: \"less\", left: \"zeroMoney\", right: \"scheduledOutstanding\" },\n { id: \"elapsed\", op: \"daysBetween\", left: \"due\", right: \"observed\" },\n { id: \"nonnegativeDays\", op: \"maximum\", left: \"elapsed\", right: \"zeroDays\" },\n { id: \"daysPastDue\", op: \"choose\", condition: \"unpaid\", yes: \"nonnegativeDays\", no: \"zeroDays\" }\n ]\n },\n {\n id: \"borrowerAccounts\",\n source: \"account\",\n instruments: [ ],\n rowKey: \"accountId\",\n columns: [\n {\n name: \"accountId\",\n field: \"id\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"participant\",\n field: \"ownerParticipantId\",\n type: { kind: \"text\" },\n required: false\n }\n ],\n expressions: [ ]\n },\n {\n id: \"borrowers\",\n source: \"identity\",\n instruments: [ ],\n rowKey: \"customerId\",\n columns: [\n {\n name: \"customerId\",\n field: \"id\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"participantId\",\n field: \"participantId\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"entityId\",\n field: \"entityId\",\n type: { kind: \"text\" },\n required: true\n }\n ],\n expressions: [ ]\n }\n ],\n time: { timezone: \"Asia/Riyadh\", boundary: \"startInclusiveEndExclusive\", observation: \"periodEnd\", history: \"retainedOnly\" },\n selection: { dataset: \"facilities\" },\n calculation: {\n joins: [\n {\n dataset: \"schedule\",\n local: \"facilityId\",\n foreign: \"planId\",\n cardinality: \"many\",\n missing: \"refuse\",\n aggregates: [\n { name: \"outstandingPrincipal\", op: \"sum\", value: \"principal\" },\n { name: \"remainingScheduledProfit\", op: \"sum\", value: \"profit\" },\n { name: \"scheduledPrincipalTotal\", op: \"sum\", value: \"scheduledPrincipal\" },\n { name: \"capturedScheduleCount\", op: \"count\" },\n { name: \"oldestUnpaidDays\", op: \"maximum\", value: \"daysPastDue\" }\n ]\n },\n {\n dataset: \"borrowerAccounts\",\n local: \"borrowerAccount\",\n foreign: \"accountId\",\n cardinality: \"one\",\n missing: \"refuse\",\n aggregates: [\n { name: \"borrowerParticipant\", op: \"minimum\", value: \"participant\" }\n ]\n },\n {\n dataset: \"borrowers\",\n local: \"borrowerParticipant\",\n foreign: \"participantId\",\n cardinality: \"one\",\n missing: \"refuse\",\n aggregates: [\n { name: \"borrowerEntity\", op: \"minimum\", value: \"entityId\" }\n ]\n }\n ],\n expressions: [\n { id: \"recordedMonth\", op: \"bucket\", value: \"recordedCreation\", unit: \"month\" }\n ],\n groupBy: [ \"recordedMonth\" ],\n aggregates: [\n { name: \"facilities\", op: \"count\" },\n { name: \"principalMinor\", op: \"sum\", value: \"outstandingPrincipal\" }\n ],\n resultExpressions: [ ]\n },\n validation: {\n empty: \"noEligibleFacilities\",\n required: [ \"borrowerEntity\" ],\n reconcile: [ ],\n rowReconcile: [\n { left: \"originalPrincipal\", right: \"scheduledPrincipalTotal\" },\n { left: \"scheduleCount\", right: \"capturedScheduleCount\" }\n ],\n unavailableFacts: [ \"business-effective origination timestamp\", \"dated repayment allocation and recovery history\" ],\n lockTimeoutMs: lock_wait_ms,\n captureTimeoutMs: capture_ms,\n maxRows: max_rows,\n maxJoinRows: max_join_rows,\n maxBytes: max_bytes\n },\n output: {\n profile: \"internal.v1\",\n formats: [ \"json\", \"csv\" ],\n columns: [\n {\n name: \"recordedMonth\",\n label: \"recordedMonth\",\n type: { kind: \"text\" }\n },\n {\n name: \"facilities\",\n label: \"facilities\",\n type: { kind: \"integer\" }\n },\n {\n name: \"principalMinor\",\n label: \"principalMinor\",\n type: { kind: \"money\", currency: \"SAR\" }\n }\n ],\n sort: [ \"recordedMonth\" ]\n },\n authority: {\n request: [ \"owner\", \"finance\" ],\n read: [ \"owner\", \"admin\", \"operations\", \"finance\", \"viewer\" ],\n release: [ ],\n independentApproval: true,\n retention: { policy: \"report_replay\", years: retention_years }\n }\n },\n {\n identity: { id: \"period_end_outstanding_principal_default_rate\", version: 1, description: \"Current active facilities with any unpaid installment at least the declared default days past due, observed at period end. Cure when arrears clear. Count and outstanding-principal weighted rates in the declared scale exclude paid and written-off facilities; write-offs are counted separately. This is a stock measure, not a new-default incidence or origination cohort rate.\" },\n scope: { kind: \"product\", classification: \"internal\", currency: \"SAR\" },\n datasets: [\n {\n id: \"facilities\",\n source: \"instrument\",\n instruments: on,\n rowKey: \"facilityId\",\n columns: [\n {\n name: \"facilityId\",\n field: \"id\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"borrowerAccount\",\n field: \"borrower\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"state\",\n field: \"status\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"originalPrincipal\",\n field: \"principal\",\n type: { kind: \"money\", currency: \"SAR\" },\n required: true\n },\n {\n name: \"scheduleCount\",\n field: \"months\",\n type: { kind: \"integer\" },\n required: true\n },\n {\n name: \"recordedCreation\",\n field: \"createdAt\",\n type: { kind: \"date\" },\n required: true\n }\n ],\n expressions: [\n {\n id: \"activeState\",\n op: \"literal\",\n type: { kind: \"text\" },\n value: \"active\"\n },\n {\n id: \"paidState\",\n op: \"literal\",\n type: { kind: \"text\" },\n value: \"paid\"\n },\n {\n id: \"writtenState\",\n op: \"literal\",\n type: { kind: \"text\" },\n value: \"written_off\"\n },\n { id: \"active\", op: \"equal\", left: \"state\", right: \"activeState\" },\n { id: \"paid\", op: \"equal\", left: \"state\", right: \"paidState\" },\n { id: \"writtenOff\", op: \"equal\", left: \"state\", right: \"writtenState\" },\n { id: \"activeOrPaid\", op: \"or\", left: \"active\", right: \"paid\" },\n { id: \"financed\", op: \"or\", left: \"active\", right: \"writtenOff\" }\n ],\n selection: \"financed\"\n },\n {\n id: \"schedule\",\n source: \"instrument\",\n instruments: child(on, slice),\n rowKey: \"sliceId\",\n columns: [\n {\n name: \"sliceId\",\n field: \"id\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"planId\",\n field: \"plan\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"due\",\n field: \"dueAt\",\n type: { kind: \"date\" },\n required: true\n },\n {\n name: \"principal\",\n field: \"principalReceivable.balance\",\n type: { kind: \"money\", currency: \"SAR\" },\n required: true\n },\n {\n name: \"profit\",\n field: \"profitReceivable.balance\",\n type: { kind: \"money\", currency: \"SAR\" },\n required: true\n },\n {\n name: \"scheduledPrincipal\",\n field: \"principal\",\n type: { kind: \"money\", currency: \"SAR\" },\n required: true\n }\n ],\n expressions: [\n {\n id: \"zeroMoney\",\n op: \"literal\",\n type: { kind: \"money\", currency: \"SAR\" },\n value: \"0\"\n },\n {\n id: \"zeroDays\",\n op: \"literal\",\n type: { kind: \"integer\" },\n value: 0\n },\n { id: \"observed\", op: \"parameter\", name: \"observationAt\" },\n { id: \"scheduledOutstanding\", op: \"sum\", left: \"principal\", right: \"profit\" },\n { id: \"unpaid\", op: \"less\", left: \"zeroMoney\", right: \"scheduledOutstanding\" },\n { id: \"elapsed\", op: \"daysBetween\", left: \"due\", right: \"observed\" },\n { id: \"nonnegativeDays\", op: \"maximum\", left: \"elapsed\", right: \"zeroDays\" },\n { id: \"daysPastDue\", op: \"choose\", condition: \"unpaid\", yes: \"nonnegativeDays\", no: \"zeroDays\" }\n ]\n },\n {\n id: \"borrowerAccounts\",\n source: \"account\",\n instruments: [ ],\n rowKey: \"accountId\",\n columns: [\n {\n name: \"accountId\",\n field: \"id\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"participant\",\n field: \"ownerParticipantId\",\n type: { kind: \"text\" },\n required: false\n }\n ],\n expressions: [ ]\n },\n {\n id: \"borrowers\",\n source: \"identity\",\n instruments: [ ],\n rowKey: \"customerId\",\n columns: [\n {\n name: \"customerId\",\n field: \"id\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"participantId\",\n field: \"participantId\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"entityId\",\n field: \"entityId\",\n type: { kind: \"text\" },\n required: true\n }\n ],\n expressions: [ ]\n }\n ],\n time: { timezone: \"Asia/Riyadh\", boundary: \"startInclusiveEndExclusive\", observation: \"periodEnd\", history: \"retainedOnly\" },\n selection: { dataset: \"facilities\" },\n calculation: {\n joins: [\n {\n dataset: \"schedule\",\n local: \"facilityId\",\n foreign: \"planId\",\n cardinality: \"many\",\n missing: \"refuse\",\n aggregates: [\n { name: \"outstandingPrincipal\", op: \"sum\", value: \"principal\" },\n { name: \"remainingScheduledProfit\", op: \"sum\", value: \"profit\" },\n { name: \"scheduledPrincipalTotal\", op: \"sum\", value: \"scheduledPrincipal\" },\n { name: \"capturedScheduleCount\", op: \"count\" },\n { name: \"oldestUnpaidDays\", op: \"maximum\", value: \"daysPastDue\" }\n ]\n },\n {\n dataset: \"borrowerAccounts\",\n local: \"borrowerAccount\",\n foreign: \"accountId\",\n cardinality: \"one\",\n missing: \"refuse\",\n aggregates: [\n { name: \"borrowerParticipant\", op: \"minimum\", value: \"participant\" }\n ]\n },\n {\n dataset: \"borrowers\",\n local: \"borrowerParticipant\",\n foreign: \"participantId\",\n cardinality: \"one\",\n missing: \"refuse\",\n aggregates: [\n { name: \"borrowerEntity\", op: \"minimum\", value: \"entityId\" }\n ]\n }\n ],\n expressions: [\n {\n id: \"threshold\",\n op: \"literal\",\n type: { kind: \"integer\" },\n value: default_days\n },\n {\n id: \"zero\",\n op: \"literal\",\n type: { kind: \"integer\" },\n value: 0\n },\n {\n id: \"one\",\n op: \"literal\",\n type: { kind: \"integer\" },\n value: 1\n },\n {\n id: \"zeroMoney\",\n op: \"literal\",\n type: { kind: \"money\", currency: \"SAR\" },\n value: \"0\"\n },\n { id: \"pastThreshold\", op: \"atMost\", left: \"threshold\", right: \"oldestUnpaidDays\" },\n { id: \"isDefault\", op: \"and\", left: \"active\", right: \"pastThreshold\" },\n { id: \"activeCount\", op: \"choose\", condition: \"active\", yes: \"one\", no: \"zero\" },\n { id: \"defaultCount\", op: \"choose\", condition: \"isDefault\", yes: \"one\", no: \"zero\" },\n { id: \"writeOffCount\", op: \"choose\", condition: \"writtenOff\", yes: \"one\", no: \"zero\" },\n { id: \"activePrincipal\", op: \"choose\", condition: \"active\", yes: \"outstandingPrincipal\", no: \"zeroMoney\" },\n { id: \"defaultPrincipal\", op: \"choose\", condition: \"isDefault\", yes: \"outstandingPrincipal\", no: \"zeroMoney\" }\n ],\n groupBy: [ ],\n aggregates: [\n { name: \"activeFacilities\", op: \"sum\", value: \"activeCount\" },\n { name: \"defaultFacilities\", op: \"sum\", value: \"defaultCount\" },\n { name: \"writtenOffFacilities\", op: \"sum\", value: \"writeOffCount\" },\n { name: \"activePrincipalMinor\", op: \"sum\", value: \"activePrincipal\" },\n { name: \"defaultPrincipalMinor\", op: \"sum\", value: \"defaultPrincipal\" }\n ],\n resultExpressions: [\n { id: \"countRate\", op: \"ratio\", numerator: \"defaultFacilities\", denominator: \"activeFacilities\", scale: ratio_scale, rounding: ratio_rounding, zero: \"null\" },\n { id: \"principalRate\", op: \"ratio\", numerator: \"defaultPrincipalMinor\", denominator: \"activePrincipalMinor\", scale: ratio_scale, rounding: ratio_rounding, zero: \"null\" },\n {\n id: \"restructuringEvidence\",\n op: \"literal\",\n type: { kind: \"text\" },\n value: \"unavailable\"\n },\n {\n id: \"defaultDays\",\n op: \"literal\",\n type: { kind: \"integer\" },\n value: default_days\n },\n {\n id: \"rateScale\",\n op: \"literal\",\n type: { kind: \"integer\" },\n value: ratio_scale\n }\n ]\n },\n validation: {\n empty: \"refuse\",\n required: [ \"borrowerEntity\" ],\n reconcile: [ ],\n rowReconcile: [\n { left: \"originalPrincipal\", right: \"scheduledPrincipalTotal\" },\n { left: \"scheduleCount\", right: \"capturedScheduleCount\" }\n ],\n unavailableFacts: [ ],\n lockTimeoutMs: lock_wait_ms,\n captureTimeoutMs: capture_ms,\n maxRows: max_rows,\n maxJoinRows: max_join_rows,\n maxBytes: max_bytes\n },\n output: {\n profile: \"internal.v1\",\n formats: [ \"json\", \"csv\" ],\n columns: [\n {\n name: \"activeFacilities\",\n label: \"activeFacilities\",\n type: { kind: \"integer\" }\n },\n {\n name: \"defaultFacilities\",\n label: \"defaultFacilities\",\n type: { kind: \"integer\" }\n },\n {\n name: \"writtenOffFacilities\",\n label: \"writtenOffFacilities\",\n type: { kind: \"integer\" }\n },\n {\n name: \"activePrincipalMinor\",\n label: \"activePrincipalMinor\",\n type: { kind: \"money\", currency: \"SAR\" }\n },\n {\n name: \"defaultPrincipalMinor\",\n label: \"defaultPrincipalMinor\",\n type: { kind: \"money\", currency: \"SAR\" }\n },\n {\n name: \"countRate\",\n label: \"countRate\",\n type: { kind: \"integer\" }\n },\n {\n name: \"principalRate\",\n label: \"principalRate\",\n type: { kind: \"integer\" }\n },\n {\n name: \"restructuringEvidence\",\n label: \"restructuringEvidence\",\n type: { kind: \"text\" }\n },\n {\n name: \"defaultDays\",\n label: \"defaultDays\",\n type: { kind: \"integer\" }\n },\n {\n name: \"rateScale\",\n label: \"rateScale\",\n type: { kind: \"integer\" }\n }\n ],\n sort: [ \"activeFacilities\" ]\n },\n authority: {\n request: [ \"owner\", \"finance\" ],\n read: [ \"owner\", \"admin\", \"operations\", \"finance\", \"viewer\" ],\n release: [ ],\n independentApproval: true,\n retention: { policy: \"report_replay\", years: retention_years }\n }\n },\n {\n identity: { id: \"bureau_facility\", version: 1, description: \"Bureau facility definition only. No submission, provider layout or transport is admitted until the member specification and required governed facts exist.\" },\n scope: { kind: \"product\", classification: \"internal\", currency: \"SAR\" },\n datasets: [\n {\n id: \"facilities\",\n source: \"instrument\",\n instruments: on,\n rowKey: \"facilityId\",\n columns: [\n {\n name: \"facilityId\",\n field: \"id\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"borrowerAccount\",\n field: \"borrower\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"state\",\n field: \"status\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"originalPrincipal\",\n field: \"principal\",\n type: { kind: \"money\", currency: \"SAR\" },\n required: true\n },\n {\n name: \"scheduleCount\",\n field: \"months\",\n type: { kind: \"integer\" },\n required: true\n },\n {\n name: \"recordedCreation\",\n field: \"createdAt\",\n type: { kind: \"date\" },\n required: true\n }\n ],\n expressions: [\n {\n id: \"activeState\",\n op: \"literal\",\n type: { kind: \"text\" },\n value: \"active\"\n },\n {\n id: \"paidState\",\n op: \"literal\",\n type: { kind: \"text\" },\n value: \"paid\"\n },\n {\n id: \"writtenState\",\n op: \"literal\",\n type: { kind: \"text\" },\n value: \"written_off\"\n },\n { id: \"active\", op: \"equal\", left: \"state\", right: \"activeState\" },\n { id: \"paid\", op: \"equal\", left: \"state\", right: \"paidState\" },\n { id: \"writtenOff\", op: \"equal\", left: \"state\", right: \"writtenState\" },\n { id: \"activeOrPaid\", op: \"or\", left: \"active\", right: \"paid\" },\n { id: \"financed\", op: \"or\", left: \"active\", right: \"writtenOff\" }\n ],\n selection: \"financed\"\n },\n {\n id: \"schedule\",\n source: \"instrument\",\n instruments: child(on, slice),\n rowKey: \"sliceId\",\n columns: [\n {\n name: \"sliceId\",\n field: \"id\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"planId\",\n field: \"plan\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"due\",\n field: \"dueAt\",\n type: { kind: \"date\" },\n required: true\n },\n {\n name: \"principal\",\n field: \"principalReceivable.balance\",\n type: { kind: \"money\", currency: \"SAR\" },\n required: true\n },\n {\n name: \"profit\",\n field: \"profitReceivable.balance\",\n type: { kind: \"money\", currency: \"SAR\" },\n required: true\n },\n {\n name: \"scheduledPrincipal\",\n field: \"principal\",\n type: { kind: \"money\", currency: \"SAR\" },\n required: true\n }\n ],\n expressions: [\n {\n id: \"zeroMoney\",\n op: \"literal\",\n type: { kind: \"money\", currency: \"SAR\" },\n value: \"0\"\n },\n {\n id: \"zeroDays\",\n op: \"literal\",\n type: { kind: \"integer\" },\n value: 0\n },\n { id: \"observed\", op: \"parameter\", name: \"observationAt\" },\n { id: \"scheduledOutstanding\", op: \"sum\", left: \"principal\", right: \"profit\" },\n { id: \"unpaid\", op: \"less\", left: \"zeroMoney\", right: \"scheduledOutstanding\" },\n { id: \"elapsed\", op: \"daysBetween\", left: \"due\", right: \"observed\" },\n { id: \"nonnegativeDays\", op: \"maximum\", left: \"elapsed\", right: \"zeroDays\" },\n { id: \"daysPastDue\", op: \"choose\", condition: \"unpaid\", yes: \"nonnegativeDays\", no: \"zeroDays\" }\n ]\n },\n {\n id: \"borrowerAccounts\",\n source: \"account\",\n instruments: [ ],\n rowKey: \"accountId\",\n columns: [\n {\n name: \"accountId\",\n field: \"id\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"participant\",\n field: \"ownerParticipantId\",\n type: { kind: \"text\" },\n required: false\n }\n ],\n expressions: [ ]\n },\n {\n id: \"borrowers\",\n source: \"identity\",\n instruments: [ ],\n rowKey: \"customerId\",\n columns: [\n {\n name: \"customerId\",\n field: \"id\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"participantId\",\n field: \"participantId\",\n type: { kind: \"text\" },\n required: true\n },\n {\n name: \"entityId\",\n field: \"entityId\",\n type: { kind: \"text\" },\n required: true\n }\n ],\n expressions: [ ]\n }\n ],\n time: { timezone: \"Asia/Riyadh\", boundary: \"startInclusiveEndExclusive\", observation: \"periodEnd\", history: \"retainedOnly\" },\n selection: { dataset: \"facilities\" },\n calculation: {\n joins: [\n {\n dataset: \"schedule\",\n local: \"facilityId\",\n foreign: \"planId\",\n cardinality: \"many\",\n missing: \"refuse\",\n aggregates: [\n { name: \"outstandingPrincipal\", op: \"sum\", value: \"principal\" },\n { name: \"remainingScheduledProfit\", op: \"sum\", value: \"profit\" },\n { name: \"scheduledPrincipalTotal\", op: \"sum\", value: \"scheduledPrincipal\" },\n { name: \"capturedScheduleCount\", op: \"count\" },\n { name: \"oldestUnpaidDays\", op: \"maximum\", value: \"daysPastDue\" }\n ]\n },\n {\n dataset: \"borrowerAccounts\",\n local: \"borrowerAccount\",\n foreign: \"accountId\",\n cardinality: \"one\",\n missing: \"refuse\",\n aggregates: [\n { name: \"borrowerParticipant\", op: \"minimum\", value: \"participant\" }\n ]\n },\n {\n dataset: \"borrowers\",\n local: \"borrowerParticipant\",\n foreign: \"participantId\",\n cardinality: \"one\",\n missing: \"refuse\",\n aggregates: [\n { name: \"borrowerEntity\", op: \"minimum\", value: \"entityId\" }\n ]\n }\n ],\n expressions: [ ],\n groupBy: [ ],\n aggregates: [ ],\n resultExpressions: [ ]\n },\n validation: {\n empty: \"refuse\",\n required: [ \"borrowerEntity\" ],\n reconcile: [ ],\n rowReconcile: [\n { left: \"originalPrincipal\", right: \"scheduledPrincipalTotal\" },\n { left: \"scheduleCount\", right: \"capturedScheduleCount\" }\n ],\n unavailableFacts: [ \"approved member format contract\", \"versioned borrower identity and dispute facts\", \"business-effective origination and repayment allocation history\" ],\n lockTimeoutMs: lock_wait_ms,\n captureTimeoutMs: capture_ms,\n maxRows: max_rows,\n maxJoinRows: max_join_rows,\n maxBytes: max_bytes\n },\n output: {\n profile: \"internal.v1\",\n formats: [ \"json\", \"csv\" ],\n columns: [\n {\n name: \"facilityId\",\n label: \"facilityId\",\n type: { kind: \"text\" }\n },\n {\n name: \"borrowerEntity\",\n label: \"borrowerEntity\",\n type: { kind: \"text\" }\n },\n {\n name: \"outstandingPrincipal\",\n label: \"outstandingPrincipal\",\n type: { kind: \"money\", currency: \"SAR\" }\n }\n ],\n sort: [ \"facilityId\" ]\n },\n authority: {\n request: [ \"owner\", \"finance\" ],\n read: [ \"owner\", \"admin\", \"operations\", \"finance\", \"viewer\" ],\n release: [ ],\n independentApproval: true,\n retention: { policy: \"report_replay\", years: retention_years }\n }\n }\n ]\n}\n"],
12
13
  ["savings.hsx", "header savings\n\ninstrument circle(contribution: money, members: integer(1, 366), starts: date, memberships: ref<savings.membership> = object(savings.membership)) {\n summary: \"A fixed group contributes on its explicit calendar and takes the pot in order.\"\n fields { contribution: money = contribution, members: integer = members, startsAt: date = starts, dates: list(date, members), pot: money = multiply(self.contribution, self.members), held: account of self }\n lifecycle { states: [forming, active, closed, disbanded], initial: forming }\n action create { }\n action activate {\n from: forming, to: active, actor: clock, due: { at: self.startsAt }\n requires count of { instrument: memberships, reference: \"circle\", anchor: self.id, states: [joined], limit: 60 } == self.members\n }\n action close {\n from: active, to: closed\n requires count of { instrument: memberships, reference: \"circle\", anchor: self.id, states: [paid], limit: 60 } == self.members\n requires self.held.balance == \"0\"\n }\n action disband { from: forming, to: disbanded }\n}\n\ninstrument membership(circle: ref<savings.circle>, member: party) {\n fields { circle: ref<circle>, member: account of member, position: integer(1, 60), preceding: integer = subtract(self.position, 1), receivesAt: date = at(self.circle.dates, self.position), contribution: money = self.circle.contribution, total: money = self.circle.pot, dates: list(date, 60) }\n lifecycle { states: [joined, active, paid, withdrawn], initial: joined }\n action create { requires self.position <= self.circle.members; requires self.circle in [forming]; requires unique \"circle_seat\" on [self.circle, self.position]; requires unique \"circle_member\" on [self.circle, self.member] }\n action activate {\n from: joined, to: active\n requires self.circle in [active]\n requires count of { instrument: contribution, reference: \"membership\", anchor: self.id, states: [pending], limit: 60 } == self.circle.members\n }\n action receive {\n from: active, to: paid, actor: clock, due: { at: self.receivesAt }\n requires self.circle in [active]\n requires count of { instrument: all(savings.membership), reference: \"circle\", anchor: self.circle, states: [paid], limit: 60 } == self.preceding\n moves self.total from self.circle.held to self.member\n }\n action withdraw { from: joined, to: withdrawn, requires self.circle in [disbanded] }\n records {\n contribution: {\n fields { membership: ref<parent>, position: integer(1, 60), dueAt: date = at(self.membership.circle.dates, self.position), amount: money = self.membership.contribution }\n lifecycle { states: [pending, paid], initial: pending }\n action create { requires self.position <= self.membership.circle.members; requires self.membership in [joined]; requires unique \"seat_period\" on [self.membership, self.position] }\n action pay { from: pending, to: paid, actor: clock, due: { at: self.dueAt }, requires self.membership in [active, paid]; requires self.membership.circle in [active], moves self.amount from self.membership.member to self.membership.circle.held }\n }\n }\n}\n"],
13
14
  ["travel.hsx", "header travel\n\ninstrument package(price: money, supplier_cost: money, departure: date) {\n constraints { supplier_cost: at_most(price) }\n summary: \"Immutable package price, supplier cost and departure.\"\n fields { price: money = price, supplierCost: money = supplier_cost, departure: date = departure }\n lifecycle { states: [draft, published, closed], initial: draft }\n action create { requires self.supplierCost <= self.price }\n action publish { from: draft, to: published }\n action close { from: published, to: closed, actor: clock, due: { at: self.departure } }\n}\n\ninstrument booking(package: ref<travel.package>, buyer: party, supplier: approval, cover: ref<insurance.cover>, deposit: percent = 30%, balance_before: duration = 14d, confirm_within: duration = 24h, tax: percent = 15%, early_before: duration = 30d, middle_before: duration = 15d, middle_penalty: percent = 10%, late_penalty: percent = 30%) {\n constraints { early_before: greater_than(middle_before) }\n summary: \"A deposited booking with three cancellation bands and supplier confirmation.\"\n fields {\n package: ref<package>, bookingReference: text, buyer: account of buyer, supplier: account of supplier\n price: money = self.package.price, supplierCost: money = self.package.supplierCost\n deposit: money = rate(self.price, deposit), balance: money = subtract(self.price, self.deposit)\n margin: money = subtract(self.price, self.supplierCost)\n tax: money = rate(self.margin, tax), operatorNet: money = subtract(self.margin, self.tax)\n middlePenalty: money = rate(self.supplierCost, middle_penalty)\n latePenalty: money = rate(self.supplierCost, late_penalty)\n balanceAt: date = before(self.package.departure, balance_before)\n earlyAt: date = before(self.package.departure, early_before)\n middleAt: date = before(self.package.departure, middle_before)\n lateAt: date = after(self.middleAt, 1ms)\n confirmBy: date = after(self.package.departure, confirm_within)\n held: account of self\n refund: money?, retainedMargin: money?, retainedTax: money?, retainedNet: money?\n }\n lifecycle { states: [created, deposit_paid, paid, completed, cancelled, refunded], initial: created }\n action create {\n requires self.package in [published]\n requires unique \"booking_reference\" on [self.bookingReference]\n }\n action deposit {\n from: created, to: deposit_paid, actor: { party: buyer }, deadline: { at: self.balanceAt }\n requires count of { instrument: child(cover, slice), reference: \"covers\", anchor: self.id, states: [pending], limit: 366 } >= 1\n moves self.deposit from buyer to self.held\n invoke: [{ selection: { instrument: child(cover, slice), reference: \"covers\", anchor: self.id, states: [pending], limit: 366 }, action: collect, input: {} }]\n }\n action balance {\n from: deposit_paid, to: paid, actor: { party: buyer }, deadline: { at: self.balanceAt }\n moves self.balance from buyer to self.held\n }\n action confirm {\n from: paid, to: completed, actor: { party: supplier }\n due: { at: self.package.departure }, deadline: { at: self.confirmBy }\n requires approval by supplier\n moves self.supplierCost from self.held to supplier\n moves self.tax from self.held to programTax\n moves self.operatorNet from self.held to programOperator\n }\n action timeout {\n from: paid, to: refunded, actor: clock, due: { at: self.confirmBy }\n moves self.price from self.held to buyer\n }\n action cancel_early {\n from: [deposit_paid, paid], to: cancelled, deadline: { at: self.earlyAt }\n moves self.held.balance from self.held to buyer\n }\n action cancel_middle {\n from: [deposit_paid, paid], to: cancelled, due: { at: self.earlyAt }, deadline: { at: self.lateAt }\n calculate: [\n { target: refund, op: \"subtract\", base: { field: self.held.balance }, subtract: [{ field: self.deposit }] }\n { target: retainedMargin, op: \"subtract\", base: { field: self.deposit }, subtract: [{ field: self.middlePenalty }] }\n { target: retainedTax, op: \"rate\", base: { field: self.retainedMargin }, bps: { literal: tax }, rounding: \"floor\" }\n { target: retainedNet, op: \"subtract\", base: { field: self.retainedMargin }, subtract: [{ field: self.retainedTax }] }\n ]\n moves self.refund from self.held to buyer\n moves self.middlePenalty from self.held to supplier\n moves self.retainedTax from self.held to programTax\n moves self.retainedNet from self.held to programOperator\n }\n action cancel_late {\n from: [deposit_paid, paid], to: cancelled, actor: caller, due: { at: self.lateAt }\n calculate: [\n { target: retainedMargin, op: \"subtract\", base: { field: self.held.balance }, subtract: [{ field: self.latePenalty }] }\n { target: retainedTax, op: \"rate\", base: { field: self.retainedMargin }, bps: { literal: tax }, rounding: \"floor\" }\n { target: retainedNet, op: \"subtract\", base: { field: self.retainedMargin }, subtract: [{ field: self.retainedTax }] }\n ]\n moves self.latePenalty from self.held to supplier\n moves self.retainedTax from self.held to programTax\n moves self.retainedNet from self.held to programOperator\n }\n action default_balance {\n from: deposit_paid, to: cancelled, actor: clock, due: { at: self.balanceAt }\n calculate: [\n { target: retainedMargin, op: \"subtract\", base: { field: self.held.balance }, subtract: [{ field: self.latePenalty }] }\n { target: retainedTax, op: \"rate\", base: { field: self.retainedMargin }, bps: { literal: tax }, rounding: \"floor\" }\n { target: retainedNet, op: \"subtract\", base: { field: self.retainedMargin }, subtract: [{ field: self.retainedTax }] }\n ]\n moves self.latePenalty from self.held to supplier\n moves self.retainedTax from self.held to programTax\n moves self.retainedNet from self.held to programOperator\n }\n}\n"],
15
+ ["vehicles.hsx", "header vehicles\n\ninstrument vehicle(listing: ref<marketplace.listing>, seller: party) {\n summary: \"Seller-declared vehicle identity and kilometre odometer, corrected only before publication.\"\n fields {\n listing: ref<listing>, seller: account of seller\n vin: text(17, 17, \"^[A-HJ-NPR-Z0-9]{17}$\"), make: text(1, 80), model: text(1, 80)\n year: integer(1886, 2200), odometer: integer(0, 10000000), odometerUnit: enum(kilometres) = kilometres\n correctedAt: date?, correctionEvidence: text?\n }\n lifecycle { states: [draft, published], initial: draft }\n action create {\n actor: { party: seller }\n requires self.listing in [draft]; requires self.seller == self.listing.seller\n requires unique \"listing_vehicle\" on [self.listing]\n }\n action publish {\n from: draft, to: published, actor: { parent: listing }\n requires self.listing in [active]\n requires unique \"vehicle_identity\" on [self.vin]\n }\n action correct {\n from: draft, to: draft, actor: { party: seller }\n input { make: text(1, 80), model: text(1, 80), year: integer(1886, 2200), odometer: integer(0, 10000000), evidence: text }\n requires self.listing in [draft]; requires self.seller == self.listing.seller\n set: { make: { field: input.make }, model: { field: input.model }, year: { field: input.year }, odometer: { field: input.odometer }, correctionEvidence: { field: input.evidence }, correctedAt: { field: self.now } }\n }\n action correct_identity {\n from: draft, to: draft, actor: { party: seller }\n input { vin: text(17, 17, \"^[A-HJ-NPR-Z0-9]{17}$\"), evidence: text }\n requires self.listing in [draft]; requires self.seller == self.listing.seller\n set: { vin: { field: input.vin }, correctionEvidence: { field: input.evidence }, correctedAt: { field: self.now } }\n }\n}\n"],
14
16
  ["wallet.hsx", "header wallet\n\ninstrument balance(holder: party, spend_limit: money = 100000 SAR) {\n summary: \"A holder's reusable balance with an immutable per-spend ceiling.\"\n fields { holder: account of holder, held: account of self, spendLimit: money = spend_limit }\n lifecycle { states: [pending, active, frozen, closed], initial: pending }\n action create { }\n action activate { from: pending, to: active, actor: { party: holder } }\n action topup {\n from: active, to: active, actor: { party: holder }\n input { amount: money }\n moves input.amount from holder to self.held\n }\n action withdraw {\n from: active, to: active, actor: { party: holder }\n input { amount: money }\n moves input.amount from self.held to holder\n }\n action freeze { from: active, to: frozen, }\n action unfreeze { from: frozen, to: active, }\n action close { from: [pending, active], to: closed, requires self.held.balance == \"0\" }\n}\n\ninstrument spend(wallet: ref<wallet.balance>, payee: party) {\n summary: \"Reserve one wallet spend, then post or void the same reservation.\"\n fields { wallet: ref<wallet>, amount: money, expiresAt: date, reservation: text? }\n lifecycle { states: [pending, reserved, paid, cancelled, expired], initial: pending }\n action create {\n requires self.wallet in [active]\n requires self.amount <= self.wallet.spendLimit\n }\n action reserve {\n from: pending, to: reserved\n requires self.wallet in [active]\n deadline: { at: self.expiresAt }\n moves reserve self.amount from self.wallet.held to payee capture \"reservation\"\n }\n action pay { from: reserved, to: paid, moves post self.reservation }\n action cancel { from: reserved, to: cancelled, moves void self.reservation }\n action expire { from: reserved, to: expired, actor: clock, due: { at: self.expiresAt }, moves void self.reservation }\n}\n"],
15
17
  ]);
16
18
  //# sourceMappingURL=std-bundle.js.map
@@ -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,eAAe,EAAE,u8BAAu8B,CAAC;IAC19B,CAAC,WAAW,EAAE,i5GAAi5G,CAAC;IACh6G,CAAC,iBAAiB,EAAE,suEAAsuE,CAAC;IAC3vE,CAAC,YAAY,EAAE,66DAA66D,CAAC;IAC77D,CAAC,eAAe,EAAE,82gCAA82gC,CAAC;IACj4gC,CAAC,eAAe,EAAE,ojGAAojG,CAAC;IACvkG,CAAC,aAAa,EAAE,ohPAAohP,CAAC;IACriP,CAAC,iBAAiB,EAAE,ujCAAujC,CAAC;IAC5kC,CAAC,WAAW,EAAE,2tWAA2tW,CAAC;IAC1uW,CAAC,aAAa,EAAE,qmGAAqmG,CAAC;IACtnG,CAAC,YAAY,EAAE,0zLAA0zL,CAAC;IAC10L,CAAC,YAAY,EAAE,w1DAAw1D,CAAC;CACz2D,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,eAAe,EAAE,u8BAAu8B,CAAC;IAC19B,CAAC,WAAW,EAAE,i5GAAi5G,CAAC;IACh6G,CAAC,iBAAiB,EAAE,2jKAA2jK,CAAC;IAChlK,CAAC,YAAY,EAAE,gpFAAgpF,CAAC;IAChqF,CAAC,eAAe,EAAE,2voDAA2voD,CAAC;IAC9woD,CAAC,eAAe,EAAE,ojGAAojG,CAAC;IACvkG,CAAC,aAAa,EAAE,ohPAAohP,CAAC;IACriP,CAAC,iBAAiB,EAAE,gxQAAgxQ,CAAC;IACryQ,CAAC,WAAW,EAAE,+vWAA+vW,CAAC;IAC9wW,CAAC,eAAe,EAAE,g15CAAg15C,CAAC;IACn25C,CAAC,aAAa,EAAE,qmGAAqmG,CAAC;IACtnG,CAAC,YAAY,EAAE,0zLAA0zL,CAAC;IAC10L,CAAC,cAAc,EAAE,6yDAA6yD,CAAC;IAC/zD,CAAC,YAAY,EAAE,w1DAAw1D,CAAC;CACz2D,CAAC,CAAC"}
@@ -1,3 +1,3 @@
1
- export declare const HSX_VERSION = "3.2.0";
1
+ export declare const HSX_VERSION = "3.3.0";
2
2
  export declare const HSX_TARGET_UDL_VERSION = 3;
3
3
  //# sourceMappingURL=version.d.ts.map
@@ -1,3 +1,3 @@
1
- export const HSX_VERSION = "3.2.0";
1
+ export const HSX_VERSION = "3.3.0";
2
2
  export const HSX_TARGET_UDL_VERSION = 3;
3
3
  //# sourceMappingURL=version.js.map
package/docs/README.md CHANGED
@@ -143,6 +143,12 @@ when disburse_to is borrower {
143
143
  }
144
144
  ```
145
145
 
146
+ `when <reference tunable> has <field>` includes its clauses only when the bound
147
+ object declares that field. The compiler checks the object's declared shape,
148
+ regardless of declaration order, and emits no runtime branch. Financing uses
149
+ this to commit marketplace orders for order-backed holds while plain money
150
+ holds need no order relation.
151
+
146
152
  `when <enum tunable> is <value>` accepts requirements, calculations, moves and
147
153
  invocations, including nested branches. The compiler emits only the selected
148
154
  clauses and preserves their order within each UDL phase. Lifecycle and actor