appcore-storage
Estável 1.0.0 · MSRV Rust 1.89 · crates.io · docs.rs · código-fonte
Guia e exemplos mantidos pelo crate
O repositório do Runtime mantém o guia detalhado, exemplo básico e exemplo intermediário. O wiki resume a fronteira pública; detalhes de API e execução ficam junto ao código do crate.
Responsabilidade: contratos genéricos de storage e provider local em arquivo.
Dependências internas: appcore-contracts, appcore-dnt,
appcore-security, appcore-types.
API principal: StorageProvider, Repository, Migration, Transaction,
health/status/errors, IDs validados, FileStorageProvider, manifests de
storage, backup V1, helpers autenticados de storage remoto e stores opcionais
selados por DNT para objetos, snapshots e segredos.
O adapter selado em arquivo escreve DNT normal por padrão e expõe
DntFileObjectStore::write_object_compact para snapshots, backups e arquivos
de domínio exportáveis quando o payload for compressível. Escritas compactadas
continuam sendo envelopes DNT comuns sobre o mesmo provider de arquivo; o
contrato do backend de storage não muda.
Leituras seladas derivam o limite do envelope completo de
SealedStoragePolicy e rejeitam arquivos grandes demais antes de alocar o
buffer do arquivo.
Snapshots completos mantêm seu inventário limitado de arquivos, mas o manifest V1 de 16 MiB não precisa mais de um buffer codificado completo ao lado dele. O pretty JSON é serializado diretamente por um writer limitado de 16 KiB para um temporário atômico exclusivo e desserializado por um reader limitado de 16 KiB. Input exatamente no limite continua válido e um byte não retido detecta crescimento concorrente.
Use quando aplicação ou serviço precisa do perfil local-first documentado. Mantenha schemas e tabelas de domínio fora. Transações não suportadas falham.
Housekeeping e traversal de backup são iterativos, limitados e nunca seguem symlinks ou reparse points do Windows. A listagem usa timestamps persistidos no manifest do snapshot e só recorre aos metadados de criação/modificação para backups simples em arquivo. A abertura final usa no-follow da plataforma e é revalidada sob o lock do processo. O perfil de um processo ainda pressupõe uma raiz protegida pelo proprietário: a troca maliciosa de um diretório ancestral por outro processo da mesma conta durante a operação permanece fora desta boundary portátil.
O traversal visita no máximo 200.000 entradas incrementalmente, retendo apenas a pilha limitada de 16.384 diretórios e os resultados exigidos pelo consumidor. O snapshot mantém seus paths ordenados necessários sem uma segunda lista global de entradas; health retém somente um contador, cleanup apenas os temporários correspondentes e a validação de symlink nenhuma entrada. O teto de profundidade continua 128. A verificação do snapshot também conta arquivos reais incrementalmente e empresta o path anterior ao conferir a ordem; ela não cria um segundo inventário de paths nem clona um path por entrada.
Preflight de capacidades pós-1.0
StorageCapabilityDescriptorV1 define sete garantias exatas: transactions,
locking, snapshot, streaming, backup online, multi-process e multi-host. O
catálogo é limitado a 32 providers. Deployments usam explicitamente
required_capabilities; storage.shared=true exige multi_host. Requisitos
desconhecidos, duplicados ou não suportados falham antes de abrir storage e
nunca selecionam provider mais fraco. O provider de arquivo anuncia somente
snapshot. O formato publicado dos manifests V1 não muda.
A certificação clean-source em 12cbfc3 mediu p99 de 83 ns e 10.493.879
preflights/s sob limites fixos de sete capacidades e 32 providers.
Maturidade: contratos estáveis; provider em arquivo certificado para um processo local e filesystem com locks/sync/rename adequados.
Bootstrap do candidato e arquivos atômicos individuais
Adições disponíveis em 1.0.5-rc: após bloquear e drenar writes, deployment
pode chamar authorize_candidate_bootstrap("candidate") uma vez. Reservar antes
de seal_after_install_start, depois consumir a autoridade com run. O callback
recebe CandidateBootstrapPermit restrito, sem API de clone/nesting/escape.
open normal continua rejeitado; sucesso, erro ou panic mantêm a barreira
selada. Descartar autoridade não usada a revoga. Deployment escolhe candidato e
permissões de filesystem; admissão é local ao processo, não token entre
processos, sandbox ou mecanismo de autorização do filesystem.
AtomicFileWriter::new(absolute_path, max_bytes)?.write(bytes) substitui um
arquivo fora da raiz gerida. Exige diretórios pais reais existentes; rejeita
symlinks/reparse e traversal. Budget entre 1 byte e 64 MiB; verifica tamanho
antes do staging e sincroniza temporário exclusivo antes de rename. Unix usa
0600 e sync do diretório pai; demais plataformas mantêm os limites de
durabilidade do provider. Deployment protege os pais. Em concorrência vence o
último rename bem-sucedido; não é transação. Falha de sync após rename pode
reportar erro com os novos bytes já visíveis.
Formato de backup da aplicação exige ponte de importação externa: limitar e autenticar/decriptar o arquivo com codec original, rejeitar versões desconhecidas ou paths inseguros, validar inventário e preparar arquivos opacos verificados num snapshot novo. Validar antes da troca de raízes, preservar raiz anterior para rollback e testar interrupções. Não renomear arquivo legado como snapshot do Runtime nem adicionar parsers legados ao AppCore.
Release publicada
1.0.5-rc — publicado no crates.io; versões anteriores permanecem imutáveis.
Pacote publicado
appcore-storage 1.0.5-rc · docs.rs · source.
Prerelease independente — 2026-10-14
1.0.5-rc.1: alinhamento de dependências.