ファイル履歴スナップショットの永続化
概要
この変更により、永続化される JSONL スキーマを変更することなく、/rewind ファイル履歴の A+C 永続化のギャップを解消します。
file_history_snapshot レコードは追記専用のシステム レコードのままです。再開(Resume)時は、リニア履歴内のすべてのスナップショット レコードを読み取り、last-wins セマンティクスで promptId ごとに重複排除することでファイル履歴を再構築します。つまり、同じプロンプトの更新されたスナップショットは、古いログを書き換えることなく後から追記できます。
スナップショット更新の記録
makeSnapshot(promptId) は引き続きターン境界のスナップショットを作成し、呼び出し元は引き続きそれを明示的に記録します。欠落していた最終ターンのケースは、FileHistoryService にオプションのレコーダー コールバックを渡すことで処理されます。trackEdit(filePath) が最新の快照(スナップショット)に新しいバックアップを正常に追加した場合、またはそのスナップショット内の失敗したバックアップ エントリを修復した場合、更新されたスナップショットを指定してレコーダーを呼び出します。
すでにキャプチャされた失敗していないファイルに対する重複する trackEdit 呼び出しは、スナップショットが変更されないため、再度記録されません。
レコーダーのエラーは握りつぶされ、ログに記録されます。ファイルの編集はベストエフォートである必要があります。ファイル履歴の永続化によって、編集ツールや書き込みツールが失敗してはなりません。
永続化の形状
スキーマ バージョンは追加されません。既存のペイロードには、後方互換性のある再構築に必要な十分な構造がすでに備わっています。
{
"type": "system",
"subtype": "file_history_snapshot",
"systemPayload": {
"snapshots": []
}
}これらのレコードを含まない古いログは、ファイル履歴の状態なしで引き続き再開されます。不正な形式のスナップショット レコードは警告とともにスキップされ、その後の有効なレコードは引き続き使用可能です。
明示的な isSnapshotUpdate フラグは追加されません。同じ promptId を持つ別の file_history_snapshot レコードを追記しても、SessionService.loadSession() によってすでに promptId による last-wins 重複排除が適用されているため、実質的な動作は同じになります。
対象範囲
これは A+C のみ対象です。
B1 のシミュレートされた sed -i カバレッジは別の PR に残されます。汎用シェル編集トラッキング、getDiffStats の同時実行制限、およびファイルごとの失敗理由も先送りされます。Claude Code は現在これらの動作をサポートしていないため、qwen-code もこの互換性パスの一部としてそれらを追加すべきではありません。
永続化されるレコードの形状は変更されていないため、移行は不要です。