Not every file a user attaches has prior provenance. When a file is new to the system, you need to ask: who created this? The answer changes the action type recorded, but in both cases the file gets a content-addressed CID that downstream AI actions can reference.
The Two Cases
Case 1 — Known file (provenance exists)
The file matches an existing record in the system. The existing CID is reused as aninputCid — no additional recording needed.
Case 2 — New file (no prior provenance)
The file is not in the system. Ask the user: “Do you own this file?”
Both paths produce a CID. Both CIDs can be used as
inputCids in downstream provenance actions.
Why Both Cases Matter
Claimed resources (action.type = "create") establish a clean ownership chain. The provenance graph shows user → creates → file → inputs → AI response. This is strong evidence for copyright claims (see the Human Creative Input pattern).
Unclaimed resources (action.type = "reference") are equally important. Recording that an AI response used an unknown-origin file is honest provenance — it accurately represents the training data and inputs used. Silently omitting unattributed inputs is worse than recording their existence.
An unclaimed resource is not a problem in the provenance graph — it’s an honest representation of reality. The absence of a creator entity signals “origin unknown” rather than “created by no one.”
Implementation
Server-side claim endpoint
Client-side with FileProvenanceTag
FileProvenanceTag renders FileOwnershipClaim inline:
Using the CID in downstream actions
Once the file has a CID (from either a match or a claim), pass it asinputCids when recording the AI response:
On-Chain Recording
Both"create" and "reference" actions are eligible for on-chain recording. If CHAIN_PRIVATE_KEY and BASE_SEPOLIA_RPC_URL are set, pk.file() automatically records the action hash to the ProvenanceRegistry contract on Base Sepolia.
What the Provenance Graph Looks Like
Claimed file
Unclaimed file (referenced)
create signals Alice made it; reference signals Alice used it but didn’t make it. Both are honest, auditable records.
Gotchas
- Ask before the message is sent: The ownership decision should happen in the attachment UI, not after submission.
FileProvenanceTaghandles this — it runs the search and shows the claim prompt while the file is still in the input area. - Reuse existing CIDs: If
FileProvenanceTagfinds a match (score ≥ some threshold), use the existing CID directly asinputCid. Don’t re-record the same file as a new resource. - CID propagation: Store the claimed CID in local state immediately after
onClaimresolves so it’s available when the message is submitted.FileOwnershipClaim’sonClaimcallback is the right place to callsetState. - Binary files (PDFs): For files where text content can’t be extracted inline, the provenance record still captures the file hash (CID). The LLM won’t see the content, but the provenance chain remains complete.