Przejdź do głównej zawartości

Podstawa platformy

Libre WebUI obsługuje lokalny profil solo i współdzielony profil team. Solo używa SQLite, zaszyfrowanych lokalnych blobów, zaszyfrowanych wektorów osadzonych, lokalnej koordynacji i wbudowanego trwałego workera. Team używa PostgreSQL, prywatnych blobów zgodnych z S3, PGVector, koordynacji Redis i zewnętrznego trwałego workera. Uruchamianie odrzuca profile mieszane zamiast po cichu rozdzielać stan między backendy lokalne i współdzielone.

Bieżący etap​

ObszarZaimplementowana podstawaPozostała praca wywołujących
TrwałośćRepozytoria SQLite i PostgreSQL, niezmienne migracje, transakcje z puliNowe domeny muszą używać granic repozytoriów
BlobySzyfrowane lokalne i zgodne z S3 magazyny strumieniowe, zakresy, sumy i trwałe kwotyPrzenieść załączniki czatów, awatary i pozostałe pola binarne inline
WektorySzyfrowane wektory osadzone, ACL PGVector i bezpieczne przy usuwaniu odbudowy indeksówNowi wywołujący embeddingi muszą zachować ten sam kontrakt autorytetu i cyklu życia
KoordynacjaLokalne i Redis zdarzenia, pamięć, dzierżawy, limity, unieważnienia i stanRedis musi pozostać nieautorytatywny
Zadania/zdarzeniaKolejki SQLite/PostgreSQL, zdarzenia transakcyjne, workery, ponowienia, anulowanie, administracjaKażdy nowy efekt uboczny wymaga idempotencji lub projektu outbox
OperacjeBramki stanu, podpisane/zaszyfrowane archiwa, odtwarzanie do czystego celu, weryfikacjaĆwiczyć odtwarzanie i akceptację między replikami w każdym środowisku

Profile środowiska wykonawczego​

LIBRE_PLATFORM_MODE=solo jest wartością domyślną. Wybiera SQLite, lokalne bloby, osadzone wektory, lokalną koordynację i wbudowanego workera. Redis można wybrać w solo, ale nie czyni to SQLite ani lokalnych plików bezpiecznymi do współdzielenia między replikami.

LIBRE_PLATFORM_MODE=team wymaga jednocześnie wszystkich zależności współdzielonych:

  • DATABASE_BACKEND=postgres z DATABASE_URL;
  • BLOB_STORE_BACKEND=s3;
  • VECTOR_STORE_BACKEND=pgvector;
  • COORDINATION_BACKEND=redis z REDIS_URL; oraz
  • JOB_WORKER_MODE=external.

Selektory tworzą spójny zestaw. Start team kończy się błędem, gdy brakuje zależności współdzielonej albo profil zawiera backend lokalny.

Migracja istniejącej instalacji solo​

Przed migracją zatrzymaj wszystkie aplikacje Libre i workery. Przykłady używają zainstalowanego libre-webui z globalnego npm lub Homebrew; bez instalacji zastąp go npx --yes libre-webui@latest. W kopii źródeł zbuduj raz i zastąp libre-webui migrate-postgres przez npm run migrate:postgres --. Skonfiguruj docelowe PostgreSQL, S3 i wersjonowane klucze dokładnie jak docelowe wdrożenie team, a następnie zacznij od analizy tylko do odczytu:

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

Zastosuj wyłącznie do pustego celu wskazanego przez raport. Nieudane wykonanie pozostawia dziennik importu z sumami; wznów tę samą parę źródło–cel zamiast rozpoczynać inny import:

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

Znacznik ukończenia pojawia się dopiero po przeniesieniu i uwierzytelnieniu w PostgreSQL/S3/PGVector wierszy relacyjnych, definicji wtyczek, lokalnych zaszyfrowanych blobów, osadzonych wektorów i starych wektorów person. Polecenie nigdy nie wymyśla klucza źródłowego: ENCRYPTION_KEY musi odpowiadać źródłowemu .encryption_key, a STORAGE_ENCRYPTION_KEYS musi zawierać aktywny klucz i pasujący wpis legacy.

Uruchamianie dołączonego profilu team​

MinIO nie publikuje już obrazów kontenerów. Profil team i CI pobierają kompilacje serwera i klienta MinIO od Chainguard z cgr.dev/chainguard, przypięte skrótem (digest). Hosty ograniczające dostęp do rejestrów muszą zezwolić na cgr.dev. Serwer działa jako root, tak jak wcześniejszy oficjalny obraz, więc woluminy utworzone przed zmianą pozostają zapisywalne.

