メインコンテンツまでスキップ

プラットフォーム基盤

Libre WebUI は、ローカル優先の solo プロファイルと、共有型の team プロファイルに対応しています。solo は SQLite、暗号化されたローカル blob、暗号化された埋め込みベクトル、ローカル調整、組み込み永続ワーカーを使います。team は PostgreSQL、S3 互換の非公開 blob、PGVector、Redis による調整、外部永続ワーカーを使います。ローカルと共有のバックエンドに状態を黙って分割せず、プロファイルが混在している場合は起動を拒否します。

現在のマイルストーン

領域実装済みの基盤呼び出し側に残る作業
永続化SQLite/PostgreSQL リポジトリ、不変のマイグレーション、プールされたトランザクション新しいドメインはリポジトリ境界を使う必要があります
blob暗号化されたローカル/S3 互換ストリーミングストア、範囲取得、チェックサム、永続クォータチャット添付、アバター、残っているインラインバイナリフィールドを移行します
ベクトル暗号化された埋め込みベクトル、PGVector ACL、削除に安全な文書インデックス再構築新しい埋め込み呼び出し側は、同じ権限とライフサイクル契約を守る必要があります
調整ローカル/Redis のイベント、キャッシュ、リース、レート制限、無効化、正常性Redis を正式な状態にしてはいけません
ジョブ/イベントSQLite/PostgreSQL キュー、トランザクショナルイベント、ワーカー、再試行、キャンセル、管理新しい副作用には必ず、冪等性または outbox の設計が必要です
運用ヘルスゲート、署名/暗号化バックアップアーカイブ、クリーンな対象への復元、検証各デプロイ環境で復元とレプリカ間の受け入れを実地検証します

ランタイムプロファイル

既定値は LIBRE_PLATFORM_MODE=solo です。SQLite、ローカル blob、埋め込みベクトル、ローカル調整、組み込み永続ワーカーを選択します。solo モードで Redis を選ぶことはできますが、それによって SQLite やローカルファイルをレプリカ間で安全に共有できるようにはなりません。

LIBRE_PLATFORM_MODE=team では、次の共有依存関係をすべて同時に設定する必要があります。

  • DATABASE_BACKEND=postgresDATABASE_URL
  • BLOB_STORE_BACKEND=s3
  • VECTOR_STORE_BACKEND=pgvector
  • COORDINATION_BACKEND=redisREDIS_URL
  • JOB_WORKER_MODE=external

これらのセレクターは、一貫した 1 組です。共有依存関係が 1 つでも欠けている場合や、ローカルバックエンドがプロファイルに混在している場合、team の起動は失敗します。

既存の solo インストールを移行する

移行前に、すべての Libre アプリケーションとワーカーを停止します。以下の例では、グローバル npm または Homebrew からインストールした libre-webui コマンドを使います。グローバルにインストールしない場合は、npx --yes libre-webui@latest に置き換えます。ソースのチェックアウトからは一度ビルドし、libre-webui migrate-postgresnpm run migrate:postgres -- に置き換えます。対象の PostgreSQL、S3、バージョン付き暗号化キー環境を、移行先 team デプロイとまったく同じに設定してから、まず読み取り専用の分析を実行します。

libre-webui migrate-postgres \
--source /absolute/path/to/data.sqlite \
--plugins /absolute/path/to/plugins \
--mode dry-run

そのレポートで特定された空の対象にだけ適用します。失敗した実行はチェックサム付きのインポートジャーナルを残します。無関係なインポートを開始せず、同じソースと対象で再開してください。

libre-webui migrate-postgres \
--source /absolute/path/to/data.sqlite \
--plugins /absolute/path/to/plugins \
--mode apply

# Only after an interrupted apply of this exact source and target:
libre-webui migrate-postgres \
--source /absolute/path/to/data.sqlite \
--plugins /absolute/path/to/plugins \
--mode apply --resume

libre-webui migrate-postgres \
--source /absolute/path/to/data.sqlite \
--plugins /absolute/path/to/plugins \
--mode validate

