{"record":{"id":"d2cb3c8f4cebbe1d","repo":"affaan-m/ECC","slug":"retrospective-conflicting-identity","errorCode":"retrospective.conflicting_identity","errorMessage":"conflicting snapshots share a capsule identity","messagePattern":"conflicting snapshots share a capsule identity","errorType":"error_code","errorClass":"RetrospectiveError","httpStatus":null,"severity":"error","filePath":"scripts/lib/eval-harness/retrospective.js","lineNumber":79,"sourceCode":" * Different checkpoints of the same identity are ambiguous and refused.\n * Does not read saved projections, copy payloads, write files or invoke tools.\n */\nfunction groupCapsules(dirs) {\n  if (!Array.isArray(dirs) || dirs.length < 1 || dirs.length > MAX_INPUTS\n      || !Array.from(dirs).every(dir => typeof dir === 'string' && dir.trim() && !dir.includes('\\0'))) {\n    throw new RetrospectiveError('retrospective.invalid_inputs', `supply 1 to ${MAX_INPUTS} capsule directory paths`);\n  }\n  const projections = dirs.map(readProjection);\n  const family = projections[0].task_family;\n  const unique = new Map();\n  for (const [index, projection] of projections.entries()) {\n    if (projection.task_family !== family) {\n      throw new RetrospectiveError('retrospective.mixed_task_families', 'all capsules must have the same task family', index);\n    }\n    const key = identity(projection);\n    const previous = unique.get(key);\n    if (previous && previous.projection_hash !== projection.projection_hash) {\n      throw new RetrospectiveError('retrospective.conflicting_identity', 'conflicting snapshots share a capsule identity', index);\n    }\n    unique.set(key, projection);\n  }\n  const byHarness = new Map();\n  for (const projection of unique.values()) {\n    const version = projection.harness_version;\n    byHarness.set(version, [...(byHarness.get(version) || []), projection]);\n  }\n  const report = {\n    schema: 'capsule-retrospective/v1',\n    report_only: true,\n    task_family: family,\n    input_count: dirs.length,\n    capsule_count: unique.size,\n    duplicate_count: dirs.length - unique.size,\n    groups: [...byHarness].sort(([a], [b]) => compare(a, b))\n      .map(([version, items]) => summarizeGroup(version, items)),\n  };","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/eval-harness/retrospective.js#L61-L97","documentation":"Within one task family, each capsule identity (run_id + capsule_id) must be unambiguous: if two supplied capsules share the same identity but have different projection_hash values, they are conflicting snapshots of the same run and grouping them would silently mix inconsistent data. The library refuses at the index of the conflicting capsule. Identical duplicate snapshots (same identity and hash) are allowed and deduplicated.","triggerScenarios":"Passing two different checkpoint snapshots of the same run/capsule (same run_id and capsule_id) whose contents diverged — e.g. capsule-a and capsule-a-rerun where the rerun produced different digests; a snapshot modified after the fact so its projection_hash no longer matches the earlier copy.","commonSituations":"Re-running a task and overwriting/regenerating a capsule with the same ID; including both pre-fix and post-fix snapshots of one run in the same group; sync tools restoring an older divergent copy alongside the new one.","solutions":["Remove the older or conflicting snapshot so only one capsule per run_id/capsule_id remains","Use distinct capsule IDs for separate checkpoints of the same run (the tool intentionally refuses ambiguous same-identity checkpoints)","Regenerate the conflicting capsule if its contents were accidentally modified","Deduplicate identical copies — equal hashes are fine and collapse automatically"],"exampleFix":"// before\nnode scripts/eval-harness.js capsule group ./run-7-snap1 ./run-7-snap2  // same id, different hashes\n// after (keep one snapshot per capsule id)\nnode scripts/eval-harness.js capsule group ./run-7-snap2 ./run-8-snap1","handlingStrategy":"validation","validationCode":"// detect duplicate capsule identities before grouping\nconst seen = new Map();\nfor (const d of dirs) { const id = readCapsuleIdentity(d); if (seen.has(id)) throw new Error(`duplicate capsule identity: ${id}`); seen.set(id, d); }","typeGuard":null,"tryCatchPattern":"try { groupCapsules(dirs); } catch (e) { if (e.code === 'retrospective.conflicting_identity') console.error(`capsule #${e.index} conflicts with an earlier snapshot of the same run; keep one`); throw e; }","preventionTips":["Give each checkpoint of a run a unique capsule id","Never edit a snapshot after recording; regenerate instead","Deduplicate identical copies (same run_id/capsule_id and hash) before grouping","Avoid syncing divergent copies of the same capsule into the input set"],"tags":["capsule","conflict","deduplication"],"backgroundTag":"conflicting-config-options","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}