What Mistral actually published
The post opens with a sentence about people, not tools:
"Legacy scientific codebases accumulate over decades, and when original authors leave, the knowledge embedded in the code becomes hard to recover."
Fortran 77, as the post notes, "was standardized in 1977, as the name may suggest, and code written in it reflects those constraints directly: no modules, no namespaces, no structured types. State lives in COMMON blocks—global memory shared across the entire program." Variable names cap at six characters. A misspelled name silently creates a new variable instead of raising an error.
Mistral raised three questions before starting: "How to prove the migrated codebase matches the legacy one numerically," "How to split the migration into manageable chunks," and "How to best use autonomous agents to speed up the process." Note the ordering. Proof of equivalence came first, agent strategy came third.
The proof mechanism was a parity harness. The team added "subroutines allowing to export the state of the Fortran codebase," "a test framework to load the checkpoints into C++," and "Skill.md files to steer agents into using them correctly." Their assessment: "Building this part of the harness first was a net-positive investment for the project: it made long agent runs safer, and numerical parity is an easy-to-verify and compelling argument to show a piece of code has been successfully migrated."
Then the documentation pass. The project's existing documentation "was scattered across old PDFs and comments buried in the Fortran itself." Mistral generated a caller-callee tree "by parsing the codebase with a custom parser," then "used Vibe CLI to spawn over a hundred agents to document it," working from the leaves of the tree upward, each node opening a pull request. And they describe the result this way:
"One of the largest side-wins of the whole effort was reconciling this documentation and moving it next to the code."
The migration itself took three tries. The first: "we gave agents full autonomy: one agent per Fortran subroutine, each translating its function to C++ independently over the course of a week. The result was functional, but it couldn't be called code modernization. COMMON blocks became global structs, one-to-one. GOTO-driven control flow stayed intact instead of being restructured into loops or early returns. It looked like Fortran retyped in C++ syntax rather than modernized code."
The second attempt gave the agents structure — "a planner, a coder, a tester and a code quality reviewer working together on each module." Quality improved, but: "the source code's complexity caught up with the agents eventually. They would hit a bug, attempt a few fixes, and stall, with no one available to intervene."
What shipped was the middle ground: "a human operating a workflow of coder, tester, and reviewer agents, migrating the codebase module by module."
And the three lessons, verbatim: build the parity harness first, because "numerical agreement is the cheapest, most convincing proof that a module is done"; "Get the documentation in order before you lean on the agents, because you can't migrate code nobody can read"; and "at this scale, structured workflows with human review gates beat both full autonomy and hand-driven manual sessions."
What this does and doesn't change
It does not say agents can't migrate legacy code. They did, and Mistral's own framing is that syntax translation is "a largely solved task." The hard part was architectural: moving from procedural code to object-oriented C++ meant "there's no line-for-line correspondence to check, which is what makes verifying the migration hard."
It does not generalize to every legacy system either. Mistral says so directly: "The Fortran codebase was self-contained and runnable, which is a favorable starting condition. Migrations that depend on external systems, lack a runnable baseline, or encode physics documented nowhere would bring additional challenges not discussed in this post."
Read that last clause slowly. Physics documented nowhere. Mistral names, as the boundary of their own method, the case where the knowledge was never written down. Not badly written down. Not out of date. Absent.
What the post does change is the ranking. The binding constraint on this project was not agent capability. It was whether the reasons behind the code existed in a form anything could read — and where those reasons ended up living once recovered.
What people will take from this, and shouldn't
Three readings are already circulating, and each one drops the part that matters.
"Spawn a hundred agents at your legacy codebase." The hundred agents worked because a custom parser had already produced a caller-callee tree to assign them against, and because Mistral could exploit a property of procedural code: "the whole program can be drawn as a single caller-callee tree." Without that structure, there is nothing to fan out over. The agents were the last step, not the first.
"Documentation was a nice side effect." Mistral calls it a "side-win," but their own lesson list ranks it as a precondition — get it in order before you lean on the agents. A side effect you must produce first is a prerequisite with better manners.
"Agents can reconstruct knowledge that was lost." They reconstructed documentation from PDFs and code comments that still existed. Where nothing existed, Mistral flagged it as out of scope. This is the same boundary two other vendors draw in their own words. Cline describes its Memory Bank as "a documentation methodology that transforms Cline from a stateless assistant into a persistent development partner" — a methodology, meaning something people do, not something the tool derives. OpenHands splits the two explicitly: "keep AGENTS.md for instructions addressed to any agent working in the repository -- memory is for what the agent learned itself." Three independent vendors, three ways of saying that written intent and derived knowledge are different materials.
That is not a criticism of any of them. It is the shape of the problem.
If you want the adjacent cases we have already covered: the general version of "knowledge leaves when people do" is in what happens to AI context when someone leaves, and the mechanics of converting existing docs into something an agent will actually consult are in turning project docs into AI memory. This piece is narrower than both: it is about the record a migration creates, and whether that record survives the migration.
The Fix: Write the decisions where the next project can read them
Mistral's documentation pass recovered what the code and PDFs still contained. The category it could not recover — and named as its own limit — is the category worth planning for. Here is how to separate the two before you start.
Step 1: Sort your knowledge by whether a parser could regenerate it
Take one module and list everything a new engineer would need. Then mark each item with whether a tool reading only the repository could produce it.
Call graphs, type signatures, which function calls which, what a subroutine does mechanically: regenerable. Mistral proved that at scale — a custom parser plus agents rebuilt exactly this class of knowledge from a codebase with no centralized documentation.
Now the other column. Why this solver and not the obvious alternative. Which of these two loops the reservoir engineers said must stay bit-identical. Why the previous port attempt was abandoned in 2019. Which "intermediate points flagged by the client's reservoir engineers" matter and which are incidental — Mistral mentions those checkpoints came from the engineers, not from the code. Nothing in the repository says any of it.
The second column is your real inventory. Everything in the first column is a build artifact.
Step 2: Capture the reasons at the moment they are spoken
The reasons in column two surface during the work, not before it. They arrive in a review comment, in a call with a domain expert, in the sentence someone says when an agent stalls. Mistral's second attempt is where this is most visible: agents "would hit a bug, attempt a few fixes, and stall, with no one available to intervene." The intervention that unblocks a stall is exactly a column-two fact — and it is spoken, not committed.
So capture at that moment. When a human unblocks an agent, write one line: what the agent concluded, what was actually true, and why. When a domain expert vetoes a design, record the veto and its reason next to the design, not in the pull request thread that closes in a week.
This is the same discipline we described in what you should be writing down when a vendor's own explanations get less reliable: the durable artifact is the decision and its justification, not the transcript that produced it.
Step 3: Give the record a home that is not the project
Mistral's documentation went "next to the code," which is the right first move — pull requests into the original repository, reviewed by an agent on a cron schedule. Repository files are durable, versioned, and they travel.
But a migration produces two kinds of writing with different lifespans. The module documentation describes the code, so it belongs with the code and dies with it if the code is replaced again. The decisions — why this architecture, which constraints were non-negotiable, what the domain experts ruled out — outlive both the Fortran and the C++. They are the answer to a question the next project will ask.
Those need a home that is not a directory inside one repository. Skill files are a good vehicle for procedures, which is why Mistral wrote "Skill.md files to steer agents into using them correctly" — but a procedure is not a reason, a point we have made at length in why agent skills are not memory. And instruction files have their own scope: as we found in what coding agents actually read, agents read their instruction files, not your documentation tree.
Setting this up in MemoryLake
A shared decision layer is the piece that does not belong to any one repository. MemoryLake holds the column-two facts — the rulings, the constraints, the abandoned approaches and why — so that every agent working the migration reads the same set, and so that the set is still there when the engagement closes. Setup takes three steps: get started here.
Step 1: Create an API key
Create a workspace for the migration and generate an API key. Scope one workspace to the program rather than to a single repository — the source tree and the target tree are two repositories, and the decisions apply across both.

