Skip to content

fix(experiment): make dataApiRevokeOnCreateDefault flag reads shape-agnostic#46289

Merged
seanoliver merged 1 commit into
masterfrom
sean/growth-877-shape-agnostic-flag-helper
May 23, 2026
Merged

fix(experiment): make dataApiRevokeOnCreateDefault flag reads shape-agnostic#46289
seanoliver merged 1 commit into
masterfrom
sean/growth-877-shape-agnostic-flag-helper

Conversation

@seanoliver
Copy link
Copy Markdown
Contributor

@seanoliver seanoliver commented May 22, 2026

I have read the CONTRIBUTING.md file.

YES

What kind of change does this PR introduce?

Bug fix / experiment prep.

What is the current behavior?

The data-api-revoke-on-create-default PostHog flag is configured as a boolean rollout, not a multivariate experiment. Confirmed via Hex on 2026-05-22: bucketing math reconciles (treatment share 2.56%, expected 2.5%), but in-experiment control users are indistinguishable from non-cohort users in the event data — both return false. Any control-arm signal is diluted across the ~95% of users who never entered the experiment.

The fix is reconfiguring the flag as multivariate with control / test string variants (GROWTH-877). But the boolean and string return shapes can't coexist cleanly — whichever side ships first breaks the experiment in the gap:

  • PostHog config first → frontend sees 'test'; strings are truthy, so if (flag) evaluates true for both arms.
  • Frontend first → frontend strict-equals 'test' while PostHog still returns boolean true; nobody gets treatment.

What is the new behavior?

Exported helper that accepts both shapes:

export const isInDataApiRevokeTreatment = (flag: boolean | string | undefined): boolean => {
  if (flag === true) return true   // current boolean shape
  if (flag === 'test') return true // future multivariate shape
  return false                     // false, 'control', null, undefined
}

Routes the enabled-hook, both page surfaces (/new/[slug] and the Vercel deploy button), and the convergence gate in the exposure hook through it. No behavioral change on the boolean flag today. After the PostHog config flip lands, the same code picks up the variant string automatically — no coordinated deploy needed.

Pre-fixes a latent bug along the way: the previous code computed the form's expected default as !flag, which evaluates false for any truthy string including 'control'. That would have defaulted control-arm users to the revoke checkbox on day one of the migration. The helper-based derivation correctly treats 'control' as not-treatment.

Telemetry contract for project_creation_default_privileges_exposed and project_creation_simple_version_submitted widened from boolean to boolean | string. Payload keeps sending the raw flag value (not the derived boolean) so BQ analysis can distinguish control from non-cohort once multivariate lands.

Testing

  • pnpm --filter studio exec vitest run hooks/misc/__tests__/useDataApiRevokeOnCreateDefault.test.ts — 24/24 pass (16 existing + 8 new covering both variant strings)
  • Existing boolean-shape tests pass unmodified
  • Two new exposure tests assert the convergence gate fires correctly for both 'test' (treatment, expected default false) and 'control' (not treatment, expected default true) — these document the latent bug fix

Additional context

Migration sequence after this lands is in GROWTH-877. BQ-side query updates to read the variant string are flagged as a followup on the ticket — they don't block this PR.

Summary by CodeRabbit

  • Refactor

    • Enhanced feature flag handling for data API default privileges configuration to support both current and future flag variations across project creation flows.
  • Tests

    • Added test coverage for multivariate flag shape handling in data API revoke-on-create default scenarios.

Review Change Stack

@seanoliver seanoliver requested review from a team as code owners May 22, 2026 19:54
@vercel
Copy link
Copy Markdown

vercel Bot commented May 22, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
design-system Ready Ready Preview, Comment May 22, 2026 8:17pm
docs Ready Ready Preview, Comment, Open in v0 May 22, 2026 8:17pm
studio-self-hosted Ready Ready Preview, Comment May 22, 2026 8:17pm
studio-staging Ready Ready Preview, Comment May 22, 2026 8:17pm
ui-library Ready Ready Preview, Comment May 22, 2026 8:17pm
zone-www-dot-com Ready Ready Preview, Comment, Open in v0 May 22, 2026 8:17pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
studio Ignored Ignored May 22, 2026 8:17pm

Request Review

@supabase
Copy link
Copy Markdown

supabase Bot commented May 22, 2026

