1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
|
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Fase 4: Onboarding de Nos Institucionais — Tesseras</title>
<meta name="description" content="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.">
<!-- Open Graph -->
<meta property="og:type" content="article">
<meta property="og:title" content="Fase 4: Onboarding de Nos Institucionais">
<meta property="og:description" content="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.">
<meta property="og:image" content="https://tesseras.net/images/social.jpg">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:site_name" content="Tesseras">
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Fase 4: Onboarding de Nos Institucionais">
<meta name="twitter:description" content="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.">
<meta name="twitter:image" content="https://tesseras.net/images/social.jpg">
<link rel="stylesheet" href="https://tesseras.net/style.css?h=21f0f32121928ee5c690">
<link rel="alternate" type="application/atom+xml" title="Tesseras" href="https://tesseras.net/atom.xml">
<link rel="icon" type="image/png" sizes="32x32" href="https://tesseras.net/images/favicon.png?h=be4e123a23393b1a027d">
</head>
<body>
<header>
<h1>
<a href="https://tesseras.net/pt-br/">
<img src="https://tesseras.net/images/logo-64.png?h=c1b8d0c4c5f93b49d40b" alt="Tesseras" width="40" height="40" class="logo">
Tesseras
</a>
</h1>
<nav>
<a href="https://tesseras.net/pt-br/about/">Sobre</a>
<a href="https://tesseras.net/pt-br/news/">Notícias</a>
<a href="https://tesseras.net/pt-br/releases/">Lançamentos</a>
<a href="https://tesseras.net/pt-br/faq/">FAQ</a>
<a href="https://tesseras.net/pt-br/subscriptions/">Inscrições</a>
<a href="https://tesseras.net/pt-br/contact/">Contato</a>
</nav>
<nav class="lang-switch">
<a href="https://tesseras.net/news/phase4-institutional-onboarding/">English</a> | <strong>Português</strong>
</nav>
</header>
<main>
<article>
<h2>Fase 4: Onboarding de Nos Institucionais</h2>
<p class="news-date">2026-02-15</p>
<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>
</article>
</main>
<footer>
<p>© 2026 Tesseras Project. <a href="/atom.xml">News Feed</a> · <a href="https://git.sr.ht/~ijanc/tesseras">Source</a></p>
</footer>
</body>
</html>
|