A grant on one ladder ends a multi-ladder subscription's tiers on every ladder, and the other ladders stay empty while the subscription bills #271
Closed
opened 2026-10-26 20:58:22 +00:00 by cgalo5758
·
2 comments
Labels
Clear labels
accessibility
area/billing
area/catalog
area/discourse
area/domains
area/entitlements
area/fedwiki
area/identity
area/integrations
area/licensing
area/member-ui
area/meta
area/operator-ui
area/ops
area/testing
duplicate
good-first-issue
invalid
privacy
security
upstream
wontfix
A barrier for people using assistive technology or a keyboard alone.
The Stripe mirror, checkout, subscriptions, invoices, fulfillment.
Products, prices, plan ladders, purchasability.
The Discourse integration.
The domains registry, claims, placements, the certificate ask.
Entitlement sets, rules, grants, pools, provisioning.
The Federated Wiki integration and farm sync.
Sign-in, sessions, persons, organizations, workspaces, roles.
The provider registry, outbox and webhooks in general.
Licenses, the contributor agreement, SPDX headers.
Member pages.
The repository itself, its contributing guide, CI, the tracker and the workflow.
Operator pages, forms, lists, the design system.
Deployment, configuration, migrations, workflows, instance settings.
The test stack, screens, lint, walkthroughs.
Closed because another issue already covers it.
Small, self-contained, and explained enough to be a first contribution.
Closed because it is not a ticket for this repository.
Touches what a person's data reveals.
Touches authentication, authorization, secrets or data exposure.
Waits on another repository or project before it can move.
Closed because it will not be done, with the reason in the last comment.
kind
bug
The software does something other than what it promises; closed when it again does what it promises.
kind
debt
Code, tests or tooling to clean up with nothing visible changing; closed when they are cleaner.
kind
design
A question to settle before work can be defined; closed when the decision is written down.
kind
docs
Documentation that is wrong or missing; closed when it says the right thing.
kind
enhancement
Something the software does not do yet; closed when it does.
priority
critical
Blocks the active milestone or harms members now.
priority
high
Next in line inside the active milestone.
priority
low
Inside the active milestone, when nothing else is left.
priority
medium
Inside the active milestone, after the high ones.
Milestone
No items
No Milestone
Public launch
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: wiki-cafe/member-console#271
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The question
Some terms first. A plan ladder is a ranked sequence of tiers; an organization holds one tier per ladder at a time. A grant is an operator's record that gives an organization a product without payment. One product can be a tier of several ladders, for example a "Hosting and Support" product that is a tier of a Hosting ladder and of a Support ladder, and a member can subscribe to it when every one of its ladders offers Checkout (
plans.Across,internal/plans/offer.go:311-336).When a new plan takes a ladder, the console supersedes the plan that held it, and supersession is whole: it ends that plan's delivery on every ladder it held, including ladders the new plan is not on (
core.confer,internal/db/migrations/00023_grant_resumption.sql:578-623, the end of each rung at:600-617;docs/models/plan-ladders-transitions.md:67).So when an organization pays for the Hosting and Support product and an operator grants it a Hosting tier, the subscription's Support tier ends too. The subscription keeps billing for the whole product. Its reconcile, the console's reading of the subscription back from Stripe, leaves the product alone while the grant holds Hosting, because the console confers a product whole or not at all (
DisplacedProducts,internal/fulfillment/reconcile.go:739-757). The organization type's default is restored only when the organization holds nothing on any ladder, so Support stays empty until the grant ends (internal/entitlements/reapply_defaults.go:84-114). Meanwhile:internal/server/operator_enrollment.go:486-503);internal/plans/offer.go:181-182), which would start a second subscription while the first still bills for Support.What should a grant on one ladder do to a subscription's tiers on the ladders the grant is not on?
What depends on the answer
What a member who pays for a product on several ladders receives while an operator's grant covers one of them; the grant form's warning and the organization page's line; whether the console can deliver part of a product; the default floor, which today runs only for an organization that holds nothing (#154 asks whether the default belongs per ladder); and #88, which records the same whole-bundle end for Checkout and the plan switch.
Options known so far
Decided when
The rule for a grant over one ladder of a multi-ladder subscription is written in
docs/models/plan-ladders-transitions.mdbeside the whole-bundle supersession rule, the grant form and the organization page say what the grant does to the other ladders, and a test drives a grant over one ladder of a two-ladder subscription.A note from the grant pause work. When a subscription pays for a product that is a tier of two ladders and a grant takes one of them, the subscription stops delivering that product on both ladders, and the other ladder is left with nothing on it. If the subscription pays for nothing else, its billing is now paused while the grant holds. Checkout now refuses every tier of the other ladder, because buying there would start a second subscription while the first still exists, and the paid tier's card on that ladder offers no control. What the member should see or be offered on that ladder is still this issue's open question.
Decided: a grant on one ladder of a product that is a tier of several ladders keeps ending the subscription's tier on all of them, and the ladders the grant is not on stay empty until it ends. (A plan ladder is a ranked list of tiers, and an organization holds one tier per ladder; a grant is an operator's record that gives an organization a product without payment.) The console delivers a product whole or not at all, so keeping the rest of the product would change how every plan is delivered, which #88 is about; putting the organization type's default plan on each empty ladder is #154's question; and asking the operator to confirm the emptied ladders was turned down, because the console warns rather than blocks, as it does when an operator sells a product that gives nothing.
What changed is that every place an operator or a member looks now says so. The Issue grant form's warning, shown once the operator picks a product that would replace a tier a subscription pays for, names every ladder of that tier when there is more than one: "This grant would supersede a tier a subscription pays for on Duo and Wiki; its billing pauses until the grant ends." The Not delivering badge on the organization page's Billing card and in the operator's subscriptions list names the empty ladders too: "Billing paused while a grant holds Wiki; nothing is delivered on Duo." A ladder that another plan holds by the time the page is drawn is not named, so the sentence stays true. On the member's Products page, the paid plan's card on each ladder the grant does not hold reads "Paused while Pro is granted on Wiki", or "Billing continues while Pro is granted on Wiki" until Stripe confirms the pause; its controls stay on the card of the ladder the grant holds. When the subscription pays for nothing else, its billing pauses as it does for a tier of one ladder, because while the grant holds, that tier delivers nothing anywhere. The rule is written in
docs/models/plan-ladders-transitions.mdbeside whole-bundle supersession, and a test drives a grant over one ladder of a two-ladder subscription.Commit:
dec031e6