@openlup/core 0.0.0 → 0.6.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 (192) hide show
  1. package/CHANGELOG.md +184 -0
  2. package/CODE_OF_CONDUCT.md +39 -0
  3. package/CONTRIBUTING.md +34 -0
  4. package/LICENSE +204 -0
  5. package/MAINTAINERS.md +33 -0
  6. package/README.md +64 -3
  7. package/SECURITY.md +29 -0
  8. package/dist/bundle/contracts.d.ts +9 -0
  9. package/dist/bundle/contracts.js +1 -0
  10. package/dist/bundle/ports.d.ts +41 -0
  11. package/dist/bundle/ports.js +1 -0
  12. package/dist/catalog/identifiers.d.ts +31 -0
  13. package/dist/catalog/identifiers.js +46 -0
  14. package/dist/catalog/index.d.ts +2 -0
  15. package/dist/catalog/index.js +2 -0
  16. package/dist/checkout/idempotency.d.ts +29 -0
  17. package/dist/checkout/idempotency.js +37 -0
  18. package/dist/checkout/index.d.ts +2 -0
  19. package/dist/checkout/index.js +2 -0
  20. package/dist/company-identity/contracts.d.ts +220 -0
  21. package/dist/company-identity/contracts.js +168 -0
  22. package/dist/company-identity/index.d.ts +6 -0
  23. package/dist/company-identity/index.js +2 -0
  24. package/dist/company-identity/ports.d.ts +13 -0
  25. package/dist/company-identity/ports.js +1 -0
  26. package/dist/fulfillment/facts.d.ts +103 -0
  27. package/dist/fulfillment/facts.js +195 -0
  28. package/dist/fulfillment/index.d.ts +4 -0
  29. package/dist/fulfillment/index.js +2 -0
  30. package/dist/inventory/atp.d.ts +172 -0
  31. package/dist/inventory/atp.js +211 -0
  32. package/dist/inventory/index.d.ts +2 -0
  33. package/dist/inventory/index.js +2 -0
  34. package/dist/marketing/research/contracts.d.ts +75 -0
  35. package/dist/marketing/research/contracts.js +60 -0
  36. package/dist/marketing/research/index.d.ts +4 -0
  37. package/dist/marketing/research/index.js +4 -0
  38. package/dist/marketing/research/ports.d.ts +15 -0
  39. package/dist/marketing/research/ports.js +1 -0
  40. package/dist/partners/index.d.ts +4 -0
  41. package/dist/partners/index.js +4 -0
  42. package/dist/partners/ports.d.ts +12 -0
  43. package/dist/partners/ports.js +1 -0
  44. package/dist/partners/status.d.ts +48 -0
  45. package/dist/partners/status.js +35 -0
  46. package/dist/payment/executionBaseContracts.d.ts +81 -0
  47. package/dist/payment/executionBaseContracts.js +8 -0
  48. package/dist/payment/index.d.ts +36 -0
  49. package/dist/payment/index.js +18 -0
  50. package/dist/payment/methodLifecycle.d.ts +91 -0
  51. package/dist/payment/methodLifecycle.js +76 -0
  52. package/dist/payment/paymentControlTypes.d.ts +135 -0
  53. package/dist/payment/paymentControlTypes.js +110 -0
  54. package/dist/payment/paymentFailureTaxonomy.d.ts +80 -0
  55. package/dist/payment/paymentFailureTaxonomy.js +155 -0
  56. package/dist/payment/paymentFailureTaxonomyContracts.d.ts +106 -0
  57. package/dist/payment/paymentFailureTaxonomyContracts.js +177 -0
  58. package/dist/payment/paymentRecovery.d.ts +26 -0
  59. package/dist/payment/paymentRecovery.js +73 -0
  60. package/dist/payment/paymentRecoveryContracts.d.ts +53 -0
  61. package/dist/payment/paymentRecoveryContracts.js +10 -0
  62. package/dist/payment/paymentStateMachine.d.ts +28 -0
  63. package/dist/payment/paymentStateMachine.js +184 -0
  64. package/dist/payment/providerAttemptIdempotency.d.ts +23 -0
  65. package/dist/payment/providerAttemptIdempotency.js +31 -0
  66. package/dist/payment/providerCapability.d.ts +148 -0
  67. package/dist/payment/providerCapability.js +13 -0
  68. package/dist/platform-runtime/contracts.d.ts +9 -0
  69. package/dist/platform-runtime/contracts.js +13 -0
  70. package/dist/platform-runtime/index.d.ts +10 -0
  71. package/dist/platform-runtime/index.js +4 -0
  72. package/dist/platform-runtime/platformKernel.d.ts +44 -0
  73. package/dist/platform-runtime/platformKernel.js +39 -0
  74. package/dist/platform-runtime/ports.d.ts +100 -0
  75. package/dist/platform-runtime/ports.js +1 -0
  76. package/dist/pricing/index.d.ts +8 -0
  77. package/dist/pricing/index.js +8 -0
  78. package/dist/pricing/ports.d.ts +22 -0
  79. package/dist/pricing/ports.js +7 -0
  80. package/dist/pricing/pricingBreakdown.d.ts +86 -0
  81. package/dist/pricing/pricingBreakdown.js +155 -0
  82. package/dist/pricing/targetPriceAllocation.d.ts +97 -0
  83. package/dist/pricing/targetPriceAllocation.js +202 -0
  84. package/dist/pricing/types.d.ts +32 -0
  85. package/dist/pricing/types.js +4 -0
  86. package/dist/promo/adjustmentEngine.d.ts +4 -0
  87. package/dist/promo/adjustmentEngine.js +194 -0
  88. package/dist/promo/adjustmentTypes.d.ts +103 -0
  89. package/dist/promo/adjustmentTypes.js +13 -0
  90. package/dist/promo/index.d.ts +8 -0
  91. package/dist/promo/index.js +8 -0
  92. package/dist/promo/promoEvaluator.d.ts +25 -0
  93. package/dist/promo/promoEvaluator.js +135 -0
  94. package/dist/promo/types.d.ts +86 -0
  95. package/dist/promo/types.js +12 -0
  96. package/dist/risk/core/evaluator.d.ts +3 -0
  97. package/dist/risk/core/evaluator.js +32 -0
  98. package/dist/risk/core/rules.d.ts +3 -0
  99. package/dist/risk/core/rules.js +118 -0
  100. package/dist/risk/core/types.d.ts +65 -0
  101. package/dist/risk/core/types.js +1 -0
  102. package/dist/risk/index.d.ts +8 -0
  103. package/dist/risk/index.js +8 -0
  104. package/dist/risk/types.d.ts +32 -0
  105. package/dist/risk/types.js +43 -0
  106. package/dist/shipping/index.d.ts +4 -0
  107. package/dist/shipping/index.js +4 -0
  108. package/dist/shipping/shippingResolver.d.ts +26 -0
  109. package/dist/shipping/shippingResolver.js +88 -0
  110. package/dist/shipping/types.d.ts +45 -0
  111. package/dist/shipping/types.js +4 -0
  112. package/dist/subscription/cycleHardening.d.ts +72 -0
  113. package/dist/subscription/cycleHardening.js +95 -0
  114. package/dist/subscription/index.d.ts +14 -0
  115. package/dist/subscription/index.js +14 -0
  116. package/dist/subscription/subscriptionEngineCore.d.ts +13 -0
  117. package/dist/subscription/subscriptionEngineCore.js +145 -0
  118. package/dist/subscription/subscriptionEngineLifecycle.d.ts +52 -0
  119. package/dist/subscription/subscriptionEngineLifecycle.js +196 -0
  120. package/dist/subscription/subscriptionEnginePayment.d.ts +19 -0
  121. package/dist/subscription/subscriptionEnginePayment.js +127 -0
  122. package/dist/subscription/subscriptionEngineTypes.d.ts +94 -0
  123. package/dist/subscription/subscriptionEngineTypes.js +4 -0
  124. package/dist/subscription/subscriptionEngineUtils.d.ts +32 -0
  125. package/dist/subscription/subscriptionEngineUtils.js +74 -0
  126. package/dist/subscription/types.d.ts +58 -0
  127. package/dist/subscription/types.js +47 -0
  128. package/dist/testing.d.ts +48 -0
  129. package/dist/testing.js +105 -0
  130. package/package.json +215 -4
  131. package/release-gates.json +232 -0
  132. package/src/bundle/contracts.ts +15 -0
  133. package/src/bundle/ports.ts +32 -0
  134. package/src/catalog/identifiers.ts +50 -0
  135. package/src/catalog/index.ts +2 -0
  136. package/src/checkout/idempotency.ts +49 -0
  137. package/src/checkout/index.ts +2 -0
  138. package/src/company-identity/contracts.ts +209 -0
  139. package/src/company-identity/index.ts +27 -0
  140. package/src/company-identity/ports.ts +19 -0
  141. package/src/fulfillment/facts.ts +300 -0
  142. package/src/fulfillment/index.ts +34 -0
  143. package/src/inventory/atp.ts +249 -0
  144. package/src/inventory/index.ts +2 -0
  145. package/src/marketing/research/contracts.ts +91 -0
  146. package/src/marketing/research/index.ts +4 -0
  147. package/src/marketing/research/ports.ts +26 -0
  148. package/src/partners/index.ts +4 -0
  149. package/src/partners/ports.ts +18 -0
  150. package/src/partners/status.ts +49 -0
  151. package/src/payment/executionBaseContracts.ts +93 -0
  152. package/src/payment/index.ts +128 -0
  153. package/src/payment/methodLifecycle.ts +130 -0
  154. package/src/payment/paymentControlTypes.ts +197 -0
  155. package/src/payment/paymentFailureTaxonomy.ts +201 -0
  156. package/src/payment/paymentFailureTaxonomyContracts.ts +228 -0
  157. package/src/payment/paymentRecovery.ts +95 -0
  158. package/src/payment/paymentRecoveryContracts.ts +61 -0
  159. package/src/payment/paymentStateMachine.ts +263 -0
  160. package/src/payment/providerAttemptIdempotency.ts +57 -0
  161. package/src/payment/providerCapability.ts +172 -0
  162. package/src/platform-runtime/contracts.ts +33 -0
  163. package/src/platform-runtime/index.ts +36 -0
  164. package/src/platform-runtime/platformKernel.ts +86 -0
  165. package/src/platform-runtime/ports.ts +88 -0
  166. package/src/pricing/index.ts +8 -0
  167. package/src/pricing/ports.ts +27 -0
  168. package/src/pricing/pricingBreakdown.ts +243 -0
  169. package/src/pricing/targetPriceAllocation.ts +293 -0
  170. package/src/pricing/types.ts +36 -0
  171. package/src/promo/adjustmentEngine.ts +253 -0
  172. package/src/promo/adjustmentTypes.ts +94 -0
  173. package/src/promo/index.ts +8 -0
  174. package/src/promo/promoEvaluator.ts +137 -0
  175. package/src/promo/types.ts +97 -0
  176. package/src/risk/core/evaluator.ts +41 -0
  177. package/src/risk/core/rules.ts +128 -0
  178. package/src/risk/core/types.ts +73 -0
  179. package/src/risk/index.ts +8 -0
  180. package/src/risk/types.ts +60 -0
  181. package/src/shipping/index.ts +4 -0
  182. package/src/shipping/shippingResolver.ts +101 -0
  183. package/src/shipping/types.ts +49 -0
  184. package/src/subscription/cycleHardening.ts +141 -0
  185. package/src/subscription/index.ts +14 -0
  186. package/src/subscription/subscriptionEngineCore.ts +181 -0
  187. package/src/subscription/subscriptionEngineLifecycle.ts +282 -0
  188. package/src/subscription/subscriptionEnginePayment.ts +174 -0
  189. package/src/subscription/subscriptionEngineTypes.ts +112 -0
  190. package/src/subscription/subscriptionEngineUtils.ts +110 -0
  191. package/src/subscription/types.ts +104 -0
  192. package/src/testing.ts +169 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,184 @@
