“Which prompt wrote this line?” sounds like a lookup. It is not, and the reason is worth understanding before you trust any tool that claims to answer it.
Why you cannot replay line numbers
Git blame works because every commit is a positional diff: this many lines removed here, these lines added there. Replaying that history reconstructs authorship exactly.
AI editing tools do not produce positional diffs. An edit is typically a pair of strings — find this block, replace it with that block — and a multi-edit chains several of those together. There are no line numbers to replay, and by the time you read the file it has been edited by other tools, formatters and humans. Positional reconstruction is not available.
Matching on content instead
The approach that does work is to index the lines each interaction added, oldest to newest, and then walk the current file asking where each line came from. Most lines match exactly one interaction and the answer is unambiguous.
The interesting cases are the rest:
The same text in several interactions. Adjacency decides first: if the previous line's source is among the candidates, that source wins, because code tends to arrive in blocks. Otherwise the most recent interaction wins.
Trivial lines. A closing brace matches everywhere and means nothing on its own. These inherit the attribution of their neighbours and are marked as inherited rather than matched.
No match at all. The line stays unattributed. That covers code written before recording began, code from a machine with no recorder, and code edited enough that it no longer resembles what the model produced.
Where it breaks, stated plainly
Reformatting is the main one. A formatter that rewrites whitespace or re-wraps lines changes the text being matched, and those lines move to unknown. Large refactors do the same.
Adjacency and recency are rules, not proofs. They are applied identically every time and they are documented, but a determined reader can construct a case where they choose wrong.
And nothing can attribute what was never recorded. Coverage is a separate question from accuracy, and it deserves its own number.
Why this is still worth doing
Because the alternative is a guess. A method with documented limits and an explicit unknown column can be checked, argued with and improved. A confident percentage with no method behind it cannot be any of those things, and it fails the first time somebody tests it against a file they wrote themselves.