Zacznij od dostarczonego szablonu, który bezpiecznie odmawia startu. Gotowy plik środowiska trzymaj poza repozytorium i ogranicz do operatora:

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

Przed startem zastąp każdą wartość REPLACE_*. Hasło PostgreSQL wygeneruj alfabetem bezpiecznym dla URL (np. openssl rand -hex 32), bo ten sam literal jest hasłem serwera i częścią DATABASE_URL. ENCRYPTION_KEY oraz każda wartość w STORAGE_ENCRYPTION_KEYS muszą mieć dokładnie 64 znaki szesnastkowe. W nowej instalacji wpis legacy musi być równy ENCRYPTION_KEY; przy migracji SQLite oba muszą odpowiadać źródłu. Dla nowych zapisów blobów użyj innego aktywnego klucza i zachowaj stare do czasu, aż inwentaryzacja wykaże brak użycia.

Ten sam plik może ustawić POSTGRES_MIGRATION_MODE, POSTGRES_POOL_MAX, obsługiwane limity PostgreSQL, REDIS_CONNECT_TIMEOUT_MS, OLLAMA_BASE_URL, OLLAMA_TIMEOUT, OLLAMA_LONG_OPERATION_TIMEOUT i OLLAMA_MAX_CONTEXT; wspólne środowisko Compose przekazuje identyczne wartości aplikacji i workerowi. Limity dostawcy przyjmują 1 000–3 600 000 ms, kontekst 128–2 097 152 tokenów, a długi limit nie może być krótszy od zwykłego; błędne wartości zatrzymują oba punkty startowe przed utworzeniem stanu. Lokalne binaria Agent CLI i pliki tokenów Codex OAuth nie są obsługiwane przez zewnętrzne workery, dlatego team wymusza wyłączenie obu ścieżek i odrzuca próby ich włączenia. Następnie uruchom repliki, workera, PostgreSQL/PGVector, Redis, wersjonowany zasobnik MinIO i bramę:

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

Podstawowy profil team celowo nie montuje gniazda Docker, więc Work oparty na Dockerze jest niedostępny. Włącz go tylko przez dołączenie dostarczonej nakładki produkcyjnej do każdego polecenia cyklu życia:

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

Nakładka kieruje aplikację i workera do jednego filtrowanego proxy gniazda Docker w sieci wewnętrznej. Żaden proces nie otrzymuje surowego gniazda ani członkostwa grupy, a obszary Work w katalogach hosta pozostają wyłączone. Proxy udostępnia tylko info, images, containers, exec, volumes, networks i metody zapisu niezbędne cyklowi życia. Ogranicza to API, ale nie tworzy granicy dzierżawców: kontener nadal może bind-mountować ścieżki hosta. Gdy izolacja hosta ma znaczenie, użyj dedykowanej maszyny wirtualnej lub oddzielnego/rootless demona Work.

Nie wystawiaj usług PostgreSQL, Redis ani MinIO zarządzanych przez Compose. Dla zależności zarządzanych użyj profilu Helm team z weryfikowanym TLS; Compose wyłącza TLS PostgreSQL wyłącznie w prywatnej sieci projektu. Readiness pozostaje nieudane bez zewnętrznego workera.

Wbudowany silnik Strands przechowuje sesje swojej strony jako pliki w <DATA_DIR>/strands/, a nie w bazie danych aplikacji. Jego sterownik Work nie tworzy lokalnego trwałego magazynu: istniejące rekordy SQL Work dotyczące zadań, uruchomień, wiadomości i zatwierdzeń oraz trwałe zadania pozostają źródłem prawdy, również podczas odzyskiwania na zewnętrznym procesie roboczym. Wybór silnika jest zapisywany z wybranym modelem jako strands:<model> (przebiegi zapisane ze starszym prefiksem dsh:<model> otwierają się jako przebiegi Strands); zachowuje to istniejącą tożsamość dostawcy i autoryzację środowiska wykonawczego.

Granica trwałości i migracji​

Tożsamość i autoryzacja używają asynchronicznych repozytoriów. Callback transakcji otrzymuje jednostkę pracy związaną z tym samym połączeniem; użycie globalnego repozytorium wewnątrz jest odrzucane. To granica transakcji puli PostgreSQL zachowująca obecne zachowanie SQLite.

