Get started

データベース優先の状態管理リファクタリング

データベースファーストの状態リファクタリング

決定

2階層のSQLite構成を使用します。

  • グローバルデータベース: ~/.openclaw/state/openclaw.sqlite
  • エージェントデータベース: エージェントが所有するワークスペース、トランスクリプト、VFS、アーティファクト、およびエージェントごとの大規模なランタイム状態のために、エージェントごとに1つのSQLiteデータベース
  • 設定は引き続きファイルベースです。openclaw.json はデータベース外に残します。ランタイム認証プロファイルはSQLiteに移行しますが、外部プロバイダーまたはCLIの認証情報ファイルは、OpenClawのデータベース外で引き続き各所有者が管理します。

グローバルデータベースはコントロールプレーンのデータベースです。エージェント検出、共有Gateway状態、ペアリング、デバイス/Node状態、タスクおよびフローの台帳、Plugin状態、スケジューラーのランタイム状態、バックアップメタデータ、移行状態を所有します。

エージェントデータベースはデータプレーンのデータベースです。エージェントのセッションメタデータ、トランスクリプトイベントストリーム、VFSワークスペースまたはスクラッチ名前空間、ツールアーティファクト、実行アーティファクト、および検索・インデックス作成が可能なエージェントローカルのキャッシュデータを所有します。

これにより、大規模なエージェントワークスペース、トランスクリプト、バイナリスクラッチデータを共有Gatewayの書き込みレーンに押し込むことなく、永続的なグローバルビューを1つ提供できます。

厳格な契約

この移行における正規のランタイム形状は1つだけです。

  • セッション行にはセッションメタデータのみを永続化します。transcriptLocator、トランスクリプトのファイルパス、関連するJSONLパス、ロックパス、枝刈りメタデータ、またはファイル時代の互換性ポインターを永続化してはなりません。
  • トランスクリプトの識別子は常にSQLiteの識別子です。つまり {agentId, sessionId} に加え、プロトコルで必要な場合は任意のトピックメタデータを使用します。
  • sqlite-transcript://... はランタイムまたはプロトコルの識別子ではありません。新しいコードはトランスクリプトロケーターを導出、永続化、受け渡し、解析、移行してはなりません。ランタイムとテストには疑似ロケーターを一切含めるべきではありません。ドキュメントでこの文字列に言及できるのは、禁止を示す場合のみです。
  • レガシーの sessions.json、トランスクリプトJSONL、.jsonl.lock、枝刈り、切り詰め、古いセッションパスロジックは、doctorの移行/インポート経路にのみ属します。
  • レガシーのセッション設定エイリアスはdoctorの移行にのみ属します。ランタイムは session.idleMinutessession.resetByType.dm、または別の設定済みエージェントに対するエージェント横断の agent:main:* メインセッションエイリアスを解釈しません。
  • セッションルーティングの識別子は、型付けされたリレーショナル状態です。ホットなランタイム経路とUI経路では、sessions.session_scopesessions.account_idsessions.primary_conversation_idconversationssession_conversations を読み取るべきです。古い呼び出し箇所を削除している間の互換性用シャドウを除き、session_key を解析したり、プロバイダー識別子を得るために session_entries.entry_json を掘り起こしたりしてはなりません。
  • dmdirect のようなチャネルレベルのダイレクトメッセージマーカーはルーティング用語であり、トランスクリプトロケーターやファイルストア互換性ハンドルではありません。
  • レガシーのフックハンドラー設定はdoctorの警告/移行サーフェスにのみ属します。ランタイムは hooks.internal.handlers を読み込んではなりません。フックは、検出されたフックディレクトリと HOOK.md メタデータのみを通じて実行します。
  • ランタイム起動、ホットな返信経路、Compaction、リセット、復旧、診断、TTS、メモリフック、サブエージェント、Pluginコマンドルーティング、プロトコル境界、フックでは、ランタイム全体を通して {agentId, sessionId} を受け渡す必要があります。
  • テストでは {agentId, sessionId} を通じてSQLiteトランスクリプト行を投入し、検証すべきです。JSONLパスの転送、呼び出し元が提供したロケーターの保持、またはトランスクリプトファイルの互換性のみを証明するテストは、doctorのインポート、セッション以外のサポート/デバッグ用マテリアライズ、またはプロトコル形状を対象としていない限り削除すべきです。
  • runEmbeddedPiAgent(...)、準備済みワーカー実行、および内部の埋め込み試行は、トランスクリプトロケーターを受け付けてはなりません。これらは {agentId, sessionId} によりSQLiteトランスクリプトマネージャーを開き、そのマネージャーを内部化されたPI互換エージェントセッションに渡します。これにより、古い呼び出し元がランナーにJSON/JSONLトランスクリプトを書き込ませることを防ぎます。
  • ランナー診断は、ランタイム/キャッシュ/ペイロードのトレースレコードをSQLiteに保存する必要があります。ランタイム診断は、JSONLファイルの上書き設定や汎用的なトランスクリプトJSONLエクスポートヘルパーを公開してはなりません。ユーザー向けエクスポートでは、ファイル名をランタイムへ戻すことなく、データベース行から明示的なアーティファクトをマテリアライズできます。
  • 生ストリームのログ記録には、OPENCLAW_RAW_STREAM=1 とSQLite診断行を使用します。古いpi-monoの PI_RAW_STREAMPI_RAW_STREAM_PATHraw-openai-completions.jsonl ファイルロガー契約は、OpenClawのランタイムやテストには含まれません。
  • QMDのメモリインデックス作成では、SQLiteトランスクリプトをMarkdownファイルへエクスポートしてはなりません。QMDがインデックスを作成するのは設定済みメモリファイルのみです。セッショントランスクリプトの検索は引き続きSQLiteベースです。
  • 新しいコードでは、QMD SDKサブパスはQMD専用です。SQLiteセッショントランスクリプトのインデックス作成ヘルパーは memory-core-host-engine-session-transcripts に配置します。QMDからの再エクスポートは互換性専用であり、ランタイムコードで使用してはなりません。
  • 組み込みメモリインデックスは、それを所有するエージェントデータベースに配置します。ランタイム設定と解決済みランタイム契約は memorySearch.store.path を公開してはなりません。doctorはそのレガシー設定キーを削除し、現行コードはエージェントの databasePath を内部的に渡します。

実装作業では、doctor/インポート/エクスポート/デバッグの境界外に例外なくこれらの記述が成立するまで、コードの削除を続けるべきです。

目標状態と進捗

厳格な目標

  • 1つのグローバルSQLiteデータベースがコントロールプレーン状態を所有します。 state/openclaw.sqlite
  • エージェントごとに1つのSQLiteデータベースがデータプレーン状態を所有します。 agents/<agentId>/agent/openclaw-agent.sqlite
  • 設定は引き続きファイルベースです。openclaw.json はこのデータベースリファクタリングの対象ではありません。
  • レガシーファイルはdoctorの移行入力としてのみ使用します。
  • ランタイムは、アクティブな状態としてセッションまたはトランスクリプトJSONLを読み書きしません。

目標状態

  • not-started: ファイル時代のランタイムコードが依然としてアクティブな状態を書き込みます。
  • migrating: doctor/インポートコードがファイルデータをSQLiteへ移行できます。
  • dual-read: 一時的な橋渡しとしてSQLiteとレガシーファイルの両方を読み取ります。このリファクタリングでは、doctor専用であることが明示的に文書化されていない限り、この状態は禁止です。
  • sqlite-runtime: ランタイムはSQLiteのみを読み書きします。
  • clean: レガシーのランタイムAPIとテストが削除され、ガードによってリグレッションが防止されます。
  • done: ドキュメント、テスト、バックアップ、doctorの移行、変更チェックによってクリーンな状態が証明されます。

現在の状態

  • セッション: ランタイムについては clean。セッション行はエージェントごとのデータベースに存在し、ランタイムAPIは {agentId, sessionId} または {agentId, sessionKey} を使用します。sessions.json はdoctor専用のレガシー入力です。
  • トランスクリプト: ランタイムについては clean。トランスクリプトイベント、識別子、スナップショット、軌跡ランタイムイベントは、エージェントごとのデータベースに存在します。ランタイムはトランスクリプトロケーターやJSONLトランスクリプトパスを受け付けなくなりました。
  • PI埋め込みランナー: clean。埋め込みPI実行、準備済みワーカー、Compaction、再試行ループはSQLiteセッションスコープを使用し、古いトランスクリプトハンドルを拒否します。
  • Cron: ランタイムについては clean。ランタイムは cron_jobscron_run_logs を使用します。ランタイムテストはSQLiteの storeKey 命名を使用し、ファイル時代のCronパスはdoctorのレガシー移行テストにのみ残っています。
  • タスクレジストリ: clean。タスクとTask Flowのランタイム行は state/openclaw.sqlite に存在します。未リリースのサイドカーSQLiteインポーターは削除されています。
  • Plugin状態: clean。Plugin状態/Blob行は共有グローバルデータベースに存在します。古いPlugin状態用サイドカーSQLiteヘルパーの使用はガードされています。
  • メモリ: 組み込みメモリとセッショントランスクリプトのインデックス作成については sqlite-runtime。メモリインデックステーブルはエージェントごとのデータベースに存在し、Pluginのメモリ状態は共有Plugin状態行を使用します。レガシーメモリファイルはdoctorの移行入力またはユーザーワークスペースの内容です。
  • バックアップ: sqlite-runtime。バックアップステージはSQLiteスナップショットを圧縮し、稼働中のWAL/SHMサイドカーを除外し、SQLiteの整合性を検証し、バックアップ実行をグローバルデータベースに記録します。
  • doctorの移行: 意図的に migrating。doctorはレガシーJSON、JSONL、廃止されたサイドカーストアをSQLiteへインポートし、移行の実行/ソースを記録し、正常に処理されたソースを削除します。
  • E2Eスクリプト: ランタイムカバレッジについては clean。Docker MCPのシード処理はSQLite行を書き込みます。ランタイムコンテキスト用DockerスクリプトがレガシーJSONLを作成するのはdoctor移行用シード内だけであり、レガシーセッションインデックスパスを明示的に命名しています。

