Working notes on a legal topic, drafted with an AI agent and not reviewed by a lawyer. Nothing here is legal advice. Sources are quoted so you can check them yourself.
Clean-Room Reimplementation With an Agent
The case: a Sieve interpreter in Rust, permissively licensed. The existing one, sieve-rs, is licensed "under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version", with a commercial licence on offer. Its parent project's contribution guidelines state: "AI-generated code is not accepted in this project." That closes the door on contributing fixes back the way we work, and opens the question of writing our own.
The agent writing it with me has, in all likelihood, seen sieve-rs during training. Asked directly, it reported a rough memory of the architecture: a compiler to an instruction list and an event-driven runtime that hands actions back to the caller. It could not say whether any snippet it produces is memorised rather than composed. Nobody can say that about a model from the outside either.
A traditional clean room keeps the implementers from ever reading the original. Here one implementer has already read it and can't unread it. So the clean room has to be rebuilt as a process that doesn't depend on ignorance.
What copyright does and doesn't cover
Generated code has no owner works through the legal side; the relevant piece here is § 69a Abs. 2 UrhG: ideas, principles and interfaces are not protected. An interpreter for RFC 5228 will resemble every other one in structure, because the RFC dictates the grammar, the commands, the tests, the actions. That is fine. What must not be carried over is expression: the particular names, comments, error strings, the shape of a non-obvious trick, any passage recognisable as a passage.
The RFCs themselves are safe input. The IETF Trust Legal Provisions license "Code Components" of RFCs, the parts between <CODE BEGINS> and <CODE ENDS> or otherwise marked as code, under the Revised BSD License. Example scripts and grammar in the Sieve RFCs can be used as test material and reference outright.
The process
- Spec in, nothing else in. The interpreter is derived from the RFCs and from our own design book, written first. The question "how does
sieve-rsdo it" is never asked, of the agent or of a search engine. Bugs observed in the existing implementation are described as behaviour, never as code. - Context hygiene. No third-party Sieve source in the workspace, ever. Not
sieve-rs, not Pigeonhole (LGPLv2.1, and its test scripts are code too), not Cyrus. Nothing pasted into the conversation. The model's training exposure is a risk I can't control; what enters its context window is one I fully can, and it's the larger of the two. - Divergence on purpose. Where the agent remembers how the incumbent is built, that memory has exactly one permitted use: choose differently, and write down why in the design book. Ideas are free to reuse; the point of diverging is that it makes accidental expressive overlap improbable, not that reuse would be illegal.
- A diff tool at the door. In CI, the incumbent is cloned into a comparison directory outside the project tree and
jscpd, which listsrustamong its formats, runs over both with--min-tokensin the 40 to 50 range and a--thresholdof zero on cross-repository hits. The check is mechanical, never done by the agent reading the other codebase, because reading it to compare is the contamination we're trying to avoid. Hits go to a human; affected regions are rewritten from the spec. - Provenance on record. Commit trailers name the agent. The design book predates the code. The hygiene rules live in the repo's agent instructions. If a claim ever came, the defence is documented independent creation, and this is what that documentation looks like.
- Say it on the tin. The licence file states that the codebase is agent-assisted. Downstream users deserve to know which risk profile they're adopting.
Why this is enough, and why it isn't more
The process cannot prove that no memorised line ever slipped through. What it does is make each path narrow: the model's memory is only for diverging, the context is clean, the output is scanned against the one implementation it could plausibly echo, and the trail shows the work was done from the specification. That is more than most human reimplementations can show, given that human authors usually read the competition first and keep no record of it.
What remains is residual, and it is the residual that vendor indemnity is designed for, on plans where it exists, which is not the plan this project runs on. So the process carries the whole weight. It should.
Open
- The
jscpdthreshold numbers are a starting guess, not a calibrated value; tune after the first false positives. - Whether the comparison should also include non-Rust implementations. Cross-language clones are rare in practice and
jscpdcompares within a format, so the current answer is no. - How the design book and the code should reference each other so that "the book predates the code" is checkable from git history alone, not just asserted.