How to Tell Whether Source Code Was Copied

Most copying claims start with two codebases that look alike. Generative AI has made that resemblance cheaper to manufacture and harder to read, which makes the underlying forensics matter more, not less.

Two codebases that look alike is the weakest place a copying case can start, and usually where the weak ones end. Resemblance only tells you something when it shows up in the parts of the code nobody was forced to write the same way. That was true before generative AI. AI has made it more true, by making surface resemblance trivial to produce and by introducing a third explanation for it that did not exist a few years ago.

These disputes are always some version of the same situation. A company is certain a former engineer, a competitor, or a vendor walked off with their source. Someone has run a diff or held two files side by side, and the resemblance looks damning. Sometimes it is. More often it is the kind of resemblance two honest, independent teams would have produced anyway. And now there is a third case: a developer who never saw the original code, who described what they wanted to a model and shipped what it generated. Telling these three apart is the whole job.

A note before I start: this is about the engineering, not the law. Copyright and trade-secret doctrine decide what is protected and what a plaintiff has to prove. I am describing how you look at the code itself, which is the input those legal questions depend on, not a substitute for them.

What copying actually looks like

Copying shows up two ways, and the one most people picture is the smaller half of the problem.

The first is literal copying: the same text, verbatim or nearly so. This is the easy case. Text comparison, token comparison, and fingerprinting will surface matching passages quickly. The academic standard for fingerprinting is Moss, Alex Aiken's Measure Of Software Similarity, which reduces code to a set of hashed fragments and looks for overlap that survives reformatting and reordering. If someone lifted files wholesale, you find it fast.

The second is non-literal copying, and this is where the real work lives. Here the structure, sequence, and organization of the original are preserved while the surface is changed. Variables get renamed, formatting gets reflowed, comments get rewritten, functions get reordered, and sometimes the whole thing gets translated into another language. The text no longer matches, so a naive search comes back clean, but the architecture underneath is the same architecture.

This is why text-match percentages mislead, and the methods that survive disguise are the ones worth trusting. Abstract syntax tree comparison looks at the parsed structure of the code rather than its characters. Control-flow and data-flow analysis compares how the program moves and transforms data. Call-graph and dependency analysis compares how the pieces are wired together. Two programs can share almost no text and still be the same program underneath, and they can share a great deal of text and be unrelated. So when a claim leans on a raw percent-of-lines-that-match number, the first question worth asking is what kind of similarity that number is counting, because the disguisable kind is the kind that inflates it.

Why two codebases resemble each other when no one copied

Most similarity has an innocent explanation, and a credible analysis rules those out before it says the word copying. Here is what produces resemblance with no wrongdoing at all.

  • Efficiency. For a great many problems there are only a few sensible ways to write the solution. Sort a list, parse a date, retry a failed network call: independent engineers converge on the same shape because the good options are few and everyone can see them.
  • External constraints. Hardware, the operating system, network protocols, file formats, and public APIs dictate how code has to be written. Two programs talking to the same interface will look alike at the boundary because the interface left them no room to differ.
  • Idiom and shared training. Developers taught the same conventions write code that resembles other code by the same school. Idiomatic Rust looks like idiomatic Rust. That is the language and the community doing their job, not a fingerprint of theft.
  • Reused public material. Open-source libraries, standard-library calls, framework scaffolding, and generated boilerplate all show up identically in unrelated projects because both sides drew from the same well, legitimately.
  • Convergence. Give two competent teams the same requirement and they will often arrive at the same place independently. Same problem, same constraints, same era of best practice, similar answer.

None of these is copying. A resemblance that lives entirely in this territory is a weak claim no matter how strong it looks at first glance, and a good analysis says so even when the client does not want to hear it.

Filtering down to what matters

The discipline that separates a real claim from a coincidence is to remove everything that had to be that way, then compare only what is left. This is not my invention. It is the filter-first framework courts have leaned on since Computer Associates v. Altai in 1992, and it works in three moves.

First, abstraction: look at the program at every level from its general idea down to its literal lines, because copying can happen at any of them. Second, filtration: set aside the parts that are not protectable expression, the ideas themselves, the elements dictated by efficiency, the elements dictated by external constraints, and anything drawn from public or open-source material. Third, comparison: whatever survives filtration is the protectable expression, and only its similarity is probative.

The reason this matters to a pursue-or-pass decision is that a similarity score computed before filtration and one computed after can point in opposite directions. Two programs can be eighty percent similar by raw text and almost entirely dissimilar in protected expression once you strip out the library calls, the boilerplate, and the parts the platform forced. The unfiltered number is the one that gets attached to an early demand letter. The filtered number is the one that survives an opposing expert. An analysis that skips the filtration step shouldn't be trusted in either direction.

The evidence that is hard to explain away

The most persuasive signs of copying are the things coincidence cannot produce. Convergence explains why two teams write the same correct code. It does not explain why they would write the same useless or wrong code.

  • Shared idiosyncrasies. Identical comments, the same spelling errors, the same unusual variable names that no function requires. Convergent engineering produces similar logic, not the same private quirks.
  • Copied dead matter. Unused branches, unreachable functions, and commented-out experiments that serve no purpose in either codebase except a shared origin. Dead code has no efficiency reason to exist, so its appearing in both places is hard to wave away.
  • The same bug. A defect or security vulnerability reproduced faithfully in both codebases is among the strongest signals there is. Nobody converges on the same mistake. A mistake carried across is a mistake that traveled.
  • Metadata and history. Timestamps, build artifacts, and version-control history can corroborate or demolish a timeline. They are also worth checking against the code itself early, because a copying story that the commit history contradicts is over before it starts.

