{"record":{"id":"f7f8fb88e84cfb16","repo":"JuliusBrussee/caveman","slug":"where-change-set-or-eval-pack-is-bound-to-anoth","errorCode":null,"errorMessage":"${where} change set or eval pack is bound to another case","messagePattern":"(.+?) change set or eval pack is bound to another case","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/shared/contracts/scripts/validate-continuous-improvement.mjs","lineNumber":222,"sourceCode":"      }\n    }\n    const upstream = new Set(item.diagnosis.root_cause_hypothesis.upstream_node_ids);\n    for (const nodeID of upstream) {\n      if (!slice.node_chain.includes(nodeID) || nodeID === slice.manifestation_node_id) {\n        throw new Error(`${where} diagnosis upstream node ${nodeID} is not an upstream node of its causal slice`);\n      }\n    }\n\n    // A case that proposes nothing must carry nothing: no operator, no eval\n    // pack, no replay. Anything else would present an abstention as a proposal.\n    if (item.status === \"diagnosis_only\") {\n      if (item.change_set.operator_id !== \"\" || item.eval_pack.id !== \"\" || item.replay.status !== \"not_run\") {\n        throw new Error(`${where} is diagnosis-only but carries a change set, eval pack or replay`);\n      }\n      continue;\n    }\n    if (item.change_set.case_id !== item.id || item.eval_pack.case_id !== item.id) {\n      throw new Error(`${where} change set or eval pack is bound to another case`);\n    }\n\n    // The case must investigate the pair its own opportunity named. A cohort\n    // built from a differently-derived pair would describe one comparison and\n    // measure another.\n    const source = report.opportunities.find((opportunity) => opportunity.id === item.opportunity_id);\n    if (!source) throw new Error(`${where} names an opportunity that is not in this report`);\n    if (armVariants.get(\"baseline\").id !== source.current_variant_id || armVariants.get(\"alternative\").id !== source.alternative_variant_id) {\n      throw new Error(`${where} cohort arms (${armVariants.get(\"baseline\").id}/${armVariants.get(\"alternative\").id}) are not the variants opportunity ${source.id} named`);\n    }\n\n    // Every required grader is one the recorded interpreter actually computes.\n    // `json_schema` is deliberately absent: over a typed interpreter result it\n    // could only assert that a hash is non-empty, which is a grader that cannot\n    // fail and therefore inflates how much a replay was checked.\n    const knownGraders = new Set([\"exact_match\", \"tool_order\", \"tool_count\", \"guard_respected\"]);\n    for (const grader of item.eval_pack.graders) {\n      if (!knownGraders.has(grader)) throw new Error(`${where} requires grader ${grader}, which the recorded interpreter does not compute`);","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/shared/contracts/scripts/validate-continuous-improvement.mjs#L204-L240","documentation":"Thrown when change_set.case_id or eval_pack.case_id differs from the enclosing case's id. Every change set and eval pack is private to exactly one case; a mismatched binding means the artifacts were copied from another case and would attribute one case's proposal/evaluation to another.","triggerScenarios":"Cloning a case (including its change_set and eval_pack) to create a new case with a new id without updating the nested case_id fields.","commonSituations":"Duplicating cases in the report fixture to grow the corpus; splitting one case into two; renaming case ids during a refactor.","solutions":["Set item.change_set.case_id and item.eval_pack.case_id to the enclosing case's item.id.","Prefer generating new cases programmatically over copy-paste so nested ids are always rewritten.","Re-run the validator to catch any other nested ids that still reference the old case."],"exampleFix":"// before\ncase id: \"case-9\"\nchange_set: {case_id: \"case-8\", ...}\neval_pack: {case_id: \"case-9\", ...}\n\n// after\nchange_set: {case_id: \"case-9\", ...}\neval_pack: {case_id: \"case-9\", ...}","handlingStrategy":"validation","validationCode":"const bound = item.change_set.case_id === item.id && item.eval_pack.case_id === item.id;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always create change_set and eval_pack with the parent case id passed in, never by literal.","Add an id-rewrite step to any case-cloning utility so nested case_id fields are updated automatically."],"tags":["validation","referential-integrity","data-integrity"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}