Koordynator migracji SQLite przyjmuje istniejącą instalację dopiero po sprawdzeniu wymaganego schematu. Zapisuje numerowaną nazwę i sumę migracji, sprawdza je przy każdym starcie, odrzuca nowsze, nieznane lub niezgodne rejestry i zatrzymuje start po błędzie migracji lub schematu. Readiness i inwentaryzacja używają tego samego kanonicznego kontraktu inspekcji.

Przed importem usług stanowych start kopiuje istniejącą bazę SQLite i aktywne WAL/SHM do prywatnego katalogu roboczego i sprawdza kopię. PLATFORM_PREFLIGHT_TMP_DIR musi mieć miejsce na bazę i WAL. Dostarczone wdrożenia Docker i Helm montują tam dedykowany dysk tymczasowy; start nie polega na ograniczonym tmpfs /tmp. Brak starego klucza szyfrowania lub historyczny zagnieżdżony katalog danych blokuje start przed utworzeniem klucza zastępczego, bazy lub stanu wtyczek.

Udany start zapisuje znacznik weryfikacji powiązany z plikiem bazy i schematem. Kolejne starty używają go ponownie, dopóki plik lub schemat się nie zmienią. Identyfikatory plików są zapisywane jako dokładne ciągi dziesiętne, łącznie z dużymi identyfikatorami Windows/NTFS. Starszy znacznik liczbowy wymusza jedną pełną weryfikację przed jego zastąpieniem.

Schemat v4 dodaje kluczowany token równości dla zaszyfrowanych e-maili tożsamości. Odzyskiwanie wymaga obecności i zgodności każdego tokenu. W wąskim oknie awarii po commicie v4 start dopuszcza brak tokenu przy uwierzytelnionym e-mailu lub starej wartości bez obwiedni, aby inicjalizacja dokończyła uzupełnienie. Starsze wydania przyjmowały dowolne ciągi i czyściły pole pustą wartością; przejęcie zachowuje niepuste i normalizuje puste do NULL. Uszkodzone wartości podobne do obwiedni i każda niepusta rozbieżność nadal zatrzymują kontrolę.

Usługi aplikacji używają asynchronicznych repozytoriów dialektu. Natywne SQLite jest ograniczone do adapterów SQLite, inspekcji migracji/odzyskiwania i jawnie wstrzykniętych kontroli. Magazyn jest inicjalizowany z wybranej Persistence; aktywacja PostgreSQL nigdy nie wraca do singletonu SQLite ani historycznych JSON zależnych od bieżącego katalogu.

Wspólne środowisko trwałych zadań pozostaje neutralne wobec sterownika. Autoryzacja aktora jest czytana z wybranego repozytorium tożsamości, a tworzenie natywnego repozytorium zadań ogranicza się do jednej granicy składania adapterów. Publikatory transakcyjne otrzymują nieprzezroczysty synchroniczny executor w SQLite i executor związany z transakcją w PostgreSQL; nigdy uchwyt better-sqlite3. Test granicy odrzuca natywne uchwyty w kontraktach zadań, zasobów, tożsamości, czatu i Work.

Podstawa magazynów blobów i wektorów​

Media galerii i źródła dokumentów używają BlobStore; RAG dokumentów i pamięć person używają VectorStore. Stare wiersze galerii SQLite są podwójnie odczytywane i przy pierwszym dostępie przyjmowane jako referencje blobów. Metadane relacyjne i trwała referencja są autorytatywne; URL dostawcy ani fizyczne klucze S3 nie są zapisywane jako treść. Załączniki czatów, awatary i inne pozostałe pola binarne inline nie używają jeszcze blob store i nie wolno opisywać ich jako zmigrowanych.

Bramka odzyskiwania uwierzytelnia kolejno każdy trwały obiekt i osadzoną obwiednię wektora pod jawnymi limitami. Ściśle uwierzytelnia również rozpoznawalne stare obwiednie tekstowe i każdą binarną obwiednię głosu przy użyciu ENCRYPTION_KEY; nie używa kompatybilnościowego fallbacku zwracającego oryginał. Nie inicjalizuje, naprawia, przepisuje ani usuwa źródła; uszkodzony szyfrogram, nieznany klucz, niekanoniczny układ i przekroczone limity blokują migawkę.

