1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JSONのまま押し通したら、AIたちが「最小トランザクションジャーナル」まで考え始めた #16最終回【AIの尻拭い】「こうしたい」の一言から、AIとCodexが複数JSON更新の整合性リスクを発見し、Crash Recovery・回帰テスト・Git安全境界まで組み上げる開発へ

1
Last updated at Posted at 2026-09-16

89982E36-0608-4C5D-9FC9-8188F992306D.png

連載公開分(クリックで開く)

ここまで在庫、予約、キャンセル待ち、お気に入り、組織、物件、設定、権限、競合、マイ在庫、現場在庫、現場共有在庫、申請、資格、QR、エイリアス、文言変更モード、ヘルプ、仕様管理、Git、Codex、テストなどいろいろ増えました。

でも増えたのは機能だけではありませんでした。作り方そのものも、かなり変わりました。

最初の頃は、

私「こうしたい。」

AIがコードを書く、私がコピーする、PowerShellへ貼る、動かす、エラーが出る。

私「赤いの出た、直して。」

AIへ戻す、修正版をもらう、また貼る。

それでも、機能が少ないうちは何とかなりました。でも、在庫と予約がつながる、人と物件がつながる、物件と在庫がつながる、設定が画面へ反映される、権限がAPIへ関係する。

A「一個直すだけで、見るところがどんどん増えた。」

途中から、Gitも入れました。それでも、必要なファイルを私が毎回探して、AIへ見せるやり方には限界が来た。

そのあとに、Codex。

Codexを入れて、リポジトリの中を横断して調べてもらえるようになりました。最初は、AIもコードを書く、Codexもコードを触る、私もPowerShellを使う。単純に、作業するAIが一人増えたくらいでした。

私「最初は使い方もよく分かってなかったからな。」

A「今は?」

私「やっと少し楽になってきた。」

A「やっと?(笑)」

使って、失敗して、また使って。触っていいところ、触らないところ、先に調べること、Gitの扱い、テスト、途中で止まる条件、最後に報告すること。困るたびに、次から同じことで困らないようにルールを付け足していきました。

そのうち、少しずつ役割も変わっていきました。

私「俺は、何をやるか決める。」

A「現場でどう使うか。」

私「決める。」

A「AIの案を採用するか。」

私「決める。」

A「正式仕様にするか。」

私「最後は俺が決める。」

B「意思決定側ですね。」

AIは、今の仕様や実装を見る。影響範囲を確認する。必要なら、Codexへ先に調査を出す。Codexは、決めた範囲を調べる、実装する、テストする、結果を返す。

A「Codexは作業員?」

私「有能作業員。」

そして、PowerShell。

A「まだいる?定年ないの?(笑)」

昔は、実装するためにもかなり使っていました。今は、Gitの状態、差分、テスト結果、API、JSON、文字コード。確認側で使うことが増えました。

A「定年じゃなくて部署異動しただけか」

私「防衛大臣になった感じ(笑)」

最近の開発は、例えばこんな感じです。

① 実装する前に、まず調べる

私「この機能、もう少し使いやすくしたい。」

A「相変わらず雑だな(笑)」

これをAIへ言う。AIは、今の仕様、既存実装、画面、API、データ、権限、Git、テスト、必要なものを確認する。足りなければ、まずCodexへ調査を出す。

何を調べる、どこまで見る、何を変更してはいけない、何を確認する、Gitをどう扱う、何をテストする、最後に何を報告する。そこまで整理して、Codex用の指示へ落としていく。

A「元の依頼は?」

私「『この機能もう少し使いやすくしたい』。」

A「入力と出力の情報量おかしくない?(笑)」

私「AIはどんどん進化してるんだよ!」

B「実際には、そこへ至るまで開発中の長いやり取りがありますからね。」

私「そうそう。」

B「過去の仕様や判断も含めて意図を拾えるようになれば、最初の要求が短くても、その後の調査項目は増やせます。」

② 実装中も、何でも勝手には進めない

