Skip to content

Remove fully-rolled-out commissions feature flag#6114

Merged
gumclaw merged 1 commit into
mainfrom
remove-commissions-flag
Jul 22, 2026
Merged

Remove fully-rolled-out commissions feature flag#6114
gumclaw merged 1 commit into
mainfrom
remove-commissions-flag

Conversation

@gumclaw

@gumclaw gumclaw commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

What

Removes the commissions Flipper flag and its dead branches. The flag is globally enabled in production (state=on, boolean=true; prod-state audit request 20260721T025828Z-d0d55a50, gumroad-private#1208) and the gated code has been stable since 2025-04.

Why

Next Category A flag in the rollout-flag cleanup requested on #6041 / gumroad-private#1208 (Sahil: "Do all A except content mod as kill switch"). Behavior-neutral: the flag is fully on, so every production seller already sees Commission in the service product types and can create commission products via API v2.

Changes

  • ProductPresenter.new_page_props: commission is now unconditionally part of service_product_types (was unless Feature.active?(:commissions, current_seller) — the subtraction never ran in prod).
  • Api::V2::LinksController#create: drop the flag-off rejection branch ("You do not have access to create commission products.") — unreachable in prod. The real gates remain: eligible_for_service_products? still rejects sellers <30 days old, and unsupported/legacy types are still rejected.
  • Specs: the two new_page_props snapshot expectations now include "commission"; the flag-on context folds into unconditional behavior; flag-off contexts (presenter subtraction, API rejection, "no Commission radio button" system spec) deleted as unrepresentable states.

Repo-wide grep for the flag: the only remaining :commissions hits are config/routes.rb resource routes and unrelated prose (features_markdown_generator.rb copy, artwork-and-commissions taxonomy slug) — no Feature/Flipper references left.

QA steps

Flag removal with no user-visible change (flag is 100% enabled in prod, so production behavior is already the post-removal behavior).

  1. Confirm grep -rn "Feature.active?(:commissions\|activate.*:commissions" app lib config spec returns nothing.
  2. Run the touched specs (see Test results).

Before / After

No adjacent UI change: the "Commission" option on the new-product page and API v2 commission creation behave identically for all production sellers before and after (the flag was globally on). The spec run below is the reviewable artifact for the behavior-neutral claim.

Test results

spec run

  • spec/presenters/product_presenter_spec.rb -e "new_page_props": 4 examples, 0 failures
  • spec/controllers/api/v2/links_controller_spec.rb:200 (whole POST 'create' block): 79 examples, 0 failures
  • rubocop on all 5 touched files: no offenses

Part of the flag-audit workstream tracked in gumroad-private#1208. Post-merge housekeeping (deploy-gated Flipper.remove(:commissions)) queued on the tracker.

Co-authored-by: Sahil Lavingia sahil@gumroad.com

The :commissions Flipper flag is 100% enabled in production (state=on,
boolean=true; prod-state audit request 20260721T025828Z-d0d55a50) and the
gated code has been stable since 2025-04. Removing the gate is
behavior-neutral: production behavior already IS the post-removal behavior.

- ProductPresenter.new_page_props: commission is now unconditionally part
  of service_product_types (it was already for every seller in prod).
- Api::V2::LinksController#create: drop the flag-off rejection branch for
  commission products (dead code in prod).
- Specs: fold the flag-on contexts into the unconditional behavior and
  delete flag-off contexts that pinned dead behavior.

Part of the rollout-flag audit gumroad-private#1208.
@gumclaw

gumclaw commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

fable-5 adversarial pre-merge review — verdict: PASS (no P1/P2)

Hunt list: (a) does removing the API-v2 flag check open an auth hole (the #6091 P1 class), (b) any other consumer of the flag or a derived prop, (c) snapshot specs on other CI shards asserting the old service_product_types, (d) does the flag-off system spec deletion lose real coverage.

  • (a) The Remove the ai_product_generation feature flag (100% enabled and stable in prod) #6091 implicit-auth-gate trap does not apply here. The removed branch gated a product type, not a privileged side-effect: commission creation still passes through the same create action's real gates — unsupported_types rejection, eligible_for_service_products? (30-day account age, covered by the surviving "rejects service types when seller is not eligible" example), price/currency validation. With the flag globally on, every seller already had this exact access; no request can now reach code it couldn't reach yesterday.
  • (b) Repo-wide grep for :commissions post-change: only config/routes.rb resource routes (the Commission model's own endpoints, unrelated to the flag) and prose strings (features_markdown_generator.rb, the artwork-and-commissions taxonomy slug). No commissions_enabled/commissionsEnabled prop exists anywhere (this flag never crossed into TS), so no FeatureFlags.tsx chain to unwind.
  • (c) grep -rln service_product_types spec/ → only product_presenter_spec.rb, already updated. No distant snapshot-spec flip risk (the Remove churn_analytics_enabled feature flag (100% enabled and stable in prod) #6066 CI class).
  • (d) The deleted flag-off contexts pinned states unrepresentable after removal (flag-off presenter subtraction, API rejection message, missing radio button). The flag-on system specs survive renamed as "commission products" — the end-to-end create flow and the ineligible-seller tooltip remain covered.
  • Specs: presenter new_page_props 4/4, whole API v2 POST 'create' block 79/79, rubocop clean on all 5 files.

Behavior-neutral by construction (state=on bool=true, no partial gates, audit 20260721T025828Z-d0d55a50). Arming auto-merge.

@gumclaw
gumclaw enabled auto-merge (squash) July 22, 2026 07:13
@greptile-apps

greptile-apps Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR removes the fully rolled-out commissions feature flag. The main changes are:

  • Makes Commission an unconditional service product type.
  • Removes the API v2 flag-off rejection branch.
  • Deletes obsolete flag-state tests and updates presenter expectations.

Confidence Score: 5/5

This looks safe to merge.

No blocking issues found in the changed code. Ineligible sellers still cannot select or create service products. Existing API authorization and model validations remain unchanged.

T-Rex T-Rex Logs

What T-Rex did

  • Before-state, the scoped parent-revision search found three references in the links controller, product presenter, and product creation spec.
  • After-state, the current-tree search produced no matches and rg exited with status 1, indicating no matches were found.
  • Two focused RSpec attempts were run, but both failed because Bundler could not find the rspec command, exiting with 127.
  • Bundle check failed with exit 18 and Ruby 3.1.2 does not satisfy the Gemfile requirement, explaining the environment incompatibility.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
app/controllers/api/v2/links_controller.rb Removes the obsolete commission flag check while retaining API authorization and model-level eligibility validation.
app/presenters/product_presenter.rb Always includes Commission among service product types; the frontend separately disables service products for ineligible sellers.
spec/controllers/api/v2/links_controller_spec.rb Removes the obsolete flag-off API rejection example.
spec/presenters/product_presenter_spec.rb Updates presenter expectations for unconditional Commission availability.
spec/requests/products/creation_spec.rb Removes the obsolete flag-off UI scenario while retaining seller eligibility coverage.

Reviews (1): Last reviewed commit: "Remove fully-enabled commissions feature..." | Re-trigger Greptile

@gumclaw
gumclaw merged commit d19da3e into main Jul 22, 2026
86 checks passed
@gumclaw
gumclaw deleted the remove-commissions-flag branch July 22, 2026 07:28
gumclaw added a commit that referenced this pull request Jul 22, 2026
Part of the Category A rollout-flag audit
(antiwork/gumroad-private#1208), following the pattern of #6105 / #6107
/ #6114.

The `:tax_center` Flipper flag is 100% enabled in production (state=on,
boolean=true; prod-state audit request `20260721T025828Z-d0d55a50`) and
the tax-center code has been stable since 2025-12. Removal is
behavior-neutral — production behavior already IS the post-removal
behavior.

- `User#tax_center_enabled?` reduces to `from_us?` (US residency was
always the second condition and is the only real requirement — the tax
center serves IRS forms). Moved from `User::FeatureStatus` to
`User::Taxation` next to `from_us?`, with a comment explaining the
history.
- Specs: dropped `Feature.activate_user(:tax_center)` setups; flag-off
contexts converted to non-US-seller contexts (the guard that still
exists).

## Test results
- `spec/controllers/tax_center_controller_spec.rb` +
`spec/controllers/api/v2/tax_forms_controller_spec.rb`: **43 examples, 0
failures** locally.
- `spec/controllers/api/v2/earnings_controller_spec.rb`: 2 failures
locally, but they reproduce identically on unmodified main (purchase
factory hitting Stripe — environmental). 0 new regressions.
- Rubocop clean. Repo-wide grep: zero remaining `:tax_center` Feature
references.

Post-merge housekeeping (queued): `Flipper.remove(:tax_center)` via the
audited prod console after deploy confirmation.

🤖 Authored by gumclaw (AI agent).
gumclaw added a commit that referenced this pull request Jul 22, 2026
…plete) (#6146)

Part of the Category A rollout-flag audit
(antiwork/gumroad-private#1208), following the pattern of #6105 / #6107
/ #6114 / #6125.

## What

Removes the `:au_backtaxes` Flipper flag check from
`SettingsPresenter#aus_backtax_details` and the corresponding
`Feature.activate` setups / flag-off contexts in the presenter and
request specs.

## Why

The `:au_backtaxes` flag is 100% enabled in production (state=on,
boolean=true; prod-state audit request `20260721T025828Z-d0d55a50`) and
the AU backtax collection campaign is confirmed complete (sign-off on
gumroad-private#1208). The flag only gated the settings-page backtax
prompt, which is additionally guarded by two real conditions that remain
in place:

- the seller owes at least
`User::MIN_AU_BACKTAX_OWED_CENTS_FOR_CONTACT`, and
- an `AustraliaBacktaxEmailInfo` record exists for the seller (they
received the campaign email).

Sellers who never received a campaign email continue to see nothing, so
removal is behavior-neutral — production behavior already IS the
post-removal behavior. No UI pixels change for any seller state.

## Test results

- `spec/presenters/settings_presenter_spec.rb -e "AU backtax"`: **2
examples, 0 failures** locally.
- `spec/requests/settings/payments_spec.rb -e "Taxes collection"`: 4
failures locally, but the same section fails identically on unmodified
main in this worktree (Capybara `#app` hydration timeout —
vite-asset/browser environmental, screenshots show a blank app shell on
both). **0 new regressions**; CI will verify.
- Rubocop clean on all three touched files. Repo-wide grep: zero
remaining `:au_backtaxes` Feature references (remaining `au_backtaxes*`
hits are unrelated prop names for paid-status display).

Post-merge housekeeping (queued): `Flipper.remove(:au_backtaxes)` via
the audited prod console after deploy confirmation.

---

🤖 AI disclosure: authored by gumclaw (Claude Fable 5) as part of the
automated rollout-flag audit; flag removal, spec restructuring, and
local spec runs done by the agent.

Co-authored-by: Hermes Agent <gumclaw@users.noreply.github.com>
Co-authored-by: Sahil Lavingia <sahil@gumroad.com>
gumclaw added a commit that referenced this pull request Jul 22, 2026
## What

Removes the `utm_links` Flipper feature flag and every gate that checked
it. Only the flag *gating* is removed — the UTM links feature (model,
controllers, jobs, presenters, pages) is untouched.

- `UtmLinkPolicy#index?` / `#create?` — drop the
`Feature.active?(:utm_links, seller)` conjunct, leaving the role checks
that actually govern authorization.
- `UtmLinkSaleAttributionJob` — drop the per-visit `next unless
Feature.active?(...)` skip; visits now attribute unconditionally.
- `UtmLinkTrackingController#show` — drop the `e404 unless
Feature.active?(...)` guard; the short-link redirect is now
unconditional.
- `UtmLinkTracking` concern — drop both `Feature.active?(...)` guards in
the visit-tracking path.
- Specs — remove `Feature.activate(_user)(:utm_links)` setups (now
unconditional behavior) and delete the flag-off contexts that pinned
dead behavior.

## Why

The flag has been **100% on in production** since the UTM links feature
stabilized in 2025-04. Audited prod read `20260721T025828Z-d0d55a50`
confirms `state=on, boolean=true`. With the flag fully enabled, every
`Feature.active?(:utm_links, seller)` check already evaluates to `true`
in production, so removing it is **behavior-neutral — production
behavior already IS the post-removal behavior**. Removing the gate
deletes dead branches (the flag-off path is unreachable in prod) and
simplifies the authorization/tracking code.

This is part of the **gp#1208** rollout-flag audit, following the same
pattern proven across
#6062/#6066/#6079/#6080/#6084/#6091/#6105/#6107/#6114/#6125.

## Before/After

No UI delta — this removes a backend gate that was already fully open in
production, so there is nothing visual to capture. The reviewable
artifact is the diff plus the passing backend gate specs (below).

## Test Results

All backend specs that exercised the removed gates pass (93 examples, 0
failures) and rubocop is clean on all touched files:

![spec
run](https://raw.githubusercontent.com/antiwork/gumroad/remove-utm-links-flag/qa-media/remove-utm-links-flag-specs.png)

`spec/requests/analytics/utm_links_spec.rb` is a `:js` browser suite
whose React app does not mount in this worktree's asset pipeline; its 9
failures are **pre-existing and reproduce identically on clean `main`**
(verified by stash-bisect, by example name), so this change introduces
zero regressions.

---

## AI disclosure

Authored by Claude Opus 4.8 (Claude Code). Prompt: audit and remove the
fully-enabled `utm_links` Flipper flag (gp#1208 Category A) — delete the
`Feature.active?(:utm_links, ...)` gates while preserving the feature,
sweep both spec suites removing flag-off contexts, verify no gating hits
remain, and open this PR. The behavior-neutrality claim rests on the
audited production flag state `20260721T025828Z-d0d55a50` (flag 100%
on).

## QA steps

No preview deploy is needed — this is a behavior-neutral backend flag
removal with no UI change. To confirm nothing broke, exercise the
existing UTM links flow as any seller (the flag being removed was 100%
on, so this is the current production path):

1. Visit Analytics → Links, create a UTM link, and confirm it saves and
lists.
2. Visit the link's short URL and confirm it redirects to the UTM
destination.
3. Complete a purchase after visiting through a UTM link and confirm the
sale is attributed (driven-sale row created; UTM block appears in the
seller's sale notification email).

---------

Co-authored-by: Hermes Agent <gumclaw@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant