Implement more granular backend validation for GrowthBook experiments

What?

  1. New validation rules in util/experimentValidationRules.js
  1. Updated GB validator in validation/growthBookExperimentValidator.js
  • validateExperiment() now reads customFields.risk_level / customFields.security_review_url.
  • validateAllExperiments() now returns { validated, invalid } (the invalid list carries { id, trackingKey, errors }) so the caller can act on rejects.
  1. Update invalid experiments as "draft" in service/growthBookClient.js, experimentConfigurationService.js
  • New updateExperimentStatus(id, 'draft') is a POST {api_url}/{id}.
  • process() marks each invalid experiment as "draft" back in GrowthBook but only when saved groups were available the poll cycle. Otherwise wiki targeting can't be resolved and an experiment could fail (and be wrongly updated as "draft"). This reuses the existing preservation check. Per-experiment failures are logged + counted, never aborting the poll.
  • Added a growthbook_experiment_drafts_total{outcome} metric.
  1. Introduce experimentUsesSavedGroups in targetingConditionParser.js (true when the current phase's savedGroupTargeting references a saved group).
  • When saved groups fetch is N/A, the code used a single savedGroupsAvailable flag to skip marking all invalid experiments as draft and preserve all GB experiments. But saved groups availability only affects one validation rule (wiki targeting), so experiments failing for unrelated reasons were wrongly protected from eviction from the cache.
  • Validator tags each invalid experiment with usesSavedGroups so when saved groups are N/A, process() still marks invalid experiments as draft but filters out only the saved-group-dependent experiments
  • `preservedExperiments keeps only these instead of all GB experiments
  • Documented in the process() doc comment that savedGroupsAvailable reflects fetch success, not existence. With no saved groups configured (current state), the fetch resolves empty, the logic remains dormant, and the poll cycle matches the no-saved-groups baseline. It works automatically once saved groups are created in GrowthBook.
  1. Add/update relevant tests

Why?

Since custom hooks are not available yet in GrowthBook UI for experiments, we need to do custom validation in the TK backend during GrowthBook-sourced experiments ingestion in the poll cycle.

Notes:

  • This MR excludes validation for OKRs and Teams - will be done in a follow up MR. Implement in the future when needed per standup 6/15/26
  • Already covered by existing code (no changes needed):
    • Tracking key uniqueness, GB precedence
    • Stream name validation via Action API
    • Traffic per wiki rules

Bug: T428802
Bug: T428984

Edited by Clare Ming

Merge request reports

Loading