Every seam, a folder.
The kits stay narrow by pushing integrations to the edges: payment providers and tax engines into billing-kit-adapters, enterprise identity and RBAC engines into tenant-kit-adapters. Statuses below are honest to the repos today. A tile is never a roadmap.
Payments in
BillingProvider: settlement, capture, refunds, webhooks. billing-kit branches on capabilities, never a provider name, including whether the provider already retries a failed payment, which is what stops our dunning charging the same card twice.
Settlement, capture, refunds, verified webhooks. Ships in billing-kit.
Merchant-of-record settlement; the provider’s number is authoritative.
Invoices but does not capture: settled means invoiced, and no cash posts until a PSP says so.
Merchant of record, checkout-driven: a subscription first appears on a webhook, never on a call.
The BillingProvider contract and conformance testkit are waiting.
Same contract; the template typechecks before you write a line.
Same contract, same testkit, same review checklist.
cp -r adapters/_template. Idempotency is the rule the review checks first.
Tax in
TaxCalculator: quoted against a draft, before finalize freezes the lines and takes a gap-free number. billing-kit ships no rate table and never will: the vendor owns the rates, and we record the amount rather than recomputing it.
Rates you write, matched on the customer’s address. A rate above 1 is refused at construction, because 20 is not 20%.
One async method, and a conformance suite that checks the answer before an invoice sees it.
Same seam. Quote against the draft; commit the document once it has a number.
SaaS-shaped nexus and filing. The rate table stays theirs. That is the point of the seam.
Return money, not a formula: we record what you answered and never recompute it from a rate.
Identity in
SsoResolver. A verified assertion becomes a membership-checked ResolvedTenant. Adapters never verify credentials.
Per-tenant connections, group→role mapping, JIT provisioning.
Shared-issuer multi-tenant routing via the tid claim predicate.
Any OIDC issuer routes by exact match. Lookalikes have a test.
Verified ID-token claims in; ResolvedTenant out.
The family’s own issuer: first-party tokens for fromClaim.
A verified assertion maps to VerifiedIdentity; no separate adapter needed.
Provisioning in
ScimDirectory. The enterprise directory pushes membership; offboarding offboards, last_owner answers 409.
Lookup-then-create, replay convergence, deactivate-as-offboard.
The SCIM 2.0 Users subset the major IdPs actually drive.
Any SCIM 2.0 client speaks to the same framework-neutral handler.
Roles out
RoleBridge over a TupleStore: memberships mirrored as convergent desired-state sync; unexplained grants die on the next pass.
One direct tuple per membership; inheritance lives in the model.
Same 3-method store contract; convergent desired-state sync.
Anything storing subject–relation–object triples fits the seam.