リレーショナル行、プラグイン定義、暗号化されたローカル blob、埋め込みベクトル、レガシーのペルソナベクトルがすべて PostgreSQL/S3/PGVector へ転送され、認証されるまで、完了マーカーは付けられません。コマンドがソース暗号化キーを推測して作ることはありません。ENCRYPTION_KEY はソースの .encryption_key と一致しなければならず、STORAGE_ENCRYPTION_KEYS には、設定済みのアクティブキーと、それに一致する legacy エントリが必要です。

同梱の team プロファイルを実行する

安全側に閉じる同梱テンプレートから始めます。完成した環境ファイルはリポジトリ外に置き、運用者だけがアクセスできるよう制限します。

cp deploy/team/.env.example /absolute/path/to/libre-team.env
chmod 600 /absolute/path/to/libre-team.env

起動前に、すべての REPLACE_* 値を置き換えます。PostgreSQL パスワードは URL セーフな文字集合で生成してください(例: openssl rand -hex 32)。同じリテラル値が、サーバーパスワードと DATABASE_URL の一部の両方になるためです。ENCRYPTION_KEYSTORAGE_ENCRYPTION_KEYS 内の各値は、正確に 64 文字の 16 進数でなければなりません。新規インストールでは、legacy エントリを ENCRYPTION_KEY と同じにします。SQLite からの移行では、両方をソースキーと同じにする必要があります。新しい blob の書き込みには別のアクティブキーを使い、オブジェクトインベントリで未使用と証明されるまで古いキーを保持します。

同じファイルには、POSTGRES_MIGRATION_MODEPOSTGRES_POOL_MAX、対応する PostgreSQL タイムアウト、REDIS_CONNECT_TIMEOUT_MSOLLAMA_BASE_URLOLLAMA_TIMEOUTOLLAMA_LONG_OPERATION_TIMEOUTOLLAMA_MAX_CONTEXT も設定できます。共有 Compose 環境は、各値をアプリケーションと外部ワーカーへ同一に渡します。プロバイダータイムアウトは 1,000~3,600,000 ミリ秒、最大コンテキストは 128~2,097,152 トークンを受け付けます。長時間処理用タイムアウトを標準タイムアウトより短くすることはできません。不正な値があると、状態が作られる前に両方のサーバーエントリポイントが失敗します。ノードローカルの Agent CLI バイナリと Codex OAuth トークンファイルは、外部永続ワーカーではサポートされません。そのため team プロファイルは両方のプロバイダー経路を無効に固定し、有効化しようとすると起動を拒否します。次に、アプリケーションレプリカ、外部永続ワーカー、PostgreSQL/PGVector、Redis、バージョニング済み MinIO バケット、ゲートウェイを起動します。

docker compose --env-file /absolute/path/to/libre-team.env \
-f docker-compose.team.yml up --build --scale libre-webui=3 -d
docker compose --env-file /absolute/path/to/libre-team.env \
-f docker-compose.team.yml ps

基本の team プロファイルは意図的に Docker ソケットをマウントしないため、Docker を使う Work は利用できません。有効にする場合は、すべてのライフサイクルコマンドに同梱の本番オーバーレイを含めてください。

docker compose --env-file /absolute/path/to/libre-team.env \
-f docker-compose.team.yml -f docker-compose.team.work.yml \
up --build --scale libre-webui=3 -d
docker compose --env-file /absolute/path/to/libre-team.env \
-f docker-compose.team.yml -f docker-compose.team.work.yml ps

このオーバーレイは、アプリケーションとワーカーの両プロセスを、内部専用ネットワーク上の 1 つのフィルター済み Docker ソケットプロキシへ接続します。どちらのプロセスにも、生のソケットやソケットグループのメンバー資格は与えられず、ホストフォルダを使う Work ワークスペースは無効のままです。プロキシが公開するのは info、images、containers、exec、volumes、networks と、それらのライフサイクル呼び出しに必要な書き込みメソッドだけです。API の範囲は狭まりますが、Docker がテナント境界になるわけではありません。コンテナ作成では依然としてホストパスを bind mount できるためです。ホストの隔離が重要な場合は、専用 VM、rootless Work デーモン、または独立した Work デーモンを使ってください。

