{"record":{"id":"f44849b3fc2d95a9","repo":"affaan-m/ECC","slug":"genre-references-collapsed-into-a-generic-style-distinct","errorCode":null,"errorMessage":"genre references collapsed into a generic style; distinct specs required","messagePattern":"genre references collapsed into a generic style; distinct specs required","errorType":"validation","errorClass":"ContractError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/contract.py","lineNumber":128,"sourceCode":"                    raise ContractError(f\"output bundle contains a symlink: {entry.path}\")\n                if entry.is_dir(follow_symlinks=False):\n                    pending.append(Path(entry.path))\n                elif not entry.is_file(follow_symlinks=False):\n                    raise ContractError(f\"output bundle contains a special file: {entry.path}\")\n\n\ndef validate_genre_specs(specs: list[dict[str, Any]]) -> None:\n    \"\"\"Require complete, semantically distinct numbered genre specs.\"\"\"\n    if not specs:\n        raise ContractError(\"at least one genre spec is required\")\n    numbers = [spec.get(\"number\") for spec in specs]\n    if len(numbers) != len(set(numbers)):\n        raise ContractError(\"genre numbers must be distinct\")\n\n    fingerprints = [spec.get(\"style_fingerprint\") for spec in specs]\n    signatures = [_semantic_signature(spec) for spec in specs]\n    if len(fingerprints) != len(set(fingerprints)) or len(signatures) != len(set(signatures)):\n        raise ContractError(\"genre references collapsed into a generic style; distinct specs required\")\n\n    for spec in specs:\n        if spec.get(\"dry_run\") is not True:\n            raise ContractError(f\"genre {spec.get('number')} crosses the dry-run boundary\")\n        measured = spec.get(\"measured_features\")\n        if measured is not None:\n            if not isinstance(measured, dict):\n                raise ContractError(f\"genre {spec.get('number')} has invalid measured evidence\")\n            _validate_numeric_evidence(measured, label=f\"genre {spec.get('number')} evidence\")\n            total_duration = measured.get(\"total_duration\")\n            if not _is_finite_real(total_duration):\n                raise ContractError(f\"genre {spec.get('number')} has invalid total duration\")\n            total_duration = cast(float, total_duration)\n            if float(total_duration) <= 0:\n                raise ContractError(f\"genre {spec.get('number')} has invalid total duration\")\n            for group_name in (\"sample_times\",):\n                groups = measured.get(group_name, [])\n                if not isinstance(groups, list):","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/contract.py#L110-L146","documentation":"validate_genre_specs enforces that every genre spec in a bundle carries a genuinely distinct style reference. It collects each spec's style_fingerprint and computed _semantic_signature and raises this ContractError when two or more specs share the same fingerprint or semantic signature, meaning the genre references have collapsed into one generic style. The library throws this to prevent bundles that silently reference the same aesthetic under multiple genre numbers.","triggerScenarios":"Calling validate_genre_specs (directly or via validate_bundle) with a list of specs where at least two specs have identical style_fingerprint values, or whose _semantic_signature hashes are equal (e.g. duplicated spec dicts, copy-pasted specs, or signatures collapsed to identical defaults).","commonSituations":"Copy-pasting a spec and only changing its genre number but not the style fingerprint; programmatically generating specs from a template without varying the fingerprint; a preprocessing step that normalizes/strips style fields so all specs hash the same; tests like test_collapsing_references_into_one_generic_style_is_rejected exercise exactly this rejection.","solutions":["Give each spec a unique style_fingerprint that genuinely reflects its source material.","If two specs are truly the same style, merge them into one genre spec instead of duplicating.","Check any code that builds specs for shared/copied dicts (e.g. dict(spec) shallow copies reusing the same nested style data) and vary the style inputs.","Log the fingerprints/signatures per spec before validating to find which specs collide."],"exampleFix":"// before\nspecs = [\n    {\"number\": 1, \"style_fingerprint\": \"abc123\", ...},\n    {\"number\": 2, \"style_fingerprint\": \"abc123\", ...},\n]\n// after\nspecs = [\n    {\"number\": 1, \"style_fingerprint\": \"fingerprint-jazz-abc123\", ...},\n    {\"number\": 2, \"style_fingerprint\": \"fingerprint-lofi-def456\", ...},\n]","handlingStrategy":"validation","validationCode":"def specs_are_distinct(specs):\n    fps = [s.get(\"style_fingerprint\") for s in specs]\n    if len(fps) != len(set(fps)):\n        return False\n    sigs = [repr(sorted(s.get(\"signature\", {}).items())) for s in specs]\n    return len(sigs) == len(set(sigs))","typeGuard":"def is_unique_fingerprints(specs: list[dict]) -> bool:\n    fps = [s.get(\"style_fingerprint\") for s in specs]\n    return len(fps) == len(set(fps))","tryCatchPattern":"try:\n    validate_genre_specs(specs)\nexcept ContractError as e:\n    if \"collapsed into a generic style\" in str(e):\n        for s in specs:\n            print(s.get(\"number\"), s.get(\"style_fingerprint\"))\n    raise","preventionTips":["Generate fingerprints from distinct source material per genre.","Never duplicate a spec dict and only change its number.","Log fingerprints per spec before bundle validation.","Deduplicate specs programmatically before validation."],"tags":["validation","duplicate-data","contract"],"backgroundTag":"schema-validation-failed","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"}