Stub Renewals are exempt from the Net ARR sign logic above. See [Stub Renewal Opportunities](#stub-renewal-opportunities).
- Closed Won → Order Type = `Growth` (`ARR_Net__c` = `0`).
- Closed Lost → Order Type = `Contraction` (`ARR_Net__c` = −ARR Basis), regardless of whether the Account Family has remaining active subscriptions. `Churn - Partial` and `Churn - Final` are never applied to a Stub Renewal.
#### Abbreviated scenario table
| Subscription Type | Net ARR sign | Example Categories | Typical Order Type (Open / Closed Won) | Churn behavior (when Closed Lost) |
@@ -617,6 +624,110 @@ Please see our internal [document](https://docs.google.com/document/d/1UaKPTQePA
- Salesforce has a default behavior that when an opportunity is updated, any opportunity split that is owned by the old owner of the opportunity is updated to the new owner of the opportunity. This is irregardless of what type of split it is, if it is split or not. Even if we try to work around this exception with an After trigger the SFDC automation fires after any after triggers we write.
## Stub Renewal Opportunities
**Business Process this supports:**[Sales Renewal Process](/handbook/sales/sales-renewal-process/) and [Go-To-Market – Renewals](https://internal.gitlab.com/handbook/sales/go-to-market/renewals). This automation covers renewal of recurring products on multi-year ramp deals whose charges do **not** co-term with the underlying subscription.
**Overview:**
On a multi-year ramp deal, a recurring product can be present in one ramp interval and absent from the next — for example a 12-month GitLab Duo Enterprise add-on sitting on a 36-month Ultimate subscription. Historically the out-year ramp opportunity for that interval was created and auto-closed at booking with a negative Net ARR, so the drop was booked as pre-booked **Contraction**. When the customer later extended the product it surfaced as **Growth** on an add-on rather than as retained ATR on a renewal baseline, which distorted ATR assignment, renewal metrics, forecasting, and comp.
A **Stub Renewal** is a lightweight, product-level renewal opportunity created in an open stage to hold that renewable baseline. It is **additive**: the standard subscription-level renewal opportunity, the one-primary-renewal-per-`Customer_Subscription__c` model, and out-year ramp opportunities for quantity and price deltas on other products all behave exactly as they did before.
The feature is gated behind the `Enable_Stub_Renewal` custom metadata feature flag (`Feature_Flag.Enable_Stub_Renewal`), so it can be toggled without a deployment.
**Relevant fields**
- Opportunity object:
-`Opportunity Category` (`Opportunity_Category__c`) — new picklist value `Stub Renewal`
-`Subscription End Date` (`Subscription_End_Date__c`)
-`Parent Opportunity` (`Parent_Opportunity__c`)
- Opportunity Product object:
-`Amendment Type` — `StubRemoveProduct`
**Criteria to enter this logic:**
A Stub Renewal is created when **all** of the following are true:
1. The source opportunity is a true ramp opportunity of Subscription Type `New Business` or `Renewal`.
1. Out-year opportunity product generation produces one or more `RemoveProduct` line items — that is, a recurring product is **fully removed** in a future ramp interval.
1. The removed product is recurring, is not a trial product, and is not one-time only.
The following do **not** trigger a Stub Renewal:
- Quantity reductions or price downsizes on a product that continues into the next interval.
- Removal of a trial product.
- Addition of a new product in a later interval.
-`Add-On` opportunities.
- Source ramp opportunities that are Closed Lost.
Multiple products removed in the **same** interval produce a **single** Stub Renewal. Products removed in **different** intervals produce a **separate** Stub Renewal per interval.
**Inputs:** Source ramp Opportunity, the out-year Opportunity Products generated by `OpportunityClass.generateOutYearOpps`, `DeltaMRR` on each `RemoveProduct` line item, ramp interval start and end dates, subscription term end date.
**Outputs:** One Stub Renewal Opportunity per affected interval, plus its Opportunity Products.
| Field | Value at creation |
|----|----|
| `Name` | Must contain the phrase `Stub Renewal`, for example `[Account Name] – Stub Renewal [YYYY-MM-DD]` |
| `Opportunity_Category__c` | `Stub Renewal` |
| `Subscription_Type__c` | `Renewal` |
| `StageName` | `2-Scoping` (open) |
| `Quote_Start_Date__c` | The removed charge's end date + 1 day, that is, the start date of the ramp interval in which the product was dropped |
| `Subscription_End_Date__c` | The end date of the underlying subscription |
| `CloseDate` | The Close Date of the out-year ramp opportunity for the interval in which the product was dropped |
| `Stamped_ARR_Basis__c` | The removed charge's **positive** annual ARR (absolute value of `DeltaMRR` × 12, summed per opportunity) |
| `Amount` | The value of the removed charge across the remaining intervals of the subscription term |
| `ARR_Net__c` | `0` |
| `Parent_Opportunity__c` | The source ramp (base) opportunity |
| `OwnerId` | Follows the same Renewal Ownership logic as subscription-level renewals |
| `Initial Source`, `Pricebook2Id` | Inherited from the source opportunity |
Once the quote is built, the quote controls these fields, exactly as on any other opportunity.
**Opportunity Products**
Opportunity Products are created on the Stub Renewal for the dropped charges with `Amendment Type = StubRemoveProduct`. These are placeholders and may be deleted once a quote is created.
**Order Type behavior**
Stub Renewals are exempt from the standard Renewal Net ARR sign logic — see [Order Type System](#order-type-system):
- Closed Won → Order Type = `Growth`, `ARR_Net__c` = `0`.
- Closed Lost → Order Type = `Contraction`, `ARR_Net__c` = −(ARR Basis), **regardless** of whether the Account Family has remaining active subscriptions.
The removal is therefore not booked as negative Net ARR before the Stub Renewal's Close Date; the contraction or churn is deferred to the point the Stub Renewal is lost.
**Quoting**
Stub Renewals have **no** auto-generated or pre-populated quote. They are excluded from the `Renewal_Quote_Processing_Stage__c` / `Renewal_Quote_Processing_Status__c` batch flows used to pre-populate flat renewal quotes on standard renewal opportunities. A rep manually creates an amendment quote against the subscription when the renewal is worked.
-`Feature_Flag.Enable_Stub_Renewal` — custom metadata feature flag controlling the whole feature
-`Opportunity_Category__c` — new `Stub Renewal` picklist value
-`Parent_Opportunity_Cannot_be_Add_On` validation rule — exemption list updated so Stub Renewals can carry a Parent Opportunity
**Related Issues:**[Generate Renewal Opportunities for Ramp Charges that do not co-term](https://gitlab.com/gitlab-com/eta/business-systems/opportunity-to-quote/-/work_items/112)
## Refund Opportunity
**Business Process this supports:**[Decommission Opportunity Process](/handbook/sales/field-operations/sales-operations/deal-desk/#creating-decommission-opportunties)