@@ -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` |