1
+ # Changelog
2
+
3
+ Notable changes to this public-source workspace package are recorded here.
4
+ “Unreleased” means no npm version carries the change yet; immutable OpenLup
5
+ source previews may already ship some changes, and their release notes say
6
+ which. Declaration snapshots track candidate drift, not a stable API or
7
+ SemVer promise.
8
+
9
+ ## Unreleased — checkout recovery contracts
10
+
11
+ - Add neutral checkout recovery evidence, method, operation and action contracts
12
+ to the existing payment surface. They describe guidance only and do not change
13
+ payment admission, renewal classification or enabled payment methods.
14
+
15
+ ## [Unreleased]
16
+
17
+ ### Changed
18
+
19
+ - Publishable on the npm `preview` dist-tag as `0.6.0`, for source preview
20
+ `openlup-source-preview/6`. Directory `npm publish` stays refused.
21
+
22
+ - **BREAKING for `slugSchema`'s accepted language.** The `./catalog` schema no
23
+ longer trims its input, so a slug with leading or trailing whitespace is now
24
+ rejected rather than normalised and accepted, which is what the published
25
+ `catalogSlugFormat` it tests against always described. A caller that relied on
26
+ that normalisation must trim before validating.
27
+ - **BREAKING for the retry ladder's semantics.** `nextRetryAttemptAt` now
28
+ TERMINATES past the end of the ladder instead of capping at its last slot: an
29
+ attempt beyond the configured backoff length answers `null`, which is the pause
30
+ signal, rather than repeating the final interval forever. The stored schedule
31
+ this kernel mirrors has always terminated, so the two rails now agree; the
32
+ previous capping behaviour meant a caller asking for attempt 4 (or 9) was told
33
+ a fourth charge was scheduled when none was. Callers that guarded with
34
+ `attempt <= maxRetryAttempts()` before calling should drop the guard — asking
35
+ for the next slot IS the decision, and a second copy of the budget check is how
36
+ the two rails drifted apart in the first place.
37
+
38
+ ### Added
39
+
40
+ - `recordPaymentFailure` accepts an optional neutral `failureClass` and passes it
41
+ to the canonical retry-ladder decision. Existing callers remain
42
+ source-compatible. The shipped terminating-class set is exactly
43
+ `["hard_do_not_retry"]`: that refusal gets no later rung, while every other
44
+ class keeps the existing 24h/72h/168h schedule.
45
+ - Class-aware retry termination on `./subscription`.
46
+ `CycleRetryCadence` gains an optional `terminatingFailureClasses`, the new
47
+ `ladderTerminatedByClass(failureClass, cadence?)` answers whether the REASON
48
+ for a refusal ends the ladder, and `nextRetryAttemptAt` / `shouldScheduleRetry`
49
+ take an optional trailing `failureClass`. `DEFAULT_CYCLE_RETRY_CADENCE` ships
50
+ only `hard_do_not_retry`. The predicate fails open for an absent or unlisted
51
+ class, for a listed class the taxonomy does not recognise, and for a listed
52
+ class that `failureClassDecision` still permits. Only explicit membership plus
53
+ the taxonomy's existing refusal can end the ladder early.
54
+ - Injectable retry cadence on `./subscription`: `CycleRetryCadence` and the
55
+ frozen `DEFAULT_CYCLE_RETRY_CADENCE` (24h/72h/168h). `nextRetryAttemptAt`,
56
+ `shouldScheduleRetry` and `maxRetryAttempts` each take an optional cadence and
57
+ default to the shipped one, so a deployment can publish its own ladder without
58
+ forking the kernel and nothing changes for a caller that passes none.
59
+
60
+ - Pack budgets raised (packed 98 KiB -> 106 KiB, unpacked 448 KiB -> 480 KiB;
61
+ file count unchanged at 186): the new allocation kernel ships as one source file
62
+ plus its two build artifacts, and its adopter-facing JSDoc — the floor-clamp
63
+ rule, the two-line split rationale and the failure-versus-throw split — is most
64
+ of the added bytes. The docs are the deliverable, so the budget moves rather
65
+ than the docs. Measured, not estimated: clean base packs 98532/446519/183 and
66
+ this change packs 106488/475826/186.
67
+ - Experimental bundle target-price allocation on `./pricing`:
68
+ `allocateBundleTargetPrice`, the pure kernel that turns ONE operator-set price
69
+ for a composed bundle into exact per-component money. Largest-remainder
70
+ (Hamilton) split weighted by each component's own reference subtotal, all in
71
+ BigInt, ties broken by component code so output never depends on input order.
72
+ Two rules bound it — a component never allocates below its minimum payable per
73
+ unit (and a component priced under that minimum is held to its own reference
74
+ price, because no floor may lift a component above what it is worth), and never
75
+ above its reference unit price. A quantity whose allocated subtotal does not
76
+ divide evenly emits TWO lines rather than a rounded unit price, so the
77
+ `unitPrice x quantity === lineSubtotal` identity every quote line refines still
78
+ holds. The single asserted invariant is that the emitted lines sum to the target
79
+ exactly. Three refusals stay data rather than exceptions: nothing to weigh
80
+ against, a target above the sum of the parts, and a target that cannot cover
81
+ every minimum payable. No clock, no randomness, no I/O.
82
+ - Line-scoped `bundle` component in the pricing breakdown vocabulary, with an
83
+ optional `bundle_allocated_discount_minor` on the line input: positive on the
84
+ way in, emitted as one negative component, absent or zero emits nothing. It is
85
+ line-scoped rather than order-scoped because a bundle prices a subset of the
86
+ cart, and refunding one line must return exactly what that line was charged.
87
+ - Pack budgets raised (packed 90 KiB -> 94 KiB, unpacked 416 KiB -> 432 KiB,
88
+ files 180 -> 186): one new kernel module ships as a source file plus its build
89
+ artifacts and their maps, and its adopter-facing JSDoc is most of the added
90
+ bytes. The docs are the deliverable, so the budget moves rather than the docs.
91
+ - Experimental payment-method lifecycle vocabulary on `./payment`: the five
92
+ transitions a rail may report about a method it holds on file
93
+ (`method_registered`, `method_updated`, `method_revoked`, `method_expired`,
94
+ `method_suspended`), the neutral event an adapter translates its own event
95
+ names into, and the three published facts (`schemeLabel`, `lastDigits`,
96
+ `expiresAt`) a transition may carry — never the instrument number. Plus two
97
+ pure helpers: `endsStoredMethodUsability`, the single place that answers
98
+ whether a transition means the method can no longer back a charge (a rotation
99
+ is not a death), and `expiryInstantFromMonthYear`, which pins the convention
100
+ that a month-and-year validity runs to the LAST instant of that month in UTC.
101
+ No rail is named and no clock, network or storage is read.
102
+ - Pack budgets raised (packed 88 KiB -> 90 KiB, unpacked 400 KiB -> 416 KiB): the provider-capability contracts
103
+ add ~0.9 KiB of shipped declarations and their adopter-facing JSDoc; the
104
+ docs are the deliverable, so the budget moves rather than the docs.
105
+ - (formatting) the block-reason alias is declared single-line so the
106
+ generated declaration snapshot carries no trailing whitespace.
107
+ - Experimental payment-provider capability contracts on `./payment`: a
108
+ descriptor an adapter publishes so renewal and dunning can decide from
109
+ CAPABILITIES — whether stored consent evidence must be read and whether it
110
+ is chargeable unattended, which provider flow an unattended charge uses,
111
+ what payer context the request needs, and what a stored method must satisfy
112
+ before a charge — plus a registry contract keyed by provider kind. Types
113
+ only, with no provider named and no runtime consumer yet; branching on
114
+ provider identity is unchanged.
115
+ - Experimental payment-failure taxonomy on `./payment`: a pure classifier that
116
+ resolves a refusal into one of seven neutral classes from optional evidence
117
+ (scheme retry advice, adopter-asserted neutral hints, an opaque decline code
118
+ read through an adopter-supplied hint table, and the internal reason key),
119
+ with a documented precedence order, a frozen per-class retry decision record,
120
+ and a scheme retry ceiling helper pinned at 15 attempts per 30 days. The
121
+ kernel embeds no acquirer code tables and has no runtime consumer yet; retry
122
+ scheduling is unchanged.
123
+ - Experimental provider-neutral payment-decline evidence on `./payment`, with
124
+ a provider code (never free-form prose) and retryability hint that lets
125
+ adopters classify synchronous PSP refusals without persisting customer data.
126
+ Extended with optional `declineCode` and `adviceCode`, so a refusal keeps the
127
+ finer bank reason and the provider's retry recommendation — both codes, never
128
+ messages — for a later classification policy to read. Extended again with
129
+ optional `neutralReasonHints`, so an adapter can carry its OWN reading of a
130
+ refusal — already translated out of its code vocabulary — and a classifier
131
+ never has to learn which adapter refused.
132
+ - `PAYMENT_FAILURE_CLASSIFICATION_SOURCES` on `./payment`: the classification
133
+ sources published as a value as well as a type, so a boundary schema can
134
+ validate `decidedBy` against the kernel's own vocabulary instead of restating
135
+ it. The type is unchanged and still derives from the same four members.
136
+ - Additive `evaluatePromotionAdjustmentsV2` API in the existing candidate
137
+ `./promo` subpath. It chooses one best product and shipping adjustment,
138
+ interprets product percentages as target-effective basis points against a
139
+ trusted reference subtotal, and requires an adopter-defined product floor.
140
+ The legacy evaluator and DB-shaped types remain unchanged for compatibility;
141
+ downstream applications can adopt the package boundary before any separately
142
+ flagged runtime cutover.
143
+ - Experimental `./fulfillment` normalized-fact contract with explicit schema,
144
+ strict N/N-1 parsing, adopter-supplied canonical-status validation,
145
+ discriminated provenance, application-minted evidence references, comparable
146
+ provider ordinals, deterministic fingerprint/dedupe, and self-contained
147
+ transition-conflict diagnostics with strict stream/decision validation.
148
+ - The then-current package identity and extracted-root governance evidence;
149
+ this is historical evidence, not authorization for a separate repository or
150
+ release channel.
151
+ - Package-local documentation and governance material for the portability
152
+ boundary.
153
+ - Candidate and experimental maturity metadata for the package surface.
154
+
155
+ ### Changed
156
+
157
+ - Marked candidate/experimental declarations `@beta` and testing-only
158
+ declarations `@internal`, without changing package exports or runtime shapes.
159
+ Removed the private `./testing` neutrality matcher after moving all packaged
160
+ leak classes into the packed-artifact audit.
161
+ - Reclassified all declaration snapshots as private package-surface drift proof;
162
+ this changes no exports, runtime behavior, dependencies, or publish refusal.
163
+ - Raised the reviewed packed/unpacked artifact ceilings by 4/16 KiB to admit
164
+ the additive promo v2 declarations and implementation.
165
+ - Replaced public-surface and freeze language with the private package-surface
166
+ inventory: 16 current exports have package smoke evidence but no public
167
+ stability claim.
168
+
169
+ ### Removed
170
+
171
+ - Removed the unused `./external-effects` API, implementation, snapshot, and
172
+ self-conformance fixture before any public release. The application
173
+ one-writer cleanup left no runtime consumer, so external-effect retry
174
+ semantics stay adopter-owned instead of becoming a fourth core concern.
175
+
176
+ ### Security
177
+
178
+ - Recorded the private vulnerability-reporting contact for this proof package.
179
+
180
+ ## Release Status
181
+
182
+ No npm version has been released yet. A `preview` version establishes no
183
+ stable package API or supported upgrade channel. Add a dated section only
184
+ after a version is published.
@@ -0,0 +1,39 @@
1
+ # Code of Conduct
2
+
3
+ ## Our Standard
4
+
5
+ We want participation in this project to be respectful, specific, and
6
+ constructive. Examples of welcome behavior include:
7
+
8
+ - discussing ideas and evidence rather than attacking people,
9
+ - giving actionable feedback and accepting correction with grace,
10
+ - respecting different backgrounds, identities, experiences, and skill levels,
11
+ - protecting private information and allowing others to set personal
12
+ boundaries,
13
+ - taking responsibility for mistakes and repairing harm where possible.
14
+
15
+ Harassment, threats, discriminatory language, sexualized attention, sustained
16
+ disruption, personal attacks, doxxing, and publication of another person's
17
+ private information are not acceptable.
18
+
19
+ ## Scope
20
+
21
+ This standard applies in repository issues, pull requests, reviews,
22
+ discussions, and project-run community spaces. It also applies when someone is
23
+ representing the project in public.
24
+
25
+ ## Enforcement
26
+
27
+ Maintainers may edit or remove content, close or lock threads, reject
28
+ contributions, or temporarily or permanently restrict participation when needed
29
+ to protect the community. Enforcement decisions should consider context,
30
+ severity, prior behavior, impact, and the safety of affected people.
31
+
32
+ ## Reporting
33
+
34
+ The repository-root `CODE_OF_CONDUCT.md` owns conduct reporting and enforcement.
35
+ The repository-root `SECURITY.md` owns vulnerability reporting. This packaged
36
+ copy defines no separate moderator, inbox, or fallback reporting route.
37
+
38
+ Do not put private, sensitive, or identifying incident details in a public
39
+ issue. Follow the currently authorized repository-root policies.
@@ -0,0 +1,34 @@
1
+ # Contributing
2
+
3
+ Commerce Core is public source for framework-independent commerce kernels.
4
+ Its npm versions ride on the source previews (`preview` dist-tag only) and
5
+ activate no separate package product or stable API.
6
+
7
+ ## Set up and verify
8
+
9
+ In this package directory, use the Node and npm versions from `package.json`:
10
+
11
+ ```sh
12
+ npm ci
13
+ npm run ci
14
+ ```
15
+
16
+ The gate builds every export, runs standalone tests and isolated package smoke,
17
+ verifies declaration snapshots, and checks license, SBOM, audit, pack, and
18
+ publish controls. Neither the root test script nor root CI runs it.
19
+
20
+ ## Scope
21
+
22
+ Keep deterministic rules and provider-neutral contracts here. UI, HTTP routes,
23
+ database orchestration, schedulers, credentials, provider SDKs, and
24
+ product-specific policy remain outside the package.
25
+
26
+ Treat exported declarations as internal candidate surfaces. When a declaration
27
+ change is intentional, update tests, record the reason in [CHANGELOG.md](CHANGELOG.md),
28
+ run `npm run api:update`, and review the snapshot diff. Do not infer a stable
29
+ API, SemVer promise, independent release, or external adoption from that proof.
30
+
31
+ ## Security
32
+
33
+ Never include credentials, customer data, private repository links, or deployment
34
+ evidence. For vulnerabilities follow [SECURITY.md](SECURITY.md).
package/LICENSE ADDED
@@ -0,0 +1,204 @@
1
+ Copyright (c) 2026 Bartlomiej Roszkowski
2
+
3
+
4
+ Apache License
5
+ Version 2.0, January 2004
6
+ http://www.apache.org/licenses/
7
+
8
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
9
+
10
+ 1. Definitions.
11
+
12
+ "License" shall mean the terms and conditions for use, reproduction,
13
+ and distribution as defined by Sections 1 through 9 of this document.
14
+
15
+ "Licensor" shall mean the copyright owner or entity authorized by
16
+ the copyright owner that is granting the License.
17
+
18
+ "Legal Entity" shall mean the union of the acting entity and all
19
+ other entities that control, are controlled by, or are under common
20
+ control with that entity. For the purposes of this definition,
21
+ "control" means (i) the power, direct or indirect, to cause the
22
+ direction or management of such entity, whether by contract or
23
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
24
+ outstanding shares, or (iii) beneficial ownership of such entity.
25
+
26
+ "You" (or "Your") shall mean an individual or Legal Entity
27
+ exercising permissions granted by this License.
28
+
29
+ "Source" form shall mean the preferred form for making modifications,
30
+ including but not limited to software source code, documentation
31
+ source, and configuration files.
32
+
33
+ "Object" form shall mean any form resulting from mechanical
34
+ transformation or translation of a Source form, including but
35
+ not limited to compiled object code, generated documentation,
36
+ and conversions to other media types.
37
+
38
+ "Work" shall mean the work of authorship, whether in Source or
39
+ Object form, made available under the License, as indicated by a
40
+ copyright notice that is included in or attached to the work
41
+ (an example is provided in the Appendix below).
42
+
43
+ "Derivative Works" shall mean any work, whether in Source or Object
44
+ form, that is based on (or derived from) the Work and for which the
45
+ editorial revisions, annotations, elaborations, or other modifications
46
+ represent, as a whole, an original work of authorship. For the purposes
47
+ of this License, Derivative Works shall not include works that remain
48
+ separable from, or merely link (or bind by name) to the interfaces of,
49
+ the Work and Derivative Works thereof.
50
+
51
+ "Contribution" shall mean any work of authorship, including
52
+ the original version of the Work and any modifications or additions
53
+ to that Work or Derivative Works thereof, that is intentionally
54
+ submitted to Licensor for inclusion in the Work by the copyright owner
55
+ or by an individual or Legal Entity authorized to submit on behalf of
56
+ the copyright owner. For the purposes of this definition, "submitted"
57
+ means any form of electronic, verbal, or written communication sent
58
+ to the Licensor or its representatives, including but not limited to
59
+ communication on electronic mailing lists, source code control systems,
60
+ and issue tracking systems that are managed by, or on behalf of, the
61
+ Licensor for the purpose of discussing and improving the Work, but
62
+ excluding communication that is conspicuously marked or otherwise
63
+ designated in writing by the copyright owner as "Not a Contribution."
64
+
65
+ "Contributor" shall mean Licensor and any individual or Legal Entity
66
+ on behalf of whom a Contribution has been received by Licensor and
67
+ subsequently incorporated within the Work.
68
+
69
+ 2. Grant of Copyright License. Subject to the terms and conditions of
70
+ this License, each Contributor hereby grants to You a perpetual,
71
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
72
+ copyright license to reproduce, prepare Derivative Works of,
73
+ publicly display, publicly perform, sublicense, and distribute the
74
+ Work and such Derivative Works in Source or Object form.
75
+
76
+ 3. Grant of Patent License. Subject to the terms and conditions of
77
+ this License, each Contributor hereby grants to You a perpetual,
78
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
79
+ (except as stated in this section) patent license to make, have made,
80
+ use, offer to sell, sell, import, and otherwise transfer the Work,
81
+ where such license applies only to those patent claims licensable
82
+ by such Contributor that are necessarily infringed by their
83
+ Contribution(s) alone or by combination of their Contribution(s)
84
+ with the Work to which such Contribution(s) was submitted. If You
85
+ institute patent litigation against any entity (including a
86
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
87
+ or a Contribution incorporated within the Work constitutes direct
88
+ or contributory patent infringement, then any patent licenses
89
+ granted to You under this License for that Work shall terminate
90
+ as of the date such litigation is filed.
91
+
92
+ 4. Redistribution. You may reproduce and distribute copies of the
93
+ Work or Derivative Works thereof in any medium, with or without
94
+ modifications, and in Source or Object form, provided that You
95
+ meet the following conditions:
96
+
97
+ (a) You must give any other recipients of the Work or
98
+ Derivative Works a copy of this License; and
99
+
100
+ (b) You must cause any modified files to carry prominent notices
101
+ stating that You changed the files; and
102
+
103
+ (c) You must retain, in the Source form of any Derivative Works
104
+ that You distribute, all copyright, patent, trademark, and
105
+ attribution notices from the Source form of the Work,
106
+ excluding those notices that do not pertain to any part of
107
+ the Derivative Works; and
108
+
109
+ (d) If the Work includes a "NOTICE" text file as part of its
110
+ distribution, then any Derivative Works that You distribute must
111
+ include a readable copy of the attribution notices contained
112
+ within such NOTICE file, excluding those notices that do not
113
+ pertain to any part of the Derivative Works, in at least one
114
+ of the following places: within a NOTICE text file distributed
115
+ as part of the Derivative Works; within the Source form or
116
+ documentation, if provided along with the Derivative Works; or,
117
+ within a display generated by the Derivative Works, if and
118
+ wherever such third-party notices normally appear. The contents
119
+ of the NOTICE file are for informational purposes only and
120
+ do not modify the License. You may add Your own attribution
121
+ notices within Derivative Works that You distribute, alongside
122
+ or as an addendum to the NOTICE text from the Work, provided
123
+ that such additional attribution notices cannot be construed
124
+ as modifying the License.
125
+
126
+ You may add Your own copyright statement to Your modifications and
127
+ may provide additional or different license terms and conditions
128
+ for use, reproduction, or distribution of Your modifications, or
129
+ for any such Derivative Works as a whole, provided Your use,
130
+ reproduction, and distribution of the Work otherwise complies with
131
+ the conditions stated in this License.
132
+
133
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
134
+ any Contribution intentionally submitted for inclusion in the Work
135
+ by You to the Licensor shall be under the terms and conditions of
136
+ this License, without any additional terms or conditions.
137
+ Notwithstanding the above, nothing herein shall supersede or modify
138
+ the terms of any separate license agreement you may have executed
139
+ with Licensor regarding such Contributions.
140
+
141
+ 6. Trademarks. This License does not grant permission to use the trade
142
+ names, trademarks, service marks, or product names of the Licensor,
143
+ except as required for reasonable and customary use in describing the
144
+ origin of the Work and reproducing the content of the NOTICE file.
145
+
146
+ 7. Disclaimer of Warranty. Unless required by applicable law or
147
+ agreed to in writing, Licensor provides the Work (and each
148
+ Contributor provides its Contributions) on an "AS IS" BASIS,
149
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
150
+ implied, including, without limitation, any warranties or conditions
151
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
152
+ PARTICULAR PURPOSE. You are solely responsible for determining the
153
+ appropriateness of using or redistributing the Work and assume any
154
+ risks associated with Your exercise of permissions under this License.
155
+
156
+ 8. Limitation of Liability. In no event and under no legal theory,
157
+ whether in tort (including negligence), contract, or otherwise,
158
+ unless required by applicable law (such as deliberate and grossly
159
+ negligent acts) or agreed to in writing, shall any Contributor be
160
+ liable to You for damages, including any direct, indirect, special,
161
+ incidental, or consequential damages of any character arising as a
162
+ result of this License or out of the use or inability to use the
163
+ Work (including but not limited to damages for loss of goodwill,
164
+ work stoppage, computer failure or malfunction, or any and all
165
+ other commercial damages or losses), even if such Contributor
166
+ has been advised of the possibility of such damages.
167
+
168
+ 9. Accepting Warranty or Additional Liability. While redistributing
169
+ the Work or Derivative Works thereof, You may choose to offer,
170
+ and charge a fee for, acceptance of support, warranty, indemnity,
171
+ or other liability obligations and/or rights consistent with this
172
+ License. However, in accepting such obligations, You may act only
173
+ on Your own behalf and on Your sole responsibility, not on behalf
174
+ of any other Contributor, and only if You agree to indemnify,
175
+ defend, and hold each Contributor harmless for any liability
176
+ incurred by, or claims asserted against, such Contributor by reason
177
+ of your accepting any such warranty or additional liability.
178
+
179
+ END OF TERMS AND CONDITIONS
180
+
181
+ APPENDIX: How to apply the Apache License to your work.
182
+
183
+ To apply the Apache License to your work, attach the following
184
+ boilerplate notice, with the fields enclosed by brackets "[]"
185
+ replaced with your own identifying information. (Don't include
186
+ the brackets!) The text should be enclosed in the appropriate
187
+ comment syntax for the file format. We also recommend that a
188
+ file or class name and description of purpose be included on the
189
+ same "printed page" as the copyright notice for easier
190
+ identification within third-party archives.
191
+
192
+ Copyright [yyyy] [name of copyright owner]
193
+
194
+ Licensed under the Apache License, Version 2.0 (the "License");
195
+ you may not use this file except in compliance with the License.
196
+ You may obtain a copy of the License at
197
+
198
+ http://www.apache.org/licenses/LICENSE-2.0
199
+
200
+ Unless required by applicable law or agreed to in writing, software
201
+ distributed under the License is distributed on an "AS IS" BASIS,
202
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
203
+ See the License for the specific language governing permissions and
204
+ limitations under the License.
package/MAINTAINERS.md ADDED
@@ -0,0 +1,33 @@
1
+ # Maintainers
2
+
3
+ `@openlup/core` is maintained in the phase-5 platform monorepo. It is not an
4
+ independent product; its versions ride on the source previews.
5
+
6
+ ## Responsibilities
7
+
8
+ - preserve the `preview` publication settings and the directory-publish
9
+ refusal;
10
+ - keep package smoke, license, SBOM, audit, pack, import, and gitleaks proofs
11
+ green;
12
+ - keep provider and product-specific behavior outside this package;
13
+ - review declaration-snapshot drift as an internal candidate contract change,
14
+ without implying public stability or SemVer;
15
+ - use the smallest change that preserves the existing export graph and package
16
+ portability proof.
17
+
18
+ ## Local package gate
19
+
20
+ ```sh
21
+ npm ci
22
+ npm run ci
23
+ ```
24
+
25
+ `npm run ci` builds every export, runs tests and coverage, validates declaration
26
+ snapshots and documentation, checks licenses/SBOM/audit/pack/publish settings,
27
+ and exercises a packed first-party consumer. That consumer is package smoke,
28
+ not external-consumer evidence.
29
+
30
+ ## Security
31
+
32
+ Do not put credentials, customer data, private deployment evidence, or product
33
+ policy into this package. Report vulnerabilities through [SECURITY.md](SECURITY.md).
package/README.md CHANGED
@@ -1,5 +1,66 @@
1
- # @openlup/core
1
+ # Commerce Core
2
2
 
3
- This version reserves the package name and contains no code. It is deprecated on publication.
3
+ `@openlup/core` is a framework-independent TypeScript workspace package of
4
+ subscription and bundle commerce kernels, not a separate library product.
4
5
 
5
- Real versions of `@openlup/core` are staged by the OpenLup release workflow from a published source preview (`openlup-source-preview/<n>` → `0.<n>.0`) and approved by the maintainer. See https://github.com/openlup/openlup/blob/main/.github/VERSIONING_AND_EOL.md.
6
+ > [!IMPORTANT]
7
+ > Version `0.<n>.0` is packed from source preview `openlup-source-preview/<n>`,
8
+ > staged with provenance and approved with 2FA, on the `preview` dist-tag only.
9
+ > `npm publish` from this directory is refused. No version implies a stable
10
+ > API or supported consumer path. Build, pack, and isolated-import checks are
11
+ > package smoke evidence only.
12
+
13
+ ## Package Surface Maturity
14
+
15
+ Every current export is an internal candidate, experimental kernel, or testing
16
+ surface. Its declaration snapshot is a reviewable drift proof, not a public API
17
+ promise.
18
+
19
+ | Export | Role | Maturity | Package smoke |
20
+ | --- | --- | --- | --- |
21
+ | `./bundle` | kernel | candidate | `smoke/subscriptionBundleStandalone.test.ts` |
22
+ | `./catalog` | kernel | candidate | `smoke/catalogStandalone.test.ts` |
23
+ | `./checkout` | kernel | experimental | `smoke/checkoutStandalone.test.ts` |
24
+ | `./company-identity` | kernel | experimental | `smoke/companyIdentityStandalone.test.ts` |
25
+ | `./fulfillment` | kernel | experimental | `smoke/fulfillmentStandalone.test.ts` |
26
+ | `./inventory` | kernel | candidate | `smoke/inventoryStandalone.test.ts` |
27
+ | `./marketing/research` | kernel | experimental | `smoke/marketingResearchStandalone.test.ts` |
28
+ | `./partners` | kernel | experimental | `smoke/partnersStandalone.test.ts` |
29
+ | `./payment` | kernel | experimental | `smoke/paymentStandalone.test.ts` |
30
+ | `./platform-runtime` | kernel | experimental | `smoke/platformRuntimeStandalone.test.ts` |
31
+ | `./pricing` | kernel | candidate | `smoke/pricingStandalone.test.ts` |
32
+ | `./promo` | kernel | candidate | `smoke/promoStandalone.test.ts` |
33
+ | `./risk` | kernel | candidate | `smoke/riskStandalone.test.ts` |
34
+ | `./shipping` | kernel | candidate | `smoke/shippingStandalone.test.ts` |
35
+ | `./subscription` | kernel | candidate | `smoke/subscriptionBundleStandalone.test.ts` |
36
+ | `./testing` | testing | testing | `smoke/testingStandalone.test.ts` |
37
+
38
+ `release-gates.json` records four distinct evidence classes:
39
+
40
+ - `packageSmokeEvidence`: required hermetic build/import/pack/publish-refusal
41
+ proof for this package;
42
+ - `conformanceEvidence`: required only when a declared port/adapter seam needs
43
+ a framework-free suite;
44
+ - `dogfoodEvidence`: first-party integration seams, not independent adoption;
45
+ - `externalConsumerEvidence`: not yet evaluated; a first-party packed consumer
46
+ remains package smoke, not external adoption.
47
+
48
+ ## Local verification
49
+
50
+ From this package directory:
51
+
52
+ ```sh
53
+ npm ci
54
+ npm run ci
55
+ ```
56
+
57
+ Focused proofs are `npm run api:check`, `npm run release:check`, and
58
+ `npm run test:consumer`. The root test script skips this suite. A `preview`
59
+ install is evaluation, not a supported install.
60
+
61
+ ## Kernel Documentation
62
+
63
+ - [`docs/SUBSCRIPTION_ENGINE.md`](docs/SUBSCRIPTION_ENGINE.md) — what the
64
+ `./subscription` kernel owns, its deterministic-clock contract, the
65
+ late-payment cycle-shift rule and its monotonic clamp, and how a host
66
+ application consumes it.
package/SECURITY.md ADDED
@@ -0,0 +1,29 @@
1
+ # Security Policy
2
+
3
+ ## Release Support
4
+
5
+ No package version is supported. A `0.<n>.0` version on the `preview`
6
+ dist-tag is development-preview evaluation, not a supported public release. A
7
+ future support policy belongs to phase-5 public platform governance, not to a
8
+ separate package release channel.
9
+
10
+ ## Vulnerability Reporting
11
+
12
+ Use GitHub Private Vulnerability Reporting for the repository named by this
13
+ package's source metadata. It is the primary route for suspected vulnerabilities.
14
+ If that private route is unavailable, use the fallback named by the canonical
15
+ [repository security policy](https://github.com/openlup/openlup/security/policy).
16
+ Never use a public issue, pull request, or discussion for a vulnerability report.
17
+ Packages do not define separate reporting routes.
18
+
19
+ ## Safe Handling
20
+
21
+ Never include credentials, access tokens, private keys, personal data, or live
22
+ service payloads in an issue, pull request, test fixture, or reproduction.
23
+ Sanitize logs and use synthetic identifiers. If a secret is exposed, revoke or
24
+ rotate it at the system that issued it before sharing any follow-up evidence.
25
+
26
+ Security changes should include the smallest non-sensitive regression test that
27
+ demonstrates the repaired boundary. Public disclosure belongs after affected
28
+ users can obtain a fix and must follow the reporting policy established before
29
+ launch.
@@ -0,0 +1,9 @@
1
+ import type { BundleLineRef, CompositionConstraint } from "./ports.js";
2
+ /** @beta */
3
+ export type { BundleLineRef, CompositionConstraint, CompositionRulesPort, } from "./ports.js";
4
+ /** @beta */
5
+ export interface Bundle {
6
+ coreLines: BundleLineRef[];
7
+ addonLines: BundleLineRef[];
8
+ constraint: CompositionConstraint;
9
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,41 @@
1
+ /** Opaque, adopter-defined sizing anchor with a minimal discriminator. */
2
+ /** @beta */
3
+ export interface CompositionConstraint {
4
+ /** Adapter-owned constraint family, for example "fixed.catalog". */
5
+ kind: string;
6
+ /** Adapter-owned schema version for data. */
7
+ version: number;
8
+ /** Adapter-owned payload; core passes it through without inspecting it. */
9
+ data: Record<string, unknown>;
10
+ }
11
+ /** @beta */
12
+ export interface BundleLineRef {
13
+ variantId: string;
14
+ qty: number;
15
+ isAddon: boolean;
16
+ }
17
+ /** @beta */
18
+ export interface CompositionRulesPort {
19
+ validateComposition(input: {
20
+ coreLines: BundleLineRef[];
21
+ addonLines: BundleLineRef[];
22
+ constraint: CompositionConstraint;
23
+ }): Promise<{
24
+ ok: true;
25
+ } | {
26
+ ok: false;
27
+ code: string;
28
+ details?: Record<string, unknown>;
29
+ }>;
30
+ resizeComposition(input: {
31
+ coreLines: BundleLineRef[];
32
+ constraint: CompositionConstraint;
33
+ lever: {
34
+ kind: string;
35
+ value: unknown;
36
+ };
37
+ }): Promise<{
38
+ coreLines: BundleLineRef[];
39
+ constraint: CompositionConstraint;
40
+ } | null>;
41
+ }
@@ -0,0 +1 @@
1
+ export {};