feat(flags): activation UX - env-wins adaptive virtual-lanes flag + env docs (#9654 Wave 2)

U7: make adaptive virtual admission lanes discoverable + activatable.
- New OMNIROUTE_CHAT_VIRTUAL_LANES feature flag (boolean/runtime/requiresRestart) in featureFlagDefinitions + en.json i18n key.
- lib/admissionVirtualLanes.ts: env-wins resolver (env > DB > default) + boot warm folding a DB-sourced override into the process-global runtime env via reloadAdaptiveAdmissionRuntime(options.env) - no process.env mutation, no open-sse changes. Env still wins; DB toggle gates at next boot.
- GET /api/settings/feature-flags special-cases the flag to report the gate true source (ccDiscoveryAliases precedent); flagPayload helper dedupes the payload shape.
- Wire the warm into instrumentation-node registerNodejs (non-fatal, DB-ready).
- Document the master switch in .env.example + ENVIRONMENT.md with the system-1/system-2 distinction; zero new env-doc-sync drift.
- 11 new tests (resolver precedence + warm); 60/60 across feature-flag suites; typecheck core clean; ESLint + doc gates green.
This commit is contained in:
Brandon Bennett
2026-08-10 08:04:36 -07:00
parent 97d3f9f248
commit c23cf63b12
10 changed files with 460 additions and 36 deletions

View File

@@ -393,6 +393,12 @@ ALLOW_API_KEY_REVEAL=false
# OMNIROUTE_CHAT_VIRTUAL_TTL_MS=60000
# Per-connection virtual admission lanes (#9654): max concurrent sessions (lanes). Default 64.
# OMNIROUTE_CHAT_VIRTUAL_MAX_SESSIONS=64
# Adaptive runtime virtual admission lanes (#9654): master switch for the per-tenant
# adaptive gate (system 2, open-sse/services/admission). NOTE: the TTL/MAX_SESSIONS
# vars above tune the byte-level per-connection lanes (system 1); this switch enables
# the adaptive runtime lanes. Dashboard feature flag of the same name; env wins over
# the dashboard override; restart required. Default: off.
# OMNIROUTE_CHAT_VIRTUAL_LANES=1
# Hard cap (bytes) for a non-streaming upstream response buffered fully into memory
# (#5152). Past this the upstream reader is cancelled and the request fails fast

View File

@@ -1501,9 +1501,11 @@ These settings were introduced after the previous environment-contract snapshot.
| Variable | Default | Source File | Description |
| --- | --- | --- | --- |
| `OMNIROUTE_CHAT_ADMISSION_QUEUE_MS` | `2000` | `src/shared/middleware/chatBodyAdmission.ts` | Maximum wait for a heavyweight chat admission slot before a retryable `503`; a short bounded wait serializes agent bursts instead of an instant `503`. `0` restores immediate rejection. |
<<<<<<< HEAD
| `OMNIROUTE_CHAT_ADMISSION_MAX_QUEUED_BYTES` | `4194304` (4 MB) | `src/shared/middleware/chatBodyAdmission.ts` | Queued-bytes budget for the admission wait: bounds total buffered body bytes parked process-wide so the wait cannot amplify the heap (#4380). Over-budget waits receive a retryable `503` immediately. |
| `OMNIROUTE_CHAT_VIRTUAL_TTL_MS` | `60000` (60 s) | `src/shared/middleware/chatBodyAdmission.ts` | Deprecated no-op since #10110: per-session admission lanes were removed in favor of one process-wide budget. Accepted for configuration compatibility; ignored. |
| `OMNIROUTE_CHAT_VIRTUAL_MAX_SESSIONS` | `64` | `src/shared/middleware/chatBodyAdmission.ts` | Deprecated no-op since #10110: per-session admission lanes were removed in favor of one process-wide budget. Accepted for configuration compatibility; ignored. |
| `OMNIROUTE_CHAT_VIRTUAL_LANES` | `0` (off) | `open-sse/services/admission/runtime.ts` | Adaptive runtime virtual admission lanes (#9654): master switch for the per-tenant adaptive gate (system 2). Distinct from the deprecated per-connection lane vars above (TTL_MS / MAX_SESSIONS, no-ops since #10110). Dashboard feature flag of the same name; the env var wins over the dashboard override; requires restart. |
| `OMNIROUTE_RUNNOW_TIMEOUT_MS` | `30000` | `src/app/api/jobs/[id]/run-now/route.ts` | Bounds how long a run-now call waits for an in-flight job before starting the queued run. |
| `ADOBE_FIREFLY_BROWSER_REFRESH` | enabled | `open-sse/services/adobeFireflySession.ts` | Keeps IMS and browser-risk state fresh through account-scoped Chrome CDP sessions; set `0` to disable. |
| `ADOBE_FIREFLY_SESSION_DISK` | enabled | `open-sse/services/adobeFireflySession.ts` | Persists repaired Adobe sessions under `DATA_DIR`; set `0` for memory-only state. |

View File

@@ -2,7 +2,14 @@ import { NextRequest, NextResponse } from "next/server";
import { z } from "zod";
import { isAuthenticated } from "@/shared/utils/apiAuth";
import { isValidationFailure, validateBody } from "@/shared/validation/helpers";
import { FEATURE_FLAG_DEFINITIONS } from "@/shared/constants/featureFlagDefinitions";
import {
FEATURE_FLAG_DEFINITIONS,
type FeatureFlagDefinition,
} from "@/shared/constants/featureFlagDefinitions";
import {
ADAPTIVE_VIRTUAL_LANES_FLAG_KEY,
resolveAdaptiveVirtualLanesFlag,
} from "@/lib/admissionVirtualLanes";
import {
getFeatureFlagOverrides,
setFeatureFlagOverride,
@@ -20,6 +27,31 @@ function isActive(value: string): boolean {
return ACTIVE_VALUES.has(value);
}
/**
* Standard feature-flag payload shape for GET /api/settings/feature-flags.
* Flags whose gate resolves differently from the generic db-wins-over-env
* order pass their own effectiveValue/source (see the special cases below).
*/
function flagPayload(
definition: FeatureFlagDefinition,
effectiveValue: string,
source: "db" | "env" | "default"
) {
return {
key: definition.key,
label: definition.label,
description: definition.description,
category: definition.category,
type: definition.type,
enumValues: definition.enumValues ?? null,
defaultValue: definition.defaultValue,
effectiveValue,
source,
requiresRestart: definition.requiresRestart,
warningLevel: definition.warningLevel,
};
}
/**
* GET /api/settings/feature-flags
* Returns all feature flags with their effective values and a summary.
@@ -33,41 +65,22 @@ export async function GET(request: NextRequest) {
const resolved = resolveAllFeatureFlags();
const flags = resolved.map(({ key, effectiveValue, source, definition }) => {
// EXPOSE_CC_DISCOVERY_ALIASES resolves with env-wins-over-db precedence
// (see db/ccDiscoveryAliases.ts::getCcAliasGlobalState) — the opposite of
// resolveAllFeatureFlags' generic db-wins-over-env order. Override the
// reported effectiveValue/source with the gate's own resolution so the
// dashboard never shows a source that doesn't match actual gate behavior.
// Flags whose gate resolves with env-wins-over-db precedence (the
// opposite of resolveAllFeatureFlags' generic db-wins-over-env order)
// report the gate's own resolution so the dashboard never shows a source
// that doesn't match actual gate behavior.
if (key === CC_DISCOVERY_ALIASES_FLAG_KEY) {
const gateState = getCcAliasGlobalState();
return {
key,
label: definition.label,
description: definition.description,
category: definition.category,
type: definition.type,
enumValues: definition.enumValues ?? null,
defaultValue: definition.defaultValue,
effectiveValue: gateState.enabled ? "true" : "false",
source: gateState.source,
requiresRestart: definition.requiresRestart,
warningLevel: definition.warningLevel,
};
return flagPayload(definition, gateState.enabled ? "true" : "false", gateState.source);
}
return {
key,
label: definition.label,
description: definition.description,
category: definition.category,
type: definition.type,
enumValues: definition.enumValues ?? null,
defaultValue: definition.defaultValue,
effectiveValue,
source,
requiresRestart: definition.requiresRestart,
warningLevel: definition.warningLevel,
};
// #9654 U7: the adaptive virtual-lanes gate reads env at runtime
// construction — env wins over any DB override, and a DB override gates
// at next boot (see lib/admissionVirtualLanes.ts).
if (key === ADAPTIVE_VIRTUAL_LANES_FLAG_KEY) {
const state = resolveAdaptiveVirtualLanesFlag();
return flagPayload(definition, state.enabled ? "true" : "false", state.source);
}
return flagPayload(definition, effectiveValue, source);
});
const total = flags.length;
@@ -152,10 +165,22 @@ export async function PUT(request: NextRequest) {
const newEffectiveValue = updatedFlag?.effectiveValue ?? definition.defaultValue;
const newSource = updatedFlag?.source ?? "default";
// Env-wins gates resolve with env > DB > default (the opposite of the
// generic db-wins helper above), so report their true resolution here too —
// the response must never tell an operator they enabled a gate that the env
// var still overrides (#9654 U7).
let reportedEffectiveValue = newEffectiveValue;
let reportedSource = newSource;
if (key === ADAPTIVE_VIRTUAL_LANES_FLAG_KEY) {
const state = resolveAdaptiveVirtualLanesFlag();
reportedEffectiveValue = state.enabled ? "true" : "false";
reportedSource = state.source;
}
return NextResponse.json({
key,
effectiveValue: newEffectiveValue,
source: newSource,
effectiveValue: reportedEffectiveValue,
source: reportedSource,
previousValue,
previousSource,
requiresRestart: definition.requiresRestart,

View File

@@ -980,6 +980,7 @@
"featureFlagOmnirouteEmergencyFallbackDescription": "Route budget-exhausted requests to the emergency free fallback provider/model.",
"featureFlagArenaEloSyncEnabledDescription": "Enable periodic Arena AI leaderboard ELO sync for model intelligence rankings.",
"featureFlagExposeCcDiscoveryAliasesDescription": "Advertise claude/&lt;provider&gt;/&lt;model&gt; mirror ids on /v1/models so Claude Code gateway model discovery lists non-Claude models. Warning: doubles catalog entries for all clients when enabled globally.",
"featureFlagChatVirtualLanesEnabledDescription": "Enable per-tenant adaptive virtual admission lanes for provider dispatch (#9654): one tenant's burst no longer 503s another. The OMNIROUTE_CHAT_VIRTUAL_LANES env var wins over this dashboard override; changes take effect at server restart.",
"sidebar": {
"home": "Home",
"dashboard": "Dashboard",

View File

@@ -242,6 +242,33 @@ export async function scanComboModelNameCollisionsAtBoot(): Promise<void> {
}
}
/**
* #9654 U7: fold a dashboard DB toggle for the adaptive virtual-lanes flag into
* the process-global admission runtime's env at boot. Env-wins: no-op when the
* operator's OMNIROUTE_CHAT_VIRTUAL_LANES env var is set (the lazy runtime
* already reads process.env correctly). The runtime reads env only at
* construction, so this must run before the first request touches it — hence
* awaited here, after ensureDbReadyForBoot(). Non-fatal.
*
* Exported (rather than inline in registerNodejs()) so it can be unit tested
* directly without exercising the rest of the startup sequence.
*/
export async function warmAdaptiveVirtualLanesIntoRuntime(): Promise<void> {
try {
const { warmAdaptiveVirtualLanesIntoRuntime: warm } =
await import("@/lib/admissionVirtualLanes");
const materialized = await warm();
if (materialized) {
console.log(
"[STARTUP] Adaptive virtual lanes flag materialized from dashboard override (#9654)"
);
}
} catch (err: unknown) {
const msg = err instanceof Error ? err.message : String(err);
console.warn("[STARTUP] Could not warm adaptive virtual lanes flag (non-fatal):", msg);
}
}
export async function registerNodejs(): Promise<void> {
markServerStarting();
@@ -295,6 +322,7 @@ export async function registerNodejs(): Promise<void> {
}
await scanComboModelNameCollisionsAtBoot();
await warmAdaptiveVirtualLanesIntoRuntime();
const [
{ initGracefulShutdown },

View File

@@ -0,0 +1,91 @@
/**
* Adaptive virtual admission lanes (#9654) — src-side activation surface.
*
* The adaptive gate itself (`open-sse/services/admission/runtime.ts`) reads
* `OMNIROUTE_CHAT_VIRTUAL_LANES` from env at process-global construction. This
* module is the activation layer that lives where the DB is reachable:
*
* - `resolveAdaptiveVirtualLanesFlag` resolves the flag with **env-wins**
* precedence (env > DB override > default) — the OPPOSITE of the generic
* `resolveFeatureFlag` (db-wins), for the same reason as
* `getCcAliasGlobalState`: the runtime gate reads env directly, so the
* dashboard must report the source that matches actual gate behavior.
* - `warmAdaptiveVirtualLanesIntoRuntime` (called from the Node boot path)
* folds a DB-sourced override into the process-global runtime's env at
* construction time, so a dashboard toggle actually gates after restart.
* No-op when env/default — the lazy runtime already reads process.env.
*
* Env truthiness mirrors the runtime read (`runtime.ts`): only `"1"` or
* `"true"` enable; any other set value is explicitly off (and still wins).
*/
import { getFeatureFlagOverride } from "@/lib/db/featureFlags";
export const ADAPTIVE_VIRTUAL_LANES_FLAG_KEY = "OMNIROUTE_CHAT_VIRTUAL_LANES";
export type AdaptiveVirtualLanesFlagState = {
enabled: boolean;
source: "env" | "db" | "default";
};
export type AdaptiveVirtualLanesFlagDeps = {
env?: NodeJS.ProcessEnv;
getOverride?: (key: string) => string | undefined;
};
const ENV_ON = new Set(["1", "true"]);
/**
* Resolve the effective state of the adaptive virtual-lanes flag and where it
* came from. Env wins over the DB override (env-wins), matching the runtime
* gate's own env-only read.
*/
export function resolveAdaptiveVirtualLanesFlag(
deps: AdaptiveVirtualLanesFlagDeps = {}
): AdaptiveVirtualLanesFlagState {
const env = deps.env ?? process.env;
const envValue = env[ADAPTIVE_VIRTUAL_LANES_FLAG_KEY];
if (envValue !== undefined && envValue !== "") {
return { enabled: ENV_ON.has(envValue), source: "env" };
}
const getOverride = deps.getOverride ?? getFeatureFlagOverride;
const dbOverride = getOverride(ADAPTIVE_VIRTUAL_LANES_FLAG_KEY);
if (dbOverride !== undefined) {
const enabled = dbOverride === "true" || dbOverride === "1" || dbOverride === "yes";
return { enabled, source: "db" };
}
return { enabled: false, source: "default" };
}
export type AdaptiveVirtualLanesWarmDeps = {
resolve?: (deps?: AdaptiveVirtualLanesFlagDeps) => AdaptiveVirtualLanesFlagState;
reload?: (options: { env?: NodeJS.ProcessEnv }) => unknown;
};
/**
* Boot warm (#9654 U7): when the DB override is the effective source, fold it
* into the process-global adaptive admission runtime's env so the dashboard
* toggle actually gates — the runtime reads env only at construction, hence
* `requiresRestart: true`. Returns true when it materialized, false when
* env/default already cover the state. Never throws.
*/
export async function warmAdaptiveVirtualLanesIntoRuntime(
deps: AdaptiveVirtualLanesWarmDeps = {}
): Promise<boolean> {
const resolve = deps.resolve ?? resolveAdaptiveVirtualLanesFlag;
const state = resolve();
if (state.source !== "db") return false;
const reload =
deps.reload ??
(await import("@omniroute/open-sse/services/admission/runtime.ts"))
.reloadAdaptiveAdmissionRuntime;
reload({
env: {
...(process.env ?? {}),
[ADAPTIVE_VIRTUAL_LANES_FLAG_KEY]: state.enabled ? "1" : "0",
},
});
return true;
}

View File

@@ -457,6 +457,18 @@ export const FEATURE_FLAG_DEFINITIONS: FeatureFlagDefinition[] = [
requiresRestart: false,
warningLevel: "info",
},
{
key: "OMNIROUTE_CHAT_VIRTUAL_LANES",
label: "Adaptive Virtual Admission Lanes",
description:
"Enable per-tenant adaptive virtual admission lanes for provider dispatch (#9654): one tenant's burst no longer 503s another. The OMNIROUTE_CHAT_VIRTUAL_LANES env var wins over this dashboard override; changes take effect at server restart.",
descriptionI18nKey: "featureFlagChatVirtualLanesEnabledDescription",
category: "runtime",
defaultValue: "false",
type: "boolean",
requiresRestart: true,
warningLevel: "info",
},
{
key: "EXPOSE_FUNCTIONAL_GATEWAY_MIRRORS",
label: "Functional Gateway Mirrors",

View File

@@ -0,0 +1,132 @@
/**
* U7 (#9654 Wave 2): adaptive virtual-lanes feature flag — env-wins resolution
* and boot warm.
*
* Contract under test:
* - resolveAdaptiveVirtualLanesFlag: env (`"1"`|`"true"`) > DB override >
* default(false); env wins even when set to an explicit "off" value.
* - warmAdaptiveVirtualLanesIntoRuntime: only a DB-sourced state folds into
* the runtime env (`"1"`/`"0"`); env/default sources are no-ops.
*
* Run: bun test tests/unit/admission-virtual-lanes-flag.test.ts
*/
import assert from "node:assert/strict";
import { describe, it } from "node:test";
import {
ADAPTIVE_VIRTUAL_LANES_FLAG_KEY,
resolveAdaptiveVirtualLanesFlag,
warmAdaptiveVirtualLanesIntoRuntime,
} from "../../src/lib/admissionVirtualLanes.ts";
const emptyEnv = {};
const noOverride = (): string | undefined => undefined;
describe("resolveAdaptiveVirtualLanesFlag", () => {
it('env "1" enables and reports env, winning over a DB override', () => {
const state = resolveAdaptiveVirtualLanesFlag({
env: { [ADAPTIVE_VIRTUAL_LANES_FLAG_KEY]: "1" },
getOverride: () => "false",
});
assert.deepEqual(state, { enabled: true, source: "env" });
});
it('env "true" enables (runtime-compatible truthiness)', () => {
const state = resolveAdaptiveVirtualLanesFlag({
env: { [ADAPTIVE_VIRTUAL_LANES_FLAG_KEY]: "true" },
getOverride: noOverride,
});
assert.deepEqual(state, { enabled: true, source: "env" });
});
it('env "0" is an explicit off that still wins over the DB', () => {
const state = resolveAdaptiveVirtualLanesFlag({
env: { [ADAPTIVE_VIRTUAL_LANES_FLAG_KEY]: "0" },
getOverride: () => "true",
});
assert.deepEqual(state, { enabled: false, source: "env" });
});
it("DB override enables when env is absent", () => {
const state = resolveAdaptiveVirtualLanesFlag({
env: emptyEnv,
getOverride: () => "true",
});
assert.deepEqual(state, { enabled: true, source: "db" });
});
it('DB override "1" enables when env is absent', () => {
const state = resolveAdaptiveVirtualLanesFlag({
env: emptyEnv,
getOverride: () => "1",
});
assert.deepEqual(state, { enabled: true, source: "db" });
});
it("DB override disables when env is absent", () => {
const state = resolveAdaptiveVirtualLanesFlag({
env: emptyEnv,
getOverride: () => "false",
});
assert.deepEqual(state, { enabled: false, source: "db" });
});
it("defaults to disabled when neither env nor DB is set", () => {
const state = resolveAdaptiveVirtualLanesFlag({
env: emptyEnv,
getOverride: noOverride,
});
assert.deepEqual(state, { enabled: false, source: "default" });
});
});
describe("warmAdaptiveVirtualLanesIntoRuntime", () => {
it('folds a DB-sourced enable into the runtime env as "1"', async () => {
let reloaded = false;
let foldedEnv: NodeJS.ProcessEnv | undefined;
const materialized = await warmAdaptiveVirtualLanesIntoRuntime({
resolve: () => ({ enabled: true, source: "db" }),
reload: (options) => {
reloaded = true;
foldedEnv = options.env;
},
});
assert.equal(materialized, true);
assert.equal(reloaded, true, "must reload the runtime when the DB is the source");
assert.equal(foldedEnv?.[ADAPTIVE_VIRTUAL_LANES_FLAG_KEY], "1");
});
it('folds a DB-sourced disable into the runtime env as "0"', async () => {
let foldedEnv: NodeJS.ProcessEnv | undefined;
const materialized = await warmAdaptiveVirtualLanesIntoRuntime({
resolve: () => ({ enabled: false, source: "db" }),
reload: (options) => {
foldedEnv = options.env;
},
});
assert.equal(materialized, true);
assert.equal(foldedEnv?.[ADAPTIVE_VIRTUAL_LANES_FLAG_KEY], "0");
});
it("no-op when the source is env (operator env wins, nothing to fold)", async () => {
const materialized = await warmAdaptiveVirtualLanesIntoRuntime({
resolve: () => ({ enabled: true, source: "env" }),
reload: () => {
throw new Error("must not reload when env is the source");
},
});
assert.equal(materialized, false);
});
it("no-op when the source is default", async () => {
const materialized = await warmAdaptiveVirtualLanesIntoRuntime({
resolve: () => ({ enabled: false, source: "default" }),
reload: () => {
throw new Error("must not reload when the default applies");
},
});
assert.equal(materialized, false);
});
});

View File

@@ -0,0 +1,127 @@
/**
* U7 (#9654 Wave 2) — route-level acceptance for the adaptive virtual-lanes flag.
*
* Ticket acceptance: "flag appears in GET /api/settings/feature-flags; env
* still wins." Exercises the GET + PUT handlers directly (JWT cookie auth),
* asserting the env-wins source reporting and the requiresRestart surface.
*
* Run: bun test tests/unit/feature-flags-route-virtual-lanes.test.ts
*/
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import test, { after, before } from "node:test";
import { SignJWT } from "jose";
const TEST_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-ff-vl-route-"));
process.env.DATA_DIR = TEST_DATA_DIR;
const { GET, PUT } = await import("../../src/app/api/settings/feature-flags/route.ts");
const { removeFeatureFlagOverride, setFeatureFlagOverride } =
await import("../../src/lib/db/featureFlags");
const { ADAPTIVE_VIRTUAL_LANES_FLAG_KEY } = await import("../../src/lib/admissionVirtualLanes.ts");
const ORIGINAL_ENV_VALUE = process.env[ADAPTIVE_VIRTUAL_LANES_FLAG_KEY];
type FlagPayload = {
key: string;
label: string;
type: string;
defaultValue: string;
effectiveValue: string;
source: string;
requiresRestart: boolean;
};
async function authCookie(): Promise<string> {
process.env.JWT_SECRET = "test-feature-flags-route-secret";
const secret = new TextEncoder().encode(process.env.JWT_SECRET);
const token = await new SignJWT({ sub: "test-user" })
.setProtectedHeader({ alg: "HS256" })
.setIssuedAt()
.setExpirationTime("1h")
.sign(secret);
return `auth_token=${token}`;
}
async function buildGetRequest(): Promise<Request> {
const cookie = await authCookie();
return new Request("http://localhost/api/settings/feature-flags", {
headers: { cookie },
});
}
async function buildPutRequest(value: string): Promise<Request> {
const cookie = await authCookie();
return new Request("http://localhost/api/settings/feature-flags", {
method: "PUT",
headers: { cookie, "Content-Type": "application/json" },
body: JSON.stringify({ key: ADAPTIVE_VIRTUAL_LANES_FLAG_KEY, value }),
});
}
async function getFlag(): Promise<FlagPayload> {
const res = await GET(await buildGetRequest());
assert.equal(res.status, 200);
const json = (await res.json()) as { flags: FlagPayload[] };
const flag = json.flags.find((f) => f.key === ADAPTIVE_VIRTUAL_LANES_FLAG_KEY);
assert.ok(flag, `flag ${ADAPTIVE_VIRTUAL_LANES_FLAG_KEY} must appear in GET`);
return flag;
}
before(() => {
removeFeatureFlagOverride(ADAPTIVE_VIRTUAL_LANES_FLAG_KEY);
});
after(() => {
if (ORIGINAL_ENV_VALUE === undefined) {
delete process.env[ADAPTIVE_VIRTUAL_LANES_FLAG_KEY];
} else {
process.env[ADAPTIVE_VIRTUAL_LANES_FLAG_KEY] = ORIGINAL_ENV_VALUE;
}
removeFeatureFlagOverride(ADAPTIVE_VIRTUAL_LANES_FLAG_KEY);
});
test("flag appears in GET with the requiresRestart boolean surface (default off)", async () => {
delete process.env[ADAPTIVE_VIRTUAL_LANES_FLAG_KEY];
const flag = await getFlag();
assert.equal(flag.type, "boolean");
assert.equal(flag.defaultValue, "false");
assert.equal(flag.requiresRestart, true, "runtime reads env at construction — restart required");
assert.equal(flag.effectiveValue, "false");
assert.equal(flag.source, "default");
});
test('env wins over a DB override in GET (env "1" + DB false -> env)', async () => {
process.env[ADAPTIVE_VIRTUAL_LANES_FLAG_KEY] = "1";
setFeatureFlagOverride(ADAPTIVE_VIRTUAL_LANES_FLAG_KEY, "false");
const flag = await getFlag();
assert.equal(flag.effectiveValue, "true");
assert.equal(flag.source, "env");
});
test('env explicit off still wins in GET (env "0" + DB true -> env off)', async () => {
process.env[ADAPTIVE_VIRTUAL_LANES_FLAG_KEY] = "0";
setFeatureFlagOverride(ADAPTIVE_VIRTUAL_LANES_FLAG_KEY, "true");
const flag = await getFlag();
assert.equal(flag.effectiveValue, "false");
assert.equal(flag.source, "env");
});
test("DB override enables when env is absent (source db)", async () => {
delete process.env[ADAPTIVE_VIRTUAL_LANES_FLAG_KEY];
setFeatureFlagOverride(ADAPTIVE_VIRTUAL_LANES_FLAG_KEY, "true");
const flag = await getFlag();
assert.equal(flag.effectiveValue, "true");
assert.equal(flag.source, "db");
});
test("PUT response reports env-wins truth when env is set (operator toggle cannot lie)", async () => {
process.env[ADAPTIVE_VIRTUAL_LANES_FLAG_KEY] = "0";
const res = await PUT(await buildPutRequest("true"));
assert.equal(res.status, 200);
const json = (await res.json()) as { effectiveValue: string; source: string };
assert.equal(json.effectiveValue, "false", 'env "0" must still win over a dashboard PUT "true"');
assert.equal(json.source, "env");
});

View File

@@ -36,7 +36,7 @@ const EXPECTED_FEATURE_FLAG_COUNT = 48;
// Test group 1 — Flag definitions registry
// ──────────────────────────────────────────────────────
describe("featureFlagDefinitions", () => {
it("has exactly 47 flag definitions", () => {
it("has exactly 48 flag definitions", () => {
assert.strictEqual(FEATURE_FLAG_DEFINITIONS.length, EXPECTED_FEATURE_FLAG_COUNT);
});