chore: remove ai-gateway-cost-control experiment flag (#27579)

## Description

Closes
[AIGOV-443](https://linear.app/codercom/issue/AIGOV-443/remove-ai-gateway-cost-control-experiment-flag-once-feature-is-stable).

The AI Gateway cost control feature is planned for GA on the upcoming
release, so this removes the `ExperimentAIGatewayCostControl` experiment
and all of its gating. The cost control API endpoints remain gated by
the `FeatureAIBridge` license feature (the AI Governance add-on), so
this only drops the experiment layer.

## Changes

- **`codersdk/deployment.go`**: remove the
`ExperimentAIGatewayCostControl` const, its `DisplayName()` case, and
its `ExperimentsKnown` entry.
- **`enterprise/coderd/coderd.go`**: remove the
`httpmw.RequireExperiment(...)` gating from the AI cost control routes.
They keep `RequireFeatureMW(codersdk.FeatureAIBridge)`. Affected
endpoints:
  - `GET /organizations/{organization}/groups/ai/spend`
- `GET
/organizations/{organization}/groups/{groupName}/members/ai/spend`
  - `GET /organizations/{organization}/ai/spend/export`
  - `GET /groups/{group}/members/ai/spend`
  - `GET /groups/{group}/ai/spend`
- `GET/PUT/DELETE /users/{user}/ai/budget/override` and `GET
/users/{user}/ai/spend`
- **`enterprise/coderd/aibridge_test.go`**: drop the experiment from
test setup and remove the now-obsolete `RequiresExperiment`
negative-path tests.
- **Frontend (`site/src/...`)**: remove the `ai-gateway-cost-control`
experiment checks from the cost control UI (Groups pages, user dropdown)
and their stories/mocks. The feature is now driven solely by the
`aibridge` feature visibility.
- **Generated**: regenerated `coderd/apidoc/*`,
`docs/reference/api/schemas.md`, and `site/src/api/typesGenerated.ts`.

## Out of scope

The dogfood `CODER_EXPERIMENTS` config lives in a separate infra repo,
not `coder/coder`. Leaving `ai-gateway-cost-control` there is harmless:
unknown experiment values are logged as `"ignoring unknown experiment"`
at startup and otherwise ignored, so no ordering dependency or breakage.
That cleanup can be a follow-up.

<details>
<summary>Implementation notes</summary>

- Verified how unknown experiments are handled in `coderd/coderd.go`
`ReadExperiments`: unknown values produce a warning log and are inert,
so removing the definition before the dogfood config is updated is safe.
- Noticed the group `ai/budget` routes (`/groups/{group}/ai/budget`)
were already gated only by `FeatureAIBridge`, never by the experiment.
After this change all cost control routes are uniformly feature-gated,
resolving that inconsistency.
- Removed an obsolete `RequiresExperiment` subtest in
`TestUserAISpendStatus` that only asserted a 403 from the experiment
gate; with the gate gone it would no longer be blocked pre-RBAC.

</details>

---

_This PR was created by Coder Agents on behalf of @ssncferreira._
This commit is contained in:
Susana Ferreira
2026-07-29 14:59:58 +01:00
committed by GitHub
parent d6a5c8e9f8
commit 3deecb481e
14 changed files with 14 additions and 207 deletions
-4
View File
@@ -5365,7 +5365,6 @@ const (
ExperimentMinimumImplicitMember Experiment = "minimum-implicit-member" // Allows organizations to deviate from the default organization-member roles, in support of Gateway Accounts.
ExperimentWorkspaceCapableLicensing Experiment = "workspace-capable-licensing" // Counts only users holding the workspace-create permission toward the license seat limit.
ExperimentAIGatewaySeatExclusion Experiment = "ai-gateway-seat-exclusion" // Excludes AI Gateway (AI Bridge) usage from AI Governance seat consumption.
ExperimentAIGatewayCostControl Experiment = "ai-gateway-cost-control" // Enables AI Gateway cost control functionality.
ExperimentChatAdvisor Experiment = "chat-advisor" // Enables the advisor tool for root agent chats.
ExperimentChatVirtualDesktop Experiment = "chat-virtual-desktop" // Enables virtual desktop and computer use provider for agents.
ExperimentAgentLifecycleHooks Experiment = "agent-lifecycle-hooks" // Enables chat lifecycle hook webhooks for agent chats.
@@ -5395,8 +5394,6 @@ func (e Experiment) DisplayName() string {
return "Workspace-Capable Licensing"
case ExperimentAIGatewaySeatExclusion:
return "AI Gateway Seat Exclusion"
case ExperimentAIGatewayCostControl:
return "AI Gateway Cost Control"
case ExperimentChatAdvisor:
return "Chat Advisor"
case ExperimentChatVirtualDesktop:
@@ -5424,7 +5421,6 @@ var ExperimentsKnown = Experiments{
ExperimentMinimumImplicitMember,
ExperimentWorkspaceCapableLicensing,
ExperimentAIGatewaySeatExclusion,
ExperimentAIGatewayCostControl,
ExperimentChatAdvisor,
ExperimentChatVirtualDesktop,
ExperimentAgentLifecycleHooks,