Fundação da plataforma
O Libre WebUI oferece suporte a um perfil solo local-first e a um perfil compartilhado team.
O perfil solo usa SQLite, blobs locais criptografados, vetores incorporados criptografados, coordenação
local e um worker durável incorporado. O perfil equipe usa PostgreSQL,
blobs privados compatíveis com S3, PGVector, coordenação pelo Redis e um worker durável
externo. A inicialização rejeita perfis mistos em vez de dividir silenciosamente
o estado entre backends locais e compartilhados.
Marco atual
| Área | Fundação implementada | Trabalho restante dos chamadores |
|---|---|---|
| Persistência | Repositórios SQLite e PostgreSQL, migrações imutáveis, transações em pool | Novos domínios devem usar as barreiras dos repositórios |
| Blobs | Armazenamentos locais e compatíveis com S3, criptografados e em streaming, intervalos, checksums, cotas duráveis | Migrar anexos de conversas, avatares e os demais campos binários inline |
| Vetores | Vetores incorporados criptografados, ACLs do PGVector e reconstruções do índice de documentos seguras contra exclusão | Novos chamadores de embeddings devem preservar o mesmo contrato de autoridade e ciclo de vida |
| Coordenação | Eventos, cache, concessões, limites de taxa, invalidação e integridade locais e no Redis | Manter o Redis sem autoridade sobre o estado |
| Tarefas/eventos | Filas SQLite/PostgreSQL, eventos transacionais, workers, novas tentativas, cancelamento, administração | Todo novo efeito colateral precisa de um projeto de idempotência ou outbox |
| Operações | Barreiras de integridade, arquivos de backup assinados/criptografados, restauração em destino limpo, verificação | Exercitar restauração e aceitação entre réplicas em cada ambiente de implantação |
Perfis de ambiente de execução
LIBRE_PLATFORM_MODE=solo é o padrão. Ele seleciona SQLite, blobs locais,
vetores incorporados, coordenação local e o worker durável incorporado. O Redis
pode ser selecionado no modo solo, mas isso não torna o SQLite nem os arquivos locais
seguros para compartilhamento entre réplicas.
LIBRE_PLATFORM_MODE=team exige todas as dependências compartilhadas ao mesmo tempo:
DATABASE_BACKEND=postgrescomDATABASE_URL;BLOB_STORE_BACKEND=s3;VECTOR_STORE_BACKEND=pgvector;COORDINATION_BACKEND=rediscomREDIS_URL; eJOB_WORKER_MODE=external.
Esses seletores formam um conjunto coerente. A inicialização do perfil equipe falha quando qualquer dependência compartilhada está ausente ou quando um backend local é misturado ao perfil.
Migre uma instalação solo existente
Interrompa todos os aplicativos e workers do Libre antes de migrar. Os exemplos usam o
comando libre-webui instalado pelo npm global ou Homebrew. Sem instalação
global, substitua-o por npx --yes libre-webui@latest. Em um checkout do código-fonte,
compile uma vez e substitua libre-webui migrate-postgres por
npm run migrate:postgres --. Configure o ambiente de destino PostgreSQL, S3 e de chaves de
criptografia versionadas exatamente como na implantação equipe de destino e, então, execute primeiro a
análise somente leitura:
libre-webui migrate-postgres \
--source /absolute/path/to/data.sqlite \
--plugins /absolute/path/to/plugins \
--mode dry-run
Aplique somente ao destino vazio identificado por esse relatório. Uma execução com falha deixa um diário de importação com checksum; retome a mesma origem e o mesmo destino em vez de iniciar uma importação diferente:
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
O marcador de conclusão só é gravado depois que linhas relacionais, definições de plugins,
blobs locais criptografados, vetores incorporados e vetores legados de personas tiverem sido
transferidos e autenticados no PostgreSQL/S3/PGVector. O comando
nunca inventa uma chave de criptografia de origem: ENCRYPTION_KEY deve corresponder à
.encryption_key de origem, e STORAGE_ENCRYPTION_KEYS deve conter a chave ativa
configurada e a entrada legacy correspondente.
Execute o perfil equipe incluído
Comece pelo template fornecido que falha de forma fechada. Mantenha o arquivo de ambiente preenchido fora do repositório e restrinja-o ao operador:
cp deploy/team/.env.example /absolute/path/to/libre-team.env
chmod 600 /absolute/path/to/libre-team.env
Substitua todos os valores REPLACE_* antes da inicialização. Gere a senha do PostgreSQL
com um alfabeto seguro para URLs (por exemplo, openssl rand -hex 32), pois
o mesmo literal é usado como senha do servidor e como parte de DATABASE_URL.
ENCRYPTION_KEY e cada valor em STORAGE_ENCRYPTION_KEYS devem ter
exatamente 64 caracteres hexadecimais. Em uma instalação nova, a entrada legacy
deve ser igual a ENCRYPTION_KEY; em uma migração do SQLite, ambas devem ser iguais à chave de
origem. Use uma chave ativa diferente para novas gravações de blobs e mantenha as antigas até
que o inventário de objetos comprove que elas não são mais usadas.
O mesmo arquivo pode definir POSTGRES_MIGRATION_MODE, POSTGRES_POOL_MAX, os
timeouts compatíveis do PostgreSQL, REDIS_CONNECT_TIMEOUT_MS, OLLAMA_BASE_URL,
OLLAMA_TIMEOUT, OLLAMA_LONG_OPERATION_TIMEOUT e OLLAMA_MAX_CONTEXT;
o ambiente compartilhado do Compose envia cada valor de forma idêntica ao aplicativo
e ao worker externo. Os timeouts do provedor aceitam de 1.000 a 3.600.000 milissegundos,
o contexto máximo aceita de 128 a 2.097.152 tokens e o timeout longo não pode ser
menor que o padrão; valores malformados fazem os dois pontos de entrada do servidor falharem
antes que qualquer estado seja criado. Binários locais da Agent CLI e arquivos de token OAuth do Codex
não são compatíveis com workers duráveis externos; por isso, o perfil equipe mantém os dois caminhos
de provedores desativados, e a inicialização rejeita tentativas de ativá-los. Depois, inicie as réplicas
do aplicativo, o worker durável externo, PostgreSQL/PGVector, Redis, o bucket versionado do MinIO
e o gateway:
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
O perfil equipe básico deliberadamente não monta nenhum socket Docker; portanto, o Work baseado em Docker não fica disponível. Ative-o somente incluindo a camada de produção fornecida em todos os comandos de ciclo de vida:
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
Essa camada direciona os processos do aplicativo e do worker a um único proxy filtrado do socket Docker em uma rede somente interna. Nenhum dos processos recebe o socket bruto nem a associação ao grupo do socket, e os espaços de trabalho do Work em pastas do host permanecem desativados. O proxy expõe somente info, images, containers, exec, volumes, networks e os métodos de gravação exigidos por essas chamadas de ciclo de vida. Isso reduz a superfície da API, mas não transforma o Docker em uma barreira entre locatários: a criação de contêineres ainda pode montar caminhos do host. Use uma VM dedicada ou um daemon Work rootless/separado quando o isolamento do host for importante.
Não exponha diretamente os serviços PostgreSQL, Redis ou MinIO controlados pelo Compose. Para dependências gerenciadas, use o perfil equipe do Helm e mantenha o TLS verificado; o arquivo Compose desativa o TLS do PostgreSQL somente em sua rede privada do projeto. A prontidão permanece em falha até que um worker externo esteja presente.
Barreira de persistência e migração
Agora, identidade e autorização usam repositórios assíncronos. O callback de transação do repositório recebe uma unidade de trabalho vinculada à mesma conexão de banco de dados; usar o repositório global dentro desse callback é rejeitado. Essa é a barreira de transação usada pelo pool de conexões do PostgreSQL, preservando o comportamento atual do SQLite.
O coordenador de migração do SQLite só adota instalações existentes depois de validar o esquema obrigatório. Ele registra um nome e checksum de migração numerados, verifica-os a cada inicialização, rejeita registros mais novos/desconhecidos/divergentes e faz a inicialização falhar quando a migração ou a validação do esquema falha. A prontidão e o inventário de recuperação usam o mesmo contrato canônico de inspeção.
Antes de importar serviços com estado do aplicativo, a inicialização copia o banco SQLite
existente e os arquivos WAL/SHM ativos para um diretório temporário privado e valida essa cópia.
PLATFORM_PREFLIGHT_TMP_DIR deve ter espaço livre suficiente para o banco
e seu WAL. As implantações fornecidas de Docker e Helm montam armazenamento temporário dedicado
em disco nesse local; a inicialização não depende do tmpfs limitado em /tmp. Uma chave de
criptografia legada ausente ou um diretório histórico de dados aninhado bloqueia a inicialização
antes que uma chave, um banco ou um estado de plugin substituto possa ser criado.
O esquema v4 adiciona um token de igualdade com chave para emails de identidade criptografados. A recuperação
exige que todos os tokens estejam presentes e correspondam ao email autenticado. A inicialização
permite um token ausente com email autenticado ou um valor legado que não seja envelope
durante a curta janela de falha após o commit da v4, para que a inicialização do repositório
possa concluir o preenchimento da criptografia/do token. Versões anteriores aceitavam
strings de email arbitrárias e usavam valores vazios para limpar o campo; a adoção preserva
valores não vazios e normaliza os vazios para NULL. Valores danificados com formato de envelope
e qualquer divergência não nula ainda fazem a verificação prévia falhar.
Os serviços do aplicativo usam repositórios assíncronos por dialeto. O SQLite nativo fica
restrito aos adaptadores SQLite, à inspeção de migração/recuperação e a verificações de integridade
explicitamente injetadas. O armazenamento do ambiente de execução é inicializado a partir da Persistence
selecionada; ativar o PostgreSQL nunca recorre ao singleton do SQLite nem a arquivos JSON
históricos dependentes do diretório de trabalho atual.
O ambiente comum de tarefas duráveis também permanece independente de driver. A autorização do ator
é lida pelo repositório de identidades selecionado, enquanto a construção do repositório nativo
de tarefas fica confinada a uma única barreira de composição de adaptadores. Publicadores transacionais
de domínio recebem um executor síncrono opaco no SQLite e um executor vinculado à transação
no PostgreSQL; eles nunca recebem um handle de better-sqlite3. O teste da barreira de
persistência rejeita handles de drivers nativos nos contratos comuns de tarefas, recursos, identidade,
chat e Work.
Fundação do armazenamento de blobs e vetores
Mídia gerada da galeria e arquivos-fonte de documentos usam BlobStore; o RAG de documentos
e a memória de personas usam VectorStore. Linhas legadas da galeria no SQLite são lidas em paralelo
e adotadas como referências de blobs no primeiro acesso. Os metadados relacionais
e uma referência durável são autoritativos; URLs de provedores e chaves S3 físicas
nunca são persistidas como conteúdo do aplicativo. Anexos de conversas, avatares e outros
campos binários inline restantes ainda não chamam o blob store e não devem ser descritos como migrados.
A barreira de recuperação autentica sequencialmente todos os objetos duráveis e envelopes de vetores
incorporados sob limites agregados explícitos. Ela também autentica rigorosamente envelopes legados de
texto reconhecíveis e todos os envelopes binários de vozes salvas usando o ENCRYPTION_KEY do aplicativo;
ela nunca usa a alternativa de compatibilidade do ambiente de execução que descriptografa e retorna o original.
Ela não inicializa, repara, regrava nem exclui o armazenamento de origem; ciphertext corrompido,
chaves desconhecidas ou incorretas, layouts não canônicos de blobs e limites de verificação excedidos
bloqueiam o snapshot.
Os limites padrão da recuperação são 250.000 objetos locais, 64 GiB de bytes de blobs
criptografados e em texto simples, 250.000 linhas de vetores, 4 GiB de ciphertext serializado de vetores
e 500 milhões de componentes de vetores. Testes e chamadores incorporados podem
substituir os limites por execução por meio de RecoveryInventoryOptions; a CLI nunca
seleciona amostras nem ignora silenciosamente o estado excedente.
A verificação de ciphertext legado usa por padrão um milhão de campos candidatos preenchidos e 16 GiB para cada total agregado de bytes armazenados e autenticados em texto simples. Linhas em texto simples de gerações antigas do esquema continuam compatíveis porque os envelopes legados de texto não têm marcador durável; o relatório conta apenas envelopes autenticados. Os envelopes de vozes salvas são inequívocos e sempre se autenticam com a identidade do perfil/proprietário/campo como dados adicionais.
Blobs locais criptografados
BlobStore é limitado ao proprietário e oferece gravação/leitura em streaming, metadados/stat,
intervalos inclusivos de bytes e exclusão idempotente. LocalEncryptedBlobStore
grava objetos opacos identificados por UUID abaixo de uma raiz fornecida pelo aplicativo; o
destino de integração é ${DATA_DIR}/blobs. Ele usa arquivos temporários exclusivos,
fsync e uma renomeação atômica no mesmo sistema de arquivos, com diretórios 0700 e arquivos 0600.
Cada objeto tem uma chave de dados aleatória de 256 bits. O AES-256-GCM criptografa metadados privados e autentica de forma independente trechos limitados do corpo. Dados autenticados adicionais vinculam o ID do blob, o proprietário, a finalidade, o índice do trecho e o tamanho em texto simples. O keyring versionado de armazenamento envolve cada chave de dados. O descritor registra o tamanho em texto simples, SHA-256, tipo de conteúdo, data de criação, versão do formato e ID da chave de criptografia. Leituras completas verificam o SHA-256; leituras por intervalo autenticam todos os trechos acessados.
O contrato de cotas reserva capacidade antes do streaming, consome os bytes reais,
confirma apenas depois da visibilidade atômica e libera reservas com falha. O SQLite
usa BEGIN IMMEDIATE; o PostgreSQL usa transações serializáveis e bloqueios de linhas.
Os metadados do objeto S3 e o uso da cota são confirmados ou revertidos em uma única transação de banco de dados.
A inicialização reconcilia reservas expiradas e objetos da cota cujo blob físico está ausente.
BLOB_QUOTA_BYTES_PER_USER define o limite durável por proprietário, e
BLOB_QUOTA_RESERVATION_TTL_MS limita reservas abandonadas.
BLOB_STORE_BACKEND=s3 usa um bucket privado compatível com S3. O Libre envia
chaves de objetos opacas e streams de trechos criptografados pelo aplicativo, mantém descritores
criptografados no PostgreSQL, oferece suporte a intervalos HTTP inclusivos, verifica digests SHA-256
do texto simples e do ciphertext e realiza exclusão idempotente. Uma linha em exclusão permanece
durável até que a exclusão física e a remoção atômica de metadados/cota tenham sucesso;
a reconciliação tenta novamente exclusões interrompidas e remove órfãos físicos antigos.
A suíte do MinIO condicionada ao Docker cobre leitura/exclusão entre réplicas, isolamento de locatários,
disputa por cota, streams não consumidos e falhas injetadas no banco nos limites
de commit e exclusão.
Vetores incorporados criptografados
VectorStore exige um ator em toda consulta e mutação. Os registros contêm um
namespace, ID opaco limitado ao locatário, proprietário, ID de recurso, modelo de embedding,
dimensões, versão, revisão de origem, atributos de igualdade e concessões opcionais
a usuários/grupos.
O SQLite aplica predicados de namespace/modelo/dimensão/versão, proprietário ou concessão, recurso e atributo antes que embeddings criptografados saiam do banco. Somente esse conjunto limitado e autorizado de candidatos é descriptografado e classificado por similaridade de cosseno. O mesmo ID opaco de vetor é isolado por proprietário sem revelar a existência de outro locatário. Upserts substituem embeddings, ACLs e atributos atomicamente; as exclusões são limitadas ao proprietário e removem as linhas relacionadas em cascata.
Os embeddings usam AES-256-GCM com metadados de identidade e modelo vinculados como dados autenticados adicionais. Metadados consultáveis de identidade, concessão, modelo, versão, revisão e filtro permanecem em texto simples; portanto, os chamadores não devem colocar segredos em atributos de filtro. Os próprios embeddings são dados derivados confidenciais.
VECTOR_STORE_BACKEND=pgvector aplica predicados de namespace, modelo, dimensões, versão,
recurso, atributo, proprietário e concessão na mesma instrução SQL que a ordenação por distância
e LIMIT. É proibido pós-filtrar os vizinhos globais mais próximos.
A autorização de grupos é resolvida por um resolvedor confiável de associações atuais em toda consulta;
groupIds fornecidos pelo chamador são ignorados. Assim, a revogação é imediata, e claims
de grupo falsificadas não conseguem recuperar candidatos.
A ingestão de documentos e o endpoint de manutenção para regeneração de embeddings capturam uma especificação de execução imutável antes do início do trabalho: estado ativado, modelo, versão dos vetores, versão do divisor em trechos, tamanho dos trechos, sobreposição e limite de similaridade. Essa mesma especificação controla a geração de trechos, a publicação relacional, o upsert de vetores e a consulta semântica; uma alteração de preferência durante a execução não pode produzir trechos de modelos mistos nem consultar um vetor com um limite diferente. Os metadados publicados do documento registram a revisão agregada dos trechos e essa especificação, de modo que o SQL continua sendo o manifesto autoritativo do índice.
A regeneração mantém uma concessão do coordenador com renovação automática para cada documento e verifica novamente a linha limitada ao proprietário e seu tombstone de exclusão permanente antes da publicação relacional e antes e depois da mutação dos vetores. Uma exclusão pode ser confirmada enquanto um upsert está em andamento; a verificação de autoridade posterior ao upsert remove então os vetores recriados. Leituras semânticas no PostgreSQL/perfil equipe nunca alteram o PGVector. O SQLite pode republicar de forma adiada embeddings relacionais somente quando o manifesto armazenado comprova o modelo e a configuração de trechos atuais exatos; essa mutação opcional recarrega a linha e os trechos enquanto mantém a mesma concessão do documento. Uma revisão ocupada ou substituída é ignorada e continua elegível para a busca por palavras-chave ou para uma regeneração explícita.
Os índices de documentos são substituídos em lotes compensados de no máximo 1.000 vetores, e as verificações do índice exato percorrem por páginas todo o manifesto do recurso em vez de presumir que um lote de mutação seja o documento inteiro. Um documento pode publicar no máximo 100.000 trechos; assim, nenhum documento ultrapassa o limite total de trechos de documentos do arquivo portátil. A ingestão rejeita o 100.001º trecho antes da criação do embedding ou da publicação relacional/vetorial e coloca essa tarefa durável em dead letter sem nova tentativa; aumente o tamanho dos trechos de embedding ou remova quebras de parágrafo excessivas antes de enviar novamente.
Bancos solo anteriores ao manifesto podem conter vetores inline de documentos autenticados sem nenhum registro do modelo ou divisor que os criou. O primeiro uso semântico trata somente sua presença como sinal de atualização: ele divide novamente o texto autoritativo do documento e gera todos os vetores outra vez sob a especificação atual capturada, mantendo a concessão do documento. Ele nunca copia o payload legado nem o rotula com a preferência atual. Uma falha do provedor ou uma concessão ocupada deixa a linha legada inalterada e pesquisável por palavras-chave.
A migração de SQLite para equipe falha de forma fechada quando esse documento legado não está completamente
coberto por metadados autenticados do manifesto atual e por um índice criptografado exato de vetores da
plataforma. As preferências atuais não comprovam o modelo de um vetor histórico. Quando a simulação
informa esse bloqueio, inicie a versão atual no modo solo/SQLite com os mesmos
DATA_DIR e ENCRYPTION_KEY, ative e selecione o modelo de embedding desejado,
use Configurações -> Documentos -> Regenerar embeddings para cada proprietário afetado e
execute novamente a simulação da migração. Somente então as leituras do repositório no perfil equipe podem ignorar
o ciphertext inline preservado enquanto os vetores comprovados são movidos ao PGVector.
A confidencialidade varia por backend. O SQLite incorporado criptografa embeddings com AES-256-GCM do aplicativo após aplicar predicados de ACL nos metadados. O PGVector precisa operar sobre o embedding numérico e, por isso, não criptografa essa coluna no nível do aplicativo. Trate embeddings como dados derivados confidenciais: exija TLS, volumes e backups criptografados do PostgreSQL, um papel do aplicativo com privilégios mínimos, administração restrita do banco e logs SQL que nunca incluam vetores nem conteúdo de origem. Texto de origem, conteúdo da memória de personas, metadados da galeria e descritores de blobs continuam criptografados por envelope. Os atributos dos vetores são texto simples consultável e nunca devem conter segredos.
Chaves de criptografia do armazenamento
Durante o período atual de migração dos chamadores, implantações que ativam um keyring versionado
devem definir um ENCRYPTION_KEY estável de 64 caracteres, incluir essa mesma chave
na entrada exata legacy de STORAGE_ENCRYPTION_KEYS e definir
STORAGE_ENCRYPTION_ACTIVE_KEY_ID como uma das entradas. As gravações usam a chave ativa;
as leituras aceitam todos os IDs de chave configurados para permitir rotação gradual. Essa exigência
legada temporária impede que o serviço de criptografia existente crie de forma independente
uma chave diferente. Mantenha as chaves antigas até que todos os objetos e vetores tenham sido
regravados ou reenvolvidos e verificados.
Quando esse mapa está ausente, o adaptador aceita o ENCRYPTION_KEY existente de 64 caracteres
como ID de chave legacy ou lê o arquivo existente
${DATA_DIR}/.encryption_key quando a chave do ambiente está ausente. A fábrica de armazenamento
aceita somente um arquivo de chave comum, sem link simbólico e com permissões privadas; ela nunca
cria, regrava nem substitui esse arquivo. Se uma configuração explícita do ambiente entrar em conflito
com a chave persistente, a inicialização falha de forma fechada. Durante a rotação, uma chave legada
detectada no ambiente/arquivo deve permanecer no mapa versionado sob o ID exato legacy
até que os envelopes antigos sejam regravados e verificados. Chaves ausentes, malformadas,
divergentes ou desconhecidas falham de forma fechada.
As consultas de vetores incorporados aplicam predicados de ACL e metadados no SQLite e, depois, agregam a quantidade de candidatos, os bytes criptografados e o trabalho de classificação por dimensão antes de retornar qualquer ciphertext ao Node para descriptografia. Consultas que ultrapassam qualquer orçamento falham de forma fechada e precisam ser limitadas pelo escopo do recurso ou dos metadados.
Coordenação
O contrato do coordenador fornece eventos, entradas de cache com expiração, concessões cercadas e consumo de limites de taxa em janela fixa. A implementação local serve somente ao perfil solo de uma réplica. A implementação do Redis usa clientes separados para comandos e inscrições, payloads limitados, verificações de integridade, namespace de chaves, scripts atômicos, tokens exclusivos de proprietário, expiração de concessões e tokens de cercamento. Ela nunca recorre à coordenação local depois de um erro do Redis.
O Redis não é a fonte da verdade. Autorização, tarefas duráveis e eventos reproduzíveis devem permanecer no banco de dados; o Redis é uma camada de wake-up, invalidação de cache, presença, cotas e coordenação. Trabalho crítico também precisa validar sua concessão do banco ou token de cercamento antes de confirmar um efeito colateral.
Tickets do aplicativo, caches, invalidação compartilhada, limites de conexões, eventos do Work e bloqueios distribuídos do ambiente de execução usam essa barreira. Selecionar apenas o Redis ainda não torna a persistência local compartilhável; o modo equipe exige todo o perfil compartilhado.
Tarefas e eventos duráveis
A migração v3 do SQLite fornece tabelas duráveis de tarefas, tentativas, cabeçalhos de streams de eventos e eventos ordenados. O contrato de serviço oferece enfileiramento idempotente, novas tentativas limitadas, cancelamento, progresso, heartbeat/retomada de concessões, estado de dead letter e reprodução pelo cursor global. Payloads JSON criptografados usam o keyring da plataforma com a identidade da tarefa/evento como dados autenticados; referências de payload são identificadores opacos e limitados.
A migração v13 do SQLite e a migração v12 do PostgreSQL adicionam o índice correspondente
(stream_id, subject_id, global_cursor), usado na reprodução de chat limitada à geração.
Os filtros de stream e assunto são aplicados antes do limite de atualização; assim, as gerações
anteriores de uma sessão longa não consomem o orçamento de reprodução da geração atual
nem forçam uma varredura completa do stream de eventos.
As inicializações do aplicativo e do worker independente registram manipuladores auditados para ingestão de documentos, continuação de mídia e limpeza de recursos com novas tentativas. A barreira administrativa oferece inspeção e cancelamento limitados. O enfileiramento é idempotente, e os caminhos relacionais de criação/exclusão inserem sua tarefa durável na mesma transação SQLite/PostgreSQL. A limpeza de recursos remove vetores, blobs privados, referências duráveis, entradas de cache e trabalho enfileirado direcionado ao recurso por meio de operações seguras para novas tentativas.
O inventário de recuperação conta todos os estados de tarefas e resultados das tentativas, registra streams de eventos e seu último cursor, bloqueia trabalho em execução inseguro e autentica payloads criptografados sob limites agregados. A recuperação também rejeita divergências no cabeçalho do stream e sequências não contíguas por stream.
Tokens monotônicos de concessão impedem workers obsoletos de fazer commits posteriores no banco. O cercamento não oferece execução exatamente uma vez: um worker pode concluir um efeito colateral externo e falhar antes de registrar sucesso. Portanto, adotar um manipulador exige chaves de idempotência do provedor ou um protocolo transacional de outbox/inbox, além da revalidação da autorização do ator imediatamente antes de cada efeito colateral.
A migração v4 do SQLite adiciona um token exclusivo de busca de email com chave ao lado do ciphertext aleatório de identidade. O token é um HMAC sob a chave de criptografia do aplicativo: ele restaura a aplicação atômica de emails duplicados sem armazenar texto simples nem usar criptografia determinística. A inicialização autentica e preenche novamente todos os emails de identidade legados antes de aceitar tráfego.
Integridade e recuperação
Agora, as sondas da implantação distinguem a vivacidade do processo da prontidão das dependências:
/healthe/health/liveverificam somente o processo;/health/readyverifica o banco de dados, o registro canônico do esquema, o armazenamento de dados gravável e as dependências obrigatórias registradas, ocultando detalhes. Ela não aguarda provedores opcionais; e/health/deepexige um administrador atual e executa verificações de integridade e chaves estrangeiras do SQLite em um worker limitado fora do loop de eventos HTTP. Ela também agrega sondas opcionais de provedores no nível do servidor, como o Ollama, como avisos, sem alterar a prontidão central.
Execute libre-webui recovery-check --json; em um checkout do código-fonte, compile o
backend uma vez e use npm run recovery:check -- --json. O inventário é
somente leitura e informa identidades de esquema/chaves, a raiz de blobs locais,
contagens de vetores legados e da plataforma, autentica ciphertext de blobs/vetores locais da plataforma,
ciphertext legado do aplicativo e de vozes salvas e payloads criptografados de tarefas/eventos
duráveis, além de informar tamanhos dos dados,
definições de plugins e se estão dentro da raiz do backup, mídia incorporada,
recursos do Work e rótulos exatos de propriedade, pontos de controle de tarefas/tentativas/eventos,
execuções/visualizações e tarefas ativas do Work, bloqueios e exclusões conhecidas. Ele é uma
barreira anterior ao backup, e não um backup completo. Consulte
Prontidão de recuperação.
Operação certificada com várias réplicas
O perfil equipe é certificado para três ou mais réplicas do aplicativo e pelo menos
um worker durável externo, desde que todas as dependências compartilhadas sejam
configuradas juntas: PostgreSQL, PGVector, Redis, blobs compatíveis com S3, segredos
compartilhados estáveis e JOB_WORKER_MODE=external. O chart Helm aplica esses
pré-requisitos na renderização — uma quantidade de réplicas acima de um sem o perfil equipe
completo faz a renderização falhar em vez de implantar uma topologia insegura — e
as migrações de esquema elegem um único líder por um bloqueio consultivo do PostgreSQL, para que
réplicas com versões diferentes nunca disputem o registro.
A certificação é executável, não uma aspiração: o pipeline de lançamento executa uma
simulação com três réplicas (npm run test:team-platform) que compila a imagem real
e exercita a retomada de streams entre réplicas, a morte de um worker durante uma gravação com
reprodução determinística, a alternativa à interrupção do Redis usando o SQL autoritativo, a aplicação de revogação
durante a perda do coordenador, a consistência compartilhada dos limites de taxa, novas tentativas de exclusão no S3
e o isolamento de locatários sob carga. Os operadores podem reforçar ainda mais os pods
com secrets.existingSecret (referenciar um Secret gerenciado pelo operador em vez de
renderizar os valores do chart em um) e networkPolicy.enabled (negação por padrão de
tráfego de entrada além da porta do aplicativo; o worker durável não aceita tráfego de entrada).
Os padrões de segurança dos pods continuam rigorosos em ambos os casos: sem root, sistema de arquivos raiz
somente leitura, capabilities removidas, seccomp RuntimeDefault e nenhuma elevação de
privilégios.
Migrações pendentes conhecidas
A fundação não implica que todos os campos binários já sejam blobs. Áudio de vozes
salvas, anexos de conversas, avatares e futuros recursos binários definidos por plugins
precisam de metadados explícitos de referência, leitura dupla/preenchimento, retenção e testes de
exclusão antes de serem migrados. Da mesma forma, todo futuro chamador de embeddings
deve transportar modelo, dimensões, versão, revisão de origem, proprietário, escopo do recurso
e concessões confiáveis por VectorStore; acessar diretamente a tabela de vetores não é
um atalho aceito.
Novos efeitos colaterais de longa duração ou externamente visíveis devem registrar um destino de recurso durável, oferecer suporte a cancelamento e novas tentativas e usar uma barreira transacional de enfileiramento/outbox junto com a mutação relacional proprietária. Adicione cada novo recurso às barreiras de aceitação de upload/leitura/busca/exclusão entre réplicas e de backup/restauração antes de ativá-lo em implantações equipe.