diff options
Diffstat (limited to 'pt-br/news/phase3-api-and-apps')
| -rw-r--r-- | pt-br/news/phase3-api-and-apps/index.html | 167 | ||||
| -rw-r--r-- | pt-br/news/phase3-api-and-apps/index.html.gz | bin | 0 -> 4248 bytes |
2 files changed, 167 insertions, 0 deletions
diff --git a/pt-br/news/phase3-api-and-apps/index.html b/pt-br/news/phase3-api-and-apps/index.html new file mode 100644 index 0000000..57ea05e --- /dev/null +++ b/pt-br/news/phase3-api-and-apps/index.html @@ -0,0 +1,167 @@ +<!DOCTYPE html> +<html lang="pt-br"> +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <title>Fase 3: Memórias nas Suas Mãos — Tesseras</title> + <meta name="description" content="Tesseras agora tem um app Flutter e um nó Rust embarcado — qualquer pessoa pode criar e preservar memórias pelo celular."> + <!-- Open Graph --> + <meta property="og:type" content="article"> + <meta property="og:title" content="Fase 3: Memórias nas Suas Mãos"> + <meta property="og:description" content="Tesseras agora tem um app Flutter e um nó Rust embarcado — qualquer pessoa pode criar e preservar memórias pelo celular."> + <meta property="og:image" content="https://tesseras.net/images/social.jpg"> + <meta property="og:image:width" content="1200"> + <meta property="og:image:height" content="630"> + <meta property="og:site_name" content="Tesseras"> + <!-- Twitter Card --> + <meta name="twitter:card" content="summary_large_image"> + <meta name="twitter:title" content="Fase 3: Memórias nas Suas Mãos"> + <meta name="twitter:description" content="Tesseras agora tem um app Flutter e um nó Rust embarcado — qualquer pessoa pode criar e preservar memórias pelo celular."> + <meta name="twitter:image" content="https://tesseras.net/images/social.jpg"> + <link rel="stylesheet" href="https://tesseras.net/style.css?h=21f0f32121928ee5c690"> + + + <link rel="alternate" type="application/atom+xml" title="Tesseras" href="https://tesseras.net/atom.xml"> + + + <link rel="icon" type="image/png" sizes="32x32" href="https://tesseras.net/images/favicon.png?h=be4e123a23393b1a027d"> + +</head> +<body> + <header> + <h1> + <a href="https://tesseras.net/pt-br/"> + <img src="https://tesseras.net/images/logo-64.png?h=c1b8d0c4c5f93b49d40b" alt="Tesseras" width="40" height="40" class="logo"> + Tesseras + </a> + </h1> + <nav> + + <a href="https://tesseras.net/pt-br/about/">Sobre</a> + <a href="https://tesseras.net/pt-br/news/">Notícias</a> + <a href="https://tesseras.net/pt-br/releases/">Lançamentos</a> + <a href="https://tesseras.net/pt-br/faq/">FAQ</a> + <a href="https://tesseras.net/pt-br/subscriptions/">Inscrições</a> + <a href="https://tesseras.net/pt-br/contact/">Contato</a> + + </nav> + <nav class="lang-switch"> + + <a href="https://tesseras.net/news/phase3-api-and-apps/">English</a> | <strong>Português</strong> + + </nav> + </header> + + <main> + +<article> + <h2>Fase 3: Memórias nas Suas Mãos</h2> + <p class="news-date">2026-02-14</p> + <p>As pessoas agora podem segurar suas memórias nas próprias mãos. A Fase 3 entrega +o que as fases anteriores construíram: um app mobile onde alguém baixa o +Tesseras, cria uma identidade, tira uma foto, e aquela memória entra na rede de +preservação. Sem contas na nuvem, sem assinaturas, sem nenhuma empresa entre +você e suas memórias.</p> +<h2 id="o-que-foi-construido">O que foi construído</h2> +<p><strong>tesseras-embedded</strong> — Um nó P2P completo que roda dentro de um app mobile. A +struct <code>EmbeddedNode</code> é dona de um runtime Tokio, banco SQLite, transporte QUIC, +engine Kademlia DHT, serviço de replicação e serviço de tessera — a mesma stack +do daemon desktop, compilada como biblioteca compartilhada. Um padrão singleton +global (<code>Mutex<Option<EmbeddedNode>></code>) garante um único nó por ciclo de vida do +app. Ao iniciar, ele abre o banco de dados, executa migrações, carrega ou gera +uma identidade Ed25519 com proof-of-work para o node ID, faz bind QUIC numa +porta efêmera, conecta DHT e replicação, e inicia o loop de reparo. Ao parar, +envia um sinal de shutdown e drena graciosamente.</p> +<p>Onze funções FFI são expostas para Dart via flutter_rust_bridge: ciclo de vida +(<code>node_start</code>, <code>node_stop</code>, <code>node_is_running</code>), identidade (<code>create_identity</code>, +<code>get_identity</code>), memórias (<code>create_memory</code>, <code>get_timeline</code>, <code>get_memory</code>) e +status da rede (<code>get_network_stats</code>, <code>get_replication_status</code>). Todos os tipos +que cruzam a fronteira FFI são structs planas com apenas <code>String</code>, +<code>Option<String></code>, <code>Vec<String></code> e primitivos — sem trait objects, sem generics, +sem lifetimes.</p> +<p>Quatro módulos adaptadores fazem a ponte entre as ports do core e as +implementações concretas: <code>Blake3HasherAdapter</code>, +<code>Ed25519SignerAdapter</code>/<code>Ed25519VerifierAdapter</code> para criptografia, +<code>DhtPortAdapter</code> para operações DHT, e <code>ReplicationHandlerAdapter</code> para RPCs de +fragmentos e atestação recebidos.</p> +<p>A feature flag <code>bundled-sqlite</code> compila o SQLite a partir do código-fonte, +necessário para Android e iOS onde a biblioteca do sistema pode não estar +disponível. A configuração do Cargokit passa essa flag automaticamente em builds +de debug e release.</p> +<p><strong>App Flutter</strong> — Uma aplicação Material Design 3 com gerenciamento de estado +Riverpod, direcionada para Android, iOS, Linux, macOS e Windows a partir de uma +única base de código.</p> +<p>O <em>fluxo de onboarding</em> são três telas: uma tela de boas-vindas explicando o +projeto em uma frase ("Preserve suas memórias através dos milênios. Sem nuvem. +Sem empresa."), uma tela de criação de identidade que dispara a geração do par +de chaves Ed25519 em Rust, e uma tela de confirmação mostrando o nome do usuário +e a identidade criptográfica.</p> +<p>A <em>tela de timeline</em> exibe memórias em ordem cronológica reversa com previews de +imagem, texto de contexto e chips para tipo de memória e visibilidade. +Pull-to-refresh recarrega a partir do nó Rust. Um floating action button abre a +<em>tela de criação de memória</em>, que suporta seleção de foto da galeria ou câmera +via <code>image_picker</code>, texto de contexto opcional, dropdowns de tipo de memória e +visibilidade, e tags separadas por vírgula. Criar uma memória chama o FFI Rust +sincronamente, depois retorna à timeline.</p> +<p>A <em>tela de rede</em> mostra dois cards: status do nó (contagem de peers, tamanho da +DHT, estado de bootstrap, uptime) e saúde da replicação (total de fragmentos, +fragmentos saudáveis, fragmentos em reparo, fator de replicação). A <em>tela de +configurações</em> exibe a identidade do usuário — nome, node ID truncado, chave +pública truncada e data de criação.</p> +<p>Três providers Riverpod gerenciam o estado: <code>nodeProvider</code> inicia o nó embarcado +ao abrir o app usando o diretório de documentos e para ao fazer dispose; +<code>identityProvider</code> carrega o perfil existente ou cria um novo; +<code>timelineProvider</code> busca a lista de memórias com paginação.</p> +<p><strong>Testes</strong> — 9 testes unitários Rust em tesseras-embedded cobrindo ciclo de vida +do nó (start/stop sem panic), persistência de identidade entre reinícios, ciclos +de reinício sem corrupção do SQLite, streaming de eventos de rede, recuperação +de estatísticas, criação de memória e recuperação da timeline, e busca de +memória individual por hash. 2 testes Flutter: um teste de integração +verificando inicialização do Rust e startup do app, e um smoke test de widget.</p> +<h2 id="decisoes-de-arquitetura">Decisões de arquitetura</h2> +<ul> +<li><strong>Nó embarcado, não cliente-servidor</strong>: o celular roda a stack P2P completa, +não um thin client conversando com um daemon remoto. Isso significa que +memórias são preservadas mesmo sem internet. Usuários com um Raspberry Pi ou +VPS podem opcionalmente conectar o app ao seu daemon via GraphQL para maior +disponibilidade, mas não é obrigatório.</li> +<li><strong>FFI síncrono</strong>: todas as funções flutter_rust_bridge são marcadas como +<code>#[frb(sync)]</code> e bloqueiam no runtime Tokio interno. Isso simplifica o lado +Dart (sem complexidade de bridge assíncrono) enquanto o lado Rust lida com +concorrência internamente. A UI thread do Flutter permanece responsiva porque +o Riverpod envolve as chamadas em providers assíncronos.</li> +<li><strong>Singleton global</strong>: um global <code>Mutex<Option<EmbeddedNode>></code> garante que o +ciclo de vida do nó seja previsível — um start, um stop, sem race conditions. +Plataformas mobile matam processos agressivamente, então simplicidade no +gerenciamento de ciclo de vida é uma feature.</li> +<li><strong>Tipos FFI planos</strong>: nenhuma abstração Rust vaza pela fronteira FFI. Todo +tipo é uma struct plana com strings e números. Isso torna os bindings Dart +auto-gerados confiáveis e fáceis de debugar.</li> +<li><strong>Onboarding de três telas</strong>: a criação de identidade é o único passo +obrigatório. Sem email, sem senha, sem registro em servidor. O app gera uma +identidade criptográfica localmente e está pronto para uso.</li> +</ul> +<h2 id="o-que-vem-a-seguir">O que vem a seguir</h2> +<ul> +<li><strong>Fase 4: Resiliência e Escala</strong> — NAT traversal avançado (STUN/TURN), +Shamir's Secret Sharing para herdeiros, tesseras seladas com criptografia +temporal, ajuste de performance, auditorias de segurança, empacotamento para +Alpine/Arch/Debian/FreeBSD/OpenBSD</li> +<li><strong>Fase 5: Exploração e Cultura</strong> — Navegador público de tesseras por +era/localização/tema/idioma, curadoria institucional, integração com +genealogia, exportação para mídia física (M-DISC, microfilme, papel livre de +ácido com QR)</li> +</ul> +<p>A infraestrutura está completa. A rede existe, a replicação funciona, e agora +qualquer pessoa com um celular pode participar. O que resta é fortalecer o que +temos e abrir para o mundo.</p> + +</article> + + </main> + + <footer> + <p>© 2026 Tesseras Project. <a href="/atom.xml">News Feed</a> · <a href="https://git.sr.ht/~ijanc/tesseras">Source</a></p> + </footer> +</body> +</html> diff --git a/pt-br/news/phase3-api-and-apps/index.html.gz b/pt-br/news/phase3-api-and-apps/index.html.gz Binary files differnew file mode 100644 index 0000000..d9c466e --- /dev/null +++ b/pt-br/news/phase3-api-and-apps/index.html.gz |