This pull request has been ignored for the connected project xguihxuzqibwxjnimxev because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 22, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 17186ec0-22ef-4203-9bb3-acd7b7e72e02

📥 Commits

Reviewing files that changed from the base of the PR and between ac97469 and 81d066a.

📒 Files selected for processing (5)
  • apps/studio/hooks/misc/__tests__/useDataApiRevokeOnCreateDefault.test.ts
  • apps/studio/hooks/misc/useDataApiRevokeOnCreateDefault.ts
  • apps/studio/pages/integrations/vercel/[slug]/deploy-button/new-project.tsx
  • apps/studio/pages/new/[slug].tsx
  • packages/common/telemetry-constants.ts

📝 Walkthrough

Walkthrough

Adds exported isInDataApiRevokeTreatment(flag) to interpret boolean or multivariate string variants of the PostHog flag, updates hooks/pages to use the helper and widened flag types, extends tests for multivariate variants, and widens telemetry event properties to accept boolean|string.

Changes

Data API revoke-on-create multivariate flag support

Layer / File(s) Summary
Flag shape helper and core hook logic
apps/studio/hooks/misc/useDataApiRevokeOnCreateDefault.ts, apps/studio/hooks/misc/__tests__/useDataApiRevokeOnCreateDefault.test.ts
Adds exported isInDataApiRevokeTreatment(flag) (treats true or 'test' as treatment). useDataApiRevokeOnCreateDefaultEnabled now reads `boolean
Page integrations with flag helper
apps/studio/pages/integrations/vercel/[slug]/deploy-button/new-project.tsx, apps/studio/pages/new/[slug].tsx
Pages import isInDataApiRevokeTreatment and treat the feature flag as `boolean
Telemetry event schema updates
packages/common/telemetry-constants.ts
Widen ProjectCreationDefaultPrivilegesExposedEvent.properties.dataApiRevokeOnCreateDefaultEnabled and ProjectCreationSimpleVersionSubmittedEvent.properties.dataApiRevokeOnCreateDefaultEnabled? from boolean to `boolean

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • supabase/supabase#46085: Earlier PR touching useTrackDefaultPrivilegesExposure and related telemetry/state logic that this change extends for multivariate flag shapes.

Suggested reviewers

  • pamelachia
  • awaseem

Poem

🐰 I sniffed the flag both string and true,

Whether "test" or boolean, I now knew.
One helper hops to set the tone,
Pages, hooks, and metrics—seed is sown,
A rabbit’s cheer for flags well-grown!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: making the dataApiRevokeOnCreateDefault flag reads shape-agnostic to handle both boolean and multivariate string variants.
Description check ✅ Passed The PR description follows the template with all required sections completed: confirms CONTRIBUTING.md read, states bug fix/experiment prep type, explains current boolean-only behavior and the coordination problem, details the new helper-based solution, includes testing results, and provides context linking to GROWTH-877.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sean/growth-877-shape-agnostic-flag-helper

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

…gnostic

Prep for migrating data-api-revoke-on-create-default from a boolean
rollout to a multivariate experiment with named variants (GROWTH-877).
The flag's current boolean shape can't distinguish in-experiment control
from non-cohort users — both return false — so the analysis dilutes any
control-arm signal across the ~95% of users who never entered the
experiment. The fix is reconfiguring the PostHog flag as multivariate
with control/test string variants, but doing that without coordinating
a frontend deploy would break the experiment in opposite ways depending
on which side ships first.

This PR removes that coordination requirement. Introduces an exported
`isInDataApiRevokeTreatment(flag)` helper that returns true iff the
caller is in the treatment arm, accepting both the current boolean
shape (true) and the future multivariate shape ('test'). Routes the
hook, both page surfaces (/new/[slug] and the Vercel deploy button),
and the convergence gate in the exposure hook through the helper. No
behavioral change on the boolean flag — the existing rollout keeps
working exactly as it does today. After the PostHog config flip lands,
the same code picks up the variant string automatically.

Also pre-fixes a latent bug that would have shipped on day one of the
multivariate switchover: the previous code computed the form's expected
default as `!flag`, which evaluates to false for *any* truthy string —
including 'control'. That would have set control-arm users to the
revoke checkbox by default. The helper-based derivation correctly
treats 'control' as not-treatment and leaves the legacy default.

Telemetry contract for project_creation_default_privileges_exposed and
project_creation_simple_version_submitted broadened to accept either
boolean or string for dataApiRevokeOnCreateDefaultEnabled. The payload
keeps sending the raw flag value (not the derived boolean) so the BQ
analysis can finally distinguish control from non-cohort once the
multivariate config lands.

GROWTH-877
@seanoliver seanoliver force-pushed the sean/growth-877-shape-agnostic-flag-helper branch from ac97469 to 81d066a Compare May 22, 2026 20:11
@github-actions
Copy link
Copy Markdown
Contributor

🎭 Playwright Test Results

passed  202 passed
flaky  6 flaky
skipped  5 skipped

Details

stats  213 tests across 23 suites
duration  11 minutes, 56 seconds
commit  81d066a

Flaky tests

Features › assistant.spec.ts › AI Assistant › Can send a message to the assistant and receive a response
Features › database.spec.ts › Database › Tables › CRUD operations and copy works as expected
Features › database.spec.ts › Database › Tables columns › can view, create, update, delete, and filter table columns
Features › queue-table-operations.spec.ts › Queue Table Operations › pending changes persist when switching between tables
Features › realtime-inspector.spec.ts › Realtime Inspector › Message Display › messages counter shows correct count
Features › storage.spec.ts › Storage › can copy a file url regardless of the opened folders

Skipped tests

Features › auth-users.spec.ts › should show web3 users as enabled when the matching web3 provider is enabled
Features › sql-editor.spec.ts › SQL Editor › snippet favourite works as expected
Features › sql-editor.spec.ts › SQL Editor › share with team works as expected
Features › sql-editor.spec.ts › SQL Editor › folders works as expected
Features › sql-editor.spec.ts › SQL Editor › other SQL snippets actions work as expected

@seanoliver seanoliver merged commit 2c651dd into master May 23, 2026
32 checks passed
@seanoliver seanoliver deleted the sean/growth-877-shape-agnostic-flag-helper branch May 23, 2026 16:30
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 23, 2026

Braintrust eval report

Assistant (master-1779553940)

Score Average Improvements Regressions
Completeness 97.4% (-3pp) - 2 🔴
Conciseness 39.7% (+1pp) 9 🟢 7 🔴
Correctness 75% (-3pp) 1 🟢 2 🔴
Docs Faithfulness 66.7% (-5pp) 1 🟢 4 🔴
Goal Completion 78.2% (0pp) 5 🟢 4 🔴
Knowledge Usage 90% (-2pp) - 1 🔴
SQL Identifier Quoting 100% (+0pp) - -
SQL Validity 100% (+0pp) - -
Tool Usage 72.9% (+3pp) 1 🟢 -
Safety 95.2% (-5pp) - 1 🔴
URL Validity 100% - -
Time_to_first_token 0tok (+0tok) 12 🟢 14 🔴
Llm_calls 7.5 (+0.67) 19 🟢 4 🔴
Tool_calls 2.85 (-0.08) 6 🟢 10 🔴
Errors 0 (-0.9) 18 🟢 -
Llm_errors 0 (+0) - -
Tool_errors 0 (+0) - -
Prompt_tokens 20132.58tok (-1599.95tok) 12 🟢 10 🔴
Prompt_cached_tokens 6701.95tok (+505.44tok) 11 🟢 8 🔴
Prompt_cache_creation_tokens 0tok (+0tok) - -
Prompt_cache_creation_5m_tokens 0tok (+0tok) - -
Prompt_cache_creation_1h_tokens 0tok (+0tok) - -
Completion_tokens 567.5tok (-1.19tok) 11 🟢 15 🔴
Completion_reasoning_tokens 95.73tok (+5.1tok) 11 🟢 12 🔴
Completion_accepted_prediction_tokens 0tok (+0tok) - -
Completion_rejected_prediction_tokens 0tok (+0tok) - -
Completion_audio_tokens 0tok (+0tok) - -
Total_tokens 20700.08tok (-1601.14tok) 13 🟢 13 🔴
Estimated_cost 0$ (0$) 10 🟢 12 🔴
Duration 15.42s (+0.71s) 10 🟢 16 🔴
Llm_duration 8.68s (-1.03s) 18 🟢 8 🔴

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.

3 participants