Compose が所有する PostgreSQL、Redis、MinIO サービスを直接公開しないでください。管理対象の依存関係には Helm の team プロファイルを使い、検証済み TLS を維持してください。Compose ファイルが PostgreSQL の TLS を無効にするのは、非公開のプロジェクトネットワーク内だけです。外部ワーカーが存在するまで readiness は失敗したままです。

永続化とマイグレーションの境界

ID と認可は、非同期リポジトリを使うようになりました。リポジトリのトランザクションコールバックは、同じデータベース接続に結び付いた unit of work を受け取ります。そのコールバック内でグローバルリポジトリを使うと拒否されます。これは、現在の SQLite の動作を維持しつつ PostgreSQL 接続プールで使われるトランザクション境界です。

SQLite のマイグレーションコーディネーターは、必須スキーマを検証した後にだけ既存インストールを取り込みます。番号付きのマイグレーション名とチェックサムを記録して起動ごとに検証し、より新しい、不明、一致しない台帳を拒否します。マイグレーションまたはスキーマ検証に失敗すると、起動も失敗します。readiness と復旧インベントリは、同じ標準検査契約を利用します。

状態を持つアプリケーションサービスをインポートする前に、起動処理は既存の SQLite データベースと有効な WAL/SHM ファイルを非公開の一時ディレクトリへコピーし、そのコピーを検証します。PLATFORM_PREFLIGHT_TMP_DIR には、データベースと WAL を合わせたサイズ以上の空き容量が必要です。同梱の Docker/Helm デプロイでは、そこへディスク上の専用一時ストレージをマウントします。起動処理は、上限のある /tmp tmpfs に依存しません。レガシー暗号化キーの欠落や、過去形式の入れ子になったデータディレクトリがある場合、代替キー、データベース、プラグイン状態が作られる前に起動をブロックします。

スキーマ v4 は、暗号化された ID メールにキー付き等価トークンを追加します。復旧処理では、すべてのトークンが存在し、認証済みメールと一致する必要があります。v4 のコミット直後に起こり得る限定的なクラッシュ時間帯については、認証済みメールのトークンが欠けている場合や、エンベロープでないレガシー値がある場合でも起動を許可します。これにより、リポジトリ初期化が暗号化/トークンのバックフィルを完了できます。古いリリースは任意のメール文字列を受け付け、空の値でフィールドを消去していました。取り込み時には空でない値を維持し、空値を NULL に正規化します。破損したエンベロープ形式の値と、null ではない不一致は、引き続き事前確認を失敗させます。

アプリケーションサービスは、非同期の方言別リポジトリを使います。ネイティブ SQLite は、SQLite アダプター、マイグレーション/復旧検査、明示的に注入されたヘルスチェックだけに制限されます。ランタイムストレージは、選択された Persistence から初期化されます。PostgreSQL を有効にした場合、SQLite シングルトンや、過去の作業ディレクトリ依存 JSON ファイルへフォールスルーすることはありません。

共通の永続ジョブランタイムも、ドライバーに依存しません。アクターの認可は選択された ID リポジトリから読み取り、ネイティブジョブリポジトリの構築は、1 つのアダプター構成境界に限定します。トランザクショナルなドメインパブリッシャーは、SQLite では不透明な同期 executor を、PostgreSQL ではトランザクションに結び付いた executor を受け取ります。better-sqlite3 ハンドルを受け取ることはありません。永続化境界のテストは、共通ジョブ、リソース、ID、チャット、Work の契約でネイティブドライバーハンドルを拒否します。

blob とベクトルストレージの基盤

生成されたギャラリーメディアと文書ソースファイルは BlobStore を使い、文書 RAG とペルソナメモリは VectorStore を使います。SQLite のレガシーギャラリー行は両方の形式から読み取られ、初回アクセス時に blob 参照へ取り込まれます。リレーショナルメタデータと永続参照が正式な状態です。プロバイダー URL や物理 S3 キーがアプリケーションコンテンツとして永続化されることはありません。チャット添付、アバター、残っているほかのインラインバイナリフィールドはまだ blob ストアの呼び出し側ではなく、移行済みと説明してはいけません。

