tenseleyflow/shithub / bb04500

Browse files

Document paid org billing contract

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
bb045009daad2d3975be17d1aa3ba25259bf07de
Parents
582d0a5
Tree
ab604a3

3 changed files

StatusFile+-
A docs/internal/billing.md 157 0
M docs/internal/index.md 2 0
M docs/internal/orgs.md 12 0
docs/internal/billing.mdadded
@@ -0,0 +1,157 @@
1
+# Billing and paid organizations
2
+
3
+shithub's first paid surface is organization billing. The code does not
4
+ship billing yet; this document records the product and engineering
5
+contract that the PAYMENTS sprint series implements.
6
+
7
+The current implementation already has the important shape for paid
8
+organizations: `orgs.plan` is an enum with `free`, `team`, and
9
+`enterprise`; organizations own repositories; organization members and
10
+teams exist; branch protection and PR review gates exist; Actions has
11
+schema for org/repo secrets, variables, and artifacts. Billing must
12
+turn that substrate into a fair hosted service without taxing
13
+public/open-source collaboration.
14
+
15
+## Product contract
16
+
17
+As of 2026-05-12, GitHub's public pricing page presents Free at
18
+`$0`, Team at `$4/user/month`, and Enterprise starting at
19
+`$21/user/month`. shithub follows the same mental model but removes
20
+Copilot/AI promises from the paid-org offering.
21
+
22
+Initial decisions:
23
+
24
+- Free organizations remain self-serve.
25
+- Team is `$4` per active organization member per month.
26
+- Active organization members, including owners, count as paid seats.
27
+- Team has no launch trial.
28
+- Enterprise is a visible contact-sales stub, not self-serve.
29
+- Stripe Billing is the first payment processor.
30
+- PayPal, manual invoices, SAML, SCIM, LDAP, enterprise account
31
+  hierarchy, and contracts are deferred.
32
+
33
+The fairness rule is explicit: public/open-source collaboration should
34
+stay generous. Paid gates focus on private collaboration, hosted cost,
35
+advanced organization controls, and support expectations.
36
+
37
+## Entitlement matrix
38
+
39
+| Capability | Free | Team | Enterprise stub |
40
+| --- | --- | --- | --- |
41
+| Public org repositories | Included | Included | Contact sales |
42
+| Basic private org repositories | Included | Included | Contact sales |
43
+| Org members and invitations | Included | Billed by active member | Contact sales |
44
+| Visible teams | Included | Included | Contact sales |
45
+| Secret teams | Upgrade | Included | Contact sales |
46
+| Basic branch protection | Included | Included | Contact sales |
47
+| Advanced private-repo branch protection | Upgrade | Included | Contact sales |
48
+| Required reviewers on private org repos | Upgrade | Included | Contact sales |
49
+| CODEOWNERS review | Deferred | Deferred | Deferred |
50
+| Org-level Actions secrets | Upgrade | Included | Contact sales |
51
+| Org-level Actions variables | Upgrade | Included | Contact sales |
52
+| Actions minutes | Low quota once metered | Higher quota once metered | Contact sales |
53
+| Actions artifacts/storage | Low quota once metered | Higher quota once metered | Contact sales |
54
+| Packages storage | Deferred until Packages is active | Deferred until Packages is active | Deferred |
55
+| Pages/Wikis/Projects | Do not promise until shipped | Do not promise until shipped | Deferred |
56
+| Audit log export | Deferred | Deferred | Later Enterprise feature |
57
+| SAML/SCIM/managed users | Deferred | Deferred | Later Enterprise feature |
58
+| Data residency/compliance | Deferred | Deferred | Later Enterprise feature |
59
+| Billing support | Basic instance support | Billing support after runbook exists | Contact sales |
60
+
61
+## Current capability audit
62
+
63
+Already present and safe to gate:
64
+
65
+- Organizations with `plan` and `billing_email`.
66
+- Organization members, owner role, and invitations.
67
+- Teams, including `privacy='secret'`.
68
+- Branch protection rules and required review counts.
69
+- PR review and reviewer-request substrate.
70
+- Org/repo Actions secrets and variables schema.
71
+
72
+Present but missing enforcement or metering:
73
+
74
+- Storage quota type exists, but quota persistence and enforcement are
75
+  incomplete.
76
+- Actions minutes, artifacts, and object usage need accounting before
77
+  paid limits can be promised.
78
+- Packages storage cannot be sold until the Packages sprint is active
79
+  and quota enforcement exists.
80
+
81
+Deferred:
82
+
83
+- SAML, SCIM, LDAP, enterprise account hierarchy, audit-log export, data
84
+  residency, compliance promises, and custom support SLAs.
85
+- Copilot/AI features are intentionally outside shithub's paid-org
86
+  product.
87
+
88
+## Billing architecture
89
+
90
+Stripe is the payment source of truth. shithub is the entitlement source
91
+of truth.
92
+
93
+The billing implementation should add a local billing domain that stores
94
+only Stripe IDs and payment summaries, never card data. Webhooks update
95
+local subscription state after signature verification. Policy and
96
+request handlers read local billing/entitlement state and must not call
97
+Stripe in hot paths.
98
+
99
+Required local concepts:
100
+
101
+- Stripe customer per billable organization.
102
+- Subscription state per organization.
103
+- Subscription item ID for seat quantity sync.
104
+- Immutable webhook receipts with unique provider event IDs.
105
+- Invoice/payment summaries for UI.
106
+- Seat snapshots for auditability.
107
+- Billing grace/lock state derived from processed subscription events.
108
+
109
+## Entitlement architecture
110
+
111
+Paid feature checks must live behind a central entitlement package, not
112
+as scattered `orgs.plan` checks in handlers.
113
+
114
+Expected feature keys:
115
+
116
+- `org.secret_teams`
117
+- `org.advanced_branch_protection`
118
+- `org.required_reviewers`
119
+- `org.actions_org_secrets`
120
+- `org.actions_org_variables`
121
+- `org.private_collaboration_limit`
122
+- `org.storage_quota`
123
+- `org.actions_minutes_quota`
124
+
125
+Authorization and entitlement are separate gates. A user must have both
126
+the policy permission and the paid entitlement for gated writes. Denials
127
+must preserve existing `policy.Maybe404` behavior where existence leaks
128
+matter.
129
+
130
+## Downgrade behavior
131
+
132
+Downgrades must preserve customer data. Moving from Team to Free should
133
+not delete teams, secrets, variables, branch rules, or review settings.
134
+Existing gated resources become read-only where possible. Users can
135
+remove gated configuration, but cannot create or expand it until the
136
+organization upgrades again.
137
+
138
+## Open questions for implementation
139
+
140
+- Whether Free should limit private org collaborators before usage
141
+  metering exists, or whether the first paid gates are advanced controls
142
+  only.
143
+- Whether required reviewers are gated only for private org repos. The
144
+  current lean is private-org-only.
145
+- Whether org-level Actions secrets and variables should be Team-only
146
+  even for public repositories. The current lean is yes for org scope.
147
+- Exact Free and Team quota numbers for Actions and storage. These must
148
+  come from real host-cost estimates before SP08.
149
+
150
+## Source references
151
+
152
+- GitHub pricing: `https://github.com/pricing`
153
+- GitHub plans docs:
154
+  `https://docs.github.com/en/get-started/learning-about-github/githubs-plans`
155
+- Stripe Billing: `https://docs.stripe.com/billing`
156
+- Stripe pricing models:
157
+  `https://docs.stripe.com/products-prices/pricing-models`
docs/internal/index.mdmodified
@@ -58,6 +58,8 @@ site.
5858
 - [actions-schema.md](./actions-schema.md),