Domyślne granice to 250 000 lokalnych obiektów, 64 GiB zaszyfrowanych i jawnych bajtów blobów, 250 000 wierszy wektorów, 4 GiB serializowanego szyfrogramu i 500 milionów komponentów. Testy i wywołujący wbudowani mogą nadpisać limity przez RecoveryInventoryOptions; CLI nigdy nie próbkuje ani nie pomija nadmiaru.

Weryfikacja starego szyfrogramu domyślnie obejmuje milion wypełnionych pól kandydatów oraz po 16 GiB zapisanych i uwierzytelnionych bajtów jawnych. Jawne wiersze starych schematów pozostają zgodne, bo obwiednie tekstowe nie mają trwałego znacznika; raport liczy tylko uwierzytelnione. Obwiednie głosów są jednoznaczne i zawsze uwierzytelniają profil, właściciela i pole jako dane dodatkowe.

Zaszyfrowane bloby lokalne​

BlobStore jest przypisany właścicielowi i oferuje strumieniowe put/read, metadata/stat, inkluzywne zakresy bajtów i idempotentne usuwanie. LocalEncryptedBlobStore zapisuje nieprzezroczyste obiekty z UUID pod katalogiem aplikacji; cel to ${DATA_DIR}/blobs. Używa wyłącznych plików tymczasowych, fsync i atomowej zmiany nazwy w tym samym systemie, z katalogami 0700 i plikami 0600.

Każdy obiekt ma losowy 256-bitowy klucz danych. AES-256-GCM szyfruje prywatne metadane i niezależnie uwierzytelnia ograniczone fragmenty treści. Dane dodatkowe wiążą identyfikator blobu, właściciela, cel, indeks fragmentu i długość jawną. Wersjonowany keyring opakowuje klucze danych. Deskryptor zapisuje rozmiar jawny, SHA-256, typ, czas, wersję formatu i identyfikator klucza. Pełny odczyt sprawdza SHA-256; zakresowy uwierzytelnia każdy dotknięty fragment.

Kontrakt kwot rezerwuje pojemność przed strumieniem, zużywa rzeczywiste bajty, commit wykonuje dopiero po atomowej widoczności i zwalnia nieudane rezerwacje. SQLite używa BEGIN IMMEDIATE; PostgreSQL — transakcji serializowalnych i blokad wierszy. Metadane S3 i kwota commitują lub wycofują się w jednej transakcji. Start uzgadnia wygasłe rezerwacje i rekordy bez fizycznego blobu. BLOB_QUOTA_BYTES_PER_USER ustawia limit właściciela, a BLOB_QUOTA_RESERVATION_TTL_MS ogranicza porzucone rezerwacje.

BLOB_STORE_BACKEND=s3 używa prywatnego zasobnika zgodnego z S3. Libre przesyła nieprzezroczyste klucze i szyfrowane fragmenty, zachowuje zaszyfrowane deskryptory w PostgreSQL, obsługuje zakresy HTTP, sprawdza SHA-256 tekstu jawnego i szyfrogramu i usuwa idempotentnie. Wiersz usuwany pozostaje trwały do sukcesu fizycznego usunięcia i atomowego usunięcia metadanych/kwoty; uzgadnianie ponawia przerwania i usuwa stare sieroty. Zestaw MinIO pod Dockerem obejmuje odczyt/usuwanie między replikami, izolację dzierżawców, spory kwot, niezużyte strumienie i wstrzyknięte awarie bazy na granicach commit/usuwania.

Zaszyfrowane wektory osadzone​

VectorStore wymaga aktora przy każdym zapytaniu i mutacji. Rekordy zawierają namespace, nieprzezroczysty identyfikator dzierżawcy, właściciela, zasób, model embeddingowy, wymiary, wersję, rewizję źródła, atrybuty równości i opcjonalne przydziały użytkowników/grup.

SQLite stosuje predykaty namespace/model/wymiary/wersja, właściciel lub przydział, zasób i atrybuty zanim zaszyfrowane embeddingi opuszczą bazę. Odszyfrowywany i oceniany cosinusem jest tylko ograniczony, autoryzowany zestaw. Ten sam nieprzezroczysty identyfikator jest izolowany na właściciela bez ujawniania istnienia innego dzierżawcy. Upsert atomowo zastępuje embeddingi, ACL i atrybuty; usuwanie jest przypisane właścicielowi i kaskadowe.