復旧ゲートは、明示的な総量上限の下で、すべての永続オブジェクトと埋め込みベクトルエンベロープを順番に認証します。また、認識可能なレガシーテキストエンベロープと、すべての保存済み音声バイナリエンベロープを、アプリケーションの ENCRYPTION_KEY で厳格に認証します。ランタイムの「復号できなければ元の値を返す」互換フォールバックは決して使いません。ソースストレージの初期化、修復、書き換え、削除は行いません。破損した暗号文、不明または誤ったキー、非標準の blob レイアウト、検証上限の超過は、スナップショットをブロックします。

復旧処理の既定上限は、ローカルオブジェクト 250,000 件、暗号化済みおよび平文 blob 合計 64 GiB、ベクトル行 250,000 件、シリアライズ済みベクトル暗号文 4 GiB、ベクトル構成要素 5 億個です。テストと組み込み呼び出し側は、RecoveryInventoryOptions を通じて実行ごとの上限を上書きできます。CLI が超過状態を黙ってサンプリングまたはスキップすることはありません。

レガシー暗号文検証の既定上限は、値が入った候補フィールド 100 万件と、保存済み/認証済み平文それぞれ合計 16 GiB です。レガシーテキストエンベロープには永続マーカーがないため、古いスキーマ世代の平文行も引き続き互換性があります。レポートが数えるのは認証済みエンベロープだけです。保存済み音声エンベロープには曖昧さがなく、プロファイル/所有者/フィールド ID を追加データとして必ず認証します。

暗号化されたローカル blob

BlobStore は所有者単位で範囲が分かれ、ストリーミング put/read、メタデータ/stat、両端を含むバイト範囲、冪等な削除を公開します。LocalEncryptedBlobStore は、アプリケーション指定のルート配下に、不透明な UUID をキーとするオブジェクトを書き込みます。統合先は ${DATA_DIR}/blobs です。排他的なステージングファイル、fsync、同一ファイルシステム上のアトミックな rename を使用し、ディレクトリは 0700、ファイルは 0600 になります。

各オブジェクトには、ランダムな 256 ビットのデータキーがあります。AES-256-GCM は、非公開メタデータを暗号化し、上限付きの本文チャンクを個別に認証します。追加認証データは、blob ID、所有者、用途、チャンクインデックス、平文長を結び付けます。バージョン付きストレージキーリングは、各データキーをラップします。ディスクリプターには、平文サイズ、SHA-256、コンテンツタイプ、作成時刻、形式バージョン、暗号化キー ID が記録されます。全体読み取りでは SHA-256 を検証し、範囲読み取りでは触れたすべてのチャンクを認証します。

クォータ契約は、ストリーミング前に容量を予約し、実際のバイト数を消費し、アトミックに見える状態になった後にだけコミットし、失敗した予約を解放します。SQLite は BEGIN IMMEDIATE、PostgreSQL は serializable トランザクションと行ロックを使います。S3 オブジェクトメタデータとクォータ使用量は、1 つのデータベーストランザクションでまとめてコミットまたはロールバックされます。起動時に、期限切れの予約と、物理 blob が欠けているクォータオブジェクトを整合させます。BLOB_QUOTA_BYTES_PER_USER は所有者ごとの永続上限を設定し、BLOB_QUOTA_RESERVATION_TTL_MS は放棄された予約の期限を制限します。

BLOB_STORE_BACKEND=s3 は、非公開の S3 互換バケットを使います。Libre は不透明なオブジェクトキーと、アプリケーションで暗号化したチャンクストリームをアップロードし、暗号化されたディスクリプターを PostgreSQL に保持します。両端を含む HTTP 範囲取得に対応し、平文と暗号文の SHA-256 ダイジェストを検証して、冪等に削除します。削除中の行は、物理削除とメタデータ/クォータのアトミックな削除が成功するまで永続化されます。整合処理は、中断した削除を再試行し、古くなった物理孤立オブジェクトを削除します。Docker ゲート付き MinIO スイートは、レプリカをまたぐ読み取り/削除、テナント隔離、クォータ競合、未消費ストリーム、コミット/削除境界で注入したデータベース障害を検証します。

