確認日: 2026-09-09。対象コミット: 07277b86572f12dd67e6458867541dab7d7aad56。
何が起きるか(静的確認)
executeSave() は saveToIndexedDB() の例外を捕捉し、saveToSessionStorage() を呼んで Promise を正常完了する。後続 then は hasPendingEvents() だけで pending/synced を決め、永続化の成功/失敗を参照しない。
sessionStorage は events を含まない LightweightMultiTabStorage で、quota エラーも捕捉して返る。イベント処理済み(pending=0)でも保存が失敗した場合に、完全な記録が残っていないまま synced を表示しうる。
さらに export 前の flushToIndexedDB() は保存例外を伝播するため、永続化障害が ZIP の緊急出力も妨げる。
今回はコード経路の確認であり、実ブラウザに quota 障害を注入してデータ消失を実測したものではない。
影響・期待した動作
学習者に「保存済み」と見せた記録が reload 後に復旧できない可能性がある。保存状態は PoSW/イベント処理の完了とディスクへの永続化を区別すべき。保存先に障害があっても、メモリに残るデータの救出手段が必要。
再現・回帰テストの設計
- イベント処理が完了し pending=0 のタブを用意する。
- SessionStorageService の appendEvent/updateTab 等に QuotaExceededError または保存拒否を注入する。
- debounce 保存の後、同期状態と最後に永続化できたイベント位置を確認する。
- sessionStorage.setItem も失敗する場合を試験する。
- メモリ上の記録を救出し、その proof を full 検証する。
- 別途 reload を試験し、救済なしでどこまで残るかを確認する。
修正方針
保存処理の結果に failed/degraded を持たせ、最後に永続化したカーソルを表示状態に反映する。再試行には上限/間隔を設ける。緊急 export はイベント処理・スナップショットの整合性を維持しつつ IndexedDB 成功への依存を外す。未処理イベントを黙って捨てて valid な proof と称しない。
受け入れ条件
関連情報
スコープ外
保存基盤全体の置換、サーバーへのソース常時保存。
確認日: 2026-09-09。対象コミット:
07277b86572f12dd67e6458867541dab7d7aad56。何が起きるか(静的確認)
executeSave() は saveToIndexedDB() の例外を捕捉し、saveToSessionStorage() を呼んで Promise を正常完了する。後続 then は hasPendingEvents() だけで pending/synced を決め、永続化の成功/失敗を参照しない。
sessionStorage は events を含まない LightweightMultiTabStorage で、quota エラーも捕捉して返る。イベント処理済み(pending=0)でも保存が失敗した場合に、完全な記録が残っていないまま synced を表示しうる。
さらに export 前の flushToIndexedDB() は保存例外を伝播するため、永続化障害が ZIP の緊急出力も妨げる。
今回はコード経路の確認であり、実ブラウザに quota 障害を注入してデータ消失を実測したものではない。
影響・期待した動作
学習者に「保存済み」と見せた記録が reload 後に復旧できない可能性がある。保存状態は PoSW/イベント処理の完了とディスクへの永続化を区別すべき。保存先に障害があっても、メモリに残るデータの救出手段が必要。
再現・回帰テストの設計
修正方針
保存処理の結果に failed/degraded を持たせ、最後に永続化したカーソルを表示状態に反映する。再試行には上限/間隔を設ける。緊急 export はイベント処理・スナップショットの整合性を維持しつつ IndexedDB 成功への依存を外す。未処理イベントを黙って捨てて valid な proof と称しない。
受け入れ条件
関連情報
スコープ外
保存基盤全体の置換、サーバーへのソース常時保存。