Embeddingi używają AES-256-GCM z tożsamością i metadanymi modelu jako danymi dodatkowo uwierzytelnionymi. Zapytalne tożsamość, przydziały, model, wersja, rewizja i filtry pozostają jawne, więc nie wolno umieszczać w nich sekretów. Embeddingi są wrażliwymi danymi pochodnymi.

VECTOR_STORE_BACKEND=pgvector stosuje predykaty namespace, modelu, wymiarów, wersji, zasobu, atrybutów, właściciela i przydziałów w tym samym SQL co kolejność odległości i LIMIT. Filtrowanie globalnych najbliższych sąsiadów po fakcie jest zabronione. Grupy są rozwiązywane przy każdym zapytaniu z zaufanego aktualnego członkostwa; groupIds wywołującego są ignorowane. Cofnięcie działa natychmiast, a fałszywe oświadczenia nie pobierają kandydatów.

Przetwarzanie dokumentu i regeneracja embeddingów zapisują przed pracą jedną niezmienną specyfikację: włączenie, model, wersję wektora i chunkera, rozmiar, nakładanie i próg podobieństwa. Ta sama specyfikacja kontroluje fragmenty, publikację relacyjną, upsert i zapytanie; zmiana preferencji w trakcie nie miesza modeli ani progów. Metadane dokumentu zapisują zbiorczą rewizję i specyfikację, więc SQL jest autorytatywnym manifestem indeksu.

Regeneracja utrzymuje automatycznie odnawianą dzierżawę na dokument i ponownie sprawdza wiersz właściciela oraz trwały nagrobek przed publikacją, przed mutacją i po niej. Usunięcie może commitować podczas upsertu; kontrola po nim usuwa odtworzone wektory. Odczyty semantyczne PostgreSQL/team nigdy nie mutują PGVector. SQLite może leniwie ponownie publikować tylko wtedy, gdy manifest dowodzi dokładnego bieżącego modelu i chunkera, trzymając tę samą dzierżawę. Zajęta lub zastąpiona rewizja jest pomijana i pozostaje dostępna dla słów kluczowych lub jawnej regeneracji.

Indeksy są zastępowane w kompensowanych partiach do 1 000 wektorów, a dokładne kontrole stronicują pełny manifest, zamiast uznawać jedną partię za cały dokument. Dokument może opublikować najwyżej 100 000 fragmentów. Próba 100 001 jest odrzucana przed embeddingiem i publikacją, a zadanie trafia do dead-letter bez ponowienia; zwiększ rozmiar fragmentu lub usuń nadmiar podziałów przed ponownym przesłaniem.

Solowe bazy sprzed manifestu mogą mieć uwierzytelnione wektory inline bez informacji o modelu i chunkerze. Pierwsze użycie semantyczne traktuje samą obecność jako sygnał aktualizacji: ponownie dzieli autorytatywny tekst i generuje każdy wektor według bieżącej specyfikacji pod dzierżawą. Nigdy nie kopiuje starego ładunku ani nie etykietuje go dzisiejszą preferencją. Błąd dostawcy lub zajęta dzierżawa zostawia stary wiersz i wyszukiwanie słów.

Migracja SQLite do team bezpiecznie odmawia, jeśli stary dokument nie ma pełnych uwierzytelnionych metadanych manifestu i dokładnego zaszyfrowanego indeksu platformy. Bieżące preferencje nie dowodzą historycznego modelu. Gdy próba zgłosi blokadę, uruchom bieżące wydanie w solo/SQLite z tym samym DATA_DIR i ENCRYPTION_KEY, włącz właściwy model, użyj Settings -> Documents -> Regenerate embeddings dla każdego właściciela i ponów próbę. Dopiero wtedy team może ignorować zachowany szyfrogram inline, a dowiedzione wektory przejść do PGVector.

Poufność różni się według backendu. SQLite szyfruje embeddingi AES-256-GCM po predykatach ACL. PGVector musi działać na liczbach i nie szyfruje tej kolumny w aplikacji. Traktuj embeddingi jako wrażliwe dane: wymagaj TLS, szyfrowanych woluminów i kopii PostgreSQL, roli minimalnych uprawnień, ograniczonej administracji i logów SQL bez treści. Tekst źródłowy, pamięć person, metadane galerii i deskryptory pozostają szyfrowane obwiednią. Atrybuty wektorów są jawne i nie mogą zawierać sekretów.

Klucze szyfrowania magazynu​