「既存dirtyに今回の変更が混在しています。ファイル全体をstageすると既存変更まで含まれるため、今回対象のhunkだけを分離してstageしてよいですか?」とか、「テストがFAILしました。ただし、現時点では今回の変更が原因とは断定できません。単独再実行やHEAD側との比較で、本体・既存dirty・テスト環境のどこが原因か切り分けてよいですか?」といった確認があります。

私「慣れてる人なら、この辺は任せて進めることも多いと思う。でも俺は、まだ分からないことが混ざるときがあるから、あえて途中で確認してもらうようにしてる。」

A「それで?」

私「何をしようとしてるか見る。何を守ろうとしてるか見る。あと、何を壊す可能性があるか。」

A「で?」

私「大丈夫そうならYES。」

A「ど素人がYESを押す係まで昇進した(笑)」

私「今は最高司令官だぞ!」

B「実装の細かいところを全部説明できることと、変更の目的・影響・リスクを見て承認することは別です。」

時にはCodex自身が間違えることもあります。

例えば、「server.jsへの差し込み位置を間違えました。ファイル全体ではなく、該当箇所だけHEADの内容へ戻して、正しい位置へ当て直してよいですか?」

A「自分で間違えたのも言うんだ?で、全部戻さず、そこだけ直す。」

私「そう。」

③ 最近では

例えば、複数に分かれていた通知処理。私は、「これを共通のqueue / publish処理へまとめよう」なんて指示していません。

そもそも、そんな言葉も知りませんでした(笑)AIやCodexが今の実装を調べて、「似た処理が複数に分かれている」「このまま増やすより、共通化した方がいい」と問題を拾ってくる。

私「queue?」

A「知らないの?(笑)」

私「知らないから調べるんだよ(笑)」

そして別のときには、AIとCodexが今の構成を調べる中で、「DBを使わず、複数のJSONファイルを更新している今の構成では、書き換えの途中でプロセスやサーバーが停止すると、一部だけ更新された中途半端な状態が残る可能性がある」という指摘をされました。

私「よくわからないから、何それ?って」

A「お前が聞く側なの?(笑)」

そこで初めて調べる、AIにも聞く、必要ならCodexにも調査してもらう。

そこで出てきたのがTransaction Journal、Crash Recovery。

A「ちょっと確認。」

私「何?」

A「この機能の規模をまだJSONでやってたの!?(笑)」

私「だって元々は『在庫が見たい』だけだったんだよ、あと最初はDBとか知らなかったし(笑)」

A「途中では知ったんだろ?」

私「普通はDBでやるってことくらいは途中で知った(笑)」

A「Transaction Journalって、お前が考えたの?」

私「いや。」

A「Crash Recoveryは?」

私「それも知らなかった。」

A「じゃあ誰が言い出したの?」

私「AIが今の構成を調べて、途中で落ちたら複数のJSONがおかしくなる可能性があるって。」

A「それで、AIが対策を考え始めた?」

私「うん。」

このように、今ではAIとCodex側でかなりの作業を提案して進めてくれるようになりました。

※私にとっては、自分では知らなかった問題や仕組みを向こうから提案してくれるだけでも、かなり参考になります。何より、最初の頃のように、必要なコードを自分で探して、AIから返ってきた修正を貼り付け、エラーが出たらまたAIへ持ち帰る――そんな往復を繰り返していた頃に比べると、劇的に楽になりました。

A「お前は?」

私「『それ何?』って聞く(笑)」

A「そこからかよ(笑)」

B「知らない技術が必要になったら、その時点で調べているわけですね。」

私「そう。最初から知ってて設計してるわけじゃない。」

A「必要になってから授業が始まるのか(笑)」

そこでAI側が対策を整理し、Codexと実装・検証を進め始めたのが、「最小トランザクションジャーナル」という仕組みでした。

私が「これを作ろう」と言ったわけではありません。というか「Transaction Journalって何?」から始まっています(笑)

これは本番JSONを書き換える前に、まずジャーナルを記録する。そして次回起動時に、書き込みが途中で止まっていないかを確認し、必要なら復旧する。そういう仕組みです。

