"""Local routing around a recorded Rice predictor; no cloud deployment.""" import copy import hashlib import threading from http.server import BaseHTTPRequestHandler, HTTPServer from pathlib import Path from predictor import decode, encode, digest, validate, predict, CONTRACT HERE=Path(__file__).resolve().parent SALT='rice-canary-fixture-v1' def selected(data, expected, contract=CONTRACT): if digest(data)!=expected:raise ValueError('selected model digest mismatch') bundle=validate(decode(data)) if bundle['contract']!=contract:raise ValueError('serving feature contract incompatible') return {'bundle':bundle,'version':expected} def bundles(): raw=(HERE/'baseline-model.json').read_bytes();live=selected(raw,digest(raw)) altered=copy.deepcopy(live['bundle']);altered['bias']+=1.0 # Deliberate parameter fixture, not an independently trained candidate. altered['fixture_variant']='recorded baseline bias plus 1.0; no training' raw=encode(altered) return live,selected(raw,digest(raw)) def identity(value): if not isinstance(value,str) or not 1<=len(value)<=80:raise ValueError('bounded nonempty identity required') return value def cohort(user, basis_points=2000): identity(user) if type(basis_points) is not int or not 0<=basis_points<=10000:raise ValueError('invalid canary allocation') bucket=int.from_bytes(hashlib.sha256((SALT+':'+user).encode()).digest()[:8],'big')%10000 return 'canary' if bucket