summaryrefslogtreecommitdiffstats
path: root/pt-br/news/phase3-api-and-apps/index.html
blob: 57ea05e83a501db9049d791e9780b29c1ffe43d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
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:&#x2F;&#x2F;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:&#x2F;&#x2F;tesseras.net&#x2F;news&#x2F;phase3-api-and-apps&#x2F;">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&lt;Option&lt;EmbeddedNode&gt;&gt;</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&lt;String&gt;</code>, <code>Vec&lt;String&gt;</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&lt;Option&lt;EmbeddedNode&gt;&gt;</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>&copy; 2026 Tesseras Project. <a href="/atom.xml">News Feed</a> · <a href="https://git.sr.ht/~ijanc/tesseras">Source</a></p>
    </footer>
</body>
</html>