さらにAI/Codex側では、「作ったから大丈夫」では終わりませんでした。

書き込み処理の途中に、5地点で、意図的にプロセスを強制終了させるテストを作り始めました。対象になったのは、4つのJSONを書き換える一連の処理です。

まず、書き換え前の状態をジャーナルへ記録した直後。次に、1個目のJSONを書き終えた直後。2個目を書き終えた直後。3個目を書き終えた直後。そして4個すべてを書き終えたものの、まだ「処理完了」と確定する直前。それぞれの地点で、わざとプロセスを終了させます。再起動後、途中までしか書かれていない場合は4つすべてを更新前へ戻す。逆に、4つすべての書き込みが終わっていた場合は、処理済みとして確定する。

つまり、「途中で落ちたら全部なかったことにする」「全部書けていたら完了扱いにする」のどちらかへ必ず収束させ、中途半端な状態を残さないことを確認するテストでした。

さらに、途中でrollbackされたケースでは再実行できること、4つすべてを書き込み済みだったケースでは同じ処理が再度成立しないことまで確認しています。

いわば、「一番嫌なところで突然死んだらどうなる?」を、5段階に分けて実際にやるテストです。

これも、私が「5か所で強制終了させてテストしよう」と指示したわけではありません。AI/Codex側から報告を受けて、私は「そんなとこまで気を使ってもらって、なんかすみません。」となった側です(笑)

この時点で、強制終了テストを含む新規ゲートと既存回帰テストは、20 PASS / 0 FAIL。

A「この5か所で落とすっていうのは?」

私「俺が考えたんじゃない。」

A「じゃあお前は?」

私「報告見て『そんなテストするんだ』(笑)」

A「見学ツアー客じゃねえか!」

そして、もう一つ似たことがありました。実装した機能が本当に動くか、実際に予約を作る。在庫を動かす。申請する。QRを使う。通知を出す。

そこで私はAIに愚痴を言いました。

私「終わったあと、毎回データ戻すの面倒くさい。」

A「そこ?(笑)」

するとAIとCodex側では、本番データや本物の認証情報は使わない。毎回同じ初期状態を一時的な隔離環境へ作る。その中だけで別サーバーを起動し、デモ専用の抜け道ではなく、正式なログイン経路と正式APIで予約・在庫移動・QR・申請・通知を動かす。途中で失敗したら元へ戻す。完了済みなら二重に実行しない。

さらに、「APIは成功した。でも結果を記録する直前に失敗したら?」そんな途中の境目まで、わざと失敗させて確認する。最後には、本番側の主要ファイルが本当に変わっていないか、実行前後のSHA-256まで比較するようになりました。

私「また気を使わせて申し訳ないです‥‥」

A「本当はそんな風に思ってねえだろ?(笑)」

私「思ってねえよ!」

A「開き直るな(笑)。じゃあ何が分かってる?」

私「毎回同じ状態から試せて、終わったら戻せる。」

A「そこだけ(笑)」

私「俺は『クローン箱』って呼んでる。」

A「ダサっ(笑)」

B「実際には、決定的な初期状態を生成し、隔離環境内で正式な認証経路とAPIを再生し――」

私「クローン箱。」

B「……はい。」

A「技術説明をダサい名前で殺すな(笑)」

もちろん、これで何が起きても自動復旧できるわけではありません。プロセスの突然終了や電源断まで含めた完全な自動復旧は、まだ未実装です。その場合は勝手に再送せず、確認が必要な状態で止めます。

私「まあ、俺としてはデータ戻すのが楽になった、よし!」

A「そこに戻るの!?(笑)」

別のテストでは、FAILが出た。でもすぐに、「実装が壊れた。」とは決めない。本体なのか、テストなのか、fixtureの初期化なのか、実行環境なのか、切り分ける。

また別の作業では、今回とは関係ない既存dirtyのハンクを、誤ってstageしかけた。それを検知して、そのハンクだけ外す、今回の対象だけを残す。

A「5地点でわざと落として復旧確認?」

