{"record":{"id":"d241b521250c59fe","repo":"affaan-m/ECC","slug":"artifact-relative-cites-an-unknown-provenance-source","errorCode":null,"errorMessage":"artifact {relative} cites an unknown provenance source","messagePattern":"artifact (.+?) cites an unknown provenance source","errorType":"validation","errorClass":"ContractError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/tasteforge/contract.py","lineNumber":416,"sourceCode":"        modalities = entry.get(\"modalities\")\n        if (not isinstance(modalities, list)\n                or any(modality not in _REQUIRED_MODALITIES for modality in modalities)):\n            raise ContractError(f\"artifact {relative} has invalid modality binding\")\n        if entry.get(\"bytes\") != path.stat().st_size:\n            raise ContractError(f\"artifact {relative} byte size does not match receipt\")\n        if entry.get(\"sha256\") != _sha256(path):\n            raise ContractError(f\"artifact {relative} SHA-256 does not match receipt\")\n        provenance = entry.get(\"provenance\")\n        if not isinstance(provenance, list) or not provenance:\n            raise ContractError(f\"artifact {relative} lacks exact reference/time provenance\")\n        for source in provenance:\n            if not isinstance(source.get(\"reference_path\"), str) or not source[\"reference_path\"]:\n                raise ContractError(f\"artifact {relative} has invalid reference path\")\n            digest = source.get(\"reference_sha256\")\n            if not isinstance(digest, str) or len(digest) != 64:\n                raise ContractError(f\"artifact {relative} has invalid reference SHA-256\")\n            if (source[\"reference_path\"], digest) not in known_sources:\n                raise ContractError(f\"artifact {relative} cites an unknown provenance source\")\n            times = source.get(\"reference_times\")\n            basis = source.get(\"time_basis\")\n            if not isinstance(times, list) or basis not in {\"media_seconds\", \"whole_file\"}:\n                raise ContractError(f\"artifact {relative} has invalid reference/time provenance\")\n            if basis == \"media_seconds\" and not times:\n                raise ContractError(f\"artifact {relative} lacks media reference times\")\n            if basis == \"whole_file\" and times:\n                raise ContractError(f\"artifact {relative} whole-file provenance must not invent times\")\n            if basis == \"media_seconds\":\n                expected_duration = source_durations.get((source[\"reference_path\"], digest))\n                if expected_duration is None or source.get(\"source_duration\") != expected_duration:\n                    raise ContractError(f\"artifact {relative} has an unbound source duration\")\n                for time in times:\n                    _validate_media_time(\n                        time, expected_duration,\n                        label=f\"artifact {relative} media reference time\",\n                    )\n","sourceCodeStart":398,"sourceCodeEnd":434,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/tasteforge/contract.py#L398-L434","documentation":"After validating the format of each provenance source, the validator checks that the (reference_path, reference_sha256) pair exists in the bundle's known_sources set — the registry of reference files the receipt declared. This error means the artifact cites a source that is not registered, so its provenance cannot be traced to a verified reference.","triggerScenarios":"validate_artifact_receipt finding a source tuple absent from known_sources — citing a reference file that was never declared to validate_bundle, a renamed/moved reference, a stale digest after the reference file changed, or a typo in the reference path.","commonSituations":"Editing the reference file after generating the receipt (digest changed), renaming reference directories, declaring provenance to a reference that was dropped from the bundle manifest, mixing receipts across bundles.","solutions":["Update the receipt's reference_sha256 to the current digest of the actual reference file","Register the cited reference file in the bundle's known reference list passed to validate_bundle","Fix a renamed/moved reference path in the receipt to match the registered path","Regenerate the artifact and receipt together so provenance is consistent with the current bundle"],"exampleFix":"# before (reference was renamed)\n'reference_path': 'refs/old_intro.mp4'\n# after\n'reference_path': 'refs/intro.mp4'  # path that is registered in known_sources","handlingStrategy":"validation","validationCode":"known = {(s['reference_path'], s['reference_sha256']) for s in bundle_sources}\nfor src in entry['provenance']:\n    assert (src['reference_path'], src['reference_sha256']) in known, 'unregistered provenance source'","typeGuard":"def source_is_known(src: dict, known_sources: set) -> bool:\n    return (src.get('reference_path'), src.get('reference_sha256')) in known_sources","tryCatchPattern":"try:\n    validate_artifact_receipt(out_dir)\nexcept ContractError as e:\n    if 'unknown provenance source' in str(e):\n        sync_receipt_references_with_bundle(out_dir)\n    else:\n        raise","preventionTips":["Generate receipt and reference registry in the same run","Re-hash references whenever reference files are updated","Never rename reference files without regenerating the receipt","Keep one source of truth for the reference manifest"],"tags":["provenance","integrity","validation"],"backgroundTag":"record-not-found","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"}