残作業

  • [x] doctorのレガシー入力でない限り、Cronランタイムテストのストア変数名を storePath 以外へ変更する。 ファイル: src/cron/service.test-harness.tssrc/cron/service.runs-one-shot-main-job-disables-it.test.tssrc/cron/service/timer.regression.test.tssrc/cron/service/ops.test.tssrc/cron/service/store.test.tssrc/cron/service.heartbeat-ok-summary-suppressed.test.tssrc/cron/service.main-job-passes-heartbeat-target-last.test.tssrc/cron/store.test.ts。 証明: pnpm check:database-first-legacy-stores; rg -n 'storePath' src/cron --glob '!**/commands/doctor/**'
  • [x] 廃止されたファイル時代のエクスポートテストモックを削除または改名する。 ファイル: src/auto-reply/reply/commands-export-test-mocks.ts。 証明: rg -n 'resolveSessionFilePath|sessionFile|storePath|transcriptLocator' src/auto-reply/reply
  • [x] DockerランタイムコンテキストのレガシーJSONLシードが明確にdoctor専用だと分かるようにする。 ファイル: scripts/e2e/session-runtime-context-docker-client.ts。 証明: rg -n 'sessions\\.json|sessionFile|\\.jsonl' scripts/e2e/session-runtime-context-docker-client.ts では seedBrokenLegacySessionForDoctorMigration のみが表示される。
  • [x] スキーマ変更後もKyselyの生成型を整合させる。 ファイル: src/state/openclaw-state-schema.sqlsrc/state/openclaw-agent-schema.sqlsrc/state/*generated*。 証明: 今回の変更ではスキーマ変更なし。pnpm db:kysely:check; pnpm lint:kysely
  • [x] 変更したストア、コマンド、スクリプトに対して対象を絞ったテストを再実行する。 証明: pnpm test src/cron/service/store.test.ts src/cron/store.test.ts src/cron/service.heartbeat-ok-summary-suppressed.test.ts src/cron/service.main-job-passes-heartbeat-target-last.test.ts src/cron/service.every-jobs-fire.test.ts src/cron/service.persists-delivered-status.test.ts src/cron/service.runs-one-shot-main-job-disables-it.test.ts src/cron/service/ops.test.ts src/cron/service/timer.regression.test.ts src/auto-reply/reply/commands-export-trajectory.test.ts extensions/telegram/src/thread-bindings.test.ts extensions/slack/src/monitor/message-handler/prepare.test.ts src/acp/translator.session-lineage-meta.test.ts; git diff --check
  • [x] done と宣言する前に、変更ゲートまたはリモートでの広範な証明を実行する。 証明: pnpm check:changed --timed -- <changed extension paths> は、一時的なNode 24/pnpmセットアップと、同期された.gitなしワークスペース向けの明示的なパスルーティングを行った後、Hetzner Crabbox実行 run_3f1cabf6b25c で成功した。

リグレッション禁止事項

  • トランスクリプトロケーターを使用しない。
  • アクティブなセッションファイルを使用しない。
  • doctorのレガシー移行テストを除き、偽のJSONLテストフィクスチャを使用しない。
  • Kyselyの使用が想定される場所で、SQLiteへ直接アクセスしない。
  • ファイル時代の新しいDB移行を追加しない。グローバルスキーマはバージョン 1 のままです。 リリース済みのエージェントごとのバージョン 1 スキーマには、安定したメモリソース識別子のため、バージョン 2 への限定的なランタイム移行が1つあります。

コード確認時の前提

この計画を妨げる追加のプロダクト判断はありません。実装は次の前提に基づいて進めるべきです。

  • このストレージパスでは node:sqlite を直接使用し、Node 22+ ランタイムを必須とします。
  • 通常の設定ファイルは厳密に 1 つだけ維持します。このリファクタリングでは、設定、Plugin マニフェスト、Git ワークスペースを SQLite に移動しません。
  • ランタイム互換性ファイルは不要です。従来の JSON および JSONL ファイルは移行入力としてのみ扱います。ブランチローカルの SQLite サイドカーは一度もリリースされていないため、インポートせずに削除します。
  • 従来のファイルからデータベースへの移行は openclaw doctor --fix が担います。ランタイム起動時に行うのは、リリース済みの SQLite スキーマバージョン間における範囲の限定されたアップグレードのみです。ファイル時代の状態をインポートしてはなりません。
  • 認証情報の互換性にも同じルールを適用します。ランタイムの認証情報は SQLite に保存します。古い auth-profiles.json、エージェントごとの auth.json、共有の credentials/oauth.json ファイルは doctor の移行入力として使用し、インポート後に削除します。
  • 生成されたモデルカタログの状態はデータベースに保存します。ランタイムコードは agents/<agentId>/agent/models.json に書き込んではなりません。既存の models.json ファイルは従来形式の doctor 入力として扱い、agent_model_catalogs へのインポート後に削除します。
  • ランタイムはトランスクリプトロケーターを移行、正規化、橋渡ししてはなりません。SQLite におけるアクティブなトランスクリプトの識別子は {agentId, sessionId} です。ファイルパスは従来形式の doctor 入力としてのみ扱い、sqlite-transcript://... は境界ハンドルとして扱うのではなく、ランタイム、プロトコル、フック、Plugin の各サーフェスから排除しなければなりません。
  • ランタイムによる SQLite トランスクリプトの読み取りでは、古い JSONL エントリ形式の移行や、互換性確保のためのトランスクリプト全体の再書き込みを行いません。従来形式のエントリの正規化は、明示的な doctor/インポートユーティリティにのみ残します。doctor は従来の JSONL トランスクリプトファイルを正規化してから SQLite の行を挿入します。現在のランタイム行は、すでに現在のトランスクリプトスキーマで書き込まれています。軌跡/セッションのエクスポートでは、それらの行をそのまま読み取り、エクスポート時に従来形式の移行を実行してはなりません。
  • 従来のトランスクリプト JSONL の解析/移行ヘルパーは doctor 専用です。ランタイムのトランスクリプト形式コードは、現在の SQLite トランスクリプトコンテキストのみを構築します。古い JSONL エントリを行として挿入する前のアップグレードは doctor が担います。
  • ランタイムが所有していた古い JSONL トランスクリプトストリーミングヘルパーは削除されました。doctor のインポートコードが従来ファイルの明示的な読み取りを担い、ランタイムのセッション履歴は SQLite の行を読み取ります。
  • Codex app-server バインディングでは、OpenClaw の sessionId を Codex Plugin 状態名前空間の正規キーとして使用します。sessionKey はルーティング/表示用のメタデータであり、永続的なセッション ID を置き換えたり、トランスクリプトファイルの識別子を復活させたりしてはなりません。
  • コンテキストエンジンは、現在のランタイム契約を直接受け取ります。レジストリは、sessionKeytranscriptScopeprompt を削除する再試行シムでエンジンをラップしてはなりません。現在のデータベース優先パラメータを受け入れられないエンジンは、橋渡しするのではなく明示的に失敗させる必要があります。
  • バックアップ出力は単一のアーカイブファイルのままにします。データベースの内容は、生の稼働中 WAL サイドカーではなく、コンパクトな SQLite スナップショットとしてそのアーカイブに格納する必要があります。
  • トランスクリプト検索は有用ですが、最初のデータベース優先版には必須ではありません。後から FTS を追加できるようにスキーマを設計します。
  • データベース境界が安定するまでは、ワーカー実行を設定の背後にある実験的機能として維持します。

コード調査結果

現在のブランチは、すでに概念実証の段階を過ぎています。共有データベースは存在し、Node の node:sqlite は小規模なランタイムヘルパーを介して接続され、以前のストアは現在 state/openclaw.sqlite または所有元の openclaw-agent.sqlite データベースに書き込んでいます。

残っている作業は SQLite を選択することではありません。新しい境界を明確に保ち、古いファイル世界に似た互換性指向のインターフェースを削除することです。

  • セッションの storePath は、ランタイム識別子、テストフィクスチャ形式、ステータスペイロードフィールドではなくなりました。ランタイムおよびブリッジのテストには storePath という契約名が存在せず、その従来の用語は doctor/移行コードが所有します。
  • セッションの書き込みは、古いインプロセスの store-writer.ts キューを経由しなくなりました。SQLite パッチ書き込みはトランザクションの外部で準備した後、明示的な競合検出を備えた短時間の同期的な検証/適用トランザクションを使用します。
  • 従来のパス探索には移行用途として引き続き正当性がありますが、ランタイムコードは sessions.json およびトランスクリプト JSONL ファイルを潜在的な書き込み先として扱うのをやめる必要があります。
  • エージェントが所有するテーブルは、エージェントごとの SQLite データベースに配置します。グローバル DB はレジストリ/コントロールプレーンの行を保持します。トランスクリプトの識別子は、エージェントごとのトランスクリプト行における {agentId, sessionId} です。ランタイムコードはトランスクリプトのファイルパスを永続化したり、トランスクリプトロケーターを移行したりしてはなりません。
  • doctor はすでに複数の従来ファイルをインポートしています。クリーンアップでは、これを doctor が呼び出す単一の明示的な移行実装にまとめ、永続的な移行レポートを生成します。

実装を妨げる追加の製品上の問題はありません。

現在のコード構成

このブランチには、すでに実用的な共有 SQLite 基盤があります。

  • ランタイムの最低要件は Node 22+ になりました。package.json、CLI のランタイムガード、 インストーラーのデフォルト、macOS ランタイムロケーター、CI、公開インストールドキュメントの すべてで要件が統一されています。従来の Node 22 互換性レーンは削除されました。
  • src/state/openclaw-state-db.tsopenclaw.sqlite を開き、WAL、 synchronous=NORMALbusy_timeout=30000foreign_keys=ON を設定し、 src/state/openclaw-state-schema.sql から生成された スキーマモジュールを適用します。
  • Kysely のテーブル型とランタイムスキーマモジュールは、コミット済みの .sql ファイルから 作成される使い捨ての SQLite データベースを基に生成されます。ランタイムコードでは、 グローバル、エージェント単位、またはプロキシキャプチャ用データベースのスキーマ文字列を コピー&ペーストして保持することはなくなりました。
  • ランタイムストアは、SQLite の行構造を手動で重複定義する代わりに、生成された Kysely の DB インターフェースから選択行と挿入行の型を導出します。生 SQL の使用は、 スキーマの適用、プラグマ、およびマイグレーション専用 DDL に限定されます。
  • グローバル SQLite スキーマは引き続き user_version = 1 です。エージェント単位のスキーマは バージョン 2 で、そのオープナーはリリース済みバージョン 1 のメモリソースキーを 安定した整数 ID へアトミックに移行します。ファイルからデータベースへのインポートは 引き続き doctor コードで行われます。
  • 所有権の境界が正規である箇所では、リレーショナルな所有関係が強制されます。 ソースマイグレーション行は migration_runs から、タスク配信状態は task_runs から、 トランスクリプト ID 行はトランスクリプトイベントからカスケードされます。
  • 現在の共有テーブルには、agent_databasesauth_profile_storesauth_profile_stateplugin_state_entriesplugin_blob_entriesmedia_blobsskill_uploadscapture_sessionscapture_eventscapture_blobssandbox_registry_entriescron_run_logscron_jobscommitmentsdelivery_queue_entriesmodel_capability_cacheworkspace_setup_statenative_hook_relay_bridgescurrent_conversation_bindingsplugin_binding_approvalstui_last_sessionsacp_sessionsacp_replay_sessionsacp_replay_eventstask_runstask_delivery_stateflow_runssubagent_runsmigration_runs、および backup_runs が含まれます。
  • Plugin が所有する任意の状態に、ホスト所有の型付きテーブルを割り当てることはありません。 インストール済み Plugin は、バージョン付き JSON ペイロードには plugin_state_entries、 バイト列には plugin_blob_entries を使用し、名前空間/キーの所有権、TTL クリーンアップ、 バックアップ、および Plugin のマイグレーション記録を利用します。ホストがクエリ契約を 所有する場合、plugin_binding_approvals など、ホスト所有の Plugin オーケストレーション状態には 引き続き型付きテーブルを使用できます。
  • Plugin のマイグレーションは、ホストスキーマのマイグレーションではなく、Plugin が所有する 名前空間に対するデータマイグレーションです。Plugin はマイグレーションプロバイダーを介して 自身のバージョン付き状態/Blob エントリを移行でき、ホストは通常のマイグレーション台帳に ソース/実行状態を記録します。ホスト自体が Plugin 間の新しい契約の所有権を引き受ける場合を 除き、新しい Plugin のインストールに openclaw-state-schema.sql の変更は必要ありません。
  • src/state/openclaw-agent-db.tsagents/<agentId>/agent/openclaw-agent.sqlite を開き、そのデータベースをグローバル DB に 登録し、エージェントローカルのセッション、トランスクリプト、VFS、成果物、キャッシュ、 およびメモリインデックスの各テーブルを所有します。共有ランタイムの検出処理は、呼び出し箇所ごとに クエリを再実装するのではなく、生成された型を持つ agent_databases レジストリを読み取るようになりました。
  • グローバルおよびエージェント単位のデータベースは、データベースの役割、スキーマバージョン、 タイムスタンプ、およびエージェントデータベースの場合はエージェント ID を含む schema_meta 行を 記録します。グローバル DB は引き続き user_version = 1 です。エージェント単位の DB は、 限定的なメモリソース ID マイグレーション後にバージョン 2 を使用します。
  • エージェント単位のセッション ID には、session_id をキーとする正規のルートテーブル sessions が設けられました。session_keysession_scopeaccount_idprimary_conversation_id、タイムスタンプ、表示フィールド、モデルメタデータ、 ハーネス ID、親/生成元の関連付けが、クエリ可能な列として格納されます。session_routessession_key から現在の session_id への一意なアクティブルートインデックスです。 これにより、ホットリードで重複する sessions.session_key 行から選択することなく、 ルートキーを新しい永続セッションへ移動できます。従来の互換性形式の session_entries.entry_json ペイロードは、外部キーによって永続的な session_id ルートに 接続されます。これはもはや、スキーマレベルでセッションを表現する唯一の方法ではありません。
  • エージェント単位の外部会話 ID もリレーショナルになりました。 conversations は正規化されたプロバイダー/アカウント/会話 ID を格納し、 session_conversations は 1 つの OpenClaw セッションを 1 つ以上の外部会話に関連付けます。 これは、複数の相手を意図的に 1 つのセッションへマッピングできる共有メイン DM セッションを、 session_key に虚偽の情報を格納せずに扱います。SQLite はプロバイダーの自然 ID に対する 一意性も強制するため、同じチャネル/アカウント/種別/相手/スレッドの組を複数の会話 ID に 分岐させることはできません。共有メインの直接の相手は participant ロールで関連付けられるため、 1 つの OpenClaw セッションで複数の外部 DM 相手を表現でき、以前の相手を曖昧な関連行へ 降格させる必要はありません。sessions.primary_conversation_id は引き続き現在の型付き配信先を 指します。閉じた集合であるルーティング/状態列は、TypeScript のユニオンだけに依存せず、 SQLite の CHECK 制約で強制されます。 ランタイムのセッション投影は、型付きセッション/会話列を適用する前に session_entries.entry_json から互換性用ルーティングのシャドウ値を消去するため、 古い JSON ペイロードが配信先を復活させることはありません。 サブエージェントの通知ルーティングでも同様に、型付き SQLite 配信コンテキストが必須となり、 互換性用の SessionEntry ルートフィールドへのフォールバックは行われなくなりました。 Gateway の chat.send における明示的な配信継承は、originlast* 互換性フィールドではなく、 型付き SQLite 配信コンテキストを読み取ります。 同様に、tools.effective は古い last* セッションエントリのシャドウ値ではなく、 型付き SQLite 配信/ルーティング行からプロバイダー/アカウント/スレッドのコンテキストを導出します。 システムイベントのプロンプトコンテキストは、origin のシャドウ値ではなく、 型付き配信フィールドからチャネル/宛先/アカウント/スレッドの各フィールドを再構築します。 共有の deliveryContextFromSession ヘルパーとセッションから会話へのマッパーは、 SessionEntry.origin を完全に無視するようになりました。ホットルート ID を作成できるのは、 型付き配信フィールドとリレーショナルな会話行だけです。 ランタイムのセッションエントリ正規化では、entry_json の永続化または投影前に origin を除去し、 インバウンドメタデータの書き込みでは、新しい origin シャドウ値を作成する代わりに、 型付きチャネル/チャットフィールドとリレーショナルな会話行を書き込みます。
  • トランスクリプトイベント、トランスクリプトスナップショット、および軌跡ランタイムイベントは、 正規のエージェント単位 sessions ルートを参照し、セッション削除時にカスケードされるようになりました。 トランスクリプト ID/冪等性の行は、引き続き対応する正確なトランスクリプトイベント行から カスケードされます。
  • memory-core インデックスでは、明示的なエージェントデータベーステーブル memory_index_metamemory_index_sourcesmemory_index_chunks、および memory_embedding_cache を使用し、memory_index_state でリビジョン変更を追跡するようになりました。 オプションの FTS/ベクトルサイドインデックスには、汎用的な metafileschunkschunks_ftschunks_vec テーブルではなく、memory_index_chunks_fts および memory_index_chunks_vec という名前が付けられます。正規名は、現在のパス/ソース行の構造と シリアライズ済み埋め込みの互換性を維持します。これらのテーブルは派生/検索キャッシュであり、 正規のトランスクリプトストレージではありません。メモリワークスペースファイルと設定済みソースから 削除して再構築できます。リリース済みの汎用名メモリインデックスを開くと、そのメタデータ、 ソース、チャンク、および埋め込みキャッシュが正規テーブルへ移行されます。派生した FTS/ベクトル テーブルは、正規名で再構築されます。
  • サブエージェント実行の復旧状態は、子、リクエスター、およびコントローラーのセッションキーに インデックスを持つ、型付き共有 subagent_runs 行に格納されるようになりました。従来の subagents/runs.json ファイルは、doctor のマイグレーション入力としてのみ使用されます。
  • 現在の会話バインディングは、正規化された会話 ID をキーとする型付き共有 current_conversation_bindings 行に格納されるようになりました。対象エージェント/セッション列、 会話種別、状態、有効期限、およびメタデータは、重複した不透明なバインディングレコードではなく、 リレーショナルな列として格納されます。永続的なバインディングキーには正規化された会話種別が 含まれるため、直接/グループ/チャネル参照が衝突することはなく、SQLite は無効なバインディングの 種別/状態値を拒否します。従来の bindings/current-conversations.json ファイルは、doctor のマイグレーション入力としてのみ使用されます。
  • 配信キューの復旧では、チャネル、対象、アカウント、セッション、再試行、エラー、 プラットフォーム送信、および復旧状態の型付きキュー列を、リプレイ JSON に重ねるようになりました。 entry_json はリプレイペイロード、フック、およびフォーマット用ペイロードを保持しますが、 ホットキューのルーティング/状態については型付き列が正となります。
  • TUI の最終セッション復元ポインターは、ハッシュ化された TUI 接続/セッションスコープをキーとする 型付き共有 tui_last_sessions 行に格納されるようになりました。従来の TUI JSON ファイルは、 doctor のマイグレーション入力としてのみ使用されます。
  • デフォルトの TTS 設定は、speech-core Plugin 配下をキーとする共有 Plugin 状態の SQLite 行に格納されるようになりました。従来の settings/tts.json ファイルは doctor の マイグレーション入力としてのみ使用されます。ランタイムは TTS 設定の JSON ファイルを 読み書きしなくなり、レガシーパスリゾルバーは doctor のマイグレーションモジュールに置かれます。
  • シークレット対象のメタデータでは、すべての認証情報の対象を設定ファイルであるかのように扱わず、 ストアとして記述するようになりました。openclaw.json は引き続き設定ストアです。 認証プロファイルの対象では、プロバイダー形式の認証情報を JSON ペイロードとして保持する、 型付き SQLite auth_profile_stores 行を使用します。
  • シークレット監査では、廃止されたエージェント単位の auth.json ファイルをスキャンしなくなりました。 そのレガシーファイルに関する警告、インポート、および削除は doctor が担当します。
  • レガシー認証プロファイルのパスヘルパーは、doctor のレガシーコードに置かれるようになりました。 コアの認証プロファイルパスヘルパーは、auth-profiles.jsonauth-state.json の ランタイムパスではなく、SQLite 認証ストアの ID と表示場所を公開します。
  • サブエージェント実行の復旧モジュールと OpenRouter モデル機能キャッシュのランタイムモジュールは、 SQLite スナップショットのリーダー/ライターを、doctor 専用のレガシー JSON インポートヘルパーから 分離するようになりました。OpenRouter の機能には、不透明なキャッシュ Blob やプロバイダー固有の ホストテーブルではなく、provider_id = "openrouter" 配下の型付き汎用 model_capability_cache 行を使用します。サブエージェント実行の taskName は、 型付き subagent_runs.task_name 列に格納されます。payload_json のコピーは リプレイ/デバッグ用データであり、ホット表示や検索フィールドの情報源ではありません。
  • src/agents/filesystem/virtual-agent-fs.sqlite.ts は、エージェントデータベースの vfs_entries テーブル上に SQLite VFS を実装します。ディレクトリの読み取り、再帰的エクスポート、 削除、および名前変更では、名前空間全体をスキャンしたり LIKE によるパス照合に依存したりせず、 インデックス付きの (namespace, path) プレフィックス範囲を使用します。
  • src/agents/runtime-worker.entry.ts は、ワーカーごとに実行単位の SQLite VFS、 ツール成果物、実行成果物、およびスコープ付きキャッシュストアを作成します。
  • ワークスペースのブートストラップ完了マーカーは、.openclaw/workspace-state.json ではなく、 解決済みワークスペースパスをキーとする型付き共有 workspace_setup_state 行に 格納されるようになりました。ランタイムはレガシーワークスペースマーカーを読み取ったり 書き換えたりしなくなり、ヘルパー API もストレージ ID を導出するためだけに架空の .openclaw/setup-state パスを受け渡すことはなくなりました。
  • exec 承認は、型付き共有 SQLite exec_approvals_config のシングルトン行に格納されるようになりました。 doctor はレガシーの ~/.openclaw/exec-approvals.json をインポートします。ランタイムの書き込みで そのファイルを作成または書き換えることはなくなり、アクティブなストアの場所として報告することも ありません。macOS コンパニオンは同じ state/openclaw.sqlite テーブル行を読み書きします。 ディスク上に保持するのは Unix プロンプトソケットだけです。これは永続ランタイム状態ではなく IPC であるためです。
  • デバイス ID、デバイス認証、およびブートストラップの各ランタイムモジュールは、 SQLite スナップショットのリーダー/ライターを、doctor 専用のレガシー JSON インポートヘルパーから 分離するようになりました。デバイス ID には型付き device_identities 行を使用し、 デバイス認証トークンには型付き device_auth_tokens 行を使用します。デバイス認証の書き込みでは、 トークンテーブルを切り詰めるのではなく、デバイス/ロールごとに行を整合させます。また、ランタイムはもはや 単一トークンの更新を、古いストア全体アダプター経由で処理します。レガシーの version-1 JSON ペイロードは、doctor のインポート/エクスポート形式としてのみ存在します。
  • GitHub Copilot のトークン交換キャッシュは、github-copilot/token-cache/default 配下の共有 SQLite Plugin 状態テーブルを使用します。これはプロバイダー所有のキャッシュ状態であるため、 ホストスキーマテーブルを意図的に追加していません。
  • GitHub Copilot の Compaction は、openclaw-compaction-*.json ワークスペースサイドカーファイルを今後書き込みません。ハーネスは、追跡対象の SDK セッションに対して SDK 履歴 Compaction RPC を呼び出し、OpenClaw は互換性マーカーファイルの代わりに、 永続的なセッション/トランスクリプト状態を SQLite に保持します。
  • 共有 Swift ランタイム(OpenClawKit)は、デバイス ID とデバイス認証に同じ state/openclaw.sqlite 行を使用します。macOS アプリの ヘルパーは、別の JSON または SQLite パスを独自に所有する代わりに、共有 SQLite ヘルパーをインポートします。残存するレガシー identity/device.json がある場合、 doctor がそれを SQLite にインポートするまで ID の作成をブロックし、 TypeScript および Android の起動ゲートと一致させます。
  • Android のデバイス ID は、型付きの state/openclaw.sqlite#table/device_identities 行に保存された、TypeScript 互換の同じキーマテリアルを使用します。 openclaw/identity/device.json の読み取りも書き込みも行いません。残存するレガシーファイルがある場合、 doctor がそれを SQLite にインポートするまで起動をブロックします。
  • Android でキャッシュされたデバイス認証トークンも、型付きの state/openclaw.sqlite#table/device_auth_tokens 行を使用し、TypeScript および Swift と同じ version-1 トークンセマンティクスを共有します。ランタイムは今後、SecurePrefsgateway.deviceToken* 互換キーを読み取りません。これらは移行/doctor ロジック専用です。
  • Android の通知における最近のパッケージ履歴は、型付きの android_notification_recent_packages 行を使用します。ランタイムは今後、 古い SharedPreferences CSV キーを移行または読み取りません。
  • レガシーの identity/device.json が存在する場合、SQLite の ID 行が無効な場合、 または SQLite の ID ストアを開けない場合、デバイス ID の作成はフェイルクローズします。 doctor が最初にそのファイルをインポートして削除するため、ランタイムの起動時に、 移行前のペアリング ID が暗黙にローテーションされることはありません。
  • デバイス ID の選択には、JSON ファイルのロケーターではなく SQLite の行キーを使用します。テスト と Gateway ヘルパーは明示的な ID キーを渡します。廃止された identity/device.json ファイル名を認識するのは、doctor の移行とフェイルクローズの起動ゲートだけです。
  • セッションリセットの互換性処理は、doctor の設定移行に置かれるようになりました。 session.idleMinutessession.reset.idleMinutes に移動され、 session.resetByType.dmsession.resetByType.direct に移動されます。また、 ランタイムのリセットポリシーは正規のリセットキーのみを読み取ります。
  • レガシー設定の互換性処理は、src/commands/doctor/ 配下に置かれるようになりました。通常の readConfigFileSnapshot() 検証では、doctor のレガシー検出器を インポートしたり、レガシー問題に注釈を付けたりしません。runDoctorConfigPreflight() は、 doctor の修復/レポート作成用にそれらの問題を追加します。doctor の設定フローは src/commands/doctor/legacy-config.ts をインポートし、古い OAuth プロファイル ID の修復は src/commands/doctor/legacy/oauth-profile-ids.ts 配下に置かれます。
  • doctor 以外のコマンドは、レガシー設定の修復を自動実行しません。たとえば、 openclaw update --channel は今後、無効なレガシー設定があると失敗し、 doctor の移行コードを暗黙にインポートする代わりに、doctor を実行するよう ユーザーに求めます。
  • Web プッシュ、APNs、Voice Wake、更新チェック、および設定の正常性では、 不透明な JSON BLOB 全体の代わりに、サブスクリプション、VAPID キー、Node 登録、トリガー行、 ルーティング行、更新通知状態、および設定正常性エントリ用の型付き共有 SQLite テーブルを使用するようになりました。Web プッシュと APNs のスナップショット書き込みでは、 テーブルをクリアする代わりに、主キーによってサブスクリプション/登録を 照合するようになりました。設定の正常性についても、設定パスによって同様に処理します。 これらのランタイムモジュールでは、SQLite スナップショットのリーダー/ライターと、 doctor 専用のレガシー JSON インポートヘルパーを分離しています。
  • Node ホスト設定では、共有 SQLite データベース内の型付きシングルトン行を使用するようになりました。 doctor は、通常のランタイム使用前に古い node.json ファイルをインポートします。
  • デバイス/Node のペアリング、チャネルのペアリング、チャネルの許可リスト、およびブートストラップ状態では、 不透明な JSON BLOB 全体の代わりに型付き SQLite 行を使用するようになりました。Plugin バインディングの 承認と Cron ジョブの状態も同じ分離方式に従います。ランタイムモジュールは、 SQLite ベースの操作と中立的なスナップショットヘルパーを公開します。また、ペアリング/ブートストラップ および Plugin バインディング承認のスナップショット書き込みでは、テーブルを切り詰める代わりに 主キーによって行を照合し、doctor は src/commands/doctor/legacy/* モジュールを介して古い JSON ファイルをインポートして削除します。
  • インストール済み Plugin のレコードは、SQLite のインストール済み Plugin インデックスに保存されるようになりました。 ランタイムの設定読み書きでは、古い plugins.installs のユーザー作成設定データを移行または保持しなくなりました。doctor は、 通常のランタイム使用前に、そのレガシー設定形式を SQLite にインポートします。
  • QQBot の認証情報復旧スナップショットは、qqbot/credential-backups 配下の SQLite Plugin 状態に保存されるようになりました。ランタイムは今後、 qqbot/data/credential-backup*.json を書き込みません。QQBot の doctor コントラクトは、 アクティブな状態ディレクトリからそれらのレガシーバックアップファイルをインポートし、 アーカイブします。
  • Gateway の再読み込み計画では、内部の installedPluginIndex.installRecords.* 差分名前空間配下にある SQLite のインストール済み Plugin インデックスの スナップショットを比較します。ランタイムの再読み込み判断では今後、 それらの行を偽の plugins.installs 設定オブジェクトでラップしません。
  • Matrix の名前付きアカウント認証情報のアップグレードは、ランタイムの 読み取り中には行われなくなりました。単一またはデフォルトの Matrix アカウントを解決できる場合、 古いトップレベルの credentials/matrix/credentials.json の名前変更は doctor が担当します。
  • コアのペアリングおよび Cron ランタイムモジュールは、レガシー JSON パス ビルダーを今後エクスポートしません。doctor 所有のレガシーモジュールは、インポートテストと 移行専用に、pending.jsonpaired.jsonbootstrap.json、および cron/jobs.json のソースパスを構築します。 レガシー Cron ジョブ形式の正規化と Cron 実行ログのインポートは、 src/commands/doctor/legacy/cron*.ts 配下に置かれます。
  • src/commands/doctor/legacy/runtime-state.ts は、Node ホスト設定を含む レガシー JSON 状態ファイルを、doctor から SQLite にインポートします。新しいレガシーファイルの インポーターは src/commands/doctor/legacy/ 配下に置きます。
  • src/commands/doctor/state-migrations.ts は、レガシーの sessions.json*.jsonl トランスクリプトを SQLite に直接インポートし、正常に処理されたソースを削除します。 ルートのレガシートランスクリプトを agents/<agentId>/sessions/*.jsonl 経由でステージングしたり、インポート前に 正規の JSONL ターゲットを作成したりすることはなくなりました。
  • 状態整合性に関する doctor のチェックでは今後、レガシーセッションディレクトリを スキャンしたり、孤立した JSONL の削除を提案したりしません。レガシートランスクリプトファイルは 移行入力専用であり、移行ステップがインポートとソース削除の両方を担当します。
  • レガシーサンドボックスレジストリのインポートは、 src/commands/doctor/legacy/sandbox-registry.ts 配下に置かれます。アクティブなサンドボックスレジストリの 読み書きは引き続き SQLite のみを使用します。
  • レガシーセッショントランスクリプトの正常性チェック/インポート修復は、 src/commands/doctor/legacy/session-transcript-health.ts 配下に置かれます。ランタイムコマンド モジュールには今後、JSONL トランスクリプトの解析コードやアクティブブランチの修復コードを含めません。

統合・削除の完了に関するハイライト:

  • Plugin の状態は、共有 state/openclaw.sqlite データベースを使用するようになりました。古い ブランチローカルの plugin-state/state.sqlite サイドカーインポーターは、 その SQLite レイアウトがリリースされなかったため削除されました。プローブ/テストヘルパーは、Plugin 状態専用の SQLite パスを公開する代わりに、共有 databasePath を報告します。
  • タスクおよび Task Flow のランタイムテーブルは、tasks/runs.sqlitetasks/flows/registry.sqlite ではなく、共有 state/openclaw.sqlite データベースに格納されるようになりました。古いサイドカーインポーターは、 同じくレイアウトがリリースされなかったため削除されました。
  • src/config/sessions/store.ts は、受信 メタデータ、ルート更新、更新日時の読み取りに storePath を必要としなくなりました。コマンドの永続化、CLI セッションのクリーンアップ、サブエージェントの深度、認証オーバーライド、トランスクリプトのセッション ID には、エージェント/セッション行 API を使用します。書き込みは、楽観的競合再試行を伴う SQLite 行パッチとして 適用されます。
  • セッションターゲット解決は、レガシーな sessions.json パスではなく、エージェントごとのデータベースターゲットを公開するようになりました。共有 Gateway、ACP メタデータ、doctor のルート修復、および openclaw sessions は、agent_databases と設定済みエージェントを列挙します。
  • Gateway のセッションルーティングは resolveGatewaySessionDatabaseTarget を使用するようになりました。 返されるターゲットには、レガシーなセッションストアのファイルパスではなく、databasePath と SQLite 行キーの候補が 含まれます。
  • チャネルセッションのランタイム型は、 更新日時の読み取り、受信メタデータ、最終ルート更新用に {agentId, sessionKey} を公開するようになりました。古い saveSessionStore(storePath, store) 互換型は削除されました。
  • Plugin ランタイム、拡張 API、Plugin SDK のセッションサーフェスは、 アクティブセッションのストア全体/ファイル互換ヘルパーではなく、SQLite ベースのセッション行ヘルパーを公開するようになりました。ルートライブラリの互換エクスポートは、 レガシーな内部呼び出し元と移行処理の呼び出し元向けに、Plugin SDK の外部でのみ引き続き利用できます。古い resolveLegacySessionStorePath ヘルパーは削除されました。レガシーな sessions.json パスの 構築は、移行処理とテストフィクスチャ内だけで行われるようになりました。
  • src/config/sessions/session-entries.sqlite.ts は、正規のセッション エントリをエージェントごとのデータベースに格納するようになり、行レベルの読み取り/upsert/削除パッチを サポートします。ランタイムの upsert/パッチ/削除は、大文字小文字のバリエーションを走査したり、 レガシーなエイリアスキーを整理したりしなくなりました。正規化は doctor が担います。 スタンドアロンの JSON インポートヘルパーは削除され、移行処理はセッションテーブル全体を置き換えるのではなく、より新しい行をマージ upsert します。公開の読み取り/一覧/ロードヘルパーは、 型付き sessions および conversations 行からホットなセッションメタデータを投影します。 entry_json は互換性/デバッグ用のシャドウであり、古くなったり無効になったりしても、 型付きのセッション ID や配信コンテキストは失われません。
  • src/config/sessions/delivery-info.ts は、型付きのエージェントごとの sessions + conversations + session_conversations 行から配信コンテキストを解決するようになりました。 session_entries.entry_json からランタイムの配信 ID を再構築しなくなりました。型付きの会話行が存在しない場合は、 ランタイムフォールバックではなく、doctor による移行/修復の問題です。
  • 保存済みセッションのリセット判断では、型付きの sessions.session_scopesessions.chat_typesessions.channel メタデータが優先されるようになりました。sessionKey の解析は、 コマンドターゲット上の明示的なスレッド/トピック接尾辞に対してのみ残されています。グループかダイレクトかというリセット分類は、 キーの形状から判断されなくなりました。
  • セッション一覧/ステータス表示の分類では、型付きのチャットメタデータと Gateway セッション種別を使用するようになりました。session_key 内の :group: または :channel: の部分文字列を、 永続的なグループ/ダイレクトの事実として扱わなくなりました。
  • サイレント応答ポリシーの選択では、明示的な会話タイプまたはサーフェス メタデータのみを使用するようになりました。session_key の部分文字列から ダイレクト/グループポリシーを推測しなくなりました。
  • セッション表示モデルの解決では、session_key から分割して取り出すのではなく、SQLite セッションデータベースターゲットからエージェント ID を受け取るようになりました。
  • エージェント間アナウンスのターゲットハイドレーションでは、型付きの sessions.list deliveryContext のみを使用するようになりました。レガシーな origin、ミラーされた last* フィールド、または session_key の形状から、 チャネル/アカウント/スレッドのルーティングを復元しなくなりました。
  • sessions_send のスレッドターゲット拒否は、型付き SQLite ルーティング メタデータを読み取るようになりました。ターゲットキーからスレッド接尾辞を解析してターゲットを拒否または許可することは なくなりました。
  • グループスコープのツールポリシー検証では、現在または生成されたセッションの型付き SQLite 会話 ルーティングを読み取るようになりました。sessionKey をデコードしてグループ/チャネル ID を信頼することはなくなりました。型付きセッション行による裏付けがない場合、呼び出し元が指定したグループ ID は破棄されます。
  • チャネルモデルのオーバーライド照合では、明示的なグループおよび親 会話メタデータを使用するようになりました。parentSessionKey から親会話 ID をデコードしなくなりました。
  • 保存済みモデルオーバーライドの継承には、型付きセッションコンテキストからの明示的な親セッションキーが 必須になりました。sessionKey 内の :thread: または :topic: 接尾辞から、 親オーバーライドを導出しなくなりました。
  • 古いセッションスレッド情報ラッパーとロード済み Plugin のスレッドパーサーは削除され、 ランタイムコードは config/sessions/thread-info をインポートしなくなりました。
  • チャネル会話ヘルパーは、完全なセッションキー解析 ブリッジを公開しなくなりました。コアは引き続き resolveSessionConversation(...) を通じてプロバイダー所有の生の会話 ID を正規化しますが、 sessionKey からルート情報を再構築することはありません。
  • 完了配信、送信ポリシー、タスクメンテナンスは、session_key の形状からチャット タイプを導出しなくなりました。古いチャットタイプキーパーサーは削除されました。 これらのパスには、型付きセッションメタデータ、型付き配信コンテキスト、または 明示的な配信ターゲット語彙が必要です。
  • セッション一覧/ステータス、診断、承認アカウントのバインド、TUI の Heartbeat フィルタリング、使用状況サマリーは、プロバイダー/アカウント/スレッド/表示ルーティングのために SessionEntry.origin を 掘り出さなくなりました。ランタイムで残っている origin の読み取りは、 セッション以外の概念または現在ターンの配信オブジェクトに限られます。
  • 承認リクエストのネイティブ会話検索は、型付きのエージェントごとのセッション ルーティング行を読み取るようになりました。sessionKey からチャネル/グループ/スレッドの会話 ID を 解析しなくなりました。型付きメタデータが存在しない場合は、移行/修復の問題です。
  • Gateway のセッション変更/チャット/セッションイベントペイロードは、 SessionEntry.origin または last* のルートシャドウをエコーしなくなりました。クライアントは、型付きの channelchatTypedeliveryContext を受け取ります。
  • Heartbeat の配信解決は、型付き SQLite deliveryContext を直接受け取れるようになり、Heartbeat ランタイムは、現在のルーティングについて互換 session_entries シャドウに依存する代わりに、エージェントごとのセッション配信行を渡します。
  • Cron の分離エージェント配信ターゲット解決でも、互換 エントリペイロードにフォールバックする前に、型付きのエージェントごとのセッション配信行から現在の ルートをハイドレートするようになりました。
  • サブエージェントのアナウンス元解決は、型付きのリクエスターセッション 配信コンテキストを loadRequesterSessionEntry 経由で受け渡し、互換 last*/deliveryContext シャドウよりもその行を優先するようになりました。
  • 受信セッションメタデータの更新では、まず型付きのエージェントごとの 配信行に対してマージするようになりました。古い SessionEntry 配信フィールドは、型付き会話行が存在しない場合にのみ フォールバックとして使用されます。
  • 再起動/更新の配信抽出では、sessionKey から解析したトピック/スレッド断片よりも、型付き SQLite 配信 threadId が優先されるようになりました。解析は、 レガシーなスレッド形状キーに対するフォールバックとしてのみ行われます。
  • フックエージェントコンテキストのチャネル ID は、まず型付き SQLite 会話 ID、 次に明示的なメッセージメタデータを優先するようになりました。sessionKey からプロバイダー/グループ/チャネル 断片を解析しなくなりました。
  • Gateway の chat.send 外部ルート継承では、 sessionKey の断片からチャネル/ダイレクト/グループスコープを推論する代わりに、型付き SQLite セッション ルーティングメタデータを読み取るようになりました。チャネルスコープのセッションが継承するのは、型付き セッションチャネルとチャットタイプが保存済み配信コンテキストと一致する場合だけです。共有メイン セッションでは、より厳格な CLI/クライアントメタデータなしのルールが維持されます。
  • 再起動センチネルのウェイクおよび継続ルーティングは、Heartbeat ウェイクまたはルーティング済みエージェントターンの 継続をキューに入れる前に、型付き SQLite の 配信/ルーティング行を読み取るようになりました。セッションエントリの JSON シャドウから 配信コンテキストを再構築しなくなりました。
  • Gateway の tools.effective コンテキスト解決では、プロバイダー、アカウント、ターゲット、スレッド、応答モードの 入力について、型付き SQLite の 配信/ルーティング行を読み取るようになりました。古くなった session_entries.entry_json オリジンシャドウから、これらのホットなルーティングフィールドを復元しなくなりました。
  • リアルタイム音声コンサルトのルーティングは、型付きの エージェントごとの SQLite セッション行から親/通話配信を解決するようになりました。埋め込みエージェントの メッセージルートを選択する際に、互換 SessionEntry.deliveryContext シャドウへフォールバックしなくなりました。
  • ACP のスポーン Heartbeat リレーおよび親ストリームルーティングは、型付き SQLite セッション行から親配信を 読み取るようになりました。互換セッションエントリシャドウから親配信 コンテキストを再構築しなくなりました。
  • セッション配信ルートの保持は、型付きチャットメタデータと 永続化された配信列に従うようになりました。sessionKey からチャネルヒント、ダイレクト/メイン マーカー、スレッド形状を抽出しなくなりました。内部 Web チャットルートが外部ターゲットを継承するのは、 SQLite にそのセッションの型付き/永続化された配信 ID がすでに存在する場合だけです。
  • 汎用セッション配信抽出は、完全一致する型付き SQLite セッション配信行のみを読み取るようになりました。スレッド/トピック接尾辞を解析したり、 スレッド形状キーからベースセッションキーにフォールバックしたりしなくなりました。
  • 応答ディスパッチ、再起動センチネルの復旧、リアルタイム音声コンサルトのルーティングは、 スレッドルーティングに完全一致する型付き SQLite セッション/会話行を使用するようになりました。スレッド形状のセッションキーを解析して、 スレッド ID やベースセッションの配信コンテキストを復元しなくなりました。
  • 埋め込み PI の履歴制限では、プロバイダー、チャットタイプ、 ピア ID に型付き SQLite セッションルーティング プロジェクション(sessions + プライマリ conversations)を使用するようになりました。sessionKey からプロバイダー、DM、グループ、スレッドの形状を 解析しなくなりました。
  • Cron ツールの配信推論では、明示的な配信または現在の型付き 配信コンテキストのみを使用するようになりました。agentSessionKey からチャネル、ピア、アカウント、スレッドの ターゲットをデコードしなくなりました。
  • ランタイムセッション行は、古い lastProvider ルートエイリアスを保持しなくなりました。 ヘルパーとテストでは、型付きの lastChannel および deliveryContext フィールドを使用します。 古いルートエイリアスまたは永続化された origin シャドウを変換すべき場所は、 doctor の移行処理だけです。
  • トランスクリプトイベント、VFS 行、ツールアーティファクト行は、エージェントごとの データベースに書き込まれるようになりました。リリースされなかったグローバルなトランスクリプトファイルマッピングテーブルは削除され、 doctor は代わりに、レガシーなソースパスを永続的な移行行に記録します。
  • ランタイムのトランスクリプト検索は、JSONL のバイトオフセットを走査したり、レガシーな トランスクリプトファイルをプローブしたりしなくなりました。Gateway のチャット/メディア/履歴パスは SQLite からトランスクリプト行を 読み取ります。セッション JSONL は現在、レガシーな doctor 入力にすぎず、ランタイム状態や エクスポート形式ではありません。
  • トランスクリプトの親子関係およびブランチ関係では、パス形式の agent-db:...transcript_events... ロケーター文字列ではなく、SQLite トランスクリプト ヘッダー内の構造化された parentTranscriptScope: {agentId, sessionId} メタデータを使用します。
  • トランスクリプトマネージャーのコントラクトは、暗黙的に永続化される create(cwd) または continueRecent(cwd) コンストラクターを公開しなくなりました。永続化トランスクリプト マネージャーは、明示的な {agentId, sessionId} スコープで開かれます。スコープなしのままなのは、 テストおよび純粋なトランスクリプト変換用のインメモリマネージャーだけです。
  • ランタイムのトランスクリプトストア API は、ファイルシステムパスではなく SQLite スコープを解決します。古い resolve...ForPath ヘルパーと未使用の transcriptPath 書き込みオプションは、 ランタイムの呼び出し元から削除されました。
  • ランタイムのセッション解決は {agentId, sessionId} を使用するようになり、外部境界向けに sqlite-transcript://<agent>/<session> 文字列を導出してはなりません。 レガシーな絶対 JSONL パスは、doctor の移行入力としてのみ使用されます。
  • ネイティブフックリレーのダイレクトブリッジレコードは、リレー ID をキーとする型付き共有 native_hook_relay_bridges 行に格納されるようになりました。ランタイムは、これらの短命なブリッジ レコード用に /tmp JSON レジストリや不透明な汎用レコードを書き込まなくなりました。
  • runEmbeddedPiAgent(...) には、トランスクリプトロケーターのパラメーターがなくなりました。 準備済みのワーカーディスクリプターからもトランスクリプトロケーターが省かれます。ランタイムセッション 状態とキューに入れられたフォローアップ実行では、派生トランスクリプトハンドルの代わりに {agentId, sessionId} を保持します。
  • 組み込み Compaction は、agentIdsessionId から SQLite スコープを受け取るようになりました。 Compaction フック、コンテキストエンジン呼び出し、CLI 委譲、プロトコル応答に、 派生した sqlite-transcript://... ハンドルを渡してはなりません。エクスポート/デバッグコードでは 行から明示的なユーザー成果物を具現化できますが、汎用的なセッション JSONL エクスポートパスを 提供したり、ファイル名をランタイム ID に戻したりすることはありません。
  • /export-session は SQLite からトランスクリプト行を読み取り、要求された スタンドアロン HTML ビューのみを書き込みます。組み込みビューアーは、それらの行から セッション JSONL を再構築またはダウンロードしなくなりました。
  • コンテキストエンジンへの委譲では、エージェント ID を復元するためにトランスクリプトロケーターを 解析しなくなりました。準備済みランタイムコンテキストが、解決済みの agentId を 組み込み Compaction アダプターへ渡します。
  • トランスクリプトの書き換えとライブツール結果の切り詰めでは、{agentId, sessionId} によって トランスクリプト状態を読み取り、永続化するようになり、トランスクリプト更新イベントの ペイロード用に一時ロケーターを派生させることはありません。
  • トランスクリプト状態ヘルパーのサーフェスには、ロケーターベースの readTranscriptStatereplaceTranscriptStateEvents、または persistTranscriptStateMutation バリアントがなくなりました。ランタイム呼び出し元は {agentId, sessionId} API を使用する必要があります。Doctor インポートは明示的なファイルパスで レガシーファイルを読み取り、SQLite 行を書き込みます。ロケーター文字列は移行しません。
  • ランタイムセッションマネージャーのコントラクトでは、open(locator)forkFrom(locator)、または setTranscriptLocator(...) を公開しなくなりました。 永続化セッションマネージャーは {agentId, sessionId} のみで開きます。リスト/フォークヘルパーは、 トランスクリプトマネージャーのファサードではなく、行指向のセッションおよびチェックポイント API に 配置されます。
  • Gateway のトランスクリプトリーダー API はスコープ優先です。 {agentId, sessionId} を受け取り、誤ってランタイム ID になり得る位置引数の トランスクリプトロケーターは受け付けません。アクティブなトランスクリプトロケーターの解析は 廃止され、レガシーソースパスを読み取るのは Doctor のインポートコードのみです。
  • トランスクリプト更新イベントもスコープ優先です。emitSessionTranscriptUpdate は ロケーター文字列単体を受け付けなくなり、リスナーはハンドルを解析せずに {agentId, sessionId} でルーティングします。
  • Gateway のセッションメッセージブロードキャストでは、トランスクリプトロケーターではなく、 エージェント/セッションスコープからセッションキーを解決します。古い トランスクリプトロケーターからセッションキーへのリゾルバー/キャッシュは廃止されました。
  • Gateway のセッション履歴 SSE は、エージェント/セッションスコープでライブ更新を フィルタリングします。ストリームが更新を受信すべきか判断するために、トランスクリプトロケーターの 候補、実パス、またはファイル形式のトランスクリプト ID を正規化しなくなりました。
  • セッションライフサイクルフックは、session_end でトランスクリプトロケーターを派生または 公開しなくなりました。フックの利用側は sessionIdsessionKey、次のセッション ID、 およびエージェントコンテキストを受け取ります。トランスクリプトファイルは ライフサイクルコントラクトに含まれません。
  • リセットフックもトランスクリプトロケーターを派生または公開しなくなりました。 before_reset ペイロードには、復元された SQLite メッセージとリセット理由が含まれ、 セッション ID はフックコンテキストに保持されます。
  • エージェントハーネスのリセットは、トランスクリプトロケーターを受け付けなくなりました。 リセットのディスパッチは、sessionId/sessionKey と理由によってスコープ設定されます。
  • エージェント拡張機能のセッション型は transcriptLocator を公開しなくなりました。 拡張機能は、ファイル形式のトランスクリプト ID にアクセスするのではなく、セッションコンテキストと ランタイム API を使用する必要があります。
  • Plugin の Compaction フックは、トランスクリプトロケーターを公開しなくなりました。 フックコンテキストにはすでにセッション ID が含まれており、トランスクリプトの読み取りは ファイル形式のハンドルではなく、SQLite のスコープ対応 API を介して行う必要があります。
  • before_agent_finalize フックは、ネイティブフックのリレーペイロードを含め、 transcriptPath を公開しなくなりました。ファイナライズフックではセッションコンテキストのみを 使用します。
  • Gateway のリセット応答は、返されるエントリにトランスクリプトロケーターを合成しなくなりました。 リセットでは SQLite トランスクリプト行を作成し、クリーンなセッションエントリを返し、 トランスクリプトへのアクセスはスコープ対応リーダーに委ねます。
  • 組み込み実行と Compaction の結果では、セッションアカウンティング用の トランスクリプトロケーターを公開しなくなりました。自動 Compaction は、アクティブな sessionId、Compaction カウンター、およびトークンメタデータのみを更新します。
  • 組み込み試行の結果は transcriptLocatorUsed を返さなくなり、コンテキストエンジンの compact() の結果もトランスクリプトロケーターを返さなくなりました。 ランタイムの再試行ループが受け付ける後続値は sessionId のみです。
  • 配信ミラーのトランスクリプト追記結果は、トランスクリプトロケーターを返さなくなりました。 呼び出し元は追記された messageId を受け取り、トランスクリプト更新シグナルでは SQLite スコープを使用します。
  • 親セッションのフォークヘルパーは、フォークされた sessionId のみを返します。サブエージェントの 準備では、子エージェント/セッションのスコープをエンジンに渡します。
  • CLI ランナーのパラメーターと履歴の再シードは、トランスクリプトロケーターを受け付けなくなりました。 CLI の履歴読み取りは、{agentId, sessionId} とセッションキーコンテキストから SQLite トランスクリプトスコープを解決します。
  • CLI と組み込みランナーのテストフィクスチャは、アクティブなセッションを *.jsonl ファイルと 見なしたり、ランタイムパラメーターを通じて sqlite-transcript://... 文字列を渡したりせず、 セッション ID によって SQLite トランスクリプト行をシードおよび読み取るようになりました。
  • セッションのツール結果ガードイベントは、メモリ内マネージャーに派生ロケーターがない場合でも、 既知のセッションスコープから発行されます。そのテストでは、アクティブな /tmp/*.jsonl トランスクリプトファイルを偽装しなくなりました。
  • BTW と Compaction チェックポイントのヘルパーは、SQLite スコープによってトランスクリプト行を 読み取り、フォークするようになりました。チェックポイントメタデータには、セッション ID と リーフ/エントリ ID のみが保存されるようになり、派生ロケーターはチェックポイントペイロードに 書き込まれなくなりました。
  • Gateway のトランスクリプトキー検索は、プロトコル境界で SQLite トランスクリプトスコープを 使用し、トランスクリプトファイル名の実パス解決や stat を行わなくなりました。
  • 自動 Compaction のトランスクリプトローテーションは、後続のトランスクリプト行を SQLite トランスクリプトストアを通じて直接書き込みます。セッション行には、永続的な JSONL パスや 永続化されたロケーターではなく、後続セッションの ID のみが保持されます。
  • 組み込みコンテキストエンジンの Compaction は、SQLite 名のトランスクリプトローテーション ヘルパーを使用します。ローテーションのテストでは、後続の JSONL パスを構築したり、 アクティブなセッションをファイルとしてモデル化したりしなくなりました。
  • 管理対象の送信画像保持では、ファイルシステムの stat 呼び出しではなく、 SQLite トランスクリプト統計からトランスクリプトメッセージキャッシュのキーを生成します。
  • ランタイムセッションロックと、スタンドアロンのレガシー .jsonl.lock Doctor レーンは削除されました。
  • Microsoft Teams ランタイムのバレルと公開 Plugin SDK は、古いファイルロックヘルパーを 再エクスポートしなくなりました。永続的な Plugin 状態パスは SQLite を基盤とします。
  • セッションの経過時間/件数によるプルーニングと、明示的なセッションクリーンアップは削除されました。 Doctor がレガシーインポートを担当し、古いセッションは明示的にリセットまたは削除されます。
  • Doctor の整合性チェックでは、レガシー JSONL ファイルを SQLite セッション行の有効な アクティブトランスクリプトとしてカウントしなくなりました。アクティブなトランスクリプトの 正常性は SQLite のみで判定され、レガシー JSONL ファイルは移行/孤立データクリーンアップの 入力として報告されます。
  • Doctor は agents/<agent>/sessions/ を必須のランタイム状態として扱わなくなりました。 そのディレクトリがすでに存在する場合にのみ、レガシーインポートまたは 孤立データクリーンアップの入力としてスキャンします。
  • Gateway の sessions.resolve、セッションのパッチ/リセット/compact パス、サブエージェントの 起動、高速中止、ACP メタデータ、Heartbeat 分離セッション、および TUI のパッチ処理は、 通常のランタイム処理の副作用としてレガシーセッションキーを移行またはプルーニングしなくなりました。
  • CLI コマンドのセッション解決は、storePath ではなく所有元の agentId を返すようになり、 通常の --to または --session-id 解決中にレガシーのメインセッション行を コピーしなくなりました。レガシーのメイン行の正規化は Doctor のみが担当します。
  • ランタイムのサブエージェント深度解決は、sessions.json または JSON5 セッションストアを 読み取らなくなりました。エージェント ID によって SQLite の session_entries を読み取り、 レガシーの深度/セッションメタデータは Doctor のインポートパスを通じてのみ取り込めます。
  • 認証プロファイルのセッションオーバーライドは、ファイル形式のセッションストアランタイムを 遅延ロードするのではなく、{agentId, sessionKey} 行を直接 upsert することで永続化されます。
  • 自動応答の詳細表示ゲートとセッション更新ヘルパーは、セッション ID によって SQLite セッション行を 読み取り/upsert するようになり、永続化された行の状態を操作する前にレガシーストアパスを 必要としなくなりました。
  • コマンド実行のセッションメタデータヘルパーは、エントリ指向の名前とモジュールパスを 使用するようになりました。古い session-store コマンドヘルパーのサーフェスは削除されました。
  • ブートストラップヘッダーのシードと手動 Compaction 境界の堅牢化では、SQLite トランスクリプト行を 直接変更するようになりました。ランタイム呼び出し元は、書き込み可能な .jsonl パスではなく、 セッション ID を渡します。
  • サイレントセッションローテーションのリプレイでは、SQLite トランスクリプト行から {agentId, sessionId} によって最近のユーザー/アシスタントのターンをコピーします。 ソースまたはターゲットのトランスクリプトロケーターは受け付けなくなりました。
  • 新しいランタイムセッション行は、トランスクリプトロケーターを保存しなくなりました。呼び出し元は {agentId, sessionId} を直接使用します。エクスポート/デバッグコマンドは、行を具現化するときに 出力ファイル名を選択できます。
  • 新しい永続化トランスクリプトセッションを開始すると、常にスコープによって SQLite 行が開かれます。 セッションマネージャーは、新しいセッションの ID として、以前のファイル時代の トランスクリプトパスまたはロケーターを再利用しなくなりました。
  • 永続化トランスクリプトセッションでは、明示的な openTranscriptSessionManagerForSession({agentId, sessionId}) API を使用します。古い 静的な SessionManager.create/openForSession/list/forkFromSession ファサードは廃止され、 テストやランタイムコードが誤ってファイル時代のセッション検出を再作成できないようになりました。
  • Plugin ランタイムは api.runtime.agent.session.resolveTranscriptLocatorPath を 公開しなくなりました。Plugin コードは SQLite 行ヘルパーとスコープ値を使用します。
  • 公開 session-store-runtime SDK サーフェスは、セッション行とトランスクリプト行のヘルパーのみを エクスポートするようになりました。特定用途の SQLite スキーマ/パス/トランザクションヘルパーは sqlite-runtime に配置され、生の open/close/reset ヘルパーはファーストパーティテスト専用として ローカルに残ります。
  • レガシー .jsonl 軌跡/チェックポイントのファイル名分類子は、Doctor のレガシーセッションファイル モジュールに配置されるようになりました。コアセッション検証では、通常の SQLite セッション ID を 判断するためにファイル成果物ヘルパーをインポートしなくなりました。
  • Active Memory のブロッキングサブエージェント実行では、Plugin 状態配下に一時的または永続的な session.jsonl ファイルを作成せず、SQLite トランスクリプト行を使用します。古い transcriptDir オプションは削除されました。
  • 単発のスラッグ生成と Crestodian プランナーの実行では、一時的な session.jsonl ファイルを 作成せず、SQLite トランスクリプト行を使用します。
  • llm-task ヘルパーの実行と非表示コミットメントの抽出も SQLite トランスクリプト行を使用するため、 これらのモデル専用ヘルパーセッションでは一時的な JSON/JSONL トランスクリプトファイルを 作成しなくなりました。
  • TranscriptSessionManager は、現在では開かれた SQLite トランスクリプトスコープにすぎません。 ランタイムコードは openTranscriptSessionManagerForSession({agentId, sessionId}) でこれを開きます。作成、分岐、継続、一覧、およびフォークのフローは、 静的なマネージャーファサードではなく、それぞれを所有する SQLite 行ヘルパーに配置されます。 Doctor/インポート/デバッグコードは、ランタイムセッションマネージャーの外部で明示的な レガシーソースファイルを処理します。
  • 古くなった SessionManager.newSession() および SessionManager.createBranchedSession() ファサードメソッドは削除されました。新しいセッションと トランスクリプトの子孫は、すでに開かれたマネージャーを別の永続化セッションへ変更するのではなく、 それぞれを所有する SQLite ワークフローによって作成されます。
  • 親トランスクリプトのフォーク判定とフォーク作成は、storePath または sessionsDir を 受け付けなくなりました。保持されたファイルシステムパスのメタデータではなく、 {agentId, sessionId} の SQLite トランスクリプトスコープを使用します。
  • メモリホストは、何もしないセッションディレクトリのトランスクリプト分類ヘルパーを エクスポートしなくなりました。トランスクリプトのフィルタリングは、エントリ構築時に SQLite 行メタデータから導出されるようになりました。
  • メモリホストと QMD のセッションエクスポートテストでは、SQLite トランスクリプトスコープを 使用します。古い agents/<agentId>/sessions/*.jsonl パスが対象となるのは、テストで Doctor/インポート/エクスポートの互換性を意図的に検証する場合のみです。
  • QA-lab の生セッション検査では、agents/qa/sessions/sessions.json を読み取る代わりに、Gateway 経由で sessions.list を使用するようになりました。MSteams のフィードバックは、JSONL パスを捏造せず、SQLite トランスクリプトへ直接追記されます。
  • 共有受信チャネルのターンでは、従来の storePath ではなく {agentId, sessionKey} を保持するようになりました。LINE、WhatsApp、Slack、Discord、Telegram、Matrix、Signal、iMessage、BlueBubbles、Feishu、Google Chat、IRC、Nextcloud Talk、Zalo、Zalo Personal、QA Channel、Microsoft Teams、Mattermost、Synology Chat、Tlon、Twitch、QQBot の記録パスでは、更新日時メタデータを読み取り、SQLite ID を通じて受信セッション行を記録するようになりました。
  • トランスクリプトロケーターの永続化は、アクティブなセッション行から削除されました。resolveSessionTranscriptTargetagentIdsessionId、および任意のトピックメタデータを返します。従来のトランスクリプトファイル名をインポートするコードは doctor のみです。
  • ランタイムトランスクリプトヘッダーは SQLite バージョン 1 から始まります。古い JSONL V1/V2/V3 形式のアップグレードは doctor のインポート内にのみ存在し、行を保存する前に、インポートされたヘッダーを現在の SQLite トランスクリプトバージョンへ正規化します。
  • データベース優先ガードでは、SessionManager.listAllSessionManager.forkFromSession も禁止されるようになりました。セッション一覧とフォーク/復元ワークフローは、行ベース/スコープ指定の SQLite API のみを使用する必要があります。
  • このガードでは、doctor/インポートコード以外で従来のトランスクリプト JSONL 解析/アクティブブランチ修復ヘルパー名も禁止されるため、ランタイムに従来形式のトランスクリプト移行パスがもう一つ追加されることはありません。
  • 組み込み PI 実行は、受信したトランスクリプトハンドルを拒否します。ワーカー起動前、および試行がトランスクリプト状態に触れる前に、SQLite の {agentId, sessionId} ID を使用します。古い /tmp/*.jsonl 入力でランタイム書き込み先を選択することはできません。
  • キャッシュトレース、Anthropic ペイロード、生ストリーム、診断タイムラインのレコードは、型付き SQLite diagnostic_events 行へ書き込まれるようになりました。Gateway 安定性バンドルは、型付き SQLite diagnostic_stability_bundles 行へ書き込まれるようになりました。従来の diagnostics.cacheTrace.filePathOPENCLAW_CACHE_TRACE_FILEOPENCLAW_ANTHROPIC_PAYLOAD_LOG_FILEOPENCLAW_DIAGNOSTICS_TIMELINE_PATH の JSONL 上書きパスは削除され、通常の安定性キャプチャでは logs/stability/*.json ファイルが書き込まれなくなりました。
  • Cron の永続化では、保存のたびにジョブテーブル全体を削除して再挿入する代わりに、SQLite の cron_jobs 行を照合するようになりました。Plugin ターゲットの書き戻しでは、該当する Cron 行を直接更新し、ランタイムの Cron 状態を同じ状態データベーストランザクション内に維持します。
  • Cron ランタイムの呼び出し元は、安定した SQLite Cron ストアキーを使用するようになりました。従来の cron.store パスは doctor のインポート入力専用です。本番 Gateway、タスク保守、ステータス、実行ログ、Telegram ターゲットの書き戻しパスでは resolveCronStoreKey を使用し、キーのパス正規化は行われなくなりました。Cron ステータスでは、従来のファイル形式の storePath フィールドではなく storeKey が報告されるようになりました。
  • Cron ランタイムの読み込みとスケジューリングでは、jobIdschedule.cron、数値の atMs、文字列の真偽値、欠落した sessionTarget など、従来の永続化ジョブ形式を正規化しなくなりました。行が SQLite に挿入される前のこれらの修復は、doctor の従来形式インポートが担当します。
  • ACP のスポーンでは、トランスクリプト JSONL ファイルパスの解決や永続化を行わなくなりました。スポーンとスレッドバインドのセットアップでは、SQLite セッション行を直接永続化し、保持するトランスクリプト ID としてセッション ID を使用します。
  • ACP セッションメタデータ API は、agentId によって SQLite 行を読み取り/一覧表示/upsert するようになり、ACP セッションエントリ契約の一部として storePath を公開しなくなりました。
  • セッション使用量の計測と Gateway 使用量の集計では、トランスクリプトを {agentId, sessionId} のみで解決するようになりました。コスト/使用量キャッシュと検出済みセッションの概要では、トランスクリプトロケーター文字列の合成や返却を行わなくなりました。
  • Gateway チャットの追記、中止時の部分永続化、/sessions.send、Web チャットメディアのトランスクリプト書き込みは、SQLite トランスクリプトスコープを通じて直接追記されるようになりました。Gateway のトランスクリプト注入ヘルパーは、transcriptLocator パラメーターを受け取らなくなりました。
  • SQLite トランスクリプト検出では、トランスクリプトスコープと統計情報のみを一覧表示するようになりました:{agentId, sessionId, updatedAt, eventCount}。使用されていなかった互換性ヘルパー listSqliteSessionTranscriptLocators と、行ごとの locator フィールドは削除されました。
  • トランスクリプト修復ランタイムが公開するのは、repairTranscriptSessionStateIfNeeded({agentId, sessionId}) のみになりました。従来のロケーターベースの修復ヘルパーは削除されました。doctor/デバッグコードは明示的なソースファイルパスを読み取り、ロケーター文字列を移行することはありません。
  • ACP リプレイ台帳ランタイムでは、acp/event-ledger.json の代わりに、セッションごとのリプレイ行を共有 SQLite 状態データベースへ保存するようになりました。doctor は従来のファイルをインポートして削除します。
  • Gateway のトランスクリプト読み取りヘルパーは、従来の session-utils.fs モジュール名ではなく、src/gateway/session-transcript-readers.ts に配置されるようになりました。フォールバック再試行履歴の確認は、従来のファイルヘルパー面ではなく、SQLite トランスクリプト内容に基づく名前になりました。
  • Gateway の注入チャットヘルパーと Compaction ヘルパーは、値をトランスクリプトパスやソースファイルと呼ぶ代わりに、内部ヘルパー API を通じて SQLite トランスクリプトスコープを渡すようになりました。
  • ブートストラップ継続検出では、hasCompletedBootstrapTranscriptTurn を通じて SQLite トランスクリプト行を確認するようになりました。ファイル形式のヘルパー名は公開されなくなりました。
  • 組み込みランナーのテストでは SQLite トランスクリプト ID を使用するようになり、新しいトランスクリプトマネージャーを開く際は、常に明示的な sessionId が必要になりました。
  • メモリインデックス作成ヘルパーでは、最初から最後まで SQLite トランスクリプト用語を使用するようになりました。ホストは listSessionTranscriptScopesForAgentsessionTranscriptKeyForScope をエクスポートし、対象指定同期キューは sessionTranscripts を使用し、公開セッション検索のヒットは不透明な transcript:<agent>:<session> パスを公開します。内部 DB のソースキーは、偽のファイルパスではなく、source_kind='sessions' 配下の session:<session> です。
  • 汎用 Plugin SDK の永続的重複排除ヘルパーは、ファイル形式のオプションを公開しなくなりました。呼び出し元は SQLite スコープキーを指定し、永続的な重複排除行は共有 Plugin 状態に保存されます。
  • Microsoft Teams SSO トークンは、ロックされた JSON ファイルから SQLite Plugin 状態へ移行しました。doctor は msteams-sso-tokens.json をインポートし、ペイロードから正規の SSO トークンキーを再構築して、ソースファイルを削除します。委任された OAuth トークンは、既存の非公開認証情報ファイル境界に留まります。
  • Matrix 同期キャッシュ状態は、bot-storage.json から SQLite Plugin 状態へ移行しました。doctor は従来の生またはラップされた同期ペイロードをインポートし、ソースファイルを削除します。アクティブな Matrix および QA Matrix クライアントは、偽の sync-store.json または bot-storage.json パスではなく、SQLite 同期ストアのルートディレクトリを渡します。
  • Matrix の従来暗号化移行ステータスは、legacy-crypto-migration.json から SQLite Plugin 状態へ移行しました。doctor は古いステータスファイルをインポートします。Matrix SDK IndexedDB スナップショットは、crypto-idb-snapshot.json から SQLite Plugin BLOB へ移行しました。Matrix のリカバリーキーと認証情報は SQLite Plugin 状態行になり、従来の JSON ファイルは doctor の移行入力専用です。
  • Memory Wiki のアクティビティログでは、.openclaw-wiki/log.jsonl の代わりに SQLite Plugin 状態を使用するようになりました。Memory Wiki 移行プロバイダーは古い JSONL ログをインポートします。Wiki の Markdown とユーザー保管庫の内容は、ワークスペースコンテンツとして引き続きファイルに保持されます。
  • Memory Wiki は、.openclaw-wiki/state.json や未使用の .openclaw-wiki/locks ディレクトリを作成しなくなりました。古い保管庫にこれらが残っている場合、移行プロバイダーが廃止済みの Plugin メタデータファイルを削除します。
  • Crestodian 監査エントリでは、audit/crestodian.jsonl の代わりにコア SQLite Plugin 状態を使用するようになりました。doctor は従来の JSONL 監査ログをインポートし、インポート成功後に削除します。
  • 設定の書き込み/監視監査エントリでは、logs/config-audit.jsonl の代わりにコア SQLite Plugin 状態を使用するようになりました。doctor は従来の JSONL 監査ログをインポートし、インポート成功後に削除します。
  • macOS コンパニオンは、openclaw.json の編集中に、アプリローカルの logs/config-audit.jsonllogs/config-health.json サイドカーを書き込まなくなりました。設定ファイルは引き続きファイルに保持され、リカバリースナップショットは設定ファイルの隣に保持されます。永続的な設定監査/健全性状態は Gateway SQLite ストアが所有します。
  • Crestodian レスキューの保留中承認では、crestodian/rescue-pending/*.json の代わりにコア SQLite Plugin 状態を使用するようになりました。doctor は従来の保留中承認ファイルをインポートし、インポート成功後に削除します。
  • Phone Control の一時的なアーム状態では、plugins/phone-control/armed.json の代わりに SQLite Plugin 状態を使用するようになりました。doctor は従来のアーム状態ファイルを phone-control/arm-state 名前空間へインポートし、ファイルを削除します。
  • doctor は、JSONL トランスクリプトをその場で修復したり、バックアップ JSONL ファイルを作成したりしなくなりました。アクティブブランチを SQLite へインポートし、従来のソースを削除します。
  • セッションメモリフックのトランスクリプト検索では、{agentId, sessionId} スコープのみの SQLite 読み取りを使用します。そのヘルパーは、トランスクリプトロケーター、従来のファイル読み取り、ファイル書き換えオプションを受け取ることも導出することもなくなりました。
  • Codex app-server の会話バインディングでは、OpenClaw セッションキーまたは明示的な {agentId, sessionId} スコープを使用して、SQLite Plugin 状態のキーを設定するようになりました。トランスクリプトパスのフォールバックバインディングを保持してはなりません。
  • Codex app-server のミラー履歴読み取りでは、SQLite トランスクリプトスコープのみを使用します。トランスクリプトファイルパスから ID を復元してはなりません。
  • ロール順序付けと Compaction リセットのパスでは、古いトランスクリプトファイルのリンク解除を行わなくなりました。リセットでは、SQLite セッション行とトランスクリプト ID のみをローテーションします。
  • Gateway のリセットおよびチェックポイント応答は、クリーンなセッション行とセッション ID を返します。クライアント向けに SQLite トランスクリプトロケーターを合成しなくなりました。
  • memory-core の Dreaming では、欠落した JSONL ファイルを調べてセッション行を削除しなくなりました。サブエージェントのクリーンアップは、ファイルシステムの存在確認ではなく、セッションランタイム API を通じて行われます。そのトランスクリプト取り込みテストでは、agents/<id>/sessions フィクスチャやロケータープレースホルダーを作成する代わりに、SQLite 行を直接シードします。
  • メモリトランスクリプトのインデックス作成では、引用/読み取りヘルパー向けの仮想検索ヒットパスとして transcript:<agentId>:<sessionId> を公開する場合があります。永続的なインデックスソースはリレーショナル形式(source_kind='sessions'source_key='session:<sessionId>'session_id=<sessionId>)であるため、この値はランタイムトランスクリプトロケーターでもファイルシステムパスでもなく、セッションランタイム API に戻して渡してはなりません。
  • Gateway doctor のメモリステータスは、memory/.dreams/*.json ではなく、SQLite Plugin 状態行から短期想起数とフェーズシグナル数を読み取ります。CLI と doctor の出力では、そのストレージをパスではなく SQLite ストアと表記するようになりました。
  • memory-core ランタイム、CLI ステータス、Gateway doctor メソッド、Plugin SDK ファサードでは、従来の .dreams/session-corpus ファイルを監査またはアーカイブしなくなりました。これらのファイルは移行入力専用です。doctor はそれらを SQLite へインポートし、検証後にソースを削除します。アクティブなセッション取り込み証拠行では、仮想 SQLite パス memory/session-ingestion/<day>.txt を使用するようになりました。ランタイムが .dreams/session-corpus へ書き込んだり、そこから状態を導出したりすることはありません。
  • memory-core の公開アーティファクトは、SQLite ホストイベントを仮想 JSON アーティファクト memory/events/memory-host-events.json として公開します。従来の .dreams/events.jsonl ソースパスは再利用されなくなりました。
  • サンドボックスのコンテナ/ブラウザレジストリでは、型付きのセッション、イメージ、タイムスタンプ、バックエンド/設定、ブラウザポート列を持つ共有 SQLite テーブル sandbox_registry_entries を使用するようになりました。doctor は従来の単一およびシャード化された JSON レジストリファイルをインポートし、正常に処理されたソースを削除します。ランタイム読み取りでは、型付き行の列を信頼できる情報源として使用します。entry_json はリプレイ/デバッグ用コピーにすぎません。
  • コミットメントでは、ストア全体の JSON BLOB の代わりに、型付き共有 commitments テーブルを使用するようになりました。スナップショット保存では、テーブルをクリアして再挿入する代わりに、コミットメント ID ごとに upsert し、存在しなくなった行のみを削除します。ランタイムは、型付きのスコープ、配信時間枠、ステータス、試行、テキスト列からコミットメントを読み込みます。record_json はリプレイ/デバッグ用コピーにすぎません。doctor は従来の commitments.json をインポートし、インポート成功後に削除します。
  • Cron ジョブ定義、スケジュール状態、実行履歴には、ランタイムがなくなりました JSON の書き込み処理や読み取り処理。ランタイムは、型付きのスケジュール、 ペイロード、配信、失敗アラート、セッション、ステータス、ランタイム状態の各カラムを持つ cron_jobs 行と、 ステータス、診断サマリー、配信ステータス/エラー、 セッション/実行、モデル、トークン合計のための型付き cron_run_logs メタデータを使用します。job_json は再生/デバッグ用コピーにすぎません。state_json は、 まだ頻繁なクエリ用フィールドを持たないネストされたランタイム診断を保持し、ランタイムは 型付きカラムから頻繁に使用する状態フィールドを復元します。Doctor は 旧形式の jobs.jsonjobs-state.jsonruns/*.jsonl ファイルをインポートし、 インポート元を削除します。Plugin ターゲットの書き戻しでは、Cron ストア全体を読み込んで置き換えるのではなく、 一致する cron_jobs 行を更新します。
  • Gateway の起動時には、ランタイム投影内の旧形式の notify: true マーカーを無視します。 Doctor は、cron.webhook が有効な場合、それらを明示的な SQLite 配信に変換し、 未設定の場合は機能しないマーカーを削除し、設定された Webhook が無効な場合は 警告とともに保持します。
  • 送信キューとセッション配信キューは、キューのステータス、エントリ種別、 セッションキー、チャネル、ターゲット、アカウント ID、再試行回数、最終試行/エラー、 復旧状態、プラットフォーム送信マーカーを、共有 delivery_queue_entries テーブルの型付きカラムとして保存するようになりました。ランタイムの復旧処理は、 これらの頻繁に使用するフィールドを型付きカラムから読み取り、再試行/復旧の変更時には、 再生用 JSON を書き換えずに、それらのカラムを直接更新します。完全な JSON ペイロードは、 メッセージ本文やその他の使用頻度が低い再生データ向けの再生/デバッグ用 BLOB としてのみ残ります。
  • 管理対象の送信画像レコードは、型付きの共有 managed_outgoing_image_records 行を使用するようになり、メディアのバイト列は引き続き media_blobs に保存されます。JSON レコードは再生/デバッグ用コピーとしてのみ残ります。
  • Discord のモデル選択設定、コマンドデプロイのハッシュ、スレッドバインディングは、 共有 SQLite Plugin 状態を使用するようになりました。旧形式 JSON のインポート計画は、 コアの移行コードではなく、Discord Plugin のセットアップ/Doctor 移行サーフェスに置かれます。
  • Plugin の旧形式インポート検出処理は、 doctor-legacy-state.tsdoctor-state-imports.ts など、Doctor の名前を冠したモジュールを使用します。通常のチャネルランタイム モジュールは、旧形式 JSON の検出処理をインポートしてはなりません。
  • BlueBubbles のキャッチアップカーソルと受信重複排除マーカーは、共有 SQLite Plugin 状態を使用するようになりました。旧形式 JSON のインポート計画は、 コアの移行コードではなく、BlueBubbles Plugin のセットアップ/Doctor 移行サーフェスに置かれます。
  • Telegram の更新オフセット、ステッカーキャッシュ行、送信済みメッセージキャッシュ行、 トピック名キャッシュ行、スレッドバインディングは、共有 SQLite Plugin 状態を使用するようになりました。旧形式 JSON のインポート計画は、コアの移行コードではなく、 Telegram Plugin のセットアップ/Doctor 移行サーフェスに置かれます。
  • iMessage のキャッチアップカーソル、返信の短縮 ID マッピング、送信エコー重複排除行は、 共有 SQLite Plugin 状態を使用するようになりました。旧形式の imessage/catchup/*.jsonimessage/reply-cache.jsonlimessage/sent-echoes.jsonl ファイルは、 Doctor の入力としてのみ使用されます。
  • Feishu のメッセージ重複排除行は、feishu/dedup/*.json ファイルや、 廃止された独自実装の dedup.* ストアではなく、コアの取得可能な重複排除機構 (共有 SQLite Plugin 状態内の feishu.dedup.* 名前空間)を使用するようになりました。 アップグレード後に再生保護キャッシュが再構築されるため、旧形式からのインポートはありません。
  • Microsoft Teams の会話、投票、保留中のアップロードバッファ、フィードバックからの学習内容は、 共有 SQLite Plugin 状態/BLOB テーブルを使用するようになりました。保留中のアップロード パスは plugin_blob_entries を使用するため、メディアバッファは base64 JSON ではなく SQLite BLOB として保存されます。ランタイムヘルパー名も、*-fs というファイルストア命名ではなく、 SQLite/状態を示す命名を使用するようになり、旧形式の storePath シムは これらのストアから削除されました。旧形式 JSON のインポート計画は、Microsoft Teams Plugin のセットアップ/Doctor 移行サーフェスに置かれます。
  • Zalo でホストされる送信メディアは、openclaw-zalo-outbound-media の JSON/bin 一時サイドカーではなく、 共有 SQLite の plugin_blob_entries を使用するようになりました。
  • 差分ビューアの HTML とメタデータは、meta.jsonviewer.html 一時ファイルではなく、 共有 SQLite の plugin_blob_entries を使用するようになりました。レンダリングされた PNG/PDF 出力は、 チャネル配信で引き続きファイルパスが必要なため、一時的な実体化として残ります。
  • Canvas の管理対象ドキュメントは、デフォルトの state/canvas/documents ディレクトリではなく、 共有 SQLite の plugin_blob_entries を使用するようになりました。Canvas ホストはこれらの BLOB を直接配信します。ローカルファイルが作成されるのは、明示的な host.root のオペレーターコンテンツの場合、または下流のメディア読み取り処理がパスを必要とする場合の 一時的な実体化に限られます。
  • File Transfer の監査判断は、上限のない audit/file-transfer.jsonl ランタイムログではなく、 共有 SQLite の plugin_state_entries を使用するようになりました。Doctor は、 旧形式の JSONL 監査ファイルを Plugin 状態へインポートし、正常にインポートされた後で インポート元を削除します。
  • ACPX のプロセスリースと Gateway インスタンス ID は、共有 SQLite Plugin 状態を使用するようになりました。Doctor は、旧形式の gateway-instance-id ファイルを Plugin 状態へ インポートし、インポート元を削除します。
  • ACPX が生成するラッパースクリプトと分離された Codex ホームは、永続的な OpenClaw 状態ではなく、 OpenClaw の一時ルート配下に一時的に実体化されます。永続的な ACPX ランタイムレコードは、 SQLite のリース行と Gateway インスタンス行です。旧形式の ACPX stateDir 設定サーフェスは、 そこへランタイム状態が書き込まれなくなったため削除されました。
  • Gateway のメディア添付ファイルは、共有 media_blobs SQLite テーブルを 正規のバイトストアとして使用するようになりました。チャネルおよびサンドボックスの 互換性サーフェスに返されるローカルパスは、永続的なメディアストアではなく、データベース行を 一時的に実体化したものです。ランタイムのメディア許可リストには、旧形式の $OPENCLAW_STATE_DIR/media または設定ディレクトリの media ルートが含まれなくなりました。これらのディレクトリは、 Doctor のインポート元としてのみ使用されます。
  • シェル補完は、$OPENCLAW_STATE_DIR/completions/* キャッシュ ファイルを書き込まなくなりました。インストール、Doctor、更新、リリースのスモークテストでは、 永続的な補完キャッシュファイルではなく、生成された補完出力またはプロファイルの読み込みを使用します。
  • Gateway の Skill アップロード用ステージングは、共有 skill_uploads 行を使用するようになりました。アップロードの メタデータ、冪等性キー、アーカイブのバイト列は SQLite に保存されます。インストーラーが受け取るのは、 インストールの実行中だけ一時的に実体化されたアーカイブパスです。
  • サブエージェントのインライン添付ファイルは、ワークスペースの .openclaw/attachments/* 配下に実体化されなくなりました。生成パスは SQLite VFS のシードエントリを準備し、 インライン実行では、それらのエントリをエージェントごとのランタイムスクラッチ名前空間へシードし、 ディスクベースのツールは添付ファイルパス用にその SQLite スクラッチをオーバーレイします。旧形式の サブエージェント実行用添付ディレクトリレジストリのカラムとクリーンアップフックは削除されました。
  • CLI の画像ハイドレーションは、安定した openclaw-cli-images キャッシュ ファイルを維持しなくなりました。外部 CLI バックエンドは引き続きファイルパスを受け取りますが、 それらのパスは実行ごとの一時的な実体化であり、クリーンアップされます。
  • キャッシュトレース診断、Anthropic ペイロード診断、生のモデルストリーム 診断、診断タイムラインイベント、Gateway 安定性バンドルは、 logs/*.jsonl または logs/stability/*.json ファイルではなく、 SQLite 行へ書き込まれるようになりました。 ランタイムパスを上書きするフラグと環境変数は削除されました。エクスポート/デバッグ コマンドは、データベース行からファイルを明示的に実体化できます。
  • macOS コンパニオンには、ローテーションする diagnostics.jsonl 書き込み処理がなくなりました。アプリの ログは統合ログへ送られ、永続的な Gateway 診断は SQLite ベースのままです。
  • macOS のポートガーディアンのレコード一覧は、Application Support の JSON ファイルや 不透明な単一 BLOB ではなく、型付きの共有 SQLite macos_port_guardian_records 行を使用するようになりました。
  • Gateway の単一インスタンスロックは、一時ディレクトリのロックファイルではなく、 gateway_locks スコープ配下の型付き共有 SQLite state_leases 行を使用するようになりました。Fly と OAuth の トラブルシューティングドキュメントでは、古いファイルロックのクリーンアップではなく、 SQLite のリース/認証更新ロックを案内するようになりました。
  • Gateway の再起動センチネル状態は、restart-sentinel.json ではなく、 型付きの共有 SQLite gateway_restart_sentinel 行を使用するようになりました。ランタイムは、 センチネルの種別、ステータス、ルーティング、メッセージ、継続情報、統計を 型付きカラムから読み取ります。payload_json は再生/デバッグ用コピーにすぎません。ランタイムコードは、 SQLite 行を直接消去し、ファイルクリーンアップの配管処理を保持しなくなりました。
  • Gateway の再起動意図とスーパーバイザーへの引き継ぎ状態は、 gateway-restart-intent.json および gateway-supervisor-restart-handoff.json サイドカーではなく、型付き共有 SQLite gateway_restart_intent 行と gateway_restart_handoff 行を使用するようになりました。
  • Gateway の単一インスタンス調整は、gateway.<hash>.lock ファイルを書き込む代わりに、 gateway_locks 配下の型付き state_leases 行を使用するようになりました。リース行は、 ロック所有者、有効期限、Heartbeat、デバッグペイロードを保持し、SQLite が アトミックな取得/解放境界を担います。廃止されたファイルロックディレクトリのオプションは 削除され、テストでは SQLite 行の ID を直接使用します。
  • cron/runs/*.jsonl ファイルを走査していた、旧形式の未参照 Cron 使用量レポートヘルパーは 削除されました。Cron 実行履歴レポートは、型付きの cron_run_logs SQLite 行を読み取る必要があります。
  • メインセッションの再起動復旧では、agents/*/sessions ディレクトリを走査する代わりに、SQLite の agent_databases レジストリを通じて候補エージェントを検出するようになりました。
  • Gemini のセッション破損復旧では、SQLite のセッション行だけを削除するようになりました。 旧形式の storePath ゲートは不要になり、導出された トランスクリプト JSONL パスのリンク解除も試みません。
  • パス上書き処理では、リテラルの undefinednull 環境変数値を 未設定として扱うようになり、テストやシェル間の引き継ぎ時に、リポジトリルートへ誤って undefined/state/*.sqlite データベースが作成されることを防ぎます。
  • 設定健全性フィンガープリントは、logs/config-health.json ではなく、 型付きの共有 SQLite config_health_entries 行を使用するようになり、通常の設定ファイルが 認証情報以外で唯一の設定ドキュメントとして維持されます。macOS コンパニオンは、 プロセスローカルの健全性状態のみを保持し、旧形式の JSON サイドカーを再作成しません。
  • 認証プロファイルのランタイムは、認証情報 JSON ファイルをインポートまたは書き込みしなくなりました。 正規の認証情報ストアは SQLite です。auth-profiles.json、エージェントごとの auth.json、共有の credentials/oauth.json は Doctor の移行入力であり、 インポート後に削除されます。
  • 認証プロファイルの保存/状態テストは、型付き SQLite 認証テーブルを直接検証するようになり、 旧形式の認証プロファイルファイル名は Doctor の移行入力にのみ使用します。
  • openclaw secrets apply は、設定ファイル、環境ファイル、SQLite 認証プロファイルストアのみから機密情報を除去します。廃止されたエージェントごとの auth.json を編集する 互換性ロジックは保持しなくなりました。このファイルのインポートと削除は Doctor が担います。
  • Hermes のシークレット移行は、インポートした API キープロファイルを SQLite 認証プロファイルストアへ 直接計画して適用します。中間ターゲットとして auth-profiles.json を書き込んだり検証したりしなくなりました。
  • ユーザー向けの認証ドキュメントでは、auth-profiles.json の確認やコピーを案内する代わりに、 state/openclaw.sqlite#table/auth_profile_stores/<agentDir> を説明するようになりました。旧形式の OAuth/認証 JSON 名は、Doctor のインポート入力としてのみ引き続き文書化されます。
  • コアの状態パスヘルパーは、廃止された credentials/oauth.json ファイルを公開しなくなりました。旧形式のファイル名は、Doctor の認証インポートパス内に限定されます。
  • インストール、セキュリティ、オンボーディング、モデル認証、SecretRef のドキュメントでは、 エージェントごとの認証プロファイル JSON ファイルではなく、 SQLite の認証プロファイル行と状態全体のバックアップ/移行を説明するようになりました。
  • PI のモデル検出は、正規の認証情報をメモリ内の pi-coding-agent 認証ストレージへ渡すようになりました。検出中に、 エージェントごとの auth.json を作成、機密情報除去、書き込みしなくなりました。
  • Voice Wake のトリガーとルーティング設定は、 settings/voicewake.jsonsettings/voicewake-routing.json、不透明な汎用行ではなく、 型付きの共有 SQLite テーブルを使用するようになりました。Doctor は旧形式の JSON ファイルをインポートし、 移行が成功した後に削除します。
  • 更新チェック状態は、update-check.json や不透明な汎用 BLOB ではなく、 型付きの共有 update_check_state 行を使用するようになりました。Doctor は 旧形式の JSON ファイルをインポートし、移行が成功した後に削除します。
  • 設定健全性状態は、logs/config-health.json や不透明な汎用 BLOB ではなく、 型付きの共有 config_health_entries 行を使用するようになりました。Doctor は 旧形式の JSON ファイルをインポートし、移行が成功した後に削除します。
  • Plugin の会話バインディング承認は、型付きの 不透明な共有 SQLite 状態や plugin-binding-approvals.json ではなく、plugin_binding_approvals 行を使用します。レガシーファイルは doctor の移行入力です。
  • 汎用の現在の会話バインディングは、 bindings/current-conversations.json を書き換える代わりに、型付きの current_conversation_bindings 行を保存するようになりました。doctor はレガシー JSON ファイルをインポートし、 移行に成功した後に削除します。
  • Memory Wiki のインポート済みソース同期台帳は、.openclaw-wiki/source-sync.json を書き換える代わりに、 vault/source キーごとに 1 つの SQLite Plugin 状態行を保存するようになりました。 移行プロバイダーはレガシー JSON 台帳をインポートして削除します。
  • Memory Wiki の ChatGPT インポート実行レコードは、.openclaw-wiki/import-runs/*.json に書き込む代わりに、 vault/run ID ごとに 1 つの SQLite Plugin 状態行を保存するようになりました。 ロールバックスナップショットは、インポート実行スナップショットのアーカイブが blob ストレージへ移行されるまで、明示的な vault ファイルとして残ります。
  • Memory Wiki のコンパイル済みダイジェストは、 .openclaw-wiki/cache/agent-digest.json および .openclaw-wiki/cache/claims.jsonl に書き込む代わりに、SQLite Plugin blob 行を保存するようになりました。移行プロバイダーは古いキャッシュ ファイルをインポートし、空になった時点でキャッシュディレクトリを削除します。
  • ClawHub の skill インストール追跡は、実行時に .clawhub/lock.json および .clawhub/origin.json サイドカーを書き込んだり読み取ったりする代わりに、 workspace/skill ごとに 1 つの SQLite Plugin 状態行を保存するようになりました。ランタイムコードは、ファイル形式の lockfile/origin 抽象化ではなく、 追跡対象インストール状態オブジェクトを使用します。doctor は、設定されたエージェントワークスペースから レガシーサイドカーをインポートし、正常なインポート後に削除します。
  • インストール済み Plugin インデックスは、plugins/installs.json の代わりに、 型付き共有 SQLite の installed_plugin_index シングルトン行を読み書きするようになりました。レガシー JSON ファイルは doctor の移行入力としてのみ使用され、インポート後に削除されます。
  • レガシーの plugins/installs.json パスヘルパーは doctor のレガシーコード内に配置されるようになりました。 ランタイムの Plugin インデックスモジュールが公開する永続化オプションは SQLite ベースのみで、 JSON ファイルパスは公開しません。
  • Gateway の再起動センチネル、再起動意図、およびスーパーバイザーハンドオフ状態は、汎用の 不透明な blob の代わりに、型付き共有 SQLite 行(gateway_restart_sentinelgateway_restart_intentgateway_restart_handoff)を使用するようになりました。ランタイムの再起動コードには、ファイル形式のセンチネル/意図/ハンドオフ コントラクトはありません。
  • Matrix の同期キャッシュ、ストレージメタデータ、スレッドバインディング、受信重複排除マーカー、 起動検証のクールダウン状態、SDK IndexedDB 暗号化スナップショット、 認証情報、およびリカバリーキーは、共有 SQLite の Plugin 状態/blob テーブルを使用するようになりました。ランタイムのパス構造体は storage-meta.json メタデータ パスを公開しなくなりました。このファイル名はレガシー移行入力としてのみ使用されます。これらのレガシー JSON インポート 計画は、Matrix Plugin のセットアップ/doctor 移行サーフェスにあります。受信 重複排除マーカーは、コアの獲得可能な重複排除(共有状態 DB 内の matrix.inbound-dedupe.* 名前空間)を使用します。Matrix doctor の状態移行は、 廃止されたルートごとの inbound-dedupe 行と inbound-dedupe.json を一度だけインポートし、 その後ランタイムは獲得可能な重複排除ストアのみを読み取ります。
  • Matrix の起動時に、レガシー Matrix ファイル状態をスキャン、報告、または完了することはなくなりました。 Matrix ファイルの検出、レガシー暗号化スナップショットの作成、ルームキー 復元移行状態、インポート、およびソース削除は、すべて doctor が所有します。
  • Matrix ランタイムの移行 barrel は削除されました。レガシー状態/暗号化の検出 および変更ヘルパーは、ランタイム API サーフェスの一部ではなく、Matrix doctor から直接インポートされます。
  • Matrix 移行スナップショットの再利用マーカーは、matrix/migration-snapshot.json ではなく、 SQLite Plugin 状態に格納されるようになりました。doctor は、サイドカー状態ファイルを書き込まずに、 同じ検証済み移行前アーカイブを引き続き再利用できます。
  • Nostr バスカーソルおよびプロフィール公開状態は、共有 SQLite Plugin 状態を使用するようになりました。これらのレガシー JSON インポート計画は、Nostr Plugin のセットアップ/doctor 移行サーフェスにあります。
  • Active Memory のセッショントグルは、session-toggles.json ではなく、 共有 SQLite Plugin 状態を使用するようになりました。メモリを再びオンにすると、JSON オブジェクトを書き換える代わりに 行を削除します。
  • Skill Workshop の提案およびレビューカウンターは、ワークスペースごとの skill-workshop/<workspace>.json ストアではなく、共有 SQLite Plugin 状態を使用するようになりました。各提案は skill-workshop/proposals 配下の個別の行であり、レビュー カウンターは skill-workshop/reviews 配下の個別の行です。
  • Skill Workshop のレビュアーサブエージェント実行は、skill-workshop/<sessionId>.json サイドカーセッション パスを作成する代わりに、ランタイムのセッショントランスクリプト リゾルバーを使用するようになりました。
  • ACPX プロセスリースは、ファイル全体の process-leases.json レジストリではなく、 acpx/process-leases 配下の共有 SQLite Plugin 状態を使用するようになりました。 各リースは独立した行として保存されるため、ランタイムの JSON 書き換えパスなしで 起動時の古いプロセス回収が維持されます。
  • ACPX ラッパースクリプトおよび分離された Codex ホームは、 OpenClaw の一時ルートに生成されます。必要に応じて再作成され、バックアップまたは 移行入力にはなりません。
  • サブエージェント実行レジストリの永続化には、型付き共有 subagent_runs 行を使用します。 古い subagents/runs.json パスは doctor の移行入力としてのみ使用されるようになり、 ランタイムヘルパー名は状態レイヤーをディスクベースとして表現しなくなりました。 ランタイムテストでは、レジストリの動作を証明するために無効または空の runs.json フィクスチャを作成しなくなり、 SQLite 行を直接シードして読み取ります。
  • バックアップは、アーカイブ前に状態ディレクトリをステージングし、データベース以外のファイルをコピーし、 VACUUM INTO でデータベースのスナップショットを作成し、稼働中の WAL/SHM サイドカーを省略し、 アーカイブマニフェストにスナップショットメタデータを記録し、完了した バックアップ実行をアーカイブマニフェストとともに SQLite に記録します。openclaw backup create は、書き込まれたアーカイブをデフォルトで検証します。--no-verify は 明示的な高速パスです。
  • openclaw backup restore は抽出前にアーカイブを検証し、検証機能の 正規化済みマニフェストを再利用し、検証済みマニフェスト資産を記録された ソースパスへ復元します。書き込みには --yes が必須であり、復元計画用に --dry-run をサポートします。
  • 古いバックアップの揮発性パスフィルターは削除されました。SQLite スナップショットはアーカイブ作成前にステージングされるため、バックアップでレガシーセッションまたは Cron の JSON/JSONL ファイル向けの ライブ tar スキップリストは不要になりました。
  • 通常のセットアップおよびオンボーディングでのワークスペース準備では、 agents/<agentId>/sessions/ ディレクトリを作成しなくなりました。作成するのは設定/ワークスペースのみです。 SQLite セッション行およびトランスクリプト行は、エージェントごとのデータベース内で 必要に応じて作成されます。
  • セキュリティ権限の修復対象は、sessions.json およびトランスクリプト JSONL ファイルではなく、グローバルおよびエージェントごとの SQLite データベースと WAL/SHM サイドカーになりました。
  • サンドボックスレジストリのランタイム名は、アクティブストアにレガシー JSON レジストリ用語を引き継ぐ代わりに、 SQLite レジストリの種類を直接表すようになりました。
  • openclaw reset --scope config+creds+sessions は、レガシーの sessions/ ディレクトリだけでなく、エージェントごとの openclaw-agent.sqlite データベースと WAL/SHM サイドカーも削除します。
  • Gateway の集約セッションヘルパーは、エントリ指向の名前を使用するようになりました。 loadCombinedSessionEntriesForGateway{ databasePath, entries } を返します。 古い結合ストアの命名はランタイム呼び出し元から削除されました。
  • Docker MCP チャンネルのシード処理は、sessions.json と JSONL トランスクリプトを作成する代わりに、 メインセッション行およびトランスクリプトイベントを エージェントごとの SQLite データベースへ書き込むようになりました。
  • バンドルされた session-memory フックは、{agentId, sessionId} により SQLite から前回セッションのコンテキストを解決するようになりました。トランスクリプトパスや workspace/sessions ディレクトリのスキャン、保存、または合成は行わなくなりました。
  • バンドルされた command-logger フックは、logs/commands.log に追記する代わりに、 コマンド監査行を共有 SQLite の command_log_entries テーブルへ書き込むようになりました。
  • チャンネルペアリング許可リストは、ランタイムおよび Plugin SDK で SQLite ベースの読み書きヘルパーのみを公開するようになりました。古い *-allowFrom.json パスリゾルバーおよび ファイルリーダーは、doctor のレガシーインポートコード配下にのみ存在します。
  • migration_runs は、レガシー状態の移行実行を、ステータス、 タイムスタンプ、および JSON レポートとともに記録します。
  • migration_sources は、インポートされた各レガシーファイルソースについて、ハッシュ、サイズ、 レコード数、対象テーブル、実行 ID、ステータス、およびソース削除状態を記録します。
  • backup_runs は、バックアップアーカイブパス、ステータス、および JSON マニフェストを記録します。
  • グローバルスキーマには、未使用の agents レジストリテーブルを保持しません。ランタイムに 実際のエージェントレコード所有者ができるまでは、エージェントデータベースの検出が正規の agent_databases レジストリです。
  • 生成されたモデルカタログ設定は、エージェントディレクトリをキーとする型付きグローバル SQLite agent_model_catalogs 行に保存されます。ランタイム呼び出し元は ensureOpenClawModelCatalog を使用します。ランタイムコードに models.json 互換 API は ありません。この実装は SQLite に書き込み、models.json ファイルを作成せずに、 保存されたペイロードから組み込み PI レジストリをハイドレートします。
  • QMD セッショントランスクリプトの Markdown エクスポートおよび memory.qmd.sessions 設定は 削除されました。QMD トランスクリプトコレクション、qmd/sessions* ランタイム パス、およびファイルベースのセッションメモリブリッジは存在しません。
  • memory-core ランタイムは、QMD SDK サブパスではなく、 openclaw/plugin-sdk/memory-core-host-engine-session-transcripts から SQLite トランスクリプト索引付けヘルパーをインポートします。QMD サブパスは、メジャー SDK クリーンアップで削除できるまで、 外部呼び出し元向けの互換性再エクスポートのみを維持します。
  • QMD 自体の index.sqlite は、メイン SQLite の plugin_blob_entries テーブルを基盤とする 一時的なランタイム実体化になりました。ランタイムは永続的な ~/.openclaw/agents/<agentId>/qmd サイドカーを作成しなくなりました。
  • オプションの memory-lancedb Plugin は、暗黙的な OpenClaw 管理ストアとして ~/.openclaw/memory/lancedb を作成しなくなりました。これは外部の LanceDB バックエンドであり、運用者が明示的な dbPath を設定するまで無効のままです。
  • check:database-first-legacy-stores は、レガシーストア名と 書き込み形式のファイルシステム API を組み合わせる新しいランタイムソースを失敗させます。また、廃止されたトランスクリプトブリッジマーカー transcriptLocator または sqlite-transcript://... を再導入するランタイム ソースも失敗させます。移行、doctor、インポート、 および明示的なセッション以外のエクスポートコードは引き続き許可されます。sessionFilestorePath、旧 SessionManager のファイル時代の ファサードなど、より広範なレガシーコントラクト名には現在も所有者が存在し、 必須の事前チェックにできるようになる前に、別個の移行ガード作業が必要です。このガードは現在、 ランタイムの cache/*.json ストア、汎用の thread-bindings.json サイドカー、Cron 状態/実行ログ JSON、設定ヘルス JSON、 再起動およびロックサイドカー、Voice Wake 設定、Plugin バインディング承認、 インストール済み Plugin インデックス JSON、File Transfer 監査 JSONL、Memory Wiki アクティビティ ログ、旧バンドル版 command-logger テキストログ、および pi-mono raw-stream JSONL 診断ノブも対象にします。また、互換性コードが src/commands/doctor/ 配下に留まるよう、古いルートレベルの doctor レガシーモジュール名も禁止します。Android デバッグハンドラーも、 camera_debug.log または debug_logs.txt キャッシュファイルをステージングする代わりに、 logcat/メモリ内出力を使用します。

ターゲットスキーマの形状

スキーマは明示的に保ちます。ホスト所有のランタイム状態には型付きテーブルを使用します。Plugin 所有の 不透明な状態には plugin_state_entries / plugin_blob_entries を使用し、汎用的な ホストの kv テーブルは設けません。

グローバルデータベース:

text
state_leases(scope, lease_key, owner, expires_at, heartbeat_at, payload_json, created_at, updated_at)exec_approvals_config(config_key, raw_json, socket_path, has_socket_token, default_security, default_ask, default_ask_fallback, auto_allow_skills, agent_count, allowlist_count, updated_at_ms)schema_meta(meta_key, role, schema_version, agent_id, app_version, created_at, updated_at)agent_databases(agent_id, path, schema_version, last_seen_at, size_bytes)task_runs(...)task_delivery_state(...)flow_runs(...)subagent_runs(run_id, child_session_key, requester_session_key, controller_session_key, created_at, ended_at, cleanup_handled, payload_json)current_conversation_bindings(binding_key, binding_id, target_agent_id, target_session_id, target_session_key, channel, account_id, conversation_kind, parent_conversation_id, conversation_id, target_kind, status, bound_at, expires_at, metadata_json, updated_at)plugin_binding_approvals(plugin_root, channel, account_id, plugin_id, plugin_name, approved_at)tui_last_sessions(scope_key, session_key, updated_at)plugin_state_entries(plugin_id, namespace, entry_key, value_json, created_at, expires_at)plugin_blob_entries(plugin_id, namespace, entry_key, metadata_json, blob, created_at, expires_at)media_blobs(subdir, id, content_type, size_bytes, blob, created_at, updated_at)skill_uploads(upload_id, kind, slug, force, size_bytes, sha256, actual_sha256, received_bytes, archive_blob, created_at, expires_at, committed, committed_at, idempotency_key_hash)web_push_subscriptions(endpoint_hash, subscription_id, endpoint, p256dh, auth, created_at_ms, updated_at_ms)web_push_vapid_keys(key_id, public_key, private_key, subject, updated_at_ms)apns_registrations(node_id, transport, token, relay_handle, send_grant, installation_id, topic, environment, distribution, token_debug_suffix, updated_at_ms)node_host_config(config_key, version, node_id, token, display_name, gateway_host, gateway_port, gateway_tls, gateway_tls_fingerprint, updated_at_ms)device_identities(identity_key, device_id, public_key_pem, private_key_pem, created_at_ms, updated_at_ms)device_auth_tokens(device_id, role, token, scopes_json, updated_at_ms)macos_port_guardian_records(pid, port, command, mode, timestamp)workspace_setup_state(workspace_key, workspace_path, version, bootstrap_seeded_at, setup_completed_at, updated_at)native_hook_relay_bridges(relay_id, pid, hostname, port, token, expires_at_ms, updated_at_ms)model_capability_cache(provider_id, model_id, name, input_text, input_image, reasoning, supports_tools, context_window, max_tokens, cost_input, cost_output, cost_cache_read, cost_cache_write, updated_at_ms)agent_model_catalogs(catalog_key, agent_dir, raw_json, updated_at)managed_outgoing_image_records(attachment_id, session_key, message_id, created_at, updated_at, retention_class, alt, original_media_id, original_media_subdir, original_content_type, original_width, original_height, original_size_bytes, original_filename, record_json)gateway_restart_sentinel(sentinel_key, version, kind, status, ts, session_key, thread_id, delivery_channel, delivery_to, delivery_account_id, message, continuation_json, doctor_hint, stats_json, payload_json, updated_at_ms)channel_pairing_requests(channel_key, account_id, request_id, code, created_at, last_seen_at, meta_json)channel_pairing_allow_entries(channel_key, account_id, entry, sort_order, updated_at)voicewake_triggers(config_key, position, trigger, updated_at_ms)voicewake_routing_config(config_key, version, default_target_mode, default_target_agent_id, default_target_session_key, updated_at_ms)voicewake_routing_routes(config_key, position, trigger, target_mode, target_agent_id, target_session_key, updated_at_ms)update_check_state(state_key, last_checked_at, last_notified_version, last_notified_tag, last_available_version, last_available_tag, auto_install_id, auto_first_seen_version, auto_first_seen_tag, auto_first_seen_at, auto_last_attempt_version, auto_last_attempt_at, auto_last_success_version, auto_last_success_at, updated_at_ms)config_health_entries(config_path, last_known_good_json, last_promoted_good_json, last_observed_suspicious_signature, updated_at_ms)sandbox_registry_entries(registry_kind, container_name, session_key, backend_id, runtime_label, image, created_at_ms, last_used_at_ms, config_label_kind, config_hash, cdp_port, no_vnc_port, entry_json, updated_at)cron_run_logs(store_key, job_id, seq, ts, status, error, summary, diagnostics_summary, delivery_status, delivery_error, delivered, session_id, session_key, run_id, run_at_ms, duration_ms, next_run_at_ms, model, provider, total_tokens, entry_json, created_at)cron_jobs(store_key, job_id, name, description, enabled, delete_after_run, created_at_ms, agent_id, session_key, schedule_kind, schedule_expr, schedule_tz, every_ms, anchor_ms, at, stagger_ms, session_target, wake_mode, payload_kind, payload_message, payload_model, payload_fallbacks_json, payload_thinking, payload_timeout_seconds, payload_allow_unsafe_external_content, payload_external_content_source_json, payload_light_context, payload_tools_allow_json, delivery_mode, delivery_channel, delivery_to, delivery_thread_id, delivery_account_id, delivery_best_effort, failure_delivery_mode, failure_delivery_channel, failure_delivery_to, failure_delivery_account_id, failure_alert_disabled, failure_alert_after, failure_alert_channel, failure_alert_to, failure_alert_cooldown_ms, failure_alert_include_skipped, failure_alert_mode, failure_alert_account_id, next_run_at_ms, running_at_ms, last_run_at_ms, last_run_status, last_error, last_duration_ms, consecutive_errors, consecutive_skipped, schedule_error_count, last_delivery_status, last_delivery_error, last_delivered, last_failure_alert_at_ms, job_json, state_json, runtime_updated_at_ms, schedule_identity, sort_order, updated_at)delivery_queue_entries(queue_name, id, status, entry_kind, session_key, channel, target, account_id, retry_count, last_attempt_at, last_error, recovery_state, platform_send_started_at, entry_json, enqueued_at, updated_at, failed_at)commitments(id, agent_id, session_key, channel, account_id, recipient_id, thread_id, sender_id, kind, sensitivity, source, status, reason, suggested_text, dedupe_key, confidence, due_earliest_ms, due_latest_ms, due_timezone, source_message_id, source_run_id, created_at_ms, updated_at_ms, attempts, last_attempt_at_ms, sent_at_ms, dismissed_at_ms, snoozed_until_ms, expired_at_ms, record_json)migration_runs(id, started_at, finished_at, status, report_json)migration_sources(source_key, migration_kind, source_path, target_table, source_sha256, source_size_bytes, source_record_count, last_run_id, status, imported_at, removed_source, report_json)backup_runs(id, created_at, archive_path, status, manifest_json)

エージェントデータベース:

text
schema_meta(meta_key, role, schema_version, agent_id, app_version, created_at, updated_at)sessions(session_id, session_key, session_scope, created_at, updated_at, started_at, ended_at, status, chat_type, channel, account_id, primary_conversation_id, model_provider, model, agent_harness_id, parent_session_key, spawned_by, display_name)conversations(conversation_id, channel, account_id, kind, peer_id, parent_conversation_id, thread_id, native_channel_id, native_direct_user_id, label, metadata_json, created_at, updated_at)session_conversations(session_id, conversation_id, role, first_seen_at, last_seen_at)session_routes(session_key, session_id, updated_at)session_entries(session_id, session_key, entry_json, updated_at)transcript_events(session_id, seq, event_json, created_at)transcript_event_identities(session_id, event_id, seq, event_type, has_parent, parent_id, message_idempotency_key, created_at)transcript_snapshots(session_id, snapshot_id, reason, event_count, created_at, metadata_json)vfs_entries(namespace, path, kind, content_blob, metadata_json, updated_at)tool_artifacts(run_id, artifact_id, kind, metadata_json, blob, created_at)run_artifacts(run_id, path, kind, metadata_json, blob, created_at)trajectory_runtime_events(session_id, run_id, seq, event_json, created_at)memory_index_meta(key, value)memory_index_sources(id, path, source, hash, mtime, size)memory_index_chunks(id, path, source, start_line, end_line, hash, model, text, embedding, updated_at)memory_embedding_cache(provider, model, provider_key, hash, embedding, dims, updated_at)memory_index_state(id, revision)cache_entries(scope, key, value_json, blob, expires_at, updated_at)

memory_index_sources.id は安定した整数の主キーであり、(path, source) は引き続き一意です。

将来の検索機能では、正規のイベントテーブルを変更せずに FTS テーブルを追加できます:

text
transcript_events_fts(session_id, seq, text)vfs_entries_fts(namespace, path, text)

大きな値には JSON 文字列エンコーディングではなく blob カラムを使用します。標準の SQLite ツールで引き続き検査可能である必要がある小さな構造化データには、 value_json を使用します。

このブランチでは agent_databases が正規のレジストリです。実際のエージェントレコードの所有者が 存在するまでは agents テーブルを追加しないでください。エージェント設定は引き続き openclaw.json に保持します。

Doctor マイグレーションの形状

Doctor は、報告可能で再実行しても安全な、明示的な単一のマイグレーション手順を 呼び出す必要があります:

bash
openclaw doctor --fix

openclaw doctor --fix は通常の設定事前チェック後に状態マイグレーションの実装を呼び出し、 インポート前に検証済みバックアップを作成します。ランタイムの起動時および openclaw migrate では、従来の OpenClaw 状態ファイルをインポートしてはなりません。

マイグレーションの特性:

  • 1 回のマイグレーション処理で、従来のすべてのファイルソースを検出し、何かを変更する 前に計画を作成します。
  • Doctor は従来のファイルをインポートする前に、検証済みのマイグレーション前バックアップアーカイブを 作成します。
  • インポートは冪等であり、ソースパス、mtime、サイズ、ハッシュ、およびターゲット テーブルをキーとします。
  • 正常に処理されたソースファイルは、ターゲットデータベースのコミット後に削除または アーカイブされます。
  • インポートに失敗した場合、ソースは変更されず、migration_runs に警告が 記録されます。
  • マイグレーションが存在するようになった後、ランタイムコードは SQLite のみを読み取ります。
  • ダウングレード用またはランタイムファイルへのエクスポート用の経路は不要です。

マイグレーション対象一覧

以下をグローバルデータベースへ移行します:

  • タスクレジストリのランタイム書き込みは共有データベースを使用するようになり、未リリースの tasks/runs.sqlite サイドカーインポーターは削除されました。スナップショット保存ではタスク id ごとに upsert し、存在しないタスク行と配信行のみを削除します。
  • Task Flow のランタイム書き込みは共有データベースを使用するようになり、未リリースの tasks/flows/registry.sqlite サイドカーインポーターは削除されました。スナップショット保存では フロー id ごとに upsert し、存在しないフロー行のみを削除します。
  • Plugin 状態のランタイム書き込みは共有データベースを使用するようになり、未リリースの plugin-state/state.sqlite サイドカーインポーターは削除されました。
  • 組み込みメモリ検索は memory/<agentId>.sqlite をデフォルトとしなくなりました。その インデックステーブルは所有元のエージェントデータベースに格納され、明示的な memorySearch.store.path サイドカーのオプトインは doctor の設定 移行に移されました。
  • 組み込みメモリの再インデックスでは、エージェントデータベース内のメモリ所有テーブルのみをリセットします。 同じデータベースがセッション、トランスクリプト、VFS 行、アーティファクト、ランタイムキャッシュを 所有するため、SQLite ファイル全体を置き換えてはなりません。
  • モノリシックおよびシャーディングされた JSON によるサンドボックスコンテナ/ブラウザレジストリ。ランタイム 書き込みは共有データベースを使用するようになりました。レガシー JSON のインポートは維持されます。
  • Cron ジョブ定義、スケジュール状態、実行履歴は共有 SQLite を使用するようになりました。 doctor はレガシーの jobs.jsonjobs-state.json、および cron/runs/*.jsonl ファイルをインポートして削除します
  • デバイスのアイデンティティ/認証、プッシュ、更新チェック、コミットメント、OpenRouter モデル キャッシュ、インストール済み Plugin インデックス、app-server バインディング
  • デバイス/Node のペアリングおよびブートストラップレコードは、型付き SQLite テーブルを使用するようになりました
  • デバイスペア通知のサブスクライバーと配信済みリクエストマーカーは、 device-pair-notify.json の代わりに共有 SQLite Plugin 状態テーブルを使用するようになりました。
  • 音声通話の通話レコードは、calls.jsonl の代わりに voice-call / calls 名前空間の共有 SQLite Plugin 状態テーブルを使用するようになりました。Plugin CLI は、 SQLite に保存された通話履歴を追尾して要約します。
  • QQBot Gateway セッション、既知ユーザーレコード、ref-index 引用キャッシュは、 session-*.jsonknown-users.jsonref-index.jsonl の代わりに、qqbot 名前空間(gateway-sessionsknown-usersref-index)の SQLite Plugin 状態を使用するようになりました。これらのレガシーファイルはキャッシュであり、移行されません。
  • Discord のモデル選択設定、コマンドデプロイハッシュ、スレッドバインディングは、 model-picker-preferences.jsoncommand-deploy-cache.jsonthread-bindings.json の代わりに、discord 名前空間 (model-picker-preferencescommand-deploy-hashesthread-bindings) の SQLite Plugin 状態を使用するようになりました。Discord の doctor/セットアップ移行は、 レガシーファイルをインポートして削除します。
  • BlueBubbles のキャッチアップカーソルと受信重複排除マーカーは、 bluebubbles/catchup/*.json および bluebubbles/inbound-dedupe/*.json の代わりに、bluebubbles 名前空間(catchup-cursorsinbound-dedupe) の SQLite Plugin 状態を使用するようになりました。BlueBubbles の doctor/セットアップ移行は、 レガシーファイルをインポートして削除します。
  • Telegram の更新オフセット、ステッカーキャッシュエントリ、返信チェーンメッセージキャッシュ エントリ、送信済みメッセージキャッシュエントリ、トピック名キャッシュエントリ、スレッド バインディングは、update-offset-*.jsonsticker-cache.json*.telegram-messages.json*.telegram-sent-messages.json*.telegram-topic-names.jsonthread-bindings-*.json の代わりに、telegram 名前空間 (update-offsetssticker-cachemessage-cachesent-messagestopic-namesthread-bindings)の SQLite Plugin 状態を使用するようになりました。Telegram の doctor/セットアップ移行は、 レガシーファイルをインポートして削除します。
  • iMessage のキャッチアップカーソル、返信 short-id マッピング、送信エコー重複排除行は、 imessage/catchup/*.jsonimessage/reply-cache.jsonlimessage/sent-echoes.jsonl の代わりに、imessage 名前空間(catchup-cursorsreply-cachesent-echoes)の SQLite Plugin 状態を使用するようになりました。iMessage の doctor/セットアップ移行は、レガシーファイルをインポートして削除します。
  • Microsoft Teams の会話、投票、SSO トークン、フィードバック学習は、 msteams-conversations.jsonmsteams-polls.jsonmsteams-sso-tokens.json*.learnings.json の代わりに、SQLite Plugin 状態名前空間 (conversationspollssso-tokensfeedback-learnings)を使用するようになりました。Microsoft Teams の doctor/セットアップ移行は、レガシーファイルをインポートして アーカイブします。保留中のアップロードは短期間のみ保持される SQLite キャッシュであり、古い JSON キャッシュファイルは 移行されません。
  • Matrix の同期キャッシュ、ストレージメタデータ、スレッドバインディング、受信重複排除マーカー、 起動時検証のクールダウン状態、認証情報、リカバリキー、SDK IndexedDB 暗号化スナップショットは、bot-storage.jsonstorage-meta.jsonthread-bindings.jsoninbound-dedupe.jsonstartup-verification.jsoncredentials.jsonrecovery-key.jsoncrypto-idb-snapshot.json の代わりに、matrix 配下の SQLite Plugin 状態/blob 名前空間 (sync-storestorage-metathread-bindings、 コアの取得可能な重複排除を介した matrix.inbound-dedupe.*startup-verificationcredentialsrecovery-keyidb-snapshots) を使用するようになりました。Matrix の doctor/セットアップ移行は、アカウント単位の Matrix ストレージルートから、 これらのレガシーファイル(および廃止されたルート単位の inbound-dedupe SQLite 行)をインポートして削除します。
  • Nostr バスカーソルとプロフィール公開状態は、 bus-state-*.json および profile-state-*.json の代わりに、 nostr 名前空間(bus-stateprofile-state)の SQLite Plugin 状態を使用するようになりました。Nostr の doctor/セットアップ 移行は、レガシーファイルをインポートして削除します。
  • Active Memory のセッション切り替えは、session-toggles.json の代わりに、 active-memory/session-toggles の SQLite Plugin 状態を使用するようになりました。
  • Skill Workshop の提案キューとレビューカウンターは、 ワークスペースごとの skill-workshop/<workspace>.json ファイルの代わりに、 skill-workshop/proposals および skill-workshop/reviews の SQLite Plugin 状態を使用するようになりました。
  • 送信配信キューとセッション配信キューは、永続的な delivery-queue/*.jsondelivery-queue/failed/*.jsonsession-delivery-queue/*.json ファイルの代わりに、個別のキュー名 (outbound-deliverysession-delivery)でグローバル SQLite delivery_queue_entries テーブルを共有するようになりました。doctor のレガシー状態ステップは、 保留中および失敗した行をインポートし、古い配信済みマーカーを削除し、インポート後に古い JSON ファイルを削除します。ホットルーティングおよび再試行フィールドは型付きカラムです。 JSON ペイロードは、再実行/デバッグ専用としてのみ保持されます。
  • ACPX プロセスリースは、process-leases.json の代わりに acpx/process-leases の SQLite Plugin 状態を使用するようになりました。
  • バックアップおよび移行実行のメタデータ

以下をエージェントデータベースに移動します:

  • エージェントセッションルートと互換形式のセッションエントリペイロード。ランタイム書き込みについては完了しています。 ホットセッションメタデータは sessions でクエリでき、レガシー形式の完全な SessionEntry ペイロードは session_entries に残ります。
  • エージェントトランスクリプトイベント。ランタイム書き込みについては完了しています。
  • Compaction チェックポイントとトランスクリプトスナップショット。ランタイム書き込みについては完了しています。 チェックポイントのトランスクリプトコピーは SQLite のトランスクリプト行であり、チェックポイント メタデータは transcript_snapshots に記録されます。Gateway のチェックポイントヘルパーは、 これらの値をソースファイルではなくトランスクリプトスナップショットとして扱うようになりました。
  • エージェント VFS のスクラッチ/ワークスペース名前空間。ランタイム VFS 書き込みについては完了しています。
  • サブエージェントの添付ペイロード。ランタイム書き込みについては完了しています。これらは SQLite VFS シードエントリであり、永続的なワークスペースファイルになることはありません。
  • ツールアーティファクト。ランタイム書き込みについては完了しています。
  • 実行アーティファクト。エージェントごとの run_artifacts テーブルを介したワーカーのランタイム書き込みについては完了しています。
  • エージェントローカルのランタイムキャッシュ。エージェントごとの cache_entries テーブルを介したワーカーランタイムのスコープ付きキャッシュ書き込みについては完了しています。Gateway 全体のモデルキャッシュは、 エージェント固有にならない限りグローバルデータベースに残ります。
  • ACP 親ストリームログ。ランタイム書き込みについては完了しています。
  • ACP 再生台帳セッション。acp_replay_sessions および acp_replay_events を介したランタイム書き込みについては完了しています。レガシーの acp/event-ledger.json は doctor の入力としてのみ残ります。
  • ACP セッションメタデータ。acp_sessions を介したランタイム書き込みについては完了しています。sessions.json 内のレガシー entry.acp ブロックは、doctor の移行入力としてのみ使用されます。
  • 明示的なエクスポートファイルではない場合のトラジェクトリサイドカー。ランタイム 書き込みについては完了しています。トラジェクトリキャプチャはエージェントデータベースの trajectory_runtime_events 行を書き込み、実行スコープのアーティファクトを SQLite にミラーリングします。レガシーサイドカーは doctor の インポート入力としてのみ使用されます。エクスポートでは新しい JSONL サポートバンドル出力を生成できますが、 ランタイムで古いトラジェクトリ/トランスクリプトサイドカーを読み取ったり移行したりしません。 ランタイムのトラジェクトリキャプチャは SQLite スコープを公開します。JSONL パスヘルパーは、 エクスポート/デバッグサポートに限定され、ランタイムモジュールから再エクスポートされません。 組み込みランナーのトラジェクトリメタデータは、トランスクリプトロケーターを永続化する代わりに、 {agentId, sessionId, sessionKey} アイデンティティを記録します。

現時点では、以下をファイルベースのまま維持します:

  • openclaw.json
  • プロバイダーまたは CLI の認証情報ファイル
  • Plugin/パッケージマニフェスト
  • ディスクモードが選択されている場合のユーザーワークスペースおよび Git リポジトリ
  • 特定のログ領域が移動されない限り、オペレーターによる追尾を目的としたログ

移行計画

フェーズ 0:境界を固定する

さらに多くの行を移動する前に、永続状態の境界を明示します:

  • グローバルデータベースに migration_runs テーブルを追加します。 レガシー状態移行の実行レポートについては完了しています。
  • ファイルからデータベースへのインポート用に、doctor が単独で所有する状態移行サービスを追加します。 完了:openclaw doctor --fix はレガシー状態移行の実装を使用します。
  • plan を読み取り専用にし、apply でバックアップの作成、インポート、検証を行った後、 古いファイルを削除または隔離するようにします。 完了:doctor は検証済みの移行前バックアップを作成し、バックアップパスを migration_runs に渡して、インポーター/削除パスを再利用します。
  • 静的禁止ルールを追加し、移行コードとテストでは引き続きレガシー状態ファイルのシード/読み取りができる一方で、 新しいランタイムコードがそれらを書き込めないようにします。 現在移行済みのレガシーストアについては完了しています。このガードは、禁止されたランタイムのトランスクリプトロケーター契約について、 ネストされたテストもスキャンします。

フェーズ 1:グローバルコントロールプレーンを完成させる

共有調整状態を state/openclaw.sqlite に保持します:

  • エージェントおよびエージェントデータベースレジストリ
  • タスクおよび Task Flow の台帳
  • Plugin 状態
  • サンドボックスコンテナ/ブラウザレジストリ
  • Cron/スケジューラー実行履歴
  • ペアリング、デバイス、プッシュ、更新チェック、TUI、OpenRouter/モデルキャッシュ、およびその他の 小規模な Gateway スコープのランタイム状態
  • バックアップおよび移行メタデータ
  • Gateway メディア添付のバイトデータ。ランタイム書き込みについては完了しています。直接ファイルパスは、 チャネル送信元およびサンドボックスステージングとの互換性のための一時的な実体化です。 ランタイム許可リストは、レガシー状態/設定のメディアルートではなく、SQLite の実体化パスを受け入れます。doctor は、 レガシーメディアファイルを media_blobs にインポートし、行の書き込みが成功した後に ソースファイルを削除します。
  • デバッグプロキシのキャプチャセッション、イベント、ペイロード blob。完了:キャプチャは 共有状態 DB に格納され、共有状態 DB のブートストラップ、スキーマ、 WAL、busy-timeout 設定を介して開かれます。ペイロードのバイトデータは capture_blobs.data 内で gzip 圧縮されます。デバッグプロキシのランタイム用サイドカー DB オーバーライド、 blob ディレクトリ、またはプロキシキャプチャ専用の生成スキーマ/codegen ターゲットはありません。 doctor/起動時移行は、アクティブなレガシー DB/blob 環境 オーバーライドを含む、リリース済みの debug-proxy/capture.sqlite 行と参照先ペイロード blob をインポートし、 CA 証明書をそのまま残してそれらのソースをアーカイブします。

このフェーズでは、これらのサブシステムから重複するサイドカーオープナー、権限ヘルパー、WAL 設定、ファイルシステムの整理、互換性ライターも削除します。

フェーズ 2:エージェントごとのデータベースを導入する

エージェントごとに 1 つのデータベースを作成し、グローバル DB から登録します:

text
~/.openclaw/state/openclaw.sqlite~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite

グローバルの agent_databases 行には、パス、スキーマバージョン、最終確認 タイムスタンプ、基本的なサイズ/整合性メタデータが格納されます。ランタイムコードは、 ファイルパスを直接導出する代わりに、レジストリにエージェント DB を問い合わせます。

エージェント DB が所有するもの:

  • 正規のセッションルートとしての sessions、そのルートに関連付けられた互換形状のペイロードテーブルとしての session_entries、および一意のアクティブな session_key 検索としての session_routes
  • セッションに関連付けられた正規化済みプロバイダールーティング ID としての conversations および session_conversations
  • transcript_events
  • トランスクリプトスナップショットと Compaction チェックポイント。ランタイム書き込みについては完了。
  • vfs_entries
  • tool_artifacts と実行アーティファクト
  • エージェントローカルのランタイム/キャッシュ行。ワーカースコープのキャッシュについては完了。
  • ACP 親ストリームイベント
  • 明示的なエクスポートアーティファクトではない場合の軌跡ランタイムイベント

フェーズ 3:セッションストア API の置き換え

ランタイムについては完了。ファイル形状のセッションストアサーフェスは、アクティブなランタイム契約ではありません。

  • ランタイムは loadSessionStore(storePath) を呼び出さなくなり、storePath をセッション ID として扱いません。
  • ランタイムの行操作は getSessionEntryupsertSessionEntrypatchSessionEntrydeleteSessionEntrylistSessionEntries です。
  • ストア全体の書き換えヘルパー、ファイルライター、キューテスト、エイリアスの剪定、およびレガシーキー削除パラメーターはランタイムから削除されています。
  • 非推奨のルートパッケージ互換エクスポートは、引き続き正規の sessions.json パスを SQLite 行 API に適合させます。
  • sessions.json の解析は doctor の移行/インポートコードと doctor テストにのみ残っています。
  • ランタイムライフサイクルのフォールバックは、JSONL の先頭行ではなく SQLite のトランスクリプトヘッダーを読み取ります。

ファイルロックのパラメーター、ファイル保守としての剪定/切り詰めという語彙、ストアパスによる ID、または JSON 永続化だけをアサートするテストを再導入するものは、引き続き削除してください。

フェーズ 4:トランスクリプト、ACP ストリーム、軌跡、VFS の移行

すべてのエージェントデータストリームをデータベースネイティブにします。

  • トランスクリプトの追記書き込みは、セッションヘッダーを確保し、メッセージの冪等性を確認し、親末尾を選択し、transcript_events に挿入し、検索可能な ID メタデータを transcript_event_identities に記録する、単一の SQLite トランザクションを経由します。トランスクリプトメッセージの直接追記と通常の永続化された TranscriptSessionManager 追記については完了しています。明示的なブランチ操作では、明示的に選択された親を維持し、ファイルロケーターを導出することなく SQLite 行への書き込みを継続します。
  • ACP 親ストリームログは .acp-stream.jsonl ファイルではなく行になります。完了。
  • ACP スポーンのセットアップは、トランスクリプト JSONL パスを永続化しなくなりました。完了。
  • ランタイムの軌跡キャプチャは、イベント行/アーティファクトを直接書き込みます。明示的なサポート/エクスポートコマンドは、エクスポート形式としてサポートバンドル JSONL アーティファクトを引き続き生成できますが、セッションエクスポートでセッション JSONL を再作成することはありません。完了。
  • ディスクモードとして設定されたディスクワークスペースは、引き続きディスク上に保持されます。
  • VFS スクラッチおよび実験的な VFS 専用ワークスペースモードは、エージェント DB を使用します。

移行では古い JSONL ファイルを一度だけインポートし、件数/ハッシュを migration_runs に記録し、整合性チェック後にインポート済みファイルを削除します。

フェーズ 5:バックアップ、復元、Vacuum、検証

バックアップは単一のアーカイブファイルのままです。

  • すべてのグローバルデータベースとエージェントデータベースをチェックポイントします。
  • SQLite のバックアップセマンティクスまたは VACUUM INTO を使用して各 DB のスナップショットを作成します。
  • コンパクトな DB スナップショット、設定、外部認証情報、および要求されたワークスペースエクスポートをアーカイブします。
  • 生の稼働中 *.sqlite-wal および *.sqlite-shm ファイルは除外します。
  • 各 DB スナップショットを開き、PRAGMA integrity_check を実行して検証します。openclaw backup create はデフォルトでこのアーカイブ検証を実行します。--no-verify でスキップされるのは書き込み後のアーカイブ処理だけであり、スナップショット作成時の整合性チェックはスキップされません。
  • 復元では、スナップショットを対象パスへコピーして戻します。復元されたグローバル DB はバージョン 1、復元されたエージェント単位 DB はバージョン 2 を使用し、バージョン 1 のスナップショットは開かれたときにアトミックにアップグレードされます。

フェーズ 6:ワーカーランタイム

データベース分割の導入中は、ワーカーモードを実験的な状態に保ちます。

  • ワーカーは、エージェント ID、実行 ID、ファイルシステムモード、および DB レジストリ ID を受け取ります。
  • 各ワーカーは独自の SQLite 接続を開きます。
  • 親はチャネル配信、承認、設定、およびキャンセル権限を保持します。
  • まずアクティブな実行ごとに 1 ワーカーとし、ライフサイクルと DB 接続の所有権が安定した後にのみプーリングを追加します。

フェーズ 7:旧世界の削除

ランタイムのセッション管理については完了。旧世界は、明示的な doctor 入力またはサポート/エクスポート出力としてのみ許可されます。

  • ランタイムによる sessions.json、トランスクリプト JSONL、サンドボックスレジストリ JSON、タスクサイドカー SQLite、または Plugin 状態サイドカー SQLite への書き込みはありません。
  • JSON/セッションファイルの剪定、ファイルトランスクリプトの切り詰め、セッションファイルロック、またはロック形状のセッションテストはありません。
  • 古いセッションファイルを最新状態に保つことを目的とするランタイム互換エクスポートはありません。
  • 明示的なサポートエクスポートは、ユーザーが要求したアーカイブ/実体化形式として残り、ファイル名をランタイム ID にフィードバックしてはなりません。

バックアップと復元

バックアップは単一のアーカイブファイルにする必要がありますが、データベースのキャプチャは SQLite ネイティブにする必要があります。

  1. 長時間実行される書き込み処理を停止するか、短時間のバックアップバリアに入ります。
  2. すべてのグローバルデータベースとエージェントデータベースでチェックポイントを実行します。
  3. VACUUM INTO を使用して、一時バックアップディレクトリにデータベースのスナップショットを作成します。所有者定義の SQLite 機能を必要とする Plugin スキーマは、所有者が安全なスナップショット契約を提供するまでフェイルクローズします。
  4. データベーススナップショット、設定ファイル、認証情報ディレクトリ、選択されたワークスペース、およびマニフェストをアーカイブします。
  5. 各 SQLite スナップショットのファイル形状を検証し、正規の OpenClaw データベースを開いて PRAGMA integrity_check とロール検証を実行します。専用の Plugin スキーマは、その所有者が検証機能を提供しない限り不透明なままです。openclaw backup create はこれをデフォルトで実行します。--no-verify は、書き込み後のアーカイブ処理を意図的にスキップする場合にのみ使用します。

生の稼働中 *.sqlite*.sqlite-wal*.sqlite-shm のコピーを主要なバックアップ形式として使用しないでください。アーカイブマニフェストには、データベースロール、エージェント ID、スキーマバージョン、ソースパス、スナップショットパス、バイトサイズ、および整合性ステータスを記録する必要があります。

復元では、アーカイブスナップショットからグローバルデータベースファイルとエージェントデータベースファイルを再構築する必要があります。グローバルスキーマはバージョン 1 のままです。エージェント単位のバージョン 1 スナップショットには、バージョン 2 への限定的なランタイムアップグレードが適用されます。ファイルからデータベースへのインポートは、引き続き doctor のみが所有します。復元コマンドは最初にアーカイブを検証し、その後、検証済みの展開ペイロードから各マニフェストアセットを置き換えます。

ランタイムリファクタリング計画

  1. データベースレジストリ API を追加します。

    • グローバル DB とエージェント単位 DB のパスを解決します。
    • グローバルスキーマを user_version = 1 に維持します。エージェント単位 DB はバージョン 2 を使用し、リリース済みのバージョン 1 メモリソース形状から 1 回のアトミックな移行を行います。
    • テスト、バックアップ、doctor で使用するクローズ/チェックポイント/整合性ヘルパーを追加します。
  2. サイドカー SQLite ストアを統合します。

    • Plugin 状態テーブルをグローバルデータベースに移動します。ランタイム書き込みについては完了しており、未リリースのレガシーサイドカーインポーターは削除されています。
    • タスクレジストリテーブルをグローバルデータベースに移動します。ランタイム書き込みについては完了しており、未リリースのレガシーサイドカーインポーターは削除されています。
    • Task Flow テーブルをグローバルデータベースに移動します。ランタイム書き込みについては完了しており、未リリースのレガシーサイドカーインポーターは削除されています。
    • 組み込みメモリ検索テーブルを各エージェントデータベースに移動します。完了。明示的なカスタム memorySearch.store.path は、doctor の設定移行によって削除されるようになりました。完全な再インデックスはメモリテーブルのみを対象としてその場で実行されます。古いファイル全体のスワップパスとサイドカーインデックススワップヘルパーは削除されています。
    • これらのサブシステムから、重複したデータベースオープナー、WAL セットアップ、権限ヘルパー、およびクローズ処理を削除します。
  3. エージェント所有のテーブルをエージェント単位のデータベースへ移動します。

    • グローバルデータベースレジストリを通じて、必要に応じてエージェント DB を作成します。完了。
    • ランタイムセッションエントリ、トランスクリプトイベント、VFS 行、およびツールアーティファクトをエージェント DB に移動します。完了。
    • ブランチローカルな共有 DB のセッションエントリ、トランスクリプトイベント、VFS 行、またはツールアーティファクトは移行しません。そのレイアウトは一度もリリースされていません。doctor には、レガシーファイルからデータベースへのインポートのみを残します。
  4. セッションストア API を置き換えます。

    • ランタイム ID としての storePath を削除します。ランタイムについては完了しており、check:database-first-legacy-stores によって保護されています。セッションメタデータ、ルート更新、コマンド永続化、CLI セッションクリーンアップ、Feishu 推論プレビュー、トランスクリプト状態の永続化、サブエージェント深度、認証プロファイルのセッションオーバーライド、親フォークロジック、および QA ラボ検査は、正規のエージェント/セッションキーからデータベースを解決するようになりました。 Gateway/TUI/UI/macOS のセッション一覧レスポンスは、レガシーな path の代わりに databasePath を公開するようになりました。macOS のデバッグサーフェスは、session.store 設定へ書き込む代わりに、エージェント単位のデータベースを読み取り専用状態として表示します。 /status、チャット駆動の軌跡エクスポート、および CLI 依存関係プロキシは、レガシーストアパスを伝播しなくなりました。トランスクリプト使用量のフォールバックは、エージェント/セッション ID に基づいて SQLite を読み取ります。ランタイムテストとブリッジテストは storePath を公開しなくなり、レガシーフィールド名は doctor/移行入力が所有します。 Gateway の統合セッション読み込みには、テンプレート化されていない session.store 値に対する特別なランタイム分岐がなくなり、エージェント単位の SQLite 行を集約します。 レガシーなセッションロックの doctor レーンと、その .jsonl.lock クリーンアップヘルパーは削除されました。現在は SQLite がセッションの並行処理境界です。 高頻度のランタイム呼び出し箇所では、resolveSessionRowEntry のような行指向のヘルパー名を使用します。古い resolveSessionStoreEntry 互換エイリアスは、ランタイムと Plugin SDK エクスポートから削除されています。
  • { agentId, sessionKey } 行操作を使用します。 完了:getSessionEntryupsertSessionEntrydeleteSessionEntrypatchSessionEntrylistSessionEntries は、セッションストアパスを必要としない SQLite 優先の API です。ステータス概要、ローカルエージェントステータス、ヘルス、および openclaw sessions 一覧コマンドは、エージェント単位の行を直接読み取り、sessions.json パスではなくエージェント単位の SQLite データベースパスを表示するようになりました。
  • ストア全体の削除/挿入を、upsertSessionEntrydeleteSessionEntrylistSessionEntries、および SQL クリーンアップクエリで置き換えます。 ランタイムについては完了しています。高頻度パスは行 API と競合時に再試行する行パッチを使用するようになりました。残っているストア全体のインポート/置換ヘルパーは、移行インポートコードと SQLite バックエンドテストに限定されています。
    • store-writer.ts とライターキューテストを削除します。完了。
    • セッション行の upsert/patch から、ランタイムのレガシーキー剪定およびエイリアス削除パラメーターを削除します。完了。
  1. ランタイムの JSON レジストリ動作を削除します。
    • サンドボックスレジストリの読み書きを SQLite 専用にします。完了。
    • モノリシック JSON とシャード化 JSON は、移行ステップからのみインポートします。完了。
    • シャード化レジストリのロックと JSON 書き込みを削除します。完了。
  • 形状が引き続き高頻度パスの運用状態である場合、レジストリ行を汎用の不透明な JSON として保存するのではなく、型付きレジストリテーブルを 1 つ維持します。完了。
  1. ファイルロック形状のセッション変更処理を削除します。

    • ランタイムのロック作成とランタイムロック API については完了。
    • 独立したレガシー .jsonl.lock doctor クリーンアップレーンは削除されています。
    • session.writeLock は doctor によって移行されるレガシー設定であり、型付きランタイム設定ではありません。
    • 状態整合性には、孤立したトランスクリプトファイルを剪定する独立したパスがなくなりました。doctor の移行が、レガシー JSONL ソースのインポート/削除を 1 か所で行います。
    • Gateway のシングルトン調整は、gateway_locks 配下の型付き SQLite state_leases 行を使用し、ファイルロックディレクトリのシームを公開しなくなりました。
    • 汎用 Plugin SDK の重複排除永続化は、ファイルロックや JSON ファイルを使用しなくなり、共有 SQLite Plugin 状態行へ書き込みます。完了。
    • QMD 埋め込み調整は、qmd/embed.lock の代わりに SQLite 状態リースを使用します。完了。
  2. ワーカーをデータベース対応にします。

    • ワーカーは独自の SQLite 接続を開きます。
    • 親は配信、チャネルコールバック、および設定を所有します。
    • ワーカーは、ライブハンドルではなく、エージェント ID、実行 ID、ファイルシステムモード、および DB レジストリ ID を受け取ります。
    • vfs-only は実験的なままとし、ストレージルートとしてエージェントデータベースを使用します。
    • まずアクティブな実行ごとに 1 ワーカーを維持します。プーリングは、DB 接続の有効期間とキャンセル動作が安定するまで待つことができます。
  3. バックアップ統合。

    • バックアップがグローバル、エージェント、Plugin の各データベースを VACUUM INTO でスナップショットできるようにする。state アセット配下で検出された *.sqlite ファイルについて完了済み。利用できない所有者機能を必要とする Plugin スキーマはフェイルクローズする。
    • 正規 SQLite の整合性とスキーマ識別情報に対するバックアップ検証に加え、 専用 Plugin スナップショットに対する汎用的なファイル形式検証を追加する。バックアップ作成と デフォルトのアーカイブ検証について完了済み。
    • バックアップ実行メタデータを SQLite に記録する。アーカイブパス、ステータス、 マニフェスト JSON を含む共有 backup_runs テーブルによって完了済み。
    • 検証済みアーカイブスナップショットからの復元を追加する。完了済み:openclaw backup restore は展開前に検証し、検証機能によって正規化された マニフェストを使用し、--dry-run をサポートし、記録されたソースパスを置換する前に --yes を必須とする。
    • VFS/ワークスペースのエクスポートは要求された場合のみ含める。セッション内部情報を JSON または JSONL としてエクスポートしない。
  4. 廃止されたテストとコードを削除する。既知のランタイムセッションサーフェスについて完了済み。

  • ランタイムによる sessions.json またはトランスクリプト JSONL ファイルの作成を表明するテストを削除する。コアセッションストア、チャット、Gateway のトランスクリプトイベント、 プレビュー、ライフサイクル、コマンドのセッションエントリー更新、自動返信のリセット/トレース、および memory-core の Dreaming フィクスチャ、承認ターゲットのルーティング、セッショントランスクリプトの 修復、セキュリティ権限の修復、軌跡エクスポート、セッションエクスポートについて完了済み。 Active Memory のトランスクリプトテストは、SQLite スコープ、および一時的または 永続的な JSONL ファイルが作成されないことを表明するようになった。 ランタイムが JSONL トランスクリプトを切り詰めなくなったため、 古い Heartbeat のトランスクリプト整理に関するリグレッションテストを削除した。 エージェントのセッション一覧ツールのテストでは、従来の sessions.json パスを Gateway レスポンス形式としてモデル化しなくなった。アプリ/UI/macOS のテストでは databasePath を使用する。 /status のトランスクリプト使用量テストでは、JSONL ファイルを書き込む代わりに SQLite のトランスクリプト行を直接シードするようになった。 Gateway のセッションライフサイクルテストでは、SQLite トランスクリプトのシードヘルパーを 直接使用するようになった。古い単一行セッションファイルのフィクスチャ形式は、リセットおよび 削除のカバレッジから除去された。 sessions.delete は、ファイル時代の archived: [] フィールドを返さなくなった。削除では 行の変更結果のみを報告する。古い deleteTranscript オプションも 廃止された。セッションを削除すると正規の sessions ルートが削除され、SQLite によって セッション所有のトランスクリプト、スナップショット、軌跡の各行がカスケード削除されるため、 呼び出し元がトランスクリプトを孤立させたり、クリーンアップ分岐を忘れたりすることはない。 コンテキストエンジンの軌跡キャプチャテストでは、 session.trajectory.jsonl を読み取る代わりに、分離されたエージェントデータベースから trajectory_runtime_events 行を読み取るようになった。 Docker MCP チャンネルのシードスクリプトでは、SQLite 行を直接シードするようになった。 sessions.json への直接書き込みは doctor のフィクスチャに限定される。 Tool Search Gateway E2E は、agents/<agentId>/sessions/*.jsonl ファイルをスキャンする代わりに、 SQLite トランスクリプト行からツール呼び出しの証拠を読み取る。 Memory-core のホストイベントとセッションコーパスのスクラッチ行は、共有 SQLite Plugin 状態に格納されるようになった。events.jsonlsession-corpus/*.txt は、従来形式を対象とする doctor 移行の入力にのみ使用される。アクティブな行では .dreams/session-corpus ではなく memory/session-ingestion/ 仮想パスを使用する。ランタイムがそのコーパスの ファイルアーカイブ修復を担わなくなったため、古い memory-core の Dreaming 修復モジュールとその CLI/Gateway テストを削除した。Memory-core の ブリッジ/公開アーティファクトテストでは .dreams/events.jsonl を公開しなくなり、 SQLite を基盤とする仮想 JSON アーティファクト名を使用する。 公開 SDK/Codex テストドキュメントでは、セッションファイルではなく SQLite セッション状態と記載するようになり、 チャンネルターンの例では storePath 引数を公開しなくなった。 Matrix の同期状態では、SQLite の Plugin 状態ストアを直接使用するようになった。アクティブな クライアント/ランタイム契約は bot-storage.json パスではなく、アカウントのストレージルートを渡し、 doctor は従来の bot-storage.json を SQLite にインポートしてから ソースを削除する。QA の Matrix 再起動/破壊的シナリオでは、偽の bot-storage.json ファイルを作成または削除する代わりに、 SQLite 同期行を直接変更するようになり、 E2EE 基盤は偽の sync-store.json パスではなく同期ストアのルートを渡す。 Matrix のストレージルート選択では、従来の同期/スレッド JSON ファイルに基づいてルートを評価しなくなり、永続的なルートメタデータと実際の暗号化状態を使用する。 ランタイム SQLite セッションバックエンドのテストスイートでは、 sessions.json を捏造しなくなった。従来のソースフィクスチャは、それらをインポートする doctor テストに置かれるようになった。 Gateway のセッションテストでは、createSessionStoreDir ヘルパーや 未使用の一時セッションストアパス設定を公開しなくなった。フィクスチャディレクトリは明示的であり、直接の 行設定では SQLite セッション行の命名を使用する。 doctor 専用の JSON5 セッションストアパーサーのカバレッジは、インフラテストから doctor 移行テストへ移動したため、ランタイムテストスイートは従来の セッションファイル解析を担わなくなった。 Microsoft Teams ランタイムの SSO/保留中アップロードのテストでは、JSON サイドカーの フィクスチャやパーサーを保持しなくなった。従来の SSO トークン解析は Plugin 移行モジュールにのみ存在する。Telegram のテストでは、偽の /tmp/*.json ストア パスをシードしなくなり、SQLite を基盤とするメッセージキャッシュを直接リセットする。汎用の OpenClaw テスト状態ヘルパーでは、従来の auth-profiles.json ライターを公開しなくなった。doctor の認証移行テストがそのフィクスチャをローカルに所有する。 TUI の最終セッションポインター、実行承認、Active Memory の 切り替え、Matrix の重複排除/起動検証、Memory Wiki のソース同期、 現在の会話のバインディング、オンボーディング認証、Hermes のシークレットインポートに関するランタイムテストでは、 古いサイドカーファイルを作成したり、古いファイル名が存在しないことを表明したりしなくなった。これらのテストでは SQLite 行と公開ストア API を通じて動作を証明する。従来のソースファイル名が属するのは doctor/移行テストのみである。 デバイス/Node のペアリング、チャンネルの allowFrom、再起動インテント、 再起動ハンドオフ、セッション配信キューエントリー、設定の正常性、iMessage キャッシュ、Cron ジョブ、PI トランスクリプトヘッダー、サブエージェントレジストリ、管理対象 画像添付に関するランタイムテストでも、無視または不在を証明するためだけに 廃止済みの JSON/JSONL ファイルを作成しなくなった。 PI のオーバーフロー回復では、SessionManager の書き換え/切り詰め フォールバックを使用しなくなった。ツール結果の切り詰めとコンテキストエンジンのトランスクリプト書き換えは、 SQLite トランスクリプト行を変更してから、データベースからアクティブなプロンプト状態を更新する。 永続化された SessionManager のメッセージ追加処理は、親の選択と冪等性のために アトミックな SQLite トランスクリプト追加ヘルパーへ委譲する。通常の メタデータ/カスタムエントリーの追加でも、SQLite 内で現在の親を選択するため、 古いマネージャーインスタンスが SQLite 移行前の親チェーン競合を復活させることはない。 ターン途中の事前チェックと sessions_yield に対する合成 PI テールのクリーンアップでは、 SQLite トランスクリプト状態を直接切り詰めるようになった。古い SessionManager のテール削除 ブリッジとそのテストは削除された。 Compaction チェックポイントのキャプチャでも SQLite からのみスナップショットを取得する。呼び出し元は 代替トランスクリプトソースとして稼働中の SessionManager を渡さなくなった。

  • 従来ファイルをシードするテストは、移行専用としてのみ維持する。

  • アクティブなランタイムサーフェスでは、JSON ファイルによる証明を SQL 行による証明に置き換えた。

  • 従来のセッション/キャッシュ JSON パスへのランタイム書き込みを静的に禁止する。 リポジトリガードについて完了済み。

  1. 移行レポートを監査可能にする。
    • 開始/終了タイムスタンプ、ソースパス、ソースハッシュ、件数、警告、 バックアップパスを含む移行実行記録を SQLite に保存する。 完了済み:従来状態の移行実行では、ソースパス/テーブルのインベントリ、ソースファイルの SHA-256、サイズ、 レコード件数、警告、バックアップパスを含む migration_runs レポートを永続化するようになった。 完了済み:従来状態の移行実行では、ソース単位の監査と将来のスキップ/バックフィル判断のために migration_sources 行も永続化するようになった。
    • 適用処理を冪等にする。部分的なインポート後に再実行した場合は、 インポート済みのソースをスキップするか、安定したキーでマージする必要がある。 完了済み:セッションインデックス、トランスクリプト、配信キュー、Plugin 状態、タスク 台帳、およびエージェント所有のグローバル SQLite 行は、安定したキーまたは upsert/replace セマンティクスによってインポートされるため、再実行しても永続行を重複させずに マージされる。
    • インポートに失敗した場合は、元のソースファイルをその場に保持する必要がある。 完了済み:失敗したトランスクリプトのインポートでは、元の JSONL ソースを 検出されたパスに残し、次回の doctor 実行に備えて migration_sourceswarningremoved_source=0 として記録する。

パフォーマンス規則

  • スレッド/プロセスごとに 1 接続で問題ない。ワーカー間でハンドルを共有しない。
  • WAL、foreign_keys=ON、5s のビジータイムアウト、短い BEGIN IMMEDIATE 書き込みトランザクションを使用する。SQLite の単一のビジー待機の上に、 同期的なロック再試行を重ねない。
  • 明示的なミューテックス/バックプレッシャーのセマンティクスを持つ非同期トランザクション API が追加されない限り、書き込みトランザクションヘルパーは同期のままにする。
  • 親への配信書き込みは小さく、トランザクション内に収める。
  • ストア全体の書き換えを避け、行単位の upsert/delete を使用する。
  • ホットコードを移行する前に、エージェント別一覧、セッション別一覧、更新日時、実行 ID、 有効期限の各パスにインデックスを追加する。
  • 大きなアーティファクト、メディア、ベクトルは、base64 や数値配列 JSON ではなく、 BLOB またはチャンク化された BLOB 行として保存する。
  • 不透明な Plugin 状態エントリーは、小さく、適切なスコープに限定する。
  • ファイルシステムの整理ではなく、TTL/有効期限に対する SQL クリーンアップを追加する。 データベース所有のランタイムストアについて完了済み。メディア、Plugin 状態、Plugin BLOB、 永続的な重複排除、エージェントキャッシュはすべて SQLite 行を通じて期限切れになる。残る ファイルシステムのクリーンアップは、一時的な実体化または明示的な 削除コマンドに限定される。

静的禁止事項

従来の状態パスへの新規ランタイム書き込みを失敗させるリポジトリチェックを追加する:

  • sessions.json
  • マテリアライズされたサポートバンドル出力を除く *.trajectory.jsonl
  • .acp-stream.jsonl
  • acp/event-ledger.json
  • cache/*.json ランタイムキャッシュファイル
  • agents/<agentId>/agent/auth.json
  • agents/<agentId>/agent/models.json
  • credentials/oauth.json
  • github-copilot.token.json
  • openrouter-models.json
  • auth-profiles.json
  • auth-state.json
  • exec-approvals.json
  • workspace-state.json
  • Matrix の credentials*.json および recovery-key.json
  • cron/runs/*.jsonl
  • cron/jobs.json
  • jobs-state.json
  • device-pair-notify.json
  • devices/pending.json / devices/paired.json / devices/bootstrap.json (2026.7 で廃止:ランタイムストアは共有状態 DB 内の device_pairing_* / device_bootstrap_tokens。ペアリング済みレコードは Gateway 起動時にインポートされ、 一時的な保留中/ブートストラップ行は削除される)
  • nodes/pending.json / nodes/paired.json(2026.7 で廃止:Gateway 起動時にペアリング済みデバイスレコードへ統合)
  • identity/device.json
  • identity/device-auth.json
  • push/web-push-subscriptions.json
  • push/vapid-keys.json
  • push/apns-registrations.json
  • process-leases.json
  • gateway-instance-id
  • session-toggles.json
  • Memory-core .dreams/events.jsonl
  • Memory-core .dreams/session-corpus/
  • Memory-core .dreams/daily-ingestion.json
  • Memory-core .dreams/session-ingestion.json
  • Memory-core .dreams/short-term-recall.json
  • Memory-core .dreams/phase-signals.json
  • Memory-core .dreams/short-term-promotion.lock
  • Skill Workshop skill-workshop/<workspace>.json
  • Skill Workshop skill-workshop/skill-workshop-review-*.json
  • Nostr bus-state-*.json
  • Nostr profile-state-*.json
  • calls.jsonl
  • known-users.json
  • ref-index.jsonl
  • QQBot session-*.json
  • BlueBubbles bluebubbles/catchup/*.json
  • BlueBubbles bluebubbles/inbound-dedupe/*.json
  • Telegram update-offset-*.json
  • Telegram sticker-cache.json
  • Telegram *.telegram-messages.json
  • Telegram *.telegram-sent-messages.json
  • Telegram *.telegram-topic-names.json
  • Telegram thread-bindings-*.json
  • iMessage catchup/*.json
  • iMessage reply-cache.jsonl
  • iMessage sent-echoes.jsonl
  • Microsoft Teams msteams-conversations.json
  • Microsoft Teams msteams-polls.json
  • Microsoft Teams msteams-sso-tokens.json
  • Microsoft Teams *.learnings.json
  • Matrix bot-storage.json
  • Matrix sync-store.json
  • Matrix thread-bindings.json
  • Matrix inbound-dedupe.json
  • Matrix startup-verification.json
  • Matrix storage-meta.json
  • Matrix crypto-idb-snapshot.json
  • Discord model-picker-preferences.json
  • Discord command-deploy-cache.json
  • サンドボックスレジストリのシャード JSON ファイル
  • ネイティブフックリレーの /tmp ブリッジ JSON ファイル
  • plugin-state/state.sqlite
  • アドホックな openclaw-state.sqlite ランタイムサイドカー
  • tasks/runs.sqlite
  • tasks/flows/registry.sqlite
  • bindings/current-conversations.json
  • restart-sentinel.json
  • gateway-restart-intent.json
  • gateway-supervisor-restart-handoff.json
  • gateway.<hash>.lock
  • qmd/embed.lock
  • commands.log
  • config-health.json
  • port-guard.json
  • settings/voicewake.json
  • settings/voicewake-routing.json
  • plugin-binding-approvals.json
  • plugins/installs.json
  • audit/file-transfer.jsonl
  • audit/crestodian.jsonl
  • crestodian/rescue-pending/*.json
  • plugins/phone-control/armed.json
  • Memory Wiki .openclaw-wiki/log.jsonl
  • Memory Wiki .openclaw-wiki/state.json
  • Memory Wiki .openclaw-wiki/locks/
  • Memory Wiki .openclaw-wiki/source-sync.json
  • Memory Wiki .openclaw-wiki/import-runs/*.json
  • Memory Wiki .openclaw-wiki/cache/agent-digest.json
  • Memory Wiki .openclaw-wiki/cache/claims.jsonl
  • ClawHub .clawhub/lock.json
  • ClawHub .clawhub/origin.json
  • ブラウザプロファイル装飾 .openclaw-profile-decorated
  • SessionManager.open(...) のファイルベースセッションオープナー
  • SessionManager.listAll(...) および TranscriptSessionManager.listAll(...) のトランスクリプト一覧ファサード
  • SessionManager.forkFromSession(...) および TranscriptSessionManager.forkFromSession(...) のトランスクリプトフォークファサード
  • SessionManager.newSession(...) および TranscriptSessionManager.newSession(...) の可変セッション置換ファサード
  • SessionManager.createBranchedSession(...) および TranscriptSessionManager.createBranchedSession(...) のブランチセッションファサード

この禁止規則では、テストによるレガシーフィクスチャの作成、および移行コードによる レガシーファイルソースの読み取り/インポート/削除を許可する必要があります。未出荷の SQLite サイドカーは引き続き禁止され、 doctor のインポート許可の対象にはなりません。

完了条件

  • ランタイムデータおよびキャッシュの書き込み先が、グローバルまたはエージェントの SQLite データベースになっている。
  • ランタイムがセッションインデックス、トランスクリプト JSONL、サンドボックスレジストリ JSON、タスクサイドカー SQLite、またはプラグイン状態サイドカー SQLite に書き込まなくなっている。未出荷のタスク およびプラグイン状態サイドカー SQLite のインポーターが削除されている。
  • レガシーファイルのインポートが doctor のみで行われる。
  • バックアップによって、コンパクトな SQLite スナップショットと整合性証明を含む単一のアーカイブが生成される。
  • エージェントワーカーが、ディスク、VFS スクラッチ、または実験的な VFS のみの ストレージで実行できる。
  • 設定ファイルおよび明示的な認証情報ファイルだけが、永続化されることを想定した データベース外の制御ファイルとして残る。
  • リポジトリチェックによって、レガシーなランタイムファイルストアの再導入が防止される。
Was this useful?
On this page

On this page