business-as-code 2.1.3 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. package/.turbo/turbo-build.log +4 -5
  2. package/CHANGELOG.md +53 -0
  3. package/README.md +2 -0
  4. package/dist/dollar.d.ts.map +1 -1
  5. package/dist/dollar.js +2 -2
  6. package/dist/dollar.js.map +1 -1
  7. package/dist/entities/organization.d.ts +4 -0
  8. package/dist/entities/organization.d.ts.map +1 -1
  9. package/dist/entities/organization.js +27 -18
  10. package/dist/entities/organization.js.map +1 -1
  11. package/dist/entities/planning.d.ts +87 -0
  12. package/dist/finance/account.d.ts +44 -0
  13. package/dist/finance/account.d.ts.map +1 -0
  14. package/dist/finance/account.js +6 -0
  15. package/dist/finance/account.js.map +1 -0
  16. package/dist/finance/authority.d.ts +78 -0
  17. package/dist/finance/authority.d.ts.map +1 -0
  18. package/dist/finance/authority.js +27 -0
  19. package/dist/finance/authority.js.map +1 -0
  20. package/dist/finance/card.d.ts +36 -0
  21. package/dist/finance/card.d.ts.map +1 -0
  22. package/dist/finance/card.js +6 -0
  23. package/dist/finance/card.js.map +1 -0
  24. package/dist/finance/identity.d.ts +30 -0
  25. package/dist/finance/identity.d.ts.map +1 -0
  26. package/dist/finance/identity.js +8 -0
  27. package/dist/finance/identity.js.map +1 -0
  28. package/dist/finance/index.d.ts +36 -0
  29. package/dist/finance/index.d.ts.map +1 -0
  30. package/dist/finance/index.js +22 -0
  31. package/dist/finance/index.js.map +1 -0
  32. package/dist/finance/ledger.d.ts +24 -0
  33. package/dist/finance/ledger.d.ts.map +1 -0
  34. package/dist/finance/ledger.js +8 -0
  35. package/dist/finance/ledger.js.map +1 -0
  36. package/dist/finance/merchant.d.ts +129 -0
  37. package/dist/finance/merchant.d.ts.map +1 -0
  38. package/dist/finance/merchant.js +21 -0
  39. package/dist/finance/merchant.js.map +1 -0
  40. package/dist/finance/outcome-contract.d.ts +139 -0
  41. package/dist/finance/outcome-contract.d.ts.map +1 -0
  42. package/dist/finance/outcome-contract.js +27 -0
  43. package/dist/finance/outcome-contract.js.map +1 -0
  44. package/dist/finance/port.d.ts +121 -0
  45. package/dist/finance/port.d.ts.map +1 -0
  46. package/dist/finance/port.js +10 -0
  47. package/dist/finance/port.js.map +1 -0
  48. package/dist/finance/pricing.d.ts +154 -0
  49. package/dist/finance/pricing.d.ts.map +1 -0
  50. package/dist/finance/pricing.js +79 -0
  51. package/dist/finance/pricing.js.map +1 -0
  52. package/dist/finance/proof-predicate.d.ts +92 -0
  53. package/dist/finance/proof-predicate.d.ts.map +1 -0
  54. package/dist/finance/proof-predicate.js +80 -0
  55. package/dist/finance/proof-predicate.js.map +1 -0
  56. package/dist/finance/refund.d.ts +44 -0
  57. package/dist/finance/refund.d.ts.map +1 -0
  58. package/dist/finance/refund.js +41 -0
  59. package/dist/finance/refund.js.map +1 -0
  60. package/dist/finance/sla.d.ts +25 -0
  61. package/dist/finance/sla.d.ts.map +1 -0
  62. package/dist/finance/sla.js +7 -0
  63. package/dist/finance/sla.js.map +1 -0
  64. package/dist/finance/types.d.ts +79 -0
  65. package/dist/finance/types.d.ts.map +1 -0
  66. package/dist/finance/types.js +8 -0
  67. package/dist/{canvas → finance}/types.js.map +1 -1
  68. package/dist/goals.d.ts +19 -0
  69. package/dist/goals.d.ts.map +1 -1
  70. package/dist/goals.js +81 -12
  71. package/dist/goals.js.map +1 -1
  72. package/dist/index.d.ts +12 -8
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +19 -7
  75. package/dist/index.js.map +1 -1
  76. package/dist/kpis.d.ts +19 -0
  77. package/dist/kpis.d.ts.map +1 -1
  78. package/dist/kpis.js +71 -6
  79. package/dist/kpis.js.map +1 -1
  80. package/dist/metrics.d.ts.map +1 -1
  81. package/dist/metrics.js +29 -24
  82. package/dist/metrics.js.map +1 -1
  83. package/dist/okrs.d.ts +34 -0
  84. package/dist/okrs.d.ts.map +1 -1
  85. package/dist/okrs.js +135 -13
  86. package/dist/okrs.js.map +1 -1
  87. package/dist/organization.d.ts.map +1 -1
  88. package/dist/organization.js +11 -11
  89. package/dist/organization.js.map +1 -1
  90. package/dist/process.d.ts.map +1 -1
  91. package/dist/process.js +13 -12
  92. package/dist/process.js.map +1 -1
  93. package/dist/product.d.ts.map +1 -1
  94. package/dist/product.js +9 -9
  95. package/dist/product.js.map +1 -1
  96. package/dist/queries.d.ts.map +1 -1
  97. package/dist/queries.js +194 -32
  98. package/dist/queries.js.map +1 -1
  99. package/dist/roles.d.ts +25 -31
  100. package/dist/roles.d.ts.map +1 -1
  101. package/dist/roles.js +37 -10
  102. package/dist/roles.js.map +1 -1
  103. package/dist/workflow.d.ts.map +1 -1
  104. package/dist/workflow.js +13 -12
  105. package/dist/workflow.js.map +1 -1
  106. package/package.json +20 -13
  107. package/src/dollar.ts +5 -2
  108. package/src/entities/organization.ts +31 -18
  109. package/src/finance/account.ts +48 -0
  110. package/src/finance/authority.ts +42 -0
  111. package/src/finance/card.ts +38 -0
  112. package/src/finance/identity.ts +31 -0
  113. package/src/finance/index.ts +117 -0
  114. package/src/finance/ledger.ts +26 -0
  115. package/src/finance/merchant.ts +127 -0
  116. package/src/finance/outcome-contract.ts +157 -0
  117. package/src/finance/port.ts +144 -0
  118. package/src/finance/pricing.ts +197 -0
  119. package/src/finance/proof-predicate.ts +106 -0
  120. package/src/finance/refund.ts +52 -0
  121. package/src/finance/sla.ts +33 -0
  122. package/src/finance/types.ts +75 -0
  123. package/src/goals.ts +78 -12
  124. package/src/index.ts +48 -18
  125. package/src/kpis.ts +62 -8
  126. package/src/metrics.ts +92 -79
  127. package/src/okrs.ts +120 -20
  128. package/src/organization.ts +12 -15
  129. package/src/process.ts +11 -12
  130. package/src/product.ts +8 -9
  131. package/src/queries.ts +238 -75
  132. package/src/roles.ts +62 -61
  133. package/src/workflow.ts +22 -15
  134. package/test/business.test.ts +282 -0
  135. package/test/dollar.test.ts +270 -0
  136. package/test/entities.test.ts +628 -0
  137. package/test/financials.test.ts +539 -0
  138. package/test/goals.test.ts +451 -0
  139. package/{src → test}/index.test.ts +1 -1
  140. package/test/kpis.test.ts +440 -0
  141. package/test/metrics.test.ts +744 -0
  142. package/test/okrs.test.ts +741 -0
  143. package/test/organization.test.ts +548 -0
  144. package/test/process.test.ts +503 -0
  145. package/test/product.test.ts +430 -0
  146. package/test/queries.test.ts +556 -0
  147. package/test/roles.test.ts +546 -0
  148. package/test/service.test.ts +450 -0
  149. package/test/types.test.ts +1141 -0
  150. package/test/vision.test.ts +214 -0
  151. package/test/workflow.test.ts +501 -0
  152. package/vitest.config.ts +47 -0
  153. package/LICENSE +0 -21
  154. package/dist/canvas/activities.d.ts +0 -19
  155. package/dist/canvas/activities.d.ts.map +0 -1
  156. package/dist/canvas/activities.js +0 -20
  157. package/dist/canvas/activities.js.map +0 -1
  158. package/dist/canvas/channels.d.ts +0 -20
  159. package/dist/canvas/channels.d.ts.map +0 -1
  160. package/dist/canvas/channels.js +0 -21
  161. package/dist/canvas/channels.js.map +0 -1
  162. package/dist/canvas/relationships.d.ts +0 -20
  163. package/dist/canvas/relationships.d.ts.map +0 -1
  164. package/dist/canvas/relationships.js +0 -21
  165. package/dist/canvas/relationships.js.map +0 -1
  166. package/dist/canvas/resources.d.ts +0 -20
  167. package/dist/canvas/resources.d.ts.map +0 -1
  168. package/dist/canvas/resources.js +0 -30
  169. package/dist/canvas/resources.js.map +0 -1
  170. package/dist/canvas/revenue.d.ts +0 -22
  171. package/dist/canvas/revenue.d.ts.map +0 -1
  172. package/dist/canvas/revenue.js +0 -30
  173. package/dist/canvas/revenue.js.map +0 -1
  174. package/dist/canvas/segments.d.ts +0 -20
  175. package/dist/canvas/segments.d.ts.map +0 -1
  176. package/dist/canvas/segments.js +0 -28
  177. package/dist/canvas/segments.js.map +0 -1
  178. package/dist/canvas/types.d.ts +0 -232
  179. package/dist/canvas/types.d.ts.map +0 -1
  180. package/dist/canvas/types.js +0 -8
  181. package/dist/canvas/value.d.ts +0 -20
  182. package/dist/canvas/value.d.ts.map +0 -1
  183. package/dist/canvas/value.js +0 -21
  184. package/dist/canvas/value.js.map +0 -1
  185. package/src/business.js +0 -108
  186. package/src/canvas/activities.ts +0 -32
  187. package/src/canvas/canvas.ts +0 -482
  188. package/src/canvas/channels.ts +0 -34
  189. package/src/canvas/costs.ts +0 -43
  190. package/src/canvas/economics.ts +0 -99
  191. package/src/canvas/index.ts +0 -206
  192. package/src/canvas/partnerships.ts +0 -34
  193. package/src/canvas/projections.ts +0 -141
  194. package/src/canvas/relationships.ts +0 -34
  195. package/src/canvas/resources.ts +0 -43
  196. package/src/canvas/revenue.ts +0 -56
  197. package/src/canvas/segments.ts +0 -42
  198. package/src/canvas/types.ts +0 -363
  199. package/src/canvas/value.ts +0 -34
  200. package/src/dollar.js +0 -106
  201. package/src/entities/assets.js +0 -322
  202. package/src/entities/business.js +0 -369
  203. package/src/entities/communication.js +0 -254
  204. package/src/entities/customers.js +0 -988
  205. package/src/entities/financials.js +0 -931
  206. package/src/entities/goals.js +0 -799
  207. package/src/entities/index.js +0 -197
  208. package/src/entities/legal.js +0 -300
  209. package/src/entities/market.js +0 -300
  210. package/src/entities/marketing.js +0 -1156
  211. package/src/entities/offerings.js +0 -726
  212. package/src/entities/operations.js +0 -786
  213. package/src/entities/organization.js +0 -806
  214. package/src/entities/partnerships.js +0 -299
  215. package/src/entities/planning.js +0 -270
  216. package/src/entities/projects.js +0 -348
  217. package/src/entities/risk.js +0 -292
  218. package/src/entities/sales.js +0 -1247
  219. package/src/financials.js +0 -296
  220. package/src/goals.js +0 -214
  221. package/src/index.js +0 -131
  222. package/src/index.test.js +0 -274
  223. package/src/kpis.js +0 -231
  224. package/src/metrics.js +0 -324
  225. package/src/okrs.js +0 -268
  226. package/src/organization.js +0 -172
  227. package/src/process.js +0 -240
  228. package/src/product.js +0 -144
  229. package/src/queries.js +0 -414
  230. package/src/roles.js +0 -254
  231. package/src/service.js +0 -139
  232. package/src/types.js +0 -4
  233. package/src/vision.js +0 -67
  234. package/src/workflow.js +0 -246
  235. package/tests/canvas.test.ts +0 -842