暗号化された埋め込みベクトル

VectorStore は、すべてのクエリと変更にアクターを要求します。レコードには、名前空間、不透明なテナント単位 ID、所有者、リソース ID、埋め込みモデル、次元数、バージョン、ソースリビジョン、等価属性、任意のユーザー/グループ許可が含まれます。

SQLite は、暗号化された埋め込みがデータベースを出る前に、名前空間/モデル/次元/バージョン、所有者または許可、リソース、属性の述語を適用します。その上限付きで認可済みの候補集合だけを復号し、コサイン類似度を計算します。同じ不透明なベクトル ID でも、別のテナントの存在を明らかにせず、所有者ごとに隔離されます。upsert は埋め込み、ACL、属性をアトミックに置き換えます。削除は所有者単位で範囲を限定し、関連行をカスケード削除します。

埋め込みには AES-256-GCM を使い、ID とモデルのメタデータを追加認証データとして結び付けます。クエリ可能な ID、許可、モデル、バージョン、リビジョン、フィルターメタデータは平文のままなので、呼び出し側はフィルター属性へシークレットを入れてはいけません。埋め込み自体は機密性のある派生データです。

VECTOR_STORE_BACKEND=pgvector は、名前空間、モデル、次元数、バージョン、リソース、属性、所有者、許可の述語を、距離順と LIMIT と同じ SQL 文の中で適用します。グローバル最近傍を取得した後にフィルタリングすることは禁止されています。グループ認可は、クエリごとに信頼済みの現在メンバーシップリゾルバーから解決され、呼び出し側が指定した groupIds は無視されます。そのため、取り消しは直ちに反映され、偽造したグループ主張で候補を取得することはできません。

文書取り込みと埋め込み再生成メンテナンスエンドポイントは、処理開始前に 1 つの不変な実行仕様を取り込みます。有効状態、モデル、ベクトルバージョン、チャンカーバージョン、チャンクサイズ、オーバーラップ、類似度しきい値です。同じ仕様が、チャンク生成、リレーショナル公開、ベクトル upsert、セマンティッククエリを制御します。実行中に設定を変更しても、異なるモデルのチャンクが混在したり、異なるしきい値でベクトルを照会したりすることはありません。公開済みの文書メタデータには、集約されたチャンクリビジョンとこの仕様が記録され、SQL が正式なインデックスマニフェストとして維持されます。

再生成は文書ごとに自動更新されるコーディネーターリースを保持し、リレーショナル公開の前、およびベクトル変更の前後に、所有者単位の行と永続削除トゥームストーンを再確認します。upsert の進行中に削除がコミットされる場合があります。その場合、upsert 後の権限確認が再作成されたベクトルを削除します。PostgreSQL/team のセマンティック読み取りが PGVector を変更することはありません。保存済みマニフェストが、現在のモデルとチャンク設定が完全に同じであることを証明できる場合に限り、SQLite はリレーショナル埋め込みを遅延再公開できます。この任意の変更では、同じ文書リースを保持しながら行とチャンクを再読み込みします。処理中または置き換え済みのリビジョンはスキップされ、キーワードフォールバックや明示的な再生成の対象として残ります。

文書インデックスは、一度に最大 1,000 ベクトルの補償可能なバッチで置き換えます。正確なインデックス検査では、1 回の変更バッチを文書全体と見なさず、完全なリソースマニフェストをページングします。1 文書が公開できるチャンクは最大 100,000 件なので、単一文書がポータブルアーカイブの文書チャンク総数上限を超えることはありません。取り込み処理は 100,001 番目のチャンクを埋め込みやリレーショナル/ベクトル公開の前に拒否し、その永続ジョブを再試行せずデッドレター化します。再アップロードする前に、埋め込みのチャンクサイズを増やすか、過剰な段落区切りを削除してください。