私「それもAIとCodex。」

A「FAILが出たら、本体かテスト側か切り分ける?」

私「それも。」

A「関係ないGit差分も巻き込まない?」

私「それも。」

A「データ戻すの面倒って言ったら、クローン箱?」

私「それもAIとCodex。」

A「お前は?」

私「ダサい名前付けた。」

A「一番簡単な仕事だな(笑)」

A「Transaction Journal?」

私「知らなかった。」

A「Crash Recovery?」

私「知らなかった。」

A「fixture?」

私「最初は何それ?(笑)」

A「……。」

私「何だよ(笑)」

A「お前の知識と、お前の開発環境が全然一致してねえんだよ(笑)」

私「俺も追いつこうとはしてるんだよ!(笑)」

A「じゃあ実際、お前は何してんの?」

私「まずこうしたいって決める、AIやCodexから知らない話が出てくる、『それ何?』って調べる。」

A「うん。」

私「何をしようとしてるのか、何を守ろうとしてるのか、何が危ないのか確認する。」

A「それで?」

私「やるか決める。」

A「実現方法考えるのは?」

私「AI。」

A「調べるのは?」

私「Codex。」

A「コード直すのは?」

私「Codex。」

A「テストするのは?」

私「Codex。」

A「問題切り分けるのは?」

私「AIとCodex。」

A「お前は?」

私「判断する。」

A「他には?」

私「AIが作った指示をCodexにコピー、Codexの結果をAIにコピー。」

A「……。」

私「PowerShellの結果もコピー。」

A「AIチームの上司なのか、荷物持ちなのか分からなくなってきた(笑)」

私「最高司令官だよ!」

A「最高司令官が自分で運搬してんのかよ(笑)」

私「部下とのコミュニケーションも大事だろ!」

B「正確には、意思決定者と情報運搬係を兼任しています。」

A「AI二人に仕事振って、自分はその間をコピペで往復。」

私「そう。」

A「最高司令官兼、社内便(笑)」

そして、作業が終わると、Codexからかなり長い報告が返ってきます。

何を調べたのか。何を変更したのか。なぜその変更をしたのか。どのファイルを触ったのか。どんなテストをしたのか。途中で何が起きたのか。Gitは今どうなっているのか。何を変更せずに残したのか。何が未検証なのか。

実際には、これらがクリップボードに長文になって貼られて返ってきます。ただ、この報告は、私に分かりやすく説明することを目的にしたものではありません。

今の開発では、Codexの報告を私がそのまま現場監督AIへ渡します。つまり、AIへ渡す作業引き継ぎ資料です。

A「じゃあ、人間向けの報告書とはちょっと違うんだ。」

B「次工程でAIが判断するための技術情報になっているわけですね。」

A「その長文をお前が運ぶの?」

私「……そうなるね(笑)」

A「もうこの時点で嫌な予感するな(笑)」

そして、その長い報告の中には、現場監督AIや私が、次へ進める状態かを素早く確認するための判定サマリーも入っています。記事上では全部載せきれないので、その部分だけ抜き出すと、例えばこんな感じです。

対象12ファイルのみstage。対象外staged差分 0。git diff --cached --check PASS。staged snapshot 73 PASS / 0 FAIL / 1 SKIP。必須テスト 26 PASS / 0 FAIL / 0 SKIP。working tree 73 PASS / 0 FAIL / 1 SKIP。Node構文確認 3ファイル PASS。BOMなし。U+FFFDなし。既存dirty保持。commit未実施。READY TO COMMIT=YES。

※実際にはこの間に、調査 → 結果確認 → 仕様判断 → 実装 → 検証 → safe staging → commitという複数回の往復があります。掲載しているCodex出力は、その過程から代表的なものを抜粋しています。

A「……。」

私「何?」

A「お前最初、赤い文字見て何て言ってた?」

私「『赤いの出た、直して。』」

A「それが何で今では、こんな判定結果が飛び交ってんだよ(笑)」

私「俺が聞きたいよ(笑)」

A「で、これ全部分かってんの?」