5959
   [actions-runner-api.md](./actions-runner-api.md)
6060
 - [orgs.md](./orgs.md), [teams.md](./teams.md)
61
+- [billing.md](./billing.md) — paid org product contract,
62
+  entitlements, and Stripe integration guardrails.
6163
 - [notifications.md](./notifications.md)
6264
 - [search.md](./search.md), [markdown.md](./markdown.md)
6365
 - [seo.md](./seo.md) — crawler endpoints, metadata, sitemap, and
docs/internal/orgs.mdmodified
@@ -182,6 +182,18 @@ Soft-deleted users/orgs are dropped from `principals` so their slug
182182
 becomes available — the username_redirects table still preserves the
183183
 old slug for 301s during the rename cooldown.
184184
 
185
+## Billing posture
186
+
187
+Organizations are the first planned paid shithub surface. The
188
+`orgs.plan` and `billing_email` fields are present today, but payment
189
+processing and entitlement enforcement live in the PAYMENTS sprint
190
+series. The durable product and implementation contract is tracked in
191
+[`billing.md`](./billing.md).
192
+
193
+Until that series lands, production code must not branch on
194
+`orgs.plan` for feature access. Paid feature checks should go through
195
+the future entitlement package described in the billing doc.
196
+
185197
 ## What we deferred from the spec
186198
 
187199
 * **`username_redirects` rename to `principal_redirects`**. The