W obecnym okresie migracji wdrożenie z wersjonowanym keyringiem musi ustawić stabilny 64-znakowy ENCRYPTION_KEY, umieścić go pod dokładnym wpisem legacy w STORAGE_ENCRYPTION_KEYS i ustawić STORAGE_ENCRYPTION_ACTIVE_KEY_ID. Zapisy używają aktywnego klucza; odczyty przyjmują wszystkie identyfikatory dla rotacji. Tymczasowy wymóg zapobiega utworzeniu niezależnego klucza przez starą usługę. Zachowaj stare klucze do przepisania lub ponownego opakowania i weryfikacji wszystkich obiektów i wektorów.

Bez mapy adapter przyjmuje istniejący 64-znakowy ENCRYPTION_KEY jako legacy albo odczytuje ${DATA_DIR}/.encryption_key, gdy brak środowiskowego. Fabryka akceptuje tylko zwykły, niebędący dowiązaniem plik z prywatnymi uprawnieniami; nigdy go nie tworzy ani nie zmienia. Konflikt jawnego środowiska z trwałym kluczem zatrzymuje start. Podczas rotacji wykryty stary klucz musi pozostać jako legacy do przepisania i kontroli obwiedni. Brakujące, błędne, rozbieżne i nieznane klucze bezpiecznie odmawiają.

Zapytania wektorów osadzonych stosują ACL i metadane w SQLite, a następnie sumują liczbę kandydatów, zaszyfrowane bajty i pracę według wymiarów przed zwróceniem szyfrogramu do Node. Przekroczenie budżetu zamyka zapytanie i wymaga zawężenia zasobu lub metadanych.

Koordynacja​

Kontrakt koordynatora zapewnia zdarzenia, wygasającą pamięć, ogrodzone dzierżawy i limity stałego okna. Implementacja lokalna jest tylko dla jednej repliki solo. Redis używa osobnych klientów poleceń i subskrypcji, ograniczonych ładunków, kontroli stanu, namespace kluczy, atomowych skryptów, unikalnych tokenów właściciela, wygaśnięcia i tokenów ogrodzenia. Po błędzie Redis nigdy nie wraca do koordynacji lokalnej.

Redis nie jest źródłem prawdy. Autoryzacja, trwałe zadania i odtwarzalne zdarzenia pozostają w bazie; Redis służy do budzenia, unieważnienia pamięci, obecności, kwot i koordynacji. Krytyczna praca musi też sprawdzić dzierżawę bazy lub token ogrodzenia przed efektem ubocznym.

Bilety aplikacji, pamięci, wspólne unieważnienia, limity połączeń, zdarzenia Work i rozproszone blokady używają tej granicy. Sam Redis nie czyni lokalnej trwałości współdzieloną; team wymaga pełnego profilu.

Trwałe zadania i zdarzenia​

Migracja SQLite v3 dodaje tabele trwałych zadań, prób, głów strumieni i uporządkowanych zdarzeń. Kontrakt obsługuje idempotentne kolejkowanie, ograniczone ponowienia, anulowanie, postęp, heartbeat/odzyskanie dzierżawy, dead-letter i odtwarzanie globalnym kursorem. Zaszyfrowane ładunki JSON używają keyringu platformy z tożsamością zadania/zdarzenia jako AAD; referencje są nieprzezroczystymi ograniczonymi identyfikatorami.

Migracja SQLite v13 i PostgreSQL v12 dodają indeks (stream_id, subject_id, global_cursor) dla odtwarzania czatu według generowania. Filtry strumienia i podmiotu są stosowane przed limitem, więc wcześniejsze generowania nie zużywają budżetu ani nie wymuszają pełnego skanu.

Start aplikacji i samodzielnego workera rejestruje audytowane procedury przetwarzania dokumentów, kontynuacji mediów i ponawialnego czyszczenia zasobów. Granica administratora zapewnia ograniczoną inspekcję i anulowanie. Kolejkowanie jest idempotentne, a ścieżki tworzenia/usuwania wstawiają zadanie w tej samej transakcji SQLite/PostgreSQL. Czyszczenie usuwa wektory, prywatne bloby, trwałe referencje, pamięć i zadania skierowane do zasobu przez operacje bezpieczne do ponowienia.

Inwentaryzacja liczy stany i wyniki prób, zapisuje strumienie i kursory, blokuje niebezpieczną aktywną pracę i uwierzytelnia ładunki pod limitami. Odrzuca też niezgodne głowy i nieciągłe sekwencje strumieni.