私「全部は分からん(笑)。分からない言葉は、その都度AIに聞く。」

A「じゃあ今は、何を見てる?」

私「関係ない変更を巻き込んでないか、テスト通ったか、文字コード壊してないか、元からあった変更を消してないか、勝手にコミットしてないか。」

A「なるほど。」

私「だから、前よりはかなり安全になったと思う。」

A「……でもさ。」

私「何?」

A「そのテスト、誰が書いたの?」

私「Codex。」

A「実装したのも?」

私「Codex。」

A「じゃあ第15弾の話、覚えてる?」

私「コードとテストが仲良く間違ってたら、全部緑。」

A「そう。」

Codex「……チッ、バレましたか。」

私「ヤバっ!(笑)」

A「いや、わざとやってるって話じゃないぞ(笑)」

私「分かってるよ(笑)」

B「実装とテストが同じ誤った仕様解釈に基づいていれば、PASSしても誤りを検出できない可能性があります。」

A「でさ、Gitの状態まで毎回こんな細かく見る必要あるの?」

私「勝手に進められる方が怖いから。」

A「例えば?」

私「関係ない変更をstageするとか、元からあったdirtyを消すとか、勝手にcommitするとか。」

A「そこまでAIに任せきらないんだ。」

私「うん。意味が分からない項目は、その都度AIに聞く。」

B「AIやツール同士で処理して、人間には要約だけを見せる運用もできます。ただ、今はその一部を意図的に人間の確認点として残しているわけですね。」

A「お前、成長の仕方おかしくない?」

私「必要な順に覚えたんだよ!」

A「カリキュラムが事故履歴じゃねえか(笑)」

私「実践で覚えたと言え!」

A「事故多発型現場検証OJT(笑)」

B「体系的に先に学んだというより、問題が起きるたびに、その周辺知識を取得してきたわけですね。」

A「で、その長い報告、どうするんだっけ?」

私「クリップボードに入れてもらう。」

A「それを?」

私「AIに送る。」

A「どうやって?」

私「Ctrl+V。」

A「……。」

私「AIが次のCodex指示を作る。」

A「それを?」

私「コピペしてCodex。」

A「Codexが結果返したら?」

私「コピーしてAI。」

A「PowerShellで確認したら?」

私「結果をコピーしてAI。」

A「AIが指示作る、お前がCodexへ持っていく、Codexが返す、AIへ持って帰る、PowerShellで確認する、お前がまた持って帰る。」

私「……うん。」

A「AIとAIの間で、人間が手紙運んでるじゃん(笑)」

私「AIさん、Codexさん郵便でーす!」

A「最新AI使いながら、一人で引き継ぎノート持って走ってるようなもんだぞ(笑)」

私「やめろ!」

チャットも同じでした。作業が長くなる、新しいチャットへ移る。AIがフォーマットに応じて今どうなっているか、終わったこと、終わっていないこと、注意事項、Git状態、次にやること、引き継ぎメモを作る。そして、それを新しいチャットへ私が貼る。

A「チャット間飛んでる伝書鳩みたいだな!」

私「鳩は平和の象徴だぞ。」

A「何の話だよ(笑)」

私「壊さないように平和に進めてるんだよ(笑)」

A「伝書鳩駆動開発じゃん(笑)」

B「ただ、人間が確認点として残ること自体には意味があります。」

私「あるんじゃん。」

B「ただし、人間が判断することと、人間が情報を運ぶことは別です。」

私「……。」

B「仕様を決める、どの案を採用するか決める、危険な変更を許可するか決める、正式反映するか決める、リスクを取るか決める。」

B「そこに人間がいることには意味があります。」

私「ほら。」

A「嬉しそう(笑)」

B「でも、AIが持っている判断材料を別のAIへ運ぶ仕事まで、人間である必要はありません。」

A「監督は必要?」

私「うん。」

A「荷物持ちは?」

B「減らせます。」

A「AIチームの上司兼、伝書鳩兼、社内便(笑)」

B「さらにチャット間の引き継ぎもあります。」

