{"record":{"id":"01835491d8dcae4f","repo":"JuliusBrussee/caveman","slug":"at-is-a-generated-case-whose-id-does-not-name-i","errorCode":null,"errorMessage":"${at} is a generated case whose id does not name its generator and source unit","messagePattern":"(.+?) is a generated case whose id does not name its generator and source unit","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/shared/contracts/scripts/validate-continuous-improvement.mjs","lineNumber":270,"sourceCode":"      [\"adversarial_stale_input.v1\", \"stale_input\"],\n    ]);\n    const roleCounts = { target_failure: 0, prior_success: 0, boundary: 0, adversarial: 0 };\n    const recordedSources = new Set();\n    const datasetCaseIDs = new Set();\n    for (const entry of dataset.cases) {\n      const at = `${where} dataset case ${entry.id}`;\n      if (datasetCaseIDs.has(entry.id)) throw new Error(`${at} appears twice in the dataset`);\n      datasetCaseIDs.add(entry.id);\n      if (!unitsByID.has(entry.source_unit_id)) throw new Error(`${at} names source unit ${entry.source_unit_id} that is not an analysis unit of this report`);\n      if (!familyUnits.has(entry.source_unit_id)) throw new Error(`${at} names source unit ${entry.source_unit_id} that is not a member of task family ${family.id}`);\n      if (generatorPerturbation.get(entry.generator) !== entry.perturbation) {\n        throw new Error(`${at} generator ${entry.generator} disagrees with perturbation ${entry.perturbation}`);\n      }\n      if (entry.perturbation === \"none\" && entry.id !== entry.source_unit_id) {\n        throw new Error(`${at} replays a recorded flow but is not identified by its source unit`);\n      }\n      if (entry.perturbation !== \"none\" && entry.id !== `${entry.generator}:${entry.source_unit_id}`) {\n        throw new Error(`${at} is a generated case whose id does not name its generator and source unit`);\n      }\n      roleCounts[entry.role] += 1;\n      if (entry.role === \"target_failure\" || entry.role === \"prior_success\") recordedSources.add(entry.source_unit_id);\n    }\n    for (const entry of dataset.cases) {\n      // Leakage: a generated case must not perturb a unit the manifest already\n      // replays unperturbed.\n      if (entry.perturbation !== \"none\" && recordedSources.has(entry.source_unit_id)) {\n        throw new Error(`${where} generated case ${entry.id} perturbs a unit the dataset already replays unperturbed`);\n      }\n    }\n\n    // Manifest composition arithmetic (spec 18.2): target-failure + prior-success\n    // + one boundary + up to two adversarial, each capped and each recomputable.\n    //\n    // The boundary and stale-input generators perturb the localization evidence\n    // a confidence guard reads. A ChangeSet whose applicability never reads that\n    // evidence has no threshold to sit beside, so those two cases must NOT be","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/shared/contracts/scripts/validate-continuous-improvement.mjs#L252-L288","documentation":"Thrown when a generated case (perturbation != \"none\") has an id that is not exactly `${generator}:${source_unit_id}`. Generated-case ids must name their generator and source unit so provenance is recomputable from the id alone.","triggerScenarios":"Inventing a friendly id (\"edge-case-3\") for a generated case; changing the generator field without updating the id; omitting the \":\" or reordering the two components.","commonSituations":"Hand-authoring adversarial cases; renaming generators during a version bump without rewriting ids.","solutions":["Rewrite the id as `${entry.generator}:${entry.source_unit_id}` exactly (generator string first, colon, unit id).","After fixing, check for the leakage rule: the same source unit must not also appear as an unperturbed recorded case.","Keep ids machine-generated by the composer to avoid drift."],"exampleFix":"// before\n{id: \"edge-case-3\", generator: \"adversarial_stale_input.v1\", source_unit_id: \"unit-07\", perturbation: \"stale_input\"}\n\n// after\n{id: \"adversarial_stale_input.v1:unit-07\", generator: \"adversarial_stale_input.v1\", source_unit_id: \"unit-07\", perturbation: \"stale_input\"}","handlingStrategy":"validation","validationCode":"const generatedIdsOk = dataset.cases\n  .filter((c) => c.perturbation !== \"none\")\n  .every((c) => c.id === `${c.generator}:${c.source_unit_id}`);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive generated-case ids with a template literal at composition time.","Treat any hand-written dataset case id as a smell — regenerate instead."],"tags":["validation","dataset","naming-convention"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}