@@ -0,0 +1,31 @@
1
+ /**
2
+ * AgentIdentity + AgentMerchant — cross-provider identity for the four
3
+ * agentic-commerce gaps Stripe didn't ship at Sessions 2026:
4
+ * - Agent-as-buyer with delegation (B2A2D, B2A2B)
5
+ * - Agent-as-merchant (Stripe makes you wire through Connect manually)
6
+ */
7
+
8
+ export interface AgentIdentity {
9
+ $id: string
10
+ $type: 'AgentIdentity'
11
+ /** Worker the identity is for (Person/Agent/Role); ThingRef shape. */
12
+ workerRef: string
13
+ /**
14
+ * When the agent buys on behalf of someone else (B2A2D, B2A2B).
15
+ * Null when buying for self (B2A or A2A).
16
+ */
17
+ delegatedFor?: string
18
+ /** OAuth / capability scopes the identity carries. */
19
+ scopes: string[]
20
+ /** Per-provider credentials (Stripe Projects keys, Tempo wallet IDs, etc.). */
21
+ providerCreds: Record<string, unknown>
22
+ }
23
+
24
+ export interface AgentMerchant {
25
+ $id: string
26
+ $type: 'AgentMerchant'
27
+ workerRef: string
28
+ /** Account that receives payouts. */
29
+ payoutAccountRef: string
30
+ providerData: Record<string, unknown>
31
+ }
@@ -0,0 +1,117 @@
1
+ /**
2
+ * business-as-code/finance — the outcome-contract economic substrate.
3
+ *
4
+ * Source of truth for the economic primitives of the agentic economy:
5
+ * Money/Cost/Budget value types, Account/Card/Ledger/Identity payment types,
6
+ * Pricing, OutcomeContract, ProofPredicate, SLAPolicy, RefundContract,
7
+ * AuthorityBoundary, and the FinanceProvider/Merchant ports.
8
+ *
9
+ * Finance is foundational here because it is the core of the default OKRs
10
+ * (Revenue / Growth / Profit). `services-as-software` and `digital-tools`
11
+ * consume these primitives directly from here.
12
+ *
13
+ * Importable via the `business-as-code/finance` subpath export.
14
+ *
15
+ * @packageDocumentation
16
+ */
17
+
18
+ // Money + Cost + Budget + spend-control
19
+ export type {
20
+ FiatCurrency,
21
+ StablecoinCurrency,
22
+ CryptoCurrency,
23
+ Currency,
24
+ Money,
25
+ Cost,
26
+ Budget,
27
+ BudgetScope,
28
+ SpendControl,
29
+ CostModel,
30
+ } from './types.js'
31
+
32
+ // Account + transfer
33
+ export type { Account, AccountSpec, TransferOpts, TransferResult } from './account.js'
34
+
35
+ // Card (Issuing)
36
+ export type { Card, CardSpec } from './card.js'
37
+
38
+ // Ledger
39
+ export type { LedgerEntry, LedgerLine } from './ledger.js'
40
+
41
+ // Identity (cross-provider)
42
+ export type { AgentIdentity, AgentMerchant } from './identity.js'
43
+
44
+ // ProofPredicate union + factories
45
+ export type { ProofPredicate } from './proof-predicate.js'
46
+ export {
47
+ SchemaMatch,
48
+ EvaluatorPass,
49
+ HumanSign,
50
+ External,
51
+ LoadBearingPass,
52
+ OverallFloor,
53
+ UnmetRequirementsPass,
54
+ AND,
55
+ OR,
56
+ } from './proof-predicate.js'
57
+
58
+ // Outcome contract + proof of result
59
+ export type {
60
+ OutcomeContract,
61
+ OutcomeContractBase,
62
+ OutcomeContractWithExpiresAt,
63
+ OutcomeContractWithTimeoutDays,
64
+ OutcomeContractWithTiers,
65
+ ProofOfResult,
66
+ } from './outcome-contract.js'
67
+ export { resolveOutcomeAmount } from './outcome-contract.js'
68
+
69
+ // SLA policy
70
+ export type { SLAPolicy, SLATarget } from './sla.js'
71
+
72
+ // Refund contract + catalog
73
+ export type { RefundContractRef } from './refund.js'
74
+ export { RefundContracts } from './refund.js'
75
+
76
+ // Authority boundary + catalog
77
+ export type { AuthorityBoundaryRef } from './authority.js'
78
+ export { AuthorityBoundaries } from './authority.js'
79
+
80
+ // Pricing factories — type + value merged on the same name (Pricing.outcome(...), etc.)
81
+ export type {
82
+ OutcomeTier,
83
+ PerInvocationTier,
84
+ MeteredEntry,
85
+ CompositeBase,
86
+ SubscriptionPlan,
87
+ PercentOfBasis,
88
+ } from './pricing.js'
89
+ export { Pricing, money } from './pricing.js'
90
+ export type { Pricing as PricingValue } from './pricing.js'
91
+
92
+ // Provider port + capabilities
93
+ export type {
94
+ FinanceProvider,
95
+ ProviderCapabilities,
96
+ ProviderRail,
97
+ ChargeOpts,
98
+ ChargeResult,
99
+ RefundResult,
100
+ EscrowHandle,
101
+ ReleaseResult,
102
+ SubscribeOpts,
103
+ Subscription,
104
+ MeterEvent,
105
+ } from './port.js'
106
+
107
+ // Merchant / Connect provisioning (product-line + hosted checkout + payout)
108
+ export type {
109
+ MerchantCapable,
110
+ PriceInterval,
111
+ ProvisionProductOpts,
112
+ ProvisionedProduct,
113
+ CheckoutOpts,
114
+ CheckoutSession,
115
+ PayoutOpts,
116
+ PayoutResult,
117
+ } from './merchant.js'
@@ -0,0 +1,26 @@
1
+ /**
2
+ * LedgerEntry — double-entry record. Every entry IS an Action under the SVO substrate.
3
+ *
4
+ * Invariant: per-currency, sum(debits.amount) === sum(credits.amount).
5
+ * The ledger is append-only; reversals are new entries with opposite sign.
6
+ */
7
+
8
+ import type { Money } from './types.js'
9
+
10
+ export interface LedgerEntry {
11
+ $id: string
12
+ $type: 'LedgerEntry'
13
+ /** Reference to the underlying Action (digital-objects ActionRef shape). */
14
+ actionRef: string
15
+ debits: LedgerLine[]
16
+ credits: LedgerLine[]
17
+ /** Optional human-readable memo. */
18
+ memo?: string
19
+ /** ISO-8601 timestamp. */
20
+ postedAt: string
21
+ }
22
+
23
+ export interface LedgerLine {
24
+ accountRef: string
25
+ amount: Money
26
+ }
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Merchant provisioning — the platform/Connect half of the FinanceProvider
3
+ * port: turn a priced Offer into a sellable product-line under a holdco, and
4
+ * mint a checkout for it.
5
+ *
6
+ * Motivation (added by explore.startups.studio B4, issue #222): the substrate
7
+ * `FinanceProvider` port modeled CHARGING (`charge`/`refund`/`subscribe`) but
8
+ * not the upstream provisioning a hosted-checkout flow needs:
9
+ * 1. provision a Product + Price under a platform account (Stripe Connect:
10
+ * one platform / holdco, many product-lines), keyed to a caller-supplied
11
+ * durable id (NOT a name — names are mutable),
12
+ * 2. open a hosted Checkout session that returns a redirectable URL,
13
+ * 3. report a payout against the platform balance.
14
+ *
15
+ * Stripe ships all three; the gap was only that the port did not EXPRESS them,
16
+ * so a consumer had to reach past the port into raw Stripe. These types close
17
+ * that gap so the consumer wires through the port (Stripe / Tempo / x402 are
18
+ * interchangeable behind it).
19
+ */
20
+
21
+ import type { Money } from './types.js'
22
+ import type { Pricing } from './pricing.js'
23
+
24
+ /** How a provisioned Price recurs — mirrors Stripe `price.recurring.interval`. */
25
+ export type PriceInterval = 'day' | 'week' | 'month' | 'quarter' | 'year'
26
+
27
+ /**
28
+ * Provision a per-product-line Product + Price under the platform/holdco
29
+ * account. `merchantRef` is the caller's DURABLE key for the product-line
30
+ * (e.g. a Startup Id) — adapters MUST round-trip it as provider metadata so a
31
+ * re-provision is idempotent on it, NOT on the (mutable) display name.
32
+ */
33
+ export interface ProvisionProductOpts {
34
+ /** Caller's durable product-line key (e.g. Startup Id). The idempotency anchor. */
35
+ merchantRef: string
36
+ /** Display name for the product (mutable; never used as the key). */
37
+ name: string
38
+ /** Optional product description. */
39
+ description?: string
40
+ /** The unit price of the representative tier. */
41
+ price: Money
42
+ /** Recurring interval; omit for a one-time price. */
43
+ interval?: PriceInterval
44
+ /** The full authored Pricing architecture (carried as provider metadata for audit). */
45
+ pricing?: Pricing
46
+ /** Idempotency key for at-most-once provisioning. */
47
+ idempotencyKey?: string
48
+ /** Provider-specific opts; pass-through. */
49
+ providerOpts?: Record<string, unknown>
50
+ }
51
+
52
+ export interface ProvisionedProduct {
53
+ $id: string
54
+ $type: 'Product'
55
+ /** Echoed durable product-line key. */
56
+ merchantRef: string
57
+ /** Provider product + price ids. */
58
+ providerData: { provider: string; productId: string; priceId: string }
59
+ }
60
+
61
+ /** Open a hosted-checkout session for a provisioned Price. */
62
+ export interface CheckoutOpts {
63
+ /** The provider price id (from {@link ProvisionedProduct}). */
64
+ priceId: string
65
+ /** Caller's durable product-line key — round-tripped onto the resulting payment. */
66
+ merchantRef: string
67
+ /** Quantity of the price to purchase (default 1). */
68
+ quantity?: number
69
+ /** Where the provider redirects on success (may carry a `{CHECKOUT_SESSION_ID}` template). */
70
+ successUrl: string
71
+ /** Where the provider redirects on cancel. */
72
+ cancelUrl: string
73
+ /** Mode of the session: one-time payment vs. recurring subscription. */
74
+ mode?: 'payment' | 'subscription'
75
+ /** Arbitrary metadata to attach to the session + resulting payment (e.g. correlation ids). */
76
+ metadata?: Record<string, string>
77
+ /** Idempotency key for at-most-once session creation. */
78
+ idempotencyKey?: string
79
+ /** Provider-specific opts; pass-through. */
80
+ providerOpts?: Record<string, unknown>
81
+ }
82
+
83
+ export interface CheckoutSession {
84
+ $id: string
85
+ $type: 'CheckoutSession'
86
+ /** The redirectable hosted-checkout URL the buyer is sent to. */
87
+ url: string
88
+ /** Caller's durable product-line key. */
89
+ merchantRef: string
90
+ status: 'open' | 'complete' | 'expired'
91
+ providerData: { provider: string; externalId: string }
92
+ }
93
+
94
+ export interface PayoutOpts {
95
+ /** Amount to pay out from the platform balance. */
96
+ amount: Money
97
+ /** The connected/destination account ref receiving the payout. */
98
+ destinationRef: string
99
+ /** Idempotency key for at-most-once payout. */
100
+ idempotencyKey?: string
101
+ providerOpts?: Record<string, unknown>
102
+ }
103
+
104
+ export interface PayoutResult {
105
+ $id: string
106
+ $type: 'Payout'
107
+ amount: Money
108
+ destinationRef: string
109
+ status: 'pending' | 'paid' | 'failed'
110
+ /** ISO-8601 timestamp. */
111
+ createdAt: string
112
+ providerData: { provider: string; externalId: string }
113
+ }
114
+
115
+ /**
116
+ * The merchant/platform-provisioning capability set. A FinanceProvider MAY
117
+ * implement these (gated by {@link ProviderCapabilities.merchant}); a
118
+ * charge-only adapter omits them.
119
+ */
120
+ export interface MerchantCapable {
121
+ /** Provision (idempotently, on `merchantRef`) a Product + Price under the platform/holdco. */
122
+ provisionProduct(opts: ProvisionProductOpts): Promise<ProvisionedProduct>
123
+ /** Open a hosted-checkout session for a provisioned price; returns a redirectable URL. */
124
+ createCheckoutSession(opts: CheckoutOpts): Promise<CheckoutSession>
125
+ /** Report a payout against the platform balance to a destination account. */
126
+ payout?(opts: PayoutOpts): Promise<PayoutResult>
127
+ }
@@ -0,0 +1,157 @@
1
+ /**
2
+ * OutcomeContract — definition-of-done + escrow + release condition.
3
+ * Distinct from OutputContract (technical schema; lives in services-as-software).
4
+ *
5
+ * The predicate is evaluated against the runtime state of a Service invocation;
6
+ * when it passes, escrow releases funds to the seller.
7
+ */
8
+
9
+ import type { OutcomeTier } from './pricing.js'
10
+ import type { Money } from './types.js'
11
+ import type { ProofPredicate } from './proof-predicate.js'
12
+
13
+ /**
14
+ * Fields shared by all {@link OutcomeContract} variants.
15
+ *
16
+ * Split from the timeout + amount fields so the discriminated union below can
17
+ * express "exactly one of `expiresAt` / `timeoutDays`" AND "exactly one of
18
+ * `amount` / `tiers`" at the type level.
19
+ */
20
+ export interface OutcomeContractBase {
21
+ $id: string
22
+ $type: 'OutcomeContract'
23
+ /** Worker (Person/Agent/Role) that bought the outcome. */
24
+ buyer: string
25
+ /** Worker (Person/Agent/Role) that sold/delivers the outcome. */
26
+ seller: string
27
+ /** Service this contract is bound to. */
28
+ serviceRef: string
29
+ predicate: ProofPredicate
30
+ /** Account holding escrowed funds until predicate passes. */
31
+ escrowAccountRef?: string
32
+ onTimeout?: 'auto-cancel' | 'auto-refund' | 'escalate'
33
+ }
34
+
35
+ /**
36
+ * Variant carrying an absolute ISO-8601 *timestamp* (e.g.
37
+ * `'2026-05-12T00:00:00Z'`). The runtime treats this as the wall-clock
38
+ * deadline. Carries a single {@link Money} `amount`.
39
+ */
40
+ export interface OutcomeContractWithExpiresAt extends OutcomeContractBase {
41
+ /**
42
+ * Absolute ISO-8601 timestamp — the contract expires (and `onTimeout` fires)
43
+ * exactly at this instant. For relative durations from contract creation,
44
+ * use {@link OutcomeContractWithTimeoutDays.timeoutDays} instead.
45
+ */
46
+ expiresAt: string
47
+ timeoutDays?: never
48
+ amount: Money
49
+ tiers?: never
50
+ selectedTierId?: never
51
+ }
52
+
53
+ /**
54
+ * Variant carrying a relative-duration deadline measured in whole days from
55
+ * contract creation. The runtime computes
56
+ * `expiresAt = createdAt + timeoutDays * 24h`. Carries a single {@link Money}
57
+ * `amount`.
58
+ */
59
+ export interface OutcomeContractWithTimeoutDays extends OutcomeContractBase {
60
+ /**
61
+ * Whole days from contract creation until expiry. Mutually exclusive with
62
+ * {@link OutcomeContractWithExpiresAt.expiresAt}.
63
+ */
64
+ timeoutDays: number
65
+ expiresAt?: never
66
+ amount: Money
67
+ tiers?: never
68
+ selectedTierId?: never
69
+ }
70
+
71
+ /**
72
+ * Variant carrying a multi-tier `OutcomeTier[]` mirror of
73
+ * `Pricing.outcome.tiers`. Used when the Service quotes a tiered price (e.g.
74
+ * S/M/L by feature complexity) and the headline contract figure should be
75
+ * computed lazily from the chosen tier rather than baked at declaration time.
76
+ *
77
+ * At runtime, `Service.invoke` selects a tier based on input characteristics
78
+ * and sets `selectedTierId`; the headline {@link Money} amount is then
79
+ * computed by `tiers.find(t => t.id === selectedTierId)?.amount`.
80
+ *
81
+ * Carries `timeoutDays` (the tiered variant currently couples with relative-
82
+ * duration deadlines; absolute-deadline + tiers can be added later if a
83
+ * catalog Service needs both).
84
+ */
85
+ export interface OutcomeContractWithTiers extends OutcomeContractBase {
86
+ /**
87
+ * Whole days from contract creation until expiry. Mutually exclusive with
88
+ * {@link OutcomeContractWithExpiresAt.expiresAt}.
89
+ */
90
+ timeoutDays: number
91
+ expiresAt?: never
92
+ /**
93
+ * Mirror of `Pricing.outcome.tiers` — one entry per quoted complexity tier
94
+ * (e.g. S / M / L). The runtime resolves the headline amount from the
95
+ * selected tier at invocation time.
96
+ */
97
+ tiers: OutcomeTier[]
98
+ /**
99
+ * Tier id selected by the runtime at invocation time (e.g. `'S'`). Omitted
100
+ * at declaration time — `Service.invoke` sets it based on input
101
+ * characteristics, then a lazy getter computes the headline {@link Money}
102
+ * amount as `tiers.find(t => t.id === selectedTierId)?.amount`.
103
+ */
104
+ selectedTierId?: string
105
+ /**
106
+ * The runtime computes the headline amount from the selected tier — never
107
+ * declared inline on this variant.
108
+ */
109
+ amount?: never
110
+ }
111
+
112
+ /**
113
+ * Discriminated union — exactly one of `expiresAt` / `timeoutDays` is required,
114
+ * and exactly one of `amount` / `tiers` is required.
115
+ *
116
+ * Use {@link OutcomeContractWithExpiresAt} for absolute deadlines + a single
117
+ * {@link Money} amount; use {@link OutcomeContractWithTimeoutDays} for
118
+ * relative durations from contract creation + a single {@link Money} amount;
119
+ * use {@link OutcomeContractWithTiers} when the Service quotes a tiered price
120
+ * (S/M/L) and the runtime selects a tier per-invocation.
121
+ */
122
+ export type OutcomeContract =
123
+ | OutcomeContractWithExpiresAt
124
+ | OutcomeContractWithTimeoutDays
125
+ | OutcomeContractWithTiers
126
+
127
+ /**
128
+ * Resolve the headline {@link Money} amount on an {@link OutcomeContract},
129
+ * lazily computing from `tiers[selectedTierId]` for the
130
+ * {@link OutcomeContractWithTiers} variant.
131
+ *
132
+ * Returns `undefined` for the tiers variant when no tier has been selected
133
+ * yet (e.g. pre-invocation, at declaration / publish time).
134
+ */
135
+ export function resolveOutcomeAmount(contract: OutcomeContract): Money | undefined {
136
+ if (contract.tiers !== undefined) {
137
+ if (contract.selectedTierId === undefined) return undefined
138
+ const tier = contract.tiers.find((t) => t.id === contract.selectedTierId)
139
+ if (!tier) return undefined
140
+ return { amount: tier.amount, currency: tier.currency ?? 'USD' }
141
+ }
142
+ return contract.amount
143
+ }
144
+
145
+ export interface ProofOfResult {
146
+ $id: string
147
+ $type: 'ProofOfResult'
148
+ contractRef: string
149
+ /** Worker (Person/Agent/Role) that signed the proof. */
150
+ signedBy: string
151
+ /** ISO-8601 timestamp. */
152
+ signedAt: string
153
+ /** Action that produced the verifiable output. */
154
+ outputRef?: string
155
+ /** Cryptographic signature where applicable. */
156
+ signature?: string
157
+ }
@@ -0,0 +1,144 @@
1
+ /**
2
+ * FinanceProvider — port for adapter implementations (Stripe, Tempo, x402,
3
+ * Privy, Lightspark). Every method is optional and gated by ProviderCapabilities;
4
+ * adapters declare which capabilities they support.
5
+ *
6
+ * Adapter implementations are forthcoming and ship outside the substrate —
7
+ * none are bundled here.
8
+ */
9
+
10
+ import type { Currency, Money, Cost } from './types.js'
11
+ import type { Account, AccountSpec, TransferOpts, TransferResult } from './account.js'
12
+ import type { Card, CardSpec } from './card.js'
13
+ import type { OutcomeContract, ProofOfResult } from './outcome-contract.js'
14
+ import type { StablecoinCurrency } from './types.js'
15
+ import type { MerchantCapable } from './merchant.js'
16
+
17
+ export type ProviderRail =
18
+ | 'mpp'
19
+ | 'spt'
20
+ | 'x402'
21
+ | 'streaming'
22
+ | 'card'
23
+ | 'wire'
24
+ | 'ach'
25
+ | 'lightning'
26
+ | 'on-chain'
27
+
28
+ export interface ProviderCapabilities {
29
+ payments: boolean
30
+ refunds: boolean
31
+ issuing: boolean
32
+ treasury: boolean
33
+ escrow: boolean
34
+ subscriptions: boolean
35
+ metering: boolean
36
+ /** Platform/Connect product-line provisioning + hosted checkout (see MerchantCapable). */
37
+ merchant: boolean
38
+ multiCurrency: boolean
39
+ currencies: Currency[]
40
+ stablecoins: StablecoinCurrency[]
41
+ rails: ProviderRail[]
42
+ }
43
+
44
+ export interface ChargeOpts {
45
+ /** Counterparty Worker paying the charge (ThingRef shape). */
46
+ buyer: string
47
+ amount: Money
48
+ /** Service or invocation reference for attribution. */
49
+ ref?: string
50
+ /** Idempotency key for at-most-once semantics. */
51
+ idempotencyKey?: string
52
+ /** Provider-specific opts; pass-through. */
53
+ providerOpts?: Record<string, unknown>
54
+ }
55
+
56
+ export interface ChargeResult {
57
+ $id: string
58
+ $type: 'Charge'
59
+ amount: Money
60
+ status: 'pending' | 'authorized' | 'captured' | 'failed' | 'refunded'
61
+ /** ISO-8601 timestamp. */
62
+ createdAt: string
63
+ providerData: { provider: string; externalId: string }
64
+ }
65
+
66
+ export interface RefundResult {
67
+ $id: string
68
+ $type: 'Refund'
69
+ chargeId: string
70
+ amount: Money
71
+ /** ISO-8601 timestamp. */
72
+ createdAt: string
73
+ }
74
+
75
+ export interface EscrowHandle {
76
+ $id: string
77
+ contractRef: string
78
+ state: 'held' | 'released' | 'expired' | 'cancelled'
79
+ providerData: { provider: string; externalId: string }
80
+ }
81
+
82
+ export interface ReleaseResult {
83
+ $id: string
84
+ escrowHandle: string
85
+ releasedAt: string
86
+ /** ISO-8601 timestamp. */
87
+ amount: Money
88
+ }
89
+
90
+ export interface SubscribeOpts {
91
+ buyer: string
92
+ planRef: string
93
+ /** Provider-specific opts; pass-through. */
94
+ providerOpts?: Record<string, unknown>
95
+ }
96
+
97
+ export interface Subscription {
98
+ $id: string
99
+ $type: 'Subscription'
100
+ buyer: string
101
+ planRef: string
102
+ state: 'active' | 'paused' | 'cancelled' | 'past-due'
103
+ /** ISO-8601 timestamp. */
104
+ startedAt: string
105
+ providerData: { provider: string; externalId: string }
106
+ }
107
+
108
+ export interface MeterEvent {
109
+ /** Subscription or customer this event meters against. */
110
+ subscriptionRef: string
111
+ event: string
112
+ quantity: bigint
113
+ /** ISO-8601 timestamp. */
114
+ occurredAt: string
115
+ }
116
+
117
+ export interface FinanceProvider extends Partial<MerchantCapable> {
118
+ readonly name: string
119
+ readonly capabilities: ProviderCapabilities
120
+
121
+ // Charge / refund
122
+ charge(opts: ChargeOpts): Promise<ChargeResult>
123
+ refund(chargeId: string, amount?: Money): Promise<RefundResult>
124
+
125
+ // Cards (optional)
126
+ issueCard?(spec: CardSpec): Promise<Card>
127
+ lockCard?(cardId: string): Promise<void>
128
+
129
+ // Treasury (optional)
130
+ openAccount?(spec: AccountSpec): Promise<Account>
131
+ balance?(accountId: string): Promise<Money>
132
+ transfer?(opts: TransferOpts): Promise<TransferResult>
133
+
134
+ // Outcome / escrow (optional; built on MPP Sessions / x402 escrow / native)
135
+ escrow?(contract: OutcomeContract): Promise<EscrowHandle>
136
+ release?(escrowHandle: string, proof: ProofOfResult): Promise<ReleaseResult>
137
+
138
+ // Subscriptions / metering (optional)
139
+ subscribe?(opts: SubscribeOpts): Promise<Subscription>
140
+ meter?(event: MeterEvent): Promise<void>
141
+
142
+ // Cost capture — provider-side cost reporting (e.g. LLM provider per-token)
143
+ captureCost?(cost: Omit<Cost, '$id' | '$type'>): Promise<Cost>
144
+ }