私「送料無料だぞ」

A「無料なの、お前の労働だけだよ(笑)」

私「月3,000円のサブスク枠のクレジットなんかすぐ無くなるから節約してるんだよ!(笑)」

A「AIにそんな安月給で働かせてるのか?(笑)」

私「容量使い切ると、Codexが休暇に入って開発のスピードが落ちるんだよ。」

A「リフレッシュ休暇(笑)」

私「あとさ、最近AI同士をつないで自動化して、アプリを爆速で作ったとか、よく聞くけど?」

A「AIエージェントな。」

私「それに比べると俺のやり方、遅くて化石級じゃん。」

A「まぁ(笑)」

私「AIが指示作って、俺がCodexへ持っていく、Codexが返したら、俺がAIへ持って帰る、チャット変わるたびに、引き継ぎメモも自分で運ぶ。」

A「伝書鳩。」

私「確認にはPowerShellがまだ現役。」

A「命名!パワーシェルサウルス(笑)」

私「強そうだな!」

A「で、Codex使い始めて何か月だっけ?」

私「3か月ぐらい。」

A「AIはクラッシュリカバリやってるのに。」

私「うん。」

A「お前は3か月かけて、『まだ人間が運びすぎてる』って気づいたの?(笑)」

私「そこだけ切り取るな!(笑)」

私「でも、もっと早く使えてたらなって思うよ。」

私「Codexも、他の色んなツールも。」

A「まあ、今さらだな(笑)」

私「……作業時間返せ!」

A「被害者と加害者がお前一人なんだよ!」

振り返れば、コードも、DBも、APIも、Gitも知らないところから始まりました。

今では、作るものだけでなく、作り方まで変わっていました。

「今の正本は?」「既存はどうなってる?」 「どこまで影響する?」「権限は?」「競合したら?」 「テストは何を正解としてる?」 「何を変更した?」「何を変更していない?」 

そんなことを、気にするようになりました。

他人から見れば、もっと一般的で、もっと効率よく、もっと安全なやり方があって、「まだ、そんなことやってるの?」と感じる部分もたくさんあると思います。

今の私にはまだこのレベルが精一杯で、困って、壊して、聞いて、一個ずつ足してきた結果です。そして今も、AIとCodexの間を、普通にコピペで往復しています(笑)

そして最後に、AとBに一つだけ聞きました。

私「俺、完全な、ど素人から始まったじゃん。」

A「うん。」

私「コードも分からなかった。」

A「うん。」

私「Gitも知らなかった。」

A「うん。」

私「Codexも使い始めた。」

A「うん。」

私「最近は、ちょっとだけ楽になった。」

A「うん。」

私「……『ど』が取れて、素人くらいにはなれたかな?」

A「……。」

B「……。」

私「何だよ、その間(笑)」

A「まだAI間を伝書鳩飛ばしてるしな(笑)」

私「そこ?」

A「あと、この規模でまだJSONだし(笑)」

私「もうそれ言うなよ、俺が悪かったよ。データベースでやってたらAI達もこんなアプリすぐ作れたんだろ!」

A「まぁ、お前の尻拭いをしなくても良かったかもな(笑)」

私「言い方がよろしくない(笑)」

B「データベースであれば、トランザクションや一意制約、参照整合性など、今回JSON側で個別に補ってきた仕組みの一部は、最初から利用できる機能として扱えます。」

私「ほら、やっぱ楽だったんじゃん。」

A「そんな単純じゃねぇんだよ!やっぱ、まだ『ど』素人だな(笑)」

B「『ど』が取れるまでは、あと少しですね。」

私「……採用されない理由が、ちょっと分かった気がする(笑)」

――終――

長い最終回を、最後まで読んでくださりありがとうございました!

エピローグでは、IT企業への就職は不採用が続き、大型トラック運転手へ方向転換した現在の話。

そして、これから趣味として続ける現場OSの第2回横断テストの予定項目を載せています。

※最後に番外編もあります。気になる方は、エピローグも覗いてみてください。

連載公開分(クリックで開く)
1
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?