Monotoniczne tokeny dzierżawy odgradzają stare workery od późniejszych commitów. Nie zapewniają wykonania dokładnie raz: worker może wykonać zewnętrzny efekt i zawieść przed zapisem sukcesu. Przyjęcie procedury wymaga więc kluczy idempotencji dostawcy lub transakcyjnego outbox/inbox oraz ponownej autoryzacji aktora tuż przed efektem.

Migracja SQLite v4 dodaje unikalny kluczowany token wyszukiwania e-maila obok losowego szyfrogramu. Token jest HMAC pod kluczem aplikacji i przywraca atomowe wykrywanie duplikatu bez tekstu jawnego lub szyfrowania deterministycznego. Start uwierzytelnia i uzupełnia każdy stary e-mail przed przyjęciem ruchu.

Stan i odzyskiwanie​

Sondy wdrożenia rozróżniają żywotność procesu od gotowości zależności:

  • /health i /health/live dotyczą tylko procesu;
  • /health/ready sprawdza bazę, kanoniczny rejestr schematu, zapisywalny magazyn i wymagane zależności z redakcją szczegółów. Nie czeka na opcjonalnych dostawców; oraz
  • /health/deep wymaga bieżącego administratora i uruchamia kontrole integralności SQLite i kluczy obcych w ograniczonym workerze poza pętlą HTTP. Agreguje opcjonalne sondy dostawców, takich jak Ollama, jako ostrzeżenia bez zmiany gotowości podstawowej.

Uruchom libre-webui recovery-check --json; ze źródeł zbuduj backend i użyj npm run recovery:check -- --json. Inwentaryzacja tylko do odczytu raportuje tożsamości schematu/klucza, lokalny katalog blobów, liczby starych i platformowych wektorów, uwierzytelnia lokalne bloby/wektory, stare dane aplikacji i głosów oraz zaszyfrowane ładunki zadań/zdarzeń, a także rozmiary, wtyczki i ich położenie w kopii, osadzone media, zasoby Work i etykiety własności, punkty zadań/prób/zdarzeń, aktywne wykonania i blokady oraz wyłączenia. To bramka przed kopią, nie pełna kopia. Zobacz Gotowość do odzyskiwania.

Certyfikowana praca wielu replik​

Profil team jest certyfikowany dla co najmniej trzech replik aplikacji i jednego zewnętrznego workera, jeśli razem skonfigurowano PostgreSQL, PGVector, Redis, bloby S3, stabilne sekrety i JOB_WORKER_MODE=external. Chart Helm egzekwuje wymagania przy renderowaniu — więcej niż jedna replika bez pełnego team kończy render błędem — a migracje wybierają jednego lidera advisory lockiem PostgreSQL, aby różne wersje nie ścigały się o rejestr.

Certyfikacja jest wykonywalna: pipeline wydania uruchamia ćwiczenie trzech replik (npm run test:team-platform), które buduje rzeczywisty obraz i sprawdza wznowienie strumieni między replikami, śmierć workera podczas zapisu z deterministycznym odtwarzaniem, awarię Redis z autorytatywnym SQL, cofnięcie dostępu podczas utraty koordynatora, zgodność limitów, ponowienie usuwania S3 i izolację dzierżawców pod obciążeniem. Pody można wzmocnić przez secrets.existingSecret i networkPolicy.enabled. Domyślne bezpieczeństwo pozostaje ścisłe: non-root, system tylko do odczytu, usunięte capabilities, seccomp RuntimeDefault i brak eskalacji.

Znane pozostałe przełączenia​

Podstawa nie oznacza, że każde pole binarne jest już blobem. Audio zapisanych głosów, załączniki, awatary i przyszłe zasoby binarne wtyczek wymagają metadanych referencji, podwójnego odczytu/uzupełnienia, retencji i testów usuwania. Każdy przyszły wywołujący embeddingi musi przenosić model, wymiary, wersję, rewizję źródła, właściciela, zakres zasobu i zaufane przydziały przez VectorStore; bezpośredni dostęp do tabeli nie jest skrótem.

Nowe długotrwałe lub widoczne efekty muszą rejestrować trwały cel zasobu, obsługiwać anulowanie i ponowienie oraz używać transakcyjnej granicy enqueue/outbox z mutacją relacyjną. Dodaj każdy zasób do bramek akceptacyjnych przesyłania, odczytu, wyszukiwania, usuwania i kopii/odtwarzania między replikami przed włączeniem w team.