40 lines
1.5 KiB
TypeScript
40 lines
1.5 KiB
TypeScript
import { createHash } from "node:crypto";
|
|
import { rectificationDeploymentModeSchema, type RectificationDeploymentMode } from "../rectification-v4/contracts.ts";
|
|
|
|
type RectificationFeatureEnv = Readonly<{
|
|
RECTIFICATION_AGENT_V5_ENABLED?: string;
|
|
RECTIFICATION_AGENT_V5_SHADOW?: string;
|
|
RECTIFICATION_AGENT_V5_CANARY_PERCENT?: string;
|
|
}>;
|
|
|
|
function enabled(value: string | undefined): boolean {
|
|
return /^(1|true|yes|on)$/i.test(value?.trim() ?? "");
|
|
}
|
|
|
|
function percentage(value: string | undefined): number {
|
|
if (!value?.trim()) return 100;
|
|
const parsed = Number(value);
|
|
if (!Number.isFinite(parsed)) return 0;
|
|
return Math.max(0, Math.min(100, parsed));
|
|
}
|
|
|
|
export function rectificationCanaryBucket(stableId: string): number {
|
|
const prefix = createHash("sha256").update(stableId).digest().readUInt32BE(0);
|
|
return prefix / 0x1_0000_0000 * 100;
|
|
}
|
|
|
|
export function selectRectificationDeploymentMode(
|
|
stableId: string,
|
|
env: RectificationFeatureEnv = {
|
|
RECTIFICATION_AGENT_V5_ENABLED: process.env.RECTIFICATION_AGENT_V5_ENABLED,
|
|
RECTIFICATION_AGENT_V5_SHADOW: process.env.RECTIFICATION_AGENT_V5_SHADOW,
|
|
RECTIFICATION_AGENT_V5_CANARY_PERCENT: process.env.RECTIFICATION_AGENT_V5_CANARY_PERCENT,
|
|
},
|
|
): RectificationDeploymentMode {
|
|
if (!enabled(env.RECTIFICATION_AGENT_V5_ENABLED)) return "v4_legacy";
|
|
if (rectificationCanaryBucket(stableId) >= percentage(env.RECTIFICATION_AGENT_V5_CANARY_PERCENT)) return "v4_legacy";
|
|
return rectificationDeploymentModeSchema.parse(
|
|
enabled(env.RECTIFICATION_AGENT_V5_SHADOW) ? "v5_shadow" : "v5_agent",
|
|
);
|
|
}
|