Step 2: Upload your first memories
Start with the interventions. Every time a person unblocked an agent, that exchange contains a fact the code does not state. Add the domain-expert rulings next, then the checkpoint list and why each checkpoint was chosen. PDFs, meeting notes, and review threads can go in directly; you are not required to convert them to markdown first.

Step 3: Connect your AI & agents
Connect the agents actually doing the work — the coder, the tester, the reviewer. Each one reads the same decision set, so a reviewer agent can flag a change that contradicts a constraint the coder never saw. This is the gap that structured workflows close by hand, with a human in the loop; a shared layer closes part of it before the human has to.

What this changes in practice
Your first sprint stops producing knowledge that only exists in three people's heads. When a module is handed to a new agent workflow, the constraints arrive with it.
The second attempt's failure mode gets cheaper. Agents stall on the same class of problem repeatedly — a numerical convention, an implicit contract, a physics assumption. The first stall costs a human intervention. Subsequent stalls on the same fact cost nothing, because the fact is now readable.
And the record survives the project. Mistral's first sprint covered 40,000 of 300,000 lines, which means five more sprints are coming, likely with different people. Whether sprint six starts from the reasons or rediscovers them is decided now, by where you put them.
Best practices for keeping what a migration teaches you
Write the parity harness before the migration code. Mistral's strongest claim is that numerical agreement is "the cheapest, most convincing proof that a module is done." A harness is also a written record of what "correct" means — the most reusable document the project will produce.
Keep regenerable and non-regenerable knowledge in separate places. Mixing them means every regeneration risks overwriting the part that cannot be regenerated. This is the same trap we described in how agents recorded what was already true during a large proof effort: the durable value was in the written record, not in the run that produced it.
Record vetoes, not just decisions. "We chose PetSc" is weaker than "we chose PetSc after ruling out two alternatives, for these reasons." The ruled-out options are what stop the next agent from proposing them again.
Date the domain facts. A reservoir engineer's constraint in September may be superseded in March. Undated constraints get followed forever or ignored entirely.
Treat human review gates as a source, not just a control. Mistral's third lesson is that gates beat full autonomy. Each gate is also a moment when a person states something the repository does not contain — capture it there.
Conclusion
Mistral's report will be read as a story about agents migrating legacy code, and at one level it is. But their own three lessons put a harness and a documentation pass ahead of agent strategy, and the boundary they draw around their own method is code that "encode[s] physics documented nowhere."
Agents made the mechanical work cheap. They did not make undocumented intent recoverable, and Mistral does not claim otherwise. The migration will end. The C++ will eventually be legacy too. What carries forward is the part somebody chose to write down — and where they put it.