{"record":{"id":"d37b01bdafd0057c","repo":"affaan-m/ECC","slug":"retrospective-mixed-task-families","errorCode":"retrospective.mixed_task_families","errorMessage":"all capsules must have the same task family","messagePattern":"all capsules must have the same task family","errorType":"error_code","errorClass":"RetrospectiveError","httpStatus":null,"severity":"error","filePath":"scripts/lib/eval-harness/retrospective.js","lineNumber":74,"sourceCode":"}\n\n/**\n * Group up to 100 selected snapshots of one task family by harness_version.\n * Duplicate identities count once only if the verified projections match.\n * 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,","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/eval-harness/retrospective.js#L56-L92","documentation":"A retrospective can only group capsules from one task family, since the report aggregates runs of comparable tasks. After reading projections, groupCapsules takes the first capsule's task_family and requires every other capsule to match; the first mismatched input (by index) triggers this error. This prevents statistically meaningless comparisons across unrelated task families.","triggerScenarios":"Calling groupCapsules with directories whose capsules were produced for different task families, e.g. mixing 'fix-bug' family capsules with 'add-feature' family capsules; passing capsules from differently named task families after a rename.","commonSituations":"Aggregating snapshots across repos or task types; a task_family label change in the harness between snapshot generations; copy-pasting a capsule group command that still references directories from a previous, different-family experiment.","solutions":["Group only capsules that share the same task_family; run a separate retrospective per family","Regenerate the mismatched capsules with the correct task family label","Check each capsule's projection task_family before grouping","If the family was renamed, re-label or re-record old capsules so families align"],"exampleFix":"// before\nnode scripts/eval-harness.js capsule group ./caps-fix-1 ./caps-feature-1  // mixed families\n// after\nnode scripts/eval-harness.js capsule group ./caps-fix-1 ./caps-fix-2      // one family per run","handlingStrategy":"validation","validationCode":"// read task_family from each capsule's projection metadata before grouping\nconst families = new Set(dirs.map(d => readCapsuleFamily(d)));\nif (families.size > 1) throw new Error(`mixed task families: ${[...families].join(', ')}`);","typeGuard":null,"tryCatchPattern":"try { groupCapsules(dirs); } catch (e) { if (e.code === 'retrospective.mixed_task_families') console.error(`capsule #${e.index} is from a different task family; group per family`); throw e; }","preventionTips":["Keep one retrospective per task family","Verify task_family labels when adopting capsules from other repos or harness versions","Rename directories or re-record capsules after a task_family rename","Group capsules by family programmatically before calling groupCapsules"],"tags":["capsule","task-family","retrospective"],"backgroundTag":"incompatible-source-type","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"}