One more discipline belongs here. Similarity is necessary but not sufficient. The familiar frame is access plus substantial similarity: resemblance matters only alongside a plausible path by which one party could have reached the other's code. Strong similarity with no credible access is a thin case. Modest similarity with clear access and a copied bug is a much stronger one. Hold that thought, because access is exactly what AI complicates.

When the copying goes through a model

AI changes three things about this analysis: whether copying happened in the legal sense at all, how easily the surface can be disguised, and who had access. They pull in different directions, so take them in order.

Functional cloning is not code copying. The most common thing people call theft right now is the vibe-coded lookalike: someone points a model at an existing product, or just describes it, and ships an app that does the same thing and looks the same. That feels like theft to the original team, and on a code-copyright axis it usually is not. Copyright protects expression, not function, not ideas, and not the behavior a user sees on screen. Reimplementing what a program does, in fresh code generated from a description, is the same thing clean-room reimplementation has always been allowed to do. The Supreme Court's decision in Google v. Oracle reinforced how thin the protection is around the functional and interface layers that clones tend to target. A lookalike can still hit other walls: design patents and trade dress on the look, utility patents on a method, trade-secret claims if the cloner had inside access. But if the question is "did they copy our source code," a clone built without ever touching that source often did not, however much it stings. Separating "does the same thing" from "contains our expression" is the first cut, and it disposes of a surprising number of claims.

AI is a laundering tool. The flip side: when there is real copying, AI is the most capable disguise machine yet built. Ask a model to rewrite code in a different style, restructure it, or port it to another language, and it will defeat text matching while preserving the structure that text matching was standing in for. This does not create a new problem so much as retire an old shortcut. The similarity percentage was always weak. Now it is worthless, and all the weight falls on the structural and idiosyncratic analysis that was doing the real work anyway. The same applies to reverse engineering: a model lowers the cost of turning observed behavior, or a decompiled binary, into clean-looking equivalent source, which means more disputes will arrive already laundered.

A model can copy without the person knowing. Models trained on large code corpora can memorize and emit fragments of that training data close to verbatim, especially code that appeared many times. So literal copied code can surface in a project whose developer never saw the original, never had access in the traditional sense, and never intended to copy anything. The access came through the model. This strains the oldest inference in copyright analysis, access plus substantial similarity, because access is now an attribute of the tool rather than the person. It is also genuinely unsettled. The marquee case, the GitHub Copilot class action filed in 2022 against GitHub, Microsoft, and OpenAI, is instructive precisely because it has struggled on the copying axis: courts dismissed most of the straight copyright claims, in large part because the plaintiffs could not point to output reproduced identically from their code, and the surviving fight shifted to open-source license breach and removal-of-attribution theories, with the attribution question now before the Ninth Circuit. The practical lesson for anyone scoping a claim is that AI-mediated similarity is hard to land as copying, and the exposure tends to concentrate in provenance and licensing rather than in resemblance.

So provenance becomes the analysis. A modern code dispute is rarely "are these similar." It is "where did this code come from," and there are at least four answers with four different consequences: a human copied it; a model regurgitated it from training data; a model generated it fresh from a description and it merely resembles the original; or two efforts converged. AI-generated code has tells that help sort these, characteristic structure, comment habits, and boilerplate patterns a trained reader can recognize, alongside version-control history that shows whether code arrived in sudden large commits, the way generated or pasted code does, or grew the way hand-written code grows.

And the copied-bug test still cuts through all of it. Here is the reassuring part. The single strongest piece of evidence from the pre-AI world is the strongest in the AI world too, for the same reason. Convergence does not reproduce the same bug. A model generating fresh code from a description does not either. But a model regurgitating memorized training data carries the exact idiosyncrasies of its source: the same comment, the same odd name, the same defect. A copied mistake is a mistake that traveled, whether it traveled through a person or through a model's weights. When the surface has been laundered and the provenance is murky, the idiosyncrasies are what stay legible.

One consequence is already settled enough to act on while the harder questions move through the courts: if code ships in a product, the team that shipped it owns the licensing exposure, whether a person, a library, or a model produced it. A model does not wash a license off the code it learned from.

What it comes down to

A copying analysis is only as good as its willingness to argue the other side. The questions worth returning to:

  1. Where did the code come from? Provenance, whether a human copied it, a model regurgitated it, a model generated it fresh, or two efforts converged, drives every other answer. Ask it before asking whether the code is similar.
  2. Is the similarity forced or free? Forced similarity from efficiency, constraints, idiom, and reused public code proves nothing. Free similarity is where the signal is. Filter before you compare.
  3. Do the idiosyncrasies line up? The same comment, dead code, or bug outweighs a thousand ordinary matching lines, and it survives both manual disguise and AI laundering when little else does.
  4. Where did access come from? It can now run through a model rather than a person, so a clean-handed developer can still ship copied or contaminated code. Weigh access and licensing, not resemblance alone.
  5. Is it a clone or a copy? A functional lookalike that reproduces behavior is usually not code copying. Separate "does the same thing" from "contains our expression" before anyone spends money.

This is for you if you are weighing whether a code-copying or cloning claim is worth pursuing and want to know what the resemblance actually means before you spend on it. This is not for you if you want a tool that prints a similarity score and a verdict; the score is the beginning of the analysis, and in the age of generated code it is a smaller beginning than it used to be.


Roland Rodriguez is a software and distributed-systems engineer with thirty years of experience building production systems, including a Principal role at AWS and the Azure launch team, and current work in production machine-learning systems. He takes on consulting and expert-witness engagements involving source-code analysis, software intellectual property, AI and machine-learning systems, and software-project disputes. Contact and more writing at rodriguez.today.

How to Tell Whether Source Code Was Copied - Roland Rodriguez