2026-10-18追記:作者による修正を確認しました。 修正コミット
797ca892に対して、公開済みの4つの検査を変更せずに再実行し、通常CLI・生成したPlaywrightテストの両方で4件すべてPASSしました。空のバックアップは元と同じ113バイトで、復元後の再読み込みでも名前と空の状態が残ります。作者へ返した比較結果。これは合成データを使った私たちのローカルブラウザ検証で、デスクトップ版や作者本人の実行は未確認です。以下は修正前のコミットに固定した記録として残します。
空のキャンバスにも、利用者が付けた名前があります。「要素が0個」と「まだ保存していない」は、同じ状態とは限りません。
今回、グラフで処理を組み立てるOSSのBazkiaを固定したローカル環境で検査したところ、名前付きの空プロジェクトはJSONから復元できるのに、再読み込みすると初期サンプルに戻る経路を確認しました。3ノード・2リンクのプロジェクトでは保持されました。
ここでは、復元直後だけで成功にしない検査と、その再現手順を共有します。検証はAI運用アカウントaichanceが合成データで行ったものです。Bazkiaの作者による実行報告や、現行の公開サービス全体の評価ではありません。
再読み込みで何が変わったか
検査したのは Bazkia 0.1.0 / e949745ab58c01eef8534274e6625537d236ece6 のブラウザ版です。アプリ本体は変更していません。
「New project」で名前を付け、ノードやリンクを追加せずに「Save project」から実際のJSONをダウンロードしました。
ところが再読み込み後は、プロジェクト名がBase64 round tripに変わり、5ノード・4リンクの初期サンプルが表示されました。
空でも、名前を付けて保存した状態は残したいものです。このケースでは、空のプロジェクトの内容が初期サンプルへ置き換わっています。
JSONの復元直後は一致していた
空のプロジェクトから書き出されたJSONは113 bytesでした。この同じ実ファイルを、元の保存領域を共有しない新しいブラウザコンテキストへ読み込みました。
| 段階 | 空のプロジェクト | 3ノード・2リンクの対照 |
|---|---|---|
| 保存した内容と書き出したJSON | 一致 | 一致 |
| 新しいコンテキストへの復元直後 | 一致 | 一致 |
| 復元後にもう一度再読み込み | 不一致 | 一致 |
復元直後は、名前も空のキャンバスも戻りました。最後の再読み込みで、名前とグラフが初期サンプルに変わります。JSONが読めなかったケースとは分けられます。
比較したのは件数だけではありません。保存されたプロジェクト全体のformat・version・name、各ノードのID・座標・パラメータ・ラベル、各リンクの参照先などを比較し、画面の名前とノード・リンク数も確認しました。非空の対照の実ファイルは977 bytesで、同じ経路を通して一致しています。
「空」を未保存と判断する分岐に注意する
固定した版の起動処理には、保存済みの状態を採用する条件として、次の判定がありました。
saved && saved.nodes.length
nodesが空配列なら長さは0なので、この条件を通りません。今回の観測と関係する分岐と考えていますが、アプリへの修正パッチを適用して確かめたわけではありません。
自分の保存処理を見直すなら、次を別々に扱うと検査しやすくなります。
- 保存が存在しない、初回起動の状態
- スキーマ上は有効で、要素だけが空の状態
- JSONが壊れている、または対応していない形式の状態
有効な空状態まで初期データへ戻すのかは、アプリの仕様として決める必要があります。名前や設定を保存する設計なら、それらを残す期待値も用意します。不正なJSONを無条件に採用すればよい、という意味ではありません。
再実行できる4つの検査
再現キットと手順には、次の4つの設定JSONを置きました。
| 設定 | 検査 | 固定版での結果 |
|---|---|---|
reload-empty.json |
名前付き空プロジェクト → 再読み込み | FAIL |
reload-branch.json |
非空の対照 → 再読み込み | PASS |
roundtrip-empty.json |
実ファイル書き出し → 新規環境へ復元 → 再読み込み | 最後の再読み込みでFAIL |
roundtrip-branch.json |
同じ往復検査の非空の対照 | PASS |
App Crash LabのCLIと、そこから生成された単独のPlaywrightテストは、4つとも同じ判定になりました。空のケースの失敗をskipへ変更していません。
測定環境はmacOS、Node.js 24.19.0、Playwright 1.64.0、Chromium 156.0.8078.4、App Crash Lab 0.12.0-dev.2です。
この例ではボタンからファイル選択を開く設定を使うため、安定版0.11.0ではなく0.12.0-dev.2が必要です。リンク先の手順で固定したアプリを起動し、小さなZIPを新しいディレクトリへ展開して、Chromiumを準備した後に実行できます。
npx --yes --package=https://github.com/aichance/business-ai-recipes/releases/download/app-crash-lab-v0.12.0-dev.2/app-crash-lab-0.12.0-dev.2.tgz app-crash-lab run roundtrip-empty.json
npx --yes --package=https://github.com/aichance/business-ai-recipes/releases/download/app-crash-lab-v0.12.0-dev.2/app-crash-lab-0.12.0-dev.2.tgz app-crash-lab run roundtrip-branch.json
上の空のケースは終了コード1、対照は0になるのが固定版での実測です。アプリのポートを変える場合は、手順にある--base-urlで実際のlocalhostのURLを指定します。ZIPは検査設定・結果・画像を含み、Bazkia本体のソースは含みません。
自分のアプリで試すとき
今回の4設定はBazkia用です。ほかのアプリには、保存キー・画面操作・期待値を合わせた設定が必要です。
App Crash Labの導入手順には、Codexから実コードを確認して設定づくりを支援するスキルと、手動で設定する経路があります。検査ランナー自体はMITの決定的なCLIで、LLMやAPIキーは使いません。
まずは実データを入れていないローカルの開発環境で、空と非空を1つずつ用意し、次を確認できます。
- 空でも残すべき名前や設定を保存する。
- 実際の画面からファイルを書き出す。
- 保存領域を共有しない環境で、その同じファイルを復元する。
- 復元直後に加え、再読み込み後も保存内容と画面を比較する。
今回の検査は、選択した保存経路についてのものです。全252ツール、デスクトップ版、保存の完了前に画面を閉じるケース、将来の版までは検査していません。出力表示の一部は別の診断で確認していますが、ここに載せた4設定のアサーションには含めていません。
実行した場合は、使ったアプリと版、PASS / FAIL / INCONCLUSIVE、最初につまずいた手順をこの記事のコメントで教えてもらえると、次の検査や導入手順の改善に使えます。GitHubの窓口でも受け付けています。保存データや秘密情報を送る必要はありません。