マニフェスト導入前の solo データベースには、作成時のモデルやチャンカーの記録がない、認証済みインライン文書ベクトルが含まれる場合があります。最初のセマンティック利用時には、その存在だけをアップグレードのシグナルとして扱います。文書リースを保持しながら、正式な文書テキストを再チャンク化し、現在取り込まれた仕様に従ってすべてのベクトルを再生成します。レガシーペイロードをコピーしたり、現在の設定というラベルを付けたりすることはありません。プロバイダー障害や使用中のリースがある場合、レガシー行は変更されず、キーワード検索可能なままです。

このようなレガシー文書が、認証済みの現在マニフェストメタデータと、正確に暗号化されたプラットフォームベクトルインデックスで完全にカバーされていない場合、SQLite から team への移行は安全側に閉じて失敗します。現在の設定では、過去のベクトルのモデルを証明できません。dry-run がこのブロッカーを報告した場合は、同じ DATA_DIRENCRYPTION_KEY を使って現在のリリースを solo/SQLite モードで起動し、目的の埋め込みモデルを有効にして選択し、影響を受ける所有者ごとに設定 -> 文書 -> 埋め込みを再生成を使ってから、移行の dry-run を再実行してください。その後にだけ、team リポジトリの読み取りは保存済みインライン暗号文を無視でき、証明済みのベクトルを PGVector へ移動できます。

機密性はバックエンドによって異なります。埋め込み SQLite は、メタデータ ACL の述語を適用した後、アプリケーションの AES-256-GCM で埋め込みを暗号化します。PGVector は数値の埋め込みを操作する必要があるため、その列をアプリケーションで暗号化しません。埋め込みを機密性のある派生データとして扱ってください。TLS、暗号化された PostgreSQL ボリュームとバックアップ、最小権限のアプリケーションロール、制限されたデータベース管理を必須とし、SQL ログにベクトルやソース内容を含めてはいけません。ソーステキスト、ペルソナメモリの内容、ギャラリーメタデータ、blob ディスクリプターは、引き続きエンベロープ暗号化されます。ベクトル属性はクエリ可能な平文であり、シークレットを含めてはいけません。

ストレージ暗号化キー

現在の呼び出し側移行期間中、バージョン付きキーリングを有効にするデプロイでは、安定した 64 文字の ENCRYPTION_KEY を設定し、STORAGE_ENCRYPTION_KEYS の正確な legacy エントリに同じキーを含め、STORAGE_ENCRYPTION_ACTIVE_KEY_ID をいずれか 1 つのエントリに設定する必要があります。書き込みにはアクティブキーを使い、読み取りでは段階的なローテーションに対応するため、設定済みの全キー ID を受け付けます。この一時的なレガシー要件により、既存の暗号化サービスが別のキーを独立して作成することを防ぎます。すべてのオブジェクトとベクトルが書き換えまたは再ラップされ、検証されるまで古いキーを保持してください。

このマップがない場合、アダプターは既存の 64 文字の ENCRYPTION_KEY をキー ID legacy として受け付けます。環境キーがない場合は、既存の ${DATA_DIR}/.encryption_key ファイルを読み取ります。ストレージファクトリーが受け付けるキーファイルは、非公開権限を持つ、シンボリックリンクではない通常ファイルだけです。そのファイルを作成、書き換え、置換することはありません。明示的な環境設定が永続キーと競合する場合、起動は安全側に閉じて失敗します。ローテーション中にレガシーの環境/ファイルキーが検出された場合、古いエンベロープが書き換え、検証されるまで、正確なキー ID legacy でバージョン付きマップに残す必要があります。キーの欠落、不正、食い違い、不明なキーは、安全側に閉じて失敗します。

埋め込みベクトルのクエリは、SQLite 内で ACL とメタデータの述語を適用した後、Node へ暗号文を返して復号する前に、候補数、暗号化バイト数、次元別件数のスコアリング作業を集計します。いずれかの予算を超えるクエリは安全側に閉じて失敗するため、リソースまたはメタデータの範囲を狭める必要があります。

