{"record":{"id":"abca6ae0b4fc779d","repo":"JuliusBrussee/caveman","slug":"caveman-build-qualityretention-must-be-in-0-1","errorCode":null,"errorMessage":"caveman build: qualityRetention must be in (0,1]","messagePattern":"caveman build: qualityRetention must be in \\(0,1\\]","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/agent/src/build.ts","lineNumber":50,"sourceCode":"  const config: BuildConfig = {\n    entry: options.entry,\n    evals: options.evals,\n    efficiency: options.efficiency ?? \"max\",\n    requiredFixturePassRate: options.requiredFixturePassRate ?? 1,\n    qualityRetention: options.qualityRetention ?? 0.98,\n    maxSearchCostUsd: options.maxSearchCostUsd ?? 2,\n    lock: options.lock ?? \"strict\",\n    sandbox: options.sandbox ?? \"required\",\n    ...(options.allowedModels === undefined ? {} : { allowedModels: [...options.allowedModels] }),\n    ...(options.deniedModels === undefined ? {} : { deniedModels: [...options.deniedModels] }),\n    ...(options.maxP95LatencyMs === undefined ? {} : { maxP95LatencyMs: options.maxP95LatencyMs }),\n    ...(options.forbiddenSafetyClasses === undefined ? {} : { forbiddenSafetyClasses: [...options.forbiddenSafetyClasses] }),\n  };\n  if (!(config.requiredFixturePassRate > 0 && config.requiredFixturePassRate <= 1)) {\n    throw new Error(\"caveman build: requiredFixturePassRate must be in (0,1]\");\n  }\n  if (!(config.qualityRetention > 0 && config.qualityRetention <= 1)) {\n    throw new Error(\"caveman build: qualityRetention must be in (0,1]\");\n  }\n  if (!(config.maxSearchCostUsd > 0)) {\n    throw new Error(\"caveman build: maxSearchCostUsd must be positive\");\n  }\n  return Object.freeze(config);\n}\n\nexport interface CavePlan {\n  schema_version: 1;\n  plan_id: string;\n  model: string;\n  reasoning: \"none\" | \"minimal\" | \"low\" | \"medium\" | \"high\";\n  segment_routes: Array<{\n    segment_kind: ContextKind;\n    segment_id?: string;\n    transform_id: string;\n    fallback: \"original\";\n  }>;","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/agent/src/build.ts#L32-L68","documentation":"Thrown by defineBuild when qualityRetention is outside the interval (0, 1]. This is the minimum fraction of baseline quality the optimized build must retain, as verified by evals: 0 means any quality loss is acceptable (defeating the optimizer's contract), values above 1 are impossible, and NaN fails the range check. The default is 0.98.","triggerScenarios":"Passing qualityRetention: 0, a negative number, 1.2, or NaN; computing retention from a ratio whose inputs can be undefined; config values written as percentages (98) instead of fractions (0.98).","commonSituations":"Confusing percentage scale (0–100) with fraction scale (0–1) and passing 98; disabling the quality floor during aggressive optimization experiments; unvalidated numeric env vars.","solutions":["Pass a fraction in (0, 1]: 0.98 (default) tolerates 2% quality loss; 1 demands no measurable loss.","If your config stores percentages, divide by 100 and range-check before calling defineBuild.","Validate the value at config load time with a clear error naming the expected range."],"exampleFix":"// before\ndefineBuild({ entry, evals, qualityRetention: 98 }); // percentage, not fraction\n\n// after\ndefineBuild({ entry, evals, qualityRetention: 0.98 });","handlingStrategy":"validation","validationCode":"function retention(v: number | undefined): number {\n  const r = v ?? 0.98;\n  if (!(r > 0 && r <= 1)) throw new Error(`qualityRetention must be in (0,1], got ${r}`);\n  return r;\n}","typeGuard":"function isUnitInterval(v: unknown): v is number {\n  return typeof v === \"number\" && Number.isFinite(v) && v > 0 && v <= 1;\n}","tryCatchPattern":null,"preventionTips":["The scale is 0–1: write 0.98, not 98.","Validate config-sourced values with a (0,1] range check before calling defineBuild.","Keep retention high (>= 0.9) unless you have evals that prove lower retention is acceptable."],"tags":["build","config","validation","quality","numbers"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}