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
Owner

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:

  • the grant form's warning says only that a tier held by a subscription would be superseded;
  • the organization page's Billing card names only Hosting as a ladder the subscription delivers nothing on (internal/server/operator_enrollment.go:486-503);
  • the member's Products page reads Support as holding nothing and offers its tiers through Checkout (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

  • Keep the behaviour: the product is left alone and the other ladders stay empty until the grant ends. The warning and the Billing card then name every ladder the subscription stops delivering on.
  • Refuse a grant that would supersede part of a multi-ladder subscription's product, or make the operator confirm the ladders it empties.
  • Deliver the rest of the product: keep the subscription's tiers on the ladders the grant is not on. The conferral delivers a product whole today, so this changes the conferral model.
  • Restore the default on each ladder left empty, which is #154's per-ladder question.

Decided when

The rule for a grant over one ladder of a multi-ladder subscription is written in docs/models/plan-ladders-transitions.md beside 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.

### 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: - the grant form's warning says only that a tier held by a subscription would be superseded; - the organization page's Billing card names only Hosting as a ladder the subscription delivers nothing on (`internal/server/operator_enrollment.go:486-503`); - the member's Products page reads Support as holding nothing and offers its tiers through Checkout (`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 - Keep the behaviour: the product is left alone and the other ladders stay empty until the grant ends. The warning and the Billing card then name every ladder the subscription stops delivering on. - Refuse a grant that would supersede part of a multi-ladder subscription's product, or make the operator confirm the ladders it empties. - Deliver the rest of the product: keep the subscription's tiers on the ladders the grant is not on. The conferral delivers a product whole today, so this changes the conferral model. - Restore the default on each ladder left empty, which is #154's per-ladder question. ### Decided when The rule for a grant over one ladder of a multi-ladder subscription is written in `docs/models/plan-ladders-transitions.md` beside 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.
cgalo5758 added this to the Public launch milestone 2026-10-26 20:58:22 +00:00
Author
Owner

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.

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.
Author
Owner

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.md beside whole-bundle supersession, and a test drives a grant over one ladder of a two-ladder subscription.

Commit: dec031e6

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.md` beside whole-bundle supersession, and a test drives a grant over one ladder of a two-ladder subscription. Commit: dec031e6
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: wiki-cafe/member-console#271