From f186b71ca51e83837db60de13322394bb5e6d348 Mon Sep 17 00:00:00 2001
From: murilo ijanc
Date: Tue, 24 Mar 2026 21:41:06 -0300
Subject: Initial commit
Import existing tesseras.net website content.
---
pt-br/news/atom.xml | 2101 ++++++++++++++++++++
pt-br/news/atom.xml.gz | Bin 0 -> 42802 bytes
pt-br/news/cli-daemon-rpc/index.html | 147 ++
pt-br/news/cli-daemon-rpc/index.html.gz | Bin 0 -> 3452 bytes
pt-br/news/hello-world/index.html | 81 +
pt-br/news/hello-world/index.html.gz | Bin 0 -> 1398 bytes
pt-br/news/index.html | 198 ++
pt-br/news/index.html.gz | Bin 0 -> 2732 bytes
pt-br/news/packaging-archlinux/index.html | 124 ++
pt-br/news/packaging-archlinux/index.html.gz | Bin 0 -> 2262 bytes
pt-br/news/packaging-debian/index.html | 159 ++
pt-br/news/packaging-debian/index.html.gz | Bin 0 -> 2677 bytes
pt-br/news/phase0-foundation/index.html | 130 ++
pt-br/news/phase0-foundation/index.html.gz | Bin 0 -> 2885 bytes
pt-br/news/phase1-basic-network/index.html | 177 ++
pt-br/news/phase1-basic-network/index.html.gz | Bin 0 -> 4349 bytes
pt-br/news/phase2-replication/index.html | 213 ++
pt-br/news/phase2-replication/index.html.gz | Bin 0 -> 4668 bytes
pt-br/news/phase3-api-and-apps/index.html | 167 ++
pt-br/news/phase3-api-and-apps/index.html.gz | Bin 0 -> 4248 bytes
pt-br/news/phase4-encryption-sealed/index.html | 187 ++
pt-br/news/phase4-encryption-sealed/index.html.gz | Bin 0 -> 4633 bytes
.../phase4-institutional-onboarding/index.html | 252 +++
.../phase4-institutional-onboarding/index.html.gz | Bin 0 -> 5866 bytes
pt-br/news/phase4-nat-traversal/index.html | 238 +++
pt-br/news/phase4-nat-traversal/index.html.gz | Bin 0 -> 5590 bytes
pt-br/news/phase4-performance-tuning/index.html | 169 ++
pt-br/news/phase4-performance-tuning/index.html.gz | Bin 0 -> 4039 bytes
pt-br/news/phase4-shamir-heir-recovery/index.html | 209 ++
.../news/phase4-shamir-heir-recovery/index.html.gz | Bin 0 -> 4927 bytes
pt-br/news/phase4-storage-deduplication/index.html | 229 +++
.../phase4-storage-deduplication/index.html.gz | Bin 0 -> 5097 bytes
.../phase4-wasm-browser-verification/index.html | 199 ++
.../phase4-wasm-browser-verification/index.html.gz | Bin 0 -> 5122 bytes
pt-br/news/reed-solomon/index.html | 210 ++
pt-br/news/reed-solomon/index.html.gz | Bin 0 -> 5034 bytes
36 files changed, 5190 insertions(+)
create mode 100644 pt-br/news/atom.xml
create mode 100644 pt-br/news/atom.xml.gz
create mode 100644 pt-br/news/cli-daemon-rpc/index.html
create mode 100644 pt-br/news/cli-daemon-rpc/index.html.gz
create mode 100644 pt-br/news/hello-world/index.html
create mode 100644 pt-br/news/hello-world/index.html.gz
create mode 100644 pt-br/news/index.html
create mode 100644 pt-br/news/index.html.gz
create mode 100644 pt-br/news/packaging-archlinux/index.html
create mode 100644 pt-br/news/packaging-archlinux/index.html.gz
create mode 100644 pt-br/news/packaging-debian/index.html
create mode 100644 pt-br/news/packaging-debian/index.html.gz
create mode 100644 pt-br/news/phase0-foundation/index.html
create mode 100644 pt-br/news/phase0-foundation/index.html.gz
create mode 100644 pt-br/news/phase1-basic-network/index.html
create mode 100644 pt-br/news/phase1-basic-network/index.html.gz
create mode 100644 pt-br/news/phase2-replication/index.html
create mode 100644 pt-br/news/phase2-replication/index.html.gz
create mode 100644 pt-br/news/phase3-api-and-apps/index.html
create mode 100644 pt-br/news/phase3-api-and-apps/index.html.gz
create mode 100644 pt-br/news/phase4-encryption-sealed/index.html
create mode 100644 pt-br/news/phase4-encryption-sealed/index.html.gz
create mode 100644 pt-br/news/phase4-institutional-onboarding/index.html
create mode 100644 pt-br/news/phase4-institutional-onboarding/index.html.gz
create mode 100644 pt-br/news/phase4-nat-traversal/index.html
create mode 100644 pt-br/news/phase4-nat-traversal/index.html.gz
create mode 100644 pt-br/news/phase4-performance-tuning/index.html
create mode 100644 pt-br/news/phase4-performance-tuning/index.html.gz
create mode 100644 pt-br/news/phase4-shamir-heir-recovery/index.html
create mode 100644 pt-br/news/phase4-shamir-heir-recovery/index.html.gz
create mode 100644 pt-br/news/phase4-storage-deduplication/index.html
create mode 100644 pt-br/news/phase4-storage-deduplication/index.html.gz
create mode 100644 pt-br/news/phase4-wasm-browser-verification/index.html
create mode 100644 pt-br/news/phase4-wasm-browser-verification/index.html.gz
create mode 100644 pt-br/news/reed-solomon/index.html
create mode 100644 pt-br/news/reed-solomon/index.html.gz
(limited to 'pt-br/news')
diff --git a/pt-br/news/atom.xml b/pt-br/news/atom.xml
new file mode 100644
index 0000000..99f3061
--- /dev/null
+++ b/pt-br/news/atom.xml
@@ -0,0 +1,2101 @@
+
+
+ Tesseras - Notícias
+ Rede P2P para preservar memórias humanas através dos milênios
+
+
+ Zola
+ 2026-02-16T10:00:00+00:00
+ https://tesseras.net/pt-br/news/atom.xml
+
+ Empacotando o Tesseras para Debian
+ 2026-02-16T10:00:00+00:00
+ 2026-02-16T10:00:00+00:00
+
+
+
+
+ Unknown
+
+
+
+
+
+ https://tesseras.net/pt-br/news/packaging-debian/
+
+ <p>O Tesseras agora inclui um pacote <code>.deb</code> para Debian e Ubuntu. Este post explica
+como compilar e instalar o pacote a partir do código-fonte usando <code>cargo-deb</code>.</p>
+<h2 id="pre-requisitos">Pré-requisitos</h2>
+<p>Você precisa de uma toolchain Rust funcional e das bibliotecas de sistema
+necessárias:</p>
+<pre><code data-lang="sh">sudo apt install build-essential pkg-config libsqlite3-dev
+rustup toolchain install stable
+cargo install cargo-deb
+</code></pre>
+<h2 id="compilando">Compilando</h2>
+<p>Clone o repositório e execute a recipe <code>just deb</code>:</p>
+<pre><code data-lang="sh">git clone https://git.sr.ht/~ijanc/tesseras
+cd tesseras
+just deb
+</code></pre>
+<p>Essa recipe faz três coisas:</p>
+<ol>
+<li><strong>Compila</strong> <code>tesd</code> (o daemon) e <code>tes</code> (o CLI) em modo release com
+<code>cargo build --release</code></li>
+<li><strong>Gera completions de shell</strong> para bash, zsh e fish a partir do binário <code>tes</code></li>
+<li><strong>Empacota</strong> tudo em um arquivo <code>.deb</code> com
+<code>cargo deb -p tesseras-daemon --no-build</code></li>
+</ol>
+<p>O resultado é um arquivo <code>.deb</code> em <code>target/debian/</code>.</p>
+<h2 id="instalando">Instalando</h2>
+<pre><code data-lang="sh">sudo dpkg -i target/debian/tesseras-daemon_*.deb
+</code></pre>
+<p>Se houver dependências faltando, corrija com:</p>
+<pre><code data-lang="sh">sudo apt install -f
+</code></pre>
+<h2 id="configuracao-pos-instalacao">Configuração pós-instalação</h2>
+<p>O script <code>postinst</code> cria automaticamente um usuário de sistema <code>tesseras</code> e o
+diretório de dados <code>/var/lib/tesseras</code>. Para usar o CLI sem sudo, adicione seu
+usuário ao grupo:</p>
+<pre><code data-lang="sh">sudo usermod -aG tesseras $USER
+</code></pre>
+<p>Faça logout e login novamente, depois inicie o daemon:</p>
+<pre><code data-lang="sh">sudo systemctl enable --now tesd
+</code></pre>
+<h2 id="o-que-o-pacote-inclui">O que o pacote inclui</h2>
+<table><thead><tr><th>Caminho</th><th>Descrição</th></tr></thead><tbody>
+<tr><td><code>/usr/bin/tesd</code></td><td>Daemon do nó completo</td></tr>
+<tr><td><code>/usr/bin/tes</code></td><td>Cliente CLI</td></tr>
+<tr><td><code>/etc/tesseras/config.toml</code></td><td>Configuração padrão (marcado como conffile)</td></tr>
+<tr><td><code>/lib/systemd/system/tesd.service</code></td><td>Unit systemd com hardening de segurança</td></tr>
+<tr><td>Completions de shell</td><td>bash, zsh e fish</td></tr>
+</tbody></table>
+<h2 id="como-o-cargo-deb-funciona">Como o cargo-deb funciona</h2>
+<p>Os metadados de empacotamento ficam em <code>crates/tesseras-daemon/Cargo.toml</code> na
+seção <code>[package.metadata.deb]</code>. Essa seção define:</p>
+<ul>
+<li><strong>depends</strong> — dependências em tempo de execução: <code>libc6</code> e <code>libsqlite3-0</code></li>
+<li><strong>assets</strong> — arquivos incluídos no pacote (binários, config, unit systemd,
+completions de shell)</li>
+<li><strong>conf-files</strong> — arquivos tratados como configuração (preservados na
+atualização)</li>
+<li><strong>maintainer-scripts</strong> — scripts <code>postinst</code> e <code>postrm</code> em
+<code>packaging/debian/scripts/</code></li>
+<li><strong>systemd-units</strong> — integração automática com systemd</li>
+</ul>
+<p>O script <code>postinst</code> cria o usuário de sistema <code>tesseras</code> e o diretório de dados
+na instalação. O script <code>postrm</code> remove o usuário, grupo e diretório de dados
+apenas no <code>purge</code> (não na remoção simples).</p>
+<h2 id="hardening-do-systemd">Hardening do systemd</h2>
+<p>A unit <code>tesd.service</code> inclui diretivas de hardening de segurança:</p>
+<pre><code data-lang="ini">NoNewPrivileges=true
+ProtectSystem=strict
+ProtectHome=true
+ReadWritePaths=/var/lib/tesseras
+PrivateTmp=true
+PrivateDevices=true
+ProtectKernelTunables=true
+ProtectControlGroups=true
+RestrictSUIDSGID=true
+MemoryDenyWriteExecute=true
+</code></pre>
+<p>O daemon roda como o usuário não-privilegiado <code>tesseras</code> e só pode escrever em
+<code>/var/lib/tesseras</code>.</p>
+<h2 id="deploy-para-um-servidor-remoto">Deploy para um servidor remoto</h2>
+<p>O justfile inclui uma recipe <code>deploy</code> para enviar o <code>.deb</code> a um host remoto:</p>
+<pre><code data-lang="sh">just deploy bootstrap1.tesseras.net
+</code></pre>
+<p>Isso compila o <code>.deb</code>, copia via <code>scp</code>, instala com <code>dpkg -i</code> e reinicia o
+serviço <code>tesd</code>.</p>
+<h2 id="atualizando">Atualizando</h2>
+<p>Depois de baixar novas mudanças, basta rodar <code>just deb</code> novamente e reinstalar:</p>
+<pre><code data-lang="sh">git pull
+just deb
+sudo dpkg -i target/debian/tesseras-daemon_*.deb
+</code></pre>
+
+
+
+
+ Empacotando o Tesseras para Arch Linux
+ 2026-02-16T09:00:00+00:00
+ 2026-02-16T09:00:00+00:00
+
+
+
+
+ Unknown
+
+
+
+
+
+ https://tesseras.net/pt-br/news/packaging-archlinux/
+
+ <p>O Tesseras agora inclui um PKGBUILD para Arch Linux. Este post explica como
+compilar e instalar o pacote a partir do código-fonte.</p>
+<h2 id="pre-requisitos">Pré-requisitos</h2>
+<p>Você precisa de uma toolchain Rust funcional e do grupo base-devel:</p>
+<pre><code data-lang="sh">sudo pacman -S --needed base-devel sqlite
+rustup toolchain install stable
+</code></pre>
+<h2 id="compilando">Compilando</h2>
+<p>Clone o repositório e execute a recipe <code>just arch</code>:</p>
+<pre><code data-lang="sh">git clone https://git.sr.ht/~ijanc/tesseras
+cd tesseras
+just arch
+</code></pre>
+<p>Isso executa <code>makepkg -sf</code> dentro de <code>packaging/archlinux/</code>, que:</p>
+<ol>
+<li><strong>prepare</strong> — baixa as dependências Cargo com <code>cargo fetch --locked</code></li>
+<li><strong>build</strong> — compila <code>tesd</code> e <code>tes</code> (o CLI) em modo release</li>
+<li><strong>package</strong> — instala binários, serviço systemd, configs sysusers/tmpfiles,
+completions de shell (bash, zsh, fish) e um arquivo de configuração padrão</li>
+</ol>
+<p>O resultado é um arquivo <code>.pkg.tar.zst</code> em <code>packaging/archlinux/</code>.</p>
+<h2 id="instalando">Instalando</h2>
+<pre><code data-lang="sh">sudo pacman -U packaging/archlinux/tesseras-*.pkg.tar.zst
+</code></pre>
+<h2 id="configuracao-pos-instalacao">Configuração pós-instalação</h2>
+<p>O pacote cria automaticamente um usuário e grupo de sistema <code>tesseras</code> via
+systemd-sysusers. Para usar o CLI sem sudo, adicione seu usuário ao grupo:</p>
+<pre><code data-lang="sh">sudo usermod -aG tesseras $USER
+</code></pre>
+<p>Faça logout e login novamente, depois inicie o daemon:</p>
+<pre><code data-lang="sh">sudo systemctl enable --now tesd
+</code></pre>
+<h2 id="o-que-o-pacote-inclui">O que o pacote inclui</h2>
+<table><thead><tr><th>Caminho</th><th>Descrição</th></tr></thead><tbody>
+<tr><td><code>/usr/bin/tesd</code></td><td>Daemon do nó completo</td></tr>
+<tr><td><code>/usr/bin/tes</code></td><td>Cliente CLI</td></tr>
+<tr><td><code>/etc/tesseras/config.toml</code></td><td>Configuração padrão (marcado como backup)</td></tr>
+<tr><td><code>/usr/lib/systemd/system/tesd.service</code></td><td>Unit systemd com hardening de segurança</td></tr>
+<tr><td><code>/usr/lib/sysusers.d/tesseras.conf</code></td><td>Definição do usuário de sistema</td></tr>
+<tr><td><code>/usr/lib/tmpfiles.d/tesseras.conf</code></td><td>Diretório de dados <code>/var/lib/tesseras</code></td></tr>
+<tr><td>Completions de shell</td><td>bash, zsh e fish</td></tr>
+</tbody></table>
+<h2 id="detalhes-do-pkgbuild">Detalhes do PKGBUILD</h2>
+<p>O PKGBUILD compila diretamente a partir do checkout git local em vez de baixar
+um tarball. A variável de ambiente <code>TESSERAS_ROOT</code> aponta o makepkg para a raiz
+do workspace. O diretório target do Cargo é configurado para <code>$srcdir/target</code>
+para manter os artefatos de build dentro do sandbox do makepkg.</p>
+<p>O pacote depende apenas de <code>sqlite</code> em tempo de execução e <code>cargo</code> em tempo de
+build.</p>
+<h2 id="atualizando">Atualizando</h2>
+<p>Depois de baixar novas mudanças, basta rodar <code>just arch</code> novamente e reinstalar:</p>
+<pre><code data-lang="sh">git pull
+just arch
+sudo pacman -U packaging/archlinux/tesseras-*.pkg.tar.zst
+</code></pre>
+
+
+
+
+ Fase 4: Deduplicacao de Armazenamento
+ 2026-02-15T23:00:00+00:00
+ 2026-02-15T23:00:00+00:00
+
+
+
+
+ Unknown
+
+
+
+
+
+ https://tesseras.net/pt-br/news/phase4-storage-deduplication/
+
+ <p>Quando multiplas tesseras compartilham a mesma foto, o mesmo clipe de audio ou
+os mesmos dados de fragmento, a camada de armazenamento antiga mantinha copias
+separadas de cada. Em um no armazenando milhares de tesseras para a rede, essa
+duplicacao se acumula rapidamente. A Fase 4 continua com deduplicacao de
+armazenamento: um armazenamento enderecavel por conteudo (CAS) que garante que
+cada dado unico seja armazenado exatamente uma vez em disco, independentemente
+de quantas tesseras o referenciam.</p>
+<p>O design e simples e comprovado: hash do conteudo com BLAKE3, usar o hash como
+nome do arquivo e manter uma contagem de referencias no SQLite. Quando duas
+tesseras incluem a mesma foto de 5 MB, um arquivo existe em disco com
+refcount 2. Quando uma tessera e deletada, o refcount cai para 1 e o arquivo
+permanece. Quando a ultima referencia e liberada, uma varredura periodica limpa
+o orfao.</p>
+<h2 id="o-que-foi-construido">O que foi construido</h2>
+<p><strong>Migracao do esquema CAS</strong> (<code>tesseras-storage/migrations/004_dedup.sql</code>) — Tres
+novas tabelas:</p>
+<ul>
+<li><code>cas_objects</code> — rastreia cada objeto no armazenamento: hash BLAKE3 (chave
+primaria), tamanho em bytes, contagem de referencias e timestamp de criacao</li>
+<li><code>blob_refs</code> — mapeia identificadores logicos de blobs (hash da tessera + hash
+da memoria + nome do arquivo) para hashes CAS, substituindo a convencao antiga
+de caminhos no sistema de arquivos</li>
+<li><code>fragment_refs</code> — mapeia identificadores logicos de fragmentos (hash da
+tessera + indice do fragmento) para hashes CAS, substituindo o antigo layout
+do diretorio <code>fragments/</code></li>
+</ul>
+<p>Indices nas colunas de hash garantem lookups O(1) durante leituras e contagem de
+referencias.</p>
+<p><strong>CasStore</strong> (<code>tesseras-storage/src/cas.rs</code>) — O motor central de armazenamento
+enderecavel por conteudo. Arquivos sao armazenados sob um diretorio de prefixo
+de dois niveis: <code><raiz>/<prefixo-hex-2-chars>/<hash-completo>.blob</code>. O
+armazenamento fornece cinco operacoes:</p>
+<ul>
+<li><code>put(hash, data)</code> — escreve dados em disco se ainda nao presente, incrementa o
+refcount. Retorna se ocorreu um hit de deduplicacao.</li>
+<li><code>get(hash)</code> — le dados do disco pelo hash</li>
+<li><code>release(hash)</code> — decrementa o refcount. Se chegar a zero, o arquivo em disco
+e deletado imediatamente.</li>
+<li><code>contains(hash)</code> — verifica existencia sem ler</li>
+<li><code>ref_count(hash)</code> — retorna a contagem de referencias atual</li>
+</ul>
+<p>Todas as operacoes sao atomicas dentro de uma unica transacao SQLite. O refcount
+e a fonte de verdade — se o refcount diz que o objeto existe, o arquivo deve
+estar em disco.</p>
+<p><strong>FsBlobStore com CAS</strong> (<code>tesseras-storage/src/blob.rs</code>) — Reescrito para
+delegar todo armazenamento ao CAS. Quando um blob e escrito, seu hash BLAKE3 e
+computado e passado para <code>cas.put()</code>. Uma linha em <code>blob_refs</code> mapeia o caminho
+logico (tessera + memoria + arquivo) para o hash CAS. Leituras buscam o hash CAS
+via <code>blob_refs</code> e leem de <code>cas.get()</code>. Deletar uma tessera libera todas as suas
+referencias de blob em uma unica transacao.</p>
+<p><strong>FsFragmentStore com CAS</strong> (<code>tesseras-storage/src/fragment.rs</code>) — Mesmo padrao
+para fragmentos codificados com erasure coding. O checksum BLAKE3 de cada
+fragmento ja e computado durante a codificacao Reed-Solomon, entao e usado
+diretamente como chave CAS. A verificacao de fragmentos agora checa o hash CAS
+ao inves de recomputar do zero — se o CAS diz que os dados estao intactos,
+estao.</p>
+<p><strong>Coletor de lixo sweep</strong> (<code>cas.rs:sweep()</code>) — Uma passagem periodica de GC que
+trata tres casos limite que o caminho normal de refcount nao consegue:</p>
+<ol>
+<li><strong>Arquivos orfaos</strong> — arquivos em disco sem linha correspondente em
+<code>cas_objects</code>. Pode acontecer apos um crash durante escrita. Arquivos com
+menos de 1 hora sao pulados (periodo de graca para escritas em andamento);
+orfaos mais antigos sao deletados.</li>
+<li><strong>Refcounts vazados</strong> — linhas em <code>cas_objects</code> com refcount zero que nao
+foram limpas (ex: se o processo morreu entre decrementar e deletar). Essas
+linhas sao removidas.</li>
+<li><strong>Idempotente</strong> — executar sweep duas vezes produz o mesmo resultado.</li>
+</ol>
+<p>O sweep e conectado ao loop de reparo existente em <code>tesseras-replication</code>, entao
+roda automaticamente a cada 24 horas junto com as verificacoes de saude dos
+fragmentos.</p>
+<p><strong>Migracao do layout antigo</strong> (<code>tesseras-storage/src/migration.rs</code>) — Uma
+estrategia de migracao copy-first que move dados do layout antigo baseado em
+diretorios (<code>blobs/<tessera>/<memoria>/<arquivo></code> e
+<code>fragments/<tessera>/<indice>.shard</code>) para o CAS. A migracao:</p>
+<ol>
+<li>Verifica a versao de armazenamento em <code>storage_meta</code> (versao 1 = layout
+antigo, versao 2 = CAS)</li>
+<li>Percorre os diretorios antigos <code>blobs/</code> e <code>fragments/</code></li>
+<li>Computa hashes BLAKE3 e insere no CAS via <code>put()</code> — duplicatas sao
+automaticamente deduplicadas</li>
+<li>Cria entradas correspondentes em <code>blob_refs</code> / <code>fragment_refs</code></li>
+<li>Remove diretorios antigos somente apos todos os dados estarem seguros no CAS</li>
+<li>Atualiza a versao de armazenamento para 2</li>
+</ol>
+<p>A migracao roda na inicializacao do daemon, e idempotente (segura para
+re-executar) e reporta estatisticas: arquivos migrados, duplicatas encontradas,
+bytes economizados.</p>
+<p><strong>Metricas Prometheus</strong> (<code>tesseras-storage/src/metrics.rs</code>) — Dez novas metricas
+para observabilidade:</p>
+<table><thead><tr><th>Metrica</th><th>Descricao</th></tr></thead><tbody>
+<tr><td><code>cas_objects_total</code></td><td>Total de objetos unicos no CAS</td></tr>
+<tr><td><code>cas_bytes_total</code></td><td>Total de bytes armazenados</td></tr>
+<tr><td><code>cas_dedup_hits_total</code></td><td>Numero de escritas que encontraram um objeto existente</td></tr>
+<tr><td><code>cas_bytes_saved_total</code></td><td>Bytes economizados por deduplicacao</td></tr>
+<tr><td><code>cas_gc_refcount_deletions_total</code></td><td>Objetos deletados quando refcount chegou a zero</td></tr>
+<tr><td><code>cas_gc_sweep_orphans_cleaned_total</code></td><td>Arquivos orfaos removidos pelo sweep</td></tr>
+<tr><td><code>cas_gc_sweep_leaked_refs_cleaned_total</code></td><td>Linhas de refcount vazadas limpas</td></tr>
+<tr><td><code>cas_gc_sweep_skipped_young_total</code></td><td>Orfaos jovens pulados (periodo de graca)</td></tr>
+<tr><td><code>cas_gc_sweep_duration_seconds</code></td><td>Tempo gasto no sweep GC</td></tr>
+</tbody></table>
+<p><strong>Testes baseados em propriedades</strong> — Dois testes proptest verificam invariantes
+do CAS sob entradas aleatorias:</p>
+<ul>
+<li><code>refcount_matches_actual_refs</code> — apos N operacoes aleatorias de put/release, o
+refcount sempre corresponde ao numero real de referencias pendentes</li>
+<li><code>cas_path_is_deterministic</code> — o mesmo hash sempre produz o mesmo caminho no
+sistema de arquivos</li>
+</ul>
+<p><strong>Atualizacao de testes de integracao</strong> — Todos os testes de integracao em
+<code>tesseras-core</code>, <code>tesseras-replication</code>, <code>tesseras-embedded</code> e <code>tesseras-cli</code>
+atualizados para os novos construtores com CAS. Testes de deteccao de
+adulteracao atualizados para funcionar com o layout de diretorio CAS.</p>
+<p>347 testes passam em todo o workspace. Clippy limpo com <code>-D warnings</code>.</p>
+<h2 id="decisoes-de-arquitetura">Decisoes de arquitetura</h2>
+<ul>
+<li><strong>BLAKE3 como chave CAS</strong>: o hash de conteudo que ja computamos para
+verificacao de integridade serve tambem como chave de deduplicacao. Nenhuma
+etapa adicional de hashing — o hash computado durante <code>create</code> ou <code>replicate</code>
+e reutilizado como endereco CAS.</li>
+<li><strong>Refcount SQLite ao inves de reflinks do sistema de arquivos</strong>: consideramos
+usar copy-on-write no nivel do sistema de arquivos (reflinks em btrfs/XFS),
+mas isso amarraria o Tesseras a sistemas de arquivos especificos. Refcounting
+em SQLite funciona em qualquer sistema de arquivos, incluindo FAT32 em
+pendrives baratos e ext4 em Raspberry Pis.</li>
+<li><strong>Diretorios de prefixo hexadecimal de dois niveis</strong>: armazenar todos os
+objetos CAS em um diretorio plano desaceleraria sistemas de arquivos com
+milhoes de entradas. A divisao <code><prefixo 2 chars>/</code> limita qualquer diretorio
+individual a ~65k entradas antes de um segundo nivel ser necessario. Isso
+segue a abordagem usada pelo object store do Git.</li>
+<li><strong>Periodo de graca para arquivos orfaos</strong>: o sweep GC pula arquivos com menos
+de 1 hora para evitar deletar objetos sendo escritos por uma operacao
+concorrente. Esta e uma escolha pragmatica — troca uma pequena janela de
+potenciais orfaos por seguranca contra crashes sem exigir fsync ou commit de
+duas fases.</li>
+<li><strong>Migracao copy-first</strong>: a migracao copia dados para o CAS antes de remover
+diretorios antigos. Se o processo for interrompido, os dados antigos
+permanecem intactos e a migracao pode ser re-executada. Isso e mais lento que
+mover arquivos mas garante zero perda de dados.</li>
+<li><strong>Sweep no loop de reparo</strong>: ao inves de adicionar um timer separado de GC, o
+sweep CAS aproveita o loop de reparo existente de 24 horas. Isso mantem o
+daemon simples — um unico ciclo de manutencao em segundo plano cuida tanto da
+saude dos fragmentos quanto da limpeza de armazenamento.</li>
+</ul>
+<h2 id="o-que-vem-a-seguir">O que vem a seguir</h2>
+<ul>
+<li><strong>Fase 4 continuacao</strong> — auditorias de seguranca, empacotamento para OS
+(Alpine, Arch, Debian, OpenBSD, FreeBSD)</li>
+<li><strong>Fase 5: Exploracao e Cultura</strong> — navegador publico de tesseras por
+era/localizacao/tema/idioma, curadoria institucional, integracao genealogica
+(FamilySearch, Ancestry), exportacao para midia fisica (M-DISC, microfilme,
+papel livre de acido com QR), contexto assistido por IA</li>
+</ul>
+<p>A deduplicacao de armazenamento completa a historia de eficiencia de
+armazenamento do Tesseras. Um no que armazena fragmentos para milhares de
+usuarios — comum para nos institucionais e nos completos sempre ligados — agora
+paga o custo de disco apenas por dados unicos. Combinado com codificacao de
+apagamento Reed-Solomon (que ja minimiza redundancia no nivel da rede), o
+sistema alcanca armazenamento eficiente tanto nas camadas local quanto
+distribuida.</p>
+
+
+
+
+ Fase 4: Onboarding de Nos Institucionais
+ 2026-02-15T22:00:00+00:00
+ 2026-02-15T22:00:00+00:00
+
+
+
+
+ Unknown
+
+
+
+
+
+ https://tesseras.net/pt-br/news/phase4-institutional-onboarding/
+
+ <p>Uma rede P2P composta apenas por individuos e fragil. Discos rigidos morrem,
+celulares sao perdidos, pessoas perdem interesse. A sobrevivencia a longo prazo
+das memorias da humanidade depende de instituicoes — bibliotecas, arquivos,
+museus, universidades — que medem seus tempos de vida em seculos. A Fase 4
+continua com o onboarding de nos institucionais: organizacoes verificadas agora
+podem prometer armazenamento, manter indices de busca e participar da rede com
+uma identidade distinta.</p>
+<p>O design segue um principio de confiar mas verificar: instituicoes se
+identificam via registros DNS TXT (o mesmo mecanismo usado por SPF, DKIM e DMARC
+para email), prometem um orcamento de armazenamento e recebem isencoes de
+reciprocidade para que possam armazenar fragmentos para outros sem esperar nada
+em troca. Em contrapartida, a rede trata seus fragmentos como replicas de maior
+qualidade e limita a dependencia excessiva de qualquer instituicao individual
+atraves de restricoes de diversidade.</p>
+<h2 id="o-que-foi-construido">O que foi construido</h2>
+<p><strong>Bits de capacidade</strong> (<code>tesseras-core/src/network.rs</code>) — Dois novos flags
+adicionados ao bitfield <code>Capabilities</code>: <code>INSTITUTIONAL</code> (bit 7) e <code>SEARCH_INDEX</code>
+(bit 8). Um novo construtor <code>institutional_default()</code> retorna o conjunto
+completo de capacidades da Fase 2 mais esses dois bits e <code>RELAY</code>. Nos normais
+anunciam <code>phase2_default()</code> que nao inclui flags institucionais. Testes de
+roundtrip de serializacao verificam que os novos bits sobrevivem a codificacao
+MessagePack.</p>
+<p><strong>Tipos de busca</strong> (<code>tesseras-core/src/search.rs</code>) — Tres novos tipos de dominio
+para o subsistema de busca:</p>
+<ul>
+<li><code>SearchFilters</code> — parametros de consulta: <code>memory_type</code>, <code>visibility</code>,
+<code>language</code>, <code>date_range</code>, <code>geo</code> (bounding box), <code>page</code>, <code>page_size</code></li>
+<li><code>SearchHit</code> — um resultado individual: hash do conteudo mais um
+<code>MetadataExcerpt</code> (titulo, descricao, tipo de memoria, data de criacao,
+visibilidade, idioma, tags)</li>
+<li><code>GeoFilter</code> — bounding box com <code>min_lat</code>, <code>max_lat</code>, <code>min_lon</code>, <code>max_lon</code> para
+consultas espaciais</li>
+</ul>
+<p>Todos os tipos derivam <code>Serialize</code>/<code>Deserialize</code> para transporte e
+<code>Clone</code>/<code>Debug</code> para diagnostico.</p>
+<p><strong>Configuracao institucional do daemon</strong> (<code>tesd/src/config.rs</code>) — Uma nova secao
+<code>[institutional]</code> no TOML com <code>domain</code> (o dominio DNS a verificar),
+<code>pledge_bytes</code> (compromisso de armazenamento em bytes) e <code>search_enabled</code>
+(toggle para o indice FTS5). O metodo <code>to_dht_config()</code> agora define
+<code>Capabilities::institutional_default()</code> quando a configuracao institucional esta
+presente, para que nos institucionais anunciem os bits de capacidade corretos em
+respostas Pong.</p>
+<p><strong>Verificacao DNS TXT</strong> (<code>tesd/src/institutional.rs</code>) — Resolucao DNS assincrona
+usando <code>hickory-resolver</code> para verificar identidade institucional. O daemon
+consulta registros TXT em <code>_tesseras.<dominio></code> e analisa campos chave-valor:
+<code>v</code> (versao), <code>node</code> (node ID em hexadecimal) e <code>pledge</code> (compromisso de
+armazenamento em bytes). A verificacao checa:</p>
+<ol>
+<li>Um registro TXT existe em <code>_tesseras.<dominio></code></li>
+<li>O campo <code>node</code> corresponde ao node ID do proprio daemon</li>
+<li>O campo <code>pledge</code> esta presente e e valido</li>
+</ol>
+<p>Na inicializacao, o daemon tenta a verificacao DNS. Se bem-sucedida, o no roda
+com capacidades institucionais. Se falhar, o no registra um aviso e faz
+downgrade para um no completo normal — sem crash, sem intervencao manual.</p>
+<p><strong>Comando CLI de setup</strong> (<code>tesseras-cli/src/institutional.rs</code>) — Um novo
+subcomando <code>institutional setup</code> que guia operadores pelo onboarding:</p>
+<ol>
+<li>Le a identidade do no a partir do diretorio de dados</li>
+<li>Solicita nome de dominio e tamanho do pledge</li>
+<li>Gera o registro DNS TXT exato a adicionar:
+<code>v=tesseras1 node=<hex> pledge=<bytes></code></li>
+<li>Escreve a secao institucional no arquivo de configuracao do daemon</li>
+<li>Imprime os proximos passos: adicionar o registro TXT, reiniciar o daemon</li>
+</ol>
+<p><strong>Indice de busca SQLite</strong> (<code>tesseras-storage</code>) — Uma migracao
+(<code>003_institutional.sql</code>) que cria tres estruturas:</p>
+<ul>
+<li><code>search_content</code> — uma tabela virtual FTS5 para busca full-text sobre
+metadados de tesseras (titulo, descricao, criador, tags, idioma)</li>
+<li><code>geo_index</code> — uma tabela virtual R-tree para consultas espaciais de bounding
+box sobre latitude/longitude</li>
+<li><code>geo_map</code> — uma tabela de mapeamento ligando IDs de linhas do R-tree a hashes
+de conteudo</li>
+</ul>
+<p>O adaptador <code>SqliteSearchIndex</code> implementa o port trait <code>SearchIndex</code> com
+<code>index_tessera()</code> (inserir/atualizar) e <code>search()</code> (consultar com filtros).
+Consultas FTS5 suportam busca em linguagem natural; consultas geo usam
+<code>INTERSECT</code> do R-tree para lookups de bounding box. Resultados sao ranqueados
+por score de relevancia do FTS5.</p>
+<p>A migracao tambem adiciona uma coluna <code>is_institutional</code> a tabela <code>reciprocity</code>,
+tratada de forma idempotente via checagens <code>pragma_table_info</code> (o
+<code>ALTER TABLE ADD COLUMN</code> do SQLite nao tem <code>IF NOT EXISTS</code>).</p>
+<p><strong>Bypass de reciprocidade</strong> (<code>tesseras-replication/src/service.rs</code>) — Nos
+institucionais sao isentos de checagens de reciprocidade. Quando
+<code>receive_fragment()</code> e chamado, se o node ID do remetente esta marcado como
+institucional no ledger de reciprocidade, a checagem de saldo e ignorada
+completamente. Isso significa que instituicoes podem armazenar fragmentos para
+toda a rede sem precisar "ganhar" creditos primeiro — sua identidade verificada
+por DNS e compromisso de armazenamento servem como credencial.</p>
+<p><strong>Restricao de diversidade por tipo de no</strong>
+(<code>tesseras-replication/src/distributor.rs</code>) — Uma nova funcao
+<code>apply_institutional_diversity()</code> limita quantas replicas de uma unica tessera
+podem ir para nos institucionais. O limite e <code>ceil(fator_replicacao / 3.5)</code> —
+com o padrao <code>r=7</code>, no maximo 2 de 7 replicas vao para instituicoes. Isso impede
+que a rede se torne dependente de um pequeno numero de grandes instituicoes: se
+os servidores de uma universidade cairem, pelo menos 5 replicas permanecem em
+nos independentes.</p>
+<p><strong>Extensoes de mensagens DHT</strong> (<code>tesseras-dht/src/message.rs</code>) — Duas novas
+variantes de mensagem:</p>
+<table><thead><tr><th>Mensagem</th><th>Proposito</th></tr></thead><tbody>
+<tr><td><code>Search</code></td><td>Cliente envia string de consulta, filtros e numero da pagina</td></tr>
+<tr><td><code>SearchResult</code></td><td>No institucional responde com resultados e contagem total</td></tr>
+</tbody></table>
+<p>A funcao <code>encode()</code> foi trocada de serializacao MessagePack posicional para
+nomeada (<code>rmp_serde::to_vec_named</code>) para lidar corretamente com campos opcionais
+de <code>SearchFilters</code> — a codificacao posicional quebra quando
+<code>skip_serializing_if</code> omite campos.</p>
+<p><strong>Metricas Prometheus</strong> (<code>tesd/src/metrics.rs</code>) — Oito metricas especificas
+institucionais:</p>
+<ul>
+<li><code>tesseras_institutional_pledge_bytes</code> — compromisso de armazenamento
+configurado</li>
+<li><code>tesseras_institutional_stored_bytes</code> — bytes realmente armazenados</li>
+<li><code>tesseras_institutional_pledge_utilization_ratio</code> — razao armazenado/prometido</li>
+<li><code>tesseras_institutional_peers_served</code> — peers unicos que receberam fragmentos</li>
+<li><code>tesseras_institutional_search_index_total</code> — tesseras no indice de busca</li>
+<li><code>tesseras_institutional_search_queries_total</code> — consultas de busca recebidas</li>
+<li><code>tesseras_institutional_dns_verification_status</code> — 1 se verificado por DNS, 0
+caso contrario</li>
+<li><code>tesseras_institutional_dns_verification_last</code> — timestamp Unix da ultima
+verificacao</li>
+</ul>
+<p><strong>Testes de integracao</strong> — Dois testes em
+<code>tesseras-replication/tests/integration.rs</code>:</p>
+<ul>
+<li><code>institutional_peer_bypasses_reciprocity</code> — verifica que um peer institucional
+com deficit massivo (-999.999 de saldo) ainda pode armazenar fragmentos,
+enquanto um peer nao institucional com o mesmo deficit e rejeitado</li>
+<li><code>institutional_node_accepts_fragment_despite_deficit</code> — teste async completo
+usando <code>ReplicationService</code> com DHT, fragment store, reciprocity ledger e blob
+store mockados: envia um fragmento de um remetente institucional e verifica
+que e aceito</li>
+</ul>
+<p>322 testes passam em todo o workspace. Clippy limpo com <code>-D warnings</code>.</p>
+<h2 id="decisoes-de-arquitetura">Decisoes de arquitetura</h2>
+<ul>
+<li><strong>DNS TXT ao inves de PKI ou blockchain</strong>: DNS e universalmente implantado,
+universalmente compreendido e ja usado para verificacao de dominio (SPF, DKIM,
+Let's Encrypt). Instituicoes ja gerenciam DNS. Nenhuma autoridade
+certificadora, nenhum token, nenhuma transacao on-chain — apenas um registro
+TXT. Se uma instituicao perder controle de seu dominio, a verificacao
+naturalmente falha na proxima checagem.</li>
+<li><strong>Degradacao graciosa em falha DNS</strong>: se a verificacao DNS falha na
+inicializacao, o daemon faz downgrade para um no completo normal ao inves de
+recusar iniciar. Isso previne incidentes operacionais — uma misconfiguracao
+DNS nao deveria tirar um no do ar.</li>
+<li><strong>Limite de diversidade em <code>ceil(r / 3.5)</code></strong>: com <code>r=7</code>, no maximo 2 replicas
+vao para instituicoes. Isso e conservador — garante que a rede nunca dependa
+de instituicoes para quorum majoritario, enquanto ainda se beneficia de sua
+capacidade de armazenamento e uptime.</li>
+<li><strong>Codificacao MessagePack nomeada</strong>: trocar de codificacao posicional para
+nomeada adiciona ~15% de overhead por mensagem mas elimina uma classe de bugs
+de serializacao quando campos opcionais estao presentes. O DHT nao e limitado
+por largura de banda no nivel de mensagem, entao o tradeoff vale a pena.</li>
+<li><strong>Isencao de reciprocidade ao inves de concessao de creditos</strong>: ao inves de
+dar as instituicoes um saldo inicial grande de creditos (que e arbitrario e
+precisa de ajuste), isentamos completamente. Sua identidade verificada por DNS
+e compromisso publico de armazenamento substituem o mecanismo de reciprocidade
+bilateral.</li>
+<li><strong>FTS5 + R-tree no SQLite</strong>: busca full-text e indexacao espacial sao
+embutidas no SQLite como extensoes carregaveis. Nenhum motor de busca externo
+(Elasticsearch, Meilisearch) necessario. Isso mantem o deploy como um unico
+binario com um unico arquivo de banco de dados — critico para operadores
+institucionais que podem nao ter uma equipe de DevOps.</li>
+</ul>
+<h2 id="o-que-vem-a-seguir">O que vem a seguir</h2>
+<ul>
+<li><strong>Fase 4 continuacao</strong> — deduplicacao de armazenamento (armazenamento
+enderecavel por conteudo com BLAKE3), auditorias de seguranca, empacotamento
+para OS (Alpine, Arch, Debian, OpenBSD, FreeBSD)</li>
+<li><strong>Fase 5: Exploracao e Cultura</strong> — navegador publico de tesseras por
+era/localizacao/tema/idioma, curadoria institucional, integracao genealogica
+(FamilySearch, Ancestry), exportacao para midia fisica (M-DISC, microfilme,
+papel livre de acido com QR), contexto assistido por IA</li>
+</ul>
+<p>O onboarding institucional fecha uma lacuna critica no modelo de preservacao do
+Tesseras. Nos individuais fornecem resiliencia de base — milhares de
+dispositivos ao redor do globo, cada um armazenando alguns fragmentos. Nos
+institucionais fornecem ancoragem — organizacoes com infraestrutura
+profissional, armazenamento redundante e horizontes operacionais de multiplas
+decadas. Juntos, formam uma rede onde memorias podem sobreviver tanto a
+dispositivos individuais quanto a instituicoes individuais.</p>
+
+
+
+
+ Fase 4: Tuning de Performance
+ 2026-02-15T20:00:00+00:00
+ 2026-02-15T20:00:00+00:00
+
+
+
+
+ Unknown
+
+
+
+
+
+ https://tesseras.net/pt-br/news/phase4-performance-tuning/
+
+ <p>Uma rede P2P que atravessa NATs mas engasga com seu proprio I/O nao serve de
+muito. A Fase 4 continua com tuning de performance: centralizacao da
+configuracao do banco de dados, cache de blobs de fragmentos em memoria,
+gerenciamento de ciclo de vida de conexoes QUIC e eliminacao de leituras
+desnecessarias de disco no hot path de atestacao.</p>
+<p>O principio orientador foi o mesmo do resto do Tesseras: fazer a coisa mais
+simples que realmente funciona. Sem alocadores customizados, sem estruturas de
+dados lock-free, sem complexidade prematura. Um <code>StorageConfig</code> centralizado, um
+cache LRU, um reaper de conexoes e uma correcao pontual para evitar reler blobs
+que ja tinham checksum calculado.</p>
+<h2 id="o-que-foi-construido">O que foi construido</h2>
+<p><strong>Configuracao SQLite centralizada</strong> (<code>tesseras-storage/src/database.rs</code>) — Um
+novo struct <code>StorageConfig</code> e funcoes <code>open_database()</code> / <code>open_in_memory()</code> que
+aplicam todos os pragmas SQLite em um unico lugar: journal mode WAL, foreign
+keys, modo synchronous (NORMAL por padrao, FULL para hardware instavel como
+RPi + cartao SD), busy timeout, tamanho do cache de paginas e intervalo de
+autocheckpoint WAL. Anteriormente, cada ponto de chamada abria uma conexao e
+aplicava pragmas ad hoc. Agora o daemon, CLI e testes passam todos pelo mesmo
+caminho. 7 testes cobrindo foreign keys, busy timeout, journal mode, migracoes,
+modos synchronous e criacao de arquivos WAL em disco.</p>
+<p><strong>Cache LRU de fragmentos</strong> (<code>tesseras-storage/src/cache.rs</code>) — Um
+<code>CachedFragmentStore</code> que envolve qualquer <code>FragmentStore</code> com um cache LRU
+ciente de bytes. Blobs de fragmentos sao cacheados na leitura e invalidados na
+escrita ou exclusao. Quando o cache excede seu limite de bytes configurado, as
+entradas menos recentemente usadas sao removidas. O cache e transparente: ele
+proprio implementa <code>FragmentStore</code>, entao o resto da pilha nao sabe que esta la.
+Metricas Prometheus opcionais rastreiam hits, misses e uso atual de bytes. 3
+testes: hit no cache evita leitura interna, store invalida cache, remocao quando
+excede bytes maximos.</p>
+<p><strong>Metricas Prometheus de storage</strong> (<code>tesseras-storage/src/metrics.rs</code>) — Um
+struct <code>StorageMetrics</code> com tres contadores/gauges: <code>fragment_cache_hits</code>,
+<code>fragment_cache_misses</code> e <code>fragment_cache_bytes</code>. Registrado no registry
+Prometheus e conectado ao cache de fragmentos via <code>with_metrics()</code>.</p>
+<p><strong>Correcao do hot path de atestacao</strong> (<code>tesseras-replication/src/service.rs</code>) —
+O fluxo de atestacao anteriormente lia cada blob de fragmento do disco e
+recalculava seu checksum BLAKE3. Como <code>list_fragments()</code> ja retorna <code>FragmentId</code>
+com um checksum armazenado, a correcao e trivial: usar <code>frag.checksum</code> ao inves
+de <code>blake3::hash(&data)</code>. Isso elimina uma leitura de disco por fragmento
+durante atestacao — para uma tessera com 100 fragmentos, sao 100 leituras a
+menos. Um teste com <code>expect_read_fragment().never()</code> verifica que nenhuma
+leitura de blob acontece durante atestacao.</p>
+<p><strong>Ciclo de vida do pool de conexoes QUIC</strong>
+(<code>tesseras-net/src/quinn_transport.rs</code>) — Um struct <code>PoolConfig</code> controlando
+maximo de conexoes, timeout de inatividade e intervalo do reaper.
+<code>PooledConnection</code> envolve cada <code>quinn::Connection</code> com um timestamp
+<code>last_used</code>. Quando o pool atinge capacidade maxima, a conexao inativa mais
+antiga e removida antes de abrir uma nova. Uma tarefa reaper em background
+(Tokio spawn) periodicamente fecha conexoes que ficaram inativas alem do
+timeout. 4 novas metricas de pool: <code>tesseras_conn_pool_size</code>, <code>pool_hits_total</code>,
+<code>pool_misses_total</code>, <code>pool_evictions_total</code>.</p>
+<p><strong>Integracao no daemon</strong> (<code>tesd/src/config.rs</code>, <code>main.rs</code>) — Uma nova secao
+<code>[performance]</code> na configuracao TOML com campos para tamanho de cache SQLite,
+modo synchronous, busy timeout, tamanho de cache de fragmentos, maximo de
+conexoes, timeout de inatividade e intervalo do reaper. O <code>main()</code> do daemon
+agora chama <code>open_database()</code> com o <code>StorageConfig</code> configurado, envolve
+<code>FsFragmentStore</code> com <code>CachedFragmentStore</code> e vincula QUIC com o <code>PoolConfig</code>
+configurado. A dependencia direta de <code>rusqlite</code> foi removida do crate do daemon.</p>
+<p><strong>Migracao do CLI</strong> (<code>tesseras-cli/src/commands/init.rs</code>, <code>create.rs</code>) — Ambos
+os comandos <code>init</code> e <code>create</code> agora usam <code>tesseras_storage::open_database()</code> com
+o <code>StorageConfig</code> padrao ao inves de abrir conexoes <code>rusqlite</code> diretamente. A
+dependencia de <code>rusqlite</code> foi removida do crate do CLI.</p>
+<h2 id="decisoes-de-arquitetura">Decisoes de arquitetura</h2>
+<ul>
+<li><strong>Padrao decorator para cache</strong>: <code>CachedFragmentStore</code> envolve
+<code>Box<dyn FragmentStore></code> e implementa <code>FragmentStore</code> ele proprio. Isso
+significa que cache e opt-in, composavel e invisivel para consumidores. O
+daemon habilita; testes podem pular.</li>
+<li><strong>Remocao ciente de bytes</strong>: o cache LRU rastreia bytes totais, nao contagem
+de entradas. Blobs de fragmentos variam muito em tamanho (um fragmento de
+texto de 4KB vs um shard de foto de 2MB), entao contar entradas daria uma
+visao enganosa do uso de memoria.</li>
+<li><strong>Sem crate de pool de conexoes</strong>: ao inves de trazer uma biblioteca generica
+de pool, o pool de conexoes e um wrapper fino sobre
+<code>DashMap<SocketAddr, PooledConnection></code> com um reaper Tokio. Conexoes QUIC sao
+multiplexadas, entao o "pool" e realmente sobre gerenciamento de ciclo de vida
+(limpeza de inativos, maximo de conexoes) e nao sobre emprestar/devolver.</li>
+<li><strong>Checksums armazenados ao inves de releituras</strong>: a correcao de atestacao e
+intencionalmente minima — uma linha alterada, uma leitura de disco removida
+por fragmento. Os checksums ja estavam armazenados no SQLite por
+<code>store_fragment()</code>, apenas nao estavam sendo usados.</li>
+<li><strong>Configuracao centralizada de pragmas</strong>: um unico struct <code>StorageConfig</code>
+substitui chamadas <code>PRAGMA</code> espalhadas. O flag <code>sqlite_synchronous_full</code>
+existe especificamente para implantacoes em Raspberry Pi onde o kernel pode
+crashar e perder transacoes WAL nao checkpointadas.</li>
+</ul>
+<h2 id="o-que-vem-a-seguir">O que vem a seguir</h2>
+<ul>
+<li><strong>Fase 4 continuacao</strong> — Shamir's Secret Sharing para herdeiros, tesseras
+seladas (criptografia time-lock), auditorias de seguranca, onboarding de nos
+institucionais, deduplicacao de storage, empacotamento para OS</li>
+<li><strong>Fase 5: Exploracao e Cultura</strong> — navegador publico de tesseras por
+era/localizacao/tema/idioma, curadoria institucional, integracao genealogica,
+exportacao para midia fisica (M-DISC, microfilme, papel livre de acido com QR)</li>
+</ul>
+<p>Com tuning de performance implementado, Tesseras lida com o caso comum de forma
+eficiente: leituras de fragmentos acertam o cache LRU, atestacao pula I/O de
+disco, conexoes QUIC inativas sao removidas automaticamente e o SQLite e
+configurado consistentemente em toda a pilha. Os proximos passos focam em
+funcionalidades criptograficas (Shamir, time-lock) e hardening para implantacao
+em producao.</p>
+
+
+
+
+ Fase 4: Verificar Sem Instalar Nada
+ 2026-02-15T20:00:00+00:00
+ 2026-02-15T20:00:00+00:00
+
+
+
+
+ Unknown
+
+
+
+
+
+ https://tesseras.net/pt-br/news/phase4-wasm-browser-verification/
+
+ <p>Confiança não deveria exigir instalação de software. Se alguém te envia uma
+tessera — um pacote de memórias preservadas — você deveria poder verificar que é
+genuína e não foi modificada sem baixar um app, criar uma conta, ou confiar em
+um servidor. É isso que o <code>tesseras-wasm</code> entrega: arraste um arquivo tessera
+para uma página web, e a verificação criptográfica acontece inteiramente no seu
+navegador.</p>
+<h2 id="o-que-foi-construido">O que foi construído</h2>
+<p><strong>tesseras-wasm</strong> — Um crate Rust que compila para WebAssembly via wasm-pack,
+expondo quatro funções stateless para JavaScript. O crate depende do
+<code>tesseras-core</code> para parsing do manifesto e chama primitivas criptográficas
+diretamente (blake3, ed25519-dalek) ao invés de depender do <code>tesseras-crypto</code>,
+que puxa bibliotecas pós-quânticas baseadas em C que não compilam para
+<code>wasm32-unknown-unknown</code>.</p>
+<p><code>parse_manifest</code> recebe os bytes brutos do MANIFEST (texto UTF-8 plano, não
+MessagePack), delega para <code>tesseras_core::manifest::Manifest::parse()</code>, e
+retorna uma string JSON com a chave pública Ed25519 do criador, caminhos dos
+arquivos de assinatura, e uma lista de arquivos com seus hashes BLAKE3
+esperados, tamanhos e tipos MIME. Structs internas (<code>ManifestJson</code>,
+<code>CreatorPubkey</code>, <code>SignatureFiles</code>, <code>FileEntry</code>) são serializadas com serde_json.
+Os campos de chave pública ML-DSA e arquivo de assinatura estão presentes no
+contrato JSON mas definidos como <code>null</code> — prontos para quando a assinatura
+pós-quântica for implementada no lado nativo.</p>
+<p><code>hash_blake3</code> computa um hash BLAKE3 de bytes arbitrários e retorna uma string
+hexadecimal de 64 caracteres. É chamada uma vez por arquivo na tessera para
+verificar integridade contra o MANIFEST.</p>
+<p><code>verify_ed25519</code> recebe uma mensagem, uma assinatura de 64 bytes e uma chave
+pública de 32 bytes, constrói uma <code>ed25519_dalek::VerifyingKey</code>, e retorna se a
+assinatura é válida. A validação de comprimento retorna erros descritivos
+("Ed25519 public key must be 32 bytes") ao invés de causar panic.</p>
+<p><code>verify_ml_dsa</code> é um stub que retorna um erro explicando que verificação ML-DSA
+ainda não está disponível. Isso é deliberado: o crate <code>ml-dsa</code> no crates.io está
+na v0.1.0-rc.7 (pré-release), e o <code>tesseras-crypto</code> usa <code>pqcrypto-dilithium</code>
+(CRYSTALS-Dilithium baseado em C) que é incompatível em nível de bytes com FIPS
+204 ML-DSA. Ambos os lados precisam usar a mesma implementação em Rust puro
+antes que a verificação cruzada funcione. Verificação Ed25519 é suficiente —
+toda tessera é assinada com Ed25519.</p>
+<p>Todas as quatro funções usam um padrão de duas camadas para testabilidade:
+funções internas retornam <code>Result<T, String></code> e são testadas nativamente,
+enquanto wrappers finos <code>#[wasm_bindgen]</code> convertem erros para <code>JsError</code>. Isso
+evita que <code>JsError::new()</code> cause panic em targets não-WASM durante os testes.</p>
+<p>O binário WASM compilado tem 109 KB bruto e 44 KB com gzip — bem abaixo do
+orçamento de 200 KB. O wasm-opt aplica otimização <code>-Oz</code> após o wasm-pack
+compilar com <code>opt-level = "z"</code>, LTO e uma única unidade de codegen.</p>
+<p><strong>@tesseras/verify</strong> — Um pacote npm TypeScript (<code>crates/tesseras-wasm/js/</code>) que
+orquestra a verificação no lado do navegador. A API pública é uma única função:</p>
+<pre><code data-lang="typescript">async function verifyTessera(
+ archive: Uint8Array,
+ onProgress?: (current: number, total: number, file: string) => void
+): Promise<VerificationResult>
+</code></pre>
+<p>O tipo <code>VerificationResult</code> fornece tudo que uma UI precisa: validade geral,
+hash da tessera, chaves públicas do criador, status das assinaturas
+(valid/invalid/missing para Ed25519 e ML-DSA), resultados de integridade por
+arquivo com hashes esperados e reais, uma lista de arquivos inesperados não
+presentes no MANIFEST, e um array de erros.</p>
+<p>A descompactação de arquivos (<code>unpack.ts</code>) lida com três formatos: tar
+comprimido com gzip (detectado pelos magic bytes <code>\x1f\x8b</code>, descomprimido com
+fflate e depois parseado como tar), ZIP (magic <code>PK\x03\x04</code>, descompactado com
+<code>unzipSync</code> do fflate), e tar bruto (<code>ustar</code> no offset 257). Uma função
+<code>normalizePath</code> remove o prefixo <code>tessera-<hash>/</code> para que os caminhos internos
+correspondam às entradas do MANIFEST.</p>
+<p>A verificação roda em um Web Worker (<code>worker.ts</code>) para manter a thread da UI
+responsiva. O worker inicializa o módulo WASM, descompacta o arquivo, parseia o
+MANIFEST, verifica a assinatura Ed25519 contra a chave pública do criador,
+depois faz hash de cada arquivo com BLAKE3 e compara com os valores esperados.
+Mensagens de progresso são transmitidas de volta para a thread principal após
+cada arquivo. Se qualquer assinatura é inválida, a verificação para
+imediatamente sem fazer hash dos arquivos — falhando rápido na verificação mais
+crítica.</p>
+<p>O arquivo é transferido para o worker com zero-copy
+(<code>worker.postMessage({ type: "verify", archive }, [archive.buffer])</code>) para
+evitar duplicar arquivos de tessera potencialmente grandes na memória.</p>
+<p><strong>Pipeline de build</strong> — Três novos targets no justfile: <code>wasm-build</code> executa
+wasm-pack com <code>--target web --release</code> e otimiza com wasm-opt; <code>wasm-size</code>
+reporta o tamanho do binário bruto e com gzip; <code>test-wasm</code> executa a suíte de
+testes nativos.</p>
+<p><strong>Testes</strong> — 9 testes unitários nativos cobrem hashing BLAKE3 (entrada vazia,
+valor conhecido), verificação Ed25519 (assinatura válida, assinatura inválida,
+chave errada, comprimento de chave inválido), e parsing do MANIFEST (manifesto
+válido, UTF-8 inválido, lixo). 3 testes de integração WASM rodam em Chrome
+headless via <code>wasm-pack test --headless --chrome</code>, verificando que
+<code>hash_blake3</code>, <code>verify_ed25519</code> e <code>parse_manifest</code> funcionam corretamente quando
+compilados para <code>wasm32-unknown-unknown</code>.</p>
+<h2 id="decisoes-de-arquitetura">Decisões de arquitetura</h2>
+<ul>
+<li><strong>Sem dependência do tesseras-crypto</strong>: o crate WASM chama blake3 e
+ed25519-dalek diretamente. O <code>tesseras-crypto</code> depende do <code>pqcrypto-kyber</code>
+(ML-KEM baseado em C via pqcrypto-traits) que requer um toolchain de
+compilador C e não tem target wasm32. Dependendo apenas de crates Rust puros,
+o build WASM tem zero dependências C e compila sem problemas para WebAssembly.</li>
+<li><strong>ML-DSA adiado, não fingido</strong>: ao invés de silenciosamente pular a
+verificação pós-quântica, o stub retorna um erro explícito. Isso garante que
+se uma tessera contiver uma assinatura ML-DSA, o resultado da verificação
+reportará <code>ml_dsa: "missing"</code> ao invés de fingir que foi verificada. O
+orquestrador JS lida com isso graciosamente — uma tessera é válida se Ed25519
+passar e ML-DSA estiver ausente (ainda não implementado em nenhum dos lados).</li>
+<li><strong>Padrão de função interna</strong>: <code>JsError</code> não pode ser construído em targets
+não-WASM (causa panic). Dividir cada função em
+<code>foo_inner() -> Result<T, String></code> e <code>foo() -> Result<T, JsError></code> permite que
+a suíte de testes nativa exercite toda a lógica sem tocar em tipos JavaScript.
+Os testes de integração WASM em Chrome headless testam a superfície completa
+do <code>#[wasm_bindgen]</code>.</li>
+<li><strong>Isolamento em Web Worker</strong>: operações criptográficas (especialmente BLAKE3
+sobre arquivos de mídia grandes) podem levar centenas de milissegundos. Rodar
+em um Worker previne travamentos na UI. O protocolo de progresso com streaming
+(<code>{ type: "progress", current, total, file }</code>) permite que a UI mostre uma
+barra de progresso durante a verificação de tesseras com muitos arquivos.</li>
+<li><strong>Transferência zero-copy</strong>: <code>archive.buffer</code> é transferido para o Worker, não
+copiado. Para um arquivo tessera de 50 MB, isso evita dobrar o uso de memória
+durante a verificação.</li>
+<li><strong>MANIFEST em texto plano, não MessagePack</strong>: o crate WASM parseia o mesmo
+formato de MANIFEST em texto plano que o CLI. Isso é por design — o MANIFEST é
+a Pedra de Rosetta da tessera, legível por qualquer pessoa com um editor de
+texto. A dependência <code>rmp-serde</code> no Cargo.toml não é usada e será removida.</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> — Empacotamento para sistemas operacionais
+(Alpine, Arch, Debian, FreeBSD, OpenBSD), CI no SourceHut e GitHub Actions,
+auditorias de segurança, explorador de tesseras no navegador em tesseras.net
+usando @tesseras/verify</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 verificação não exige mais confiança em software. Um arquivo tessera arrastado
+para um navegador é verificado com o mesmo rigor criptográfico do CLI — mesmos
+hashes BLAKE3, mesmas assinaturas Ed25519, mesmo parser de MANIFEST. A diferença
+é que agora qualquer pessoa pode fazer isso.</p>
+
+
+
+
+ Fase 4: Furando NATs
+ 2026-02-15T18:00:00+00:00
+ 2026-02-15T18:00:00+00:00
+
+
+
+
+ Unknown
+
+
+
+
+
+ https://tesseras.net/pt-br/news/phase4-nat-traversal/
+
+ <p>A maioria dos dispositivos das pessoas ficam atras de um NAT — um tradutor de
+enderecos de rede que permite acessar a internet mas impede conexoes de entrada.
+Para uma rede P2P, isso e um problema existencial: se dois nos atras de NATs nao
+conseguem se comunicar, a rede se fragmenta. A Fase 4 continua com uma pilha
+completa de travessia de NAT: descoberta via STUN, hole punching coordenado e
+fallback por relay.</p>
+<p>A abordagem segue o mesmo padrao da maioria dos sistemas P2P consolidados
+(WebRTC, BitTorrent, IPFS): tente a opcao mais barata primeiro, escale apenas
+quando necessario. Conectividade direta nao custa nada. Hole punching custa
+alguns pacotes coordenados. Relay custa largura de banda sustentada de um
+terceiro. Tesseras tenta nessa ordem.</p>
+<h2 id="o-que-foi-construido">O que foi construido</h2>
+<p><strong>Classificacao NatType</strong> (<code>tesseras-core/src/network.rs</code>) — Um novo enum
+<code>NatType</code> (Public, Cone, Symmetric, Unknown) adicionado a camada de dominio
+core. Esse tipo e compartilhado por toda a pilha: o cliente STUN o escreve, o
+DHT o divulga em mensagens Pong, e o coordenador de punch o le para decidir se
+hole punching vale a pena tentar (Cone-para-Cone funciona ~80% das vezes;
+Symmetric-para-Symmetric quase nunca funciona).</p>
+<p><strong>Cliente STUN</strong> (<code>tesseras-net/src/stun.rs</code>) — Uma implementacao STUN minima
+(RFC 5389 Binding Request/Response) que descobre o endereco externo de um no. O
+codec codifica requisicoes de 20 bytes com um ID de transacao aleatorio e
+decodifica respostas XOR-MAPPED-ADDRESS. A funcao <code>discover_nat()</code> consulta
+multiplos servidores STUN em paralelo (Google, Cloudflare por padrao), compara
+os enderecos mapeados e classifica o tipo de NAT:</p>
+<ul>
+<li>Mesmo IP e porta de todos os servidores → <strong>Public</strong> (sem NAT)</li>
+<li>Mesmo endereco mapeado de todos os servidores → <strong>Cone</strong> (hole punching
+funciona)</li>
+<li>Enderecos mapeados diferentes → <strong>Symmetric</strong> (hole punching nao confiavel)</li>
+<li>Sem respostas → <strong>Unknown</strong></li>
+</ul>
+<p>Retentativas com backoff exponencial e timeouts configuraveis. 12 testes
+cobrindo roundtrips de codec, todos os caminhos de classificacao e consultas
+async em loopback.</p>
+<p><strong>Coordenacao de punch assinada</strong> (<code>tesseras-net/src/punch.rs</code>) — Assinatura e
+verificacao Ed25519 para mensagens <code>PunchIntro</code>, <code>RelayRequest</code> e
+<code>RelayMigrate</code>. Cada introducao e assinada pelo iniciador com uma janela de
+timestamp de 30 segundos, prevenindo ataques de reflexao (onde um atacante
+reproduz uma introducao antiga para redirecionar trafego). O formato do payload
+e <code>target || external_addr || timestamp</code> — alterar qualquer campo invalida a
+assinatura. 6 testes unitarios mais 3 testes baseados em propriedades com
+proptest (IDs de no, portas e tokens de sessao arbitrarios).</p>
+<p><strong>Gerenciador de sessoes de relay</strong> (<code>tesseras-net/src/relay.rs</code>) — Gerencia
+sessoes de relay UDP transparente entre nos com NAT. Cada sessao tem um token
+aleatorio de 16 bytes; os nos prefixam seus pacotes com o token, o relay remove
+e encaminha. Funcionalidades:</p>
+<ul>
+<li>Encaminhamento bidirecional (A→R→B e B→R→A)</li>
+<li>Limite de taxa: 256 KB/s para nos reciprocos, 64 KB/s para nao reciprocos</li>
+<li>Duracao maxima de 10 minutos para sessoes bootstrap (nao reciprocas)</li>
+<li>Migracao de endereco: quando o IP de um no muda (Wi-Fi para celular), um
+<code>RelayMigrate</code> assinado atualiza a sessao sem derruba-la</li>
+<li>Limpeza por inatividade com timeout configuravel</li>
+<li>8 testes unitarios mais 2 testes baseados em propriedades</li>
+</ul>
+<p><strong>Extensoes de mensagens DHT</strong> (<code>tesseras-dht/src/message.rs</code>) — Sete novas
+variantes de mensagem adicionadas ao protocolo DHT:</p>
+<table><thead><tr><th>Mensagem</th><th>Proposito</th></tr></thead><tbody>
+<tr><td><code>PunchIntro</code></td><td>"Quero conectar ao no X, aqui esta meu endereco externo assinado"</td></tr>
+<tr><td><code>PunchRequest</code></td><td>O introdutor encaminha a requisicao ao destino</td></tr>
+<tr><td><code>PunchReady</code></td><td>O destino confirma prontidao, envia seu endereco externo</td></tr>
+<tr><td><code>RelayRequest</code></td><td>"Crie uma sessao de relay para o no X"</td></tr>
+<tr><td><code>RelayOffer</code></td><td>O relay responde com seu endereco e token de sessao</td></tr>
+<tr><td><code>RelayClose</code></td><td>Encerrar uma sessao de relay</td></tr>
+<tr><td><code>RelayMigrate</code></td><td>Atualizar sessao apos mudanca de rede</td></tr>
+</tbody></table>
+<p>A mensagem <code>Pong</code> foi estendida com metadados NAT: <code>nat_type</code>,
+<code>relay_slots_available</code> e <code>relay_bandwidth_used_kbps</code>. Todos os novos campos
+usam <code>#[serde(default)]</code> para compatibilidade retroativa — nos antigos ignoram o
+que nao reconhecem, nos novos usam defaults. 9 novos testes de roundtrip de
+serializacao.</p>
+<p><strong>Trait NatHandler e dispatch</strong> (<code>tesseras-dht/src/engine.rs</code>) — Uma nova trait
+async <code>NatHandler</code> (5 metodos) injetada no engine DHT, seguindo o mesmo padrao
+de injecao de dependencia do <code>ReplicationHandler</code> existente. O loop de dispatch
+de mensagens do engine agora roteia todas as mensagens punch/relay para o
+handler. Isso mantem o engine DHT agnóstico ao protocolo enquanto permite que a
+logica de travessia de NAT viva em <code>tesseras-net</code>.</p>
+<p><strong>Tipos de reconexao mobile</strong> (<code>tesseras-embedded/src/reconnect.rs</code>) — Uma
+maquina de estados de reconexao em tres fases para dispositivos moveis:</p>
+<ol>
+<li><strong>QuicMigration</strong> (0-2s) — tenta migracao de conexao QUIC para todos os peers
+ativos</li>
+<li><strong>ReStun</strong> (2-5s) — redescobre endereco externo via STUN</li>
+<li><strong>ReEstablish</strong> (5-10s) — reconecta peers que a migracao nao conseguiu salvar</li>
+</ol>
+<p>Peers sao reconectados em ordem de prioridade: nos bootstrap primeiro, depois
+nos que guardam nossos fragmentos, depois nos cujos fragmentos guardamos, depois
+vizinhos DHT gerais. Uma nova variante de evento <code>NetworkChanged</code> foi adicionada
+ao stream de eventos FFI para que o app Flutter possa mostrar progresso de
+reconexao.</p>
+<p><strong>Configuracao NAT do daemon</strong> (<code>tesd/src/config.rs</code>) — Uma nova secao <code>[nat]</code>
+na configuracao TOML com lista de servidores STUN, toggle de relay, maximo de
+sessoes relay, limites de largura de banda (reciproco vs bootstrap) e timeout de
+inatividade. Todos os campos tem defaults sensiveis; relay e desabilitado por
+padrao.</p>
+<p><strong>Metricas Prometheus</strong> (<code>tesseras-net/src/metrics.rs</code>) — 16 metricas em quatro
+subsistemas:</p>
+<ul>
+<li><strong>STUN</strong>: requisicoes, falhas, histograma de latencia</li>
+<li><strong>Punch</strong>: tentativas/sucessos/falhas (por par de tipo NAT), histograma de
+latencia</li>
+<li><strong>Relay</strong>: sessoes ativas, sessoes totais, bytes encaminhados, timeouts por
+inatividade, hits de rate limit</li>
+<li><strong>Reconexao</strong>: mudancas de rede, tentativas/sucessos por fase, histograma de
+duracao</li>
+</ul>
+<p>6 testes verificando registro, incremento, cardinalidade de labels e deteccao de
+registro duplo.</p>
+<p><strong>Testes de integracao</strong> — Dois testes end-to-end usando <code>MemTransport</code> (rede
+simulada em memoria):</p>
+<ul>
+<li><code>punch_integration.rs</code> — Fluxo completo de hole-punch com 3 nos: A envia
+<code>PunchIntro</code> assinado ao introdutor I, I verifica e encaminha <code>PunchRequest</code> a
+B, B verifica a assinatura original e envia <code>PunchReady</code> de volta, A e B
+trocam mensagens diretamente. Tambem testa que uma assinatura invalida e
+corretamente rejeitada.</li>
+<li><code>relay_integration.rs</code> — Fluxo completo de relay com 3 nos: A solicita relay
+de R, R cria sessao e envia <code>RelayOffer</code> a ambos os peers, A e B trocam
+pacotes prefixados com token atraves de R, A migra para um novo endereco no
+meio da sessao, A fecha a sessao, e o teste verifica que a sessao e encerrada
+e encaminhamento posterior falha.</li>
+</ul>
+<p><strong>Testes de propriedade</strong> — 7 testes baseados em proptest cobrindo: roundtrips
+de assinatura para todos os tres tipos de mensagem assinada (IDs de no, portas e
+tokens arbitrarios), determinismo de classificacao NAT (mesmas entradas sempre
+produzem mesma saida), validade de binding request STUN, unicidade de tokens de
+sessao, e rejeicao de pacotes curtos pelo relay.</p>
+<p><strong>Alvos Justfile</strong> — <code>just test-nat</code> executa todos os testes de travessia NAT em
+<code>tesseras-net</code> e <code>tesseras-dht</code>. <code>just test-chaos</code> e um placeholder para futuros
+testes de caos com Docker Compose e <code>tc netem</code>.</p>
+<h2 id="decisoes-de-arquitetura">Decisoes de arquitetura</h2>
+<ul>
+<li><strong>STUN ao inves de TURN</strong>: implementamos STUN (descoberta) e relay customizado
+ao inves de TURN completo. TURN requer alocacao autenticada e foi projetado
+para relay de midia; nosso relay e mais simples — encaminhamento UDP com
+prefixo de token e limites de taxa. Isso mantem o protocolo minimo e evita
+depender de servidores TURN externos.</li>
+<li><strong>Assinaturas em introducoes</strong>: cada <code>PunchIntro</code> e assinado pelo iniciador.
+Sem isso, um atacante poderia enviar introducoes forjadas para redirecionar as
+tentativas de hole-punch de um no para um endereco controlado pelo atacante
+(ataque de reflexao). A janela de timestamp de 30 segundos limita replay.</li>
+<li><strong>Tiers reciprocos de largura de banda</strong>: nos relay dao 4x mais largura de
+banda (256 vs 64 KB/s) para peers com boas pontuacoes de reciprocidade. Isso
+incentiva nos a armazenar fragmentos para outros — se voce contribui, recebe
+melhor servico de relay quando precisa.</li>
+<li><strong>Extensao Pong retrocompativel</strong>: novos campos NAT em <code>Pong</code> usam
+<code>#[serde(default)]</code> e <code>Option<T></code>. Nos antigos que nao entendem esses campos
+simplesmente os pulam durante deserializacao. Nenhum bump de versao de
+protocolo necessario.</li>
+<li><strong>NatHandler como trait async</strong>: a logica de travessia NAT e injetada no
+engine DHT via trait, assim como <code>ReplicationHandler</code>. Isso mantem o engine
+DHT focado em roteamento e gerenciamento de peers, e permite que a
+implementacao NAT seja trocada ou desabilitada sem tocar no codigo core do
+DHT.</li>
+</ul>
+<h2 id="o-que-vem-a-seguir">O que vem a seguir</h2>
+<ul>
+<li><strong>Fase 4 continuacao</strong> — tuning de performance (pooling de conexoes, cache de
+fragmentos, SQLite WAL), auditorias de seguranca, onboarding de nos
+institucionais, empacotamento para OS</li>
+<li><strong>Fase 5: Exploracao e Cultura</strong> — navegador publico de tesseras por
+era/localizacao/tema/idioma, curadoria institucional, integracao genealogica,
+exportacao para midia fisica (M-DISC, microfilme, papel livre de acido com QR)</li>
+</ul>
+<p>Com travessia de NAT, Tesseras pode conectar nos independentemente de sua
+topologia de rede. Nos publicos conversam diretamente. Nos com NAT Cone furam
+com ajuda de um introdutor. Nos com NAT Symmetric ou firewalled usam relay
+atraves de peers voluntarios. A rede se adapta ao mundo real, onde a maioria dos
+dispositivos esta atras de um NAT e as condicoes de rede mudam constantemente.</p>
+
+
+
+
+ CLI Encontra a Rede: Comandos Publish, Fetch e Status
+ 2026-02-15T00:00:00+00:00
+ 2026-02-15T00:00:00+00:00
+
+
+
+
+ Unknown
+
+
+
+
+
+ https://tesseras.net/pt-br/news/cli-daemon-rpc/
+
+ <p>Até agora o CLI operava isoladamente: criar uma tessera, verificar, exportar,
+listar o que você tem. Tudo ficava na sua máquina. Com esta atualização, o <code>tes</code>
+ganha três comandos que fazem a ponte entre o armazenamento local e a rede P2P —
+<code>publish</code>, <code>fetch</code> e <code>status</code> — comunicando-se com um <code>tesd</code> em execução através
+de um socket Unix.</p>
+<h2 id="o-que-foi-construido">O que foi construído</h2>
+<p><strong>Crate <code>tesseras-rpc</code></strong> — Um novo crate compartilhado entre CLI e daemon.
+Define o protocolo RPC usando serialização MessagePack com enquadramento
+prefixado por tamanho (cabeçalho big-endian de 4 bytes, máximo de 64 MiB). Três
+tipos de requisição (<code>Publish</code>, <code>Fetch</code>, <code>Status</code>) e suas respostas
+correspondentes. Um <code>DaemonClient</code> síncrono gerencia a conexão do socket Unix
+com timeouts configuráveis. O protocolo é deliberadamente simples — uma
+requisição, uma resposta, conexão fechada — para manter a implementação
+auditável.</p>
+<p><strong><code>tes publish <hash></code></strong> — Publica uma tessera na rede. Aceita hashes completos
+ou prefixos curtos (ex.: <code>tes publish a1b2</code>), que são resolvidos no banco de
+dados local. O daemon lê todos os arquivos da tessera do armazenamento, empacota
+em um único buffer MessagePack e entrega ao motor de replicação. Tesseras
+pequenas (< 4 MB) são replicadas como um único fragmento; maiores passam por
+codificação de apagamento Reed-Solomon. A saída mostra o hash curto e a contagem
+de fragmentos:</p>
+<pre><code>Published tessera 9f2c4a1b (24 fragments created)
+Distribution in progress — use `tes status 9f2c4a1b` to track.
+</code></pre>
+<p><strong><code>tes fetch <hash></code></strong> — Busca uma tessera da rede usando o hash de conteúdo
+completo. O daemon coleta fragmentos disponíveis localmente, reconstrói os dados
+originais via decodificação de apagamento se necessário, desempacota os arquivos
+e armazena no CAS (content-addressable store). Retorna o número de memórias e o
+tamanho total buscado.</p>
+<p><strong><code>tes status <hash></code></strong> — Exibe a saúde de replicação de uma tessera. A saída
+mapeia diretamente o modelo interno de saúde do motor de replicação:</p>
+<table><thead><tr><th>Estado</th><th>Significado</th></tr></thead><tbody>
+<tr><td>Local</td><td>Ainda não publicada — existe apenas na sua máquina</td></tr>
+<tr><td>Publishing</td><td>Fragmentos sendo distribuídos, redundância crítica</td></tr>
+<tr><td>Replicated</td><td>Distribuída, mas abaixo da redundância alvo</td></tr>
+<tr><td>Healthy</td><td>Redundância completa alcançada</td></tr>
+</tbody></table>
+<p><strong>Listener RPC no daemon</strong> — O daemon agora escuta em um socket Unix (padrão:
+<code>$XDG_RUNTIME_DIR/tesseras/daemon.sock</code>) com permissões de diretório adequadas
+(0700), limpeza de sockets obsoletos e shutdown gracioso. Cada conexão é tratada
+em uma task Tokio — o listener converte o stream assíncrono para I/O síncrono
+para a camada de enquadramento, despacha para o handler RPC e escreve a resposta
+de volta.</p>
+<p><strong>Pack/unpack no <code>tesseras-core</code></strong> — Um módulo pequeno que serializa uma lista
+de entradas de arquivo (caminho + dados) em um único buffer MessagePack e
+vice-versa. Esta é a ponte entre a estrutura de diretórios da tessera e os blobs
+opacos do motor de replicação.</p>
+<h2 id="decisoes-de-arquitetura">Decisões de arquitetura</h2>
+<ul>
+<li><strong>Socket Unix ao invés de TCP</strong>: a comunicação RPC entre CLI e daemon acontece
+na mesma máquina. Sockets Unix são mais rápidos, não precisam de alocação de
+porta, e as permissões do sistema de arquivos fornecem controle de acesso sem
+TLS.</li>
+<li><strong>MessagePack ao invés de JSON</strong>: o mesmo formato wire usado em todo o
+Tesseras. Compacto, sem schema, e já é uma dependência do workspace. Uma
+ida-e-volta típica de publish request/response ocupa menos de 200 bytes.</li>
+<li><strong>Cliente síncrono, daemon assíncrono</strong>: o <code>DaemonClient</code> usa I/O bloqueante
+porque o CLI não precisa de concorrência — envia uma requisição e espera. O
+listener do daemon é assíncrono (Tokio) para tratar múltiplas conexões. A
+camada de enquadramento funciona com qualquer impl <code>Read</code>/<code>Write</code>, conectando
+ambos os mundos.</li>
+<li><strong>Resolução de prefixo no lado do cliente</strong>: <code>publish</code> e <code>status</code> resolvem
+prefixos curtos localmente antes de enviar o hash completo ao daemon. Isso
+mantém o daemon stateless — ele não precisa acessar o banco de dados do CLI.</li>
+<li><strong>Alinhamento do diretório de dados padrão</strong>: o padrão do CLI mudou de
+<code>~/.tesseras</code> para <code>~/.local/share/tesseras</code> (via <code>dirs::data_dir()</code>) para
+coincidir com o daemon. Um aviso de migração é exibido quando dados no caminho
+antigo são detectados.</li>
+</ul>
+<h2 id="proximos-passos">Próximos passos</h2>
+<ul>
+<li><strong>Contagem de peers no DHT</strong>: o comando <code>status</code> atualmente reporta 0 peers —
+conectar a contagem real do DHT é o próximo passo</li>
+<li><strong><code>tes show</code></strong>: exibir o conteúdo de uma tessera (memórias, metadados) sem
+exportar</li>
+<li><strong>Fetch com streaming</strong>: para tesseras grandes, transmitir fragmentos conforme
+chegam ao invés de esperar por todos</li>
+</ul>
+
+
+
+
+ Fase 4: Recuperação de Chaves por Herdeiros com Shamir's Secret Sharing
+ 2026-02-15T00:00:00+00:00
+ 2026-02-15T00:00:00+00:00
+
+
+
+
+ Unknown
+
+
+
+
+
+ https://tesseras.net/pt-br/news/phase4-shamir-heir-recovery/
+
+ <p>O que acontece com suas memórias quando você morre? Até agora, Tesseras
+conseguia preservar conteúdo ao longo de milênios — mas as chaves privadas e
+seladas morriam com o dono. A Fase 4 continua com uma solução: Shamir's Secret
+Sharing, um esquema criptográfico que permite dividir sua identidade em
+fragmentos e distribuí-los para as pessoas em quem você mais confia.</p>
+<p>A matemática é elegante: você escolhe um limiar T e um total N. Qualquer T
+fragmentos reconstroem o segredo completo; T-1 fragmentos não revelam
+absolutamente nada. Isso não é "quase nada" — é informação-teoricamente seguro.
+Um atacante com um fragmento a menos que o limiar tem exatamente zero bits de
+informação sobre o segredo, independentemente do poder computacional que tenha.</p>
+<h2 id="o-que-foi-construido">O que foi construído</h2>
+<p><strong>Aritmética de corpo finito GF(256)</strong> (<code>tesseras-crypto/src/shamir/gf256.rs</code>) —
+Shamir's Secret Sharing requer aritmética em um corpo finito. Implementamos
+GF(256) usando o mesmo polinômio irredutível do AES (x^8 + x^4 + x^3 + x + 1),
+com tabelas de lookup para logaritmo e exponenciação computadas em tempo de
+compilação. Todas as operações são em tempo constante via consulta a tabelas —
+sem ramificações baseadas em dados secretos. O módulo inclui o método de Horner
+para avaliação de polinômios e interpolação de Lagrange em x=0 para recuperação
+do segredo. 233 linhas, exaustivamente testado: todos os 256 elementos para
+propriedades de identidade/inverso, comutatividade e associatividade.</p>
+<p><strong>ShamirSplitter</strong> (<code>tesseras-crypto/src/shamir/mod.rs</code>) — A API principal de
+split/reconstruct. <code>split()</code> recebe uma fatia de bytes do segredo, uma
+configuração (limiar T, total N) e a chave pública Ed25519 do dono. Para cada
+byte do segredo, constrói um polinômio aleatório de grau T-1 sobre GF(256) com o
+byte do segredo como termo constante, e então o avalia em N pontos distintos.
+<code>reconstruct()</code> recebe T ou mais fragmentos e recupera o segredo via
+interpolação de Lagrange. Ambas as operações incluem validação extensiva:
+limites do limiar, consistência de sessão, correspondência de impressão digital
+do dono e verificação de checksum BLAKE3.</p>
+<p><strong>Formato HeirShare</strong> — Cada fragmento é um artefato autocontido e serializável
+com:</p>
+<ul>
+<li>Versão do formato (v1) para compatibilidade futura</li>
+<li>Índice do fragmento (1..N) e metadados de limiar/total</li>
+<li>ID de sessão (8 bytes aleatórios) — impede mistura de fragmentos de sessões
+diferentes</li>
+<li>Impressão digital do dono (primeiros 8 bytes do hash BLAKE3 da chave pública
+Ed25519)</li>
+<li>Dados do fragmento (os y-values de Shamir, mesmo comprimento do segredo)</li>
+<li>Checksum BLAKE3 sobre todos os campos anteriores</li>
+</ul>
+<p>Os fragmentos são serializados em dois formatos: <strong>MessagePack</strong> (binário
+compacto, para uso programático) e <strong>texto base64</strong> (legível por humanos, para
+impressão e armazenamento físico). O formato texto inclui um cabeçalho com
+metadados e delimitadores:</p>
+<pre><code>--- TESSERAS HEIR SHARE ---
+Format: v1
+Owner: a1b2c3d4e5f6a7b8 (fingerprint)
+Share: 1 of 3 (threshold: 2)
+Session: 9f8e7d6c5b4a3210
+Created: 2026-02-15
+
+<dados MessagePack codificados em base64>
+--- END HEIR SHARE ---
+</code></pre>
+<p>Este formato é projetado para ser impresso em papel, armazenado em um cofre
+bancário ou gravado em metal. O cabeçalho é informacional — apenas o payload
+base64 é analisado durante a reconstrução.</p>
+<p><strong>Integração com CLI</strong> (<code>tesseras-cli/src/commands/heir.rs</code>) — Três novos
+subcomandos:</p>
+<ul>
+<li><code>tes heir create</code> — divide sua identidade Ed25519 em fragmentos de herdeiros.
+Solicita confirmação (sua identidade completa está em jogo), gera arquivos
+<code>.bin</code> e <code>.txt</code> para cada fragmento e escreve <code>heir_meta.json</code> no diretório de
+identidade.</li>
+<li><code>tes heir reconstruct</code> — carrega arquivos de fragmentos (detecta
+automaticamente formato binário vs texto), valida consistência, reconstrói o
+segredo, deriva o par de chaves Ed25519 e opcionalmente o instala em
+<code>~/.tesseras/identity/</code> (com backup automático da identidade existente).</li>
+<li><code>tes heir info</code> — exibe metadados do fragmento e verifica o checksum sem expor
+nenhum material secreto.</li>
+</ul>
+<p><strong>Formato do blob secreto</strong> — As chaves de identidade são serializadas em um
+blob versionado antes da divisão: um byte de versão (0x01), um byte de flags
+(0x00 para somente Ed25519), seguido da chave secreta Ed25519 de 32 bytes. Isso
+deixa espaço para expansão futura quando as chaves privadas X25519 e ML-KEM-768
+forem integradas ao sistema de fragmentos de herdeiros.</p>
+<p><strong>Testes</strong> — 20 testes unitários para ShamirSplitter (roundtrip, todas as
+combinações de fragmentos, fragmentos insuficientes, dono errado, sessão errada,
+limite threshold-1, segredos grandes até o tamanho de chave ML-KEM-768). 7
+testes unitários para aritmética GF(256) (propriedades de campo exaustivas). 3
+testes baseados em propriedades com proptest (segredos arbitrários até 5000
+bytes, configurações T-de-N arbitrárias, verificação de segurança
+informação-teórica). Testes de roundtrip de serialização para ambos os formatos
+MessagePack e texto base64. 2 testes de integração cobrindo o ciclo de vida
+completo de herdeiros: gerar identidade, dividir em fragmentos, serializar,
+desserializar, reconstruir, verificar par de chaves e assinar/verificar com
+chaves reconstruídas.</p>
+<h2 id="decisoes-de-arquitetura">Decisões de arquitetura</h2>
+<ul>
+<li><strong>GF(256) ao invés de GF(primo)</strong>: usamos GF(256) ao invés de um corpo primo
+porque ele mapeia naturalmente para bytes — cada elemento é um único byte,
+cada fragmento tem o mesmo comprimento do segredo. Sem aritmética de inteiros
+grandes, sem redução modular, sem padding. Esta é a mesma abordagem usada pela
+maioria das implementações reais de Shamir, incluindo SSSS e Hashicorp Vault.</li>
+<li><strong>Tabelas de lookup em tempo de compilação</strong>: as tabelas LOG e EXP para
+GF(256) são computadas em tempo de compilação usando <code>const fn</code>. Isso
+significa zero custo de inicialização em tempo de execução e operações em
+tempo constante via consulta a tabelas ao invés de loops.</li>
+<li><strong>ID de sessão previne mistura entre sessões</strong>: cada chamada a <code>split()</code> gera
+um novo ID de sessão aleatório. Se um herdeiro acidentalmente usar fragmentos
+de duas sessões diferentes de divisão (por exemplo, antes e depois de uma
+rotação de chaves), a reconstrução falha de forma limpa com um erro de
+validação ao invés de produzir dados corrompidos.</li>
+<li><strong>Checksums BLAKE3 detectam corrupção</strong>: cada fragmento inclui um checksum
+BLAKE3 sobre seu conteúdo. Isso captura degradação de bits, erros de
+transmissão e truncamento acidental antes de qualquer tentativa de
+reconstrução. Um fragmento impresso em papel e escaneado via OCR vai falhar no
+checksum se um único caractere estiver errado.</li>
+<li><strong>Impressão digital do dono para identificação</strong>: os fragmentos incluem os
+primeiros 8 bytes de BLAKE3(chave pública Ed25519) como impressão digital.
+Isso permite aos herdeiros verificar a qual identidade um fragmento pertence
+sem revelar a chave pública completa. Durante a reconstrução, a impressão
+digital é verificada contra a chave recuperada.</li>
+<li><strong>Formato duplo para resiliência</strong>: ambos os formatos binário (MessagePack) e
+texto (base64) são gerados porque mídias físicas têm modos de falha diferentes
+de armazenamento digital. Um pendrive pode falhar; papel sobrevive. Um QR code
+pode ficar ilegível; texto base64 pode ser digitado manualmente.</li>
+<li><strong>Versionamento do blob</strong>: o segredo é envolvido em um blob versionado
+(versão + flags + material de chave) para que versões futuras possam incluir
+chaves adicionais (X25519, ML-KEM-768) sem quebrar compatibilidade com
+fragmentos existentes.</li>
+</ul>
+<h2 id="o-que-vem-a-seguir">O que vem a seguir</h2>
+<ul>
+<li><strong>Fase 4 continuada: Resiliência e Escala</strong> — NAT traversal avançado
+(STUN/TURN), ajuste de performance (pool de conexões, cache de fragmentos,
+SQLite WAL), auditorias de segurança, integração de nós institucionais,
+empacotamento para sistemas operacionais</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>Com Shamir's Secret Sharing, Tesseras fecha a última lacuna crítica na
+preservação a longo prazo. Suas memórias sobrevivem a falhas de infraestrutura
+através de erasure coding. Sua privacidade sobrevive a computadores quânticos
+através de criptografia híbrida. E agora, sua identidade sobrevive a você —
+passada adiante para as pessoas que você escolheu, exigindo a cooperação delas
+para desbloquear o que você deixou para trás.</p>
+
+
+
+
+ Fase 4: Criptografia e Tesseras Seladas
+ 2026-02-14T16:00:00+00:00
+ 2026-02-14T16:00:00+00:00
+
+
+
+
+ Unknown
+
+
+
+
+
+ https://tesseras.net/pt-br/news/phase4-encryption-sealed/
+
+ <p>Algumas memórias não são para todos. Um diário privado, uma carta para ser
+aberta em 2050, um segredo de família selado até que os netos tenham idade
+suficiente. Até agora, toda tessera na rede era aberta. A Fase 4 muda isso:
+Tesseras agora criptografa conteúdo privado e selado com um esquema
+criptográfico híbrido projetado para resistir tanto a ataques clássicos quanto
+quânticos.</p>
+<p>O princípio continua o mesmo — criptografar o mínimo possível. Memórias públicas
+precisam de disponibilidade, não de sigilo. Mas quando alguém cria uma tessera
+privada ou selada, o conteúdo agora é trancado por criptografia AES-256-GCM com
+chaves protegidas por um mecanismo híbrido de encapsulamento de chaves
+combinando X25519 e ML-KEM-768. Ambos os algoritmos precisam ser quebrados para
+acessar o conteúdo.</p>
+<h2 id="o-que-foi-construido">O que foi construído</h2>
+<p><strong>Encriptador AES-256-GCM</strong> (<code>tesseras-crypto/src/encryption.rs</code>) — Criptografia
+simétrica de conteúdo com nonces aleatórios de 12 bytes e dados autenticados
+associados (AAD). O AAD vincula o texto cifrado ao seu contexto: para tesseras
+privadas, o hash do conteúdo é incluído; para tesseras seladas, tanto o hash do
+conteúdo quanto o timestamp <code>open_after</code> são vinculados no AAD. Isso significa
+que mover texto cifrado entre tesseras com datas de abertura diferentes causa
+falha na decriptação — você não consegue enganar o sistema para abrir uma
+memória selada antecipadamente trocando o texto cifrado para uma tessera com uma
+data de selo anterior.</p>
+<p><strong>Mecanismo Híbrido de Encapsulamento de Chaves</strong> (<code>tesseras-crypto/src/kem.rs</code>)
+— Troca de chaves usando X25519 (Diffie-Hellman clássico em curva elíptica)
+combinado com ML-KEM-768 (o KEM pós-quântico baseado em reticulados padronizado
+pelo NIST, anteriormente Kyber). Ambos os segredos compartilhados são combinados
+via <code>blake3::derive_key</code> com uma string de contexto fixa ("tesseras hybrid kem
+v1") para produzir uma única chave de criptografia de conteúdo de 256 bits. Isso
+segue a mesma filosofia "dual desde o início" das assinaturas duplas do projeto
+(Ed25519 + ML-DSA): se qualquer algoritmo for quebrado no futuro, o outro ainda
+protege o conteúdo.</p>
+<p><strong>Envelope de Chave Selada</strong> (<code>tesseras-crypto/src/sealed.rs</code>) — Encapsula uma
+chave de criptografia de conteúdo usando o KEM híbrido, para que apenas o dono
+da tessera possa recuperá-la. O KEM produz uma chave de transporte, que é XORed
+com a chave de conteúdo para produzir uma chave encapsulada armazenada junto ao
+texto cifrado do KEM. Ao desselar, o dono decapsula o texto cifrado do KEM para
+recuperar a chave de transporte, depois faz XOR novamente para recuperar a chave
+de conteúdo.</p>
+<p><strong>Publicação de Chave</strong> (<code>tesseras-crypto/src/sealed.rs</code>) — Um artefato assinado
+independente para publicar a chave de conteúdo de uma tessera selada após a data
+<code>open_after</code> ter passado. O dono assina a chave de conteúdo, o hash da tessera e
+o timestamp de publicação com suas chaves duais (Ed25519, com placeholder
+ML-DSA). O manifesto permanece imutável — a publicação da chave é um documento
+separado. Outros nós verificam a assinatura contra a chave pública do dono antes
+de usar a chave publicada para decriptar o conteúdo.</p>
+<p><strong>EncryptionContext</strong> (<code>tesseras-core/src/enums.rs</code>) — Um tipo de domínio que
+representa o contexto AAD para criptografia. Ele vive em tesseras-core e não em
+tesseras-crypto porque é um conceito de domínio (não um detalhe de implementação
+criptográfica). O método <code>to_aad_bytes()</code> produz serialização determinística: um
+byte de tag (0x00 para Private, 0x01 para Sealed), seguido do hash de conteúdo
+e, para Sealed, o timestamp <code>open_after</code> como i64 little-endian.</p>
+<p><strong>Validação de domínio</strong> (<code>tesseras-core/src/service.rs</code>) —
+<code>TesseraService::create()</code> agora rejeita tesseras Sealed e Private que não
+fornecem chaves de criptografia. Esta é uma validação no nível de domínio: a
+camada de serviço garante que você não pode criar uma memória selada sem a
+maquinaria criptográfica para protegê-la. A mensagem de erro é clara: "missing
+encryption keys for visibility sealed until 2050-01-01."</p>
+<p><strong>Atualizações de tipos do core</strong> — <code>TesseraIdentity</code> agora inclui um campo
+opcional <code>encryption_public: Option<HybridEncryptionPublic></code> contendo tanto as
+chaves públicas X25519 quanto ML-KEM-768. <code>KeyAlgorithm</code> ganhou as variantes
+<code>X25519</code> e <code>MlKem768</code>. O layout do sistema de arquivos de identidade agora
+suporta <code>node.x25519.key</code>/<code>.pub</code> e <code>node.mlkem768.key</code>/<code>.pub</code>.</p>
+<p><strong>Testes</strong> — 8 testes unitários para AES-256-GCM (roundtrip, chave errada, texto
+cifrado adulterado, AAD errado, falha de decriptação cross-context, nonces
+únicos, mais 2 testes baseados em propriedades para payloads arbitrários e
+unicidade de nonces). 5 testes unitários para HybridKem (roundtrip, par de
+chaves errado, X25519 adulterado, determinismo do KDF, mais 1 teste baseado em
+propriedades). 4 testes unitários para SealedKeyEnvelope e KeyPublication. 2
+testes de integração cobrindo o ciclo de vida completo de tesseras seladas e
+privadas: gerar chaves, criar chave de conteúdo, criptografar, selar, desselar,
+decriptar, publicar chave e verificar — o ciclo completo.</p>
+<h2 id="decisoes-de-arquitetura">Decisões de arquitetura</h2>
+<ul>
+<li><strong>KEM híbrido desde o início</strong>: X25519 + ML-KEM-768 segue a mesma filosofia
+das assinaturas duplas. Não sabemos quais suposições criptográficas se
+manterão ao longo dos milênios, então combinamos algoritmos clássicos e
+pós-quânticos. O custo é ~1,2 KB de material de chave adicional por identidade
+— trivial comparado às fotos e vídeos em uma tessera.</li>
+<li><strong>BLAKE3 para KDF</strong>: ao invés de adicionar <code>hkdf</code> + <code>sha2</code> como novas
+dependências, usamos <code>blake3::derive_key</code> com uma string de contexto fixa. O
+modo de derivação de chaves do BLAKE3 é especificamente projetado para este
+caso de uso, e o projeto já depende do BLAKE3 para hashing de conteúdo.</li>
+<li><strong>Manifestos imutáveis</strong>: quando a data <code>open_after</code> de uma tessera selada
+passa, a chave de conteúdo é publicada como um artefato assinado separado
+(<code>KeyPublication</code>), não modificando o manifesto. Isso preserva a natureza
+append-only e endereçada por conteúdo das tesseras. O manifesto foi assinado
+no momento da criação e nunca muda.</li>
+<li><strong>Vinculação AAD previne troca de texto cifrado</strong>: o <code>EncryptionContext</code>
+vincula tanto o hash de conteúdo quanto (para tesseras seladas) o timestamp
+<code>open_after</code> nos dados autenticados do AES-GCM. Um atacante que copie conteúdo
+criptografado de uma tessera "selada até 2050" para uma tessera "selada até
+2025" vai descobrir que a decriptação falha — o AAD não corresponde mais.</li>
+<li><strong>Encapsulamento de chave por XOR</strong>: o envelope de chave selada usa um XOR
+simples da chave de conteúdo com a chave de transporte derivada do KEM, ao
+invés de uma camada adicional de AES-GCM. Como a chave de transporte é um
+valor aleatório fresco do KEM e é usada exatamente uma vez, o XOR é
+informação-teoricamente seguro para este caso de uso específico e evita
+complexidade desnecessária.</li>
+<li><strong>Validação de domínio, não validação de storage</strong>: a verificação de "chaves
+de criptografia ausentes" vive em <code>TesseraService::create()</code>, não na camada de
+storage. Isso segue o padrão de arquitetura hexagonal: regras de domínio são
+aplicadas na fronteira de serviço, não espalhadas pelos adaptadores.</li>
+</ul>
+<h2 id="o-que-vem-a-seguir">O que vem a seguir</h2>
+<ul>
+<li><strong>Fase 4 continuada: Resiliência e Escala</strong> — Shamir's Secret Sharing para
+distribuição de chaves de herdeiros, NAT traversal avançado (STUN/TURN),
+ajuste de performance, auditorias de segurança, empacotamento para sistemas
+operacionais</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>Tesseras seladas fazem do Tesseras uma verdadeira cápsula do tempo. Um pai agora
+pode gravar uma mensagem para o neto que ainda não nasceu, selá-la até 2060 e
+saber que o envelope criptográfico vai resistir — mesmo que os computadores
+quânticos do futuro tentem abri-lo antes da hora.</p>
+
+
+
+
+ Fase 3: Memórias nas Suas Mãos
+ 2026-02-14T14:00:00+00:00
+ 2026-02-14T14:00:00+00:00
+
+
+
+
+ Unknown
+
+
+
+
+
+ https://tesseras.net/pt-br/news/phase3-api-and-apps/
+
+ <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>
+
+
+
+
+ Reed-Solomon: Como o Tesseras Sobrevive à Perda de Dados
+ 2026-02-14T14:00:00+00:00
+ 2026-02-14T14:00:00+00:00
+
+
+
+
+ Unknown
+
+
+
+
+
+ https://tesseras.net/pt-br/news/reed-solomon/
+
+ <p>Seu disco rígido vai morrer. Seu provedor de nuvem vai pivotar. O array RAID no
+seu armário vai sobreviver ao controlador, mas não ao dono. Se uma memória está
+armazenada em exatamente um lugar, ela tem exatamente uma forma de se perder
+para sempre.</p>
+<p>Tesseras é uma rede que mantém memórias humanas vivas através de ajuda mútua. O
+mecanismo central de sobrevivência é a <strong>codificação de apagamento
+Reed-Solomon</strong> — uma técnica emprestada da comunicação espacial profunda que nos
+permite reconstruir dados mesmo quando pedaços desaparecem.</p>
+<h2 id="o-que-e-reed-solomon">O que é Reed-Solomon?</h2>
+<p>Reed-Solomon é uma família de códigos corretores de erros inventada por Irving
+Reed e Gustave Solomon em 1960. O caso de uso original era corrigir erros em
+dados transmitidos por canais ruidosos — pense na Voyager enviando fotos de
+Júpiter, ou num CD tocando apesar de arranhões.</p>
+<p>A ideia-chave: se você adicionar redundância cuidadosamente calculada aos seus
+dados <em>antes</em> que algo dê errado, você pode recuperar o original mesmo depois de
+perder alguns pedaços.</p>
+<p>Eis a intuição. Suponha que você tenha um polinômio de grau 2 — uma parábola.
+Você precisa de 3 pontos para defini-lo de forma única. Mas se você avaliá-lo em
+5 pontos, pode perder quaisquer 2 desses 5 e ainda reconstruir o polinômio a
+partir dos 3 restantes. Reed-Solomon generaliza essa ideia para trabalhar sobre
+corpos finitos (corpos de Galois), onde o "polinômio" são seus dados e os
+"pontos de avaliação" são seus fragmentos.</p>
+<p>Em termos concretos:</p>
+<ol>
+<li><strong>Divida</strong> seus dados em <em>k</em> shards de dados</li>
+<li><strong>Calcule</strong> <em>m</em> shards de paridade a partir dos shards de dados</li>
+<li><strong>Distribua</strong> todos os <em>k + m</em> shards em diferentes locais</li>
+<li><strong>Reconstrua</strong> os dados originais a partir de quaisquer <em>k</em> dos <em>k + m</em>
+shards</li>
+</ol>
+<p>Você pode perder até <em>m</em> shards — quaisquer <em>m</em>, de dados ou paridade, em
+qualquer combinação — e ainda recuperar tudo.</p>
+<h2 id="por-que-nao-simplesmente-fazer-copias">Por que não simplesmente fazer cópias?</h2>
+<p>A abordagem ingênua para redundância é a replicação: faça 3 cópias, armazene-as
+em 3 lugares. Isso dá tolerância a 2 falhas ao custo de 3x o seu armazenamento.</p>
+<p>Reed-Solomon é dramaticamente mais eficiente:</p>
+<table><thead><tr><th>Estratégia</th><th style="text-align: right">Overhead de armazenamento</th><th style="text-align: right">Falhas toleradas</th></tr></thead><tbody>
+<tr><td>Replicação 3x</td><td style="text-align: right">200%</td><td style="text-align: right">2 de 3</td></tr>
+<tr><td>Reed-Solomon (16,8)</td><td style="text-align: right">50%</td><td style="text-align: right">8 de 24</td></tr>
+<tr><td>Reed-Solomon (48,24)</td><td style="text-align: right">50%</td><td style="text-align: right">24 de 72</td></tr>
+</tbody></table>
+<p>Com 16 shards de dados e 8 de paridade, você usa 50% de armazenamento extra mas
+pode sobreviver à perda de um terço de todos os fragmentos. Para alcançar a
+mesma tolerância a falhas só com replicação, você precisaria de 3x o
+armazenamento.</p>
+<p>Para uma rede que visa preservar memórias ao longo de décadas e séculos, essa
+eficiência não é um luxo — é a diferença entre um sistema viável e um que se
+afoga no próprio overhead.</p>
+<h2 id="como-o-tesseras-usa-reed-solomon">Como o Tesseras usa Reed-Solomon</h2>
+<p>Nem todos os dados merecem o mesmo tratamento. Uma memória de texto de 500 bytes
+e um vídeo de 100 MB têm necessidades de redundância muito diferentes. O
+Tesseras usa uma estratégia de fragmentação em três camadas:</p>
+<p><strong>Small (< 4 MB)</strong> — Replicação do arquivo inteiro para 7 pares. Para tesseras
+pequenas, o overhead da codificação de apagamento (tempo de codificação,
+gerenciamento de fragmentos, lógica de reconstrução) supera seus benefícios.
+Cópias simples são mais rápidas e mais simples.</p>
+<p><strong>Medium (4–256 MB)</strong> — 16 shards de dados + 8 de paridade = 24 fragmentos no
+total. Cada fragmento tem aproximadamente 1/16 do tamanho original. Quaisquer 16
+dos 24 fragmentos reconstroem o original. Distribuídos entre 7 pares.</p>
+<p><strong>Large (≥ 256 MB)</strong> — 48 shards de dados + 24 de paridade = 72 fragmentos no
+total. Maior contagem de shards significa fragmentos individuais menores (mais
+fáceis de transferir e armazenar) e maior tolerância absoluta a falhas. Também
+distribuídos entre 7 pares.</p>
+<p>A implementação usa o crate <code>reed-solomon-erasure</code> operando sobre GF(2⁸) — o
+mesmo corpo de Galois usado em códigos QR e CDs. Cada fragmento carrega um
+checksum BLAKE3 para que a corrupção seja detectada imediatamente, não propagada
+silenciosamente.</p>
+<pre><code>Tessera (álbum de fotos de 120 MB)
+ ↓ codificar
+16 shards de dados (7,5 MB cada) + 8 shards de paridade (7,5 MB cada)
+ ↓ distribuir
+24 fragmentos entre 7 pares (diversidade de sub-rede)
+ ↓ quaisquer 16 fragmentos
+Tessera original recuperada
+</code></pre>
+<h2 id="os-desafios">Os desafios</h2>
+<p>Reed-Solomon resolve o problema matemático da redundância. Os desafios de
+engenharia estão em tudo ao redor.</p>
+<h3 id="rastreamento-de-fragmentos">Rastreamento de fragmentos</h3>
+<p>Cada fragmento precisa ser localizável. O Tesseras usa uma DHT Kademlia para
+descoberta de pares e mapeamento de fragmentos para pares. Quando um nó fica
+offline, seus fragmentos precisam ser recriados e distribuídos para novos pares.
+Isso significa rastrear quais fragmentos existem, onde estão e se ainda estão
+intactos — numa rede sem autoridade central.</p>
+<h3 id="corrupcao-silenciosa">Corrupção silenciosa</h3>
+<p>Um fragmento que retorna dados errados é pior que um ausente — pelo menos um
+fragmento ausente é honestamente ausente. O Tesseras aborda isso com
+verificações de saúde baseadas em atestação: o loop de reparo periodicamente
+pede aos detentores de fragmentos que provem posse retornando checksums BLAKE3.
+Se um checksum não bater, o fragmento é tratado como perdido.</p>
+<h3 id="falhas-correlacionadas">Falhas correlacionadas</h3>
+<p>Se todos os 24 fragmentos de uma tessera caírem em máquinas no mesmo datacenter,
+uma única queda de energia os elimina todos. A matemática do Reed-Solomon assume
+falhas independentes. O Tesseras impõe <strong>diversidade de sub-rede</strong> durante a
+distribuição: no máximo 2 fragmentos por sub-rede /24 IPv4 (ou prefixo /48
+IPv6). Isso espalha fragmentos por diferentes infraestruturas físicas.</p>
+<h3 id="velocidade-de-reparo-vs-carga-na-rede">Velocidade de reparo vs. carga na rede</h3>
+<p>Quando um par fica offline, o relógio começa a contar. Fragmentos perdidos
+precisam ser recriados antes que mais falhas se acumulem. Mas reparo agressivo
+inunda a rede. O Tesseras equilibra isso com um loop de reparo configurável
+(padrão: a cada 24 horas com 2 horas de jitter) e limites de transferências
+simultâneas (padrão: 4 transferências simultâneas). O jitter previne tempestades
+de reparo onde cada nó verifica seus fragmentos no mesmo momento.</p>
+<h3 id="gerenciamento-de-chaves-a-longo-prazo">Gerenciamento de chaves a longo prazo</h3>
+<p>Reed-Solomon protege contra perda de dados, não contra perda de acesso. Se uma
+tessera é criptografada (visibilidade privada ou selada), você precisa da chave
+de descriptografia para tornar os dados recuperados úteis. O Tesseras separa
+essas preocupações: codificação de apagamento cuida da disponibilidade, enquanto
+o Compartilhamento de Segredo de Shamir (uma fase futura) cuidará da
+distribuição de chaves entre herdeiros. A filosofia de design do projeto —
+criptografar o mínimo possível — mantém o problema de gerenciamento de chaves
+pequeno.</p>
+<h3 id="limitacoes-do-corpo-de-galois">Limitações do corpo de Galois</h3>
+<p>O corpo GF(2⁸) limita o número total de shards a 255 (dados + paridade
+combinados). Para o Tesseras, isso não é uma restrição prática — mesmo a camada
+Large usa apenas 72 shards. Mas significa que arquivos extremamente grandes com
+milhares de fragmentos exigiriam um corpo diferente ou um esquema de codificação
+em camadas.</p>
+<h3 id="compatibilidade-evolutiva-do-codec">Compatibilidade evolutiva do codec</h3>
+<p>Uma tessera codificada hoje precisa ser decodificável em 50 anos. Reed-Solomon
+sobre GF(2⁸) é um dos algoritmos mais amplamente implementados na computação —
+está em todo leitor de CD, em todo scanner de código QR, em toda sonda espacial.
+Essa ubiquidade é em si uma estratégia de sobrevivência. O algoritmo não será
+esquecido porque metade da infraestrutura do mundo depende dele.</p>
+<h2 id="o-quadro-geral">O quadro geral</h2>
+<p>Reed-Solomon é uma peça de um quebra-cabeça maior. Ele trabalha em conjunto com:</p>
+<ul>
+<li><strong>DHT Kademlia</strong> para encontrar pares e rotear fragmentos</li>
+<li><strong>Checksums BLAKE3</strong> para verificação de integridade</li>
+<li><strong>Reciprocidade bilateral</strong> para troca justa de armazenamento (sem blockchain)</li>
+<li><strong>Diversidade de sub-rede</strong> para independência de falhas</li>
+<li><strong>Reparo automático</strong> para manter a redundância ao longo do tempo</li>
+</ul>
+<p>Nenhuma técnica isolada faz memórias sobreviverem. Reed-Solomon garante que
+dados <em>podem</em> ser recuperados. A DHT garante que fragmentos <em>podem ser
+encontrados</em>. A reciprocidade garante que pares <em>querem ajudar</em>. O reparo
+garante que nada disso se degrade com o tempo.</p>
+<p>Uma tessera é uma aposta de que a soma desses mecanismos, rodando em muitas
+máquinas independentes operadas por muitas pessoas independentes, é mais durável
+que qualquer instituição isolada. Reed-Solomon é a fundação matemática dessa
+aposta.</p>
+
+
+
+
+ Fase 2: Memórias Sobrevivem
+ 2026-02-14T12:00:00+00:00
+ 2026-02-14T12:00:00+00:00
+
+
+
+
+ Unknown
+
+
+
+
+
+ https://tesseras.net/pt-br/news/phase2-replication/
+
+ <p>Uma tessera não está mais presa a uma única máquina. A Fase 2 entrega a camada
+de replicação: os dados são divididos em fragmentos com codificação de
+apagamento, distribuídos entre múltiplos pares e reparados automaticamente
+quando nós ficam offline. Um livro-razão de reciprocidade bilateral garante
+troca justa de armazenamento — sem blockchain, sem tokens.</p>
+<h2 id="o-que-foi-construido">O que foi construído</h2>
+<p><strong>tesseras-core</strong> (atualizado) — Novos tipos de domínio de replicação:
+<code>FragmentPlan</code> (seleciona a camada de fragmentação baseada no tamanho da
+tessera), <code>FragmentId</code> (hash da tessera + índice + contagem de shards +
+checksum), <code>FragmentEnvelope</code> (fragmento com seus metadados para transporte na
+rede), <code>FragmentationTier</code> (Small/Medium/Large), <code>Attestation</code> (prova de que um
+nó possui um fragmento em um dado momento) e <code>ReplicateAck</code> (confirmação de
+recebimento de fragmento). Três novas traits de porta definem os limites
+hexagonais: <code>DhtPort</code> (encontrar pares, replicar fragmentos, solicitar
+atestações, ping), <code>FragmentStore</code> (armazenar/ler/deletar/listar/verificar
+fragmentos) e <code>ReciprocityLedger</code> (registrar trocas de armazenamento, consultar
+saldos, encontrar melhores pares). O tamanho máximo de uma tessera é 1 GB.</p>
+<p><strong>tesseras-crypto</strong> (atualizado) — O <code>ReedSolomonCoder</code> existente agora alimenta
+a codificação de fragmentos. Os dados são divididos em shards, shards de
+paridade são computados, e qualquer combinação de shards de dados pode
+reconstruir o original — desde que o número de shards ausentes não exceda a
+contagem de paridade.</p>
+<p><strong>tesseras-storage</strong> (atualizado) — Dois novos adaptadores:</p>
+<ul>
+<li><code>FsFragmentStore</code> — armazena dados de fragmentos como arquivos em disco
+(<code>{raiz}/{hash_tessera}/{indice:03}.shard</code>) com um índice de metadados SQLite
+rastreando hash da tessera, índice do shard, contagem de shards, checksum e
+tamanho em bytes. A verificação recalcula o hash BLAKE3 e compara com o
+checksum armazenado.</li>
+<li><code>SqliteReciprocityLedger</code> — contabilidade bilateral de armazenamento em
+SQLite. Cada par tem uma linha rastreando bytes armazenados para eles e bytes
+que eles armazenam para nós. A coluna <code>balance</code> é uma coluna gerada
+(<code>bytes_they_store_for_us - bytes_stored_for_them</code>). UPSERT garante incremento
+atômico dos contadores.</li>
+</ul>
+<p>Nova migração (<code>002_replication.sql</code>) adiciona tabelas para fragmentos, planos
+de fragmentação, detentores, mapeamentos detentor-fragmento e saldos de
+reciprocidade.</p>
+<p><strong>tesseras-dht</strong> (atualizado) — Quatro novas variantes de mensagem: <code>Replicate</code>
+(enviar um envelope de fragmento), <code>ReplicateAck</code> (confirmar recebimento),
+<code>AttestRequest</code> (pedir a um nó que prove que possui os fragmentos de uma
+tessera) e <code>AttestResponse</code> (retornar atestação com checksums e timestamp). O
+engine trata essas mensagens em seu loop de despacho.</p>
+<p><strong>tesseras-replication</strong> — O novo crate, com cinco módulos:</p>
+<ul>
+<li>
+<p><em>Codificação de fragmentos</em> (<code>fragment.rs</code>): <code>encode_tessera()</code> seleciona a
+camada de fragmentação baseada no tamanho e então chama a codificação
+Reed-Solomon para as camadas Medium e Large. Três camadas:</p>
+<ul>
+<li><strong>Small</strong> (< 4 MB): replicação do arquivo inteiro para r=7 pares, sem
+codificação de apagamento</li>
+<li><strong>Medium</strong> (4–256 MB): 16 shards de dados + 8 de paridade, distribuídos
+entre r=7 pares</li>
+<li><strong>Large</strong> (≥ 256 MB): 48 shards de dados + 24 de paridade, distribuídos
+entre r=7 pares</li>
+</ul>
+</li>
+<li>
+<p><em>Distribuição</em> (<code>distributor.rs</code>): filtragem de diversidade de sub-rede limita
+pares por sub-rede /24 IPv4 (ou prefixo /48 IPv6) para evitar falhas
+correlacionadas. Se todos os seus fragmentos caírem no mesmo rack, uma única
+queda de energia os elimina.</p>
+</li>
+<li>
+<p><em>Serviço</em> (<code>service.rs</code>): <code>ReplicationService</code> é o orquestrador.
+<code>replicate_tessera()</code> codifica os dados, encontra os pares mais próximos via
+DHT, aplica diversidade de sub-rede e distribui fragmentos em round-robin.
+<code>receive_fragment()</code> valida o checksum BLAKE3, verifica o saldo de
+reciprocidade (rejeita se o déficit do remetente exceder o limite
+configurado), armazena o fragmento e atualiza o livro-razão.
+<code>handle_attestation_request()</code> lista os fragmentos locais e calcula seus
+checksums como prova de posse.</p>
+</li>
+<li>
+<p><em>Reparo</em> (<code>repair.rs</code>): <code>check_tessera_health()</code> solicita atestações dos
+detentores conhecidos, recorre ao ping para nós não responsivos, verifica a
+integridade local dos fragmentos e retorna uma de três ações: <code>Healthy</code>,
+<code>NeedsReplication { deficit }</code> ou <code>CorruptLocal { fragment_index }</code>. O loop de
+reparo roda a cada 24 horas (com 2 horas de jitter) via <code>tokio::select!</code> com
+integração de desligamento.</p>
+</li>
+<li>
+<p><em>Configuração</em> (<code>config.rs</code>): <code>ReplicationConfig</code> com padrões para intervalo
+de reparo (24h), jitter (2h), transferências simultâneas (4), espaço livre
+mínimo (1 GB), tolerância de déficit (256 MB) e limite de armazenamento por
+par (1 GB).</p>
+</li>
+</ul>
+<p><strong>tesd</strong> (atualizado) — O daemon agora abre um banco de dados SQLite
+(<code>db/tesseras.db</code>), executa migrações, cria instâncias de <code>FsFragmentStore</code>,
+<code>SqliteReciprocityLedger</code> e <code>FsBlobStore</code>, envolve o engine DHT em um
+<code>DhtPortAdapter</code>, constrói um <code>ReplicationService</code> e lança o loop de reparo como
+tarefa em segundo plano com desligamento gracioso.</p>
+<p><strong>Testes</strong> — 193 testes em todo o workspace:</p>
+<ul>
+<li>15 testes unitários em tesseras-replication (camadas de codificação de
+fragmentos, validação de checksum, diversidade de sub-rede, verificações de
+saúde do reparo, fluxos de recebimento/replicação do serviço)</li>
+<li>3 testes de integração com armazenamento real (ciclo completo
+codificar→distribuir→receber para tessera média, replicação de arquivo inteiro
+para tessera pequena, rejeição de fragmento adulterado)</li>
+<li>Testes usam SQLite em memória + diretório temporário para fragmentos com mocks
+mockall para DHT e BlobStore</li>
+<li>Zero avisos do clippy, formatação limpa</li>
+</ul>
+<h2 id="decisoes-de-arquitetura">Decisões de arquitetura</h2>
+<ul>
+<li><strong>Fragmentação em três camadas</strong>: arquivos pequenos não precisam de
+codificação de apagamento — o overhead não compensa. Arquivos médios e grandes
+recebem progressivamente mais shards de paridade. Isso evita desperdiçar
+armazenamento em tesseras pequenas enquanto oferece redundância forte para as
+grandes.</li>
+<li><strong>Distribuição por push do dono</strong>: o dono da tessera codifica os fragmentos e
+os envia aos pares, em vez dos pares puxarem. Isso simplifica o protocolo (sem
+fase de negociação) e garante que os fragmentos são distribuídos
+imediatamente.</li>
+<li><strong>Reciprocidade bilateral sem consenso</strong>: cada nó rastreia seu próprio saldo
+com cada par localmente. Sem livro-razão global, sem token, sem blockchain. Se
+o par A armazena 500 MB para o par B, o par B deveria armazenar
+aproximadamente 500 MB para o par A. Free riders perdem redundância
+gradualmente — seus fragmentos são despriorizados para reparo, mas nunca
+deletados.</li>
+<li><strong>Diversidade de sub-rede</strong>: os fragmentos são espalhados por diferentes
+sub-redes para sobreviver a falhas correlacionadas. Uma queda de datacenter
+não deveria eliminar todas as cópias de uma tessera.</li>
+<li><strong>Verificações de saúde por atestação primeiro</strong>: o loop de reparo pede aos
+detentores que provem posse (atestação com checksums) antes de declarar uma
+tessera degradada. Apenas quando a atestação falha é que ele recorre a um
+simples ping. Isso detecta corrupção silenciosa de dados, não apenas partida
+de nós.</li>
+</ul>
+<h2 id="o-que-vem-a-seguir">O que vem a seguir</h2>
+<ul>
+<li><strong>Fase 3: API e Apps</strong> — App Flutter mobile/desktop via flutter_rust_bridge,
+API GraphQL (async-graphql), nó WASM no navegador</li>
+<li><strong>Fase 4: Resiliência e Escala</strong> — Assinaturas pós-quânticas ML-DSA, travessia
+avançada de NAT, Compartilhamento de Segredo de Shamir para herdeiros,
+empacotamento para Alpine/Arch/Debian/FreeBSD/OpenBSD, CI no SourceHut</li>
+<li><strong>Fase 5: Exploração e Cultura</strong> — navegador público de tesseras, curadoria
+institucional, integração genealógica, exportação para mídia física</li>
+</ul>
+<p>Os nós conseguem se encontrar e manter vivas as memórias uns dos outros. Em
+seguida, damos às pessoas uma forma de segurar suas memórias nas mãos.</p>
+
+
+
+
+ Fase 1: Nós Se Encontram
+ 2026-02-14T11:00:00+00:00
+ 2026-02-14T11:00:00+00:00
+
+
+
+
+ Unknown
+
+
+
+
+
+ https://tesseras.net/pt-br/news/phase1-basic-network/
+
+ <p>Tesseras não é mais uma ferramenta apenas local. A Fase 1 entrega a camada de
+rede: nós se descobrem através de uma DHT Kademlia, comunicam-se sobre QUIC e
+publicam ponteiros de tesseras que qualquer par na rede pode encontrar. Uma
+tessera criada no nó A agora pode ser encontrada a partir do nó C.</p>
+<h2 id="o-que-foi-construido">O que foi construído</h2>
+<p><strong>tesseras-core</strong> (atualizado) — Novos tipos de domínio de rede:
+<code>TesseraPointer</code> (referência leve aos detentores de uma tessera e localização
+dos fragmentos), <code>NodeIdentity</code> (ID do nó + chave pública + nonce de prova de
+trabalho), <code>NodeInfo</code> (identidade + endereço + capacidades) e <code>Capabilities</code>
+(bitflags do que um nó suporta: DHT, armazenamento, relay, replicação).</p>
+<p><strong>tesseras-net</strong> — A camada de transporte, construída sobre QUIC via quinn. A
+trait <code>Transport</code> define a porta: <code>send</code>, <code>recv</code>, <code>disconnect</code>, <code>local_addr</code>.
+Dois adaptadores a implementam:</p>
+<ul>
+<li><code>QuinnTransport</code> — QUIC real com TLS auto-assinado, negociação ALPN
+(<code>tesseras/1</code>), pool de conexões via DashMap e um loop de aceitação em
+background que trata streams recebidas.</li>
+<li><code>MemTransport</code> + <code>SimNetwork</code> — canais em memória para testes determinísticos
+sem I/O de rede. Cada teste de integração no crate DHT roda contra este
+adaptador.</li>
+</ul>
+<p>O protocolo de fio usa MessagePack com prefixo de comprimento: um cabeçalho de 4
+bytes big-endian seguido de um payload rmp-serde. <code>WireMessage</code> carrega um byte
+de versão, ID de requisição e um corpo que pode ser requisição, resposta ou erro
+de protocolo. Tamanho máximo de mensagem é 64 KiB.</p>
+<p><strong>tesseras-dht</strong> — Uma implementação completa de Kademlia:</p>
+<ul>
+<li><em>Tabela de roteamento</em>: 160 k-buckets com k=20. Evicção do menos recentemente
+visto, mover-para-trás ao atualizar, verificação por ping antes de substituir
+a entrada mais antiga de um bucket cheio.</li>
+<li><em>Distância XOR</em>: métrica XOR de 160 bits com indexação de bucket pelo bit mais
+significativo diferente.</li>
+<li><em>Prova de trabalho</em>: nós iteram um nonce até que
+<code>BLAKE3(pubkey || nonce)[..20]</code> tenha 8 bits zero iniciais (~256 tentativas de
+hash em média). Barato o suficiente para qualquer dispositivo, caro o
+suficiente para tornar ataques Sybil impraticáveis em escala.</li>
+<li><em>Mensagens de protocolo</em>: Ping/Pong, FindNode/FindNodeResponse,
+FindValue/FindValueResult, Store — todos serializados com MessagePack via
+serde.</li>
+<li><em>Armazenamento de ponteiros</em>: armazenamento em memória limitado com TTL
+configurável (24 horas padrão) e máximo de entradas (10.000 padrão). Quando
+cheio, remove ponteiros mais distantes do ID do nó local, seguindo o modelo de
+responsabilidade baseado em distância do Kademlia.</li>
+<li><em>DhtEngine</em>: o orquestrador principal. Trata RPCs recebidos, executa buscas
+iterativas (paralelismo alpha=3), bootstrap, publicação e busca. O método
+<code>run()</code> dirige um loop <code>tokio::select!</code> com timers de manutenção: refresh da
+tabela de roteamento a cada 60 segundos, expiração de ponteiros a cada 5
+minutos.</li>
+</ul>
+<p><strong>tesd</strong> — Um binário de nó completo. Analisa argumentos de CLI (endereço de
+bind, pares de bootstrap, diretório de dados), gera uma identidade de nó válida
+por PoW, abre um endpoint QUIC, faz bootstrap na rede e roda o motor DHT.
+Desligamento gracioso com Ctrl+C via tratamento de sinais do tokio.</p>
+<p><strong>Infraestrutura</strong> — Configuração OpenTofu para dois nós bootstrap no Hetzner
+Cloud (instâncias cx22 em Falkenstein, Alemanha e Helsinki, Finlândia). Script
+de provisionamento cloud-init cria um usuário dedicado <code>tesseras</code>, escreve um
+arquivo de configuração e configura um serviço systemd. Regras de firewall abrem
+UDP 4433 (QUIC) e restringem métricas a acesso interno.</p>
+<p><strong>Testes</strong> — 139 testes em todo o workspace:</p>
+<ul>
+<li>47 testes unitários em tesseras-dht (tabela de roteamento, distância, PoW,
+armazenamento de ponteiros, serialização de mensagens, RPCs do engine)</li>
+<li>5 testes de integração multi-nó (bootstrap de 3 nós, convergência de lookup
+com 10 nós, publicar-e-encontrar, detecção de partida de nó, rejeição de PoW)</li>
+<li>14 testes em tesseras-net (roundtrips de codec, send/recv de transporte,
+backpressure, disconnect)</li>
+<li>Testes de fumaça com Docker Compose usando 3 nós containerizados comunicando
+sobre QUIC real</li>
+<li>Zero avisos do clippy, formatação limpa</li>
+</ul>
+<h2 id="decisoes-de-arquitetura">Decisões de arquitetura</h2>
+<ul>
+<li><strong>Transport como porta</strong>: a trait <code>Transport</code> é a única interface entre o
+motor DHT e a rede. Trocar QUIC por qualquer outro protocolo significa
+implementar quatro métodos. Todos os testes de DHT usam o adaptador em
+memória, tornando-os rápidos e determinísticos.</li>
+<li><strong>Um stream por RPC</strong>: cada par requisição-resposta DHT usa um stream
+bidirecional QUIC novo. Sem complexidade de multiplexação, sem bloqueio
+head-of-line entre operações independentes. O QUIC trata a multiplexação no
+nível da conexão.</li>
+<li><strong>MessagePack em vez de Protobuf</strong>: codificação binária compacta sem geração
+de código ou arquivos de esquema. Integração com serde significa que adicionar
+um campo a uma mensagem é uma mudança de uma linha. Trade-off: sem garantias
+de evolução de esquema embutidas, mas neste estágio velocidade importa mais.</li>
+<li><strong>PoW em vez de stake ou reputação</strong>: uma identidade de nó custa ~256 hashes
+BLAKE3. Isso roda em menos de um segundo em qualquer hardware, incluindo um
+Raspberry Pi, mas gerar milhares de identidades para um ataque Sybil se torna
+caro. Sem tokens, sem blockchain, sem dependências externas.</li>
+<li><strong>Busca iterativa com atualização da tabela de roteamento</strong>: nós descobertos
+são adicionados à tabela de roteamento conforme encontrados durante buscas
+iterativas, seguindo o comportamento padrão do Kademlia. Isso garante que a
+tabela de roteamento melhore organicamente conforme os nós interagem.</li>
+</ul>
+<h2 id="o-que-vem-a-seguir">O que vem a seguir</h2>
+<ul>
+<li><strong>Fase 2: Replicação</strong> — Codificação de apagamento Reed-Solomon pela rede,
+distribuição de fragmentos, loops de reparo automáticos, livro-razão de
+reciprocidade bilateral (sem blockchain, sem tokens)</li>
+<li><strong>Fase 3: API e Apps</strong> — App Flutter mobile/desktop via flutter_rust_bridge,
+API GraphQL (async-graphql), nó WASM no navegador</li>
+<li><strong>Fase 4: Resiliência e Escala</strong> — Assinaturas pós-quânticas ML-DSA, travessia
+avançada de NAT, Compartilhamento de Segredo de Shamir para herdeiros,
+empacotamento para Alpine/Arch/Debian/FreeBSD/OpenBSD, CI no SourceHut</li>
+<li><strong>Fase 5: Exploração e Cultura</strong> — navegador público de tesseras, curadoria
+institucional, integração genealógica, exportação para mídia física</li>
+</ul>
+<p>Os nós conseguem se encontrar. Em seguida, aprendem a manter vivas as memórias
+uns dos outros.</p>
+
+
+
+
+ Fase 0: Fundação Construída
+ 2026-02-14T10:00:00+00:00
+ 2026-02-14T10:00:00+00:00
+
+
+
+
+ Unknown
+
+
+
+
+
+ https://tesseras.net/pt-br/news/phase0-foundation/
+
+ <p>O primeiro marco do projeto Tesseras está completo. A Fase 0 estabelece a
+fundação sobre a qual cada componente futuro será construído: tipos de domínio,
+criptografia, armazenamento e uma interface de linha de comando funcional.</p>
+<h2 id="o-que-foi-construido">O que foi construído</h2>
+<p><strong>tesseras-core</strong> — A camada de domínio define o formato tessera: <code>ContentHash</code>
+(BLAKE3, 32 bytes), <code>NodeId</code> (Kademlia, 20 bytes), tipos de memória (Moment,
+Reflection, Daily, Relation, Object), modos de visibilidade (Private, Circle,
+Public, PublicAfterDeath, Sealed) e um formato de manifesto em texto plano que
+pode ser interpretado por qualquer linguagem de programação pelos próximos mil
+anos. A camada de serviço (<code>TesseraService</code>) gerencia operações de criação,
+verificação, exportação e listagem através de port traits, seguindo arquitetura
+hexagonal.</p>
+<p><strong>tesseras-crypto</strong> — Geração de chaves Ed25519, assinatura e verificação. Um
+framework de assinatura dual (Ed25519 + placeholder ML-DSA) pronto para migração
+pós-quântica. Hashing de conteúdo com BLAKE3. Codificação de apagamento
+Reed-Solomon atrás de uma feature flag para futura replicação.</p>
+<p><strong>tesseras-storage</strong> — Índice SQLite via rusqlite com migrações em SQL puro.
+Blob store no sistema de arquivos com layout endereçável por conteúdo
+(<code>blobs/<tessera_hash>/<memory_hash>/<filename></code>). Persistência de chaves de
+identidade em disco.</p>
+<p><strong>tesseras-cli</strong> — Um binário <code>tesseras</code> funcional com cinco comandos:</p>
+<ul>
+<li><code>init</code> — gera identidade Ed25519, cria banco de dados SQLite</li>
+<li><code>create <dir></code> — varre um diretório por arquivos de mídia, cria uma tessera
+assinada</li>
+<li><code>verify <hash></code> — verifica assinatura e integridade dos arquivos</li>
+<li><code>export <hash> <dest></code> — escreve um diretório tessera autocontido</li>
+<li><code>list</code> — mostra uma tabela das tesseras armazenadas</li>
+</ul>
+<p><strong>Testes</strong> — 67+ testes em todo o workspace: testes unitários em cada módulo,
+testes baseados em propriedades (proptest) para roundtrips hex e serialização de
+manifesto, testes de integração cobrindo o ciclo completo de
+criação-verificação-exportação incluindo detecção de arquivos adulterados e
+assinaturas inválidas. Zero avisos do clippy.</p>
+<h2 id="decisoes-de-arquitetura">Decisões de arquitetura</h2>
+<ul>
+<li><strong>Arquitetura hexagonal</strong>: operações criptográficas são injetadas via trait
+objects (<code>Box<dyn Hasher></code>, <code>Box<dyn ManifestSigner></code>,
+<code>Box<dyn ManifestVerifier></code>), mantendo o crate core livre de dependências
+criptográficas concretas.</li>
+<li><strong>Feature flags</strong>: a feature <code>service</code> no tesseras-core controla a camada de
+aplicação assíncrona. As features <code>classical</code> e <code>erasure</code> no tesseras-crypto
+controlam quais algoritmos são compilados.</li>
+<li><strong>Manifesto em texto plano</strong>: interpretável sem qualquer biblioteca de formato
+binário, com prefixos de hash explícitos <code>blake3:</code> e layout legível por
+humanos.</li>
+</ul>
+<h2 id="o-que-vem-a-seguir">O que vem a seguir</h2>
+<p>A Fase 0 é a fundação local. O caminho adiante:</p>
+<ul>
+<li><strong>Fase 1: Rede</strong> — Transporte QUIC (quinn), DHT Kademlia para descoberta de
+pares, travessia de NAT</li>
+<li><strong>Fase 2: Replicação</strong> — Codificação de apagamento Reed-Solomon pela rede,
+loops de reparo, reciprocidade bilateral (sem blockchain, sem tokens)</li>
+<li><strong>Fase 3: Clientes</strong> — App Flutter mobile/desktop via flutter_rust_bridge, API
+GraphQL, nó WASM no navegador</li>
+<li><strong>Fase 4: Endurecimento</strong> — Assinaturas pós-quânticas ML-DSA, empacotamento
+para Alpine/Arch/Debian/FreeBSD/OpenBSD, CI no SourceHut</li>
+</ul>
+<p>O formato tessera é estável. Tudo construído a partir daqui se conecta e estende
+o que existe hoje.</p>
+
+
+
+
+ Olá, Mundo
+ 2026-02-13T00:00:00+00:00
+ 2026-02-13T00:00:00+00:00
+
+
+
+
+ Unknown
+
+
+
+
+
+ https://tesseras.net/pt-br/news/hello-world/
+
+ <p>Hoje anunciamos o projeto Tesseras: uma rede peer-to-peer para preservar
+memórias humanas através dos milênios.</p>
+<p>Tesseras é construído sobre uma ideia simples — suas fotos, gravações e escritos
+merecem sobreviver a qualquer empresa, plataforma ou formato de arquivo. Cada
+pessoa cria uma tessera, uma cápsula do tempo autocontida que a rede mantém viva
+através de ajuda mútua e redundância.</p>
+<p>O projeto está em seu estágio mais inicial. Estamos construindo a fundação:
+ferramentas para criar, verificar e exportar tesseras offline. A camada de rede,
+replicação e aplicativos virão em seguida.</p>
+<p>Se essa missão ressoa com você,
+<a href="/pt-br/subscriptions/">entre na lista de discussão</a> ou navegue pelo
+<a rel="external" href="https://git.sr.ht/~ijanc/tesseras">código-fonte</a>.</p>
+
+
+
+
diff --git a/pt-br/news/atom.xml.gz b/pt-br/news/atom.xml.gz
new file mode 100644
index 0000000..2870951
Binary files /dev/null and b/pt-br/news/atom.xml.gz differ
diff --git a/pt-br/news/cli-daemon-rpc/index.html b/pt-br/news/cli-daemon-rpc/index.html
new file mode 100644
index 0000000..3b43961
--- /dev/null
+++ b/pt-br/news/cli-daemon-rpc/index.html
@@ -0,0 +1,147 @@
+
+
+
CLI Encontra a Rede: Comandos Publish, Fetch e Status
+
2026-02-15
+
Até agora o CLI operava isoladamente: criar uma tessera, verificar, exportar,
+listar o que você tem. Tudo ficava na sua máquina. Com esta atualização, o tes
+ganha três comandos que fazem a ponte entre o armazenamento local e a rede P2P —
+publish, fetch e status — comunicando-se com um tesd em execução através
+de um socket Unix.
+
O que foi construído
+
Crate tesseras-rpc — Um novo crate compartilhado entre CLI e daemon.
+Define o protocolo RPC usando serialização MessagePack com enquadramento
+prefixado por tamanho (cabeçalho big-endian de 4 bytes, máximo de 64 MiB). Três
+tipos de requisição (Publish, Fetch, Status) e suas respostas
+correspondentes. Um DaemonClient síncrono gerencia a conexão do socket Unix
+com timeouts configuráveis. O protocolo é deliberadamente simples — uma
+requisição, uma resposta, conexão fechada — para manter a implementação
+auditável.
+
tes publish <hash> — Publica uma tessera na rede. Aceita hashes completos
+ou prefixos curtos (ex.: tes publish a1b2), que são resolvidos no banco de
+dados local. O daemon lê todos os arquivos da tessera do armazenamento, empacota
+em um único buffer MessagePack e entrega ao motor de replicação. Tesseras
+pequenas (< 4 MB) são replicadas como um único fragmento; maiores passam por
+codificação de apagamento Reed-Solomon. A saída mostra o hash curto e a contagem
+de fragmentos:
+
Published tessera 9f2c4a1b (24 fragments created)
+Distribution in progress — use `tes status 9f2c4a1b` to track.
+
+
tes fetch <hash> — Busca uma tessera da rede usando o hash de conteúdo
+completo. O daemon coleta fragmentos disponíveis localmente, reconstrói os dados
+originais via decodificação de apagamento se necessário, desempacota os arquivos
+e armazena no CAS (content-addressable store). Retorna o número de memórias e o
+tamanho total buscado.
+
tes status <hash> — Exibe a saúde de replicação de uma tessera. A saída
+mapeia diretamente o modelo interno de saúde do motor de replicação:
+
Estado
Significado
+
Local
Ainda não publicada — existe apenas na sua máquina
+
Publishing
Fragmentos sendo distribuídos, redundância crítica
+
Replicated
Distribuída, mas abaixo da redundância alvo
+
Healthy
Redundância completa alcançada
+
+
Listener RPC no daemon — O daemon agora escuta em um socket Unix (padrão:
+$XDG_RUNTIME_DIR/tesseras/daemon.sock) com permissões de diretório adequadas
+(0700), limpeza de sockets obsoletos e shutdown gracioso. Cada conexão é tratada
+em uma task Tokio — o listener converte o stream assíncrono para I/O síncrono
+para a camada de enquadramento, despacha para o handler RPC e escreve a resposta
+de volta.
+
Pack/unpack no tesseras-core — Um módulo pequeno que serializa uma lista
+de entradas de arquivo (caminho + dados) em um único buffer MessagePack e
+vice-versa. Esta é a ponte entre a estrutura de diretórios da tessera e os blobs
+opacos do motor de replicação.
+
Decisões de arquitetura
+
+
Socket Unix ao invés de TCP: a comunicação RPC entre CLI e daemon acontece
+na mesma máquina. Sockets Unix são mais rápidos, não precisam de alocação de
+porta, e as permissões do sistema de arquivos fornecem controle de acesso sem
+TLS.
+
MessagePack ao invés de JSON: o mesmo formato wire usado em todo o
+Tesseras. Compacto, sem schema, e já é uma dependência do workspace. Uma
+ida-e-volta típica de publish request/response ocupa menos de 200 bytes.
+
Cliente síncrono, daemon assíncrono: o DaemonClient usa I/O bloqueante
+porque o CLI não precisa de concorrência — envia uma requisição e espera. O
+listener do daemon é assíncrono (Tokio) para tratar múltiplas conexões. A
+camada de enquadramento funciona com qualquer impl Read/Write, conectando
+ambos os mundos.
+
Resolução de prefixo no lado do cliente: publish e status resolvem
+prefixos curtos localmente antes de enviar o hash completo ao daemon. Isso
+mantém o daemon stateless — ele não precisa acessar o banco de dados do CLI.
+
Alinhamento do diretório de dados padrão: o padrão do CLI mudou de
+~/.tesseras para ~/.local/share/tesseras (via dirs::data_dir()) para
+coincidir com o daemon. Um aviso de migração é exibido quando dados no caminho
+antigo são detectados.
+
+
Próximos passos
+
+
Contagem de peers no DHT: o comando status atualmente reporta 0 peers —
+conectar a contagem real do DHT é o próximo passo
+
tes show: exibir o conteúdo de uma tessera (memórias, metadados) sem
+exportar
+
Fetch com streaming: para tesseras grandes, transmitir fragmentos conforme
+chegam ao invés de esperar por todos
Hoje anunciamos o projeto Tesseras: uma rede peer-to-peer para preservar
+memórias humanas através dos milênios.
+
Tesseras é construído sobre uma ideia simples — suas fotos, gravações e escritos
+merecem sobreviver a qualquer empresa, plataforma ou formato de arquivo. Cada
+pessoa cria uma tessera, uma cápsula do tempo autocontida que a rede mantém viva
+através de ajuda mútua e redundância.
+
O projeto está em seu estágio mais inicial. Estamos construindo a fundação:
+ferramentas para criar, verificar e exportar tesseras offline. A camada de rede,
+replicação e aplicativos virão em seguida.
Uma nova camada de armazenamento enderecavel por conteudo elimina dados duplicados entre tesseras, reduzindo uso de disco e habilitando coleta de lixo automatica.
Bibliotecas, arquivos e museus agora podem ingressar na rede Tesseras como nos institucionais verificados com identidade baseada em DNS, indices de busca full-text e compromissos configuraveis de armazenamento.
SQLite em modo WAL com configuracao centralizada de pragmas, cache LRU de fragmentos, gerenciamento de ciclo de vida do pool de conexoes QUIC e otimizacao do hot path de atestacao.
Tesseras agora compila para WebAssembly — qualquer pessoa pode verificar integridade e autenticidade de uma tessera diretamente no navegador, sem instalar nenhum software.
Os nos Tesseras agora podem descobrir seu tipo de NAT via STUN, coordenar UDP hole punching atraves de introdutores e usar relay transparente quando a conectividade direta falha.
O CLI do tesseras agora pode publicar tesseras na rede, buscá-las de peers e monitorar o estado de replicação — tudo através de uma nova ponte RPC via socket Unix para o daemon.
Tesseras agora permite dividir sua identidade criptográfica em fragmentos distribuídos a herdeiros de confiança — qualquer limiar deles pode reconstruir suas chaves, mas menos que isso não revela nada.
Tesseras agora suporta memórias privadas e seladas com criptografia híbrida pós-quântica — AES-256-GCM, X25519 + ML-KEM-768 e publicação de chaves com bloqueio temporal.
Um mergulho profundo na codificação de apagamento Reed-Solomon — o que é, por que o Tesseras a utiliza e os desafios de manter memórias vivas ao longo dos séculos.
Tesseras agora fragmenta, distribui e repara dados automaticamente pela rede usando codificação de apagamento Reed-Solomon e um livro-razão de reciprocidade bilateral.
O pacote cria automaticamente um usuário e grupo de sistema tesseras via
+systemd-sysusers. Para usar o CLI sem sudo, adicione seu usuário ao grupo:
+
sudo usermod -aG tesseras $USER
+
+
Faça logout e login novamente, depois inicie o daemon:
+
sudo systemctl enable --now tesd
+
+
O que o pacote inclui
+
Caminho
Descrição
+
/usr/bin/tesd
Daemon do nó completo
+
/usr/bin/tes
Cliente CLI
+
/etc/tesseras/config.toml
Configuração padrão (marcado como backup)
+
/usr/lib/systemd/system/tesd.service
Unit systemd com hardening de segurança
+
/usr/lib/sysusers.d/tesseras.conf
Definição do usuário de sistema
+
/usr/lib/tmpfiles.d/tesseras.conf
Diretório de dados /var/lib/tesseras
+
Completions de shell
bash, zsh e fish
+
+
Detalhes do PKGBUILD
+
O PKGBUILD compila diretamente a partir do checkout git local em vez de baixar
+um tarball. A variável de ambiente TESSERAS_ROOT aponta o makepkg para a raiz
+do workspace. O diretório target do Cargo é configurado para $srcdir/target
+para manter os artefatos de build dentro do sandbox do makepkg.
+
O pacote depende apenas de sqlite em tempo de execução e cargo em tempo de
+build.
+
Atualizando
+
Depois de baixar novas mudanças, basta rodar just arch novamente e reinstalar:
O Tesseras agora inclui um pacote .deb para Debian e Ubuntu. Este post explica
+como compilar e instalar o pacote a partir do código-fonte usando cargo-deb.
+
Pré-requisitos
+
Você precisa de uma toolchain Rust funcional e das bibliotecas de sistema
+necessárias:
O script postinst cria automaticamente um usuário de sistema tesseras e o
+diretório de dados /var/lib/tesseras. Para usar o CLI sem sudo, adicione seu
+usuário ao grupo:
+
sudo usermod -aG tesseras $USER
+
+
Faça logout e login novamente, depois inicie o daemon:
+
sudo systemctl enable --now tesd
+
+
O que o pacote inclui
+
Caminho
Descrição
+
/usr/bin/tesd
Daemon do nó completo
+
/usr/bin/tes
Cliente CLI
+
/etc/tesseras/config.toml
Configuração padrão (marcado como conffile)
+
/lib/systemd/system/tesd.service
Unit systemd com hardening de segurança
+
Completions de shell
bash, zsh e fish
+
+
Como o cargo-deb funciona
+
Os metadados de empacotamento ficam em crates/tesseras-daemon/Cargo.toml na
+seção [package.metadata.deb]. Essa seção define:
+
+
depends — dependências em tempo de execução: libc6 e libsqlite3-0
+
assets — arquivos incluídos no pacote (binários, config, unit systemd,
+completions de shell)
+
conf-files — arquivos tratados como configuração (preservados na
+atualização)
+
maintainer-scripts — scripts postinst e postrm em
+packaging/debian/scripts/
+
systemd-units — integração automática com systemd
+
+
O script postinst cria o usuário de sistema tesseras e o diretório de dados
+na instalação. O script postrm remove o usuário, grupo e diretório de dados
+apenas no purge (não na remoção simples).
+
Hardening do systemd
+
A unit tesd.service inclui diretivas de hardening de segurança:
O primeiro marco do projeto Tesseras está completo. A Fase 0 estabelece a
+fundação sobre a qual cada componente futuro será construído: tipos de domínio,
+criptografia, armazenamento e uma interface de linha de comando funcional.
+
O que foi construído
+
tesseras-core — A camada de domínio define o formato tessera: ContentHash
+(BLAKE3, 32 bytes), NodeId (Kademlia, 20 bytes), tipos de memória (Moment,
+Reflection, Daily, Relation, Object), modos de visibilidade (Private, Circle,
+Public, PublicAfterDeath, Sealed) e um formato de manifesto em texto plano que
+pode ser interpretado por qualquer linguagem de programação pelos próximos mil
+anos. A camada de serviço (TesseraService) gerencia operações de criação,
+verificação, exportação e listagem através de port traits, seguindo arquitetura
+hexagonal.
+
tesseras-crypto — Geração de chaves Ed25519, assinatura e verificação. Um
+framework de assinatura dual (Ed25519 + placeholder ML-DSA) pronto para migração
+pós-quântica. Hashing de conteúdo com BLAKE3. Codificação de apagamento
+Reed-Solomon atrás de uma feature flag para futura replicação.
+
tesseras-storage — Índice SQLite via rusqlite com migrações em SQL puro.
+Blob store no sistema de arquivos com layout endereçável por conteúdo
+(blobs/<tessera_hash>/<memory_hash>/<filename>). Persistência de chaves de
+identidade em disco.
+
tesseras-cli — Um binário tesseras funcional com cinco comandos:
+
+
init — gera identidade Ed25519, cria banco de dados SQLite
+
create <dir> — varre um diretório por arquivos de mídia, cria uma tessera
+assinada
+
verify <hash> — verifica assinatura e integridade dos arquivos
+
export <hash> <dest> — escreve um diretório tessera autocontido
+
list — mostra uma tabela das tesseras armazenadas
+
+
Testes — 67+ testes em todo o workspace: testes unitários em cada módulo,
+testes baseados em propriedades (proptest) para roundtrips hex e serialização de
+manifesto, testes de integração cobrindo o ciclo completo de
+criação-verificação-exportação incluindo detecção de arquivos adulterados e
+assinaturas inválidas. Zero avisos do clippy.
+
Decisões de arquitetura
+
+
Arquitetura hexagonal: operações criptográficas são injetadas via trait
+objects (Box<dyn Hasher>, Box<dyn ManifestSigner>,
+Box<dyn ManifestVerifier>), mantendo o crate core livre de dependências
+criptográficas concretas.
+
Feature flags: a feature service no tesseras-core controla a camada de
+aplicação assíncrona. As features classical e erasure no tesseras-crypto
+controlam quais algoritmos são compilados.
+
Manifesto em texto plano: interpretável sem qualquer biblioteca de formato
+binário, com prefixos de hash explícitos blake3: e layout legível por
+humanos.
+
+
O que vem a seguir
+
A Fase 0 é a fundação local. O caminho adiante:
+
+
Fase 1: Rede — Transporte QUIC (quinn), DHT Kademlia para descoberta de
+pares, travessia de NAT
+
Fase 2: Replicação — Codificação de apagamento Reed-Solomon pela rede,
+loops de reparo, reciprocidade bilateral (sem blockchain, sem tokens)
+
Fase 3: Clientes — App Flutter mobile/desktop via flutter_rust_bridge, API
+GraphQL, nó WASM no navegador
+
Fase 4: Endurecimento — Assinaturas pós-quânticas ML-DSA, empacotamento
+para Alpine/Arch/Debian/FreeBSD/OpenBSD, CI no SourceHut
+
+
O formato tessera é estável. Tudo construído a partir daqui se conecta e estende
+o que existe hoje.
Tesseras não é mais uma ferramenta apenas local. A Fase 1 entrega a camada de
+rede: nós se descobrem através de uma DHT Kademlia, comunicam-se sobre QUIC e
+publicam ponteiros de tesseras que qualquer par na rede pode encontrar. Uma
+tessera criada no nó A agora pode ser encontrada a partir do nó C.
+
O que foi construído
+
tesseras-core (atualizado) — Novos tipos de domínio de rede:
+TesseraPointer (referência leve aos detentores de uma tessera e localização
+dos fragmentos), NodeIdentity (ID do nó + chave pública + nonce de prova de
+trabalho), NodeInfo (identidade + endereço + capacidades) e Capabilities
+(bitflags do que um nó suporta: DHT, armazenamento, relay, replicação).
+
tesseras-net — A camada de transporte, construída sobre QUIC via quinn. A
+trait Transport define a porta: send, recv, disconnect, local_addr.
+Dois adaptadores a implementam:
+
+
QuinnTransport — QUIC real com TLS auto-assinado, negociação ALPN
+(tesseras/1), pool de conexões via DashMap e um loop de aceitação em
+background que trata streams recebidas.
+
MemTransport + SimNetwork — canais em memória para testes determinísticos
+sem I/O de rede. Cada teste de integração no crate DHT roda contra este
+adaptador.
+
+
O protocolo de fio usa MessagePack com prefixo de comprimento: um cabeçalho de 4
+bytes big-endian seguido de um payload rmp-serde. WireMessage carrega um byte
+de versão, ID de requisição e um corpo que pode ser requisição, resposta ou erro
+de protocolo. Tamanho máximo de mensagem é 64 KiB.
+
tesseras-dht — Uma implementação completa de Kademlia:
+
+
Tabela de roteamento: 160 k-buckets com k=20. Evicção do menos recentemente
+visto, mover-para-trás ao atualizar, verificação por ping antes de substituir
+a entrada mais antiga de um bucket cheio.
+
Distância XOR: métrica XOR de 160 bits com indexação de bucket pelo bit mais
+significativo diferente.
+
Prova de trabalho: nós iteram um nonce até que
+BLAKE3(pubkey || nonce)[..20] tenha 8 bits zero iniciais (~256 tentativas de
+hash em média). Barato o suficiente para qualquer dispositivo, caro o
+suficiente para tornar ataques Sybil impraticáveis em escala.
+
Mensagens de protocolo: Ping/Pong, FindNode/FindNodeResponse,
+FindValue/FindValueResult, Store — todos serializados com MessagePack via
+serde.
+
Armazenamento de ponteiros: armazenamento em memória limitado com TTL
+configurável (24 horas padrão) e máximo de entradas (10.000 padrão). Quando
+cheio, remove ponteiros mais distantes do ID do nó local, seguindo o modelo de
+responsabilidade baseado em distância do Kademlia.
+
DhtEngine: o orquestrador principal. Trata RPCs recebidos, executa buscas
+iterativas (paralelismo alpha=3), bootstrap, publicação e busca. O método
+run() dirige um loop tokio::select! com timers de manutenção: refresh da
+tabela de roteamento a cada 60 segundos, expiração de ponteiros a cada 5
+minutos.
+
+
tesd — Um binário de nó completo. Analisa argumentos de CLI (endereço de
+bind, pares de bootstrap, diretório de dados), gera uma identidade de nó válida
+por PoW, abre um endpoint QUIC, faz bootstrap na rede e roda o motor DHT.
+Desligamento gracioso com Ctrl+C via tratamento de sinais do tokio.
+
Infraestrutura — Configuração OpenTofu para dois nós bootstrap no Hetzner
+Cloud (instâncias cx22 em Falkenstein, Alemanha e Helsinki, Finlândia). Script
+de provisionamento cloud-init cria um usuário dedicado tesseras, escreve um
+arquivo de configuração e configura um serviço systemd. Regras de firewall abrem
+UDP 4433 (QUIC) e restringem métricas a acesso interno.
+
Testes — 139 testes em todo o workspace:
+
+
47 testes unitários em tesseras-dht (tabela de roteamento, distância, PoW,
+armazenamento de ponteiros, serialização de mensagens, RPCs do engine)
+
5 testes de integração multi-nó (bootstrap de 3 nós, convergência de lookup
+com 10 nós, publicar-e-encontrar, detecção de partida de nó, rejeição de PoW)
+
14 testes em tesseras-net (roundtrips de codec, send/recv de transporte,
+backpressure, disconnect)
+
Testes de fumaça com Docker Compose usando 3 nós containerizados comunicando
+sobre QUIC real
+
Zero avisos do clippy, formatação limpa
+
+
Decisões de arquitetura
+
+
Transport como porta: a trait Transport é a única interface entre o
+motor DHT e a rede. Trocar QUIC por qualquer outro protocolo significa
+implementar quatro métodos. Todos os testes de DHT usam o adaptador em
+memória, tornando-os rápidos e determinísticos.
+
Um stream por RPC: cada par requisição-resposta DHT usa um stream
+bidirecional QUIC novo. Sem complexidade de multiplexação, sem bloqueio
+head-of-line entre operações independentes. O QUIC trata a multiplexação no
+nível da conexão.
+
MessagePack em vez de Protobuf: codificação binária compacta sem geração
+de código ou arquivos de esquema. Integração com serde significa que adicionar
+um campo a uma mensagem é uma mudança de uma linha. Trade-off: sem garantias
+de evolução de esquema embutidas, mas neste estágio velocidade importa mais.
+
PoW em vez de stake ou reputação: uma identidade de nó custa ~256 hashes
+BLAKE3. Isso roda em menos de um segundo em qualquer hardware, incluindo um
+Raspberry Pi, mas gerar milhares de identidades para um ataque Sybil se torna
+caro. Sem tokens, sem blockchain, sem dependências externas.
+
Busca iterativa com atualização da tabela de roteamento: nós descobertos
+são adicionados à tabela de roteamento conforme encontrados durante buscas
+iterativas, seguindo o comportamento padrão do Kademlia. Isso garante que a
+tabela de roteamento melhore organicamente conforme os nós interagem.
+
+
O que vem a seguir
+
+
Fase 2: Replicação — Codificação de apagamento Reed-Solomon pela rede,
+distribuição de fragmentos, loops de reparo automáticos, livro-razão de
+reciprocidade bilateral (sem blockchain, sem tokens)
+
Fase 3: API e Apps — App Flutter mobile/desktop via flutter_rust_bridge,
+API GraphQL (async-graphql), nó WASM no navegador
+
Fase 4: Resiliência e Escala — Assinaturas pós-quânticas ML-DSA, travessia
+avançada de NAT, Compartilhamento de Segredo de Shamir para herdeiros,
+empacotamento para Alpine/Arch/Debian/FreeBSD/OpenBSD, CI no SourceHut
+
Fase 5: Exploração e Cultura — navegador público de tesseras, curadoria
+institucional, integração genealógica, exportação para mídia física
+
+
Os nós conseguem se encontrar. Em seguida, aprendem a manter vivas as memórias
+uns dos outros.
Uma tessera não está mais presa a uma única máquina. A Fase 2 entrega a camada
+de replicação: os dados são divididos em fragmentos com codificação de
+apagamento, distribuídos entre múltiplos pares e reparados automaticamente
+quando nós ficam offline. Um livro-razão de reciprocidade bilateral garante
+troca justa de armazenamento — sem blockchain, sem tokens.
+
O que foi construído
+
tesseras-core (atualizado) — Novos tipos de domínio de replicação:
+FragmentPlan (seleciona a camada de fragmentação baseada no tamanho da
+tessera), FragmentId (hash da tessera + índice + contagem de shards +
+checksum), FragmentEnvelope (fragmento com seus metadados para transporte na
+rede), FragmentationTier (Small/Medium/Large), Attestation (prova de que um
+nó possui um fragmento em um dado momento) e ReplicateAck (confirmação de
+recebimento de fragmento). Três novas traits de porta definem os limites
+hexagonais: DhtPort (encontrar pares, replicar fragmentos, solicitar
+atestações, ping), FragmentStore (armazenar/ler/deletar/listar/verificar
+fragmentos) e ReciprocityLedger (registrar trocas de armazenamento, consultar
+saldos, encontrar melhores pares). O tamanho máximo de uma tessera é 1 GB.
+
tesseras-crypto (atualizado) — O ReedSolomonCoder existente agora alimenta
+a codificação de fragmentos. Os dados são divididos em shards, shards de
+paridade são computados, e qualquer combinação de shards de dados pode
+reconstruir o original — desde que o número de shards ausentes não exceda a
+contagem de paridade.
+
tesseras-storage (atualizado) — Dois novos adaptadores:
+
+
FsFragmentStore — armazena dados de fragmentos como arquivos em disco
+({raiz}/{hash_tessera}/{indice:03}.shard) com um índice de metadados SQLite
+rastreando hash da tessera, índice do shard, contagem de shards, checksum e
+tamanho em bytes. A verificação recalcula o hash BLAKE3 e compara com o
+checksum armazenado.
+
SqliteReciprocityLedger — contabilidade bilateral de armazenamento em
+SQLite. Cada par tem uma linha rastreando bytes armazenados para eles e bytes
+que eles armazenam para nós. A coluna balance é uma coluna gerada
+(bytes_they_store_for_us - bytes_stored_for_them). UPSERT garante incremento
+atômico dos contadores.
+
+
Nova migração (002_replication.sql) adiciona tabelas para fragmentos, planos
+de fragmentação, detentores, mapeamentos detentor-fragmento e saldos de
+reciprocidade.
+
tesseras-dht (atualizado) — Quatro novas variantes de mensagem: Replicate
+(enviar um envelope de fragmento), ReplicateAck (confirmar recebimento),
+AttestRequest (pedir a um nó que prove que possui os fragmentos de uma
+tessera) e AttestResponse (retornar atestação com checksums e timestamp). O
+engine trata essas mensagens em seu loop de despacho.
+
tesseras-replication — O novo crate, com cinco módulos:
+
+
+
Codificação de fragmentos (fragment.rs): encode_tessera() seleciona a
+camada de fragmentação baseada no tamanho e então chama a codificação
+Reed-Solomon para as camadas Medium e Large. Três camadas:
+
+
Small (< 4 MB): replicação do arquivo inteiro para r=7 pares, sem
+codificação de apagamento
+
Medium (4–256 MB): 16 shards de dados + 8 de paridade, distribuídos
+entre r=7 pares
+
Large (≥ 256 MB): 48 shards de dados + 24 de paridade, distribuídos
+entre r=7 pares
+
+
+
+
Distribuição (distributor.rs): filtragem de diversidade de sub-rede limita
+pares por sub-rede /24 IPv4 (ou prefixo /48 IPv6) para evitar falhas
+correlacionadas. Se todos os seus fragmentos caírem no mesmo rack, uma única
+queda de energia os elimina.
+
+
+
Serviço (service.rs): ReplicationService é o orquestrador.
+replicate_tessera() codifica os dados, encontra os pares mais próximos via
+DHT, aplica diversidade de sub-rede e distribui fragmentos em round-robin.
+receive_fragment() valida o checksum BLAKE3, verifica o saldo de
+reciprocidade (rejeita se o déficit do remetente exceder o limite
+configurado), armazena o fragmento e atualiza o livro-razão.
+handle_attestation_request() lista os fragmentos locais e calcula seus
+checksums como prova de posse.
+
+
+
Reparo (repair.rs): check_tessera_health() solicita atestações dos
+detentores conhecidos, recorre ao ping para nós não responsivos, verifica a
+integridade local dos fragmentos e retorna uma de três ações: Healthy,
+NeedsReplication { deficit } ou CorruptLocal { fragment_index }. O loop de
+reparo roda a cada 24 horas (com 2 horas de jitter) via tokio::select! com
+integração de desligamento.
+
+
+
Configuração (config.rs): ReplicationConfig com padrões para intervalo
+de reparo (24h), jitter (2h), transferências simultâneas (4), espaço livre
+mínimo (1 GB), tolerância de déficit (256 MB) e limite de armazenamento por
+par (1 GB).
+
+
+
tesd (atualizado) — O daemon agora abre um banco de dados SQLite
+(db/tesseras.db), executa migrações, cria instâncias de FsFragmentStore,
+SqliteReciprocityLedger e FsBlobStore, envolve o engine DHT em um
+DhtPortAdapter, constrói um ReplicationService e lança o loop de reparo como
+tarefa em segundo plano com desligamento gracioso.
+
Testes — 193 testes em todo o workspace:
+
+
15 testes unitários em tesseras-replication (camadas de codificação de
+fragmentos, validação de checksum, diversidade de sub-rede, verificações de
+saúde do reparo, fluxos de recebimento/replicação do serviço)
+
3 testes de integração com armazenamento real (ciclo completo
+codificar→distribuir→receber para tessera média, replicação de arquivo inteiro
+para tessera pequena, rejeição de fragmento adulterado)
+
Testes usam SQLite em memória + diretório temporário para fragmentos com mocks
+mockall para DHT e BlobStore
+
Zero avisos do clippy, formatação limpa
+
+
Decisões de arquitetura
+
+
Fragmentação em três camadas: arquivos pequenos não precisam de
+codificação de apagamento — o overhead não compensa. Arquivos médios e grandes
+recebem progressivamente mais shards de paridade. Isso evita desperdiçar
+armazenamento em tesseras pequenas enquanto oferece redundância forte para as
+grandes.
+
Distribuição por push do dono: o dono da tessera codifica os fragmentos e
+os envia aos pares, em vez dos pares puxarem. Isso simplifica o protocolo (sem
+fase de negociação) e garante que os fragmentos são distribuídos
+imediatamente.
+
Reciprocidade bilateral sem consenso: cada nó rastreia seu próprio saldo
+com cada par localmente. Sem livro-razão global, sem token, sem blockchain. Se
+o par A armazena 500 MB para o par B, o par B deveria armazenar
+aproximadamente 500 MB para o par A. Free riders perdem redundância
+gradualmente — seus fragmentos são despriorizados para reparo, mas nunca
+deletados.
+
Diversidade de sub-rede: os fragmentos são espalhados por diferentes
+sub-redes para sobreviver a falhas correlacionadas. Uma queda de datacenter
+não deveria eliminar todas as cópias de uma tessera.
+
Verificações de saúde por atestação primeiro: o loop de reparo pede aos
+detentores que provem posse (atestação com checksums) antes de declarar uma
+tessera degradada. Apenas quando a atestação falha é que ele recorre a um
+simples ping. Isso detecta corrupção silenciosa de dados, não apenas partida
+de nós.
+
+
O que vem a seguir
+
+
Fase 3: API e Apps — App Flutter mobile/desktop via flutter_rust_bridge,
+API GraphQL (async-graphql), nó WASM no navegador
+
Fase 4: Resiliência e Escala — Assinaturas pós-quânticas ML-DSA, travessia
+avançada de NAT, Compartilhamento de Segredo de Shamir para herdeiros,
+empacotamento para Alpine/Arch/Debian/FreeBSD/OpenBSD, CI no SourceHut
+
Fase 5: Exploração e Cultura — navegador público de tesseras, curadoria
+institucional, integração genealógica, exportação para mídia física
+
+
Os nós conseguem se encontrar e manter vivas as memórias uns dos outros. Em
+seguida, damos às pessoas uma forma de segurar suas memórias nas mãos.
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.
+
O que foi construído
+
tesseras-embedded — Um nó P2P completo que roda dentro de um app mobile. A
+struct EmbeddedNode é 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 (Mutex<Option<EmbeddedNode>>) 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.
+
Onze funções FFI são expostas para Dart via flutter_rust_bridge: ciclo de vida
+(node_start, node_stop, node_is_running), identidade (create_identity,
+get_identity), memórias (create_memory, get_timeline, get_memory) e
+status da rede (get_network_stats, get_replication_status). Todos os tipos
+que cruzam a fronteira FFI são structs planas com apenas String,
+Option<String>, Vec<String> e primitivos — sem trait objects, sem generics,
+sem lifetimes.
+
Quatro módulos adaptadores fazem a ponte entre as ports do core e as
+implementações concretas: Blake3HasherAdapter,
+Ed25519SignerAdapter/Ed25519VerifierAdapter para criptografia,
+DhtPortAdapter para operações DHT, e ReplicationHandlerAdapter para RPCs de
+fragmentos e atestação recebidos.
+
A feature flag bundled-sqlite 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.
+
App Flutter — 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.
+
O fluxo de onboarding 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.
+
A tela de timeline 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
+tela de criação de memória, que suporta seleção de foto da galeria ou câmera
+via image_picker, 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.
+
A tela de rede 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 tela de
+configurações exibe a identidade do usuário — nome, node ID truncado, chave
+pública truncada e data de criação.
+
Três providers Riverpod gerenciam o estado: nodeProvider inicia o nó embarcado
+ao abrir o app usando o diretório de documentos e para ao fazer dispose;
+identityProvider carrega o perfil existente ou cria um novo;
+timelineProvider busca a lista de memórias com paginação.
+
Testes — 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.
+
Decisões de arquitetura
+
+
Nó embarcado, não cliente-servidor: 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.
+
FFI síncrono: todas as funções flutter_rust_bridge são marcadas como
+#[frb(sync)] 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.
+
Singleton global: um global Mutex<Option<EmbeddedNode>> 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.
+
Tipos FFI planos: 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.
+
Onboarding de três telas: 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.
+
+
O que vem a seguir
+
+
Fase 4: Resiliência e Escala — 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
+
Fase 5: Exploração e Cultura — 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)
+
+
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.
Algumas memórias não são para todos. Um diário privado, uma carta para ser
+aberta em 2050, um segredo de família selado até que os netos tenham idade
+suficiente. Até agora, toda tessera na rede era aberta. A Fase 4 muda isso:
+Tesseras agora criptografa conteúdo privado e selado com um esquema
+criptográfico híbrido projetado para resistir tanto a ataques clássicos quanto
+quânticos.
+
O princípio continua o mesmo — criptografar o mínimo possível. Memórias públicas
+precisam de disponibilidade, não de sigilo. Mas quando alguém cria uma tessera
+privada ou selada, o conteúdo agora é trancado por criptografia AES-256-GCM com
+chaves protegidas por um mecanismo híbrido de encapsulamento de chaves
+combinando X25519 e ML-KEM-768. Ambos os algoritmos precisam ser quebrados para
+acessar o conteúdo.
+
O que foi construído
+
Encriptador AES-256-GCM (tesseras-crypto/src/encryption.rs) — Criptografia
+simétrica de conteúdo com nonces aleatórios de 12 bytes e dados autenticados
+associados (AAD). O AAD vincula o texto cifrado ao seu contexto: para tesseras
+privadas, o hash do conteúdo é incluído; para tesseras seladas, tanto o hash do
+conteúdo quanto o timestamp open_after são vinculados no AAD. Isso significa
+que mover texto cifrado entre tesseras com datas de abertura diferentes causa
+falha na decriptação — você não consegue enganar o sistema para abrir uma
+memória selada antecipadamente trocando o texto cifrado para uma tessera com uma
+data de selo anterior.
+
Mecanismo Híbrido de Encapsulamento de Chaves (tesseras-crypto/src/kem.rs)
+— Troca de chaves usando X25519 (Diffie-Hellman clássico em curva elíptica)
+combinado com ML-KEM-768 (o KEM pós-quântico baseado em reticulados padronizado
+pelo NIST, anteriormente Kyber). Ambos os segredos compartilhados são combinados
+via blake3::derive_key com uma string de contexto fixa ("tesseras hybrid kem
+v1") para produzir uma única chave de criptografia de conteúdo de 256 bits. Isso
+segue a mesma filosofia "dual desde o início" das assinaturas duplas do projeto
+(Ed25519 + ML-DSA): se qualquer algoritmo for quebrado no futuro, o outro ainda
+protege o conteúdo.
+
Envelope de Chave Selada (tesseras-crypto/src/sealed.rs) — Encapsula uma
+chave de criptografia de conteúdo usando o KEM híbrido, para que apenas o dono
+da tessera possa recuperá-la. O KEM produz uma chave de transporte, que é XORed
+com a chave de conteúdo para produzir uma chave encapsulada armazenada junto ao
+texto cifrado do KEM. Ao desselar, o dono decapsula o texto cifrado do KEM para
+recuperar a chave de transporte, depois faz XOR novamente para recuperar a chave
+de conteúdo.
+
Publicação de Chave (tesseras-crypto/src/sealed.rs) — Um artefato assinado
+independente para publicar a chave de conteúdo de uma tessera selada após a data
+open_after ter passado. O dono assina a chave de conteúdo, o hash da tessera e
+o timestamp de publicação com suas chaves duais (Ed25519, com placeholder
+ML-DSA). O manifesto permanece imutável — a publicação da chave é um documento
+separado. Outros nós verificam a assinatura contra a chave pública do dono antes
+de usar a chave publicada para decriptar o conteúdo.
+
EncryptionContext (tesseras-core/src/enums.rs) — Um tipo de domínio que
+representa o contexto AAD para criptografia. Ele vive em tesseras-core e não em
+tesseras-crypto porque é um conceito de domínio (não um detalhe de implementação
+criptográfica). O método to_aad_bytes() produz serialização determinística: um
+byte de tag (0x00 para Private, 0x01 para Sealed), seguido do hash de conteúdo
+e, para Sealed, o timestamp open_after como i64 little-endian.
+
Validação de domínio (tesseras-core/src/service.rs) —
+TesseraService::create() agora rejeita tesseras Sealed e Private que não
+fornecem chaves de criptografia. Esta é uma validação no nível de domínio: a
+camada de serviço garante que você não pode criar uma memória selada sem a
+maquinaria criptográfica para protegê-la. A mensagem de erro é clara: "missing
+encryption keys for visibility sealed until 2050-01-01."
+
Atualizações de tipos do core — TesseraIdentity agora inclui um campo
+opcional encryption_public: Option<HybridEncryptionPublic> contendo tanto as
+chaves públicas X25519 quanto ML-KEM-768. KeyAlgorithm ganhou as variantes
+X25519 e MlKem768. O layout do sistema de arquivos de identidade agora
+suporta node.x25519.key/.pub e node.mlkem768.key/.pub.
+
Testes — 8 testes unitários para AES-256-GCM (roundtrip, chave errada, texto
+cifrado adulterado, AAD errado, falha de decriptação cross-context, nonces
+únicos, mais 2 testes baseados em propriedades para payloads arbitrários e
+unicidade de nonces). 5 testes unitários para HybridKem (roundtrip, par de
+chaves errado, X25519 adulterado, determinismo do KDF, mais 1 teste baseado em
+propriedades). 4 testes unitários para SealedKeyEnvelope e KeyPublication. 2
+testes de integração cobrindo o ciclo de vida completo de tesseras seladas e
+privadas: gerar chaves, criar chave de conteúdo, criptografar, selar, desselar,
+decriptar, publicar chave e verificar — o ciclo completo.
+
Decisões de arquitetura
+
+
KEM híbrido desde o início: X25519 + ML-KEM-768 segue a mesma filosofia
+das assinaturas duplas. Não sabemos quais suposições criptográficas se
+manterão ao longo dos milênios, então combinamos algoritmos clássicos e
+pós-quânticos. O custo é ~1,2 KB de material de chave adicional por identidade
+— trivial comparado às fotos e vídeos em uma tessera.
+
BLAKE3 para KDF: ao invés de adicionar hkdf + sha2 como novas
+dependências, usamos blake3::derive_key com uma string de contexto fixa. O
+modo de derivação de chaves do BLAKE3 é especificamente projetado para este
+caso de uso, e o projeto já depende do BLAKE3 para hashing de conteúdo.
+
Manifestos imutáveis: quando a data open_after de uma tessera selada
+passa, a chave de conteúdo é publicada como um artefato assinado separado
+(KeyPublication), não modificando o manifesto. Isso preserva a natureza
+append-only e endereçada por conteúdo das tesseras. O manifesto foi assinado
+no momento da criação e nunca muda.
+
Vinculação AAD previne troca de texto cifrado: o EncryptionContext
+vincula tanto o hash de conteúdo quanto (para tesseras seladas) o timestamp
+open_after nos dados autenticados do AES-GCM. Um atacante que copie conteúdo
+criptografado de uma tessera "selada até 2050" para uma tessera "selada até
+2025" vai descobrir que a decriptação falha — o AAD não corresponde mais.
+
Encapsulamento de chave por XOR: o envelope de chave selada usa um XOR
+simples da chave de conteúdo com a chave de transporte derivada do KEM, ao
+invés de uma camada adicional de AES-GCM. Como a chave de transporte é um
+valor aleatório fresco do KEM e é usada exatamente uma vez, o XOR é
+informação-teoricamente seguro para este caso de uso específico e evita
+complexidade desnecessária.
+
Validação de domínio, não validação de storage: a verificação de "chaves
+de criptografia ausentes" vive em TesseraService::create(), não na camada de
+storage. Isso segue o padrão de arquitetura hexagonal: regras de domínio são
+aplicadas na fronteira de serviço, não espalhadas pelos adaptadores.
+
+
O que vem a seguir
+
+
Fase 4 continuada: Resiliência e Escala — Shamir's Secret Sharing para
+distribuição de chaves de herdeiros, NAT traversal avançado (STUN/TURN),
+ajuste de performance, auditorias de segurança, empacotamento para sistemas
+operacionais
+
Fase 5: Exploração e Cultura — 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)
+
+
Tesseras seladas fazem do Tesseras uma verdadeira cápsula do tempo. Um pai agora
+pode gravar uma mensagem para o neto que ainda não nasceu, selá-la até 2060 e
+saber que o envelope criptográfico vai resistir — mesmo que os computadores
+quânticos do futuro tentem abri-lo antes da hora.
Uma rede P2P composta apenas por individuos e fragil. Discos rigidos morrem,
+celulares sao perdidos, pessoas perdem interesse. A sobrevivencia a longo prazo
+das memorias da humanidade depende de instituicoes — bibliotecas, arquivos,
+museus, universidades — que medem seus tempos de vida em seculos. A Fase 4
+continua com o onboarding de nos institucionais: organizacoes verificadas agora
+podem prometer armazenamento, manter indices de busca e participar da rede com
+uma identidade distinta.
+
O design segue um principio de confiar mas verificar: instituicoes se
+identificam via registros DNS TXT (o mesmo mecanismo usado por SPF, DKIM e DMARC
+para email), prometem um orcamento de armazenamento e recebem isencoes de
+reciprocidade para que possam armazenar fragmentos para outros sem esperar nada
+em troca. Em contrapartida, a rede trata seus fragmentos como replicas de maior
+qualidade e limita a dependencia excessiva de qualquer instituicao individual
+atraves de restricoes de diversidade.
+
O que foi construido
+
Bits de capacidade (tesseras-core/src/network.rs) — Dois novos flags
+adicionados ao bitfield Capabilities: INSTITUTIONAL (bit 7) e SEARCH_INDEX
+(bit 8). Um novo construtor institutional_default() retorna o conjunto
+completo de capacidades da Fase 2 mais esses dois bits e RELAY. Nos normais
+anunciam phase2_default() que nao inclui flags institucionais. Testes de
+roundtrip de serializacao verificam que os novos bits sobrevivem a codificacao
+MessagePack.
+
Tipos de busca (tesseras-core/src/search.rs) — Tres novos tipos de dominio
+para o subsistema de busca:
SearchHit — um resultado individual: hash do conteudo mais um
+MetadataExcerpt (titulo, descricao, tipo de memoria, data de criacao,
+visibilidade, idioma, tags)
+
GeoFilter — bounding box com min_lat, max_lat, min_lon, max_lon para
+consultas espaciais
+
+
Todos os tipos derivam Serialize/Deserialize para transporte e
+Clone/Debug para diagnostico.
+
Configuracao institucional do daemon (tesd/src/config.rs) — Uma nova secao
+[institutional] no TOML com domain (o dominio DNS a verificar),
+pledge_bytes (compromisso de armazenamento em bytes) e search_enabled
+(toggle para o indice FTS5). O metodo to_dht_config() agora define
+Capabilities::institutional_default() quando a configuracao institucional esta
+presente, para que nos institucionais anunciem os bits de capacidade corretos em
+respostas Pong.
+
Verificacao DNS TXT (tesd/src/institutional.rs) — Resolucao DNS assincrona
+usando hickory-resolver para verificar identidade institucional. O daemon
+consulta registros TXT em _tesseras.<dominio> e analisa campos chave-valor:
+v (versao), node (node ID em hexadecimal) e pledge (compromisso de
+armazenamento em bytes). A verificacao checa:
+
+
Um registro TXT existe em _tesseras.<dominio>
+
O campo node corresponde ao node ID do proprio daemon
+
O campo pledge esta presente e e valido
+
+
Na inicializacao, o daemon tenta a verificacao DNS. Se bem-sucedida, o no roda
+com capacidades institucionais. Se falhar, o no registra um aviso e faz
+downgrade para um no completo normal — sem crash, sem intervencao manual.
+
Comando CLI de setup (tesseras-cli/src/institutional.rs) — Um novo
+subcomando institutional setup que guia operadores pelo onboarding:
+
+
Le a identidade do no a partir do diretorio de dados
+
Solicita nome de dominio e tamanho do pledge
+
Gera o registro DNS TXT exato a adicionar:
+v=tesseras1 node=<hex> pledge=<bytes>
+
Escreve a secao institucional no arquivo de configuracao do daemon
+
Imprime os proximos passos: adicionar o registro TXT, reiniciar o daemon
+
+
Indice de busca SQLite (tesseras-storage) — Uma migracao
+(003_institutional.sql) que cria tres estruturas:
+
+
search_content — uma tabela virtual FTS5 para busca full-text sobre
+metadados de tesseras (titulo, descricao, criador, tags, idioma)
+
geo_index — uma tabela virtual R-tree para consultas espaciais de bounding
+box sobre latitude/longitude
+
geo_map — uma tabela de mapeamento ligando IDs de linhas do R-tree a hashes
+de conteudo
+
+
O adaptador SqliteSearchIndex implementa o port trait SearchIndex com
+index_tessera() (inserir/atualizar) e search() (consultar com filtros).
+Consultas FTS5 suportam busca em linguagem natural; consultas geo usam
+INTERSECT do R-tree para lookups de bounding box. Resultados sao ranqueados
+por score de relevancia do FTS5.
+
A migracao tambem adiciona uma coluna is_institutional a tabela reciprocity,
+tratada de forma idempotente via checagens pragma_table_info (o
+ALTER TABLE ADD COLUMN do SQLite nao tem IF NOT EXISTS).
+
Bypass de reciprocidade (tesseras-replication/src/service.rs) — Nos
+institucionais sao isentos de checagens de reciprocidade. Quando
+receive_fragment() e chamado, se o node ID do remetente esta marcado como
+institucional no ledger de reciprocidade, a checagem de saldo e ignorada
+completamente. Isso significa que instituicoes podem armazenar fragmentos para
+toda a rede sem precisar "ganhar" creditos primeiro — sua identidade verificada
+por DNS e compromisso de armazenamento servem como credencial.
+
Restricao de diversidade por tipo de no
+(tesseras-replication/src/distributor.rs) — Uma nova funcao
+apply_institutional_diversity() limita quantas replicas de uma unica tessera
+podem ir para nos institucionais. O limite e ceil(fator_replicacao / 3.5) —
+com o padrao r=7, no maximo 2 de 7 replicas vao para instituicoes. Isso impede
+que a rede se torne dependente de um pequeno numero de grandes instituicoes: se
+os servidores de uma universidade cairem, pelo menos 5 replicas permanecem em
+nos independentes.
+
Extensoes de mensagens DHT (tesseras-dht/src/message.rs) — Duas novas
+variantes de mensagem:
+
Mensagem
Proposito
+
Search
Cliente envia string de consulta, filtros e numero da pagina
+
SearchResult
No institucional responde com resultados e contagem total
+
+
A funcao encode() foi trocada de serializacao MessagePack posicional para
+nomeada (rmp_serde::to_vec_named) para lidar corretamente com campos opcionais
+de SearchFilters — a codificacao posicional quebra quando
+skip_serializing_if omite campos.
tesseras_institutional_peers_served — peers unicos que receberam fragmentos
+
tesseras_institutional_search_index_total — tesseras no indice de busca
+
tesseras_institutional_search_queries_total — consultas de busca recebidas
+
tesseras_institutional_dns_verification_status — 1 se verificado por DNS, 0
+caso contrario
+
tesseras_institutional_dns_verification_last — timestamp Unix da ultima
+verificacao
+
+
Testes de integracao — Dois testes em
+tesseras-replication/tests/integration.rs:
+
+
institutional_peer_bypasses_reciprocity — verifica que um peer institucional
+com deficit massivo (-999.999 de saldo) ainda pode armazenar fragmentos,
+enquanto um peer nao institucional com o mesmo deficit e rejeitado
+
institutional_node_accepts_fragment_despite_deficit — teste async completo
+usando ReplicationService com DHT, fragment store, reciprocity ledger e blob
+store mockados: envia um fragmento de um remetente institucional e verifica
+que e aceito
+
+
322 testes passam em todo o workspace. Clippy limpo com -D warnings.
+
Decisoes de arquitetura
+
+
DNS TXT ao inves de PKI ou blockchain: DNS e universalmente implantado,
+universalmente compreendido e ja usado para verificacao de dominio (SPF, DKIM,
+Let's Encrypt). Instituicoes ja gerenciam DNS. Nenhuma autoridade
+certificadora, nenhum token, nenhuma transacao on-chain — apenas um registro
+TXT. Se uma instituicao perder controle de seu dominio, a verificacao
+naturalmente falha na proxima checagem.
+
Degradacao graciosa em falha DNS: se a verificacao DNS falha na
+inicializacao, o daemon faz downgrade para um no completo normal ao inves de
+recusar iniciar. Isso previne incidentes operacionais — uma misconfiguracao
+DNS nao deveria tirar um no do ar.
+
Limite de diversidade em ceil(r / 3.5): com r=7, no maximo 2 replicas
+vao para instituicoes. Isso e conservador — garante que a rede nunca dependa
+de instituicoes para quorum majoritario, enquanto ainda se beneficia de sua
+capacidade de armazenamento e uptime.
+
Codificacao MessagePack nomeada: trocar de codificacao posicional para
+nomeada adiciona ~15% de overhead por mensagem mas elimina uma classe de bugs
+de serializacao quando campos opcionais estao presentes. O DHT nao e limitado
+por largura de banda no nivel de mensagem, entao o tradeoff vale a pena.
+
Isencao de reciprocidade ao inves de concessao de creditos: ao inves de
+dar as instituicoes um saldo inicial grande de creditos (que e arbitrario e
+precisa de ajuste), isentamos completamente. Sua identidade verificada por DNS
+e compromisso publico de armazenamento substituem o mecanismo de reciprocidade
+bilateral.
+
FTS5 + R-tree no SQLite: busca full-text e indexacao espacial sao
+embutidas no SQLite como extensoes carregaveis. Nenhum motor de busca externo
+(Elasticsearch, Meilisearch) necessario. Isso mantem o deploy como um unico
+binario com um unico arquivo de banco de dados — critico para operadores
+institucionais que podem nao ter uma equipe de DevOps.
+
+
O que vem a seguir
+
+
Fase 4 continuacao — deduplicacao de armazenamento (armazenamento
+enderecavel por conteudo com BLAKE3), auditorias de seguranca, empacotamento
+para OS (Alpine, Arch, Debian, OpenBSD, FreeBSD)
+
Fase 5: Exploracao e Cultura — navegador publico de tesseras por
+era/localizacao/tema/idioma, curadoria institucional, integracao genealogica
+(FamilySearch, Ancestry), exportacao para midia fisica (M-DISC, microfilme,
+papel livre de acido com QR), contexto assistido por IA
+
+
O onboarding institucional fecha uma lacuna critica no modelo de preservacao do
+Tesseras. Nos individuais fornecem resiliencia de base — milhares de
+dispositivos ao redor do globo, cada um armazenando alguns fragmentos. Nos
+institucionais fornecem ancoragem — organizacoes com infraestrutura
+profissional, armazenamento redundante e horizontes operacionais de multiplas
+decadas. Juntos, formam uma rede onde memorias podem sobreviver tanto a
+dispositivos individuais quanto a instituicoes individuais.
A maioria dos dispositivos das pessoas ficam atras de um NAT — um tradutor de
+enderecos de rede que permite acessar a internet mas impede conexoes de entrada.
+Para uma rede P2P, isso e um problema existencial: se dois nos atras de NATs nao
+conseguem se comunicar, a rede se fragmenta. A Fase 4 continua com uma pilha
+completa de travessia de NAT: descoberta via STUN, hole punching coordenado e
+fallback por relay.
+
A abordagem segue o mesmo padrao da maioria dos sistemas P2P consolidados
+(WebRTC, BitTorrent, IPFS): tente a opcao mais barata primeiro, escale apenas
+quando necessario. Conectividade direta nao custa nada. Hole punching custa
+alguns pacotes coordenados. Relay custa largura de banda sustentada de um
+terceiro. Tesseras tenta nessa ordem.
+
O que foi construido
+
Classificacao NatType (tesseras-core/src/network.rs) — Um novo enum
+NatType (Public, Cone, Symmetric, Unknown) adicionado a camada de dominio
+core. Esse tipo e compartilhado por toda a pilha: o cliente STUN o escreve, o
+DHT o divulga em mensagens Pong, e o coordenador de punch o le para decidir se
+hole punching vale a pena tentar (Cone-para-Cone funciona ~80% das vezes;
+Symmetric-para-Symmetric quase nunca funciona).
+
Cliente STUN (tesseras-net/src/stun.rs) — Uma implementacao STUN minima
+(RFC 5389 Binding Request/Response) que descobre o endereco externo de um no. O
+codec codifica requisicoes de 20 bytes com um ID de transacao aleatorio e
+decodifica respostas XOR-MAPPED-ADDRESS. A funcao discover_nat() consulta
+multiplos servidores STUN em paralelo (Google, Cloudflare por padrao), compara
+os enderecos mapeados e classifica o tipo de NAT:
+
+
Mesmo IP e porta de todos os servidores → Public (sem NAT)
+
Mesmo endereco mapeado de todos os servidores → Cone (hole punching
+funciona)
+
Enderecos mapeados diferentes → Symmetric (hole punching nao confiavel)
+
Sem respostas → Unknown
+
+
Retentativas com backoff exponencial e timeouts configuraveis. 12 testes
+cobrindo roundtrips de codec, todos os caminhos de classificacao e consultas
+async em loopback.
+
Coordenacao de punch assinada (tesseras-net/src/punch.rs) — Assinatura e
+verificacao Ed25519 para mensagens PunchIntro, RelayRequest e
+RelayMigrate. Cada introducao e assinada pelo iniciador com uma janela de
+timestamp de 30 segundos, prevenindo ataques de reflexao (onde um atacante
+reproduz uma introducao antiga para redirecionar trafego). O formato do payload
+e target || external_addr || timestamp — alterar qualquer campo invalida a
+assinatura. 6 testes unitarios mais 3 testes baseados em propriedades com
+proptest (IDs de no, portas e tokens de sessao arbitrarios).
+
Gerenciador de sessoes de relay (tesseras-net/src/relay.rs) — Gerencia
+sessoes de relay UDP transparente entre nos com NAT. Cada sessao tem um token
+aleatorio de 16 bytes; os nos prefixam seus pacotes com o token, o relay remove
+e encaminha. Funcionalidades:
+
+
Encaminhamento bidirecional (A→R→B e B→R→A)
+
Limite de taxa: 256 KB/s para nos reciprocos, 64 KB/s para nao reciprocos
+
Duracao maxima de 10 minutos para sessoes bootstrap (nao reciprocas)
+
Migracao de endereco: quando o IP de um no muda (Wi-Fi para celular), um
+RelayMigrate assinado atualiza a sessao sem derruba-la
+
Limpeza por inatividade com timeout configuravel
+
8 testes unitarios mais 2 testes baseados em propriedades
+
+
Extensoes de mensagens DHT (tesseras-dht/src/message.rs) — Sete novas
+variantes de mensagem adicionadas ao protocolo DHT:
+
Mensagem
Proposito
+
PunchIntro
"Quero conectar ao no X, aqui esta meu endereco externo assinado"
+
PunchRequest
O introdutor encaminha a requisicao ao destino
+
PunchReady
O destino confirma prontidao, envia seu endereco externo
+
RelayRequest
"Crie uma sessao de relay para o no X"
+
RelayOffer
O relay responde com seu endereco e token de sessao
+
RelayClose
Encerrar uma sessao de relay
+
RelayMigrate
Atualizar sessao apos mudanca de rede
+
+
A mensagem Pong foi estendida com metadados NAT: nat_type,
+relay_slots_available e relay_bandwidth_used_kbps. Todos os novos campos
+usam #[serde(default)] para compatibilidade retroativa — nos antigos ignoram o
+que nao reconhecem, nos novos usam defaults. 9 novos testes de roundtrip de
+serializacao.
+
Trait NatHandler e dispatch (tesseras-dht/src/engine.rs) — Uma nova trait
+async NatHandler (5 metodos) injetada no engine DHT, seguindo o mesmo padrao
+de injecao de dependencia do ReplicationHandler existente. O loop de dispatch
+de mensagens do engine agora roteia todas as mensagens punch/relay para o
+handler. Isso mantem o engine DHT agnóstico ao protocolo enquanto permite que a
+logica de travessia de NAT viva em tesseras-net.
+
Tipos de reconexao mobile (tesseras-embedded/src/reconnect.rs) — Uma
+maquina de estados de reconexao em tres fases para dispositivos moveis:
+
+
QuicMigration (0-2s) — tenta migracao de conexao QUIC para todos os peers
+ativos
+
ReStun (2-5s) — redescobre endereco externo via STUN
+
ReEstablish (5-10s) — reconecta peers que a migracao nao conseguiu salvar
+
+
Peers sao reconectados em ordem de prioridade: nos bootstrap primeiro, depois
+nos que guardam nossos fragmentos, depois nos cujos fragmentos guardamos, depois
+vizinhos DHT gerais. Uma nova variante de evento NetworkChanged foi adicionada
+ao stream de eventos FFI para que o app Flutter possa mostrar progresso de
+reconexao.
+
Configuracao NAT do daemon (tesd/src/config.rs) — Uma nova secao [nat]
+na configuracao TOML com lista de servidores STUN, toggle de relay, maximo de
+sessoes relay, limites de largura de banda (reciproco vs bootstrap) e timeout de
+inatividade. Todos os campos tem defaults sensiveis; relay e desabilitado por
+padrao.
+
Metricas Prometheus (tesseras-net/src/metrics.rs) — 16 metricas em quatro
+subsistemas:
+
+
STUN: requisicoes, falhas, histograma de latencia
+
Punch: tentativas/sucessos/falhas (por par de tipo NAT), histograma de
+latencia
+
Relay: sessoes ativas, sessoes totais, bytes encaminhados, timeouts por
+inatividade, hits de rate limit
+
Reconexao: mudancas de rede, tentativas/sucessos por fase, histograma de
+duracao
+
+
6 testes verificando registro, incremento, cardinalidade de labels e deteccao de
+registro duplo.
+
Testes de integracao — Dois testes end-to-end usando MemTransport (rede
+simulada em memoria):
+
+
punch_integration.rs — Fluxo completo de hole-punch com 3 nos: A envia
+PunchIntro assinado ao introdutor I, I verifica e encaminha PunchRequest a
+B, B verifica a assinatura original e envia PunchReady de volta, A e B
+trocam mensagens diretamente. Tambem testa que uma assinatura invalida e
+corretamente rejeitada.
+
relay_integration.rs — Fluxo completo de relay com 3 nos: A solicita relay
+de R, R cria sessao e envia RelayOffer a ambos os peers, A e B trocam
+pacotes prefixados com token atraves de R, A migra para um novo endereco no
+meio da sessao, A fecha a sessao, e o teste verifica que a sessao e encerrada
+e encaminhamento posterior falha.
+
+
Testes de propriedade — 7 testes baseados em proptest cobrindo: roundtrips
+de assinatura para todos os tres tipos de mensagem assinada (IDs de no, portas e
+tokens arbitrarios), determinismo de classificacao NAT (mesmas entradas sempre
+produzem mesma saida), validade de binding request STUN, unicidade de tokens de
+sessao, e rejeicao de pacotes curtos pelo relay.
+
Alvos Justfile — just test-nat executa todos os testes de travessia NAT em
+tesseras-net e tesseras-dht. just test-chaos e um placeholder para futuros
+testes de caos com Docker Compose e tc netem.
+
Decisoes de arquitetura
+
+
STUN ao inves de TURN: implementamos STUN (descoberta) e relay customizado
+ao inves de TURN completo. TURN requer alocacao autenticada e foi projetado
+para relay de midia; nosso relay e mais simples — encaminhamento UDP com
+prefixo de token e limites de taxa. Isso mantem o protocolo minimo e evita
+depender de servidores TURN externos.
+
Assinaturas em introducoes: cada PunchIntro e assinado pelo iniciador.
+Sem isso, um atacante poderia enviar introducoes forjadas para redirecionar as
+tentativas de hole-punch de um no para um endereco controlado pelo atacante
+(ataque de reflexao). A janela de timestamp de 30 segundos limita replay.
+
Tiers reciprocos de largura de banda: nos relay dao 4x mais largura de
+banda (256 vs 64 KB/s) para peers com boas pontuacoes de reciprocidade. Isso
+incentiva nos a armazenar fragmentos para outros — se voce contribui, recebe
+melhor servico de relay quando precisa.
+
Extensao Pong retrocompativel: novos campos NAT em Pong usam
+#[serde(default)] e Option<T>. Nos antigos que nao entendem esses campos
+simplesmente os pulam durante deserializacao. Nenhum bump de versao de
+protocolo necessario.
+
NatHandler como trait async: a logica de travessia NAT e injetada no
+engine DHT via trait, assim como ReplicationHandler. Isso mantem o engine
+DHT focado em roteamento e gerenciamento de peers, e permite que a
+implementacao NAT seja trocada ou desabilitada sem tocar no codigo core do
+DHT.
+
+
O que vem a seguir
+
+
Fase 4 continuacao — tuning de performance (pooling de conexoes, cache de
+fragmentos, SQLite WAL), auditorias de seguranca, onboarding de nos
+institucionais, empacotamento para OS
+
Fase 5: Exploracao e Cultura — navegador publico de tesseras por
+era/localizacao/tema/idioma, curadoria institucional, integracao genealogica,
+exportacao para midia fisica (M-DISC, microfilme, papel livre de acido com QR)
+
+
Com travessia de NAT, Tesseras pode conectar nos independentemente de sua
+topologia de rede. Nos publicos conversam diretamente. Nos com NAT Cone furam
+com ajuda de um introdutor. Nos com NAT Symmetric ou firewalled usam relay
+atraves de peers voluntarios. A rede se adapta ao mundo real, onde a maioria dos
+dispositivos esta atras de um NAT e as condicoes de rede mudam constantemente.
Uma rede P2P que atravessa NATs mas engasga com seu proprio I/O nao serve de
+muito. A Fase 4 continua com tuning de performance: centralizacao da
+configuracao do banco de dados, cache de blobs de fragmentos em memoria,
+gerenciamento de ciclo de vida de conexoes QUIC e eliminacao de leituras
+desnecessarias de disco no hot path de atestacao.
+
O principio orientador foi o mesmo do resto do Tesseras: fazer a coisa mais
+simples que realmente funciona. Sem alocadores customizados, sem estruturas de
+dados lock-free, sem complexidade prematura. Um StorageConfig centralizado, um
+cache LRU, um reaper de conexoes e uma correcao pontual para evitar reler blobs
+que ja tinham checksum calculado.
+
O que foi construido
+
Configuracao SQLite centralizada (tesseras-storage/src/database.rs) — Um
+novo struct StorageConfig e funcoes open_database() / open_in_memory() que
+aplicam todos os pragmas SQLite em um unico lugar: journal mode WAL, foreign
+keys, modo synchronous (NORMAL por padrao, FULL para hardware instavel como
+RPi + cartao SD), busy timeout, tamanho do cache de paginas e intervalo de
+autocheckpoint WAL. Anteriormente, cada ponto de chamada abria uma conexao e
+aplicava pragmas ad hoc. Agora o daemon, CLI e testes passam todos pelo mesmo
+caminho. 7 testes cobrindo foreign keys, busy timeout, journal mode, migracoes,
+modos synchronous e criacao de arquivos WAL em disco.
+
Cache LRU de fragmentos (tesseras-storage/src/cache.rs) — Um
+CachedFragmentStore que envolve qualquer FragmentStore com um cache LRU
+ciente de bytes. Blobs de fragmentos sao cacheados na leitura e invalidados na
+escrita ou exclusao. Quando o cache excede seu limite de bytes configurado, as
+entradas menos recentemente usadas sao removidas. O cache e transparente: ele
+proprio implementa FragmentStore, entao o resto da pilha nao sabe que esta la.
+Metricas Prometheus opcionais rastreiam hits, misses e uso atual de bytes. 3
+testes: hit no cache evita leitura interna, store invalida cache, remocao quando
+excede bytes maximos.
+
Metricas Prometheus de storage (tesseras-storage/src/metrics.rs) — Um
+struct StorageMetrics com tres contadores/gauges: fragment_cache_hits,
+fragment_cache_misses e fragment_cache_bytes. Registrado no registry
+Prometheus e conectado ao cache de fragmentos via with_metrics().
+
Correcao do hot path de atestacao (tesseras-replication/src/service.rs) —
+O fluxo de atestacao anteriormente lia cada blob de fragmento do disco e
+recalculava seu checksum BLAKE3. Como list_fragments() ja retorna FragmentId
+com um checksum armazenado, a correcao e trivial: usar frag.checksum ao inves
+de blake3::hash(&data). Isso elimina uma leitura de disco por fragmento
+durante atestacao — para uma tessera com 100 fragmentos, sao 100 leituras a
+menos. Um teste com expect_read_fragment().never() verifica que nenhuma
+leitura de blob acontece durante atestacao.
+
Ciclo de vida do pool de conexoes QUIC
+(tesseras-net/src/quinn_transport.rs) — Um struct PoolConfig controlando
+maximo de conexoes, timeout de inatividade e intervalo do reaper.
+PooledConnection envolve cada quinn::Connection com um timestamp
+last_used. Quando o pool atinge capacidade maxima, a conexao inativa mais
+antiga e removida antes de abrir uma nova. Uma tarefa reaper em background
+(Tokio spawn) periodicamente fecha conexoes que ficaram inativas alem do
+timeout. 4 novas metricas de pool: tesseras_conn_pool_size, pool_hits_total,
+pool_misses_total, pool_evictions_total.
+
Integracao no daemon (tesd/src/config.rs, main.rs) — Uma nova secao
+[performance] na configuracao TOML com campos para tamanho de cache SQLite,
+modo synchronous, busy timeout, tamanho de cache de fragmentos, maximo de
+conexoes, timeout de inatividade e intervalo do reaper. O main() do daemon
+agora chama open_database() com o StorageConfig configurado, envolve
+FsFragmentStore com CachedFragmentStore e vincula QUIC com o PoolConfig
+configurado. A dependencia direta de rusqlite foi removida do crate do daemon.
+
Migracao do CLI (tesseras-cli/src/commands/init.rs, create.rs) — Ambos
+os comandos init e create agora usam tesseras_storage::open_database() com
+o StorageConfig padrao ao inves de abrir conexoes rusqlite diretamente. A
+dependencia de rusqlite foi removida do crate do CLI.
+
Decisoes de arquitetura
+
+
Padrao decorator para cache: CachedFragmentStore envolve
+Box<dyn FragmentStore> e implementa FragmentStore ele proprio. Isso
+significa que cache e opt-in, composavel e invisivel para consumidores. O
+daemon habilita; testes podem pular.
+
Remocao ciente de bytes: o cache LRU rastreia bytes totais, nao contagem
+de entradas. Blobs de fragmentos variam muito em tamanho (um fragmento de
+texto de 4KB vs um shard de foto de 2MB), entao contar entradas daria uma
+visao enganosa do uso de memoria.
+
Sem crate de pool de conexoes: ao inves de trazer uma biblioteca generica
+de pool, o pool de conexoes e um wrapper fino sobre
+DashMap<SocketAddr, PooledConnection> com um reaper Tokio. Conexoes QUIC sao
+multiplexadas, entao o "pool" e realmente sobre gerenciamento de ciclo de vida
+(limpeza de inativos, maximo de conexoes) e nao sobre emprestar/devolver.
+
Checksums armazenados ao inves de releituras: a correcao de atestacao e
+intencionalmente minima — uma linha alterada, uma leitura de disco removida
+por fragmento. Os checksums ja estavam armazenados no SQLite por
+store_fragment(), apenas nao estavam sendo usados.
+
Configuracao centralizada de pragmas: um unico struct StorageConfig
+substitui chamadas PRAGMA espalhadas. O flag sqlite_synchronous_full
+existe especificamente para implantacoes em Raspberry Pi onde o kernel pode
+crashar e perder transacoes WAL nao checkpointadas.
+
+
O que vem a seguir
+
+
Fase 4 continuacao — Shamir's Secret Sharing para herdeiros, tesseras
+seladas (criptografia time-lock), auditorias de seguranca, onboarding de nos
+institucionais, deduplicacao de storage, empacotamento para OS
+
Fase 5: Exploracao e Cultura — navegador publico de tesseras por
+era/localizacao/tema/idioma, curadoria institucional, integracao genealogica,
+exportacao para midia fisica (M-DISC, microfilme, papel livre de acido com QR)
+
+
Com tuning de performance implementado, Tesseras lida com o caso comum de forma
+eficiente: leituras de fragmentos acertam o cache LRU, atestacao pula I/O de
+disco, conexoes QUIC inativas sao removidas automaticamente e o SQLite e
+configurado consistentemente em toda a pilha. Os proximos passos focam em
+funcionalidades criptograficas (Shamir, time-lock) e hardening para implantacao
+em producao.
+
+
+
+
+
+
+
+
diff --git a/pt-br/news/phase4-performance-tuning/index.html.gz b/pt-br/news/phase4-performance-tuning/index.html.gz
new file mode 100644
index 0000000..a0428ab
Binary files /dev/null and b/pt-br/news/phase4-performance-tuning/index.html.gz differ
diff --git a/pt-br/news/phase4-shamir-heir-recovery/index.html b/pt-br/news/phase4-shamir-heir-recovery/index.html
new file mode 100644
index 0000000..d2df99f
--- /dev/null
+++ b/pt-br/news/phase4-shamir-heir-recovery/index.html
@@ -0,0 +1,209 @@
+
+
+
+
+
+ Fase 4: Recuperação de Chaves por Herdeiros com Shamir's Secret Sharing — Tesseras
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Fase 4: Recuperação de Chaves por Herdeiros com Shamir's Secret Sharing
+
2026-02-15
+
O que acontece com suas memórias quando você morre? Até agora, Tesseras
+conseguia preservar conteúdo ao longo de milênios — mas as chaves privadas e
+seladas morriam com o dono. A Fase 4 continua com uma solução: Shamir's Secret
+Sharing, um esquema criptográfico que permite dividir sua identidade em
+fragmentos e distribuí-los para as pessoas em quem você mais confia.
+
A matemática é elegante: você escolhe um limiar T e um total N. Qualquer T
+fragmentos reconstroem o segredo completo; T-1 fragmentos não revelam
+absolutamente nada. Isso não é "quase nada" — é informação-teoricamente seguro.
+Um atacante com um fragmento a menos que o limiar tem exatamente zero bits de
+informação sobre o segredo, independentemente do poder computacional que tenha.
+
O que foi construído
+
Aritmética de corpo finito GF(256) (tesseras-crypto/src/shamir/gf256.rs) —
+Shamir's Secret Sharing requer aritmética em um corpo finito. Implementamos
+GF(256) usando o mesmo polinômio irredutível do AES (x^8 + x^4 + x^3 + x + 1),
+com tabelas de lookup para logaritmo e exponenciação computadas em tempo de
+compilação. Todas as operações são em tempo constante via consulta a tabelas —
+sem ramificações baseadas em dados secretos. O módulo inclui o método de Horner
+para avaliação de polinômios e interpolação de Lagrange em x=0 para recuperação
+do segredo. 233 linhas, exaustivamente testado: todos os 256 elementos para
+propriedades de identidade/inverso, comutatividade e associatividade.
+
ShamirSplitter (tesseras-crypto/src/shamir/mod.rs) — A API principal de
+split/reconstruct. split() recebe uma fatia de bytes do segredo, uma
+configuração (limiar T, total N) e a chave pública Ed25519 do dono. Para cada
+byte do segredo, constrói um polinômio aleatório de grau T-1 sobre GF(256) com o
+byte do segredo como termo constante, e então o avalia em N pontos distintos.
+reconstruct() recebe T ou mais fragmentos e recupera o segredo via
+interpolação de Lagrange. Ambas as operações incluem validação extensiva:
+limites do limiar, consistência de sessão, correspondência de impressão digital
+do dono e verificação de checksum BLAKE3.
+
Formato HeirShare — Cada fragmento é um artefato autocontido e serializável
+com:
+
+
Versão do formato (v1) para compatibilidade futura
+
Índice do fragmento (1..N) e metadados de limiar/total
+
ID de sessão (8 bytes aleatórios) — impede mistura de fragmentos de sessões
+diferentes
+
Impressão digital do dono (primeiros 8 bytes do hash BLAKE3 da chave pública
+Ed25519)
+
Dados do fragmento (os y-values de Shamir, mesmo comprimento do segredo)
+
Checksum BLAKE3 sobre todos os campos anteriores
+
+
Os fragmentos são serializados em dois formatos: MessagePack (binário
+compacto, para uso programático) e texto base64 (legível por humanos, para
+impressão e armazenamento físico). O formato texto inclui um cabeçalho com
+metadados e delimitadores:
Este formato é projetado para ser impresso em papel, armazenado em um cofre
+bancário ou gravado em metal. O cabeçalho é informacional — apenas o payload
+base64 é analisado durante a reconstrução.
+
Integração com CLI (tesseras-cli/src/commands/heir.rs) — Três novos
+subcomandos:
+
+
tes heir create — divide sua identidade Ed25519 em fragmentos de herdeiros.
+Solicita confirmação (sua identidade completa está em jogo), gera arquivos
+.bin e .txt para cada fragmento e escreve heir_meta.json no diretório de
+identidade.
+
tes heir reconstruct — carrega arquivos de fragmentos (detecta
+automaticamente formato binário vs texto), valida consistência, reconstrói o
+segredo, deriva o par de chaves Ed25519 e opcionalmente o instala em
+~/.tesseras/identity/ (com backup automático da identidade existente).
+
tes heir info — exibe metadados do fragmento e verifica o checksum sem expor
+nenhum material secreto.
+
+
Formato do blob secreto — As chaves de identidade são serializadas em um
+blob versionado antes da divisão: um byte de versão (0x01), um byte de flags
+(0x00 para somente Ed25519), seguido da chave secreta Ed25519 de 32 bytes. Isso
+deixa espaço para expansão futura quando as chaves privadas X25519 e ML-KEM-768
+forem integradas ao sistema de fragmentos de herdeiros.
+
Testes — 20 testes unitários para ShamirSplitter (roundtrip, todas as
+combinações de fragmentos, fragmentos insuficientes, dono errado, sessão errada,
+limite threshold-1, segredos grandes até o tamanho de chave ML-KEM-768). 7
+testes unitários para aritmética GF(256) (propriedades de campo exaustivas). 3
+testes baseados em propriedades com proptest (segredos arbitrários até 5000
+bytes, configurações T-de-N arbitrárias, verificação de segurança
+informação-teórica). Testes de roundtrip de serialização para ambos os formatos
+MessagePack e texto base64. 2 testes de integração cobrindo o ciclo de vida
+completo de herdeiros: gerar identidade, dividir em fragmentos, serializar,
+desserializar, reconstruir, verificar par de chaves e assinar/verificar com
+chaves reconstruídas.
+
Decisões de arquitetura
+
+
GF(256) ao invés de GF(primo): usamos GF(256) ao invés de um corpo primo
+porque ele mapeia naturalmente para bytes — cada elemento é um único byte,
+cada fragmento tem o mesmo comprimento do segredo. Sem aritmética de inteiros
+grandes, sem redução modular, sem padding. Esta é a mesma abordagem usada pela
+maioria das implementações reais de Shamir, incluindo SSSS e Hashicorp Vault.
+
Tabelas de lookup em tempo de compilação: as tabelas LOG e EXP para
+GF(256) são computadas em tempo de compilação usando const fn. Isso
+significa zero custo de inicialização em tempo de execução e operações em
+tempo constante via consulta a tabelas ao invés de loops.
+
ID de sessão previne mistura entre sessões: cada chamada a split() gera
+um novo ID de sessão aleatório. Se um herdeiro acidentalmente usar fragmentos
+de duas sessões diferentes de divisão (por exemplo, antes e depois de uma
+rotação de chaves), a reconstrução falha de forma limpa com um erro de
+validação ao invés de produzir dados corrompidos.
+
Checksums BLAKE3 detectam corrupção: cada fragmento inclui um checksum
+BLAKE3 sobre seu conteúdo. Isso captura degradação de bits, erros de
+transmissão e truncamento acidental antes de qualquer tentativa de
+reconstrução. Um fragmento impresso em papel e escaneado via OCR vai falhar no
+checksum se um único caractere estiver errado.
+
Impressão digital do dono para identificação: os fragmentos incluem os
+primeiros 8 bytes de BLAKE3(chave pública Ed25519) como impressão digital.
+Isso permite aos herdeiros verificar a qual identidade um fragmento pertence
+sem revelar a chave pública completa. Durante a reconstrução, a impressão
+digital é verificada contra a chave recuperada.
+
Formato duplo para resiliência: ambos os formatos binário (MessagePack) e
+texto (base64) são gerados porque mídias físicas têm modos de falha diferentes
+de armazenamento digital. Um pendrive pode falhar; papel sobrevive. Um QR code
+pode ficar ilegível; texto base64 pode ser digitado manualmente.
+
Versionamento do blob: o segredo é envolvido em um blob versionado
+(versão + flags + material de chave) para que versões futuras possam incluir
+chaves adicionais (X25519, ML-KEM-768) sem quebrar compatibilidade com
+fragmentos existentes.
+
+
O que vem a seguir
+
+
Fase 4 continuada: Resiliência e Escala — NAT traversal avançado
+(STUN/TURN), ajuste de performance (pool de conexões, cache de fragmentos,
+SQLite WAL), auditorias de segurança, integração de nós institucionais,
+empacotamento para sistemas operacionais
+
Fase 5: Exploração e Cultura — 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)
+
+
Com Shamir's Secret Sharing, Tesseras fecha a última lacuna crítica na
+preservação a longo prazo. Suas memórias sobrevivem a falhas de infraestrutura
+através de erasure coding. Sua privacidade sobrevive a computadores quânticos
+através de criptografia híbrida. E agora, sua identidade sobrevive a você —
+passada adiante para as pessoas que você escolheu, exigindo a cooperação delas
+para desbloquear o que você deixou para trás.
Quando multiplas tesseras compartilham a mesma foto, o mesmo clipe de audio ou
+os mesmos dados de fragmento, a camada de armazenamento antiga mantinha copias
+separadas de cada. Em um no armazenando milhares de tesseras para a rede, essa
+duplicacao se acumula rapidamente. A Fase 4 continua com deduplicacao de
+armazenamento: um armazenamento enderecavel por conteudo (CAS) que garante que
+cada dado unico seja armazenado exatamente uma vez em disco, independentemente
+de quantas tesseras o referenciam.
+
O design e simples e comprovado: hash do conteudo com BLAKE3, usar o hash como
+nome do arquivo e manter uma contagem de referencias no SQLite. Quando duas
+tesseras incluem a mesma foto de 5 MB, um arquivo existe em disco com
+refcount 2. Quando uma tessera e deletada, o refcount cai para 1 e o arquivo
+permanece. Quando a ultima referencia e liberada, uma varredura periodica limpa
+o orfao.
+
O que foi construido
+
Migracao do esquema CAS (tesseras-storage/migrations/004_dedup.sql) — Tres
+novas tabelas:
+
+
cas_objects — rastreia cada objeto no armazenamento: hash BLAKE3 (chave
+primaria), tamanho em bytes, contagem de referencias e timestamp de criacao
+
blob_refs — mapeia identificadores logicos de blobs (hash da tessera + hash
+da memoria + nome do arquivo) para hashes CAS, substituindo a convencao antiga
+de caminhos no sistema de arquivos
+
fragment_refs — mapeia identificadores logicos de fragmentos (hash da
+tessera + indice do fragmento) para hashes CAS, substituindo o antigo layout
+do diretorio fragments/
+
+
Indices nas colunas de hash garantem lookups O(1) durante leituras e contagem de
+referencias.
+
CasStore (tesseras-storage/src/cas.rs) — O motor central de armazenamento
+enderecavel por conteudo. Arquivos sao armazenados sob um diretorio de prefixo
+de dois niveis: <raiz>/<prefixo-hex-2-chars>/<hash-completo>.blob. O
+armazenamento fornece cinco operacoes:
+
+
put(hash, data) — escreve dados em disco se ainda nao presente, incrementa o
+refcount. Retorna se ocorreu um hit de deduplicacao.
+
get(hash) — le dados do disco pelo hash
+
release(hash) — decrementa o refcount. Se chegar a zero, o arquivo em disco
+e deletado imediatamente.
+
contains(hash) — verifica existencia sem ler
+
ref_count(hash) — retorna a contagem de referencias atual
+
+
Todas as operacoes sao atomicas dentro de uma unica transacao SQLite. O refcount
+e a fonte de verdade — se o refcount diz que o objeto existe, o arquivo deve
+estar em disco.
+
FsBlobStore com CAS (tesseras-storage/src/blob.rs) — Reescrito para
+delegar todo armazenamento ao CAS. Quando um blob e escrito, seu hash BLAKE3 e
+computado e passado para cas.put(). Uma linha em blob_refs mapeia o caminho
+logico (tessera + memoria + arquivo) para o hash CAS. Leituras buscam o hash CAS
+via blob_refs e leem de cas.get(). Deletar uma tessera libera todas as suas
+referencias de blob em uma unica transacao.
+
FsFragmentStore com CAS (tesseras-storage/src/fragment.rs) — Mesmo padrao
+para fragmentos codificados com erasure coding. O checksum BLAKE3 de cada
+fragmento ja e computado durante a codificacao Reed-Solomon, entao e usado
+diretamente como chave CAS. A verificacao de fragmentos agora checa o hash CAS
+ao inves de recomputar do zero — se o CAS diz que os dados estao intactos,
+estao.
+
Coletor de lixo sweep (cas.rs:sweep()) — Uma passagem periodica de GC que
+trata tres casos limite que o caminho normal de refcount nao consegue:
+
+
Arquivos orfaos — arquivos em disco sem linha correspondente em
+cas_objects. Pode acontecer apos um crash durante escrita. Arquivos com
+menos de 1 hora sao pulados (periodo de graca para escritas em andamento);
+orfaos mais antigos sao deletados.
+
Refcounts vazados — linhas em cas_objects com refcount zero que nao
+foram limpas (ex: se o processo morreu entre decrementar e deletar). Essas
+linhas sao removidas.
+
Idempotente — executar sweep duas vezes produz o mesmo resultado.
+
+
O sweep e conectado ao loop de reparo existente em tesseras-replication, entao
+roda automaticamente a cada 24 horas junto com as verificacoes de saude dos
+fragmentos.
+
Migracao do layout antigo (tesseras-storage/src/migration.rs) — Uma
+estrategia de migracao copy-first que move dados do layout antigo baseado em
+diretorios (blobs/<tessera>/<memoria>/<arquivo> e
+fragments/<tessera>/<indice>.shard) para o CAS. A migracao:
+
+
Verifica a versao de armazenamento em storage_meta (versao 1 = layout
+antigo, versao 2 = CAS)
+
Percorre os diretorios antigos blobs/ e fragments/
+
Computa hashes BLAKE3 e insere no CAS via put() — duplicatas sao
+automaticamente deduplicadas
+
Cria entradas correspondentes em blob_refs / fragment_refs
+
Remove diretorios antigos somente apos todos os dados estarem seguros no CAS
+
Atualiza a versao de armazenamento para 2
+
+
A migracao roda na inicializacao do daemon, e idempotente (segura para
+re-executar) e reporta estatisticas: arquivos migrados, duplicatas encontradas,
+bytes economizados.
+
Metricas Prometheus (tesseras-storage/src/metrics.rs) — Dez novas metricas
+para observabilidade:
+
Metrica
Descricao
+
cas_objects_total
Total de objetos unicos no CAS
+
cas_bytes_total
Total de bytes armazenados
+
cas_dedup_hits_total
Numero de escritas que encontraram um objeto existente
+
cas_bytes_saved_total
Bytes economizados por deduplicacao
+
cas_gc_refcount_deletions_total
Objetos deletados quando refcount chegou a zero
+
cas_gc_sweep_orphans_cleaned_total
Arquivos orfaos removidos pelo sweep
+
cas_gc_sweep_leaked_refs_cleaned_total
Linhas de refcount vazadas limpas
+
cas_gc_sweep_skipped_young_total
Orfaos jovens pulados (periodo de graca)
+
cas_gc_sweep_duration_seconds
Tempo gasto no sweep GC
+
+
Testes baseados em propriedades — Dois testes proptest verificam invariantes
+do CAS sob entradas aleatorias:
+
+
refcount_matches_actual_refs — apos N operacoes aleatorias de put/release, o
+refcount sempre corresponde ao numero real de referencias pendentes
+
cas_path_is_deterministic — o mesmo hash sempre produz o mesmo caminho no
+sistema de arquivos
+
+
Atualizacao de testes de integracao — Todos os testes de integracao em
+tesseras-core, tesseras-replication, tesseras-embedded e tesseras-cli
+atualizados para os novos construtores com CAS. Testes de deteccao de
+adulteracao atualizados para funcionar com o layout de diretorio CAS.
+
347 testes passam em todo o workspace. Clippy limpo com -D warnings.
+
Decisoes de arquitetura
+
+
BLAKE3 como chave CAS: o hash de conteudo que ja computamos para
+verificacao de integridade serve tambem como chave de deduplicacao. Nenhuma
+etapa adicional de hashing — o hash computado durante create ou replicate
+e reutilizado como endereco CAS.
+
Refcount SQLite ao inves de reflinks do sistema de arquivos: consideramos
+usar copy-on-write no nivel do sistema de arquivos (reflinks em btrfs/XFS),
+mas isso amarraria o Tesseras a sistemas de arquivos especificos. Refcounting
+em SQLite funciona em qualquer sistema de arquivos, incluindo FAT32 em
+pendrives baratos e ext4 em Raspberry Pis.
+
Diretorios de prefixo hexadecimal de dois niveis: armazenar todos os
+objetos CAS em um diretorio plano desaceleraria sistemas de arquivos com
+milhoes de entradas. A divisao <prefixo 2 chars>/ limita qualquer diretorio
+individual a ~65k entradas antes de um segundo nivel ser necessario. Isso
+segue a abordagem usada pelo object store do Git.
+
Periodo de graca para arquivos orfaos: o sweep GC pula arquivos com menos
+de 1 hora para evitar deletar objetos sendo escritos por uma operacao
+concorrente. Esta e uma escolha pragmatica — troca uma pequena janela de
+potenciais orfaos por seguranca contra crashes sem exigir fsync ou commit de
+duas fases.
+
Migracao copy-first: a migracao copia dados para o CAS antes de remover
+diretorios antigos. Se o processo for interrompido, os dados antigos
+permanecem intactos e a migracao pode ser re-executada. Isso e mais lento que
+mover arquivos mas garante zero perda de dados.
+
Sweep no loop de reparo: ao inves de adicionar um timer separado de GC, o
+sweep CAS aproveita o loop de reparo existente de 24 horas. Isso mantem o
+daemon simples — um unico ciclo de manutencao em segundo plano cuida tanto da
+saude dos fragmentos quanto da limpeza de armazenamento.
+
+
O que vem a seguir
+
+
Fase 4 continuacao — auditorias de seguranca, empacotamento para OS
+(Alpine, Arch, Debian, OpenBSD, FreeBSD)
+
Fase 5: Exploracao e Cultura — navegador publico de tesseras por
+era/localizacao/tema/idioma, curadoria institucional, integracao genealogica
+(FamilySearch, Ancestry), exportacao para midia fisica (M-DISC, microfilme,
+papel livre de acido com QR), contexto assistido por IA
+
+
A deduplicacao de armazenamento completa a historia de eficiencia de
+armazenamento do Tesseras. Um no que armazena fragmentos para milhares de
+usuarios — comum para nos institucionais e nos completos sempre ligados — agora
+paga o custo de disco apenas por dados unicos. Combinado com codificacao de
+apagamento Reed-Solomon (que ja minimiza redundancia no nivel da rede), o
+sistema alcanca armazenamento eficiente tanto nas camadas local quanto
+distribuida.
Confiança não deveria exigir instalação de software. Se alguém te envia uma
+tessera — um pacote de memórias preservadas — você deveria poder verificar que é
+genuína e não foi modificada sem baixar um app, criar uma conta, ou confiar em
+um servidor. É isso que o tesseras-wasm entrega: arraste um arquivo tessera
+para uma página web, e a verificação criptográfica acontece inteiramente no seu
+navegador.
+
O que foi construído
+
tesseras-wasm — Um crate Rust que compila para WebAssembly via wasm-pack,
+expondo quatro funções stateless para JavaScript. O crate depende do
+tesseras-core para parsing do manifesto e chama primitivas criptográficas
+diretamente (blake3, ed25519-dalek) ao invés de depender do tesseras-crypto,
+que puxa bibliotecas pós-quânticas baseadas em C que não compilam para
+wasm32-unknown-unknown.
+
parse_manifest recebe os bytes brutos do MANIFEST (texto UTF-8 plano, não
+MessagePack), delega para tesseras_core::manifest::Manifest::parse(), e
+retorna uma string JSON com a chave pública Ed25519 do criador, caminhos dos
+arquivos de assinatura, e uma lista de arquivos com seus hashes BLAKE3
+esperados, tamanhos e tipos MIME. Structs internas (ManifestJson,
+CreatorPubkey, SignatureFiles, FileEntry) são serializadas com serde_json.
+Os campos de chave pública ML-DSA e arquivo de assinatura estão presentes no
+contrato JSON mas definidos como null — prontos para quando a assinatura
+pós-quântica for implementada no lado nativo.
+
hash_blake3 computa um hash BLAKE3 de bytes arbitrários e retorna uma string
+hexadecimal de 64 caracteres. É chamada uma vez por arquivo na tessera para
+verificar integridade contra o MANIFEST.
+
verify_ed25519 recebe uma mensagem, uma assinatura de 64 bytes e uma chave
+pública de 32 bytes, constrói uma ed25519_dalek::VerifyingKey, e retorna se a
+assinatura é válida. A validação de comprimento retorna erros descritivos
+("Ed25519 public key must be 32 bytes") ao invés de causar panic.
+
verify_ml_dsa é um stub que retorna um erro explicando que verificação ML-DSA
+ainda não está disponível. Isso é deliberado: o crate ml-dsa no crates.io está
+na v0.1.0-rc.7 (pré-release), e o tesseras-crypto usa pqcrypto-dilithium
+(CRYSTALS-Dilithium baseado em C) que é incompatível em nível de bytes com FIPS
+204 ML-DSA. Ambos os lados precisam usar a mesma implementação em Rust puro
+antes que a verificação cruzada funcione. Verificação Ed25519 é suficiente —
+toda tessera é assinada com Ed25519.
+
Todas as quatro funções usam um padrão de duas camadas para testabilidade:
+funções internas retornam Result<T, String> e são testadas nativamente,
+enquanto wrappers finos #[wasm_bindgen] convertem erros para JsError. Isso
+evita que JsError::new() cause panic em targets não-WASM durante os testes.
+
O binário WASM compilado tem 109 KB bruto e 44 KB com gzip — bem abaixo do
+orçamento de 200 KB. O wasm-opt aplica otimização -Oz após o wasm-pack
+compilar com opt-level = "z", LTO e uma única unidade de codegen.
+
@tesseras/verify — Um pacote npm TypeScript (crates/tesseras-wasm/js/) que
+orquestra a verificação no lado do navegador. A API pública é uma única função:
O tipo VerificationResult fornece tudo que uma UI precisa: validade geral,
+hash da tessera, chaves públicas do criador, status das assinaturas
+(valid/invalid/missing para Ed25519 e ML-DSA), resultados de integridade por
+arquivo com hashes esperados e reais, uma lista de arquivos inesperados não
+presentes no MANIFEST, e um array de erros.
+
A descompactação de arquivos (unpack.ts) lida com três formatos: tar
+comprimido com gzip (detectado pelos magic bytes \x1f\x8b, descomprimido com
+fflate e depois parseado como tar), ZIP (magic PK\x03\x04, descompactado com
+unzipSync do fflate), e tar bruto (ustar no offset 257). Uma função
+normalizePath remove o prefixo tessera-<hash>/ para que os caminhos internos
+correspondam às entradas do MANIFEST.
+
A verificação roda em um Web Worker (worker.ts) para manter a thread da UI
+responsiva. O worker inicializa o módulo WASM, descompacta o arquivo, parseia o
+MANIFEST, verifica a assinatura Ed25519 contra a chave pública do criador,
+depois faz hash de cada arquivo com BLAKE3 e compara com os valores esperados.
+Mensagens de progresso são transmitidas de volta para a thread principal após
+cada arquivo. Se qualquer assinatura é inválida, a verificação para
+imediatamente sem fazer hash dos arquivos — falhando rápido na verificação mais
+crítica.
+
O arquivo é transferido para o worker com zero-copy
+(worker.postMessage({ type: "verify", archive }, [archive.buffer])) para
+evitar duplicar arquivos de tessera potencialmente grandes na memória.
+
Pipeline de build — Três novos targets no justfile: wasm-build executa
+wasm-pack com --target web --release e otimiza com wasm-opt; wasm-size
+reporta o tamanho do binário bruto e com gzip; test-wasm executa a suíte de
+testes nativos.
+
Testes — 9 testes unitários nativos cobrem hashing BLAKE3 (entrada vazia,
+valor conhecido), verificação Ed25519 (assinatura válida, assinatura inválida,
+chave errada, comprimento de chave inválido), e parsing do MANIFEST (manifesto
+válido, UTF-8 inválido, lixo). 3 testes de integração WASM rodam em Chrome
+headless via wasm-pack test --headless --chrome, verificando que
+hash_blake3, verify_ed25519 e parse_manifest funcionam corretamente quando
+compilados para wasm32-unknown-unknown.
+
Decisões de arquitetura
+
+
Sem dependência do tesseras-crypto: o crate WASM chama blake3 e
+ed25519-dalek diretamente. O tesseras-crypto depende do pqcrypto-kyber
+(ML-KEM baseado em C via pqcrypto-traits) que requer um toolchain de
+compilador C e não tem target wasm32. Dependendo apenas de crates Rust puros,
+o build WASM tem zero dependências C e compila sem problemas para WebAssembly.
+
ML-DSA adiado, não fingido: ao invés de silenciosamente pular a
+verificação pós-quântica, o stub retorna um erro explícito. Isso garante que
+se uma tessera contiver uma assinatura ML-DSA, o resultado da verificação
+reportará ml_dsa: "missing" ao invés de fingir que foi verificada. O
+orquestrador JS lida com isso graciosamente — uma tessera é válida se Ed25519
+passar e ML-DSA estiver ausente (ainda não implementado em nenhum dos lados).
+
Padrão de função interna: JsError não pode ser construído em targets
+não-WASM (causa panic). Dividir cada função em
+foo_inner() -> Result<T, String> e foo() -> Result<T, JsError> permite que
+a suíte de testes nativa exercite toda a lógica sem tocar em tipos JavaScript.
+Os testes de integração WASM em Chrome headless testam a superfície completa
+do #[wasm_bindgen].
+
Isolamento em Web Worker: operações criptográficas (especialmente BLAKE3
+sobre arquivos de mídia grandes) podem levar centenas de milissegundos. Rodar
+em um Worker previne travamentos na UI. O protocolo de progresso com streaming
+({ type: "progress", current, total, file }) permite que a UI mostre uma
+barra de progresso durante a verificação de tesseras com muitos arquivos.
+
Transferência zero-copy: archive.buffer é transferido para o Worker, não
+copiado. Para um arquivo tessera de 50 MB, isso evita dobrar o uso de memória
+durante a verificação.
+
MANIFEST em texto plano, não MessagePack: o crate WASM parseia o mesmo
+formato de MANIFEST em texto plano que o CLI. Isso é por design — o MANIFEST é
+a Pedra de Rosetta da tessera, legível por qualquer pessoa com um editor de
+texto. A dependência rmp-serde no Cargo.toml não é usada e será removida.
+
+
O que vem a seguir
+
+
Fase 4: Resiliência e Escala — Empacotamento para sistemas operacionais
+(Alpine, Arch, Debian, FreeBSD, OpenBSD), CI no SourceHut e GitHub Actions,
+auditorias de segurança, explorador de tesseras no navegador em tesseras.net
+usando @tesseras/verify
+
Fase 5: Exploração e Cultura — 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)
+
+
A verificação não exige mais confiança em software. Um arquivo tessera arrastado
+para um navegador é verificado com o mesmo rigor criptográfico do CLI — mesmos
+hashes BLAKE3, mesmas assinaturas Ed25519, mesmo parser de MANIFEST. A diferença
+é que agora qualquer pessoa pode fazer isso.
+
+
+
+
+
+
+
+
diff --git a/pt-br/news/phase4-wasm-browser-verification/index.html.gz b/pt-br/news/phase4-wasm-browser-verification/index.html.gz
new file mode 100644
index 0000000..9b90534
Binary files /dev/null and b/pt-br/news/phase4-wasm-browser-verification/index.html.gz differ
diff --git a/pt-br/news/reed-solomon/index.html b/pt-br/news/reed-solomon/index.html
new file mode 100644
index 0000000..8947909
--- /dev/null
+++ b/pt-br/news/reed-solomon/index.html
@@ -0,0 +1,210 @@
+
+
+
+
+
+ Reed-Solomon: Como o Tesseras Sobrevive à Perda de Dados — Tesseras
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Reed-Solomon: Como o Tesseras Sobrevive à Perda de Dados
+
2026-02-14
+
Seu disco rígido vai morrer. Seu provedor de nuvem vai pivotar. O array RAID no
+seu armário vai sobreviver ao controlador, mas não ao dono. Se uma memória está
+armazenada em exatamente um lugar, ela tem exatamente uma forma de se perder
+para sempre.
+
Tesseras é uma rede que mantém memórias humanas vivas através de ajuda mútua. O
+mecanismo central de sobrevivência é a codificação de apagamento
+Reed-Solomon — uma técnica emprestada da comunicação espacial profunda que nos
+permite reconstruir dados mesmo quando pedaços desaparecem.
+
O que é Reed-Solomon?
+
Reed-Solomon é uma família de códigos corretores de erros inventada por Irving
+Reed e Gustave Solomon em 1960. O caso de uso original era corrigir erros em
+dados transmitidos por canais ruidosos — pense na Voyager enviando fotos de
+Júpiter, ou num CD tocando apesar de arranhões.
+
A ideia-chave: se você adicionar redundância cuidadosamente calculada aos seus
+dados antes que algo dê errado, você pode recuperar o original mesmo depois de
+perder alguns pedaços.
+
Eis a intuição. Suponha que você tenha um polinômio de grau 2 — uma parábola.
+Você precisa de 3 pontos para defini-lo de forma única. Mas se você avaliá-lo em
+5 pontos, pode perder quaisquer 2 desses 5 e ainda reconstruir o polinômio a
+partir dos 3 restantes. Reed-Solomon generaliza essa ideia para trabalhar sobre
+corpos finitos (corpos de Galois), onde o "polinômio" são seus dados e os
+"pontos de avaliação" são seus fragmentos.
+
Em termos concretos:
+
+
Divida seus dados em k shards de dados
+
Calculem shards de paridade a partir dos shards de dados
+
Distribua todos os k + m shards em diferentes locais
+
Reconstrua os dados originais a partir de quaisquer k dos k + m
+shards
+
+
Você pode perder até m shards — quaisquer m, de dados ou paridade, em
+qualquer combinação — e ainda recuperar tudo.
+
Por que não simplesmente fazer cópias?
+
A abordagem ingênua para redundância é a replicação: faça 3 cópias, armazene-as
+em 3 lugares. Isso dá tolerância a 2 falhas ao custo de 3x o seu armazenamento.
+
Reed-Solomon é dramaticamente mais eficiente:
+
Estratégia
Overhead de armazenamento
Falhas toleradas
+
Replicação 3x
200%
2 de 3
+
Reed-Solomon (16,8)
50%
8 de 24
+
Reed-Solomon (48,24)
50%
24 de 72
+
+
Com 16 shards de dados e 8 de paridade, você usa 50% de armazenamento extra mas
+pode sobreviver à perda de um terço de todos os fragmentos. Para alcançar a
+mesma tolerância a falhas só com replicação, você precisaria de 3x o
+armazenamento.
+
Para uma rede que visa preservar memórias ao longo de décadas e séculos, essa
+eficiência não é um luxo — é a diferença entre um sistema viável e um que se
+afoga no próprio overhead.
+
Como o Tesseras usa Reed-Solomon
+
Nem todos os dados merecem o mesmo tratamento. Uma memória de texto de 500 bytes
+e um vídeo de 100 MB têm necessidades de redundância muito diferentes. O
+Tesseras usa uma estratégia de fragmentação em três camadas:
+
Small (< 4 MB) — Replicação do arquivo inteiro para 7 pares. Para tesseras
+pequenas, o overhead da codificação de apagamento (tempo de codificação,
+gerenciamento de fragmentos, lógica de reconstrução) supera seus benefícios.
+Cópias simples são mais rápidas e mais simples.
+
Medium (4–256 MB) — 16 shards de dados + 8 de paridade = 24 fragmentos no
+total. Cada fragmento tem aproximadamente 1/16 do tamanho original. Quaisquer 16
+dos 24 fragmentos reconstroem o original. Distribuídos entre 7 pares.
+
Large (≥ 256 MB) — 48 shards de dados + 24 de paridade = 72 fragmentos no
+total. Maior contagem de shards significa fragmentos individuais menores (mais
+fáceis de transferir e armazenar) e maior tolerância absoluta a falhas. Também
+distribuídos entre 7 pares.
+
A implementação usa o crate reed-solomon-erasure operando sobre GF(2⁸) — o
+mesmo corpo de Galois usado em códigos QR e CDs. Cada fragmento carrega um
+checksum BLAKE3 para que a corrupção seja detectada imediatamente, não propagada
+silenciosamente.
+
Tessera (álbum de fotos de 120 MB)
+ ↓ codificar
+16 shards de dados (7,5 MB cada) + 8 shards de paridade (7,5 MB cada)
+ ↓ distribuir
+24 fragmentos entre 7 pares (diversidade de sub-rede)
+ ↓ quaisquer 16 fragmentos
+Tessera original recuperada
+
+
Os desafios
+
Reed-Solomon resolve o problema matemático da redundância. Os desafios de
+engenharia estão em tudo ao redor.
+
Rastreamento de fragmentos
+
Cada fragmento precisa ser localizável. O Tesseras usa uma DHT Kademlia para
+descoberta de pares e mapeamento de fragmentos para pares. Quando um nó fica
+offline, seus fragmentos precisam ser recriados e distribuídos para novos pares.
+Isso significa rastrear quais fragmentos existem, onde estão e se ainda estão
+intactos — numa rede sem autoridade central.
+
Corrupção silenciosa
+
Um fragmento que retorna dados errados é pior que um ausente — pelo menos um
+fragmento ausente é honestamente ausente. O Tesseras aborda isso com
+verificações de saúde baseadas em atestação: o loop de reparo periodicamente
+pede aos detentores de fragmentos que provem posse retornando checksums BLAKE3.
+Se um checksum não bater, o fragmento é tratado como perdido.
+
Falhas correlacionadas
+
Se todos os 24 fragmentos de uma tessera caírem em máquinas no mesmo datacenter,
+uma única queda de energia os elimina todos. A matemática do Reed-Solomon assume
+falhas independentes. O Tesseras impõe diversidade de sub-rede durante a
+distribuição: no máximo 2 fragmentos por sub-rede /24 IPv4 (ou prefixo /48
+IPv6). Isso espalha fragmentos por diferentes infraestruturas físicas.
+
Velocidade de reparo vs. carga na rede
+
Quando um par fica offline, o relógio começa a contar. Fragmentos perdidos
+precisam ser recriados antes que mais falhas se acumulem. Mas reparo agressivo
+inunda a rede. O Tesseras equilibra isso com um loop de reparo configurável
+(padrão: a cada 24 horas com 2 horas de jitter) e limites de transferências
+simultâneas (padrão: 4 transferências simultâneas). O jitter previne tempestades
+de reparo onde cada nó verifica seus fragmentos no mesmo momento.
+
Gerenciamento de chaves a longo prazo
+
Reed-Solomon protege contra perda de dados, não contra perda de acesso. Se uma
+tessera é criptografada (visibilidade privada ou selada), você precisa da chave
+de descriptografia para tornar os dados recuperados úteis. O Tesseras separa
+essas preocupações: codificação de apagamento cuida da disponibilidade, enquanto
+o Compartilhamento de Segredo de Shamir (uma fase futura) cuidará da
+distribuição de chaves entre herdeiros. A filosofia de design do projeto —
+criptografar o mínimo possível — mantém o problema de gerenciamento de chaves
+pequeno.
+
Limitações do corpo de Galois
+
O corpo GF(2⁸) limita o número total de shards a 255 (dados + paridade
+combinados). Para o Tesseras, isso não é uma restrição prática — mesmo a camada
+Large usa apenas 72 shards. Mas significa que arquivos extremamente grandes com
+milhares de fragmentos exigiriam um corpo diferente ou um esquema de codificação
+em camadas.
+
Compatibilidade evolutiva do codec
+
Uma tessera codificada hoje precisa ser decodificável em 50 anos. Reed-Solomon
+sobre GF(2⁸) é um dos algoritmos mais amplamente implementados na computação —
+está em todo leitor de CD, em todo scanner de código QR, em toda sonda espacial.
+Essa ubiquidade é em si uma estratégia de sobrevivência. O algoritmo não será
+esquecido porque metade da infraestrutura do mundo depende dele.
+
O quadro geral
+
Reed-Solomon é uma peça de um quebra-cabeça maior. Ele trabalha em conjunto com:
+
+
DHT Kademlia para encontrar pares e rotear fragmentos
+
Checksums BLAKE3 para verificação de integridade
+
Reciprocidade bilateral para troca justa de armazenamento (sem blockchain)
+
Diversidade de sub-rede para independência de falhas
+
Reparo automático para manter a redundância ao longo do tempo
+
+
Nenhuma técnica isolada faz memórias sobreviverem. Reed-Solomon garante que
+dados podem ser recuperados. A DHT garante que fragmentos podem ser
+encontrados. A reciprocidade garante que pares querem ajudar. O reparo
+garante que nada disso se degrade com o tempo.
+
Uma tessera é uma aposta de que a soma desses mecanismos, rodando em muitas
+máquinas independentes operadas por muitas pessoas independentes, é mais durável
+que qualquer instituição isolada. Reed-Solomon é a fundação matemática dessa
+aposta.
+
+
+
+
+
+
+
+
diff --git a/pt-br/news/reed-solomon/index.html.gz b/pt-br/news/reed-solomon/index.html.gz
new file mode 100644
index 0000000..d7674cf
Binary files /dev/null and b/pt-br/news/reed-solomon/index.html.gz differ
--
cgit v1.2.3