COBOLコードの移行を研究するエンジニアのグループが論文を発表し、AIを「檻」に閉じ込めるアプローチを提案した。
論文のタイトルは非常にシンプルだ。『Agentic Method for Deterministic Validation of Legacy Code Migration』。彼らは「Locksmith Loop」と呼ばれるシステムを設計した。その名の通り「鍵屋(Locksmith)」であり、「達人(Master)」ではない。AIに一度で完璧な仕事をこなすことを期待するのではなく、決定論的なフレームワークの中にAIを制限し、得意なことだけをさせる設計だ。
しかし、本当に興味深いのはこの結論そのものではない。なぜ彼らがこうせざるを得なかったのか、そしてそうした後に何が起きたのかだ。
3つのモジュール、AIが触れるのは1つだけ
Locksmith Loopのアーキテクチャは3つの層に分かれている。
第1層は「Migrator」だ。COBOLのソースコードを入力し、Javaのターゲットコードを出力する。このステップではLLMを使用しない。決定論的なAST(抽象構文木)変換器を使用する。ルールは固定されており、COMPUTEはBigDecimal.add()に、PERFORM VARYINGはforループに変換される。実行するたびに毎回同じ結果が得られる。TimByte氏がHN(Hacker News)で的確に要約したように、「彼らはコード生成を決定論的ツールに委ね、モデルは入力のファジングだけを行わせている。構文には触れさせないのだ」。
第2層は「Witness Search」だ。ここがAIが登場する唯一の場所である。LLMは継続的に入力ケースを生成し、プログラムの全分岐を突破しようと試みる。各実行後、カバレッジアナライザーがまだ到達していない分岐を確認し、LLMがそれを狙って新たな入力を生成する。このプロセスを、カバレッジが向上しなくなるまで繰り返す。
第3層は「Oracle」だ。COBOLの原本とJava移行版で同じ入力を同時に実行し、出力はビット単位で完全に一致しなければならない。いかなる偏差も移行失敗とみなされ、修正のためにロールバックされる。
なぜこのような設計にするのか? 各ステップには明確な失敗モードがあるからだ。
Migratorは決定論的であるため、翻訳エラーは再現可能で追跡可能だ。もしCOMPUTEからBigDecimalへの変換で精度の問題が発生した場合、変換ルールの記述ミスだと分かる。モデルが特定の推論で確率的にズレたわけではない。
Oracleも決定論的であるため、検証結果は二値化される。正しいか、間違っているかだ。「だいたい合っている」というグレーゾーンは存在しない。
Witness Searchは唯一の非決定論的なセクションだ。しかし、その失敗モードは制御可能である。最悪のケースでも、特定の分岐をトリガーする入力が見つからず、カバレッジが不十分になるだけだ。間違ったコードを生成したり、幻覚(ハルシネーション)を引き起こしたり、翻訳プロセスでバグを混入したりすることはない。
これがLocksmithの設計哲学である。AIを、失敗した結果の影響が最も軽い場所に配置することだ。
AIが前に進めなくなった時
Witness Searchは万能ではない。ある分岐の境界に達したとき、そこで立ち往生する可能性がある。論文ではこの状況を「Locked Paragraph」と呼んでいる。深い探索を阻む条件であり、AIがそれを突破する入力を構築できない状態だ。
これが「鍵屋」という名前のもう一つの意味合いだ。システムはAIがすべての鍵を開けられるとは期待していない。AIが立ち往生した時、アナライザーはそのLocked Paragraphにマークを付け、システムは他の分岐の探索を続ける。最終的なカバレッジは、AIがいくつの「鍵」を見つけられたかにかかっている。
論文は3つのテストケースの結果を報告している。2つのオープンソースCOBOLプログラムと、1つの「内部生産レベル」のプログラムだ。規模は430行から4114行に及ぶ。2つのオープンソースプログラムは「ほぼ完全なカバー」に達した。生産レベルのプログラムは91.90%の分岐カバレッジを達成した。
91.90%。この数字自体には、サンプルが小さすぎるためあまり議論する価値はない。本当に価値があるのは、残りの8.1%が何を意味するかだ。Locked ParagraphはAIの能力の限界を示している。91.90%の鍵は見つけたが、残り8.1%の鍵は開けられなかった。これらの鍵は実際のシステムにおいて、最も複雑なビジネスロジック、最も深くネストされた条件、最も古いコーナーケースに対応している可能性が高い。
バグも一緒に移行するのは設計目標
アーキテクチャには直感に反する設計がもう一つある。移行後のJavaコードは原本のCOBOLと動作が完全に一致していなければならず、バグも含めて一致していなければならない。
Hacker Newsでaldente0630氏がこれを明確にした。「バグの保持は明確な設計目標だ」。しかし、これは論文がバグの保持を推奨しているという意味ではない。レガシーマイグレーションの世界では「バグ・フォー・バグ互換性(bug-for-bug compatibility)」と呼ばれる現実を認めているだけだ。それらのバグはすでに本番環境で20年間稼働しており、下流のシステムはその動作に依存している。1つのバグを修正することは、「他の誰かが正常だと思っている機能」を修正することと同義だからだ。
ハイラムの法則(Hyrum's Law)がここでは完全に当てはまる。「十分な数のユーザーを持つシステムでは、仕様に明記されているかどうかにかかわらず、観察可能なすべての動作に対して依存するユーザーが必ずいる」。
しかし、バグ・フォー・バグには一つの前提がある。Oracleが比較するのは動作であって、コードではない。バグの動作は保持するが、バグの理解しやすさまでは保持しないということだ。元のCOBOLのベテランプログラマーは、なぜそのバグが存在するのかを知っていた。緊急修正の名残かもしれないし、あるビジネスルール変更の遺物かもしれない。しかし、Javaプログラマーがその「意図的にバグの動作を保持した」コードを見たとき、彼らが目にするのは書き間違いのように見えるコードだけで、何のコンテキストもない。
4KLOCと230KLOC
Hacker Newsのコメントはアーキテクチャ設計についての議論ではなく、論文の規模を直接疑うものだった。
pacaro氏は現実世界のスケールを示した。「IRS(米国連邦所得税庁)だけで約160のCOBOLプログラムがあり、平均各プログラムは23万行のコードだ」。
fock氏のコメントはさらに具体的だった。彼自身が試したからだ。「私たちが使っていたコードにはインラインアセンブラが埋め込まれており、十数個のファイルにまたがって5万行あった。このプログラムはあるプリプロセッサを使っていて、私たちがテストしたすべてのLLMはそれが何なのか全く理解していなかった。彼らはその機能をでっち上げた。Gemini 2.5はプリプロセッサが存在することすら気づかなかった」。
これはLocksmith Loopの本当の限界を指し示している。Migratorは決定論的なAST変換器だが、AST変換の前提はソースコードをパースできることだ。もしソースコードにプリプロセッサのマクロ、インラインアセンブラ、CICSトランザクション命令、JCLのバッチ処理スケジューリングが含まれていたら——これらはCOBOLの構文の一部ではなく、環境の一部である。AST変換器はそれらを認識しないし、でっち上げることもしない(これは利点だ)が、単にそのまま失敗する(これが問題だ)。
Zenst氏は精度の問題を補足した。「COBOLは丸め誤差のない固定小数点演算で知られている。Javaの0.1 + 0.2は0.30000000000000004になる。全面的にBigDecimalを使用しない限り、移行は最初からダメだ」。論文ではBigDecimalを使用しており、これは正しい。しかし、金融システムのCOBOLプログラムは通常、packed-decimal(BCDエンコーディング)を使用しており、その精度と丸めの挙動はBigDecimalと完全には等価ではない。Oracleのビット単位の比較はこれらの違いを捉えるが、修正するにはMigratorの中でますます複雑なルールを書かなければならないことを意味する。
言い換えれば、Locksmith Loopの決定論的アーキテクチャの方向性は正しいが、そのエンジニアリングの複雑さはシステムの規模に伴って非線形的に増大する。4KLOCから40KLOCへの移行は、作業量が10倍になることではない。対処すべきエッジケース、環境依存、精度の違い、非標準の構文がすべて同時に爆発する。
COBOL-in-Java
dragonwriter氏はHNで、このアーキテクチャの最も根底にある矛盾を指摘した。「現実的でエラー率の低い唯一の方法は、より複雑なAIを使うことではなく、決定論的な変換である。問題は、そうして得られるものがCOBOL-in-Javaであり、正しく動作はするが、メンテナンスは悪夢になることだ」。
決定論的変換の産物は、構文はJavaでも、魂はCOBOLだ。変数名、制御フロー、データ構造はすべて1960年代の匂いを帯びている。PERFORM VARYINGはforループになったが、変数の命名規則、データの組織化ロジック、エラー処理の分岐構造はすべてそのまま残っている。
人間のプログラマーが移行を行う際、Migratorが行わないある一つの事を行う。システムの意図を再解釈し、新しい言語の慣用的な方法で再表現することだ。これにはリスクを伴う(理解が間違っているかもしれない)が、保守可能なコードを生み出す唯一の方法である。
Migratorはゼロリスクの道を選んだが、保守性という代償を支払った。COBOLのベテランプログラマーを失い、Javaプログラマーを手に入れたが、彼らがこのコードを見ると、ベテランプログラマーよりもさらに困惑する。
matsemann氏がHNでの最初の発言はまさにこのことを指していた。「以前は少なくとも数人のCOBOLのベテランプログラマーがこのシステムを理解していた。今は誰も理解していない」。誰も理解していない古いシステムを、誰も理解していない新しいシステムへと変えた。問題は解決しておらず、言語を変えただけなのだ。
論文が語らないこと
Locksmith Loopのアーキテクチャ設計は正しい。AIをテスト生成に限定し、翻訳と検証を決定論的なコードに任せること。これは厳密なソフトウェアエンジニアリングにおいてAIを使用する唯一の信頼できる方法かもしれない。
しかし、それはより大きな問題を回避している。COBOLシステムの移行における本当のボトルネックは「コードの翻訳」ではなく、このシステムが何をしているのかを理解することだからだ。20年誰も触れていないコード、ドキュメントもテストもなく、当初の開発者はすでに定年退職している。本来どのような出力を生成すべきかすら知らない状況で、Oracleの出力が正しいことをどうやって検証するのか。
論文はOracleが与えられていると仮定している。つまり、COBOLの原本が動き、出力を生成し、それをJava版と比較できる状態にあるという前提だ。しかし実シナリオでは、COBOLシステムがすでに起動できないか、再現不可能な特定のメインフレーム環境でしか動かない可能性がある。Oracleは既成品ではなく、Oracle自体が再構築すべきものだ。
これはLocksmith Loopのせいではない。検証方法に関する論文であり、移行工学の論文ではない。しかし、もしあなたが本当にCOBOLシステムの移行を検討しているなら、知るべきことは「AIにテスト生成ができるか」ではなく、「あなたのCOBOLプログラムはまだ動くか」だ。
参考ソース
• Agentic Method for Deterministic Validation of Legacy Code Migration — https://arxiv.org/abs/2607.28271
• Hacker News discussion — https://news.ycombinator.com/item?id=49150773