@hyperscale0/hsx 1.0.294 → 1.0.301
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.
- package/dist/src/std-bundle.js +1 -1
- package/dist/src/std-bundle.js.map +1 -1
- package/package.json +4 -4
- package/src/std-bundle.ts +1 -1
- package/std/insurance.hsx +4 -4
package/dist/src/std-bundle.js
CHANGED
|
@@ -5,7 +5,7 @@ export const BUNDLED_STD_FILES = new Map([
|
|
|
5
5
|
["collections.hsx", "header collections\n\n// Economics: Company capital pays agencies as participant payouts; outside capital passes through.\n// A company agency earns outside capital fees; its own capital fee is internal.\n\n// Expose case.create, assign and recover as separate steps. Creation needs overdue\n// outstanding principal and a matching slice/plan. Assignment belongs to capital;\n// recovery belongs to agency and pays the linked payment before the agency fee.\n// Payment must belong to the same plan. Recovered means that payment was processed,\n// not that the entire debt was repaid. Fee debits plan.capital, not the borrower.\n// Expose recall for capital and return_uncollected for agency when needed.\n// Contacts need an assigned case, matching agency, local hours and rolling count.\n// Contact outcomes are separate records. Reminder dispatch is operator-owned;\n// before_due/overdue are clock-owned and require active debt. Scheduled admission\n// does not prove delivery or retry. No collector can infer authority from an alias.\n\n// Cost: case recovery invokes the linked payment and then charges its agency\n// fee. Its count includes those child effects. Contact and reminder delivery costs\n// are not provider prices in hsx cost; the executor supplies commercial tariffs.\n\ninstrument case(on: ref<financing.installments>[], agency: party, capital: party = programOperator, 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, actor: { party: capital } }\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 { allowZero: true, from: recovered, to: recovered, actor: { parent: current() }, moves self.agencyFee from self.plan.capital to agency economics { recipient: agency, company: { recipient: capital, company: { purpose: internal, sourceParty: capital }, participant: { purpose: earning, sourceParty: capital } }, participant: { recipient: capital, company: { purpose: participant_payout, sourceParty: capital }, participant: { purpose: pass_through, sourceParty: capital } } } }\n action recall { from: [opened, assigned], to: recalled, actor: { party: capital } }\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
6
|
["escrow.hsx", "header escrow\n\n// Economics: Funding and unspent returns are principal. Acceptance realizes earnings for\n// the company; the payer's cash passes through to a bound outside seller, less the\n// fee the company earns. Tax is pass-through.\n\n// Expose create, fund, deliver and accept for the purchase path. Create captures\n// subject.price; acceptance pays payee less the configured fee, not payer.\n// Expose dispute, verify_return and refund separately for the return path.\n// Payer disputes delivered goods; payee verifies return evidence from disputed.\n// Refunds return the held balance to the payer. A composition can supply funding\n// controllers and the states in which they block direct refunds. Only those\n// controllers may confirm outside funding or finish its coordinated refund.\n// Expose refund_undelivered to let the payer take the whole held price back once\n// deliver_within has passed since funding without delivery. It is a payer action\n// that becomes available at that time; nothing runs it automatically.\n// The Product operator settles any disputed hold: settle_release pays the payee\n// as acceptance would, and settle_return moves it to return_verified. Without a\n// active funding controller, settle_return also runs settle_refund to return\n// the whole balance to the payer. Otherwise the controller coordinates the\n// return before the operator's settle_refund returns the rest.\n// Acceptance expiry enters disputed, never released. Neither verify_return nor\n// refund becomes public merely because dispute is exposed. Clock actions remain\n// internal. Expose cancel for a pending hold, including a checkout-funded hold;\n// it returns its credited balance to payer before cancelling. Confirm requires\n// the whole captured price in held. This flow has no partial release or refund.\n\n// Cost: create declares one owned account. Fund and refund each declare one\n// transfer; accept expands the configured fee and tax into moves. Run hsx cost\n// on the composed program for instruction counts. The executor supplies prices.\n\ninstrument hold(payer: party = party(person), payee: party = programOperator, accept_within: duration = 48h, deliver_within: duration = 14d, fee: fee = { seller: 0%, tax: 0% }, dispute: policy = { refund_after: return_verified }, funding: policy = { controllers: [], reference: \"funds\", blocking_states: [active] }) {\n revisioned: true\n summary: \"Hold the subject price through delivery, acceptance and verified return.\"\n fields {\n payer: account of payer, payee: account of payee\n held: account of self, fundedAt: date?, deliverBy: date?, deliveredAt: date?, blockingFunding: integer?\n price: money = subject.price\n }\n lifecycle { states: [pending, funded, delivered, disputed, return_verified, released, refunded, cancelled], initial: pending }\n action create {\n subject { price: money }\n actor: { party: payer }\n }\n action fund {\n from: pending, to: funded, actor: { party: payer }\n set: { fundedAt: { field: self.now } }\n moves self.price from payer to self.held economics { purpose: principal, sourceParty: payer }\n }\n action confirm {\n from: pending, to: funded, actor: { parent: funding.controllers }\n requires self.held.balance == self.price\n calculate: [{ target: deliverBy, op: shift, date: { field: self.now }, milliseconds: { literal: deliver_within }, direction: after }]\n }\n action deliver {\n from: funded, to: delivered, actor: { party: payee }\n set: { deliveredAt: { field: self.now } }\n }\n action accept { allowZero: true, requires self.price > \"0\";\n from: delivered, to: released, actor: { party: payer }\n input { acceptanceReference: text }\n deadline: { at: self.deliveredAt, offset: accept_within }\n moves self.price from self.held to payee fee fee economics { payee: { recipient: payee, company: { purpose: earning, sourceParty: payer }, participant: { purpose: pass_through, sourceParty: programOperator } }, fee: { purpose: earning, sourceParty: payer }, tax: { purpose: pass_through, sourceParty: programOperator } }\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 {\n from: disputed, to: return_verified, actor: { party: payee }\n input { returnEvidence: text }\n }\n action settle_release { allowZero: true, requires self.price > \"0\";\n from: disputed, to: released, actor: { party: programOperator }\n input { ruling: text }\n moves self.price from self.held to payee fee fee economics { payee: { recipient: payee, company: { purpose: earning, sourceParty: payer }, participant: { purpose: pass_through, sourceParty: programOperator } }, fee: { purpose: earning, sourceParty: payer }, tax: { purpose: pass_through, sourceParty: programOperator } }\n }\n action settle_return {\n from: disputed, to: return_verified, actor: { party: programOperator }\n input { ruling: text }\n calculate: [{ target: blockingFunding, op: aggregate, selection: { instrument: funding.controllers, reference: funding.reference, anchor: self.id, states: funding.blocking_states, limit: 1 }, measure: count }]\n invoke: [{ reference: self.id, action: settle_refund, guard: { kind: compare, left: { field: self.blockingFunding }, operator: \"==\", right: { literal: 0 } }, input: {} }]\n }\n action settle_refund { allowZero: true,\n from: return_verified, to: refunded, actor: { party: programOperator }\n requires count of { instrument: funding.controllers, reference: funding.reference, anchor: self.id, states: funding.blocking_states, limit: 1 } == 0\n moves self.held.balance from self.held to payer economics { purpose: principal, sourceParty: programOperator }\n }\n action refund {\n from: [funded, dispute.refund_after], to: refunded, actor: { party: payee }\n requires count of { instrument: funding.controllers, reference: funding.reference, anchor: self.id, states: funding.blocking_states, limit: 1 } == 0\n moves self.held.balance from self.held to payer economics { purpose: principal, sourceParty: programOperator }\n }\n action refund_undelivered {\n from: funded, to: refunded, actor: { party: payer }\n due: { at: self.fundedAt, offset: deliver_within }\n requires count of { instrument: funding.controllers, reference: funding.reference, anchor: self.id, states: funding.blocking_states, limit: 1 } == 0\n moves self.price from self.held to payer economics { purpose: principal, sourceParty: programOperator }\n }\n action finish_refund { allowZero: true,\n from: [funded, return_verified], to: refunded, actor: { parent: funding.controllers }\n moves self.held.balance from self.held to payer economics { purpose: principal, sourceParty: programOperator }\n }\n action cancel { allowZero: true,\n from: pending, to: cancelled, actor: { party: payer }\n moves self.held.balance from self.held to payer economics { purpose: principal, sourceParty: programOperator }\n }\n}\n"],
|
|
7
7
|
["financing.hsx", "header financing\n\n// Economics: Principal advances and repayments are excluded from earnings. Claims, waivers,\n// write-offs and allocations are internal. Paid profit and company charges are\n// earnings; receipt refunds reverse captured cash. Borrower cash paid to outside\n// capital or recovery recipients passes through, whether held first or paid direct.\n\n// Pricing is required. amortizing reads profit_rate as an annual rate on the\n// declining balance: equal monthly instalments, the last absorbing rounding.\n// flat_total reads it as one charge on principal for the whole term (murabaha,\n// fixed-fee pay-later). 12,000 at 18% over 12 months costs 13,201.95 amortizing\n// and 14,160 flat_total.\n// Expose create and sign on installments. A funding composition owns checkout,\n// destination funding and returns when disburse_to is funds. The repayment plan\n// owns principal, profit, limits and debt cancellation.\n// disburse_to: seller pays principal to the seller party at activation (pay later\n// with the merchant paid on day one). Capital may refund any paid payment to\n// the borrower. Payments stay refundable while the plan is active. The\n// payment that clears the last slice completes the plan when no late charge or\n// recovery cost is outstanding; otherwise expose complete to close it once they\n// are settled or waived. When\n// the plan leaves active (paid, written off or cancelled) it sets refundUntil to\n// refund_within (default 30d) later, and payment, late charge and recovery cost\n// refunds stop at that time. A refund that reopens the plan clears refundUntil, which is set\n// from the calculated refundWindow so a restore can clear it. Once it passes,\n// nothing can move the plan's payments or late charges, so they stop counting as\n// open records. On a return, capital runs unwind: it takes the outstanding\n// principal back to capital and cancels open slices with their claims. Seller\n// mode debits the seller, who also returns the principal the borrower repaid;\n// funds mode needs the hold in return_verified and debits the hold, after which\n// the payee's escrow refund returns the down payment and the repaid principal.\n// Before delivery, the Product\n// operator runs unwind_undelivered on a funds-mode plan whose hold is still\n// funded: principal goes back to capital and the hold's unwind_financed returns\n// the down payment to the payer and closes the hold as refunded, all in one\n// operation, so deliver is refused afterwards. It also cancels proposed and\n// assessed late charges and recovery costs: goods that never arrived earn no\n// fines. Escrow refund refuses while any plan that is\n// not cancelled funds the hold, written off included, so the borrower never\n// receives lender principal. A funds-mode plan writes off only once its hold\n// has released principal to the seller: principal still held is not a loss, and\n// unwind or unwind_undelivered returns it. unwind_undelivered needs no paid\n// payments and no collected late charges; refund them first. unwind needs no\n// assessed late charges; waive them first. When goods never arrive on a paid plan, the\n// Product operator runs unwind_paid once the hold's deliverBy has passed, so an\n// early payoff never cuts the seller's delivery window short. It refunds every\n// payment, share, profit piece, fine and cost receipt and reverses the payoff's\n// profit, fines and costs, cancels the plan, and returns the hold's whole price\n// to the borrower; capital keeps the principal the borrower repaid. A settlement\n// a lending.distribution has paid out keeps its profit and share, since investors\n// hold that profit; only the other settlements' profit is refunded. unwind_paid\n// selects at most max_history (default and most 366) of each record kind, so\n// a payment refuses when it would leave more paid payments than max_history\n// less one, keeping a settlement for the payoff, or more paid profit pieces,\n// fine receipts or cost receipts than max_history; a fine or a recovery cost\n// refuses past max_history unwaived fines or costs on the plan, counted across\n// every late charge attachment, so a waived fine's cost keeps its own slot. A company lowers it to keep unwinds smaller. If any\n// source account is short, the whole action refuses and nothing moves; a\n// company that wants a partial refund writes that rule in its own program.\n// returned_goods decides the split on returned goods, before or after payoff.\n// keep_profit, the default, keeps the profit and fines paid so far with the\n// company: unwind runs with payments still paid, and on a paid plan the Product\n// operator runs return_hold after the refund window to return a return_verified\n// hold's whole balance. refund_all makes unwind wait until capital has refunded\n// every payment and collected charge, removes return_hold, and lets unwind_paid\n// settle returned goods too.\n// Borrower- and seller-directed disbursement exclude collect_down_payment. A down_payment\n// there reduces principal but does not collect cash. Price is subject metadata,\n// not the borrower limit. The funding composition checks its payer and price.\n// Cancelling a plan cancels its debt agreement. Its funding composition owns\n// returning any cash collected before activation.\n// Approve borrower and portfolio limits before disbursement. Create builds the\n// dated slice records from future, strictly increasing dates; disbursement\n// refuses once a slice is due. Payments need a separate payment record and pay action.\n// Expose parent payoff separately and create a current, unexpired payoff_quote.\n// Expose late_charge.create as propose_assessment before the clock can assess;\n// provide matching plan, slice and borrower. Fine is fixed money, not a percentage.\n// Collection uses the minimum of payment cash and outstanding fine; a partial\n// payment does not settle the remaining fine. Recovery cost needs its own record,\n// which only the Product operator creates; only it cancels a proposed fine or cost.\n// Profit share credits capital's allocatedProfitPayable, not an outside agency.\n// Credit lines need adapter binding at activation; draws are ledger advances,\n// not evidence of outside funding. Only the line's borrower, the Product operator\n// by default, opens and closes the line and creates, draws, repays or cancels an\n// advance on it. Only the Product operator creates the portfolio limit and\n// approves borrower and portfolio limits. No clock declaration proves retries.\n\n// Cost: installments include cash and claim moves, child-account creation and\n// bounded invocations across slices and assessments. Month and charge limits affect\n// the bound. Run hsx cost on the selected policies; profit is not a platform tariff.\n\ninstrument installments(months: integer(1, 366), max_history: integer(2, 366) = 366, pricing: enum(amortizing, flat_total), profit_rate: percent, charge_limit: integer(1, 3) = 3, disburse_to: enum(funds, borrower, seller) = funds, seller: party?, 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, refund_within: duration = 30d, returned_goods: enum(keep_profit, refund_all) = keep_profit, allow_overdue: enum(allowed, blocked) = allowed, assessed_fines: enum(carry, require_waiver) = carry, down_payment: percent = 0%, funds: ref?, borrower: party = party(person), capital: party = programOperator, share: percent = 0%, limits: ref<financing.limits> = object(financing.limits), portfolio: ref<financing.portfolio_limit> = object(financing.portfolio_limit)) {\n dependencies {\n funds {\n selector: disburse_to, is: funds\n message: \"Attachment `{attachment}` disburses into a hold, but `funds` is not bound.\"\n fix: \"Bind `funds: checkout` to a funding composition. Choose `disburse_to: seller` to pay a seller on activation, or `disburse_to: borrower` only if the borrower should receive the money directly.\"\n }\n seller {\n selector: disburse_to, is: seller\n message: \"Attachment `{attachment}` pays a seller, but `seller` is not bound.\"\n fix: \"Bind `seller: merchant` to the declared business that receives the principal.\"\n }\n }\n revisioned: true\n familyRevision: 1\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<portfolio>\n months: integer = months, dates: list(date, months), historyLimit: integer = max_history, paymentLimit: integer = subtract(max_history, 1)\n allocatedPayable: account(capital, cash, \"allocatedProfitPayable\"), capital: account(capital, cash, \"capital\"), profitIncome: account(capital, cash, \"profitIncome\"), loss: account(capital, claim, \"loss\")\n principalOutstanding: money?, principalRepaid: money?, principalReturned: money?, profitReturned: money?, lossRecorded: money?, refundWindow: date?, refundUntil: date?\n openSlices: integer?, openCharges: money?, openCosts: money?, payoffRefunds: integer?\n price: money = subject.price\n downPayment: money = rate(self.price, down_payment)\n principal: money = subtract(self.price, self.downPayment)\n flatProfit: money?\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 subject { price: money }\n actor: { party: borrower }\n requires self.borrowerLimit.borrower == self.borrower\n when pricing is flat_total { calculate: [{ target: flatProfit, op: rate, base: { field: self.principal }, bps: { literal: profit_rate }, rounding: floor }] }\n when disburse_to is funds { invoke: [{ reference: self.funds, action: check, input: { plan: { field: self.id } } }] }\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 } } }, { selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [draft], limit: months, where: { first: { literal: 0 } } }, action: check_order, input: {} }]\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 }\n action collect_down_payment { allowZero: true,\n from: signed, to: signed, actor: { party: borrower }\n when disburse_to is borrower { requires true == false }\n when disburse_to is seller { requires true == false }\n when disburse_to is funds { invoke: [{ reference: self.funds, action: collect, input: { plan: { field: self.id } } }] }\n }\n action disburse { allowZero: true,\n from: signed, to: active, actor: { party: capital }\n requires self.borrowerLimit in [approved]\n requires self.portfolioLimit in [approved]\n when disburse_to is funds { invoke: [{ reference: self.funds, action: disburse, input: { plan: { field: self.id } } }] }\n when disburse_to is borrower { moves self.principal from self.capital to self.borrower economics { purpose: principal, sourceParty: capital } }\n when disburse_to is seller { moves self.principal from self.capital to seller economics { purpose: principal, sourceParty: capital } }\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [draft], limit: 366, order: [position] }, action: activate, input: {} }]\n }\n action complete {\n from: active, to: paid\n calculate: [{ target: refundWindow, op: shift, date: { field: self.now }, milliseconds: { literal: refund_within }, direction: after }]\n set: { refundUntil: { field: self.refundWindow } }\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 }, input { refundUntil: date? }, set: { refundUntil: { field: input.refundUntil } } }\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 { target: refundWindow, op: shift, date: { field: self.now }, milliseconds: { literal: refund_within }, direction: after }\n ]\n set: { refundUntil: { field: self.refundWindow } }\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, actor: { parent: write_off_request }\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\" } }, { target: refundWindow, op: shift, date: { field: self.now }, milliseconds: { literal: refund_within }, direction: after }]\n set: { refundUntil: { field: self.refundWindow } }\n due: { at: input.overdueSlice.lossEligibleAt }\n requires input.overdueSlice.plan == self.id; requires input.overdueSlice.principalReceivable.balance > \"0\"\n when disburse_to is funds { invoke: [{ reference: self.funds, action: write_off, input: { plan: { field: self.id } } }] }\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 calculate: [\n { target: openSlices, op: aggregate, selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [pending, due], limit: 366 }, measure: count }\n { target: openCharges, op: aggregate, selection: { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.id, states: [assessed, collected], limit: 366 }, measure: { sum: \"receivable.balance\" } }\n { target: openCosts, op: aggregate, selection: { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.id, states: [assessed, collected], limit: 366 }, measure: { sum: \"receivable.balance\" } }\n ]\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 invoke: [{ selection: { instrument: current(), reference: \"borrowerLimit\", anchor: self.borrowerLimit, states: [active], limit: 1, where: { id: { field: self.id }, openSlices: { literal: 0 }, openCharges: { literal: \"0\" }, openCosts: { literal: \"0\" } } }, action: complete, input: {} }]\n }\n action cancel { from: quoted, to: cancelled }\n action void { from: signed, to: cancelled, actor: { party: borrower } }\n action unwind { allowZero: true,\n from: active, to: cancelled, actor: { party: capital }\n calculate: [\n { target: refundWindow, op: shift, date: { field: self.now }, milliseconds: { literal: refund_within }, direction: after }\n { target: principalOutstanding, op: aggregate, selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [pending, due], limit: 366 }, measure: { sum: \"principalReceivable.balance\" } }\n { target: principalRepaid, op: subtract, base: { field: self.principal }, subtract: [{ field: self.principalOutstanding }] }\n ]\n set: { refundUntil: { field: self.refundWindow } }\n when disburse_to is borrower { requires true == false }\n when returned_goods is refund_all {\n requires count of { instrument: payment, reference: \"plan\", anchor: self.id, states: [paid], limit: 366 } == 0\n requires count of { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.id, states: [collected], limit: 366 } == 0\n requires count of { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.id, states: [collected], limit: 366 } == 0\n }\n requires count of { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.id, states: [assessed], limit: 366 } == 0\n requires count of { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.id, states: [assessed], limit: 366 } == 0\n when disburse_to is funds { invoke: [{ reference: self.funds, action: refund, input: { plan: { field: self.id }, principal: { field: self.principalOutstanding } } }] }\n when disburse_to is seller {\n moves self.principalOutstanding from seller to self.capital economics { purpose: principal, sourceParty: seller }\n moves self.principalRepaid from seller to self.borrower economics { purpose: principal, sourceParty: seller }\n }\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [pending, due], limit: 366, order: [position] }, action: cancel, input: {} }]\n }\n action unwind_undelivered { allowZero: true,\n from: active, to: cancelled, actor: { party: programOperator }\n calculate: [{ target: refundWindow, op: shift, date: { field: self.now }, milliseconds: { literal: refund_within }, direction: after }]\n set: { refundUntil: { field: self.refundWindow } }\n when disburse_to is borrower { requires true == false }\n when disburse_to is seller { requires true == false }\n requires count of { instrument: payment, reference: \"plan\", anchor: self.id, states: [paid], limit: 366 } == 0\n requires count of { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.id, states: [collected], limit: 366 } == 0\n requires count of { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.id, states: [collected], limit: 366 } == 0\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [pending, due], limit: 366, order: [position] }, action: cancel, input: {} }]\n invoke: [{ selection: { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.id, states: [proposed, assessed], limit: 366 }, action: cancel_undelivered, input: {} }, { selection: { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.id, states: [proposed, assessed], limit: 366 }, action: cancel_undelivered, input: {} }]\n when disburse_to is funds { invoke: [{ reference: self.funds, action: cancel_undelivered, input: { plan: { field: self.id } } }] }\n }\n action return_hold {\n from: paid, to: paid, actor: { party: programOperator }\n requires self.refundUntil < self.now\n when disburse_to is borrower { requires true == false }\n when disburse_to is seller { requires true == false }\n when returned_goods is refund_all { requires true == false }\n when disburse_to is funds {\n invoke: [{ reference: self.funds, action: return_paid, input: { plan: { field: self.id } } }]\n }\n }\n action unwind_paid {\n from: paid, to: cancelled, actor: { party: programOperator }\n when disburse_to is borrower { requires true == false }\n when disburse_to is seller { requires true == false }\n invoke: [{ selection: { instrument: settlement, reference: \"plan\", anchor: self.id, states: [recorded], limit: max_history }, action: unwind, input: {} }, { selection: { instrument: profit_piece, reference: \"plan\", anchor: self.id, states: [paid], limit: max_history, where: { payment.status: { literal: \"refunded\" } } }, action: refund, input: {} }, { selection: { instrument: payment, reference: \"plan\", anchor: self.id, states: [paid], limit: max_history }, action: unwind, input: {} }, { reference: self.id, action: unwind_payoff_profit, input: {} }]\n invoke: [{ selection: { instrument: all(financing.late_charge.receipt), reference: \"plan\", anchor: self.id, states: [paid], limit: max_history }, action: refund, input: {} }, { selection: { instrument: all(financing.late_charge.cost.receipt), reference: \"plan\", anchor: self.id, states: [paid], limit: max_history }, action: refund, input: {} }, { selection: { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.id, states: [collected], limit: max_history }, action: unwind_payoff, input: {} }, { selection: { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.id, states: [collected], limit: max_history }, action: unwind_payoff, input: {} }]\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [pending, due, paid], limit: 366, order: [position] }, action: cancel, input: {} }]\n invoke: [{ selection: { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.id, states: [proposed, assessed, collected], limit: max_history }, action: cancel_undelivered, input: {} }, { selection: { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.id, states: [proposed, assessed, collected], limit: max_history }, action: cancel_undelivered, input: {} }]\n when disburse_to is funds {\n when returned_goods is keep_profit { invoke: [{ reference: self.funds, action: unwind_paid_undelivered, input: { plan: { field: self.id } } }] }\n when returned_goods is refund_all { invoke: [{ reference: self.funds, action: unwind_paid, input: { plan: { field: self.id } } }] }\n }\n }\n action unwind_payoff_profit {\n from: cancelled, to: cancelled, actor: { parent: current() }\n calculate: [{ target: payoffRefunds, op: aggregate, selection: { instrument: settlement, reference: \"plan\", anchor: self.id, states: [refunded], limit: 1, where: { identity: { field: self.settlementIdentity } } }, measure: count }]\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [paid], limit: 366, where: { payoffIdentity: { field: self.settlementIdentity } } }, action: unwind_payoff, guard: { kind: compare, left: { field: self.payoffRefunds }, operator: \"==\", right: { literal: 1 } }, input: {} }]\n }\n records {\n write_off_request: {\n fields { plan: ref<parent>, overdueSlice: ref<slice> }\n lifecycle { states: [requested, applied, cancelled], initial: requested }\n action create { requires self.overdueSlice.plan == self.plan; requires self.plan in [active] }\n action apply {\n from: requested, to: applied, actor: { party: capital }\n invoke: [{ reference: self.plan, action: write_off, input: { overdueSlice: { field: self.overdueSlice } } }]\n }\n action cancel { from: requested, to: cancelled }\n }\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: capital }\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 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_for_amendment, input: {} }, { selection: { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.plan, states: [proposed], limit: 366 }, action: cancel_for_amendment, 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: capital } }\n action decline { from: proposed, to: declined, actor: { party: borrower } }\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), share: money?, retainedProfit: money?\n allocatedPayable: account(capital, cash, \"allocatedProfitPayable\"), capital: account(capital, cash, \"capital\"), profitIncome: account(capital, cash, \"profitIncome\"), lossAccount: account(capital, claim, \"loss\") }\n lifecycle { states: [recorded, distributed, refunded], initial: recorded }\n action create { allowZero: true,\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 calculate: [{ target: \"share\", op: \"rate\", base: { field: self.profit }, bps: { literal: share }, rounding: \"floor\" }, { target: retainedProfit, op: \"subtract\", base: { field: self.profit }, subtract: [{ field: self.share }] }]\n moves self.share from self.profitIncome to self.allocatedPayable economics { purpose: internal, sourceParty: capital }\n }\n action refund { allowZero: true,\n from: recorded, to: refunded, actor: { parent: payment }\n moves self.share from self.allocatedPayable to self.profitIncome economics { purpose: internal, sourceParty: capital }\n }\n action distribute { from: recorded, to: distributed, actor: { parent: all(lending.distribution) } }\n // profitIncome is one account per capital party, so refunding profit a\n // distribution already paid out would spend other plans' profit. unwind_paid\n // unwinds only settlements still recorded; each marks its payment refunded,\n // and the plan refunds the profit pieces and payoff profit behind them.\n action unwind { allowZero: true,\n from: recorded, to: refunded, actor: { parent: parent }\n moves self.share from self.allocatedPayable to self.profitIncome economics { purpose: internal, sourceParty: capital }\n invoke: [{ selection: { instrument: payment, reference: \"plan\", anchor: self.plan, states: [paid], limit: 1, where: { paymentIdentity: { field: self.identity } } }, action: unwind, input: {} }]\n }\n }\n slice: {\n revisioned: true\n fields {\n plan: ref<parent>, borrowerLimit: ref<limits>, portfolioLimit: ref<portfolio>, position: integer(1, months)\n originalDueAt: date = at(self.plan.dates, self.position), dueAt: date?, nextDueAt: date?, previousDueAt: date?, prior: integer = subtract(self.position, 1), previousPosition: integer = sum(self.prior, self.first), previousDate: date = at(self.plan.dates, self.previousPosition), extensionLimit: date = after(self.originalDueAt, max_extension), lossEligibleAt: date?\n first: integer = divide(1, self.position)\n principalBase: money?, principalAllocated: money?, principalRemainder: money?, principalAdjustment: money?\n profitBase: money?, profitAllocated: money?, profitRemainder: money?, profitAdjustment: money?\n principal: money, profit: money, instalment: money\n principalReceivable: account(self, claim), profitReceivable: account(self, claim), profitEarned: account(self, claim)\n payoffIdentity: text?, payoffRebate: money?, payoffProfitTotal: money?, payoffProfit: money?, payoffReceipt: text?\n paymentBudget: money?, principalPayment: money?, principalBasePayment: money?, principalRatio: money?, profitPayment: money?, profitBudget: money?, collectibleProfit: money?, collectibleTotal: money?, ratioDenominator: integer = sum(10000, profit_rate)\n debt: account(borrower, claim, contra, \"debt\"), loss: account(capital, claim, \"loss\")\n }\n lifecycle { states: [draft, pending, due, paid, written_off, cancelled], initial: draft }\n action create {\n actor: { parent: parent }\n input { plan: ref<parent>, borrowerLimit: ref<limits>, portfolioLimit: ref<portfolio>, position: integer(1, months) }\n set: { dueAt: { field: self.originalDueAt } }\n when pricing is flat_total {\n calculate: [\n { target: principalBase, op: divide, amount: { field: self.plan.principal }, divisor: { literal: months }, rounding: floor }\n { target: principalAllocated, op: multiply, amount: { field: self.principalBase }, units: { literal: months } }\n { target: principalRemainder, op: subtract, base: { field: self.plan.principal }, subtract: [{ field: self.principalAllocated }] }\n { target: principalAdjustment, op: multiply, amount: { field: self.principalRemainder }, units: { field: self.first } }\n { target: principal, op: sum, values: [{ field: self.principalBase }, { field: self.principalAdjustment }] }\n { target: profitBase, op: divide, amount: { field: self.plan.flatProfit }, divisor: { literal: months }, rounding: floor }\n { target: profitAllocated, op: multiply, amount: { field: self.profitBase }, units: { literal: months } }\n { target: profitRemainder, op: subtract, base: { field: self.plan.flatProfit }, subtract: [{ field: self.profitAllocated }] }\n { target: profitAdjustment, op: multiply, amount: { field: self.profitRemainder }, units: { field: self.first } }\n { target: profit, op: sum, values: [{ field: self.profitBase }, { field: self.profitAdjustment }] }\n { target: instalment, op: sum, values: [{ field: self.principal }, { field: self.profit }] }\n ]\n }\n when pricing is amortizing {\n calculate: [\n { target: principal, op: annuity, amount: { field: self.plan.principal }, rate: { literal: profit_rate }, periods: { literal: months }, position: { field: self.position }, part: principal }\n { target: profit, op: annuity, amount: { field: self.plan.principal }, rate: { literal: profit_rate }, periods: { literal: months }, position: { field: self.position }, part: interest }\n { target: instalment, op: sum, values: [{ field: self.principal }, { field: self.profit }] }\n ]\n }\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 requires self.originalDueAt > self.now; requires self.originalDueAt >= self.previousDate\n }\n action check_order { from: draft, to: draft, actor: { parent: parent }, requires self.originalDueAt > self.previousDate }\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 { allowZero: true,\n from: draft, to: pending, actor: { parent: parent }\n requires self.dueAt > self.now\n moves self.principal from self.debt to self.principalReceivable economics { purpose: internal, sourceParty: borrower }\n moves self.profit from self.debt to self.profitReceivable economics { purpose: internal, sourceParty: borrower }\n when profit_earned is at_disbursement { moves self.profit from self.profitReceivable to self.profitEarned economics { purpose: internal, sourceParty: programOperator } }\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: { plan: { field: self.plan }, 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: { plan: { field: self.plan }, 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 ]\n when pricing is flat_total { calculate: [{ target: principalRatio, op: ratio, amount: { field: self.paymentBudget }, numerator: { literal: 10000 }, denominator: { field: self.ratioDenominator }, rounding: floor }] }\n when pricing is amortizing { calculate: [{ target: principalRatio, op: ratio, amount: { field: self.paymentBudget }, numerator: { field: self.principal }, denominator: { field: self.instalment }, rounding: floor }] }\n calculate: [\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: { plan: { field: self.plan }, 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 { allowZero: true,\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 economics { purpose: principal, sourceParty: borrower }\n moves self.payoffProfit from self.plan.borrower to self.plan.profitIncome capture \"payoffReceipt\" economics { recipient: capital, company: { purpose: earning, sourceParty: borrower }, participant: { purpose: pass_through, sourceParty: borrower } }\n moves self.principalReceivable.balance from self.principalReceivable to self.debt economics { purpose: internal, sourceParty: programOperator }\n moves self.profitReceivable.balance from self.profitReceivable to self.debt economics { purpose: internal, sourceParty: programOperator }\n moves self.profitEarned.balance from self.profitEarned to self.debt economics { purpose: internal, sourceParty: programOperator }\n }\n action unwind_payoff { allowZero: true,\n from: paid, to: paid, actor: { parent: parent }\n moves self.payoffProfit from self.plan.profitIncome to self.plan.borrower economics { recipient: capital, company: { purpose: earning, sourceParty: capital, reversalOf: self.payoffReceipt }, participant: unclassified }\n }\n action write_off { allowZero: true,\n from: [pending, due], to: written_off, actor: { parent: parent }\n moves self.principalReceivable.balance from self.principalReceivable to self.loss economics { purpose: internal, sourceParty: programOperator }; moves self.profitReceivable.balance from self.profitReceivable to self.debt economics { purpose: internal, sourceParty: programOperator }; moves self.profitEarned.balance from self.profitEarned to self.loss economics { purpose: internal, sourceParty: programOperator }\n }\n action cancel { allowZero: true,\n from: [pending, due, paid], to: cancelled, actor: { parent: parent }\n moves self.principalReceivable.balance from self.principalReceivable to self.debt economics { purpose: internal, sourceParty: programOperator }; moves self.profitReceivable.balance from self.profitReceivable to self.debt economics { purpose: internal, sourceParty: programOperator }; moves self.profitEarned.balance from self.profitEarned to self.debt economics { purpose: internal, sourceParty: programOperator }\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 }, calculate: [{ target: dueAt, op: shift, date: { field: self.slice.dueAt }, milliseconds: { literal: 0 }, direction: after }] }\n action mature { allowZero: true, from: pending, to: recognised, actor: clock, due: { at: self.dueAt }, moves self.slice.profitReceivable.balance from self.slice.profitReceivable to self.slice.profitEarned economics { purpose: internal, sourceParty: programOperator } }\n }\n payment: {\n revisioned: true\n fields { plan: ref<parent>, amount: money, paymentIdentity: text, held: account of self\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, actor: { party: borrower }\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 economics { purpose: principal, sourceParty: borrower }\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 requires count of { instrument: current(), reference: \"plan\", anchor: self.plan, states: [paid], limit: 366 } <= self.plan.paymentLimit\n requires count of { instrument: profit_piece, reference: \"plan\", anchor: self.plan, states: [paid], limit: 366 } <= self.plan.historyLimit\n requires count of { instrument: all(financing.late_charge.receipt), reference: \"plan\", anchor: self.plan, states: [paid], limit: 366 } <= self.plan.historyLimit\n requires count of { instrument: all(financing.late_charge.cost.receipt), reference: \"plan\", anchor: self.plan, states: [paid], limit: 366 } <= self.plan.historyLimit\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 unwind { from: paid, to: refunded, actor: { parent: [parent, settlement] } }\n action refund {\n from: paid, to: refunded, actor: { party: capital }, deadline: { at: self.plan.refundUntil }\n requires unique \"settlement_consumption\" on [self.plan, self.paymentIdentity]; requires self.plan in [active, paid]\n requires count of { instrument: settlement, reference: \"plan\", anchor: self.plan, states: [recorded], limit: 366, where: { identity: { field: self.paymentIdentity } } } == 1\n invoke: [{ selection: { instrument: settlement, reference: \"plan\", anchor: self.plan, states: [recorded], limit: 366, where: { identity: { field: self.paymentIdentity } } }, action: refund, input: {} }]\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 { allowZero: true,\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 economics { purpose: principal, sourceParty: programOperator }; moves self.amount from self.slice.principalReceivable to self.slice.debt economics { purpose: internal, sourceParty: programOperator }\n }\n action refund { allowZero: true,\n from: paid, to: refunded, actor: { parent: payment }\n moves self.amount from self.slice.plan.capital to self.slice.plan.borrower economics { purpose: principal, sourceParty: capital }; moves self.amount from self.slice.debt to self.slice.principalReceivable economics { purpose: internal, sourceParty: borrower }\n }\n }\n profit_piece: {\n fields { cashReceipt: text?, plan: ref<parent>, slice: ref<slice>, payment: ref<payment>, limit: money, amount: money? }\n lifecycle { states: [paid, refunded], initial: paid }\n action create { allowZero: true,\n calculate: [{ target: amount, op: minimum, values: [{ field: self.payment.held.balance }, { field: self.limit }] }]\n actor: { parent: slice }\n input { plan: ref<parent>, 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 capture \"cashReceipt\" economics { recipient: capital, company: { purpose: earning, sourceParty: borrower }, participant: { purpose: pass_through, sourceParty: programOperator } }\n when profit_earned is on_payment { moves self.amount from self.slice.profitReceivable to self.slice.debt economics { purpose: internal, sourceParty: programOperator } }\n when profit_earned is by_schedule { moves self.amount from self.slice.profitEarned to self.slice.debt economics { purpose: internal, sourceParty: programOperator } }\n when profit_earned is at_disbursement { moves self.amount from self.slice.profitEarned to self.slice.debt economics { purpose: internal, sourceParty: programOperator } }\n }\n action refund { allowZero: true,\n from: paid, to: refunded, actor: { parent: [payment, parent] }\n moves self.amount from self.slice.plan.profitIncome to self.slice.plan.borrower economics { recipient: capital, company: { purpose: earning, sourceParty: capital, reversalOf: self.cashReceipt }, participant: unclassified }\n when profit_earned is on_payment { moves self.amount from self.slice.debt to self.slice.profitReceivable economics { purpose: internal, sourceParty: borrower } }\n when profit_earned is by_schedule { moves self.amount from self.slice.debt to self.slice.profitEarned economics { purpose: internal, sourceParty: borrower } }\n when profit_earned is at_disbursement { moves self.amount from self.slice.debt to self.slice.profitEarned economics { purpose: internal, sourceParty: borrower } }\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, borrower: party = party(person)) {\n parameterDiagnostics {\n fine {\n accepts: \"a fixed amount\"\n percentage: \"a percentage of overdue debt\"\n fix: \"Use a fixed amount only if that is the intended policy. A percentage charge needs an authored rate calculation; do not approximate it with a cash amount.\"\n }\n }\n revisioned: true\n familyRevision: 1\n summary: \"Separate 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?, payoffAmount: money?, payoffReceipt: text?\n receivable: account(self, claim), debt: account(borrower, claim, contra, \"debt\")\n }\n lifecycle { states: [proposed, assessed, collected, waived], initial: proposed }\n action create { input { slice: ref<on.slice>? }, calculate: [{ target: overdueAt, op: shift, date: { field: self.slice.dueAt }, milliseconds: { literal: grace }, direction: after }, { target: payoffAmount, op: sum, values: [{ literal: \"0\" }] }], requires unique \"late_assessment\" on [self.slice, self.overdueAt]; requires self.borrower == self.slice.plan.borrower; requires self.plan == self.slice.plan; requires count of { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.plan, states: [proposed, assessed, collected], limit: 366 } < self.plan.historyLimit }\n action assess { allowZero: true,\n from: proposed, to: assessed, actor: clock, due: { at: self.overdueAt }\n requires self.slice.principalReceivable.balance > \"0\"\n moves self.fine from self.debt to self.receivable economics { purpose: internal, sourceParty: borrower }\n }\n action collect {\n from: [assessed, collected], to: assessed, actor: { parent: child(on, slice) }, 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: { plan: { field: self.plan }, 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 { allowZero: true,\n from: [assessed, collected], to: collected, actor: { parent: on }\n requires self.plan in [paid]\n calculate: [{ target: payoffAmount, op: sum, values: [{ field: self.receivable.balance }] }]\n moves self.payoffAmount from self.plan.borrower to fines_to capture \"payoffReceipt\" economics { recipient: fines_to, company: { purpose: earning, sourceParty: borrower }, participant: { purpose: pass_through, sourceParty: borrower } }\n moves self.payoffAmount from self.receivable to self.debt economics { purpose: internal, sourceParty: programOperator }\n }\n action unwind_payoff { allowZero: true,\n from: collected, to: collected, actor: { parent: on }\n moves self.payoffAmount from fines_to to self.plan.borrower economics { recipient: fines_to, company: { purpose: earning, sourceParty: fines_to, reversalOf: self.payoffReceipt }, participant: unclassified }\n }\n action finish { from: assessed, to: collected, actor: { parent: current() }, requires self.receivable.balance == \"0\" }\n action cancel { from: proposed, to: waived, actor: { party: programOperator } }\n action cancel_for_amendment { from: proposed, to: waived, actor: { parent: child(on, amendment) } }\n action cancel_undelivered { allowZero: true, from: [proposed, assessed, collected], to: waived, actor: { parent: on }, moves self.receivable.balance from self.receivable to self.debt economics { purpose: internal, sourceParty: programOperator } }\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 { allowZero: true, from: [assessed, collected], to: waived, actor: { parent: waiver_request }, input { reason: text, evidence: text }, moves self.receivable.balance from self.receivable to self.debt economics { purpose: internal, sourceParty: programOperator } }\n action refund {\n from: [assessed, collected], to: assessed, actor: { party: fines_to }, input { payment: ref<on.payment> }, deadline: { at: self.plan.refundUntil }\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_request: {\n fields { assessment: ref<parent>, reason: text, evidence: text }\n lifecycle { states: [requested, applied, cancelled], initial: requested }\n action create { requires self.assessment in [assessed, collected] }\n action apply {\n from: requested, to: applied, actor: { party: fines_to }, input { reason: text, evidence: text }\n invoke: [{ reference: self.assessment, action: waive, input: { reason: { field: input.reason }, evidence: { field: input.evidence } } }]\n }\n action cancel { from: requested, to: cancelled }\n }\n waiver: {\n fields { assessment: ref<parent>, amendment: ref<on.amendment>, amount: money? }\n lifecycle { states: [recorded], initial: recorded }\n action create { allowZero: true,\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 economics { purpose: internal, sourceParty: programOperator }\n }\n }\n receipt: {\n fields { cashReceipt: text?, plan: ref<on>, assessment: ref<parent>, payment: ref<on.payment>, amount: money? }\n lifecycle { states: [paid, refunded], initial: paid }\n action create { allowZero: true, calculate: [{ target: amount, op: minimum, values: [{ field: self.payment.held.balance }, { field: self.assessment.receivable.balance }] }], actor: { parent: parent }, input { plan: ref<on>, 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 capture \"cashReceipt\" economics { recipient: fines_to, company: { purpose: earning, sourceParty: borrower }, participant: { purpose: pass_through, sourceParty: programOperator } }; moves self.amount from self.assessment.receivable to self.assessment.debt economics { purpose: internal, sourceParty: programOperator } }\n action refund { allowZero: true, from: paid, to: refunded, actor: { parent: [parent, on] }, moves self.amount from fines_to to self.payment.plan.borrower economics { recipient: fines_to, company: { purpose: earning, sourceParty: fines_to, reversalOf: self.cashReceipt }, participant: unclassified }; moves self.amount from self.assessment.debt to self.assessment.receivable economics { purpose: internal, sourceParty: borrower } }\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), payoffAmount: money?, payoffReceipt: text?\n receivable: account(self, claim), debt: account(borrower, claim, contra, \"debt\")\n }\n lifecycle { states: [proposed, assessed, collected, waived], initial: proposed }\n action create { actor: { party: programOperator }, calculate: [{ target: overdueAt, op: shift, date: { field: self.assessment.overdueAt }, milliseconds: { literal: 0 }, direction: after }, { target: payoffAmount, op: sum, values: [{ literal: \"0\" }] }], requires unique \"recovery_assessment\" on [self.assessment]; requires self.plan == self.assessment.plan; requires count of { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.plan, states: [proposed, assessed, collected], limit: 366 } < self.plan.historyLimit }\n action assess { allowZero: true,\n from: proposed, to: assessed, actor: clock, due: { at: self.assessment.overdueAt }\n requires self.assessment.slice.principalReceivable.balance > \"0\"\n moves self.amount from self.debt to self.receivable economics { purpose: internal, sourceParty: borrower }\n }\n action collect {\n from: [assessed, collected], to: assessed, actor: { parent: child(on, slice) }, 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: { plan: { field: self.plan }, 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 { allowZero: true,\n from: [assessed, collected], to: collected, actor: { parent: on }\n requires self.plan in [paid]\n calculate: [{ target: payoffAmount, op: sum, values: [{ field: self.receivable.balance }] }]\n moves self.payoffAmount from self.plan.borrower to costs_to capture \"payoffReceipt\" economics { recipient: costs_to, company: { purpose: earning, sourceParty: borrower }, participant: { purpose: pass_through, sourceParty: borrower } }\n moves self.payoffAmount from self.receivable to self.debt economics { purpose: internal, sourceParty: programOperator }\n }\n action unwind_payoff { allowZero: true,\n from: collected, to: collected, actor: { parent: on }\n moves self.payoffAmount from costs_to to self.plan.borrower economics { recipient: costs_to, company: { purpose: earning, sourceParty: costs_to, reversalOf: self.payoffReceipt }, participant: unclassified }\n }\n action finish { from: assessed, to: collected, actor: { parent: current() }, requires self.receivable.balance == \"0\" }\n action cancel { from: proposed, to: waived, actor: { party: programOperator } }\n action cancel_for_amendment { from: proposed, to: waived, actor: { parent: child(on, amendment) } }\n action cancel_undelivered { allowZero: true, from: [proposed, assessed, collected], to: waived, actor: { parent: on }, moves self.receivable.balance from self.receivable to self.debt economics { purpose: internal, sourceParty: programOperator } }\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 { allowZero: true, from: [assessed, collected], to: waived, actor: { parent: waiver_request }, input { reason: text, evidence: text }, moves self.receivable.balance from self.receivable to self.debt economics { purpose: internal, sourceParty: programOperator } }\n action refund {\n from: [assessed, collected], to: assessed, actor: { party: costs_to }, input { payment: ref<on.payment> }, deadline: { at: self.plan.refundUntil }\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_request: {\n fields { assessment: ref<parent>, reason: text, evidence: text }\n lifecycle { states: [requested, applied, cancelled], initial: requested }\n action create { requires self.assessment in [assessed, collected] }\n action apply {\n from: requested, to: applied, actor: { party: costs_to }, input { reason: text, evidence: text }\n invoke: [{ reference: self.assessment, action: waive, input: { reason: { field: input.reason }, evidence: { field: input.evidence } } }]\n }\n action cancel { from: requested, to: cancelled }\n }\n waiver: {\n fields { assessment: ref<parent>, amendment: ref<on.amendment>, amount: money? }\n lifecycle { states: [recorded], initial: recorded }\n action create { allowZero: true,\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 economics { purpose: internal, sourceParty: programOperator }\n }\n }\n receipt: {\n fields { cashReceipt: text?, plan: ref<on>, assessment: ref<parent>, payment: ref<on.payment>, amount: money? }\n lifecycle { states: [paid, refunded], initial: paid }\n action create { allowZero: true, calculate: [{ target: amount, op: minimum, values: [{ field: self.payment.held.balance }, { field: self.assessment.receivable.balance }] }], actor: { parent: parent }, input { plan: ref<on>, 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 capture \"cashReceipt\" economics { recipient: costs_to, company: { purpose: earning, sourceParty: borrower }, participant: { purpose: pass_through, sourceParty: programOperator } }; moves self.amount from self.assessment.receivable to self.assessment.debt economics { purpose: internal, sourceParty: programOperator } }\n action refund { allowZero: true, from: paid, to: refunded, actor: { parent: [parent, on] }, moves self.amount from costs_to to self.payment.plan.borrower economics { recipient: costs_to, company: { purpose: earning, sourceParty: costs_to, reversalOf: self.cashReceipt }, participant: unclassified }; moves self.amount from self.assessment.debt to self.assessment.receivable economics { purpose: internal, sourceParty: borrower } }\n }\n }\n }\n }\n}\n\ninstrument limits(per_borrower: money, borrower: party = party(person), active_plans: integer = 1) {\n familyRevision: 1\n scope: product\n summary: \"One outstanding balance ceiling per borrower.\"\n fields { borrower: account of borrower, limit: money = per_borrower, activePlans: integer = active_plans }\n lifecycle { states: [pending, approved], initial: pending }\n action create { actor: { party: borrower }, requires unique \"borrower_limit\" on [self.borrower] }\n action approve { from: pending, to: approved, actor: { party: programOperator } }\n}\n\ninstrument portfolio_limit(limit: money) {\n familyRevision: 1\n scope: product\n summary: \"One shared ceiling on the principal the product may hold.\"\n fields { key: text = \"portfolio\", limit: money = limit }\n lifecycle { states: [pending, approved], initial: pending }\n action create { actor: { party: programOperator }, requires unique \"portfolio_limit\" on [self.key] }\n action approve { from: pending, to: approved, actor: { party: programOperator } }\n}\n\ninstrument credit_line(borrower: party = programOperator, adapter: text, limit: money, expires: date) {\n familyRevision: 1\n summary: \"A revolving facility from an outside lender; each draw is a separate immutable advance.\"\n fields { borrower: account of borrower, facility: account(borrower, cash, \"facility\"), debt: account(borrower, claim, contra, \"debt\"), limit: money = limit, expiresAt: date = expires }\n lifecycle { states: [pending, active, suspended, closed], initial: pending }\n action create { actor: { party: borrower } }\n action activate {\n from: pending, to: active, actor: { party: borrower }\n subject { adapter: adapter }\n }\n action suspend { from: active, to: suspended, actor: { party: borrower } }\n action resume { from: suspended, to: active, actor: { party: borrower } }\n action close { from: [active, suspended], to: closed, actor: { party: borrower }, 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, borrower: party = programOperator) {\n familyRevision: 1\n summary: \"A single facility draw with an immutable principal and full repayment.\"\n fields { line: ref<line>, borrower: account of borrower, amount: money = amount, principalReceivable: account(self, claim) }\n lifecycle { states: [pending, drawn, repaid, cancelled], initial: pending }\n action create { actor: { party: borrower }, requires self.borrower == self.line.borrower; 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, actor: { party: borrower }\n requires self.line in [active]\n deadline: { at: self.line.expiresAt }\n moves self.amount from self.line.facility to self.line.borrower; moves self.amount from self.line.debt to self.principalReceivable\n }\n action repay { from: drawn, to: repaid, actor: { party: borrower }, moves self.amount from self.line.borrower to self.line.facility; moves self.amount from self.principalReceivable to self.line.debt }\n action cancel { from: pending, to: cancelled, actor: { party: borrower } }\n}\n"],
|
|
8
|
-
["insurance.hsx", "header insurance\n\n// Economics: Company commission is earning; refunds reverse its captured transfer.\n// Outside broker commissions are pass-through
|
|
8
|
+
["insurance.hsx", "header insurance\n\n// Economics: Company commission is earning; refunds reverse its captured transfer.\n// Outside broker commissions and insurer premiums are pass-through.\n// Claim moves remain unclassified until their money purpose is declared.\n\n// Expose cover.create, activate and cancel separately. The adapter names a\n// registered boundary adapter (conformance_boundary in sandbox). covers is an\n// optional link to a sibling attachment; the attached object is already the\n// insured thing. claim_limit is the sum insured: approved and paid claims on one\n// cover, across every claim attachment, never total more. Activation binds adapter;\n// each slice needs a separately created unique period and an active cover to collect.\n// Collection debits holder for insurerPremium to the insurer and commission to\n// broker as two moves. Broker defaults to programOperator; bind a declared business\n// for a distinct agency. The two amounts sum to premium. Zero portions are allowed.\n// Cover.cancel invokes refund only on paid slices, before each startsAt. It returns\n// insurerPremium from insurer and commission from broker to holder. Active or\n// expired periods are excluded; insufficient recipient funds refuse the reversal.\n// Slice refund is parent-owned, not a public alias. Expose cover.cancel instead.\n// Claims require active cover. Expose claim.create, approve, deny and pay as needed.\n// Inspector approves OR denies from submitted. After approval only pay or clock\n// expiry can consume the reservation; deny is never available after approval.\n// Inspector is a bound party, not necessarily staff. These are ledger transfers;\n// outside settlement needs the boundary protocol, not a claim of provider success.\n\n// Cost: each slice collection or refund declares two transfers. Claim approval\n// reserves once; pay posts once and expiry voids once. Cover cancellation adds\n// bounded slice invocations. Run hsx cost for composed counts, not provider prices.\n\ninstrument cover(holder: party, adapter: text, commission: percent = 0%, broker: party = programOperator, covers: ref?, premium: money = runtime, claim_limit: money = runtime) {\n summary: \"Recurring cover bound to an outside insurer across an ADL boundary.\"\n fields { covers: ref<covers>?, holder: account of holder, insurer: account(adapter(adapter), cash, \"premium\"), expiresAt: date, claimLimit: money = claim_limit }\n lifecycle { states: [pending, active, cancelled, expired], initial: pending }\n action create { actor: { party: holder } }\n action activate {\n from: pending, to: active, actor: { party: programOperator }\n subject { adapter: adapter }\n }\n action cancel {\n from: active, to: cancelled, actor: { party: holder }\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>, premium: money = premium, startsAt: date, endsAt: date\n commission: money = rate(self.premium, commission)\n insurerPremium: money = subtract(self.premium, self.commission), commissionReceipt: text?\n }\n lifecycle { states: [pending, paid, active, expired, refunded], initial: pending }\n action create {\n requires self.startsAt < self.endsAt\n requires unique \"premium_period\" on [self.cover, self.startsAt, self.endsAt]\n }\n action collect {\n allowZero: true\n requires self.premium > \"0\"\n from: pending, to: paid, actor: { party: holder }\n requires self.cover in [active]\n moves self.insurerPremium from holder to self.cover.insurer economics { purpose: pass_through, sourceParty: holder }\n moves self.commission from holder to broker capture \"commissionReceipt\" economics { recipient: broker, company: { purpose: earning, sourceParty: holder }, participant: { purpose: pass_through, sourceParty: holder } }\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 allowZero: true\n requires self.premium > \"0\"\n from: paid, to: refunded, actor: { parent: parent }, deadline: { at: self.startsAt }\n moves self.insurerPremium from self.cover.insurer to holder economics { purpose: pass_through, sourceParty: programOperator }\n moves self.commission from broker to holder economics { recipient: broker, company: { purpose: earning, sourceParty: broker, reversalOf: self.commissionReceipt }, participant: { purpose: pass_through, sourceParty: broker } }\n }\n }\n }\n}\n\ninstrument claim(cover: ref<insurance.cover>, inspector: party) {\n summary: \"A claim 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 invariants sum \"amount\" of { instrument: all(insurance.claim), reference: \"cover\", anchor: self.cover, states: [approved, paid], limit: 366 } <= self.cover.claimLimit\n action create { requires self.cover in [active] }\n action approve {\n from: submitted, to: approved\n actor: { party: inspector }\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, actor: { party: inspector }, deadline: { at: self.expiresAt }, moves post self.reservation }\n action deny { from: submitted, to: denied, actor: { party: inspector } }\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\n// Economics: Funding and commitment returns are principal. Distribution tax is\n// pass-through; own-account fee and claim allocations are internal. Mixed\n// principal/profit distributions and unbound source owners remain unclassified.\n\n// Round target is plan.principal from runtime subject.price, not its credit limit.\n// The operator opens the round and closes it before closesAt. Expose\n// round.create and close plus commitment.create and withdraw. A commitment\n// debits the bound investor's original active wallet before closesAt. Investor cap\n// aggregates by investor across wallets. A round still open at closesAt fails,\n// even when fully committed, and refunds those original wallets.\n// Closing needs the exact target; it funds plan.capital and does not disburse the\n// loan. Expose plan.disburse separately after signing and limit approval.\n// Distribution.create needs a recorded settlement matching the plan. Only the\n// payout consumes it: distribute_cash or distribute_loss claims the settlement\n// and marks it distributed, so the plan's unwind_paid keeps that profit, while an\n// abandoned distribution leaves the settlement refundable.\n// Prepare cash or loss first, then create shares against funded commitments of\n// that round. Distribution needs pending share weights equal to the round target.\n// Cash fee is a percentage of retained profit, VAT a percentage of that fee.\n// Principal plus retained profit less fee and VAT goes to weighted wallets;\n// floored residual goes to residual_to. Loss mode moves claim balances, not cash.\n// Child share execution is parent-owned. No report or clock proves outside payout.\n\n// Cost: round.create declares one owned account. Close transfers its balance\n// and invokes commitments; failure invokes their refunds. Distribution adds moves\n// and bounded share invocations. Run hsx cost for counts after policy selection.\n\ninstrument round(borrower: party, plan: ref<financing.installments> = object(financing.installments), operator: party = programOperator, 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, plan: ref<plan>, price: money = self.plan.principal, closesAt: date\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 { actor: { party: operator }, requires unique \"funding_plan\" on [self.plan]; requires self.borrower == self.plan.borrower }\n action close {\n from: open, to: funded, actor: { party: operator }\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 economics { purpose: principal, sourceParty: programOperator }\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 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>, investor: account of investor, 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: { investor: { field: self.investor } } } <= 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 actor: { party: investor }\n requires self.round in [open]\n requires self.wallet in [active]\n requires self.wallet.holder == self.investor\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 economics { purpose: principal, sourceParty: programOperator }\n }\n action fund { from: committed, to: funded, actor: { parent: round } }\n action withdraw {\n from: committed, to: withdrawn, actor: { party: investor }\n requires self.round in [open]\n deadline: { at: self.round.closesAt }\n moves self.amount from self.round.held to self.wallet.held economics { purpose: principal, sourceParty: programOperator }\n }\n action refund {\n from: committed, to: refunded, actor: { parent: round }\n moves self.amount from self.round.held to self.wallet.held economics { purpose: principal, sourceParty: programOperator }\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, operator: 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 {\n requires self.round in [funded]; requires self.source in [recorded]; requires self.source.plan == self.round.plan\n }\n action prepare_cash {\n from: pending, to: cash_ready\n requires self.mode == \"cash\"; requires self.source.kind == \"cash\"; requires self.source in [recorded]\n calculate: [\n { target: \"principal\", op: \"sum\", values: [{ field: self.source.principal }] }\n { target: \"profit\", op: \"sum\", values: [{ field: self.source.retainedProfit }] }\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\"; requires self.source in [recorded]\n calculate: [{ target: \"net\", op: \"sum\", values: [{ field: self.source.loss }] }]\n }\n action distribute_cash { allowZero: true,\n from: cash_ready, to: distributed, actor: { party: operator }\n requires self.source in [recorded]; requires unique \"settlement_consumption\" on [self.source.plan, self.source.identity]\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 economics { purpose: internal, sourceParty: programOperator }; moves self.vat from self.held to programTax economics { purpose: pass_through, sourceParty: programOperator }\n invoke: [{ reference: self.source, action: distribute, input: {} }, { 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 { allowZero: true,\n from: distributed, to: distributed, actor: { parent: current() }\n moves self.held.balance from self.held to residual_to\n }\n action distribute_loss { allowZero: true,\n from: loss_ready, to: distributed, actor: { party: operator }\n requires self.source in [recorded]; requires unique \"settlement_consumption\" on [self.source.plan, self.source.identity]\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: [{ reference: self.source, action: distribute, input: {} }, { 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 { allowZero: true,\n from: distributed, to: distributed, actor: { parent: current() }\n moves self.losses.balance from self.losses to self.residualLoss economics { purpose: internal, sourceParty: programOperator }\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 { allowZero: true,\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 { allowZero: true, from: pending, to: paid, actor: { parent: parent }, moves self.gross from self.distribution.losses to self.commitment.loss economics { purpose: internal, sourceParty: programOperator } }\n }\n }\n}\n"],
|
|
10
10
|
["marketplace.hsx", "header marketplace\n\n// Economics: Deposit funding, escrow credit and returns are principal. Retention is\n// earning for the company or passes the buyer's cash through to a bound outside recipient.\n\n// Listing, order and reservation are separate agreements. Expose their create\n// and decision actions individually. Order fulfillment does not move escrow cash;\n// only the fulfiller marks it, the Product operator unless the seller is bound.\n// Pair an order with escrow.hold and expose its fund, deliver, accept, dispute,\n// verify_return and refund aliases. Refund needs disputed -> return_verified,\n// with payee evidence, then returns the full price to payer; accept pays payee.\n// A reservation holds its own deposit. Activate requires an active listing and\n// no placed order. Only a declared converter may invoke credit. A financing\n// plan on the same hold credits it when the lender disburses. Credit consumes the\n// deposit once, credits at most the contribution, and returns excess to buyer.\n// Expose cancel, seller_cancel or operator_cancel for the intended actors.\n// Buyer cancel and expiry use configured refund percentages; seller/operator\n// cancellation return the whole reservation balance. Converted money is in escrow,\n// so subsequent return verification and refund use the escrow aliases.\n\n// Cost: listing and order actions declare no transfers. Reservation.create\n// declares one owned account; activate declares one deposit transfer. Cancellation\n// and credit split that balance into moves. Run hsx cost for the composed counts.\n\ninstrument listing(seller: party) {\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 }\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, fulfiller: party = programOperator) {\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 }\n invariants count of { instrument: all(marketplace.order), reference: \"listing\", anchor: self.listing, states: [placed, fulfilled], limit: 366 } <= 1\n action fulfill { from: placed, to: fulfilled, actor: { party: fulfiller } }\n action cancel { from: [quoted, placed], to: cancelled, actor: { party: buyer } }\n}\n\ninstrument reservation(listing: ref<marketplace.listing>, funds: ref<escrow.hold>, 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: all(marketplace.reservation), 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 economics { purpose: principal, sourceParty: buyer }\n }\n action credit { allowZero: true,\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.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 economics { purpose: principal, sourceParty: programOperator }\n moves self.refund from self.held to self.buyer economics { purpose: principal, sourceParty: programOperator }\n }\n action cancel { allowZero: true,\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 economics { purpose: principal, sourceParty: programOperator }; moves self.retained from self.held to retained_to economics { recipient: retained_to, company: { purpose: earning, sourceParty: buyer }, participant: { purpose: pass_through, sourceParty: programOperator } }\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 economics { purpose: principal, sourceParty: programOperator }\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 economics { purpose: principal, sourceParty: programOperator }\n }\n action withdraw { from: proposed, to: cancelled, actor: { party: buyer } }\n action expire { allowZero: true,\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 economics { purpose: principal, sourceParty: programOperator }; moves self.retained from self.held to retained_to economics { recipient: retained_to, company: { purpose: earning, sourceParty: buyer }, participant: { purpose: pass_through, sourceParty: programOperator } }\n }\n action expire_proposal { from: proposed, to: expired, actor: clock, due: { at: self.proposalExpiresAt } }\n}\n"],
|
|
11
11
|
["money.hsx", "header money\n\n// Economics: Held funding and returns are principal. Release to the company realizes\n// earnings; release to another participant passes the payer's cash through. Generic transfers, splits,\n// schedules, swaps, boundary payouts and metered fees retain no assumed purpose.\n\n// Expose each attachment's create and caller actions explicitly. A transfer or\n// split pays once; a hold exposes fund, release and refund separately. Release\n// pays payee and refund returns payer. A hold has no dispute or damage decision.\n// The payee proposes a schedule, which creates its count occurrences, and only\n// the payer activates or cancels it. Each due occurrence pays only while the\n// schedule is active. A due time promises no retry.\n// A pool accepts whole contributions only up to its remaining target and at most\n// 366 paid records. Expose pay to release the exact target. Clock failure refunds\n// original contributors; excess acceptance and partial contribution are absent.\n// A swap reserves both legs before exchange or voids reservations on expiry.\n// Payout instruct reserves across the selected adapter; confirm/reject require\n// matching terminal instruction evidence. An acknowledgement cannot settle it.\n// Metered bill charges a unique usage identity at the fixed unit price, only\n// under an active mandate the payer created: bills stop at its expiresAt, and at\n// most 366 billed events across every metered attachment on the mandate may sum\n// their payer debit, buyer fee and tax included, to its limit. The payer revokes\n// it to stop billing. Only the payee cancels its own unbilled usage.\n\n// Cost: transfer.pay declares one transfer. Hold.create declares one owned account;\n// fund, release and refund each declare one transfer. Schedules and pools add bounded\n// child invocations. Run hsx cost on the composed program for counts, not riyal prices.\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 }, requires self.amount > \"0\" }\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 economics { purpose: principal, sourceParty: payer }\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, actor: { party: payer }\n moves self.amount from self.held to payee economics { recipient: payee, company: { purpose: earning, sourceParty: payer }, participant: { purpose: pass_through, sourceParty: programOperator } }\n }\n action refund {\n from: funded, to: refunded, actor: { party: payee }\n moves self.amount from self.held to payer economics { purpose: principal, sourceParty: programOperator }\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 { allowZero: true, requires self.amount > \"0\"; from: pending, to: paid, actor: { party: payer }, 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 actor: { party: payee }\n invoke: [{ range: { count: { literal: count }, maximum: count, bind: position }, instrument: occurrence, action: create, input: { schedule: { field: self.id }, position: { field: position } } }]\n }\n action activate { from: draft, to: active, actor: { party: payer } }\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, actor: { party: payer } }\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 { actor: { parent: parent }, input { schedule: ref<parent>, position: integer(1, count) }, requires unique \"scheduled_position\" on [self.schedule, self.position] }\n action pay { allowZero: true, 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, actor: { party: payee }\n requires self.held.balance == self.target\n moves self.target from self.held to payee economics { recipient: payee, company: { purpose: earning, sourceParty: payer }, participant: { purpose: pass_through, sourceParty: programOperator } }\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, remaining: money? }\n lifecycle { states: [pending, paid, refunded], initial: pending }\n invariants count of { instrument: current(), reference: \"pool\", anchor: self.pool, states: [paid], limit: 366 } <= 366\n action create { requires self.pool in [open] }\n action pay { from: pending, to: paid, actor: { party: payer }, deadline: { at: self.pool.closesAt }, requires self.pool in [open], calculate: [{ target: remaining, op: subtract, base: { field: self.pool.target }, subtract: [{ field: self.pool.held.balance }] }], requires self.amount <= self.remaining, moves self.amount from self.payer to self.pool.held economics { purpose: principal, sourceParty: payer } }\n action refund { from: paid, to: refunded, actor: { parent: parent }, moves self.amount from self.pool.held to self.payer economics { purpose: principal, sourceParty: programOperator } }\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, actor: { party: first }, 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 payout(payer: party, payee: party, adapter: text, amount: money = runtime) {\n summary: \"Pay the recipient when the provider confirms settlement.\"\n fields { amount: money = amount }\n lifecycle { states: [pending, instructed, settled, rejected], initial: pending }\n action create {}\n action instruct {\n from: pending, to: instructed, actor: { party: payer }\n moves reserve self.amount from payer to payee boundary adapter\n }\n action confirm {\n from: instructed, to: settled\n moves post instruct\n }\n action reject {\n from: instructed, to: rejected\n moves void instruct\n }\n}\n\ninstrument mandate(payer: party, payee: party) {\n summary: \"A payer's permission for one payee to charge up to a total until it expires.\"\n fields { payer: account of payer, payee: account of payee, limit: money, expiresAt: date }\n lifecycle { states: [active, revoked], initial: active }\n action create { actor: { party: payer }, requires self.limit > \"0\" }\n action revoke { from: active, to: revoked, actor: { party: payer } }\n}\n\ninstrument metered(payer: party, payee: party, unit_price: money, units: integer = 1, fee: fee = { seller: 0% }, mandate: ref<money.mandate> = object(money.mandate)) {\n summary: \"A unique usage event priced once at the fixed unit price.\"\n fields { usageIdentity: text, mandate: ref<mandate>, payer: account of payer, payee: account of payee, unitPrice: money = unit_price, units: integer = units, amount: money = multiply(self.unitPrice, self.units) }\n lifecycle { states: [recorded, billed, cancelled], initial: recorded }\n invariants sum \"bill_move1_debit\" of { instrument: all(money.metered), reference: \"mandate\", anchor: self.mandate, states: [billed], limit: 366 } <= self.mandate.limit\n action create { requires unique \"usage_event\" on [self.usageIdentity]; requires self.mandate.payer == self.payer; requires self.mandate.payee == self.payee }\n action bill { allowZero: true, requires self.amount > \"0\"; from: recorded, to: billed, actor: { party: payee }, deadline: { at: self.mandate.expiresAt }, requires self.mandate in [active], moves self.amount from payer to payee fee fee }\n action cancel { from: recorded, to: cancelled, actor: { party: payee } }\n}\n"],
|
|
@@ -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,aAAa,EAAE,m7LAAm7L,CAAC;IACp8L,CAAC,WAAW,EAAE,6wMAA6wM,CAAC;IAC5xM,CAAC,iBAAiB,EAAE,qrNAAqrN,CAAC;IAC1sN,CAAC,YAAY,EAAE,mkOAAmkO,CAAC;IACnlO,CAAC,eAAe,EAAE,kinFAAkinF,CAAC;IACrjnF,CAAC,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"std-bundle.js","sourceRoot":"","sources":["../../src/std-bundle.ts"],"names":[],"mappings":"AAAA,oEAAoE;AAEpE,MAAM,CAAC,MAAM,iBAAiB,GAAgC,IAAI,GAAG,CAAiB;IACpF,CAAC,aAAa,EAAE,m7LAAm7L,CAAC;IACp8L,CAAC,WAAW,EAAE,6wMAA6wM,CAAC;IAC5xM,CAAC,iBAAiB,EAAE,qrNAAqrN,CAAC;IAC1sN,CAAC,YAAY,EAAE,mkOAAmkO,CAAC;IACnlO,CAAC,eAAe,EAAE,kinFAAkinF,CAAC;IACrjnF,CAAC,eAAe,EAAE,u8LAAu8L,CAAC;IAC19L,CAAC,aAAa,EAAE,03UAA03U,CAAC;IAC34U,CAAC,iBAAiB,EAAE,ggTAAggT,CAAC;IACrhT,CAAC,WAAW,EAAE,ogYAAogY,CAAC;IACnhY,CAAC,cAAc,EAAE,svJAAsvJ,CAAC;IACxwJ,CAAC,YAAY,EAAE,y1HAAy1H,CAAC;IACz2H,CAAC,eAAe,EAAE,4o1BAA4o1B,CAAC;IAC/p1B,CAAC,aAAa,EAAE,4hKAA4hK,CAAC;IAC7iK,CAAC,YAAY,EAAE,u8HAAu8H,CAAC;CACx9H,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperscale0/hsx",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.301",
|
|
4
4
|
"description": "The strictly typed HSX language: compile total financial programs into canonical UDL.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"hsx",
|
|
@@ -90,8 +90,8 @@
|
|
|
90
90
|
"bases:bundle": "bun scripts/bundle-bases.ts"
|
|
91
91
|
},
|
|
92
92
|
"dependencies": {
|
|
93
|
-
"@hyperscale0/adl": "1.0.
|
|
94
|
-
"@hyperscale0/udl": "1.0.
|
|
93
|
+
"@hyperscale0/adl": "1.0.301",
|
|
94
|
+
"@hyperscale0/udl": "1.0.301",
|
|
95
95
|
"fast-sha256": "1.3.0"
|
|
96
96
|
},
|
|
97
97
|
"devDependencies": {
|
|
@@ -103,5 +103,5 @@
|
|
|
103
103
|
"Amir Ayub",
|
|
104
104
|
"Sara AlBakaawi"
|
|
105
105
|
],
|
|
106
|
-
"gitHead": "
|
|
106
|
+
"gitHead": "3106a8d4d08964235405772ce727451c824866a8"
|
|
107
107
|
}
|
package/src/std-bundle.ts
CHANGED
|
@@ -6,7 +6,7 @@ export const BUNDLED_STD_FILES: ReadonlyMap<string, string> = new Map<string, st
|
|
|
6
6
|
["collections.hsx", "header collections\n\n// Economics: Company capital pays agencies as participant payouts; outside capital passes through.\n// A company agency earns outside capital fees; its own capital fee is internal.\n\n// Expose case.create, assign and recover as separate steps. Creation needs overdue\n// outstanding principal and a matching slice/plan. Assignment belongs to capital;\n// recovery belongs to agency and pays the linked payment before the agency fee.\n// Payment must belong to the same plan. Recovered means that payment was processed,\n// not that the entire debt was repaid. Fee debits plan.capital, not the borrower.\n// Expose recall for capital and return_uncollected for agency when needed.\n// Contacts need an assigned case, matching agency, local hours and rolling count.\n// Contact outcomes are separate records. Reminder dispatch is operator-owned;\n// before_due/overdue are clock-owned and require active debt. Scheduled admission\n// does not prove delivery or retry. No collector can infer authority from an alias.\n\n// Cost: case recovery invokes the linked payment and then charges its agency\n// fee. Its count includes those child effects. Contact and reminder delivery costs\n// are not provider prices in hsx cost; the executor supplies commercial tariffs.\n\ninstrument case(on: ref<financing.installments>[], agency: party, capital: party = programOperator, 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, actor: { party: capital } }\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 { allowZero: true, from: recovered, to: recovered, actor: { parent: current() }, moves self.agencyFee from self.plan.capital to agency economics { recipient: agency, company: { recipient: capital, company: { purpose: internal, sourceParty: capital }, participant: { purpose: earning, sourceParty: capital } }, participant: { recipient: capital, company: { purpose: participant_payout, sourceParty: capital }, participant: { purpose: pass_through, sourceParty: capital } } } }\n action recall { from: [opened, assigned], to: recalled, actor: { party: capital } }\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"],
|
|
7
7
|
["escrow.hsx", "header escrow\n\n// Economics: Funding and unspent returns are principal. Acceptance realizes earnings for\n// the company; the payer's cash passes through to a bound outside seller, less the\n// fee the company earns. Tax is pass-through.\n\n// Expose create, fund, deliver and accept for the purchase path. Create captures\n// subject.price; acceptance pays payee less the configured fee, not payer.\n// Expose dispute, verify_return and refund separately for the return path.\n// Payer disputes delivered goods; payee verifies return evidence from disputed.\n// Refunds return the held balance to the payer. A composition can supply funding\n// controllers and the states in which they block direct refunds. Only those\n// controllers may confirm outside funding or finish its coordinated refund.\n// Expose refund_undelivered to let the payer take the whole held price back once\n// deliver_within has passed since funding without delivery. It is a payer action\n// that becomes available at that time; nothing runs it automatically.\n// The Product operator settles any disputed hold: settle_release pays the payee\n// as acceptance would, and settle_return moves it to return_verified. Without a\n// active funding controller, settle_return also runs settle_refund to return\n// the whole balance to the payer. Otherwise the controller coordinates the\n// return before the operator's settle_refund returns the rest.\n// Acceptance expiry enters disputed, never released. Neither verify_return nor\n// refund becomes public merely because dispute is exposed. Clock actions remain\n// internal. Expose cancel for a pending hold, including a checkout-funded hold;\n// it returns its credited balance to payer before cancelling. Confirm requires\n// the whole captured price in held. This flow has no partial release or refund.\n\n// Cost: create declares one owned account. Fund and refund each declare one\n// transfer; accept expands the configured fee and tax into moves. Run hsx cost\n// on the composed program for instruction counts. The executor supplies prices.\n\ninstrument hold(payer: party = party(person), payee: party = programOperator, accept_within: duration = 48h, deliver_within: duration = 14d, fee: fee = { seller: 0%, tax: 0% }, dispute: policy = { refund_after: return_verified }, funding: policy = { controllers: [], reference: \"funds\", blocking_states: [active] }) {\n revisioned: true\n summary: \"Hold the subject price through delivery, acceptance and verified return.\"\n fields {\n payer: account of payer, payee: account of payee\n held: account of self, fundedAt: date?, deliverBy: date?, deliveredAt: date?, blockingFunding: integer?\n price: money = subject.price\n }\n lifecycle { states: [pending, funded, delivered, disputed, return_verified, released, refunded, cancelled], initial: pending }\n action create {\n subject { price: money }\n actor: { party: payer }\n }\n action fund {\n from: pending, to: funded, actor: { party: payer }\n set: { fundedAt: { field: self.now } }\n moves self.price from payer to self.held economics { purpose: principal, sourceParty: payer }\n }\n action confirm {\n from: pending, to: funded, actor: { parent: funding.controllers }\n requires self.held.balance == self.price\n calculate: [{ target: deliverBy, op: shift, date: { field: self.now }, milliseconds: { literal: deliver_within }, direction: after }]\n }\n action deliver {\n from: funded, to: delivered, actor: { party: payee }\n set: { deliveredAt: { field: self.now } }\n }\n action accept { allowZero: true, requires self.price > \"0\";\n from: delivered, to: released, actor: { party: payer }\n input { acceptanceReference: text }\n deadline: { at: self.deliveredAt, offset: accept_within }\n moves self.price from self.held to payee fee fee economics { payee: { recipient: payee, company: { purpose: earning, sourceParty: payer }, participant: { purpose: pass_through, sourceParty: programOperator } }, fee: { purpose: earning, sourceParty: payer }, tax: { purpose: pass_through, sourceParty: programOperator } }\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 {\n from: disputed, to: return_verified, actor: { party: payee }\n input { returnEvidence: text }\n }\n action settle_release { allowZero: true, requires self.price > \"0\";\n from: disputed, to: released, actor: { party: programOperator }\n input { ruling: text }\n moves self.price from self.held to payee fee fee economics { payee: { recipient: payee, company: { purpose: earning, sourceParty: payer }, participant: { purpose: pass_through, sourceParty: programOperator } }, fee: { purpose: earning, sourceParty: payer }, tax: { purpose: pass_through, sourceParty: programOperator } }\n }\n action settle_return {\n from: disputed, to: return_verified, actor: { party: programOperator }\n input { ruling: text }\n calculate: [{ target: blockingFunding, op: aggregate, selection: { instrument: funding.controllers, reference: funding.reference, anchor: self.id, states: funding.blocking_states, limit: 1 }, measure: count }]\n invoke: [{ reference: self.id, action: settle_refund, guard: { kind: compare, left: { field: self.blockingFunding }, operator: \"==\", right: { literal: 0 } }, input: {} }]\n }\n action settle_refund { allowZero: true,\n from: return_verified, to: refunded, actor: { party: programOperator }\n requires count of { instrument: funding.controllers, reference: funding.reference, anchor: self.id, states: funding.blocking_states, limit: 1 } == 0\n moves self.held.balance from self.held to payer economics { purpose: principal, sourceParty: programOperator }\n }\n action refund {\n from: [funded, dispute.refund_after], to: refunded, actor: { party: payee }\n requires count of { instrument: funding.controllers, reference: funding.reference, anchor: self.id, states: funding.blocking_states, limit: 1 } == 0\n moves self.held.balance from self.held to payer economics { purpose: principal, sourceParty: programOperator }\n }\n action refund_undelivered {\n from: funded, to: refunded, actor: { party: payer }\n due: { at: self.fundedAt, offset: deliver_within }\n requires count of { instrument: funding.controllers, reference: funding.reference, anchor: self.id, states: funding.blocking_states, limit: 1 } == 0\n moves self.price from self.held to payer economics { purpose: principal, sourceParty: programOperator }\n }\n action finish_refund { allowZero: true,\n from: [funded, return_verified], to: refunded, actor: { parent: funding.controllers }\n moves self.held.balance from self.held to payer economics { purpose: principal, sourceParty: programOperator }\n }\n action cancel { allowZero: true,\n from: pending, to: cancelled, actor: { party: payer }\n moves self.held.balance from self.held to payer economics { purpose: principal, sourceParty: programOperator }\n }\n}\n"],
|
|
8
8
|
["financing.hsx", "header financing\n\n// Economics: Principal advances and repayments are excluded from earnings. Claims, waivers,\n// write-offs and allocations are internal. Paid profit and company charges are\n// earnings; receipt refunds reverse captured cash. Borrower cash paid to outside\n// capital or recovery recipients passes through, whether held first or paid direct.\n\n// Pricing is required. amortizing reads profit_rate as an annual rate on the\n// declining balance: equal monthly instalments, the last absorbing rounding.\n// flat_total reads it as one charge on principal for the whole term (murabaha,\n// fixed-fee pay-later). 12,000 at 18% over 12 months costs 13,201.95 amortizing\n// and 14,160 flat_total.\n// Expose create and sign on installments. A funding composition owns checkout,\n// destination funding and returns when disburse_to is funds. The repayment plan\n// owns principal, profit, limits and debt cancellation.\n// disburse_to: seller pays principal to the seller party at activation (pay later\n// with the merchant paid on day one). Capital may refund any paid payment to\n// the borrower. Payments stay refundable while the plan is active. The\n// payment that clears the last slice completes the plan when no late charge or\n// recovery cost is outstanding; otherwise expose complete to close it once they\n// are settled or waived. When\n// the plan leaves active (paid, written off or cancelled) it sets refundUntil to\n// refund_within (default 30d) later, and payment, late charge and recovery cost\n// refunds stop at that time. A refund that reopens the plan clears refundUntil, which is set\n// from the calculated refundWindow so a restore can clear it. Once it passes,\n// nothing can move the plan's payments or late charges, so they stop counting as\n// open records. On a return, capital runs unwind: it takes the outstanding\n// principal back to capital and cancels open slices with their claims. Seller\n// mode debits the seller, who also returns the principal the borrower repaid;\n// funds mode needs the hold in return_verified and debits the hold, after which\n// the payee's escrow refund returns the down payment and the repaid principal.\n// Before delivery, the Product\n// operator runs unwind_undelivered on a funds-mode plan whose hold is still\n// funded: principal goes back to capital and the hold's unwind_financed returns\n// the down payment to the payer and closes the hold as refunded, all in one\n// operation, so deliver is refused afterwards. It also cancels proposed and\n// assessed late charges and recovery costs: goods that never arrived earn no\n// fines. Escrow refund refuses while any plan that is\n// not cancelled funds the hold, written off included, so the borrower never\n// receives lender principal. A funds-mode plan writes off only once its hold\n// has released principal to the seller: principal still held is not a loss, and\n// unwind or unwind_undelivered returns it. unwind_undelivered needs no paid\n// payments and no collected late charges; refund them first. unwind needs no\n// assessed late charges; waive them first. When goods never arrive on a paid plan, the\n// Product operator runs unwind_paid once the hold's deliverBy has passed, so an\n// early payoff never cuts the seller's delivery window short. It refunds every\n// payment, share, profit piece, fine and cost receipt and reverses the payoff's\n// profit, fines and costs, cancels the plan, and returns the hold's whole price\n// to the borrower; capital keeps the principal the borrower repaid. A settlement\n// a lending.distribution has paid out keeps its profit and share, since investors\n// hold that profit; only the other settlements' profit is refunded. unwind_paid\n// selects at most max_history (default and most 366) of each record kind, so\n// a payment refuses when it would leave more paid payments than max_history\n// less one, keeping a settlement for the payoff, or more paid profit pieces,\n// fine receipts or cost receipts than max_history; a fine or a recovery cost\n// refuses past max_history unwaived fines or costs on the plan, counted across\n// every late charge attachment, so a waived fine's cost keeps its own slot. A company lowers it to keep unwinds smaller. If any\n// source account is short, the whole action refuses and nothing moves; a\n// company that wants a partial refund writes that rule in its own program.\n// returned_goods decides the split on returned goods, before or after payoff.\n// keep_profit, the default, keeps the profit and fines paid so far with the\n// company: unwind runs with payments still paid, and on a paid plan the Product\n// operator runs return_hold after the refund window to return a return_verified\n// hold's whole balance. refund_all makes unwind wait until capital has refunded\n// every payment and collected charge, removes return_hold, and lets unwind_paid\n// settle returned goods too.\n// Borrower- and seller-directed disbursement exclude collect_down_payment. A down_payment\n// there reduces principal but does not collect cash. Price is subject metadata,\n// not the borrower limit. The funding composition checks its payer and price.\n// Cancelling a plan cancels its debt agreement. Its funding composition owns\n// returning any cash collected before activation.\n// Approve borrower and portfolio limits before disbursement. Create builds the\n// dated slice records from future, strictly increasing dates; disbursement\n// refuses once a slice is due. Payments need a separate payment record and pay action.\n// Expose parent payoff separately and create a current, unexpired payoff_quote.\n// Expose late_charge.create as propose_assessment before the clock can assess;\n// provide matching plan, slice and borrower. Fine is fixed money, not a percentage.\n// Collection uses the minimum of payment cash and outstanding fine; a partial\n// payment does not settle the remaining fine. Recovery cost needs its own record,\n// which only the Product operator creates; only it cancels a proposed fine or cost.\n// Profit share credits capital's allocatedProfitPayable, not an outside agency.\n// Credit lines need adapter binding at activation; draws are ledger advances,\n// not evidence of outside funding. Only the line's borrower, the Product operator\n// by default, opens and closes the line and creates, draws, repays or cancels an\n// advance on it. Only the Product operator creates the portfolio limit and\n// approves borrower and portfolio limits. No clock declaration proves retries.\n\n// Cost: installments include cash and claim moves, child-account creation and\n// bounded invocations across slices and assessments. Month and charge limits affect\n// the bound. Run hsx cost on the selected policies; profit is not a platform tariff.\n\ninstrument installments(months: integer(1, 366), max_history: integer(2, 366) = 366, pricing: enum(amortizing, flat_total), profit_rate: percent, charge_limit: integer(1, 3) = 3, disburse_to: enum(funds, borrower, seller) = funds, seller: party?, 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, refund_within: duration = 30d, returned_goods: enum(keep_profit, refund_all) = keep_profit, allow_overdue: enum(allowed, blocked) = allowed, assessed_fines: enum(carry, require_waiver) = carry, down_payment: percent = 0%, funds: ref?, borrower: party = party(person), capital: party = programOperator, share: percent = 0%, limits: ref<financing.limits> = object(financing.limits), portfolio: ref<financing.portfolio_limit> = object(financing.portfolio_limit)) {\n dependencies {\n funds {\n selector: disburse_to, is: funds\n message: \"Attachment `{attachment}` disburses into a hold, but `funds` is not bound.\"\n fix: \"Bind `funds: checkout` to a funding composition. Choose `disburse_to: seller` to pay a seller on activation, or `disburse_to: borrower` only if the borrower should receive the money directly.\"\n }\n seller {\n selector: disburse_to, is: seller\n message: \"Attachment `{attachment}` pays a seller, but `seller` is not bound.\"\n fix: \"Bind `seller: merchant` to the declared business that receives the principal.\"\n }\n }\n revisioned: true\n familyRevision: 1\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<portfolio>\n months: integer = months, dates: list(date, months), historyLimit: integer = max_history, paymentLimit: integer = subtract(max_history, 1)\n allocatedPayable: account(capital, cash, \"allocatedProfitPayable\"), capital: account(capital, cash, \"capital\"), profitIncome: account(capital, cash, \"profitIncome\"), loss: account(capital, claim, \"loss\")\n principalOutstanding: money?, principalRepaid: money?, principalReturned: money?, profitReturned: money?, lossRecorded: money?, refundWindow: date?, refundUntil: date?\n openSlices: integer?, openCharges: money?, openCosts: money?, payoffRefunds: integer?\n price: money = subject.price\n downPayment: money = rate(self.price, down_payment)\n principal: money = subtract(self.price, self.downPayment)\n flatProfit: money?\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 subject { price: money }\n actor: { party: borrower }\n requires self.borrowerLimit.borrower == self.borrower\n when pricing is flat_total { calculate: [{ target: flatProfit, op: rate, base: { field: self.principal }, bps: { literal: profit_rate }, rounding: floor }] }\n when disburse_to is funds { invoke: [{ reference: self.funds, action: check, input: { plan: { field: self.id } } }] }\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 } } }, { selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [draft], limit: months, where: { first: { literal: 0 } } }, action: check_order, input: {} }]\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 }\n action collect_down_payment { allowZero: true,\n from: signed, to: signed, actor: { party: borrower }\n when disburse_to is borrower { requires true == false }\n when disburse_to is seller { requires true == false }\n when disburse_to is funds { invoke: [{ reference: self.funds, action: collect, input: { plan: { field: self.id } } }] }\n }\n action disburse { allowZero: true,\n from: signed, to: active, actor: { party: capital }\n requires self.borrowerLimit in [approved]\n requires self.portfolioLimit in [approved]\n when disburse_to is funds { invoke: [{ reference: self.funds, action: disburse, input: { plan: { field: self.id } } }] }\n when disburse_to is borrower { moves self.principal from self.capital to self.borrower economics { purpose: principal, sourceParty: capital } }\n when disburse_to is seller { moves self.principal from self.capital to seller economics { purpose: principal, sourceParty: capital } }\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [draft], limit: 366, order: [position] }, action: activate, input: {} }]\n }\n action complete {\n from: active, to: paid\n calculate: [{ target: refundWindow, op: shift, date: { field: self.now }, milliseconds: { literal: refund_within }, direction: after }]\n set: { refundUntil: { field: self.refundWindow } }\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 }, input { refundUntil: date? }, set: { refundUntil: { field: input.refundUntil } } }\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 { target: refundWindow, op: shift, date: { field: self.now }, milliseconds: { literal: refund_within }, direction: after }\n ]\n set: { refundUntil: { field: self.refundWindow } }\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, actor: { parent: write_off_request }\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\" } }, { target: refundWindow, op: shift, date: { field: self.now }, milliseconds: { literal: refund_within }, direction: after }]\n set: { refundUntil: { field: self.refundWindow } }\n due: { at: input.overdueSlice.lossEligibleAt }\n requires input.overdueSlice.plan == self.id; requires input.overdueSlice.principalReceivable.balance > \"0\"\n when disburse_to is funds { invoke: [{ reference: self.funds, action: write_off, input: { plan: { field: self.id } } }] }\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 calculate: [\n { target: openSlices, op: aggregate, selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [pending, due], limit: 366 }, measure: count }\n { target: openCharges, op: aggregate, selection: { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.id, states: [assessed, collected], limit: 366 }, measure: { sum: \"receivable.balance\" } }\n { target: openCosts, op: aggregate, selection: { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.id, states: [assessed, collected], limit: 366 }, measure: { sum: \"receivable.balance\" } }\n ]\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 invoke: [{ selection: { instrument: current(), reference: \"borrowerLimit\", anchor: self.borrowerLimit, states: [active], limit: 1, where: { id: { field: self.id }, openSlices: { literal: 0 }, openCharges: { literal: \"0\" }, openCosts: { literal: \"0\" } } }, action: complete, input: {} }]\n }\n action cancel { from: quoted, to: cancelled }\n action void { from: signed, to: cancelled, actor: { party: borrower } }\n action unwind { allowZero: true,\n from: active, to: cancelled, actor: { party: capital }\n calculate: [\n { target: refundWindow, op: shift, date: { field: self.now }, milliseconds: { literal: refund_within }, direction: after }\n { target: principalOutstanding, op: aggregate, selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [pending, due], limit: 366 }, measure: { sum: \"principalReceivable.balance\" } }\n { target: principalRepaid, op: subtract, base: { field: self.principal }, subtract: [{ field: self.principalOutstanding }] }\n ]\n set: { refundUntil: { field: self.refundWindow } }\n when disburse_to is borrower { requires true == false }\n when returned_goods is refund_all {\n requires count of { instrument: payment, reference: \"plan\", anchor: self.id, states: [paid], limit: 366 } == 0\n requires count of { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.id, states: [collected], limit: 366 } == 0\n requires count of { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.id, states: [collected], limit: 366 } == 0\n }\n requires count of { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.id, states: [assessed], limit: 366 } == 0\n requires count of { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.id, states: [assessed], limit: 366 } == 0\n when disburse_to is funds { invoke: [{ reference: self.funds, action: refund, input: { plan: { field: self.id }, principal: { field: self.principalOutstanding } } }] }\n when disburse_to is seller {\n moves self.principalOutstanding from seller to self.capital economics { purpose: principal, sourceParty: seller }\n moves self.principalRepaid from seller to self.borrower economics { purpose: principal, sourceParty: seller }\n }\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [pending, due], limit: 366, order: [position] }, action: cancel, input: {} }]\n }\n action unwind_undelivered { allowZero: true,\n from: active, to: cancelled, actor: { party: programOperator }\n calculate: [{ target: refundWindow, op: shift, date: { field: self.now }, milliseconds: { literal: refund_within }, direction: after }]\n set: { refundUntil: { field: self.refundWindow } }\n when disburse_to is borrower { requires true == false }\n when disburse_to is seller { requires true == false }\n requires count of { instrument: payment, reference: \"plan\", anchor: self.id, states: [paid], limit: 366 } == 0\n requires count of { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.id, states: [collected], limit: 366 } == 0\n requires count of { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.id, states: [collected], limit: 366 } == 0\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [pending, due], limit: 366, order: [position] }, action: cancel, input: {} }]\n invoke: [{ selection: { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.id, states: [proposed, assessed], limit: 366 }, action: cancel_undelivered, input: {} }, { selection: { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.id, states: [proposed, assessed], limit: 366 }, action: cancel_undelivered, input: {} }]\n when disburse_to is funds { invoke: [{ reference: self.funds, action: cancel_undelivered, input: { plan: { field: self.id } } }] }\n }\n action return_hold {\n from: paid, to: paid, actor: { party: programOperator }\n requires self.refundUntil < self.now\n when disburse_to is borrower { requires true == false }\n when disburse_to is seller { requires true == false }\n when returned_goods is refund_all { requires true == false }\n when disburse_to is funds {\n invoke: [{ reference: self.funds, action: return_paid, input: { plan: { field: self.id } } }]\n }\n }\n action unwind_paid {\n from: paid, to: cancelled, actor: { party: programOperator }\n when disburse_to is borrower { requires true == false }\n when disburse_to is seller { requires true == false }\n invoke: [{ selection: { instrument: settlement, reference: \"plan\", anchor: self.id, states: [recorded], limit: max_history }, action: unwind, input: {} }, { selection: { instrument: profit_piece, reference: \"plan\", anchor: self.id, states: [paid], limit: max_history, where: { payment.status: { literal: \"refunded\" } } }, action: refund, input: {} }, { selection: { instrument: payment, reference: \"plan\", anchor: self.id, states: [paid], limit: max_history }, action: unwind, input: {} }, { reference: self.id, action: unwind_payoff_profit, input: {} }]\n invoke: [{ selection: { instrument: all(financing.late_charge.receipt), reference: \"plan\", anchor: self.id, states: [paid], limit: max_history }, action: refund, input: {} }, { selection: { instrument: all(financing.late_charge.cost.receipt), reference: \"plan\", anchor: self.id, states: [paid], limit: max_history }, action: refund, input: {} }, { selection: { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.id, states: [collected], limit: max_history }, action: unwind_payoff, input: {} }, { selection: { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.id, states: [collected], limit: max_history }, action: unwind_payoff, input: {} }]\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [pending, due, paid], limit: 366, order: [position] }, action: cancel, input: {} }]\n invoke: [{ selection: { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.id, states: [proposed, assessed, collected], limit: max_history }, action: cancel_undelivered, input: {} }, { selection: { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.id, states: [proposed, assessed, collected], limit: max_history }, action: cancel_undelivered, input: {} }]\n when disburse_to is funds {\n when returned_goods is keep_profit { invoke: [{ reference: self.funds, action: unwind_paid_undelivered, input: { plan: { field: self.id } } }] }\n when returned_goods is refund_all { invoke: [{ reference: self.funds, action: unwind_paid, input: { plan: { field: self.id } } }] }\n }\n }\n action unwind_payoff_profit {\n from: cancelled, to: cancelled, actor: { parent: current() }\n calculate: [{ target: payoffRefunds, op: aggregate, selection: { instrument: settlement, reference: \"plan\", anchor: self.id, states: [refunded], limit: 1, where: { identity: { field: self.settlementIdentity } } }, measure: count }]\n invoke: [{ selection: { instrument: slice, reference: \"plan\", anchor: self.id, states: [paid], limit: 366, where: { payoffIdentity: { field: self.settlementIdentity } } }, action: unwind_payoff, guard: { kind: compare, left: { field: self.payoffRefunds }, operator: \"==\", right: { literal: 1 } }, input: {} }]\n }\n records {\n write_off_request: {\n fields { plan: ref<parent>, overdueSlice: ref<slice> }\n lifecycle { states: [requested, applied, cancelled], initial: requested }\n action create { requires self.overdueSlice.plan == self.plan; requires self.plan in [active] }\n action apply {\n from: requested, to: applied, actor: { party: capital }\n invoke: [{ reference: self.plan, action: write_off, input: { overdueSlice: { field: self.overdueSlice } } }]\n }\n action cancel { from: requested, to: cancelled }\n }\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: capital }\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 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_for_amendment, input: {} }, { selection: { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.plan, states: [proposed], limit: 366 }, action: cancel_for_amendment, 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: capital } }\n action decline { from: proposed, to: declined, actor: { party: borrower } }\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), share: money?, retainedProfit: money?\n allocatedPayable: account(capital, cash, \"allocatedProfitPayable\"), capital: account(capital, cash, \"capital\"), profitIncome: account(capital, cash, \"profitIncome\"), lossAccount: account(capital, claim, \"loss\") }\n lifecycle { states: [recorded, distributed, refunded], initial: recorded }\n action create { allowZero: true,\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 calculate: [{ target: \"share\", op: \"rate\", base: { field: self.profit }, bps: { literal: share }, rounding: \"floor\" }, { target: retainedProfit, op: \"subtract\", base: { field: self.profit }, subtract: [{ field: self.share }] }]\n moves self.share from self.profitIncome to self.allocatedPayable economics { purpose: internal, sourceParty: capital }\n }\n action refund { allowZero: true,\n from: recorded, to: refunded, actor: { parent: payment }\n moves self.share from self.allocatedPayable to self.profitIncome economics { purpose: internal, sourceParty: capital }\n }\n action distribute { from: recorded, to: distributed, actor: { parent: all(lending.distribution) } }\n // profitIncome is one account per capital party, so refunding profit a\n // distribution already paid out would spend other plans' profit. unwind_paid\n // unwinds only settlements still recorded; each marks its payment refunded,\n // and the plan refunds the profit pieces and payoff profit behind them.\n action unwind { allowZero: true,\n from: recorded, to: refunded, actor: { parent: parent }\n moves self.share from self.allocatedPayable to self.profitIncome economics { purpose: internal, sourceParty: capital }\n invoke: [{ selection: { instrument: payment, reference: \"plan\", anchor: self.plan, states: [paid], limit: 1, where: { paymentIdentity: { field: self.identity } } }, action: unwind, input: {} }]\n }\n }\n slice: {\n revisioned: true\n fields {\n plan: ref<parent>, borrowerLimit: ref<limits>, portfolioLimit: ref<portfolio>, position: integer(1, months)\n originalDueAt: date = at(self.plan.dates, self.position), dueAt: date?, nextDueAt: date?, previousDueAt: date?, prior: integer = subtract(self.position, 1), previousPosition: integer = sum(self.prior, self.first), previousDate: date = at(self.plan.dates, self.previousPosition), extensionLimit: date = after(self.originalDueAt, max_extension), lossEligibleAt: date?\n first: integer = divide(1, self.position)\n principalBase: money?, principalAllocated: money?, principalRemainder: money?, principalAdjustment: money?\n profitBase: money?, profitAllocated: money?, profitRemainder: money?, profitAdjustment: money?\n principal: money, profit: money, instalment: money\n principalReceivable: account(self, claim), profitReceivable: account(self, claim), profitEarned: account(self, claim)\n payoffIdentity: text?, payoffRebate: money?, payoffProfitTotal: money?, payoffProfit: money?, payoffReceipt: text?\n paymentBudget: money?, principalPayment: money?, principalBasePayment: money?, principalRatio: money?, profitPayment: money?, profitBudget: money?, collectibleProfit: money?, collectibleTotal: money?, ratioDenominator: integer = sum(10000, profit_rate)\n debt: account(borrower, claim, contra, \"debt\"), loss: account(capital, claim, \"loss\")\n }\n lifecycle { states: [draft, pending, due, paid, written_off, cancelled], initial: draft }\n action create {\n actor: { parent: parent }\n input { plan: ref<parent>, borrowerLimit: ref<limits>, portfolioLimit: ref<portfolio>, position: integer(1, months) }\n set: { dueAt: { field: self.originalDueAt } }\n when pricing is flat_total {\n calculate: [\n { target: principalBase, op: divide, amount: { field: self.plan.principal }, divisor: { literal: months }, rounding: floor }\n { target: principalAllocated, op: multiply, amount: { field: self.principalBase }, units: { literal: months } }\n { target: principalRemainder, op: subtract, base: { field: self.plan.principal }, subtract: [{ field: self.principalAllocated }] }\n { target: principalAdjustment, op: multiply, amount: { field: self.principalRemainder }, units: { field: self.first } }\n { target: principal, op: sum, values: [{ field: self.principalBase }, { field: self.principalAdjustment }] }\n { target: profitBase, op: divide, amount: { field: self.plan.flatProfit }, divisor: { literal: months }, rounding: floor }\n { target: profitAllocated, op: multiply, amount: { field: self.profitBase }, units: { literal: months } }\n { target: profitRemainder, op: subtract, base: { field: self.plan.flatProfit }, subtract: [{ field: self.profitAllocated }] }\n { target: profitAdjustment, op: multiply, amount: { field: self.profitRemainder }, units: { field: self.first } }\n { target: profit, op: sum, values: [{ field: self.profitBase }, { field: self.profitAdjustment }] }\n { target: instalment, op: sum, values: [{ field: self.principal }, { field: self.profit }] }\n ]\n }\n when pricing is amortizing {\n calculate: [\n { target: principal, op: annuity, amount: { field: self.plan.principal }, rate: { literal: profit_rate }, periods: { literal: months }, position: { field: self.position }, part: principal }\n { target: profit, op: annuity, amount: { field: self.plan.principal }, rate: { literal: profit_rate }, periods: { literal: months }, position: { field: self.position }, part: interest }\n { target: instalment, op: sum, values: [{ field: self.principal }, { field: self.profit }] }\n ]\n }\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 requires self.originalDueAt > self.now; requires self.originalDueAt >= self.previousDate\n }\n action check_order { from: draft, to: draft, actor: { parent: parent }, requires self.originalDueAt > self.previousDate }\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 { allowZero: true,\n from: draft, to: pending, actor: { parent: parent }\n requires self.dueAt > self.now\n moves self.principal from self.debt to self.principalReceivable economics { purpose: internal, sourceParty: borrower }\n moves self.profit from self.debt to self.profitReceivable economics { purpose: internal, sourceParty: borrower }\n when profit_earned is at_disbursement { moves self.profit from self.profitReceivable to self.profitEarned economics { purpose: internal, sourceParty: programOperator } }\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: { plan: { field: self.plan }, 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: { plan: { field: self.plan }, 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 ]\n when pricing is flat_total { calculate: [{ target: principalRatio, op: ratio, amount: { field: self.paymentBudget }, numerator: { literal: 10000 }, denominator: { field: self.ratioDenominator }, rounding: floor }] }\n when pricing is amortizing { calculate: [{ target: principalRatio, op: ratio, amount: { field: self.paymentBudget }, numerator: { field: self.principal }, denominator: { field: self.instalment }, rounding: floor }] }\n calculate: [\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: { plan: { field: self.plan }, 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 { allowZero: true,\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 economics { purpose: principal, sourceParty: borrower }\n moves self.payoffProfit from self.plan.borrower to self.plan.profitIncome capture \"payoffReceipt\" economics { recipient: capital, company: { purpose: earning, sourceParty: borrower }, participant: { purpose: pass_through, sourceParty: borrower } }\n moves self.principalReceivable.balance from self.principalReceivable to self.debt economics { purpose: internal, sourceParty: programOperator }\n moves self.profitReceivable.balance from self.profitReceivable to self.debt economics { purpose: internal, sourceParty: programOperator }\n moves self.profitEarned.balance from self.profitEarned to self.debt economics { purpose: internal, sourceParty: programOperator }\n }\n action unwind_payoff { allowZero: true,\n from: paid, to: paid, actor: { parent: parent }\n moves self.payoffProfit from self.plan.profitIncome to self.plan.borrower economics { recipient: capital, company: { purpose: earning, sourceParty: capital, reversalOf: self.payoffReceipt }, participant: unclassified }\n }\n action write_off { allowZero: true,\n from: [pending, due], to: written_off, actor: { parent: parent }\n moves self.principalReceivable.balance from self.principalReceivable to self.loss economics { purpose: internal, sourceParty: programOperator }; moves self.profitReceivable.balance from self.profitReceivable to self.debt economics { purpose: internal, sourceParty: programOperator }; moves self.profitEarned.balance from self.profitEarned to self.loss economics { purpose: internal, sourceParty: programOperator }\n }\n action cancel { allowZero: true,\n from: [pending, due, paid], to: cancelled, actor: { parent: parent }\n moves self.principalReceivable.balance from self.principalReceivable to self.debt economics { purpose: internal, sourceParty: programOperator }; moves self.profitReceivable.balance from self.profitReceivable to self.debt economics { purpose: internal, sourceParty: programOperator }; moves self.profitEarned.balance from self.profitEarned to self.debt economics { purpose: internal, sourceParty: programOperator }\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 }, calculate: [{ target: dueAt, op: shift, date: { field: self.slice.dueAt }, milliseconds: { literal: 0 }, direction: after }] }\n action mature { allowZero: true, from: pending, to: recognised, actor: clock, due: { at: self.dueAt }, moves self.slice.profitReceivable.balance from self.slice.profitReceivable to self.slice.profitEarned economics { purpose: internal, sourceParty: programOperator } }\n }\n payment: {\n revisioned: true\n fields { plan: ref<parent>, amount: money, paymentIdentity: text, held: account of self\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, actor: { party: borrower }\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 economics { purpose: principal, sourceParty: borrower }\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 requires count of { instrument: current(), reference: \"plan\", anchor: self.plan, states: [paid], limit: 366 } <= self.plan.paymentLimit\n requires count of { instrument: profit_piece, reference: \"plan\", anchor: self.plan, states: [paid], limit: 366 } <= self.plan.historyLimit\n requires count of { instrument: all(financing.late_charge.receipt), reference: \"plan\", anchor: self.plan, states: [paid], limit: 366 } <= self.plan.historyLimit\n requires count of { instrument: all(financing.late_charge.cost.receipt), reference: \"plan\", anchor: self.plan, states: [paid], limit: 366 } <= self.plan.historyLimit\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 unwind { from: paid, to: refunded, actor: { parent: [parent, settlement] } }\n action refund {\n from: paid, to: refunded, actor: { party: capital }, deadline: { at: self.plan.refundUntil }\n requires unique \"settlement_consumption\" on [self.plan, self.paymentIdentity]; requires self.plan in [active, paid]\n requires count of { instrument: settlement, reference: \"plan\", anchor: self.plan, states: [recorded], limit: 366, where: { identity: { field: self.paymentIdentity } } } == 1\n invoke: [{ selection: { instrument: settlement, reference: \"plan\", anchor: self.plan, states: [recorded], limit: 366, where: { identity: { field: self.paymentIdentity } } }, action: refund, input: {} }]\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 { allowZero: true,\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 economics { purpose: principal, sourceParty: programOperator }; moves self.amount from self.slice.principalReceivable to self.slice.debt economics { purpose: internal, sourceParty: programOperator }\n }\n action refund { allowZero: true,\n from: paid, to: refunded, actor: { parent: payment }\n moves self.amount from self.slice.plan.capital to self.slice.plan.borrower economics { purpose: principal, sourceParty: capital }; moves self.amount from self.slice.debt to self.slice.principalReceivable economics { purpose: internal, sourceParty: borrower }\n }\n }\n profit_piece: {\n fields { cashReceipt: text?, plan: ref<parent>, slice: ref<slice>, payment: ref<payment>, limit: money, amount: money? }\n lifecycle { states: [paid, refunded], initial: paid }\n action create { allowZero: true,\n calculate: [{ target: amount, op: minimum, values: [{ field: self.payment.held.balance }, { field: self.limit }] }]\n actor: { parent: slice }\n input { plan: ref<parent>, 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 capture \"cashReceipt\" economics { recipient: capital, company: { purpose: earning, sourceParty: borrower }, participant: { purpose: pass_through, sourceParty: programOperator } }\n when profit_earned is on_payment { moves self.amount from self.slice.profitReceivable to self.slice.debt economics { purpose: internal, sourceParty: programOperator } }\n when profit_earned is by_schedule { moves self.amount from self.slice.profitEarned to self.slice.debt economics { purpose: internal, sourceParty: programOperator } }\n when profit_earned is at_disbursement { moves self.amount from self.slice.profitEarned to self.slice.debt economics { purpose: internal, sourceParty: programOperator } }\n }\n action refund { allowZero: true,\n from: paid, to: refunded, actor: { parent: [payment, parent] }\n moves self.amount from self.slice.plan.profitIncome to self.slice.plan.borrower economics { recipient: capital, company: { purpose: earning, sourceParty: capital, reversalOf: self.cashReceipt }, participant: unclassified }\n when profit_earned is on_payment { moves self.amount from self.slice.debt to self.slice.profitReceivable economics { purpose: internal, sourceParty: borrower } }\n when profit_earned is by_schedule { moves self.amount from self.slice.debt to self.slice.profitEarned economics { purpose: internal, sourceParty: borrower } }\n when profit_earned is at_disbursement { moves self.amount from self.slice.debt to self.slice.profitEarned economics { purpose: internal, sourceParty: borrower } }\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, borrower: party = party(person)) {\n parameterDiagnostics {\n fine {\n accepts: \"a fixed amount\"\n percentage: \"a percentage of overdue debt\"\n fix: \"Use a fixed amount only if that is the intended policy. A percentage charge needs an authored rate calculation; do not approximate it with a cash amount.\"\n }\n }\n revisioned: true\n familyRevision: 1\n summary: \"Separate 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?, payoffAmount: money?, payoffReceipt: text?\n receivable: account(self, claim), debt: account(borrower, claim, contra, \"debt\")\n }\n lifecycle { states: [proposed, assessed, collected, waived], initial: proposed }\n action create { input { slice: ref<on.slice>? }, calculate: [{ target: overdueAt, op: shift, date: { field: self.slice.dueAt }, milliseconds: { literal: grace }, direction: after }, { target: payoffAmount, op: sum, values: [{ literal: \"0\" }] }], requires unique \"late_assessment\" on [self.slice, self.overdueAt]; requires self.borrower == self.slice.plan.borrower; requires self.plan == self.slice.plan; requires count of { instrument: all(financing.late_charge), reference: \"plan\", anchor: self.plan, states: [proposed, assessed, collected], limit: 366 } < self.plan.historyLimit }\n action assess { allowZero: true,\n from: proposed, to: assessed, actor: clock, due: { at: self.overdueAt }\n requires self.slice.principalReceivable.balance > \"0\"\n moves self.fine from self.debt to self.receivable economics { purpose: internal, sourceParty: borrower }\n }\n action collect {\n from: [assessed, collected], to: assessed, actor: { parent: child(on, slice) }, 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: { plan: { field: self.plan }, 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 { allowZero: true,\n from: [assessed, collected], to: collected, actor: { parent: on }\n requires self.plan in [paid]\n calculate: [{ target: payoffAmount, op: sum, values: [{ field: self.receivable.balance }] }]\n moves self.payoffAmount from self.plan.borrower to fines_to capture \"payoffReceipt\" economics { recipient: fines_to, company: { purpose: earning, sourceParty: borrower }, participant: { purpose: pass_through, sourceParty: borrower } }\n moves self.payoffAmount from self.receivable to self.debt economics { purpose: internal, sourceParty: programOperator }\n }\n action unwind_payoff { allowZero: true,\n from: collected, to: collected, actor: { parent: on }\n moves self.payoffAmount from fines_to to self.plan.borrower economics { recipient: fines_to, company: { purpose: earning, sourceParty: fines_to, reversalOf: self.payoffReceipt }, participant: unclassified }\n }\n action finish { from: assessed, to: collected, actor: { parent: current() }, requires self.receivable.balance == \"0\" }\n action cancel { from: proposed, to: waived, actor: { party: programOperator } }\n action cancel_for_amendment { from: proposed, to: waived, actor: { parent: child(on, amendment) } }\n action cancel_undelivered { allowZero: true, from: [proposed, assessed, collected], to: waived, actor: { parent: on }, moves self.receivable.balance from self.receivable to self.debt economics { purpose: internal, sourceParty: programOperator } }\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 { allowZero: true, from: [assessed, collected], to: waived, actor: { parent: waiver_request }, input { reason: text, evidence: text }, moves self.receivable.balance from self.receivable to self.debt economics { purpose: internal, sourceParty: programOperator } }\n action refund {\n from: [assessed, collected], to: assessed, actor: { party: fines_to }, input { payment: ref<on.payment> }, deadline: { at: self.plan.refundUntil }\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_request: {\n fields { assessment: ref<parent>, reason: text, evidence: text }\n lifecycle { states: [requested, applied, cancelled], initial: requested }\n action create { requires self.assessment in [assessed, collected] }\n action apply {\n from: requested, to: applied, actor: { party: fines_to }, input { reason: text, evidence: text }\n invoke: [{ reference: self.assessment, action: waive, input: { reason: { field: input.reason }, evidence: { field: input.evidence } } }]\n }\n action cancel { from: requested, to: cancelled }\n }\n waiver: {\n fields { assessment: ref<parent>, amendment: ref<on.amendment>, amount: money? }\n lifecycle { states: [recorded], initial: recorded }\n action create { allowZero: true,\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 economics { purpose: internal, sourceParty: programOperator }\n }\n }\n receipt: {\n fields { cashReceipt: text?, plan: ref<on>, assessment: ref<parent>, payment: ref<on.payment>, amount: money? }\n lifecycle { states: [paid, refunded], initial: paid }\n action create { allowZero: true, calculate: [{ target: amount, op: minimum, values: [{ field: self.payment.held.balance }, { field: self.assessment.receivable.balance }] }], actor: { parent: parent }, input { plan: ref<on>, 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 capture \"cashReceipt\" economics { recipient: fines_to, company: { purpose: earning, sourceParty: borrower }, participant: { purpose: pass_through, sourceParty: programOperator } }; moves self.amount from self.assessment.receivable to self.assessment.debt economics { purpose: internal, sourceParty: programOperator } }\n action refund { allowZero: true, from: paid, to: refunded, actor: { parent: [parent, on] }, moves self.amount from fines_to to self.payment.plan.borrower economics { recipient: fines_to, company: { purpose: earning, sourceParty: fines_to, reversalOf: self.cashReceipt }, participant: unclassified }; moves self.amount from self.assessment.debt to self.assessment.receivable economics { purpose: internal, sourceParty: borrower } }\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), payoffAmount: money?, payoffReceipt: text?\n receivable: account(self, claim), debt: account(borrower, claim, contra, \"debt\")\n }\n lifecycle { states: [proposed, assessed, collected, waived], initial: proposed }\n action create { actor: { party: programOperator }, calculate: [{ target: overdueAt, op: shift, date: { field: self.assessment.overdueAt }, milliseconds: { literal: 0 }, direction: after }, { target: payoffAmount, op: sum, values: [{ literal: \"0\" }] }], requires unique \"recovery_assessment\" on [self.assessment]; requires self.plan == self.assessment.plan; requires count of { instrument: all(financing.late_charge.cost), reference: \"plan\", anchor: self.plan, states: [proposed, assessed, collected], limit: 366 } < self.plan.historyLimit }\n action assess { allowZero: true,\n from: proposed, to: assessed, actor: clock, due: { at: self.assessment.overdueAt }\n requires self.assessment.slice.principalReceivable.balance > \"0\"\n moves self.amount from self.debt to self.receivable economics { purpose: internal, sourceParty: borrower }\n }\n action collect {\n from: [assessed, collected], to: assessed, actor: { parent: child(on, slice) }, 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: { plan: { field: self.plan }, 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 { allowZero: true,\n from: [assessed, collected], to: collected, actor: { parent: on }\n requires self.plan in [paid]\n calculate: [{ target: payoffAmount, op: sum, values: [{ field: self.receivable.balance }] }]\n moves self.payoffAmount from self.plan.borrower to costs_to capture \"payoffReceipt\" economics { recipient: costs_to, company: { purpose: earning, sourceParty: borrower }, participant: { purpose: pass_through, sourceParty: borrower } }\n moves self.payoffAmount from self.receivable to self.debt economics { purpose: internal, sourceParty: programOperator }\n }\n action unwind_payoff { allowZero: true,\n from: collected, to: collected, actor: { parent: on }\n moves self.payoffAmount from costs_to to self.plan.borrower economics { recipient: costs_to, company: { purpose: earning, sourceParty: costs_to, reversalOf: self.payoffReceipt }, participant: unclassified }\n }\n action finish { from: assessed, to: collected, actor: { parent: current() }, requires self.receivable.balance == \"0\" }\n action cancel { from: proposed, to: waived, actor: { party: programOperator } }\n action cancel_for_amendment { from: proposed, to: waived, actor: { parent: child(on, amendment) } }\n action cancel_undelivered { allowZero: true, from: [proposed, assessed, collected], to: waived, actor: { parent: on }, moves self.receivable.balance from self.receivable to self.debt economics { purpose: internal, sourceParty: programOperator } }\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 { allowZero: true, from: [assessed, collected], to: waived, actor: { parent: waiver_request }, input { reason: text, evidence: text }, moves self.receivable.balance from self.receivable to self.debt economics { purpose: internal, sourceParty: programOperator } }\n action refund {\n from: [assessed, collected], to: assessed, actor: { party: costs_to }, input { payment: ref<on.payment> }, deadline: { at: self.plan.refundUntil }\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_request: {\n fields { assessment: ref<parent>, reason: text, evidence: text }\n lifecycle { states: [requested, applied, cancelled], initial: requested }\n action create { requires self.assessment in [assessed, collected] }\n action apply {\n from: requested, to: applied, actor: { party: costs_to }, input { reason: text, evidence: text }\n invoke: [{ reference: self.assessment, action: waive, input: { reason: { field: input.reason }, evidence: { field: input.evidence } } }]\n }\n action cancel { from: requested, to: cancelled }\n }\n waiver: {\n fields { assessment: ref<parent>, amendment: ref<on.amendment>, amount: money? }\n lifecycle { states: [recorded], initial: recorded }\n action create { allowZero: true,\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 economics { purpose: internal, sourceParty: programOperator }\n }\n }\n receipt: {\n fields { cashReceipt: text?, plan: ref<on>, assessment: ref<parent>, payment: ref<on.payment>, amount: money? }\n lifecycle { states: [paid, refunded], initial: paid }\n action create { allowZero: true, calculate: [{ target: amount, op: minimum, values: [{ field: self.payment.held.balance }, { field: self.assessment.receivable.balance }] }], actor: { parent: parent }, input { plan: ref<on>, 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 capture \"cashReceipt\" economics { recipient: costs_to, company: { purpose: earning, sourceParty: borrower }, participant: { purpose: pass_through, sourceParty: programOperator } }; moves self.amount from self.assessment.receivable to self.assessment.debt economics { purpose: internal, sourceParty: programOperator } }\n action refund { allowZero: true, from: paid, to: refunded, actor: { parent: [parent, on] }, moves self.amount from costs_to to self.payment.plan.borrower economics { recipient: costs_to, company: { purpose: earning, sourceParty: costs_to, reversalOf: self.cashReceipt }, participant: unclassified }; moves self.amount from self.assessment.debt to self.assessment.receivable economics { purpose: internal, sourceParty: borrower } }\n }\n }\n }\n }\n}\n\ninstrument limits(per_borrower: money, borrower: party = party(person), active_plans: integer = 1) {\n familyRevision: 1\n scope: product\n summary: \"One outstanding balance ceiling per borrower.\"\n fields { borrower: account of borrower, limit: money = per_borrower, activePlans: integer = active_plans }\n lifecycle { states: [pending, approved], initial: pending }\n action create { actor: { party: borrower }, requires unique \"borrower_limit\" on [self.borrower] }\n action approve { from: pending, to: approved, actor: { party: programOperator } }\n}\n\ninstrument portfolio_limit(limit: money) {\n familyRevision: 1\n scope: product\n summary: \"One shared ceiling on the principal the product may hold.\"\n fields { key: text = \"portfolio\", limit: money = limit }\n lifecycle { states: [pending, approved], initial: pending }\n action create { actor: { party: programOperator }, requires unique \"portfolio_limit\" on [self.key] }\n action approve { from: pending, to: approved, actor: { party: programOperator } }\n}\n\ninstrument credit_line(borrower: party = programOperator, adapter: text, limit: money, expires: date) {\n familyRevision: 1\n summary: \"A revolving facility from an outside lender; each draw is a separate immutable advance.\"\n fields { borrower: account of borrower, facility: account(borrower, cash, \"facility\"), debt: account(borrower, claim, contra, \"debt\"), limit: money = limit, expiresAt: date = expires }\n lifecycle { states: [pending, active, suspended, closed], initial: pending }\n action create { actor: { party: borrower } }\n action activate {\n from: pending, to: active, actor: { party: borrower }\n subject { adapter: adapter }\n }\n action suspend { from: active, to: suspended, actor: { party: borrower } }\n action resume { from: suspended, to: active, actor: { party: borrower } }\n action close { from: [active, suspended], to: closed, actor: { party: borrower }, 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, borrower: party = programOperator) {\n familyRevision: 1\n summary: \"A single facility draw with an immutable principal and full repayment.\"\n fields { line: ref<line>, borrower: account of borrower, amount: money = amount, principalReceivable: account(self, claim) }\n lifecycle { states: [pending, drawn, repaid, cancelled], initial: pending }\n action create { actor: { party: borrower }, requires self.borrower == self.line.borrower; 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, actor: { party: borrower }\n requires self.line in [active]\n deadline: { at: self.line.expiresAt }\n moves self.amount from self.line.facility to self.line.borrower; moves self.amount from self.line.debt to self.principalReceivable\n }\n action repay { from: drawn, to: repaid, actor: { party: borrower }, moves self.amount from self.line.borrower to self.line.facility; moves self.amount from self.principalReceivable to self.line.debt }\n action cancel { from: pending, to: cancelled, actor: { party: borrower } }\n}\n"],
|
|
9
|
-
["insurance.hsx", "header insurance\n\n// Economics: Company commission is earning; refunds reverse its captured transfer.\n// Outside broker commissions are pass-through
|
|
9
|
+
["insurance.hsx", "header insurance\n\n// Economics: Company commission is earning; refunds reverse its captured transfer.\n// Outside broker commissions and insurer premiums are pass-through.\n// Claim moves remain unclassified until their money purpose is declared.\n\n// Expose cover.create, activate and cancel separately. The adapter names a\n// registered boundary adapter (conformance_boundary in sandbox). covers is an\n// optional link to a sibling attachment; the attached object is already the\n// insured thing. claim_limit is the sum insured: approved and paid claims on one\n// cover, across every claim attachment, never total more. Activation binds adapter;\n// each slice needs a separately created unique period and an active cover to collect.\n// Collection debits holder for insurerPremium to the insurer and commission to\n// broker as two moves. Broker defaults to programOperator; bind a declared business\n// for a distinct agency. The two amounts sum to premium. Zero portions are allowed.\n// Cover.cancel invokes refund only on paid slices, before each startsAt. It returns\n// insurerPremium from insurer and commission from broker to holder. Active or\n// expired periods are excluded; insufficient recipient funds refuse the reversal.\n// Slice refund is parent-owned, not a public alias. Expose cover.cancel instead.\n// Claims require active cover. Expose claim.create, approve, deny and pay as needed.\n// Inspector approves OR denies from submitted. After approval only pay or clock\n// expiry can consume the reservation; deny is never available after approval.\n// Inspector is a bound party, not necessarily staff. These are ledger transfers;\n// outside settlement needs the boundary protocol, not a claim of provider success.\n\n// Cost: each slice collection or refund declares two transfers. Claim approval\n// reserves once; pay posts once and expiry voids once. Cover cancellation adds\n// bounded slice invocations. Run hsx cost for composed counts, not provider prices.\n\ninstrument cover(holder: party, adapter: text, commission: percent = 0%, broker: party = programOperator, covers: ref?, premium: money = runtime, claim_limit: money = runtime) {\n summary: \"Recurring cover bound to an outside insurer across an ADL boundary.\"\n fields { covers: ref<covers>?, holder: account of holder, insurer: account(adapter(adapter), cash, \"premium\"), expiresAt: date, claimLimit: money = claim_limit }\n lifecycle { states: [pending, active, cancelled, expired], initial: pending }\n action create { actor: { party: holder } }\n action activate {\n from: pending, to: active, actor: { party: programOperator }\n subject { adapter: adapter }\n }\n action cancel {\n from: active, to: cancelled, actor: { party: holder }\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>, premium: money = premium, startsAt: date, endsAt: date\n commission: money = rate(self.premium, commission)\n insurerPremium: money = subtract(self.premium, self.commission), commissionReceipt: text?\n }\n lifecycle { states: [pending, paid, active, expired, refunded], initial: pending }\n action create {\n requires self.startsAt < self.endsAt\n requires unique \"premium_period\" on [self.cover, self.startsAt, self.endsAt]\n }\n action collect {\n allowZero: true\n requires self.premium > \"0\"\n from: pending, to: paid, actor: { party: holder }\n requires self.cover in [active]\n moves self.insurerPremium from holder to self.cover.insurer economics { purpose: pass_through, sourceParty: holder }\n moves self.commission from holder to broker capture \"commissionReceipt\" economics { recipient: broker, company: { purpose: earning, sourceParty: holder }, participant: { purpose: pass_through, sourceParty: holder } }\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 allowZero: true\n requires self.premium > \"0\"\n from: paid, to: refunded, actor: { parent: parent }, deadline: { at: self.startsAt }\n moves self.insurerPremium from self.cover.insurer to holder economics { purpose: pass_through, sourceParty: programOperator }\n moves self.commission from broker to holder economics { recipient: broker, company: { purpose: earning, sourceParty: broker, reversalOf: self.commissionReceipt }, participant: { purpose: pass_through, sourceParty: broker } }\n }\n }\n }\n}\n\ninstrument claim(cover: ref<insurance.cover>, inspector: party) {\n summary: \"A claim 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 invariants sum \"amount\" of { instrument: all(insurance.claim), reference: \"cover\", anchor: self.cover, states: [approved, paid], limit: 366 } <= self.cover.claimLimit\n action create { requires self.cover in [active] }\n action approve {\n from: submitted, to: approved\n actor: { party: inspector }\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, actor: { party: inspector }, deadline: { at: self.expiresAt }, moves post self.reservation }\n action deny { from: submitted, to: denied, actor: { party: inspector } }\n action expire { from: approved, to: expired, actor: clock, due: { at: self.expiresAt }, moves void self.reservation }\n}\n"],
|
|
10
10
|
["lending.hsx", "header lending\n\n// Economics: Funding and commitment returns are principal. Distribution tax is\n// pass-through; own-account fee and claim allocations are internal. Mixed\n// principal/profit distributions and unbound source owners remain unclassified.\n\n// Round target is plan.principal from runtime subject.price, not its credit limit.\n// The operator opens the round and closes it before closesAt. Expose\n// round.create and close plus commitment.create and withdraw. A commitment\n// debits the bound investor's original active wallet before closesAt. Investor cap\n// aggregates by investor across wallets. A round still open at closesAt fails,\n// even when fully committed, and refunds those original wallets.\n// Closing needs the exact target; it funds plan.capital and does not disburse the\n// loan. Expose plan.disburse separately after signing and limit approval.\n// Distribution.create needs a recorded settlement matching the plan. Only the\n// payout consumes it: distribute_cash or distribute_loss claims the settlement\n// and marks it distributed, so the plan's unwind_paid keeps that profit, while an\n// abandoned distribution leaves the settlement refundable.\n// Prepare cash or loss first, then create shares against funded commitments of\n// that round. Distribution needs pending share weights equal to the round target.\n// Cash fee is a percentage of retained profit, VAT a percentage of that fee.\n// Principal plus retained profit less fee and VAT goes to weighted wallets;\n// floored residual goes to residual_to. Loss mode moves claim balances, not cash.\n// Child share execution is parent-owned. No report or clock proves outside payout.\n\n// Cost: round.create declares one owned account. Close transfers its balance\n// and invokes commitments; failure invokes their refunds. Distribution adds moves\n// and bounded share invocations. Run hsx cost for counts after policy selection.\n\ninstrument round(borrower: party, plan: ref<financing.installments> = object(financing.installments), operator: party = programOperator, 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, plan: ref<plan>, price: money = self.plan.principal, closesAt: date\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 { actor: { party: operator }, requires unique \"funding_plan\" on [self.plan]; requires self.borrower == self.plan.borrower }\n action close {\n from: open, to: funded, actor: { party: operator }\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 economics { purpose: principal, sourceParty: programOperator }\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 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>, investor: account of investor, 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: { investor: { field: self.investor } } } <= 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 actor: { party: investor }\n requires self.round in [open]\n requires self.wallet in [active]\n requires self.wallet.holder == self.investor\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 economics { purpose: principal, sourceParty: programOperator }\n }\n action fund { from: committed, to: funded, actor: { parent: round } }\n action withdraw {\n from: committed, to: withdrawn, actor: { party: investor }\n requires self.round in [open]\n deadline: { at: self.round.closesAt }\n moves self.amount from self.round.held to self.wallet.held economics { purpose: principal, sourceParty: programOperator }\n }\n action refund {\n from: committed, to: refunded, actor: { parent: round }\n moves self.amount from self.round.held to self.wallet.held economics { purpose: principal, sourceParty: programOperator }\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, operator: 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 {\n requires self.round in [funded]; requires self.source in [recorded]; requires self.source.plan == self.round.plan\n }\n action prepare_cash {\n from: pending, to: cash_ready\n requires self.mode == \"cash\"; requires self.source.kind == \"cash\"; requires self.source in [recorded]\n calculate: [\n { target: \"principal\", op: \"sum\", values: [{ field: self.source.principal }] }\n { target: \"profit\", op: \"sum\", values: [{ field: self.source.retainedProfit }] }\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\"; requires self.source in [recorded]\n calculate: [{ target: \"net\", op: \"sum\", values: [{ field: self.source.loss }] }]\n }\n action distribute_cash { allowZero: true,\n from: cash_ready, to: distributed, actor: { party: operator }\n requires self.source in [recorded]; requires unique \"settlement_consumption\" on [self.source.plan, self.source.identity]\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 economics { purpose: internal, sourceParty: programOperator }; moves self.vat from self.held to programTax economics { purpose: pass_through, sourceParty: programOperator }\n invoke: [{ reference: self.source, action: distribute, input: {} }, { 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 { allowZero: true,\n from: distributed, to: distributed, actor: { parent: current() }\n moves self.held.balance from self.held to residual_to\n }\n action distribute_loss { allowZero: true,\n from: loss_ready, to: distributed, actor: { party: operator }\n requires self.source in [recorded]; requires unique \"settlement_consumption\" on [self.source.plan, self.source.identity]\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: [{ reference: self.source, action: distribute, input: {} }, { 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 { allowZero: true,\n from: distributed, to: distributed, actor: { parent: current() }\n moves self.losses.balance from self.losses to self.residualLoss economics { purpose: internal, sourceParty: programOperator }\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 { allowZero: true,\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 { allowZero: true, from: pending, to: paid, actor: { parent: parent }, moves self.gross from self.distribution.losses to self.commitment.loss economics { purpose: internal, sourceParty: programOperator } }\n }\n }\n}\n"],
|
|
11
11
|
["marketplace.hsx", "header marketplace\n\n// Economics: Deposit funding, escrow credit and returns are principal. Retention is\n// earning for the company or passes the buyer's cash through to a bound outside recipient.\n\n// Listing, order and reservation are separate agreements. Expose their create\n// and decision actions individually. Order fulfillment does not move escrow cash;\n// only the fulfiller marks it, the Product operator unless the seller is bound.\n// Pair an order with escrow.hold and expose its fund, deliver, accept, dispute,\n// verify_return and refund aliases. Refund needs disputed -> return_verified,\n// with payee evidence, then returns the full price to payer; accept pays payee.\n// A reservation holds its own deposit. Activate requires an active listing and\n// no placed order. Only a declared converter may invoke credit. A financing\n// plan on the same hold credits it when the lender disburses. Credit consumes the\n// deposit once, credits at most the contribution, and returns excess to buyer.\n// Expose cancel, seller_cancel or operator_cancel for the intended actors.\n// Buyer cancel and expiry use configured refund percentages; seller/operator\n// cancellation return the whole reservation balance. Converted money is in escrow,\n// so subsequent return verification and refund use the escrow aliases.\n\n// Cost: listing and order actions declare no transfers. Reservation.create\n// declares one owned account; activate declares one deposit transfer. Cancellation\n// and credit split that balance into moves. Run hsx cost for the composed counts.\n\ninstrument listing(seller: party) {\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 }\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, fulfiller: party = programOperator) {\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 }\n invariants count of { instrument: all(marketplace.order), reference: \"listing\", anchor: self.listing, states: [placed, fulfilled], limit: 366 } <= 1\n action fulfill { from: placed, to: fulfilled, actor: { party: fulfiller } }\n action cancel { from: [quoted, placed], to: cancelled, actor: { party: buyer } }\n}\n\ninstrument reservation(listing: ref<marketplace.listing>, funds: ref<escrow.hold>, 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: all(marketplace.reservation), 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 economics { purpose: principal, sourceParty: buyer }\n }\n action credit { allowZero: true,\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.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 economics { purpose: principal, sourceParty: programOperator }\n moves self.refund from self.held to self.buyer economics { purpose: principal, sourceParty: programOperator }\n }\n action cancel { allowZero: true,\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 economics { purpose: principal, sourceParty: programOperator }; moves self.retained from self.held to retained_to economics { recipient: retained_to, company: { purpose: earning, sourceParty: buyer }, participant: { purpose: pass_through, sourceParty: programOperator } }\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 economics { purpose: principal, sourceParty: programOperator }\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 economics { purpose: principal, sourceParty: programOperator }\n }\n action withdraw { from: proposed, to: cancelled, actor: { party: buyer } }\n action expire { allowZero: true,\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 economics { purpose: principal, sourceParty: programOperator }; moves self.retained from self.held to retained_to economics { recipient: retained_to, company: { purpose: earning, sourceParty: buyer }, participant: { purpose: pass_through, sourceParty: programOperator } }\n }\n action expire_proposal { from: proposed, to: expired, actor: clock, due: { at: self.proposalExpiresAt } }\n}\n"],
|
|
12
12
|
["money.hsx", "header money\n\n// Economics: Held funding and returns are principal. Release to the company realizes\n// earnings; release to another participant passes the payer's cash through. Generic transfers, splits,\n// schedules, swaps, boundary payouts and metered fees retain no assumed purpose.\n\n// Expose each attachment's create and caller actions explicitly. A transfer or\n// split pays once; a hold exposes fund, release and refund separately. Release\n// pays payee and refund returns payer. A hold has no dispute or damage decision.\n// The payee proposes a schedule, which creates its count occurrences, and only\n// the payer activates or cancels it. Each due occurrence pays only while the\n// schedule is active. A due time promises no retry.\n// A pool accepts whole contributions only up to its remaining target and at most\n// 366 paid records. Expose pay to release the exact target. Clock failure refunds\n// original contributors; excess acceptance and partial contribution are absent.\n// A swap reserves both legs before exchange or voids reservations on expiry.\n// Payout instruct reserves across the selected adapter; confirm/reject require\n// matching terminal instruction evidence. An acknowledgement cannot settle it.\n// Metered bill charges a unique usage identity at the fixed unit price, only\n// under an active mandate the payer created: bills stop at its expiresAt, and at\n// most 366 billed events across every metered attachment on the mandate may sum\n// their payer debit, buyer fee and tax included, to its limit. The payer revokes\n// it to stop billing. Only the payee cancels its own unbilled usage.\n\n// Cost: transfer.pay declares one transfer. Hold.create declares one owned account;\n// fund, release and refund each declare one transfer. Schedules and pools add bounded\n// child invocations. Run hsx cost on the composed program for counts, not riyal prices.\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 }, requires self.amount > \"0\" }\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 economics { purpose: principal, sourceParty: payer }\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, actor: { party: payer }\n moves self.amount from self.held to payee economics { recipient: payee, company: { purpose: earning, sourceParty: payer }, participant: { purpose: pass_through, sourceParty: programOperator } }\n }\n action refund {\n from: funded, to: refunded, actor: { party: payee }\n moves self.amount from self.held to payer economics { purpose: principal, sourceParty: programOperator }\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 { allowZero: true, requires self.amount > \"0\"; from: pending, to: paid, actor: { party: payer }, 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 actor: { party: payee }\n invoke: [{ range: { count: { literal: count }, maximum: count, bind: position }, instrument: occurrence, action: create, input: { schedule: { field: self.id }, position: { field: position } } }]\n }\n action activate { from: draft, to: active, actor: { party: payer } }\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, actor: { party: payer } }\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 { actor: { parent: parent }, input { schedule: ref<parent>, position: integer(1, count) }, requires unique \"scheduled_position\" on [self.schedule, self.position] }\n action pay { allowZero: true, 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, actor: { party: payee }\n requires self.held.balance == self.target\n moves self.target from self.held to payee economics { recipient: payee, company: { purpose: earning, sourceParty: payer }, participant: { purpose: pass_through, sourceParty: programOperator } }\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, remaining: money? }\n lifecycle { states: [pending, paid, refunded], initial: pending }\n invariants count of { instrument: current(), reference: \"pool\", anchor: self.pool, states: [paid], limit: 366 } <= 366\n action create { requires self.pool in [open] }\n action pay { from: pending, to: paid, actor: { party: payer }, deadline: { at: self.pool.closesAt }, requires self.pool in [open], calculate: [{ target: remaining, op: subtract, base: { field: self.pool.target }, subtract: [{ field: self.pool.held.balance }] }], requires self.amount <= self.remaining, moves self.amount from self.payer to self.pool.held economics { purpose: principal, sourceParty: payer } }\n action refund { from: paid, to: refunded, actor: { parent: parent }, moves self.amount from self.pool.held to self.payer economics { purpose: principal, sourceParty: programOperator } }\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, actor: { party: first }, 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 payout(payer: party, payee: party, adapter: text, amount: money = runtime) {\n summary: \"Pay the recipient when the provider confirms settlement.\"\n fields { amount: money = amount }\n lifecycle { states: [pending, instructed, settled, rejected], initial: pending }\n action create {}\n action instruct {\n from: pending, to: instructed, actor: { party: payer }\n moves reserve self.amount from payer to payee boundary adapter\n }\n action confirm {\n from: instructed, to: settled\n moves post instruct\n }\n action reject {\n from: instructed, to: rejected\n moves void instruct\n }\n}\n\ninstrument mandate(payer: party, payee: party) {\n summary: \"A payer's permission for one payee to charge up to a total until it expires.\"\n fields { payer: account of payer, payee: account of payee, limit: money, expiresAt: date }\n lifecycle { states: [active, revoked], initial: active }\n action create { actor: { party: payer }, requires self.limit > \"0\" }\n action revoke { from: active, to: revoked, actor: { party: payer } }\n}\n\ninstrument metered(payer: party, payee: party, unit_price: money, units: integer = 1, fee: fee = { seller: 0% }, mandate: ref<money.mandate> = object(money.mandate)) {\n summary: \"A unique usage event priced once at the fixed unit price.\"\n fields { usageIdentity: text, mandate: ref<mandate>, payer: account of payer, payee: account of payee, unitPrice: money = unit_price, units: integer = units, amount: money = multiply(self.unitPrice, self.units) }\n lifecycle { states: [recorded, billed, cancelled], initial: recorded }\n invariants sum \"bill_move1_debit\" of { instrument: all(money.metered), reference: \"mandate\", anchor: self.mandate, states: [billed], limit: 366 } <= self.mandate.limit\n action create { requires unique \"usage_event\" on [self.usageIdentity]; requires self.mandate.payer == self.payer; requires self.mandate.payee == self.payee }\n action bill { allowZero: true, requires self.amount > \"0\"; from: recorded, to: billed, actor: { party: payee }, deadline: { at: self.mandate.expiresAt }, requires self.mandate in [active], moves self.amount from payer to payee fee fee }\n action cancel { from: recorded, to: cancelled, actor: { party: payee } }\n}\n"],
|
package/std/insurance.hsx
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
header insurance
|
|
2
2
|
|
|
3
3
|
// Economics: Company commission is earning; refunds reverse its captured transfer.
|
|
4
|
-
// Outside broker commissions are pass-through.
|
|
5
|
-
//
|
|
4
|
+
// Outside broker commissions and insurer premiums are pass-through.
|
|
5
|
+
// Claim moves remain unclassified until their money purpose is declared.
|
|
6
6
|
|
|
7
7
|
// Expose cover.create, activate and cancel separately. The adapter names a
|
|
8
8
|
// registered boundary adapter (conformance_boundary in sandbox). covers is an
|
|
@@ -59,7 +59,7 @@ instrument cover(holder: party, adapter: text, commission: percent = 0%, broker:
|
|
|
59
59
|
requires self.premium > "0"
|
|
60
60
|
from: pending, to: paid, actor: { party: holder }
|
|
61
61
|
requires self.cover in [active]
|
|
62
|
-
moves self.insurerPremium from holder to self.cover.insurer
|
|
62
|
+
moves self.insurerPremium from holder to self.cover.insurer economics { purpose: pass_through, sourceParty: holder }
|
|
63
63
|
moves self.commission from holder to broker capture "commissionReceipt" economics { recipient: broker, company: { purpose: earning, sourceParty: holder }, participant: { purpose: pass_through, sourceParty: holder } }
|
|
64
64
|
}
|
|
65
65
|
action start { from: paid, to: active, actor: clock, due: { at: self.startsAt } }
|
|
@@ -68,7 +68,7 @@ instrument cover(holder: party, adapter: text, commission: percent = 0%, broker:
|
|
|
68
68
|
allowZero: true
|
|
69
69
|
requires self.premium > "0"
|
|
70
70
|
from: paid, to: refunded, actor: { parent: parent }, deadline: { at: self.startsAt }
|
|
71
|
-
moves self.insurerPremium from self.cover.insurer to holder
|
|
71
|
+
moves self.insurerPremium from self.cover.insurer to holder economics { purpose: pass_through, sourceParty: programOperator }
|
|
72
72
|
moves self.commission from broker to holder economics { recipient: broker, company: { purpose: earning, sourceParty: broker, reversalOf: self.commissionReceipt }, participant: { purpose: pass_through, sourceParty: broker } }
|
|
73
73
|
}
|
|
74
74
|
}
|