Backfill model_registry/experiments access levels to PRIVATE on existing non-public projects
Goal
Batched background migration that sets model_registry_access_level and model_experiments_access_level to PRIVATE on existing non-public projects where these values are currently ENABLED.
Filter:
project.visibility_level != PUBLIC AND model_*_access_level = ENABLEDPRIVATE rows are left alone (already members-only). DISABLED rows are left alone (feature is deliberately off). PUBLIC is not a reachable state for these features — ProjectFeature#allowed_access_levels rejects it via validation (only pages and package_registry are excluded from that check), so no PUBLIC rows are expected to exist.
Why
Today, the ProjectPolicy carve-out
rule { ~public_project & guest & model_registry_enabled }.enable :read_model_registryforces member-only access for model registry / experiments on non-public projects regardless of the Featurable access level. Once the carve-out is removed (Task C), the Featurable access level becomes the source of truth. This migration sets the existing population to the access level that reproduces today's observable behavior.
Sequencing
Blocked by Task A (dynamic defaults). Must not deploy until A is live, because any non-public project created in the gap between B and A would still get the static ENABLED default and would regress when the policy carve-out is later removed.
References
- Parent: #599574
- Discussion: !235259 (closed)