/* RFC-1031: Canary traffic router — deterministic hash-based routing using Sha256Digest of canonical JSON input bytes (RFC-0849). Does not execute components — only makes routing decisions. Does not monitor health — that is the health monitor's job. RFC-1031: initial implementation — deterministic canary routing via Sha256Digest. */ import { byteHash } from "@warpgogol/werkstatt-shared/fingerprint"; import type { Sha256Digest } from "@warpgogol/werkstatt-shared/fingerprint"; const HASH_PREFIX_LENGTH = "sha256:".length; const ROUTING_HASH_HEX_CHARS = 12; const ROUTING_MODULUS = 100; export interface CanaryRouter { routeToCandidate(input: unknown, trafficPercent: number): boolean; getRoutingHash(input: unknown): Sha256Digest; } export function createCanaryRouter(): CanaryRouter { return { routeToCandidate(input: unknown, trafficPercent: number): boolean { if (trafficPercent <= 0) return false; if (trafficPercent >= 100) return true; const hash = this.getRoutingHash(input); const hashNum = parseInt( hash.slice(HASH_PREFIX_LENGTH, HASH_PREFIX_LENGTH + ROUTING_HASH_HEX_CHARS), 16, ); return hashNum % ROUTING_MODULUS < trafficPercent; }, getRoutingHash(input: unknown): Sha256Digest { const canonicalBytes = JSON.stringify(input); return byteHash(canonicalBytes) as Sha256Digest; }, }; }