調整

コーディネーター契約は、イベント、有効期限付きキャッシュエントリ、フェンス付きリース、固定ウィンドウのレート制限消費を提供します。ローカル実装は、1 レプリカの solo プロファイル専用です。Redis 実装は、コマンド/購読用の個別クライアント、上限付きペイロード、ヘルスチェック、キーの名前空間化、アトミックスクリプト、一意な所有者トークン、リース期限、フェンシングトークンを使います。Redis エラー後にローカル調整へフォールバックすることはありません。

Redis は正式な状態ではありません。認可、永続ジョブ、再生可能なイベントはデータベースに保持する必要があります。Redis はウェイクアップ、キャッシュ無効化、プレゼンス、クォータ、調整のための層です。重要な処理は、副作用をコミットする前にデータベースリースまたはフェンシングトークンも検証する必要があります。

アプリケーションのチケット発行、キャッシュ、共有無効化、接続制限、Work イベント、分散ランタイムロックは、この境界を使います。Redis を選択するだけでは、ローカル永続化を共有可能にはできません。team モードには共有プロファイル全体が必要です。

永続ジョブとイベント

SQLite マイグレーション v3 は、永続ジョブ、試行、イベントストリーム先頭、順序付きイベントの各テーブルを提供します。サービス契約は、冪等な enqueue、上限付き再試行、キャンセル、進行状況、リースの heartbeat/reclaim、デッドレター状態、グローバルカーソルによる再生に対応します。暗号化 JSON ペイロードは、ジョブ/イベント ID を認証データとしてプラットフォームキーリングを使います。ペイロード参照は、不透明で上限のある識別子です。

SQLite マイグレーション v13 と PostgreSQL マイグレーション v12 は、生成単位のチャット再生で使う対応する (stream_id, subject_id, global_cursor) インデックスを追加します。stream と subject のフィルターはキャッチアップ上限より前に適用されます。そのため、長いセッションの以前の生成が、現在の生成の再生予算を消費したり、イベントストリーム全体の走査を強制したりすることはありません。

アプリケーションと独立ワーカーの bootstrap は、文書取り込み、メディア継続、再試行可能なリソースクリーンアップの監査済みハンドラーを登録します。管理境界は、上限付きの検査とキャンセルを公開します。enqueue は冪等であり、リレーショナルな作成/削除経路は、その永続ジョブを同じ SQLite/PostgreSQL トランザクションに挿入します。リソースクリーンアップは、ベクトル、非公開 blob、永続参照、キャッシュエントリ、リソースを対象とするキュー済み処理を、再試行に安全な操作で削除します。

復旧インベントリは、すべてのジョブ状態と試行結果を数え、イベントストリームと最後のカーソルを記録し、安全でない実行中処理をブロックし、総量上限の下で暗号化ペイロードを認証します。また、ストリーム先頭の不一致と、ストリーム単位で連続していないシーケンスも拒否します。

単調増加するリーストークンは、古いワーカーが後からデータベースにコミットするのをフェンスします。フェンシングによって exactly-once 実行が実現するわけではありません。ワーカーが外部の副作用を完了し、成功を記録する前に失敗する可能性があります。そのため、ハンドラーの採用には、プロバイダーの冪等性キーまたはトランザクショナルな outbox/inbox プロトコルと、副作用の直前に行うアクター認可の再検証が必要です。

SQLite マイグレーション v4 は、ランダム化された ID 暗号文の横に、一意なキー付きメール検索トークンを追加します。トークンはアプリケーション暗号化キーによる HMAC です。平文を保存したり決定論的暗号化を使ったりせず、メール重複のアトミックな強制を復元します。起動処理はトラフィックを受け付ける前に、すべてのレガシー ID メールを認証し、バックフィルします。

正常性と復旧

デプロイプローブは、プロセスの liveness と依存関係の readiness を区別するようになりました。

  • /health/health/live はプロセスだけを検査します。
  • /health/ready は、詳細を秘匿しつつ、データベース、標準スキーマ台帳、書き込み可能なデータストレージ、登録済みの必須依存関係を検査します。任意のプロバイダーを待つことはありません。
  • /health/deep は現在の管理者を必要とし、HTTP イベントループ外の上限付きワーカーで SQLite の整合性と外部キー検査を実行します。Ollama など任意のサーバーレベルプロバイダープローブも警告として集約しますが、コアの readiness は変更しません。

libre-webui recovery-check --json を実行します。ソースのチェックアウトでは、バックエンドを一度ビルドして npm run recovery:check -- --json を使います。インベントリは読み取り専用で、スキーマ/キー ID、ローカル blob ルート、レガシー/プラットフォームベクトル数を報告します。ローカルプラットフォームの blob/ベクトル暗号文、レガシーアプリケーション/保存済み音声暗号文、暗号化された永続ジョブ/イベントペイロードを認証し、データサイズ、プラグイン定義とバックアップルート内にあるかどうか、埋め込みメディア、Work リソースと正確な所有ラベル、ジョブ/試行/イベントのチェックポイント、実行中の Work 実行/プレビュー/ジョブ、ブロッカー、既知の除外項目を報告します。これはバックアップ前のゲートであり、完全なバックアップではありません。復旧準備を参照してください。

認定済みマルチレプリカ運用

team プロファイルは、共有依存関係をすべて一緒に設定することを条件に、3 つ以上のアプリケーションレプリカと 1 つ以上の外部永続ワーカーで認定されています。必要な依存関係は PostgreSQL、PGVector、Redis、S3 互換 blob、安定した共有シークレット、JOB_WORKER_MODE=external です。Helm チャートはレンダリング時にこれらの前提条件を強制します。完全な team プロファイルなしでレプリカ数を 2 以上にすると、安全でないトポロジーをデプロイせずレンダリングを失敗させます。スキーママイグレーションは PostgreSQL の advisory lock を使って単一のリーダーを選ぶため、バージョンが混在するレプリカが台帳を奪い合うことはありません。

認定は願望ではなく、実行可能なものです。リリースパイプラインは 3 レプリカ訓練(npm run test:team-platform)を実行し、実際のイメージをビルドして、レプリカをまたぐストリーム再開、決定論的再生を伴う書き込み途中のワーカー停止、Redis 障害時に正式な SQL へフォールバックすること、コーディネーター喪失中の取り消し強制、共有レート制限の一貫性、S3 削除再試行、負荷下のテナント隔離を検証します。運用者は、secrets.existingSecret(チャート値を Secret にレンダリングせず、運用者管理の Secret を参照)と networkPolicy.enabled(アプリケーションポート以外の ingress を既定で拒否。永続ワーカーは ingress を受け付けません)で Pod をさらに強化できます。どちらの場合も Pod セキュリティの既定値は厳格です。非 root、読み取り専用ルートファイルシステム、capability の削除、seccomp RuntimeDefault、特権昇格なしです。

残っている既知の切り替え

この基盤があっても、すべてのバイナリフィールドがすでに blob になったわけではありません。保存済み音声の音声データ、チャット添付、アバター、将来プラグインが定義するバイナリリソースは、移行前に明示的な参照メタデータ、両形式からの読み取り/バックフィル、保持、削除のテストが必要です。同様に、将来の埋め込み呼び出し側は、モデル、次元数、バージョン、ソースリビジョン、所有者、リソース範囲、信頼済み許可を VectorStore を通じて伝える必要があります。ベクトルテーブルへ直接アクセスする近道は認められません。

新しい長時間処理や外部から見える副作用は、永続リソース対象を登録し、キャンセルと再試行に対応し、所有するリレーショナル変更とともにトランザクショナルな enqueue/outbox 境界を使う必要があります。team デプロイで有効にする前に、新しい各リソースを、レプリカ間のアップロード/読み取り/検索/削除、およびバックアップ/復元の受け入れゲートへ追加してください。